The core website behavior is the COW (copy on write) which makes it possible to
handle multiple websites on a single database.
When you do a CRUD operation on an `ir.ui.view` in a website context, the ORM
normal behavior is bypass to perform special stuff, such as:
- Write: if the view is generic (no `website_id`), we bifurcate the write on
the specific view (same `key` but with `website_id` set). If that
view doesn't exist, we create it and fork its whole descending
hierarchy. This write behavior is known as COW.
- Create: we ensure that view is created only for the website and no other.
Basically we just add a `website_id` to that view, but it might
also be about setting the correct `inherit_id` by finding the
specific view among multiple views with the same `key`.
- Unlink: if the view is generic, we will unlink that view but also create a
copy of that view for every other websites so they remain
unmodified: this is known as COU (copy on unlink).
All those behavior aims to satisfy to the multi website holy grail:
-- Any modification in a website context should never impact another website --
Because of those uncommon behaviors, it is sometimes hard to understand or
investigate a database, as views might be copied, up to the point where there
is multiple whole view hierarchies.
This commit attempts to create an user interface to easily figure what's going
on in a database at an `ir.ui.view` level.
The mains advantages of that new `ir.ui.view` Qweb view is to:
- easily figure which views are COW'd on which website
- easily detect which views have a real `arch` modification
- easily see that `arch` change
Closes#63040
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Before this commit, only whitelisted fields would be updated on cow views
during a module update.
A field would be whitelisted if he had the same value than the original view,
see it as a heuristic to not write on modified fields.
But `inherit_id` is not that simple, even if the cow view has a different value
than its original view, it doesn't mean it was modified by the user, it is just
because of the cow mechanism that assigned a copied view as inherit_id, which
is just a copy ofthe original one.
We can thus consider `inherit_id` as unchanged and whitelist it if the `key` is
the same.
In practice, it means that cow'd views did not receive the `inherit_id` updates
as in commit https://github.com/odoo/odoo/commit/c8577568a1e39f6692889b3e21652fa3b8df06b2#diff-823e5db841dca1798ff1300e243059a4e1c93343598d2be5a1d1dcd1d2d0c273R537
where `portal.my_account_link` had its `inherit_id` changed from
`portal.frontend_layout` to `portal.user_dropdow`, see https://github.com/odoo/upgrade/pull/2059:
Considering a module update changing `inherit_id` of D from A to B, the
following use cases are expected. Without this fix, D' never move:
CASE 1
A A' B A A' B
| | => / \
D D' D D'
CASE 2
A A' B B' A A' B B'
| | => | |
D D' D D'
CASE 3
A B A B
/ \ => / \
D D' D D'
CASE 4
A B B' A B B'
/ \ => | |
D D' D D'
Opw: 2422773
Opw: 2422727
Opw: 2422770
Opw: 2423406
Opw: 2423859
X-original-commit: ff69f11e9c97d63d9319a8094a87af93984aba38
Steps:
- As admin, go to "Contact us" or any other page on the website (1)
- Go to Pages > Page Properties > Publish
- Change the visibility to Signed In
- Save
- As demo, go to (1)
Bug:
The user "demo" is signed in but is returned a 403 Forbidden
Explanation:
When landing on a page with visibility: 'connected', the only way to see
the page is to have a group matching the groups of the page as seen
here: https://github.com/odoo/odoo/blob/28b748a559e1ffb5fb7c3631bf77adba121b2ebf/odoo/addons/base/models/ir_ui_view.py#L625-L626
This fix lets any connected users see the page.
opw:2431700
closesodoo/odoo#64720
X-original-commit: b02a99bec709b5a6dc4dabb6cb81435dadc24e7e
Signed-off-by: backspac <backspac@users.noreply.github.com>
SOC for ir.ui.view creation. If a view is created without a website_id,
it should get one if one is present in the context. Also check that
an explicit website_id in create values matches the one in the context.
Note: it was already the case but kinda by chance and not entirely
correct. Most of the time, the 'arch' field was specified as a creation
value... and as it is a computed field with an inverse method, a COW
was triggered. But this had also the inconvenient of creating an extra
generic view without any arch.
closesodoo/odoo#43245
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
*: web_editor, website
In stable versions, [1] was made as a fix to allow access to read
the colorpicker template for mass mailing users when they do not have
the read access right on ir.ui.view records.
This commit, for master, remove the need of using the confusing
read_template method by using render_public_asset instead (thus turning
the read into a render, which is the same for our colorpicker but might
be a change for potential custo). At the same time, this allows to
remove the read_template public method entirely.
Related to task-2412544
[1]: 8af75e00bdcda3d5ff4facd2f5f146e1d6bf79e4
closesodoo/odoo#64100
Related: odoo/enterprise#15580
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Before this commit, the time to compute all counters was making the rendering
of the portal page slow.
Now the count is done in rpc after the loading of the page.
Now you can decide which part you want to show on the portal, and only compute
for these one.
It is not because you have purchase installed for your internal process, that
it means that your supplier use your portal and it avoid the computation for
all end users.
We parallelize the counters in arbitrary 3 rpcs.
closesodoo/odoo#55999
Related: odoo/enterprise#12456
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Before this commit, the template to generate 'New' panel generates .exists()
queries for each env.ref, now only one by module.
We could still improve it, deferring this rendering on click only.
For now, each time you are editor, we render it, even if you don't plan to
create anything.
+ use some xmlid_to_res_id instead of ref to avoid useless exists query.
Courtesy of @Feyensv for the tips
*: website
Since [1], the thumbnails of the saved snippets were not right anymore,
all fallbacking to the default image. This is because snippets thumbs
now use svg files instead of png and the snippet saving feature did not
allow it. This commit fixes that and makes the feature more robust.
- Allow to use any original thumbnail, and not only for website app.
- Remove useless defaut image, a fallback for when the feature is broken
is useless.
- Identify snippets by key instead of by main class (possible since
the new `data-snippet` attribute on snippets).
[1]: https://github.com/odoo/odoo/commit/b7fe2bdae2f45372c0d538767a226a413b806f3fclosesodoo/odoo#55896
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
When you create an ir_ui_view form the backend, the encrypt function
was called with a Falsy value and crash with error:
TypeError: secret must be unicode or bytes, not bool
Now, when you create view from backend, we only set password if it is a qweb
view. In case of update, the field is dirty, so if you don't update it, it
will be not write.
closesodoo/odoo#53348
X-original-commit: 3d9101db0f7cc0adc1f34721c38b4c2f7089566d
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Things to know about specific views:
Since the introduction of website specific views, we can have multiple
views that are related to a website (specific views). These views have
no xml_id as it is only set on the original view (generic view).
We rely on the view's key to identify related views as it is the same
for all specific views of a generic view. Also the key is equals to the
xml_id.
When a generic view is updated, we will check if the specific views have
the same values as the generic view. If it is the case, the value that
are the same are considered updatable and are updated on both the
generic and specific view. Else these are considered as noupdate.
When a generic view is created we will check if the potential parent
generic view has specific views. If it is the case we will create a copy
of the created view for each specific view.
The issue:
The method that checks if a created/updated view has specific views is
located in website. When we update a module, each modules are
initialized and updated in a specific order. If a generic view that has
specific views located in a module loaded before website this view's
specific views will not be updated/created as the method does not exist.
This issue is mainly affecting portal views at the moment.
The solution:
For write:
We now COW(copy on write) the views in base module, meaning this will
apply to all qweb views that are duplicated and not only the website
specific ones.
For create:
We will create the generic view as before but wait until we have
updated all the modules to gather all generic views that are supposed
to have a specific view but don't and create the specific views.
This will result in a change of behavior being that if a specific view
that have a parent is deleted it will be recreated on update
(same behavior as a generic view).
closesodoo/odoo#52629
X-original-commit: b1a90ee2bb441aa52e3cf4607c43fb464b55b1d7
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Signed-off-by: fja-odoo <fja-odoo@users.noreply.github.com>
visibility_group was used for visibility, we now use the groups_id field.
groups_id is a M2M field while visibility_group was a M2O field resulting
in an issue to display the M2M field in the frontend. We decided to
allow editing the groups as a M2O in the frontend. If there is more
than one group the user will have to go through the backend to edit.
task-2264580
closesodoo/odoo#51846
Related: odoo/upgrade#1260
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This restricts the attributes of a BaseModel instance to `env`, `_ids`
and `_prefetch_ids`. This way, one can only assign fields on a record;
other assignments are programming errors.
This also reduces the memory footprint of records from 168 to 64 bytes
(-62%), and makes their instanciation faster.
closesodoo/odoo#51075
Related: odoo/enterprise#10529
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
render, render_template, load, activity_schedule_with_view,
get_website_pages should all be private:
It should not be possible to render an aribtrary template only with
its name or id
Still need to render some qweb views from js so the method
render_template is kept public.
This explains why the website editor still need read access on
ir.ui.view as we want to allow any snippet to be rendered.
The method fields_view_get should be the only way to retrieve the view
content. This method is executed in a super-user context.
To avoid retrieving views for a model a user does not have access to
(as it may reveal some informations like name of fields), add a
verification of 'read' rights before retrieving the view content.
Execute _postprocess_access_rights with sudo(False) as this method is
used to evaluate which buttons should be displayed.
Remove the su flag to avoid misleading the user and displaying a
button they won't be able to use.
Retrieving the database id from an view key is not considered as a
sensitive information and get_view_id and viewref can be left as a
public methods.
Add missing sudo when needed
Change _handle_visibility in website to avoid increasing the query
count: Checking the visibility (to fail most of the time) to retry in
sudo was making unecessary queries.
Most of the website rendering process depends of customize_show views which are
part of a configuration setup.
Once it has been setup, it will most likely never change afterward.
It makes sense to orm cache those infos to avoid having to query ir.ui.view
table everytime we render something.
Note that just store basic and small infos used for customize_show case.
task-2211013
Co-authored-by: Romain Derie <rde@odoo.com>
Co-authored-by: Jeremy Kersten <jke@odoo.com>
This commit:
- make handle_visibility a private function (even if not
exploitable in rpc easily since it uses request.website)
- encrypt the password in db (even if not critic, since this
password could be shared on twitter, ... it doesn't cost anything
to secure it a bit more)
- remove useless sudo, since handle_visibility does a sudo itself.
In the future, this notion of visibility should be handled on controller layer,
and no more on the View layer (during rendering)
closesodoo/odoo#48145
X-original-commit: 06e0e48217f25f17dff23331111f5dcb98e8cecd
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Before this commit, in all cases, we search the backend menu to open if you
click on edit backend menu.
But the backend menu edit is useless for non editor user.
This feature has been introduce in v13, since eLearning have his own apps, so
when you edit in backend, you want to see the slide form view, into the
elearning app and no website App.
Related to #47257
task-2211013
X-original-commit: 1da7e53f4cdd82574688eb62f7a1cb8ddca871e6
The function get_inheriting_views_arch, retrieves the architecture of
views that inherit from the given view. In the case of the module init
is currently in process only views from modules whose code is already
loaded are taken into account.
Before this commit, the function didn't process views that has been
copied (copy on write, web editor, customize show, manual copy, ...),
this raise an error when trying to install a module. For example,
install module website_sale, copy on write the view 'Main layout',
install module website_sale_wishlist.
Now, views that has been copied are also processed.
opw-2181968
closesodoo/odoo#47590
X-original-commit: d5a2890b30f869c9b4cf7aafed0e05aff9440360
Signed-off-by: Jorge Pinna Puissant (jpp) <jpp@odoo.com>
Co-authored-by: Nicolas Lempereur <nle@odoo.com>
Before this commit:
When logged in and navigating on a frontend page, the accessible `ir.ui.menu`
would be loaded in qcontext.
Loading those menus performs alot of SQL request, up to ~2.000 requests on big
databases such as Odoo.com for an user with a lot of access rights.
This is not a problem on low traffic website as this is ORM cached, but when
there is a lot of traffic, the cache is clear very often, thus this code only
is adding a lot of requests for no reason most of the time as the user is just
navigating without any intention of opening the application menu.
Note that this qcontext computation in frontend was pointless in enterprise as
the applications menu in frontend redirect to the backend without using it.
This commit removes that computation from the qcontext. The menus will be
computed and loaded only when the user really needs it, when he is about to
open the application menu.
closesodoo/odoo#46127
X-original-commit: 471ddf85ce619961e46fb281bf721968ff298d3b
Signed-off-by: Romain Derie <rdeodoo@users.noreply.github.com>
* website, mass_mailing, website_event, website_form,
website_mass_mailing, website_sale
Now the user can save snippets to use them on other pages.
task-2120409
closesodoo/odoo#40408
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Co-authored-by: qsm-odoo <qsm@odoo.com>
You can use has_group(employee) instead
+ fix enumerate_page: when you search a page with visibility constraints,
you never seen it even if force was set to True.
task-2091365 again
closesodoo/odoo#41483
X-original-commit: f1c7a34f0b8276895c18ca6c450a142f9a815e3b
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
View creation/edition represent a important part of an install and a lot
of possible view errors are not detected, like fields used in domain
filters. Some part of the code a difficult to maintain, and view checks
are splitted in multiple places.
This commit aims at refactoring view validation by regrouping most part
of the logic in ir_ui_view and trying to optimize the overall process.
Since most of the lines were touched, this task was also an opportunity
to modernize the API.
Main changes on method `check_xml`:
- extract node processign and validation to individual postprocessor
- add validation for filter node, buttons, ...
- fix accessibility checks (and improve their performance)
- move xpath check to specific Python node validator
- clarify error messages (wip to continue)
Main changes on method `read_combined`:
- optimize the search for inheriting views in a single query doing the
whole recursive search
Indeed, after removing xpath validations, `get_inheriting_views_arch`
was the most expensive method in `check_xml`, spending most of the time
in `search` because of recursive calls to retrieve children views.
The view Backend Assets is a good example of the latter point, since a
line is added in the view for almost every module. 70 views (community)
are added at first level, `get_inheriting_views_arch` is efficient and
returns all 70 views. Then at the second level, the method
`get_inheriting_views_arch` is called 70 times for nothing. 70 calls to
`search` (squared/2 since each view is checked independently) are almost
useless. The same case applies to the settings view.
As a result, the average module installation time is 25% faster, and the
average time spent in `read_combined` is almost divided by 2.
Before this commit, if you had a page_id set on a menu, and that you
fork this page, the page_id from the menu was always pointing to the
previous one, so you see old page, but edit new page.
> Reproduce:
> Fork Contactus (Page_id on menu become wrong)
> Refresh contact us (done on save btw)
> You see old content
> Edit with Html Editor, you sill see that forked view exists!
Bug was hidden before that we set page_id on menu, but it is needed if
we want to support the groups visibility on the menu item.
closesodoo/odoo#39472
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Now, you can define a Visibility mode between:
Public (All poeple)
Connected (Portal or Employee)
Restricted Group (Has this group or is Employee)
With Password (Know password or is Employee)
Internal Users (Is Employee)
It is a 'fair' feature, but without really warranty that the content is
really unreadable via others methods, ...
It is more for frontend display, that real secret. Dont use this like
a keychain ;)
We only catch the visibility on the main view and not the t-call inside.
Even if it should work on controller too, it is only display now on the
page property menu. (Or on the view directly in backend)
task-2091365
This is necessary when writing view fields from a page record because the
generic page will put the given values on its cache but in reality the values
were only meant to go on the specific page. Invalidate all fields and not only
those in vals because other fields could have been changed implicitly too.
Pr: #37363
X-original-commit: 83f9a3e2608db34a319b985271d73f7de5bc73a1
*base, website_blog, website_event, website_forum, website_slides
With this commit:
1. It is now possible to add the 'Edit in backend' entry in the frontend navbar
for any desired model, not only the ones which have the published mixin.
It will simply redirect to the main_object form view.
This commit add it to Forum and Blog.
2. When clicking on 'Edit in backend', it is now possible to land on another
module than Website.
That's especially useful for events and slides which are not directly
related to the website module as they have their own module.
3. Remove the custom Edit in backend from the forum homepage (fa-cog).
Opportunity was also taken to remove the 'edit welcome message'.
It will now be editable through the editor (welcome message will appear in
edit mode). Thus we got rid of the custom edit welcome message controller
and views.
Closes#36325
Before this commit, if one would introduce a scheme or a port in his website
domain, it would make the website selector to crash JS side.
Indeed, it would replace the current url hostname by the website domain.
If the website domain was introduced with `http://` it would lead to
`http://http://mysite.com`.
If port was introduced, `http://mysite:8069:8069`.
Also, by fixing those 2, it also make `localhost` and `127.0.0.1` to work.
(which would not work without `http://`.
Related to #36390
*= website, website_livechat, website_rating
///// Tracking Product /////
Now when a user browse products in eCommerce, we keep track of the
products he looked at. We use the website_visitor
to store the products viewed. A cookie is added with a TTl of 30 min it
will prevent the RPC for that time. We track the page only if the
product view is tracked.
The recently viewed products are displayed as a snippet but also
with the customize option in product pages of website_sale.
Products that are in cart will not be returned as recently viewed.
It is possible to add a recently viewed product to the cart directly
from the carousel, it will not redirect to the cart. If we are on the
cart page, the product is displayed in the cart.
The Visitor page in website now references products viewed
///// Tracking Page /////
Feature to track a view was remove in: https://github.com/odoo/enterprise/pull/4834
That feature is now reintroduced and will use website_track instead of
leads to be stored.
The track field is now on the view instead of the page.
url field is added to website.track, it will store the url for pages and
views
The Visitor page in website now references urls viewed
Add some tests
task-1984575
closesodoo/odoo#35810
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Those values are only used on the website navbar when the user is in both groups
so the vast majority of the time they are done for no reason.
This reduces the number of queries by 2 on every page when the user is not admin
and/or multi website is not enabled.
Part of task-2061122
closesodoo/odoo#36483
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
With this commit it is now possible to change the lang displayed in the URL.
Eg, you could use `/fr` instead of `/fr_BE`, or even a fancier `/french`.
Task-32838
Courtesy of pla@odoo.comclosesodoo/odoo#35135
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
`_view_get_inherited_children()` `options` parameter is not more useful.
Introduced with ae8232136d and not used since edce2fd6d0.
Also, the opportunity is taken to rename `options` in `_views_get` into
`get_children. Indeed `options` does not mean much.
closesodoo/odoo#35157
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Before this commit, it was not possible to install website_forum if the 'Main
Frontent Layout' had been COW'd.
When loading Forum Layout view which is a primary child view, it would crash
during view validation, not finding the element to xpath.
Triggering COW instead of copying fix the issue.
opw-2036119
closesodoo/odoo#35138
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
On a eCommerce page were there was no SEO optimization change:
- Customize > Activate "eCommerce categories"
- Customize > Activate "Colapsible category list"
- Promote > Optimize SEO > Change description > Save
Nothing happens.
Actually, an SQL error is raised because of the `ondelete='restrict'`
set at:
https://github.com/odoo/odoo/blob/897feb553e6ef75af9434cb77436b26abde3a761/odoo/addons/base/models/ir_ui_view.py#L212
In this case, we have the following structure:
```
View 1
|
---> View 2 (Website-specific)
|
---> View 3 (Website-specific)
```
For example:
```
Products
|
---> eCommerce Categories (Website-specific)
|
---> Collapsible Category List (Website-specific)
```
Since the inherited view (View 2) is website-specific, we duplicate it
and try to unlink it. However, this view has children, which raises the
error.
To solve the issue, we re-attach the children of the inherited view to
its copy. In a realistic situation, the children of a website-specific
view should also be website-specific, so there is no need to apply the
'copy or re-attach' logic recursively.
We end up with:
```
View 1 (Website-specific, duplicated)
|
---> View 2 (Website-specific, duplicated)
|
---> View 3 (Website-specific)
```
opw-1997946
closesodoo/odoo#33787
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
The goal is to be coherent with the user property.
Actually, company_id and company_ids on the environment are no fields.
Calling env.company_id returns a browse record, not an id.