def install_resources(self): jstool = getToolByName(self.context, 'portal_javascripts') for id in self.js_unregister: if self._old_res(jstool, id): jstool.unregisterResource(id) logger.info("Unregistered old %s" % (id, )) for id, compression, enabled in self.js_all: if not self._old_res(jstool, id): jstool.registerScript( id = id, enabled = enabled, cookable = True, compression = compression, ) csstool = getToolByName(self.context, 'portal_css') for css in self.css_all: if not self._old_res(csstool, css): csstool.manage_addStylesheet( id = css, rel = 'stylesheet', rendering = 'link', enabled = True, cookable = True, ) # kss stylesheets for kss in self.kss_all: if not self._old_res(csstool, kss): csstool.manage_addStylesheet(id=kss, rel='k-stylesheet', rendering = 'link', enabled=True, cookable=False, ) logger.info("Registered kss resources")
def removeBrokenCacheFu(context): portal = getToolByName(context, 'portal_url').getPortalObject() cpm = getattr(portal, 'caching_policy_manager', None) if cpm and cpm.getId() == 'broken': # If we detect a broken CacheFu install, remove it CACHEFU_IDS = [ 'CacheSetup_OFSCache', 'CacheSetup_PageCache', 'caching_policy_manager', 'HTTPCache', 'portal_cache_settings', 'portal_squid', ] cpm = aq_base(cpm) for i in CACHEFU_IDS: portal._delOb(i) objects = portal._objects portal._objects = tuple( [i for i in objects if getattr(portal, i['id'], None)]) sm = getSiteManager(context=portal) sm.unregisterUtility(component=cpm, provided=ICachingPolicyManager) del cpm transaction.savepoint(optimistic=True) manage_addCachingPolicyManager(portal) addCacheHandlers(portal) addCacheForResourceRegistry(portal) logger.info('Removed CacheSetup tools.')
def migrateMailHost(context): portal = getToolByName(context, "portal_url").getPortalObject() mh = getToolByName(portal, "MailHost", None) if mh is None: return # Migrate secure mail host and broken mail host objects meta_type = getattr(mh, "meta_type", None) if meta_type in ("Secure Mail Host", "Broken Because Product is Gone"): if meta_type == "Secure Mail Host": new_mh = MailHost( id=mh.id, title=mh.title, smtp_host=mh.smtp_host, smtp_port=mh.smtp_port, smtp_uid=mh.smtp_userid or "", smtp_pwd=mh.smtp_pass or "", force_tls=False, ) else: new_mh = MailHost(id="MailHost", smtp_host="") logger.info("Replaced a broken MailHost object.") portal._delObject("MailHost") portal._setObject("MailHost", new_mh) sm = getSiteManager(context=portal) sm.unregisterUtility(provided=IMailHost) sm.registerUtility(new_mh, provided=IMailHost)
def addReaderAndEditorRoles(context): portal = getToolByName(context, 'portal_url').getPortalObject() if 'Reader' not in portal.valid_roles(): portal._addRole('Reader') if 'Editor' not in portal.valid_roles(): portal._addRole('Editor') if 'Reader' not in portal.acl_users.portal_role_manager.listRoleIds(): portal.acl_users.portal_role_manager.addRole('Reader') if 'Editor' not in portal.acl_users.portal_role_manager.listRoleIds(): portal.acl_users.portal_role_manager.addRole('Editor') viewRoles = [ r['name'] for r in portal.rolesOfPermission('View') if r['selected'] ] modifyRoles = [ r['name'] for r in portal.rolesOfPermission('Modify portal content') if r['selected'] ] if 'Reader' not in viewRoles: viewRoles.append('Reader') portal.manage_permission('View', viewRoles, True) if 'Editor' not in modifyRoles: modifyRoles.append('Editor') portal.manage_permission('Modify portal content', modifyRoles, True) logger.info('Added reader and editor roles')
def migrateMailHost(context): portal = getToolByName(context, 'portal_url').getPortalObject() mh = getToolByName(portal, 'MailHost', None) if mh is None: return # Migrate secure mail host and broken mail host objects meta_type = getattr(mh, 'meta_type', None) if meta_type in ('Secure Mail Host', 'Broken Because Product is Gone'): if meta_type == 'Secure Mail Host': new_mh = MailHost( id=mh.id, title=mh.title, smtp_host=mh.smtp_host, smtp_port=mh.smtp_port, smtp_uid=mh.smtp_userid or '', smtp_pwd=mh.smtp_pass or '', force_tls=False, ) else: new_mh = MailHost(id='MailHost', smtp_host='') logger.info('Replaced a broken MailHost object.') portal._delObject('MailHost') portal._setObject('MailHost', new_mh) sm = getSiteManager(context=portal) sm.unregisterUtility(provided=IMailHost) sm.registerUtility(new_mh, provided=IMailHost)
def update_boolean_index(index): index_length = index._index_length if index_length is not None: return logger.info("Updating BooleanIndex `%s`." % index.getId()) index._inline_migration() logger.info("Updated BooleanIndex `%s`." % index.getId())
def addOrReplaceRamCache(context): portal = getToolByName(context, 'portal_url').getPortalObject() sm = getSiteManager(context=portal) sm.unregisterUtility(provided=OldIRAMCache) sm.unregisterUtility(provided=IRAMCache) sm.registerUtility(factory=RAMCache, provided=IRAMCache) logger.info('Installed local RAM cache utility.')
def addMissingWorkflows(context): """Add new Plone 3.0 workflows """ portal = getToolByName(context, 'portal_url').getPortalObject() wft = getToolByName(portal, 'portal_workflow', None) if wft is None: return new_workflow_ids = ['intranet_workflow', 'intranet_folder_workflow', 'one_state_workflow', 'simple_publication_workflow'] encoding = 'utf-8' path_prefix = os.path.join(package_home(cmfplone_globals), 'profiles', 'default', 'workflows') for wf_id in new_workflow_ids: if wf_id in wft.objectIds(): logger.info("Workflow %s already installed; doing nothing" % wf_id) continue path = os.path.join(path_prefix, wf_id, 'definition.xml') body = open(path, 'r').read() wft._setObject(wf_id, DCWorkflowDefinition(wf_id)) wf = wft[wf_id] wfdc = WorkflowDefinitionConfigurator(wf) (workflow_id, title, state_variable, initial_state, states, transitions, variables, worklists, permissions, scripts, description, manager_bypass, creation_guard ) = wfdc.parseWorkflowXML(body, encoding) _initDCWorkflow(wf, title, description, manager_bypass, creation_guard, state_variable, initial_state, states, transitions, variables, worklists, permissions, scripts, portal # not sure what to pass here # the site or the wft? # (does it matter at all?) ) logger.info("Added workflow %s" % wf_id)
def addCacheForKSSRegistry(context): ram_cache_id = 'ResourceRegistryCache' reg = getToolByName(context, 'portal_kss', None) if reg is not None and getattr(aq_base(reg), 'ZCacheable_setManagerId', None) is not None: reg.ZCacheable_setManagerId(ram_cache_id) reg.ZCacheable_setEnabled(1) logger.info('Associated portal_kss with %s' % ram_cache_id)
def changeAuthenticatedResourcesCondition(context): """ ResourceRegistries now has an 'authenticated' boolean property which can be used to short-circuit the expression evaluation for the simple, common case of authenticated-only resources. """ resources = { 'portal_css': ('member.css', ), 'portal_javascripts': ('dropdown.js', 'table_sorter.js', 'calendar_formfield.js', 'calendarpopup.js', 'formUnload.js', 'formsubmithelpers.js', 'unlockOnFormUnload.js')} ANON = ('not: portal/portal_membership/isAnonymousUser', 'not:portal/portal_membership/isAnonymousUser', ) for tool_id, resource_ids in resources.items(): tool = getToolByName(context, tool_id, None) if tool is None: continue for resource_id in resource_ids: resource = tool.getResource(resource_id) if resource is None: continue if resource._data['expression'] in ANON: resource.setExpression('') resource.setAuthenticated(True) tool.cookResources() logger.info('Updated expression for authenticated-only resources.')
def addObjectProvidesIndex(context): """Add the object_provides index to the portal_catalog. """ catalog = getToolByName(context, 'portal_catalog') if 'object_provides' not in catalog.indexes(): catalog.addIndex('object_provides', 'KeywordIndex') logger.info("Added object_provides index to portal_catalog")
def cleanDefaultCharset(context): portal = getToolByName(context, 'portal_url').getPortalObject() charset = portal.getProperty('default_charset', None) if charset is not None: if not charset.strip(): portal.manage_delProperties(['default_charset']) logger.info('Removed empty default_charset portal property')
def update_boolean_index(index): index_length = index._index_length if index_length is not None: return logger.info('Updating BooleanIndex `%s`.' % index.getId()) index._inline_migration() logger.info('Updated BooleanIndex `%s`.' % index.getId())
def addReaderAndEditorRoles(context): portal = getToolByName(context, 'portal_url').getPortalObject() if 'Reader' not in portal.valid_roles(): portal._addRole('Reader') if 'Editor' not in portal.valid_roles(): portal._addRole('Editor') if 'Reader' not in portal.acl_users.portal_role_manager.listRoleIds(): portal.acl_users.portal_role_manager.addRole('Reader') if 'Editor' not in portal.acl_users.portal_role_manager.listRoleIds(): portal.acl_users.portal_role_manager.addRole('Editor') viewRoles = [r['name'] for r in portal.rolesOfPermission('View') if r['selected']] modifyRoles = [r['name'] for r in portal.rolesOfPermission( 'Modify portal content') if r['selected']] if 'Reader' not in viewRoles: viewRoles.append('Reader') portal.manage_permission('View', viewRoles, True) if 'Editor' not in modifyRoles: modifyRoles.append('Editor') portal.manage_permission('Modify portal content', modifyRoles, True) logger.info('Added reader and editor roles')
def cleanupOldActions(context): portal_actions = getToolByName(context, 'portal_actions', None) if portal_actions is not None: # Remove some known unused actions from the object_tabs category and # remove the category completely if no actions are left object_tabs = getattr(portal_actions, 'object_tabs', None) if object_tabs is not None: if 'contentrules' in object_tabs.objectIds(): object_tabs._delObject('contentrules') if 'change_ownership' in object_tabs.objectIds(): object_tabs._delObject('change_ownership') if len(object_tabs.objectIds()) == 0: del object_tabs portal_actions._delObject('object_tabs') logger.info('Removed object_tabs action category.') object_ = getattr(portal_actions, 'object', None) if object_ is not None: if 'reply' in object_.objectIds(): object_._delObject('reply') user = getattr(portal_actions, 'user', None) if user is not None: if 'logged_in' in user.objectIds(): user._delObject('logged_in') if 'myworkspace' in user.objectIds(): user._delObject('myworkspace') global_ = getattr(portal_actions, 'global', None) if global_ is not None: if 'manage_members' in global_.objectIds(): global_._delObject('manage_members') if 'configPortal' in global_.objectIds(): global_._delObject('configPortal') if len(global_.objectIds()) == 0: del global_ portal_actions._delObject('global') logger.info('Removed global action category.')
def modifyKSSResourcesForDevelMode(context): # separate kukit.js and kukit-src-js based on debug mode reg = getToolByName(context, 'portal_javascripts', None) if reg is not None: id = '++resource++kukit-src.js' entry = aq_base(reg).getResourcesDict().get(id, None) if entry: pos = aq_base(reg).getResourcePosition(id) # delete kukit-src.js aq_base(reg).unregisterResource(id) # add the new ones id1 = '++resource++kukit.js' if aq_base(reg).getResourcesDict().get(id1, None): aq_base(reg).unregisterResource(id1) aq_base(reg).registerScript(id1, expression="python: not here.restrictedTraverse('@@plone_portal_state').anonymous() and here.restrictedTraverse('@@kss_devel_mode').isoff()", inline=False, enabled=True, cookable=True, compression='none', cacheable=True) id2 = '++resource++kukit-devel.js' if aq_base(reg).getResourcesDict().get(id2, None): aq_base(reg).unregisterResource(id2) aq_base(reg).registerScript(id2, expression="python: not here.restrictedTraverse('@@plone_portal_state').anonymous() and here.restrictedTraverse('@@kss_devel_mode').ison()", inline=False, enabled=True, cookable=True, compression='none', cacheable=True) # move them to where the old one has been aq_base(reg).moveResource(id1, pos) aq_base(reg).moveResource(id2, pos + 1) logger.info('Updated kss javascript resources, to enable the use ' 'of production and development versions.')
def addMissingWorkflows(context): """Add new Plone 3.0 workflows """ portal = getToolByName(context, 'portal_url').getPortalObject() wft = getToolByName(portal, 'portal_workflow', None) if wft is None: return new_workflow_ids = [ 'intranet_workflow', 'intranet_folder_workflow', 'one_state_workflow', 'simple_publication_workflow'] encoding = 'utf-8' path_prefix = os.path.join(package_home(cmfplone_globals), 'profiles', 'default', 'workflows') for wf_id in new_workflow_ids: if wf_id in wft.objectIds(): logger.info("Workflow %s already installed; doing nothing" % wf_id) continue path = os.path.join(path_prefix, wf_id, 'definition.xml') body = open(path,'r').read() wft._setObject(wf_id, DCWorkflowDefinition(wf_id)) wf = wft[wf_id] wfdc = WorkflowDefinitionConfigurator(wf) ( workflow_id , title , state_variable , initial_state , states , transitions , variables , worklists , permissions , scripts , description , manager_bypass , creation_guard ) = wfdc.parseWorkflowXML(body, encoding) _initDCWorkflow( wf , title , description , manager_bypass , creation_guard , state_variable , initial_state , states , transitions , variables , worklists , permissions , scripts , portal # not sure what to pass here # the site or the wft? # (does it matter at all?) ) logger.info("Added workflow %s" % wf_id)
def migrateHistoryTab(context): portal_actions = getToolByName(context, 'portal_actions', None) if portal_actions is not None: objects = getattr(portal_actions, 'object', None) if objects is not None: if 'rss' in objects.objectIds(): objects.manage_renameObjects(['rss'], ['history']) logger.info('Upgraded history action.')
def cleanupActionProviders(context): """Remove no longer existing action proiders.""" at = getToolByName(context, "portal_actions") for provider in at.listActionProviders(): candidate = getToolByName(context, provider, None) if candidate is None or not IActionProvider.providedBy(candidate): at.deleteActionProvider(provider) logger.info("%s is no longer an action provider" % provider)
def removeTablelessSkin(context): st = getToolByName(context, 'portal_skins') if 'Plone Tableless' in st.getSkinSelections(): st.manage_skinLayers(['Plone Tableless'], del_skin=True) logger.info("Removed the Plone Tableless skin") if st.default_skin=='Plone Tableless': st.default_skin='Plone Default' logger.info("Changed the default skin to 'Plone Default'")
def addOrReplaceRamCache(context): portal = getToolByName(context, 'portal_url').getPortalObject() sm = getSiteManager(context=portal) from zope.app.cache.interfaces.ram import IRAMCache as OldIRAMCache sm.unregisterUtility(provided=OldIRAMCache) sm.unregisterUtility(provided=IRAMCache) sm.registerUtility(factory=RAMCache, provided=IRAMCache) logger.info('Installed local RAM cache utility.')
def removeSharingAction(context): portal_types = getToolByName(context, 'portal_types', None) if portal_types is not None: for fti in portal_types.objectValues(): action_ids = [a.id for a in fti.listActions()] if 'local_roles' in action_ids: fti.deleteActions([action_ids.index('local_roles')]) logger.info('Removed explicit references to sharing action')
def updateFTII18NDomain(context): types = getToolByName(context, 'portal_types') types = types.listTypeInfo() domainless_types = [fti for fti in types if not fti.i18n_domain] for fti in domainless_types: if _check_ascii(fti.title) and _check_ascii(fti.description): fti.i18n_domain = 'plone' if domainless_types: logger.info('Updated type informations i18n domain attribute.')
def updateActionsI18NDomain(context): actions = getToolByName(context, 'portal_actions') actions = actions.listActions() domainless_actions = [a for a in actions if not a.i18n_domain] for action in domainless_actions: if _check_ascii(action.title) and _check_ascii(action.description): action.i18n_domain = 'plone' if domainless_actions: logger.info('Updated actions i18n domain attribute.')
def removeMyStuffAction(context): """The mystuff action is now covered by the dashboard""" actions = getToolByName(context, 'portal_actions') if getattr(actions, 'user', None) is None: return category=actions.user if 'mystuff' in category.objectIds(): category.manage_delObjects(ids=['mystuff']) logger.info("Removed the mystuff user action")
def fix_uuids_topic_criteria(context): catalog = getToolByName(context, "portal_catalog") search = catalog.unrestrictedSearchResults for brain in search(Type="Collection"): obj = brain.getObject() crits = [x for x in obj.contentValues() if x.getId().startswith("crit__")] for crit in crits: if getattr(crit, "_plone.uuid", None) is None: notify(ObjectCreatedEvent(crit)) logger.info("Added missing UUIDs to topic-criteria")
def updateMemberSecurity(context): portal = getToolByName(context, 'portal_url').getPortalObject() pprop = getToolByName(portal, 'portal_properties') portal.manage_permission('Add portal member', roles=['Manager','Owner'], acquire=0) pprop.site_properties.manage_changeProperties(allowAnonymousViewAbout=False) portal.manage_changeProperties(validate_email=True) pmembership = getToolByName(portal, 'portal_membership') pmembership.memberareaCreationFlag = 0 logger.info("Updated member management security")
def fix_uuids_topic_criteria(context): catalog = getToolByName(context, 'portal_catalog') search = catalog.unrestrictedSearchResults for brain in search(Type='Collection'): obj = brain.getObject() crits = [x for x in obj.contentValues( ) if x.getId().startswith('crit__')] for crit in crits: if getattr(crit, '_plone.uuid', None) is None: notify(ObjectCreatedEvent(crit)) logger.info('Added missing UUIDs to topic-criteria')
def restorePloneTool(context): portal = getToolByName(context, 'portal_url').getPortalObject() tool = getToolByName(portal, "plone_utils") if tool.meta_type == 'PlonePAS Utilities Tool': from Products.CMFPlone.PloneTool import PloneTool # PloneSite has its own security check for manage_delObjects which # breaks in the test runner. So we bypass this check. super(portal.__class__, portal).manage_delObjects(['plone_utils']) portal._setObject(PloneTool.id, PloneTool()) logger.info("Replaced obsolete PlonePAS version of plone tool " "with the normal one.")
def hidePropertiesAction(context): tt = getToolByName(context, 'portal_types', None) if not IActionProvider.providedBy(tt): return for ti in tt.listTypeInfo(): actions = ti.listActions() index=[i for i in range(len(actions) ) if actions[i].category=="object" and actions[i].id=="metadata"] if index: ti.deleteActions(index) logger.info("Removed properties action from type %s" % ti.id)
def addMissingMimeTypes(context): """ Add mime types that weren't included with the MimetypesRegistry that shipped with Plone 2.5.2 and are now required (#6695) """ # manage_addMimeType handles existing types gracefully, so we can just go # ahead and add them without testing for existing ones mtr = getToolByName(context, 'mimetypes_registry', None) if mtr is not None: mtr.manage_addMimeType('text/x-web-markdown', ['text/x-web-markdown'], ['markdown'], 'text.png') mtr.manage_addMimeType('text/x-web-textile', ['text/x-web-textile'], ['textile'], 'text.png') logger.info("Added `text/x-web-markdown` and `text/x-web-textile`.")
def addAutoGroupToPAS(context): from Products.PlonePAS.Extensions.Install import activatePluginInterfaces portal = getToolByName(context, 'portal_url').getPortalObject() sout = StringIO() if not portal.acl_users.objectIds(['Automatic Group Plugin']): from Products.PlonePAS.plugins.autogroup import manage_addAutoGroup manage_addAutoGroup(portal.acl_users, 'auto_group', 'Automatic Group Provider', 'AuthenticatedUsers', "Logged-in users (Virtual Group)") activatePluginInterfaces(portal, "auto_group", sout) logger.info("Added automatic group PAS plugin")
def cleanUpToolRegistry(context): portal = getToolByName(context, 'portal_url').getPortalObject() toolset = context.getToolsetRegistry() required = toolset._required.copy() existing = portal.keys() changed = False for name, info in required.items(): if name not in existing: del required[name] changed = True if changed: toolset._required = required logger.info('Cleaned up the toolset registry.')
def run_upgrade_dcmi_metadata(tool): """Run the upgrade_dcmi_metadata step from CMFDefault. This is only run if CMFDefault is 'installed' (importable). But in Plone 5 it may still be there as aliased module, missing the upgrade module. So we have a small wrapper around it, to avoid an ImportError on startup. """ try: from Products.CMFDefault.upgrade.to22 import upgrade_dcmi_metadata except ImportError: logger.info('Original CMFDefault DCMI upgrade step not available.') return upgrade_dcmi_metadata(tool)
def updatePASPlugins(context): from Products.PlonePAS.Extensions.Install import activatePluginInterfaces portal = getToolByName(context, 'portal_url').getPortalObject() activatePluginInterfaces(portal, 'mutable_properties') activatePluginInterfaces(portal, 'source_users') activatePluginInterfaces(portal, 'credentials_cookie_auth', disable=['ICredentialsResetPlugin', 'ICredentialsUpdatePlugin']) if not portal.acl_users.objectIds(['Plone Session Plugin']): from plone.session.plugins.session import manage_addSessionPlugin manage_addSessionPlugin(portal.acl_users, 'session') activatePluginInterfaces(portal, "session") logger.info("Added Plone Session Plugin.")
def addOnFormUnloadJS(context): """ add the form unload JS to the js registry """ jsreg = getToolByName(context, 'portal_javascripts', None) script = 'unlockOnFormUnload.js' if jsreg is not None: script_ids = jsreg.getResourceIds() # Failsafe: first make sure the stylesheet doesn't exist in the list if script not in script_ids: jsreg.registerScript(script, enabled=True, cookable=True) # put it at the bottom of the stack jsreg.moveResourceToBottom(script) logger.info("Added " + script + " to portal_javascripts")
def convertLegacyPortlets(context): """Convert portlets defined in left_slots and right_slots at the portal root to use plone.portlets. Also block portlets in the Members folder. Note - there may be other portlets defined elsewhere. These will require manual upgrade from the @@manage-portlets view. This is to avoid a full walk of the portal (i.e. waking up every single object) looking for potential left_slots/right_slots! """ portal = getToolByName(context, 'portal_url').getPortalObject() convert_legacy_portlets(portal) logger.info('Converted legacy portlets at the portal root') logger.info('NOTE: You may need to convert other portlets manually.') logger.info(' - to do so, click "manage portlets" in the relevant folder.') members = getattr(portal, 'Members', None) if members is not None: membersRightSlots = getattr(aq_base(members), 'right_slots', None) if membersRightSlots == []: rightColumn = getUtility( IPortletManager, name=u'plone.rightcolumn', context=portal) portletAssignments = getMultiAdapter( (members, rightColumn,), ILocalPortletAssignmentManager) portletAssignments.setBlacklistStatus(CONTEXT_PORTLETS, True) logger.info( 'Blacklisted contextual portlets in the Members folder')
def convertLegacyPortlets(context): """Convert portlets defined in left_slots and right_slots at the portal root to use plone.portlets. Also block portlets in the Members folder. Note - there may be other portlets defined elsewhere. These will require manual upgrade from the @@manage-portlets view. This is to avoid a full walk of the portal (i.e. waking up every single object) looking for potential left_slots/right_slots! """ portal = getToolByName(context, 'portal_url').getPortalObject() convert_legacy_portlets(portal) logger.info('Converted legacy portlets at the portal root') logger.info('NOTE: You may need to convert other portlets manually.') logger.info(' - to do so, click "manage portlets" in the relevant folder.') members = getattr(portal, 'Members', None) if members is not None: membersRightSlots = getattr(aq_base(members), 'right_slots', None) if membersRightSlots == []: rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=portal) portletAssignments = getMultiAdapter(( members, rightColumn, ), ILocalPortletAssignmentManager) portletAssignments.setBlacklistStatus(CONTEXT_PORTLETS, True) logger.info( 'Blacklisted contextual portlets in the Members folder')
def migrate_portlets_for_object(obj, path): portlet_managers = getUtilitiesFor(IPortletManager, context=obj) for portlet_manager_name, portlet_manager in portlet_managers: assignments = queryMultiAdapter( (obj, portlet_manager), IPortletAssignmentMapping, context=obj) if assignments is None: continue for portlet_id, portlet in assignments.items(): if IStaticPortlet.providedBy(portlet) and \ getattr(portlet, 'hide', False): logger.info( 'Found hidden static text portlet %s at %s' % (portlet_id, path)) settings = IPortletAssignmentSettings(portlet) settings['visible'] = False
def changeWorkflowActorVariableExpression(context): wftool = getToolByName(context, 'portal_workflow') workflows = ('intranet_folder_workflow', 'one_state_workflow', 'simple_publication_workflow') for workflow_id in workflows: wf = getattr(wftool, workflow_id, None) if wf is None: continue actor_var = wf.variables._getOb('actor', None) if actor_var is None: continue actor_var.setProperties(description=actor_var.description, default_expr='user/getId', for_status=1, update_always=1) logger.info('Updated workflow actor variable expression.')