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
  • Accessing call context
  • Examples of Interactors
  • Related Articles

    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