Interactor classes are a good practice to encapsulate related interactions in
system at a central location. They are the equivalent for classes of what
interaction_worfklows do for portal types.
Interactor classes should never be used unless there is absolutely no way to use interaction workflows instead.
Table of Contents
Example¶
from Products.ERP5Type.Interactor.Interactor import Interactor
class FieldValueCacheInteractor(Interactor):
def install(self):
"""
Installs interactions
"""
from Products.Formulator.Field import ZMIField
from Products.ERP5Form.ProxyField import ProxyField
from Products.Formulator.Form import ZMIForm
self.on(ZMIField.manage_edit).doAfter(self.purgeFieldValueCache)
self.on(ZMIField.manage_edit_xmlrpc).doAfter(self.purgeFieldValueCache)
self.on(ZMIField.manage_tales).doAfter(self.purgeFieldValueCache)
self.on(ZMIField.manage_tales_xmlrpc).doAfter(self.purgeFieldValueCache)
self.on(ProxyField.manage_edit).doAfter(self.purgeFieldValueCache)
self.on(ProxyField.manage_edit_target).doAfter(self.purgeFieldValueCache)
self.on(ProxyField.manage_tales).doAfter(self.purgeFieldValueCache)
self.on(ZMIForm.manage_renameObject).doAfter(self.purgeFieldValueCache)
def purgeFieldValueCache(self, method_call_object):
"""
Interaction method (defined at the Interactor level).
Make sure all field value caches are purged
"""
from Products.ERP5Form import Form, ProxyField
Form.purgeFieldValueCache()
ProxyField.purgeFieldValueCache()
The install method lists all cases of methods which must be considered to trigger
the interaction. Each method is defined in an argument of the on method. The
following line:
self.on(ZMIForm.manage_renameObject)
places a trigger on the ZMIForm.manage_renameObject method.
Then the following expression:
.doAfter(self.purgeFieldValueCache)
tells that the trigger which has just been define should call purgeFieldValueCache on the interactor.
Accessing call context¶
Whenever an interaction method is called, such as purgeFieldValueCache, it is
provided with a parameter called method_call_object which is an instance of
InteractorMethodCall class.
This parameter gives access to all parameters which have been provided to the
trigerred method.
Example¶s of Interactors
Type based interaction. This shows that it is possible to create interactions
based on the portal type of the instance is is called on. This is not recommended
though (use interaction workflows instead). However, the same idea could be
applied to other properties of the instance.
class TypeInteractorExample(Interactor):
def __init__(self, portal_type):
self.portal_type = portal_type
def install(self):
from Products.CMFCore.TypesTool import TypesTool
self.on(TypesTool.manage_edit).doAfter(self.doSomething)
def doSomething(self, method_call_object):
if self.portal_type == method_call_object.instance.portal_type:
pass
# do whatever
Reflexive example of Interactor of interactor:
class InteractorOfInteractor(Interactor):
def __init__(self, interactor):
self.interactor = interactor
def install(self):
self.on(interactor.doSomething).doAfter(self.doSomething)
def doSomething(self, method_call_object):
pass
Related Articles¶