plone / plone.app.portlets

provides a Plone-specific user interface for plone.portlets, as well as a standard set of portlets that ship with Plone
12 stars 26 forks source link

"root -> root_uid" migration code buggy (at least for the `INavigation` portlet) #138

Open d-maurer opened 4 years ago

d-maurer commented 4 years ago

plone.app.portlets.portlets.navigation.Assignment used to following code to migrate from the old toot field to the new root_uid field:

    def _root(self):
        # This is only called if the instance doesn't have a root_uid
        # attribute, which is probably because it has an old 'root'
        # attribute that needs to be converted.
        root = self.root
        if not root:
            return None
        portal = getToolByName(self, 'portal_url').getPortalObject()
        navroot = getNavigationRootObject(self, portal)
        try:
            root = navroot.unrestrictedTraverse(root.lstrip('/'))
        except (AttributeError, KeyError, TypeError, NotFound):
            return
        return root.UID()
    root_uid = ComputedAttribute(_root, 1)

This code fails (to determine the correct root) because getNavigationRootObject returns the portlet assignemt mapping (the parent of the portlet assignment) and nothing fit to perform a tracersal.

d-maurer commented 4 years ago

In addition: when the Assignment is retrieved by the PortletManagerRetriever, it is not acquisition wrapped. ComputedAttribute(..., 1) requires at least one level of acquisition wrapping to work. This implies that the migration code does not work at all during normal operation.

aadarsh-nagrath commented 1 year ago

I think using the getNavigationRoot function instead of getNavigationRootObject could work. The getNavigationRoot function returns the navigation root object, whereas getNavigationRootObject returns the portlet assignment mapping. Also we could try wrapping the assignment in an acquisition wrapper before passing it to the ComputedAttribute function