从 MODx CMP(自定义管理器页面)执行 AJAX 请求的正确方法


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

我按照这个官方教程创建了一个CMP:http://rtfm.modx.com/revolution/2.x/developing-in-modx/advanced-development/custom-manager-pages

在此 CMP 上,我有一个按钮,我想执行 AJAX 请求(单击时)。

创建将处理此 AJAX 请求的 php 文件的正确方法是什么?

通过在/assets/components//中创建 php 文件并在顶部使用以下代码填充它:

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

或者通过在管理器的"系统>操作"菜单中创建另一个操作并在那里执行某些操作或者以另一种方式(也许使用连接器、处理器、控制器......

好吧,感谢@ride_85027的回答。经过一些发现和谷歌搜索,我找到了另一个使用连接器和我的自定义处理器的解决方案。不知道哪个变体"更好"。所以这是我的解决方案:

我所有的 AJAX 请求都(通过 POST)发送到连接器.php文件,该文件放置在/assets/components/my_component_name/中,其中包含所需的"action"参数(定义将处理此请求的处理器)和我需要的其他自定义参数。这是我的连接器的代码.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' => ''
));

操作参数是相对于在 $modx->request->handleRequest 的"processors_path"中设置的处理器路径。我将"action"参数设置为"mgr/saveorder",因为我的自定义处理器文件位于/core/components/my_component_name/processor/mgr/saveorder中.class.php(请注意,您需要从"action"参数中省略class.php文件扩展名。

顺便说一句,正如我发现自定义处理器的名称必须是小写的。

这是我的自定义处理器的代码 - 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';

如您所见,我创建了扩展modProcessor类并重写"进程"方法的类。就我而言,它对电视进行了一些更改。成功的 AJAX 请求将获得进程方法返回的字符串。

有关更多详细信息,请谷歌"modProcessor"。您会发现还有许多其他处理器类,为您提供以节省您的时间。

是的,您需要先加载 MODx,然后再尝试在 CMP 外部使用它。我不建议将每个ajax文件绑定到系统>操作,这是矫枉过正。你和上面很接近,这是我经常使用的:

if (!defined('MODX_CORE_PATH')) {
    if(strpos($_SERVER['SERVER_NAME'],'localhost') !== false){
        define('MODX_CORE_PATH', 'C:/xampp/htdocs/yoursitename/core/');
    }else{
        define('MODX_CORE_PATH', '/home2/yoursitename/public_html/core/');
    }
}
if (!defined('MODX_CONFIG_KEY')) {
    define('MODX_CONFIG_KEY', 'config');
}
require_once( MODX_CORE_PATH . 'model/modx/modx.class.php');
$modx = new modx();
$modx->initialize('mgr');

请注意,嵌套的 if/else 语句是我添加的,用于处理在测试站点之间移动并轻松生活。您可以简单地删除它,并在需要时保留实际/home2/yoursite..etc

在PHP文件中初始化/加载MODx后,只需使用$.GET或类似的东西来处理请求。

注意:如果您使用的是自定义数据库表,请不要忘记添加软件包,以便与表进行通信!以下是addPackage请求的链接:http://rtfm.modx.com/xpdo/2.x/class-reference/xpdo/xpdo.addpackage

我知道这是旧帖子,但是在寻找相同问题的解决方案时,我降落在这里,所以我分享我的答案。

我发现下面的教程真的很有帮助

http://ridcully.dunnock.modxcloud.com/records/2014/07/08/using-custom-processors-in-modx-revolution-over-ajax-request/?quip_approved=0#quip-success-qcom