diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-01-09 15:44:05 +0000 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-01-09 15:56:53 +0000 |
| commit | 8aa8548d8ab68feb13f3bde51c557db84877e809 (patch) | |
| tree | 930790c1c84a4412db777986f6b2077808560d95 /addons/website/models | |
| parent | 55a48e341580a6a400c36b6ba0d7b12ff9997f12 (diff) | |
| parent | 3e4138deaa23b3631dc3fce33cd6d1b3be28ffbd (diff) | |
[MERGE] forward port branch 12.0 up to 3e4138deaa2
closes odoo/odoo#30045
Diffstat (limited to 'addons/website/models')
| -rw-r--r-- | addons/website/models/ir_http.py | 4 | ||||
| -rw-r--r-- | addons/website/models/ir_ui_view.py | 74 | ||||
| -rw-r--r-- | addons/website/models/website.py | 42 |
3 files changed, 69 insertions, 51 deletions
diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 25becf9749c..a649a9acc81 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -74,7 +74,9 @@ class Http(models.AbstractModel): # Force website with query string paramater, typically set from website selector in frontend navbar force_website_id = request.httprequest.args.get('fw') - if force_website_id and request.session.get('force_website_id') != force_website_id: + if (force_website_id and request.session.get('force_website_id') != force_website_id and + request.env.user.has_group('website.group_multi_website') and + request.env.user.has_group('website.group_website_publisher')): request.env['website']._force_website(request.httprequest.args.get('fw')) context = {} diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index f45f602fa8b..1a98713326d 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -125,64 +125,50 @@ class View(models.Model): # get_related_views can be called through website=False routes # (e.g. /web_editor/get_assets_editor_resources), so website # dispatch_parameters may not be added. Manually set - # website_id. + # website_id. (It will then always fallback on a website, this + # method should never be called in a generic context, even for + # tests) self = self.with_context(website_id=self.env['website'].get_current_website().id) - views = super(View, self).get_related_views(key, bundles=bundles) + return super(View, self).get_related_views(key, bundles=bundles) + + def filter_duplicate(self): + """ Filter current recordset only keeping the most suitable view per distinct key. + Every non-accessible view will be removed from the set: + * In non website context, every view with a website will be removed + * In a website context, every view from another website + """ current_website_id = self._context.get('website_id') most_specific_views = self.env['ir.ui.view'] - if not current_website_id: - return views + return self.filtered(lambda view: not view.website_id) - for view in views: + for view in self: if view.website_id and view.website_id.id == current_website_id: most_specific_views |= view - elif not view.website_id and not any(view.key == view2.key and view2.website_id and view2.website_id.id == current_website_id for view2 in views): + elif not view.website_id and not any(view.key == view2.key and view2.website_id and view2.website_id.id == current_website_id for view2 in self): most_specific_views |= view return most_specific_views - @api.multi - def _sort_suitability_key(self): - """ Key function to sort views by descending suitability - Suitability of a view is defined as follow: - * if the view and request website_id are matched - * then if the view has no set website - """ - self.ensure_one() - context_website_id = self.env.context.get('website_id', 1) - website_id = self.website_id.id or 0 - different_website = context_website_id != website_id - return (different_website, website_id) - - def filter_duplicate(self): - """ Filter current recordset only keeping the most suitable view per distinct key """ - view_with_key = self.filtered('key') - view_without_key = self - view_with_key - filtered = self.env['ir.ui.view'] - for dummy, group in groupby(view_with_key.sorted('key'), key=lambda record: record.key): - filtered += sorted(group, key=lambda record: record._sort_suitability_key())[0] - return (filtered + view_without_key).sorted(key=lambda view: (view.priority, view.id)) + @api.model + def _view_get_inherited_children(self, view, options): + extensions = super(View, self)._view_get_inherited_children(view, options) + return extensions.filter_duplicate() @api.model def _view_obj(self, view_id): - if isinstance(view_id, str): - if 'website_id' in self._context: - domain = [('key', '=', view_id)] + self.env['website'].website_domain(self._context.get('website_id')) - order = 'website_id' - else: - domain = [('key', '=', view_id)] - order = self._order - views = self.search(domain, order=order) - if views: - return views.filter_duplicate() - else: - return self.env.ref(view_id) - elif isinstance(view_id, int): - return self.browse(view_id) - - # assume it's already a view object (WTF?) - return view_id + ''' Given an xml_id or a view_id, return the corresponding view record. + In case of website context, return the most specific one. + :param view_id: either a string xml_id or an integer view_id + :return: The view record or empty recordset + ''' + if isinstance(view_id, str) or isinstance(view_id, int): + return self.env['website'].viewref(view_id) + else: + # It can already be a view object when called by '_views_get()' that is calling '_view_obj' + # for it's inherit_children_ids, passing them directly as object record. (Note that it might + # be a view_id from another website but it will be filtered in 'get_related_views()') + return view_id if view_id._name == 'ir.ui.view' else self.env['ir.ui.view'] @api.model def _get_inheriting_views_arch_website(self, view_id): diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 0a99b8ef8eb..82709c4663d 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -173,7 +173,6 @@ class Website(models.Model): default_menu = self.env.ref('website.main_menu') self.copy_menu_hierarchy(default_menu) - @api.model def copy_menu_hierarchy(self, top_menu): def copy_menu(menu, t_menu): new_menu = menu.copy({ @@ -281,11 +280,6 @@ class Website(models.Model): key_copy = string + (inc and "-%s" % inc or "") return key_copy - def key_to_view_id(self, view_id): - return self.env['ir.ui.view'].search([ - ('id', '=', view_id), ('type', '=', 'qweb') - ] + self.env['website'].website_domain(self._context.get('website_id'))) - @api.model def page_search_dependencies(self, page_id=False): """ Search dependencies just for information. It will not catch 100% @@ -506,6 +500,42 @@ class Website(models.Model): return request.env.user.id == request.website.user_id.id @api.model + def viewref(self, view_id, raise_if_not_found=True): + ''' Given an xml_id or a view_id, return the corresponding view record. + In case of website context, return the most specific one. + :param view_id: either a string xml_id or an integer view_id + :param raise_if_not_found: should the method raise an error if no view found + :return: The view record or empty recordset + ''' + View = self.env['ir.ui.view'] + view = None + if isinstance(view_id, str): + if 'website_id' in self._context: + domain = [('key', '=', view_id)] + self.env['website'].website_domain(self._context.get('website_id')) + order = 'website_id' + else: + domain = [('key', '=', view_id)] + order = View._order + views = View.with_context(active_test=False).search(domain, order=order) + if views: + view = views.filter_duplicate() + else: + view = self.env.ref(view_id) + # self.env.ref might return something else than an ir.ui.view (eg: a theme.ir.ui.view) + if view._name != 'ir.ui.view': + view = None + elif isinstance(view_id, int): + view = View.browse(view_id) + else: + raise ValueError('Expecting a string or an integer, not a %s.' % (type(view_id))) + + if view: + return view + if raise_if_not_found: + raise ValueError('No record found for unique ID %s. It may have been deleted.' % (view_id)) + return None + + @api.model def get_template(self, template): View = self.env['ir.ui.view'] if isinstance(template, int): |
