Modx: запрос getCollection не работает

Внутри моего класса процессоров у меня есть оператор, который берет все проекты из таблицы БД и форматирует их для отображения. Этот метод не работает и останавливается при вызове 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 и работает нормально, так что я не думаю, что это связано с объявлением модели. Я мог бы легко использовать второй метод, описанный выше, поскольку он, кажется, работает, но я хочу использовать лучший метод.

Что не так с первым методом?

Является ли первый метод правильным способом реализации SQL в процессоре Modx? Или есть лучший способ?

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;
    }

}

Мы можем сделать эту задачу немного проще.

@Vasis прав, но мы можем использовать базовый метод prepareRow вместо перезагрузки итерационного метода:

<?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. Это дает вам базовую структуру. Но вы можете делать свои собственные вещи.

Другие вопросы по тегам