We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 10378
    • 375 Posts
    Hello,

    we are currently working on an extra for MODx. We have a CMP with a grid and would like to execute a custom function by selecting a context menu item in a grid row. The operation doesn't include any CRUD features.

    We tried to solve this by using a processor to execute the custom functionality. Our processor has a php function which should (for example) send an email. The problem is - it seems a processor can't execute custom php functions.

    Here is the ExtJS part which calls the processor:

    ...
    ,sendNewsletter: function(btn,e) {
            MODx.msg.confirm({
                title: _('goodnews.newsletter_send')
                ,text: _('goodnews.newsletter_send_confirm')+' ('+_('goodnews.newsletter_recipients')+this.menu.record.openrecipients+')'
                ,url: GoodNews.config.connectorUrl
                ,params: {
                    action: 'mgr/send/start'
                    ,nlid: this.menu.record.id
                    ,nlaction: 'thisisnotest'
                }
                ,listeners: {
                    'success': {fn:this.refresh,scope:this}
                }
            });
        }
    ...
    


    The question is - does the processor need to be class based?
    What is the correct way to implement this?

    Our setup:
    MODx Revo 2.2.5-pl

    Thanks in advance,
    Martin

    This question has been answered by markh. See the first response.

      Freelancer @bitego http://www.bitego.com
      ---
      GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
      More infos here: http://www.bitego.com/extras/goodnews/
      • 18373 ☆ A M B ☆
      • 3,141 Posts
      Processors don't *have* to be class based, but I do recommend it. If you can extend the CRUD-based ObjectProcessors, you can use the following minimal class-based processor which for sure will work in many future versions to come (I'm not saying non-class-based processors will be gone from 2.3, but it could be something that is dropped in a 3.0 for example):

      class MyCustomProcessor extends modProcessor {
        public function process() {
          // do your custom stuff
        }
      }
      return 'MyCustomProcessor';


      Maybe you can post your processor (and its filename) to see if there may be an issue in that?
        Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

        Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
        • 10378
        • 375 Posts
        Quote from: markh at Dec 21, 2012, 04:41 PM
        Processors don't *have* to be class based, but I do recommend it. If you can extend the CRUD-based ObjectProcessors, you can use the following minimal class-based processor which for sure will work in many future versions to come (I'm not saying non-class-based processors will be gone from 2.3, but it could be something that is dropped in a 3.0 for example):

        class MyCustomProcessor extends modProcessor {
          public function process() {
            // do your custom stuff
          }
        }
        return 'MyCustomProcessor';


        Maybe you can post your processor (and its filename) to see if there may be an issue in that?

        Hi Mark,

        thanks for your hints! The problem is, we need to execute some custom functions/methods (not only some custom lines of code) which are not part of the modProcessor class.
        We have created a mailing class which has some methods to collect users and mailcontent (mail-header mail-body and so on ....) + some methods to send the (bulk-)mails and do some other stuff.

        Let me explain:

        1) we have a ExtJS grid where a user can right click and choose "send email"
        2) the JS code part in my first post calls a processor start.php (I first thought this would be the right way)
        3) in this processor we'd like to use the methods of our custom mailing class and do some other stuff (which again is not part of the original modProcessor.

        Here is a simple version of our start.php processor:

        <?php
        /* 
        we'd like to include our custom class which holds all the required methods to send the newsletters
        - using this the processor throws an error
        */
        //require_once('/var/www/modx/wwwRoot/modxdev/goodnews/core/components/goodnews/model/goodnews/mailpump.class.php');
        
        /*
        for testing:
        if we try to use/call a simple function the processor throws an error
        */
        function test() {
            $modx->log(modX::LOG_LEVEL_INFO, 'GoodNews: start sending newsletter');
            return;
        }
        
        $nlid = $scriptProperties['nlid'];
        $nlaction = $scriptProperties['nlaction'];
        //sendNL($nlid, $nlbulk = 30, $nlaction);
        
        /*
        for testing:
        */
        test();
        
        return $modx->error->success('');
        


        It seems - it simply cant be done this way.

        How would you solve this? Not using a processor to start sending mails?
        What should I call from my Ext grid?

        Greetings,
        Martin
        [ed. note: gadgetto last edited this post 13 years, 9 months ago.]
          Freelancer @bitego http://www.bitego.com
          ---
          GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
          More infos here: http://www.bitego.com/extras/goodnews/
        • discuss.answer
          • 18373 ☆ A M B ☆
          • 3,141 Posts
          You're missing the point, you can execute whatever you want in your processor.

          If you're going the OOP route (which I recommend cause it's awesome and everything), here's an example. Keep in mind that I have no idea what your mailpump class looks like. wink

          /* Include the class */
          require_once('/var/www/modx/wwwRoot/modxdev/goodnews/core/components/goodnews/model/goodnews/mailpump.class.php');
          
          class MyCustomProcessor extends modProcessor {
            /** @var MailPump $mailpump */
            public $mailpump;
          
            public function initialize() {
              $this->mailpump = new MailPump();
            }
          
            public function process() {
               $this->test();
          
               $nlid = $this->getProperty('nlid');
               $nlaction = $this->getProperty('nlaction');
          
               // If the sendNL function is a method on the MailPump class, use that, otherwise you should just have sendNL().
               // $this->mailpump->sendNL($nlid, 30, $nlaction);
               // sendNL($nlid, 30, $nlaction);
               return true;
            }
          
            public function test() {
               $this->modx->log(modX::LOG_LEVEL_INFO, 'GoodNews: start sending newsletter');
            }
          }
          return 'MyCustomProcessor';
            Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

            Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
            • 18373 ☆ A M B ☆
            • 3,141 Posts
            By the way, this code is simply wrong in your post:
            function test() {
                $modx->log(modX::LOG_LEVEL_INFO, 'GoodNews: start sending newsletter');
                return;
            }

            You only have access to local variables in functions, so you need to add global $modx:
            function test() {
                global $modx;
                $modx->log(modX::LOG_LEVEL_INFO, 'GoodNews: start sending newsletter');
                return;
            }


            That's part of why I prefer using class-based stuff, where it's just consistently $this->modx or $this->myOtherVar
              Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

              Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
              • 10378
              • 375 Posts
              Mark, you just made me a Christmas present! Thanks alot and Merry Christmas!
                Freelancer @bitego http://www.bitego.com
                ---
                GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
                More infos here: http://www.bitego.com/extras/goodnews/
                • 18373 ☆ A M B ☆
                • 3,141 Posts
                Merry Christmas! smiley
                  Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

                  Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
                  • 10378
                  • 375 Posts
                  Hi Mark,

                  sorry to ask you once again - but I simply can't get your sample to run!

                  Here is the ExtJS part:

                  ...
                      ,sendNewsletter: function(btn,e) {
                          MODx.msg.confirm({
                              title: _('goodnews.newsletter_send')
                              ,text: _('goodnews.newsletter_send_confirm')+' ('+_('goodnews.newsletter_recipients')+this.menu.record.openrecipients+')'
                              ,url: GoodNews.config.connectorUrl
                              ,params: {
                                  action: 'mgr/send/start'
                                  ,nlid: this.menu.record.id
                                  ,nlaction: 'thisisnotest'
                              }
                              ,listeners: {
                                  'success': {fn:this.refresh,scope:this}
                              }
                          });
                      }
                  ...
                  



                  And here the processor part (based on your sample):

                  <?php
                  require dirname(dirname(dirname(dirname(__FILE__)))) . '/model/goodnews/goodnewsmailing.class.php';
                  
                  class GoodNewsStartMailingProcessor extends modProcessor {
                      /** @var GoodNewsMailing $goodnewsmailing */
                      public $goodnewsmailing;
                      
                      public function initialize() {
                          $this->goodnewsmailing = new GoodNewsMailing();
                          return parent::initialize();
                      }
                      
                      public function process() {
                          
                          $nlid = $this->getProperty('nlid');
                          $nlbulk = 10;
                          $nlaction = $this->getProperty('nlaction');
                  
                          $this->modx->log(modX::LOG_LEVEL_INFO, 'Debug: process() method of class GoodNewsStartMailingProcessor');
                  
                          // send a bulk of mails
                          $this->goodnewsmailing->sendNL($nlid, $nlbulk, $nlaction);
                          return $this->modx->error->success('');
                      }
                      
                  }
                  return 'GoodNewsStartMailingProcessor';
                  


                  Even If I comment out all code parts which references to the GoodNewsMailing class the code doesn't work. I cant get the processor to write the debug message of line: 19 to the modx log.

                  (The processor works if I completely remove all class based parts and only leave in the debug-log line (19) and the return-error-success line).

                  By the way - here is the content of my connector.php from the assets directory:

                  <?php
                  /**
                   * GoodNews Connector
                   *
                   * @package goodnews
                   */
                  require_once dirname(dirname(dirname(dirname(__FILE__)))).'/config.core.php';
                  require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php';
                  require_once MODX_CONNECTORS_PATH.'index.php';
                   
                  $corePath = $modx->getOption('goodnews.core_path', null, $modx->getOption('core_path').'components/goodnews/');
                  require_once $corePath.'model/goodnews/goodnews.class.php';
                  $modx->goodnews = new GoodNews($modx);
                   
                  $modx->lexicon->load('goodnews:default');
                   
                  /* handle request */
                  $path = $modx->getOption('processorsPath', $modx->goodnews->config, $corePath.'processors/');
                  
                  $modx->request->handleRequest(array(
                      'processors_path' => $path,
                      'location' => '',
                  ));
                  


                  What else can I do? I'm completely lost at the moment...

                  [ed. note: gadgetto last edited this post 13 years, 9 months ago.]
                    Freelancer @bitego http://www.bitego.com
                    ---
                    GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
                    More infos here: http://www.bitego.com/extras/goodnews/
                    • 10378
                    • 375 Posts
                    Mark,

                    maybe it's the problem that the modProcessor class is an abstract class and the php doc says: "Classes defined as abstract may not be instantiated"?

                    The php doc is a bit confusing here as it later says: "When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility."

                    How can I inherit from a class without instantiating first?
                    Now - can I instantiate an abstract class or not?

                    Greetings,
                    Martin
                      Freelancer @bitego http://www.bitego.com
                      ---
                      GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
                      More infos here: http://www.bitego.com/extras/goodnews/
                      • 28042 ☆ A M B ☆
                      • 24,524 Posts
                      You can get an idea of all the mod...Processor classes in the children list of modProcessor http://api.modx.com/revolution/2.2/

                      So your custom processor would look much the same as these.
                        Studying MODX in the desert - http://sottwell.com
                        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                        Join the Slack Community - http://modx.org