Search code examples
phpajaxmodxmodx-revolution

Proper way to perform AJAX request from MODx CMP (Custom Manager Page)


I've created a CMP following this official tutorial: http://rtfm.modx.com/revolution/2.x/developing-in-modx/advanced-development/custom-manager-pages

On this CMP I have a button that I want to perform AJAX requests (on click).

What is the proper way to create php-file that will process this AJAX requests?

Either by creating php-file in /assets/components// and populating it with this code at the top:

require_once '/absolute/path/to/modx/config.core.php';
require_once MODX_CORE_PATH.'model/modx/modx.class.php';
$modx = new modX();
$modx->initialize('web');
// My code is here

or by creating another one action in System->Actions menu in manager and doing something there or in another way (by, maybe, using connectors, processors, controllers...)?


Solution

  • Well, thanks to @ride_85027 for his answer. After some discovery and googling I've come to another one solution using connector and my custom processor. Don't know which variant is "better". So here is my solution:

    All my AJAX requests are sent (via POST) to connector.php file, that is placed in /assets/components/my_component_name/ with required 'action' parameter (that defines processor that will handle this request) and other custom 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'; // My custom class
    $modx->my_component_className= new my_component_className($modx);
    
    /* handle request */
    $path = $modx->getOption('processorsPath',$modx->my_component_className->config,$corePath.'processors/'); // Path to directory with my custom 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 custom processor file is in /core/components/my_component_name/processors/mgr/saveorder.class.php (notice that you need to omit class.php file extension from 'action' parameter.

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

    Here is the code of my custom processor - 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';
    

    As you see I create my class that extends modProcessor class and rewrite 'process' method. In my case it makes some changes to TVs. The AJAX request on success will get string that process method return.

    For more details, please google 'modProcessor'. You will find that there are many other processors classes, provided for you to save your time.