We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 32674
    • 101 Posts
    Hey modx-topians,

    Lets say I wanted to tack some custom code onto the xPDOObject abstract class-- specifically on the Save method....

    ....basically I’d like to add a couple of events to fire before and after save on all objects. Something along the lines of OnBeforeXPDOSave and OnAfterXPDOSave.

    What would be the cleanest or best strategy to go about it? Extending the xPDOObject class seems the obvious route, but then at some point along the way Im going to have to alter core code somewhere to use my extended class instead of the core one -- at least w/o having some kind of dependency injection pattern in use.

    thoughts? ideas? best practice?

    tnx
      • 22303 MODX Staff
      • 10,725 Posts
      Just create your xPDOObject derivative class, extend the methods you want to override, and any classes you want to use this base class simply have them extend it instead of xPDOObject. Or are you talking about doing this on an existing model, namely MODx classes?
        • 32674
        • 101 Posts
        Quote from: OpenGeek at May 23, 2010, 02:14 PM

        Just create your xPDOObject derivative class, extend the methods you want to override, and any classes you want to use this base class simply have them extend it instead of xPDOObject. Or are you talking about doing this on an existing model, namely MODx classes?

        thanks Jason,

        Yeah, I wanted to guarantee that every object in modx has a ’save’ event fired before and after it some way. Preferable in the least intrusive way to the core code, too, for upgrade purposes.

        Im actually thinking of designs/patterns for a very generic workflow 3PC. Basically, the only consistent way that I can think of, to move items along a flow, and keep the 3PC flow code blackboxed from the modx code, is to check modx objects on save, and see if they are workflow defined tasks.

        Ive sort of kicked it around in my head a few of days, and using ’xpdoobject save’ seems to be the OAOO place to catch completed tasks, and trigger a workflow action to move it to the next one.

        Maybe there’s a better approach to it that doesn’t involve extending xPDOObject?

          • 26903
          • 1,336 Posts
          There are quite a few ’save’ events in the core, for instance OnDocFormSave, OnBeforePluginFormSave, OnSnipFormSave etc. for the other elements. Could you not harness these? It depends I suppose on what you mean by ’all’ objects.
            Use MODx, or the cat gets it!
            • 22303 MODX Staff
            • 10,725 Posts
            xPDO::OPT_CALLBACK_ON_SAVE is what you are looking for. You can register the callback globally OR per object instance.
              • 32674
              • 101 Posts
              thx, JC. wow. very nice. I see it’s ultimately hooked into the php "call_user_func" function...

              Line 1311: \core\xpdo\om\xpdoobject.class.php:
              call_user_func($callback, array('className' => $this->_class, 'criteria' => $criteria, 'object' => $this));


              ....so I assume these examples would be relevant to using it: http://php.net/manual/en/function.call-user-func.php.
              I still have to lookup the criteria param’s use though, to get my head around that.


                • 22303 MODX Staff
                • 10,725 Posts
                Quote from: wowzow at May 24, 2010, 12:10 PM

                ....so I assume these examples would be relevant to using it: http://php.net/manual/en/function.call-user-func.php.
                I still have to lookup the criteria param’s use though, to get my head around that.
                Yes, those examples should be relevant.

                As for criteria, that refers to the xPDOCriteria object that is generated and executed by the save() method before the callback occurs.
                  • 26903
                  • 1,336 Posts
                  Yes, but this is on ’save’
                  before the callback occurs
                  , the op asked for
                  fire before and after save on all objects
                  , how is this achieved at this level?
                    Use MODx, or the cat gets it!
                    • 32674
                    • 101 Posts
                    It is a good question on how to best install events that fire before and after saving an xpdo object at such a low level....

                    ...for me, and my original post & question, just using the callback option (OPT_CALLBACK_ON_SAVE) will work well for what Im thinking of doing on a 3PC w/o modifying core code and worrying about upgrades breaking the changes. This actually fires after the save.

                    OTOH, if I was going to have to have to add custom code to xpdo-- like I originally thought when I posted-- I would create both ’before’ and ’after’ events, since they would both be very useful at some point.

                    From looking at the current code in rc2, I don’t think it would be too hard to also add a OPT_CALLBACK_BEFORE_SAVE constant, and a few lines of code for a callback ’before’ the save happens in the xpdoobject. Of course, Jason would be the better person to give opinion on that than myself.

                      • 22303 MODX Staff
                      • 10,725 Posts
                      Quote from: wowzow at May 24, 2010, 06:40 PM

                      It is a good question on how to best install events that fire before and after saving an xpdo object at such a low level....

                      ...for me, and my original post & question, just using the callback option (OPT_CALLBACK_ON_SAVE) will work well for what Im thinking of doing on a 3PC w/o modifying core code and worrying about upgrades breaking the changes. This actually fires after the save.

                      OTOH, if I was going to have to have to add custom code to xpdo-- like I originally thought when I posted-- I would create both ’before’ and ’after’ events, since they would both be very useful at some point.

                      From looking at the current code in rc2, I don’t think it would be too hard to also add a OPT_CALLBACK_BEFORE_SAVE constant, and a few lines of code for a callback ’before’ the save happens in the xpdoobject. Of course, Jason would be the better person to give opinion on that than myself.
                      Technically, you can use a custom validation rule for pre-save events. Whether this is optimal is debatable.