1

在我的处理器类中,我有一个语句从数据库表中获取所有项目并将它们格式化以显示。此方法不起作用并在 getCollection 调用处停止。

class GlobalLinkSettingsProcessor extends modObjectGetListProcessor{

    public function initialize() {
        return parent::initialize();
    }

    public function process() {
        $result = $this->modx->getCollection('ManagerProjects');
        $project_names = array();
        foreach ($result as $row) {
            $projects = unserialize($row->get('manager_projects'));
            foreach($projects as $short_code => $project) {
                $project_names[] = array('project_name' => $project, 'project_short_code' => $short_code);
            }
        }
        return '{"total":' . count($project_names) . ',"results":' . $this->modx->toJSON($project_names) . ',"success":true}';
    }
...
}

这段使用纯 SQL 的代码确实有效

class GlobalLinkSettingsProcessor extends modObjectGetListProcessor{

    public function initialize() {
        return parent::initialize();
    }

    public function process() {
        $leadersql = "SELECT * FROM `modx_manager_projects`";
        $query = $this->modx->query($leadersql);
        $project_names = array();
        while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
            $projects = unserialize($row['manager_projects']);
            foreach($projects as $short_code => $project) {
                $project_names[] = array('project_name' => $project, 'project_short_code' => $short_code);
            }
        };
        return '{"total":' . count($project_names) . ',"results":' . $this->modx->toJSON($project_names) . ',"success":true}';
    }
...
}

我使用与第一种方法类似的方法,它可以保存ManagerProjects并正常工作,所以我认为它与模型声明无关。我可以轻松地使用上面的第二种方法,因为它似乎有效,但我想使用最好的方法。

第一种方法有什么问题?

第一种方法是在 Modx 处理器中实现 SQL 的正确方法吗?或者,还有更好的方法?

4

2 回答 2

3

我们可以更轻松地完成这项任务。

@Vasis 是对的,但我们可以使用基础prepareRow方法而不是重新加载iterate方法:

<?php
class GlobalLinkSettingsProcessor extends modObjectGetListProcessor{
    public $classKey = 'ManagerProjects';
    protected $projects = array();

    public function prepareRow(xPDOObject $object) {
        $_projects = unserialize($object->get('manager_projects'));
        foreach($_projects as $short_code => $project) {
            $this->projects[] = array('project_name' => $project, 'project_short_code' => $short_code);
        }
        return parent::prepareRow($object);
    }

    public function outputArray(array $array,$count = false) {
        $count = count($this->projects);
        return parent::outputArray($this->projects,$count);
    }
}
return 'GlobalLinkSettingsProcessor';

在那里我们可以看到 modx 的“功能”之一。在modObjectGetListProcessor 处理方法中我们可以看到:

public function process() {
    $beforeQuery = $this->beforeQuery();
    if ($beforeQuery !== true) {
        return $this->failure($beforeQuery);
    }
    $data = $this->getData();
    $list = $this->iterate($data);
    return $this->outputArray($list,$data['total']);
}

getData方法返回一个对象列表,然后它转到迭代方法(我们可以检查对象是否可访问并根据需要更改这些对象的列表)。如果您无权访问某些对象,我们将获得更改列表。它转到outputArray方法,但第二个参数仍然很旧。所以你应该再数一遍。

这是一个很好的解决方案,但您试图获取存储在对象字段中的数据。所以afterIteration方法将无法在我的处理器版本中进一步扩展。但谁在乎?:)

PS:关于你的第一个版本的处理器。modObjectGetList处理器已准备好获取集合。所以你不必使用getcollection方法。只需为其添加适当的classKey属性即可。另一种方法是在modProcessor扩展中。它为您提供了一个基本结构。但是你可以制作自己的东西。

于 2014-05-16T17:50:14.787 回答
2

因为你做错了!看看这个。正确的做法是这样的:

<?php
class GlobalLinkSettingsProcessor extends modObjectGetListProcessor{
    public $classKey = 'ManagerProjects';

    public function iterate(array $data) {
        $list = array();
        $list = $this->beforeIteration($list);
        $this->currentIndex = 0;
        /** @var xPDOObject|modAccessibleObject $object */
        foreach ($data['results'] as $object) {
            if ($this->checkListPermission && $object instanceof modAccessibleObject && !$object->checkPolicy('list')) continue;
            $projects = unserialize($object->get('manager_projects'));
            foreach($projects as $short_code => $project) {
                $objectArray = array('project_name' => $project, 'project_short_code' => $short_code);
                if (!empty($objectArray) && is_array($objectArray)) {
                    $list[] = $objectArray;
                    $this->currentIndex++;
                }
            }
        }
        $list = $this->afterIteration($list);
        return $list;
    }

}
于 2014-05-15T18:43:36.857 回答