Before this commit:
The `if` condition doing a `View._views_get` was supposed to be a sort of
'hack' for when the error occured in a child view (as the template raised would
be the parent, not the broken child).
But since we refactored that part to use etree, it was actually going into that
condition for every error even if the error was in the called template.
Proof is, we only set `editable` in that if condition, meaning going in the
else would actually prevent to show reset template.
Indeed the following code would always be true:
et = etree.fromstring(view.with_context(inherit_branding=False).read_combined(['arch'])['arch'])
node = et.find(exception.path.replace('/templates/t/', './'))
as read_combined returns all the view hierarchy DOM
Note: We could not fix this by checking exception.path against `arch` as we
could have false positive (eg the child view replace the <p> element by another
<p> element which is broken, then the path would be found in the parent view
even if the error was in the child view).
closesodoo/odoo#31515
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Commit 5a81d8883 fixed the COW view deletion on module update but introduced an
error when installing a theme.
Indeed, when installing a theme, the first step is to remove the currently
installed theme from the website (by unlinking its ir.ui.view).
Commit 5a81d8883 introduced the fact that deleting an ir.ui.view during a
module uninstall also search and delete the COW views, calling
`_get_specific_views` (that expects a singleton).
When installing a theme, it calls `_theme_cleanup` which search COW views and
unlink them. If not cow view, unlink is called with an empty record set raising
the singleton error.
closesodoo/odoo#31662
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Before this commit, when a view was removed during a module update (eg: the
record was deleted from the file), its COW views would not be deleted.
This could lead to unwanted behaviors including tracebacks(1).
This commit is somehow related/an extension of b5fe23055d that handle COW view
write during module update and 2e32cc5aa3 that remove COW views during module
uninstall.
task-1931683
Note: Some existing tests had to be run post install
(1) A view doing a t-call is COW'd, then that view and its t-called view are
removed. If the cow view is not removed, the t-call will crash (see tests
in this commit for detailed case).
closesodoo/odoo#31295
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Purpose
=======
The "publish/unpublish" widget is always shown on the frontend as long as the user
is a website_publisher and the object has a "website_published" field.
In some modules (namely website_slides) we need to handle a more refined level of access.
This commit adds a "can_publish" computed field that can be overridden to add some additional
access rules to the object and hide the widget if the user doesn't have the rights to
publish/unpublish.
- When a record has `website_published` field set at True the method
`binary_content` on `ir.http` should bypass the access rules and
always deserve the content.
This wasn't the case due to a mistake on the code. The code is
checking the access rules and may in some cases not return the
content.
closesodoo/odoo#31068
* web_editor
This commit's goal is to optimize the delay to make a scss customization
thanks to the website customize dialog. Before this commit, the JS code
took advantage of existing web_editor routes but this was far from
efficient as this was done:
1) PY: Load all scss files used in the page
2) JS: Find the one we want to customize and adapt the scss content
3) PY: Create the scss customization with the new content
(So two RPC (including one very slow) and content building in
javascript)
After this commit, this is done:
1) PY: Load the scss file being customized, adapt its content according
to the new values and save the customization
(So the whole logic is in python, requiring only one small RPC)
This commit also take the opportunity to review the web_editor ace
editor loading code (the logic is shared with website customizations).
PR https://github.com/odoo/odoo/pull/29624
task-1904244
Next commit will change that file to make it extend a web_editor model
instead of a web_editor controller. This commit only moves the file.
PR https://github.com/odoo/odoo/pull/29624
task-1904244
Since AST was introduced to compile Qweb templates, the reset templates
functionality is not working anymore.
Actually, it does not even appear anymore as the conditions to trigger and show
the reset view behavior can't be True anymore.
Indeed, the code is still importing the old QWebException from odoo.exceptions
which is now just an empty class.
The QWebException that should now be used is the one from odoo.base.models.qweb
More than just a wrong import, the QWebException properties have completely
changed.
Since its last working version (Odoo 9.0), a lot of changes occured, mostly:
- Odoo 11.0: new model website.page, which completely changed the pages
behavior and changed the models.
- Odoo 12.0: multi-website, which introduced the Copy On Write (COW) that
redefined how we write on view in a website context. We now need to reset
copied/specific views that have no model_data_id.
This fix is for a stable version. There is some flows that can't be fixed
without a refactoring or new fields (mainly because of the arch_fs being
erased when writing on `arch`, plus we can't introduce a module reload in
stable).
The goal of this commit is to fix the basic and standard case of broken views,
which is when non-technical users are breaking the views through HTML editor.
To reset the views, we will read the original arch in the XML file, as the
dev mode is doing.
To be eligible for the reset, the broken view need an `arch_fs` set. If the
view arch has been modified anywhere else than the frontend, the `arch_fs`
will be erased and the view wont be able to be reset.
As the broken views will be specific views, we will simply read the generic
view in the XML file and write it on the specific. We can't simply remove the
specific view as we might be on a specific tree.
Specific case, in case of custom views create dropping a snippet in an oe_struc
we just delete this inehrited view to allow end user to have their page back.
In some case of bad compilation in sub template, we try to guess which inherited
view, t-called view is broken by string matching based on 'last_path_node' xpath.
Add new module test_website to add tests, it will be usefull for futur test of
install/uninstall and ...
Todo in master:
- try to track on QWebException the real template that is broken and not only
the last node from the main template.
Co-authored-by: "Romain Derie <rde@odoo.com>"
Co-authored-by: "Jérémy Kersten <jke@openerp.com>"
closesodoo/odoo#29957
Once `website` module is installed, the `save` method will always write on the
specific view or create it if it does not exist yet.
This means that actually, the generic view will never have his `arch` modified
through the `save` method.
Thus, there is no need to flag it as noupdate as we want to receive update for
that view (that might be used by other website without a specific view).
Before this commit, the website selection was not working when a scheme or port
was encoded in the domain field. This was not obvious or natural for the user,
because the easiest way to fill it was to copy/paste the URL from the browser.
Now it works when scheme or port are encoded, it is even strongly recommended to
actually encode them if they don't take a default value because they will be
used when creating full URL to the website (typically when sending emails to
clients where a link back is necessary).
PR: #30000
* = base, auth_signup, mail, portal, sale, website, website_sale
Before this commit, sending an object by email would always link to web.base.url
even if the object was created from a specific website.
Now if the object has a website, we use the URL of that website if it is set.
The fallback will always be on the web.base.url.
opw-1921030
PR: #30000
Before this commit, if the first website in the select was not in your current
company, it raises a traceback.
Now with filter on your own company, and support empty website selected
removing required on related field and using attrs dynamic to make it required
closesodoo/odoo#30769
Before this commit, if you duplicate a published record on the website,
the copy was already published, while in most of case you need to update
it to adapt to the new content. There doesn't make senses to duplicate the
same content on a website and let the duplicate content.
Task-1930058
Since multi-website, we COW (copy on write) views when editing a view on a
website.
This is causing 2 issues related to module install/update:
1. During a module install, when creating an inherited view, it will create
that view as expected on the generic tree.
But that generic tree may not be used on website(s). Indeed, if the view
was edited, we are now using a copy of the view instead of the original
XML view (with an xml_id).
That copied view won't get the new inherited view in its view tree.
Now, we correctly copy the new view under every specific view tree (if
exists).
2. During a module update, when updating a view, it will only update the view
having the xml_id, so the generic one.
But most of the time, the generic view is not used as it was usually COW'd
and the specific view now replace the generic one.
Now, we also apply the update on the COW'd view. Note that only unmodified
field will be updated, this behavior basically mimic the noupdate behavior
on view's ir.model.data.
Step to reproduce for bug 1:
- Install website_sale module
- Go to a product page and then enter edit mode
- Make a modification to trigger COW, eg edit the information area under the
price "30-day money-back guarantee".
- Now install website_sale_comparison module
- The product page won't have the comparison button as the comparison view
inheriting the product view was created on the generic tree and not copied
on the specific tree (COW'd before the comparison module install).
Step to reproduce for bug 2:
- Repeat first 3 steps of bug 1
- Now make a modification in a view from the XML file in
website_sale_comparison module and update the module
- Only the view with the xml_id is updated, not it's COW'd views. This mean
that only the generic view is updated and not the specific one(s) really
used on the website.
task-1920487
closesodoo/odoo#29956
Before this commit, a generic view tree could be valid but impossible to copy
on a COW specific tree.
This was because when looping through inherit_children_ids to copy them, they
would be sorted by the ir.ui.view sort order (name, priority, id).
Indeed, when applying view inheritance and reading a view arch, children are
sorted by (priority, id).
Thus, if sorting the children by (name, priority, id) was different than
sorting by (priority, id) and the children view would conflict in that new
order, the COW would raise an error "can't find DOM element"
Step to reproduce:
- Create a parent view with just a DIV in arch
- Add a child view that add something inside that DIV
- Add another child view with a name alphabetically lower than the other
child and that replace the DIV by something else, like a SECTION
- Everything works as expected, when reading the parent view arch, the first
child is inserting something into the DIV and then the second is replacing
the DIV
- Now try to trigger the COW on the parent view by writing something on it in
a website context
- It will crash as the child views will be copied in another order, sorted
firstly by name.
- Indeed, when reading parent view, the second child will be copied first as
it's name is lower than the first, it will then replace the DIV by a SPAN.
When trying to copy the other child view that is supposed to insert
something into the DIV, the DIV will not be found and it will crash.
Commit 68e9d5504c makes the redirection type mandatory, which is
logical. Since we can't add such a constraint in stable, we make the
field required in the view and assign a default value (in case the
module is not upgraded, which is very likely to be the case).
opw-1924983
closesodoo/odoo#30252
`ref` could raise even if raise_if_not_found was False on `viewref`, now we
prevent that, and rely only on the exception on `viewref`.
Also, when not set to raise, the method could return None instead of a recorset.
PR: #29753
Fine-tuning of commit b48d2b6b5e.
The call to unlink inside the unlink can recurse infinitely
in case there is a copy of a menu.
We replace that direct call by an accumulator so no recursion occurs.
opw 1922448closesodoo/odoo#30032
*: tools, web, website, website_forum, mail, im_livechat
This commit refactors ir_http to make it more readable
and flexible.
Move the resize function of web/image to odoo.tools
Co-authored-by: XavierDo <xdo@odoo.com>
Co-authored-by: Antony Lesuisse <al@openerp.com>
closes: #28563
task: #1908896
Before this comit:
The `_views_get()` method would be called recursively for every
`inherit_children_ids`.
At the end of the method, we would get the complete view hierarchy, including
duplicate hierarchies for website specific copies (COW).
Then, the `get_related_views` that is calling `_views_get()` would be overriden
in website module to keep only most specific views.
But this would not be enough as it would leave orphans from other trees:
- Have a base view 'B'
- That has an inherited view 'I'
- That has itself an inherited view 'II'
- Now make the hierarchy specific on a website from 'I'
- And add another inherited view to 'I' on the generic tree
This become:
B
/ \
/ \
I I'
/ \ |
II II2 II'
As explained, filtering duplicates would not be enough as it would correctly
remove 'I' and 'II' from the generic tree but would not remove 'II2'.
At the end, it would return "B", "II2", "I'" and "II'".
Now, we correctly return only "B", "I'" and "II'" by ignoring generic trees
when there is a specific one.
Closes#29347
In a particular case, `_views_get` was mixing apples and oranges, ir.ui.view
and theme.ir.ui.view.
This was the case if a theme has a theme.ir.ui.view t-calling another
theme.ir.ui.view.
(Only theme's sale bridge cause this issue, eg theme_kea_sale.products)
Then, having that theme installed on a website would make all other website
without that theme to crash when opening the /shop customize menu.
Indeed, the theme.ir.ui.view would have the xml_id theme_kea_sale.search.
The generic view `website_sale.products` would have `theme_kea_sale.products`
as inherit child which is website specific and t-call `theme_kea_sale.search`.
Then, on a website witout theme_kea installed, opening the customize menu would
call `get_related_views` that would call `_views_get` that would loop through
inherit children calling `_view_obj` that would not find a view with that key
and would fallback on self.env.ref, finding the theme.ir.ui.view.
Note: `_views_get` might return specific view for another website but that will
be filtered on `get_related_views` override in website.
Step to reproduce:
- Have at least 2 websites and website_sale installed
- Install theme_kea on a website, it will also install theme_kea_sale
- Go on the website that has not theme_kea installed
- Go to /shop
- Open Customize menu, it won't load because of python crash
opw-1914576
Closes#29347
Before this commit, everyone could use the `fw` query string to force a
website during the dispatching. Plus, it would not require multi-website to be
enabled (multi-website only display UI elements, it does not affect behaviors
as they are already triggered even if multi-website is disabled).
This was intended but caused an issue for public users.
Indeed, the code that would force a website during the http dispatching would
be executed in `_add_dispatch_parameters`, after the auth methods.
Then, the request.uid would be the one from the website we were leaving and not
the one of the website we are forcing.
Public user would then not be recognized as such (if both websites have their
own public user) and would have interface glitchs (considered as connected).
Note: Next reload or page navigation would set the request.uid correctly.
Now:
To avoid such a behavior, we decided to allow only designer user to be able to
switch website with the `fw` query string, and only if multi-website is
enabled.
Note: The designer group check is done on the leaving website and not the
forcing one as `_add_dispatch_parameters` is executed after auth methods.
There is no way to check with which user the user will be logged on the
forcing website (Public, Same user, different user?).
Also, it would have to handle the same domain/different domain.
Step to reproduce:
- Activate multi-website
- Activate multi-company
- Create SiteA and SiteB
- Create CompanyA and CompanyB
- Set CompanyA on SiteA and CompanyB on SiteB
- A new public user will be bootstraped for CompanyB
- Optionnaly, setting manually a different public user for CompanyB will do
the same.
- Go to website 1, request.uid is PubUserA and request.website is SiteA
- Navigate to website 2 with `?fw=2` in URL, request.uid will be PubUserA and
request.website will be SiteB.
This is wrong, request.uid should be PubUserB as we are on SiteB
This will result in multiple bug, mainly the non logged user will see the
dropdown in the navbar as if they were logged in showing 'PubUserA'.
Fixes#27998closesodoo/odoo#29136
This commit replaces calls to pycompat helpers that were intended for
python 2 <-> python 3 interoperability for python 3 builtins, as python
2 is no longer officially supported by Odoo.
This includes:
* calls to imap/izip/ifilter replaced by map/zip/filter
* uses of text_type replaced by str
* uses of unichr replaced by chr
* calls to implements_to_string, implements_iterator removed
* string_types and integer_types replaced by str, int respectively
* calls to to_native replaced by calls to to_text
This is done in preparation to the removal of these deprecated helpers
in the following commit.
This commit only re-indents the COW feature code and adds comments to
help understand its tricky parts. Also evaluate the 'no_cow' flag only
once per write.
closesodoo/odoo#28753