Commit 52701d37 authored by Arnaud Fontaine's avatar Arnaud Fontaine

ERP5Workflow: Move StateChangeInfo from DCWorkflow.Expression to ERP5Workflow.

This reduces dependency on DCWorkflow and cleanup StateChangeInfo monkey patch.
parent 9e26d2aa
Pipeline #27221 running with stage
...@@ -222,8 +222,7 @@ def execute(self, document, form_kw=None): ...@@ -222,8 +222,7 @@ def execute(self, document, form_kw=None):
expression = variable.getVariableDefaultExpressionInstance() expression = variable.getVariableDefaultExpressionInstance()
if expression is not None: if expression is not None:
if expression_context is None: if expression_context is None:
from Products.ERP5Type.Core.Workflow import createExpressionContext from Products.ERP5Type.Core.Workflow import createExpressionContext, StateChangeInfo
from Products.DCWorkflow.Expression import StateChangeInfo
expression_context = createExpressionContext(StateChangeInfo(document, self, status_dict)) expression_context = createExpressionContext(StateChangeInfo(document, self, status_dict))
status_dict[variable_title] = expression(expression_context) status_dict[variable_title] = expression(expression_context)
......
...@@ -34,12 +34,11 @@ from Acquisition import aq_base ...@@ -34,12 +34,11 @@ from Acquisition import aq_base
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
from Products.DCWorkflow.Transitions import TRIGGER_WORKFLOW_METHOD from Products.DCWorkflow.Transitions import TRIGGER_WORKFLOW_METHOD
from Products.DCWorkflow.Expression import StateChangeInfo
from Products.ERP5Type.Workflow import addWorkflowFactory from Products.ERP5Type.Workflow import addWorkflowFactory
from Products.CMFActivity.ActiveObject import ActiveObject from Products.CMFActivity.ActiveObject import ActiveObject
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.Core.Workflow import createExpressionContext from Products.ERP5Type.Core.Workflow import createExpressionContext, StateChangeInfo
_MARKER = [] _MARKER = []
......
...@@ -67,6 +67,106 @@ def createExpressionContext(sci): ...@@ -67,6 +67,106 @@ def createExpressionContext(sci):
data['scripts'] = wf.scripts data['scripts'] = wf.scripts
return getEngine().getContext(data) return getEngine().getContext(data)
from MultiMapping import MultiMapping
class SafeMapping(MultiMapping):
"""
Mapping with security declarations and limited method exposure.
Since it subclasses MultiMapping, this class can be used to wrap
one or more mapping objects. Restricted Python code will not be
able to mutate the SafeMapping or the wrapped mappings, but will be
able to read any value.
Imported from Products.DCWorkflow.Expression
"""
__allow_access_to_unprotected_subobjects__ = 1
push = pop = None
_push = MultiMapping.push
_pop = MultiMapping.pop
from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.WorkflowCore import ObjectDeleted, ObjectMoved
from AccessControl import ClassSecurityInfo
class StateChangeInfo(object):
"""
Provides information for expressions and scripts.
Imported from Products.DCWorkflow.Expression
"""
_date = None
ObjectDeleted = ObjectDeleted
ObjectMoved = ObjectMoved
security = ClassSecurityInfo()
security.setDefaultAccess('allow')
def __init__(self, object, workflow, status=None, transition=None,
old_state=None, new_state=None, kwargs=None):
if kwargs is None:
kwargs = {}
else:
# Don't allow mutation
kwargs = SafeMapping(kwargs)
if status is None:
tool = aq_parent(aq_inner(workflow))
status = tool.getStatusOf(workflow.id, object)
if status is None:
status = {}
if status:
# Don't allow mutation
status = SafeMapping(status)
self.object = object
self.workflow = workflow
self.old_state = old_state
self.new_state = new_state
self.transition = transition
self.status = status
self.kwargs = kwargs
def __getitem__(self, name):
if name[:1] != '_' and hasattr(self, name):
return getattr(self, name)
raise KeyError(name)
def getHistory(self):
wf = self.workflow
tool = aq_parent(aq_inner(wf))
wf_id = wf.id
h = tool.getHistoryOf(wf_id, self.object)
if h:
return [d.copy() for d in h] # Don't allow mutation
else:
return ()
def getPortal(self):
ob = aq_inner(self.object)
while ob is not None:
if ISiteRoot.providedBy(ob):
return ob
ob = aq_parent(ob)
return None
def getDateTime(self):
date = self._date
if not date:
date = self._date = DateTime()
return date
def setWorkflowVariable(self, **kw):
"""
Allows to go through security checking and let a script allows to modify
a workflow variable
"""
history = self.object.workflow_history[self.workflow.getReference()]
history[-1].update(kw)
history._p_changed = 1
from Products.ERP5Type.Globals import InitializeClass
InitializeClass(StateChangeInfo)
from Products.PythonScripts.Utility import allow_class
allow_class(StateChangeInfo)
from Products.ERP5Type import WITH_LEGACY_WORKFLOW from Products.ERP5Type import WITH_LEGACY_WORKFLOW
if WITH_LEGACY_WORKFLOW: if WITH_LEGACY_WORKFLOW:
## Patch for ERP5 Workflow: This must go before any Products.DCWorkflow ## Patch for ERP5 Workflow: This must go before any Products.DCWorkflow
...@@ -81,7 +181,6 @@ if WITH_LEGACY_WORKFLOW: ...@@ -81,7 +181,6 @@ if WITH_LEGACY_WORKFLOW:
import sys import sys
from collections import defaultdict from collections import defaultdict
from AccessControl import ClassSecurityInfo
from AccessControl.unauthorized import Unauthorized from AccessControl.unauthorized import Unauthorized
from AccessControl.Permission import Permission from AccessControl.Permission import Permission
from Acquisition import aq_base from Acquisition import aq_base
...@@ -89,13 +188,11 @@ from copy import deepcopy ...@@ -89,13 +188,11 @@ from copy import deepcopy
from DateTime import DateTime from DateTime import DateTime
from DocumentTemplate.DT_Util import TemplateDict from DocumentTemplate.DT_Util import TemplateDict
from Products.CMFCore.Expression import Expression from Products.CMFCore.Expression import Expression
from Products.CMFCore.WorkflowCore import WorkflowException, ObjectDeleted,\ from Products.CMFCore.WorkflowCore import WorkflowException
ObjectMoved
from Products.DCWorkflow.Expression import StateChangeInfo
from Products.DCWorkflow.utils import Message as _ from Products.DCWorkflow.utils import Message as _
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Cache import CachingMethod from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type.Globals import PersistentMapping, InitializeClass from Products.ERP5Type.Globals import PersistentMapping
from Products.ERP5Type.Utils import convertToMixedCase from Products.ERP5Type.Utils import convertToMixedCase
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.Core.WorkflowTransition import (TRIGGER_AUTOMATIC, from Products.ERP5Type.Core.WorkflowTransition import (TRIGGER_AUTOMATIC,
......
...@@ -64,7 +64,8 @@ from Products.ERP5Type.patches import DateTimePatch ...@@ -64,7 +64,8 @@ from Products.ERP5Type.patches import DateTimePatch
from Products.ERP5Type.patches import PythonScript from Products.ERP5Type.patches import PythonScript
from Products.ERP5Type.patches import MailHost from Products.ERP5Type.patches import MailHost
from Products.ERP5Type.patches import memcache_client from Products.ERP5Type.patches import memcache_client
from Products.ERP5Type.patches import StateChangeInfoPatch if WITH_LEGACY_WORKFLOW:
from Products.ERP5Type.patches import StateChangeInfoPatch
from Products.ERP5Type.patches import transforms from Products.ERP5Type.patches import transforms
from Products.ERP5Type.patches import OFSPdata from Products.ERP5Type.patches import OFSPdata
from Products.ERP5Type.patches import DemoStorage from Products.ERP5Type.patches import DemoStorage
......
...@@ -19,9 +19,8 @@ from Products.ERP5Type import Permissions ...@@ -19,9 +19,8 @@ from Products.ERP5Type import Permissions
from Acquisition import aq_base from Acquisition import aq_base
from Products.CMFCore.utils import _checkPermission from Products.CMFCore.utils import _checkPermission
from Products.DCWorkflow.Expression import StateChangeInfo
from Products.ERP5Type.Globals import InitializeClass from Products.ERP5Type.Globals import InitializeClass
from Products.ERP5Type.Core.Workflow import createExpressionContext from Products.ERP5Type.Core.Workflow import createExpressionContext, StateChangeInfo
class GuardableMixin(ExpressionMixin('guard_expression')): class GuardableMixin(ExpressionMixin('guard_expression')):
""" """
......
...@@ -18,12 +18,12 @@ assert WITH_LEGACY_WORKFLOW ...@@ -18,12 +18,12 @@ assert WITH_LEGACY_WORKFLOW
## ERP5 Workflow: This must go before any Products.DCWorkflow imports as this ## ERP5 Workflow: This must go before any Products.DCWorkflow imports as this
## patch createExprContext() from-imported in several of its modules ## patch createExprContext() from-imported in several of its modules
from Products.ERP5Type.Core.Workflow import createExpressionContext from Products.ERP5Type.Core.Workflow import createExpressionContext, StateChangeInfo
# Optimized rendering of global actions (cache) # Optimized rendering of global actions (cache)
from Products.ERP5Type.Globals import DTMLFile from Products.ERP5Type.Globals import DTMLFile
from Products.ERP5Type import Permissions, _dtmldir from Products.ERP5Type import Permissions, _dtmldir
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition, StateChangeInfo from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
from Acquisition import aq_inner, aq_parent from Acquisition import aq_inner, aq_parent
from Products.DCWorkflow.DCWorkflow import ObjectDeleted, ObjectMoved from Products.DCWorkflow.DCWorkflow import ObjectDeleted, ObjectMoved
from Products.DCWorkflow import DCWorkflow from Products.DCWorkflow import DCWorkflow
......
...@@ -27,19 +27,12 @@ ...@@ -27,19 +27,12 @@
############################################################################## ##############################################################################
from Products.ERP5Type import WITH_LEGACY_WORKFLOW from Products.ERP5Type import WITH_LEGACY_WORKFLOW
assert WITH_LEGACY_WORKFLOW
from Products.DCWorkflow.Expression import StateChangeInfo from Products.DCWorkflow.Expression import StateChangeInfo as DCWorkflowStateChangeInfo
from Products.PythonScripts.Utility import allow_class from Products.ERP5Type.Core.Workflow import StateChangeInfo
allow_class(StateChangeInfo)
def setWorkflowVariable(self, **kw):
"""
Allows to go through security checking and let a
script allows to modify a workflow variable
"""
history = self.object.workflow_history[self.workflow.getReference()]
history[-1].update(kw)
history._p_changed = 1
StateChangeInfo.setWorkflowVariable = setWorkflowVariable from Products.PythonScripts.Utility import allow_class
allow_class(DCWorkflowStateChangeInfo)
DCWorkflowStateChangeInfo.setWorkflowVariable = StateChangeInfo.setWorkflowVariable
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment