From 8167a837f38d3deff02c5f7853a4ddd2bf979df4 Mon Sep 17 00:00:00 2001 From: Leonardo Rochael Almeida <leonardo@nexedi.com> Date: Wed, 12 May 2010 18:22:53 +0000 Subject: [PATCH] Automatic migration of actions from non-IActionProviders to portal_actions on Zope 2.12 git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@35280 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Type/patches/ActionsTool.py | 52 ++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/product/ERP5Type/patches/ActionsTool.py b/product/ERP5Type/patches/ActionsTool.py index 679e266f9a..7962831502 100644 --- a/product/ERP5Type/patches/ActionsTool.py +++ b/product/ERP5Type/patches/ActionsTool.py @@ -12,6 +12,12 @@ # ############################################################################## +import logging +import transaction +from Acquisition import aq_parent + +logger = logging.getLogger(__name__) + from Products.CMFCore.ActionsTool import ActionsTool try: from Products.CMFCore.interfaces import IActionProvider @@ -21,6 +27,36 @@ except ImportError: from Products.CMFCore.ActionsTool import IActionProvider IActionProvider_providedBy = IActionProvider.isImplementedBy +def migrateNonProviders(portal_actions): + portal_actions_path = '/'.join(portal_actions.getPhysicalPath()) + root = portal_actions.getPhysicalRoot() + # Discard all changes so far, we'll restart the request later so no changes + # are lost. + root._p_jar.sync() + txn = transaction.get() + + portal_actions = root.unrestrictedTraverse(portal_actions_path) + portal = aq_parent(portal_actions) + action_providers = list(portal_actions.action_providers) + for provider_name in portal_actions.listActionProviders(): + provider = getattr(portal, provider_name) + if ( getattr(provider, '_actions', ()) and + getattr(provider, 'listActionInfos', None) is None ): + msg = ('migrating actions from %r to %r' % + (portal_actions_path, '/'.join(provider.getPhysicalPath()))) + logger.warning(msg) + txn.note(msg) + portal_actions._actions += provider._actions + del provider._actions + action_providers.remove(provider_name) + portal_actions.action_providers = tuple(action_providers) + + txn.note('Migrated actions from non IActionProviders to portal_actions') + txn.commit() + # restart the transaction with actions already migrated + from ZODB.POSException import ConflictError + raise ConflictError('Action Migration Completed, please restart request.') + ActionsTool_listFilteredActionsFor = ActionsTool.listFilteredActionsFor def listFilteredActionsFor(self, object=None): @@ -28,6 +64,13 @@ def listFilteredActionsFor(self, object=None): This patch removes inclusion of actions from the object itself. It was never used and now, it breaks objects inside Types Tool. + + It also checks for a new ERP5-only actions API (getActionListFor), but + this API should be moved to listActionInfos() of each tool so as not to + create duplicate code paths that are sources of bugs. + + Finally, this patch detects tools that are no longer action providers and + invokes the migration of their actions to portal_actions """ actions = [] @@ -42,9 +85,16 @@ def listFilteredActionsFor(self, object=None): if action.test(ec)) elif IActionProvider_providedBy(provider): actions.extend( provider.listActionInfos(object=object) ) - else: + elif getattr(provider, '_listActionInfos', None) is not None: + # BACK: drop this clause and the 'else' clause below when we + # drop CMF 1.5 + # for Action Providers written for CMF versions before 1.5 actions.extend( self._listActionInfos(provider, object) ) + else: + # We're in 2.12 and we need to migrate objects that are no longer + # IActionProviders: + migrateNonProviders(self) # Reorganize the actions by category. filtered_actions={'user':[], -- 2.30.9