We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 39535
    • 39 Posts
    I have a web-site, that runs MODX Revolution 2.2.6-pl (traditional).

    All articles on my site have a custom TV check-box 'Actual'. When it's checked it means that this article is "Actual". All this "actual" articles are listed in separate place on my site. I need to be able to sort them.

    I know, I could make separate folder in MODX tree for all "Actual" articles and sort them there using built-in MODX drag-and-drop functionality for sorting. But client need all articles ("actual" and non-"actual") be in one folder)

    So I decided to create a Custom Manager Page (CMP) using this tutorial: http://rtfm.modx.com/revolution/2.x/case-studies-and-tutorials/developing-an-extra-in-modx-revolution/developing-an-extra-in-modx-revolution,-part-ii#DevelopinganExtrainMODXRevolution%2CPartII-AddingInlineEditing

    I managed to do this (creating controllers as in tutorial) and now I have an item in menu "Components" "Sort Actual Articles" and it displays via mysql query all "actual" articles. I also added jQuery Sortable functionality to be able to sort them.

    So for now only one thing left to do: create "Save" button that will save in DB the order of these "actual" articles and tutorial mentioned above doesn't seem to help me to do this properly.

    I know that I can simply create a php-file and add a link to it via "Save" button and it will do all saving to DB things for me. But I'm sure it's not the proper way for doing this as anyone will be able to access this php-file and make unauthorized changes. For example, MODX automatically checks users permissions when they try to get to "Sort Actual Articles" menu item.

    So what is the proper way to create this php-saving file (I guess processor is the right way to call this file) and what is the proper way to connect it with "Save" button on my "Sort Actual Articles" CMP?
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      Why not use the listing snippet to generate the list sorted by your criteria in the snippet's properties? What listing snippet are you using?
        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
        • 39535
        • 39 Posts
        Quote from: sottwell at Nov 18, 2014, 09:43 AM
        Why not use the listing snippet to generate the list sorted by your criteria in the snippet's properties? What listing snippet are you using?

        Don't really understand you. I have no sort criteria by now. I want to sort them by gragging and dropping them in my CMP. I don't use any snippet here. I created CMP where I display all my "actual" articles and where I can sort them with the help of jQuery Sortable(). But it sorts them at the front-end so need to save sorting orders in DB.
          • 8274 ☆ A M B ☆
          • 222 Posts
          I believe Susan's snippet recommendation was to create (or extend) the getlist processor that your CMP calls to add additional sort criteria for the list of resources in your CMP. If you are listing any data, there is some default criteria in the getlist processor (many times is it the by record/object id).

          So it sounds like you have a set of resources that can be categorized into two groups: Actual and not. And you want to order the Actual list by dragging and dropping.

          To do that, you need to update the menuindex of the resource as your CMP needs something to sort by. The trick is that the Resource field menuindex will be altered if the resource is moved in the tree as well as your CMP.

          So to make the ordering of you CMP stick, you need to add the new menu ordering to the resources properties field as a JSON string, then have your CMP parse that for sorting, or create a new table that captures the Resource IDs and menuindex in the CMP.

          There is also looking at some existing extras that this can be done in like Collections (works right in the resource tree with custom grid views) or MIGXdb (can create a CMP that can display and save a grid order).

          I have installed other Extras like FAQMan and looked it its Drag and Drop code to figure out how to save on release. You have to call the update processor in order for the new order to be saved to the db. I haven't seen an instance where drag and drop is used but not saved until a button click, but that should be just having the Save button call the update.php processor for you CMP.
            • 39535
            • 39 Posts
            Quote from: dvstudiosinc at Nov 18, 2014, 10:43 AM
            I believe Susan's snippet recommendation was to create (or extend) the getlist processor that your CMP calls to add additional sort criteria for the list of resources in your CMP. If you are listing any data, there is some default criteria in the getlist processor (many times is it the by record/object id).

            So it sounds like you have a set of resources that can be categorized into two groups: Actual and not. And you want to order the Actual list by dragging and dropping.

            To do that, you need to update the menuindex of the resource as your CMP needs something to sort by. The trick is that the Resource field menuindex will be altered if the resource is moved in the tree as well as your CMP.

            So to make the ordering of you CMP stick, you need to add the new menu ordering to the resources properties field as a JSON string, then have your CMP parse that for sorting, or create a new table that captures the Resource IDs and menuindex in the CMP.

            There is also looking at some existing extras that this can be done in like Collections (works right in the resource tree with custom grid views) or MIGXdb (can create a CMP that can display and save a grid order).

            I have installed other Extras like FAQMan and looked it its Drag and Drop code to figure out how to save on release. You have to call the update processor in order for the new order to be saved to the db. I haven't seen an instance where drag and drop is used but not saved until a button click, but that should be just having the Save button call the update.php processor for you CMP.

            Thank you for your reply. As you mention I do have a custom TV variable that stores a sorting order of an "actual" article. Just like menuindex does. I wrote a lot of text in my question and I see it's confusing for people. I already have a CMP where my "actual" articles are listed and already added jQuery sortable function for that list. And I have the php file that gets order of articles and make changes to my custom TV (sort index). I'm just asking what is the proper way to link my CMP with this php file.

            And as I said, I know that I can just simply add anchor tag to my CMP that points to my php script. But I just think that it's wrong way to do that as it's like out of MODS structure. Also anyone can have access to that php file.

            So the question is what is proper way to connect CMP and this php-file (that make changes to custom TV)? By creating a new controller, I don't know....
              • 28042 ☆ A M B ☆
              • 24,524 Posts
              My question was, why do they need to be sorted at all? If you are displaying them on the front-end, you can specify the sort order and the field to sort by at that time.
                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
                • 39535
                • 39 Posts
                Quote from: sottwell at Nov 18, 2014, 11:46 AM
                My question was, why do they need to be sorted at all? If you are displaying them on the front-end, you can specify the sort order and the field to sort by at that time.

                They (actual articles) are displayed on the front-end both on web-site pages (where users read them) and on Manager CMP (custom manager page). So I sort them (by dragging and dropping) on Manager CMP and save that order and after that these articles appear in that order on web-site pages.
                  • 39535
                  • 39 Posts
                  Quote from: sottwell at Nov 18, 2014, 11:46 AM
                  My question was, why do they need to be sorted at all? If you are displaying them on the front-end, you can specify the sort order and the field to sort by at that time.

                  Also, I guess by word back-end we understand different things. You, I guess, understand it as a synonym for the MODx manager interface, when I mean all server-side work (php) by that)
                    • 39535
                    • 39 Posts
                    Quote from: sottwell at Nov 18, 2014, 11:46 AM
                    My question was, why do they need to be sorted at all? If you are displaying them on the front-end, you can specify the sort order and the field to sort by at that time.

                    So the question is what is proper way to connect CMP and this php-file (that make changes to custom TV)? By creating a new controller, I don't know....
                      • 39535
                      • 39 Posts
                      For anyone how's interested in this question, here is my solution:

                      I created my custom connector and processor.
                      From my CMP, when user presses "Save" button, it sends AJAX POST request to connector.php, that is placed in /assets/components/my_component_name/ with 'action' parameter and other parameters that I need.
                      Here is the code of my connector.php:

                      <?php
                      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('my_component_name.core_path',null,$modx->getOption('core_path').'components/my_component_name/');
                      require_once $corePath.'model/my_component_name.class.php';
                      $modx->my_component_className= new my_component_className($modx);
                      
                      /* handle request */
                      $path = $modx->getOption('processorsPath',$modx->my_component_className->config,$corePath.'processors/');
                      $modx->request->handleRequest(array(
                          'processors_path' => $path,
                          'location' => ''
                      ));


                      The action parameter is a path to processor relative to path is set in 'processors_path' in $modx->request->handleRequest.
                      I set action parameter to 'mgr/saveorder' as my processor file is there /core/components/my_component_name/processors/mgr/saveorder.class.php

                      By the way, as I discovered name of processor MUST be lower-case.

                      Here is the code of saveorder.class.php:
                      <?php
                      class SortArticlesSaveOrderProcessor extends modProcessor {
                          public function initialize() {
                      	return parent::initialize();
                          }
                          public function process() {
                          	$sortOrder = json_decode($this->getProperty('order'));
                      		
                      		foreach($sortOrder as $order => $id) {			
                      			$page = $this->modx->getObject('modResource', $id);
                      			if (!$page->setTVValue('sort_id', $order)) {
                      			    $this->modx->log(xPDO::LOG_LEVEL_ERROR, 'There was a problem saving sort_id in saveorder.class.php');
                      				return 'Ошибка.';
                      			}			 
                      		}
                      		
                      		return 'Изменения успешно сохранены.';
                          }
                      }
                      return 'SortArticlesSaveOrderProcessor';