Most Powerful Open Source ERP

How To Create Interactors

showing an alternative next to workflows to encapsulate related interactions at a central location.
  • Last Update:2016-02-11
  • Version:002
  • Language:en

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.

Examples 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