We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I've been working through some general Ext JS tutorials (http://rtfm.modx.com/display/revolution20/MODExt+Tutorials), but now that it's time to make some of them work inside of MODX, I'm baffled once more... the MODX core does not seem to make *any* use of the Ext JS ArrayStore or JsonStore methods. I would have expected the MODX manager to be choked full of these, using HttpProxy to fetch the data generated by a PHP processor somewhere. I tried using HttpProxy inside a CMP, but no dice... and I've learned that the HttpProxy function does not throw any errors if can't find the page (that's normal with Ajax... but help! I need something!)

    Following along with some of the extras, I'm no closer to enlightenment, e.g. Doodles:


            ,url: Doodles.config.connectorUrl
            ,baseParams: { action: 'mgr/doodle/getList' }


    Any more obscurity and I'm not gonna survive. The built-in manager actions are all getting routed (unnecessarily?) through connectors, but I just don't see where this is getting handled.

    Can anyone shed some light on this?
      • 3749
      • 24,544 Posts
      The store is there, but implicit. With a modExt grid object, the 'action' automatically links the grid to the processor. The JSON returned from the processor automatically updates the store and the grid (on refresh). You seldom have to worry about how it's done.

      You can get the store if you need it with something like this (from the Orphans chunk grid):

      This one updates the grid (and store) based on user actions in a popup window.

      , changeCategory: function (btn, e) {
              var cs = this.getSelectedAsList();
              if (cs === false) return false;
      
              var r = {chunks: cs};
              if (!this.changeCategoryWindow) {
                  this.changeCategoryWindow = MODx.load({
                        xtype: 'orphans-chunk-window-change-category'
                        , record: r
                        , listeners: {
                          'success': {fn: function (r) {
                              var sels = this.getSelectionModel().getSelections();
                              var cat = Ext.getCmp('orphans-chunk-category-combo').lastSelectionText;
                              var s = this.getStore();
                              for (var i = 0; i < sels.length; i = i + 1) {
                                  var id = sels[i].get('id');
                                  var ri = id;
                                  var record = s.getById(ri);
                                  record.set("category", cat);
                                  record.commit();
                              }
                              this.getSelectionModel().clearSelections(false);
                          }, scope: this}
                      }
                                                        });
              }
              this.changeCategoryWindow.setValues(r);
              this.changeCategoryWindow.show(e.target);
              return true;
          }


      When struggling with this, looking at the Batcher code helped me a lot. Orphans is not a great example because (for speed) it updates the grid locally rather than using the processor response (because the processor takes a really long time to run), which is why it gets the store.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        Thanks Bob, as always. It's good to know how things work behind the scenes so we can document it for other devs... the docs on MODExt are pretty slim on this.

        So it appears that somewhere, the "processors" path is hardcoded? Is that true? E.g. in "Batcher", I see this:

                url: Batcher.config.connector_url
                ,baseParams: {
                    action: 'mgr/resource/getList'
                    ,thread: config.thread
                }


        So I need to know that it's referring to the core/components/batcher/processors/mgr/resource/getlist.php file, and I would need to know how that file is passed data (I would have expected it to be posted -- it is Ajax afterall), but instead I see it uses the $scriptProperties array, suggesting an intermediary:

        $start = $modx->getOption('start',$scriptProperties,0);


        And then finally, I need to know what format the output must be in -- Ext JS from what I've read so far expects a JSON object with node in it for the count of all object and another node flagged to be the container for the array of records. Instead I see this:

        $count = $modx->getCount('modResource',$c);
        // ...
        return $this->outputArray($list,$count);


        That itself raises some questions -- "$this" -- what object/class are we in? Do we need a count if it's just a single record?
          • 9207 ☆ A M B ☆
          • 2,475 Posts
          I'm still bumbling through this... got the URL thing figured out... my store file is getting data posted to it, but that's not much to show after fiddling with this all day. But wow... just wow. Why build it this way? Where is all this behavior documented? I've never torn any bit of software this far apart and still not been able to see how it ticks.
            • 3749
            • 24,544 Posts
            The $this, I believe, is the modProcessor class or a class that extends it.

            If you fire up Chrome dev. tools (Ctrl-shift-i) and click on something in Batcher, you can see the Ajax request process on the Network tab.

            You can expand the stuff in the log by clicking on it and see the actual information sent to the processor and the JSON object it returns in the response.

            I've been planning a blog post on the process and hope to get to it soon.

            The paths and URLs are configured in the constructor of the Batcher class itself:

            $this->config = array_merge(array(
                        'corePath' => $corePath,
                        'chunksPath' => $corePath.'elements/chunks/',
                        'modelPath' => $corePath.'model/',
                        'processorsPath' => $corePath.'processors/',
            
                        'assetsUrl' => $assetsUrl,
                        'connectorUrl' => $assetsUrl.'connector.php',
                        'cssUrl' => $assetsUrl.'css/',
                        'jsUrl' => $assetsUrl.'js/',
                    ),$config);


            That array gets made available to the JavaScript in core\components\batcher\controllers\mgr\header.php
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting