Классы MODX Revolution для разработки на PHP

Раздел: CMS -> MODX

Классы MODX в PHP: подробное руководство

MODX Revolution построен на основе объектно-ориентированной архитектуры, использующей классы PHP для работы с системой. Главный класс modX предоставляет доступ ко всем подсистемам: ресурсам, пользователям, шаблонам, чанкам, сниппетам и базе данных через ORM xPDO. В этой статье рассматриваются основные классы и варианты их применения с примерами кода.

Как получить доступ к главному объекту modX и инициализировать контекст?

Основной способ работы с MODX - получить экземпляр класса modX. В большинстве случаев он уже доступен в глобальной переменной $modx после старта системы. Если требуется инициализация вне стандартного цикла, используется метод initialize().


// Пример получения и инициализации modX
$modx = new modX();
$modx->initialize('web'); // контекст 'web' (фронт)
$modx->getService('error','error.modError');
    

Modx php class (классы modx в php)

После инициализации становятся доступны все методы: getObject, getCollection, runSnippet и другие. Проблемы: если контекст не указан или указан неверно, возникает ошибка modX::initialize() - context does not exist. Решение - убедиться в наличии контекста в базе данных.

Типичная ошибка:

Попытка обратиться к $modx до его инициализации - вызовет фатальную ошибку. Используйте проверку: if ($modx instanceof modX) { ... }.

Как получить объект ресурса (страницы) по ID?

Для работы с контентом используется метод getObject класса modX с указанием класса modResource. Это позволяет загрузить один ресурс.


$id = 123;
$resource = $modx->getObject('modResource', $id);
if ($resource) {
    echo $resource->get('pagetitle');
    echo $resource->get('content');
}
    

Результат (если ресурс с id = 123 существует):

Заголовок страницы
Текст контента...
    

Проблемы: если ID не существует, возвращается null. Ошибка игнорируется, но последующий вызов методов на null вызовет исключение. Рекомендуется проверять результат перед использованием.

Ошибка:

Вызов ->get() на null. Решение - выполнить проверку if ($resource) { ... }.

Как создать нового пользователя через класс modUser?

Для создания пользователя используется класс modUser. Объект создаётся с помощью newObject, затем заполняются поля и вызывается save().


$user = $modx->newObject('modUser');
$user->set('username', 'newuser');
$user->set('password', md5('strongpassword')); // но лучше использовать $modx->user->hashPassword()
$user->set('active', true);
if ($user->save()) {
    echo 'Пользователь создан, ID: '.$user->get('id');
} else {
    echo 'Ошибка создания пользователя';
}
    

Проблемы: пароль должен быть зашифрован правильным алгоритмом. Устаревший md5 не рекомендуется. MODX предоставляет метод hashPassword() объекта modUser. Необходимо также назначить группу пользователя (дополнительный вызов $user->joinGroup(1,'Member')).

Ошибка:

Сохранение без пароля - база данных выдаст ошибку. Убедитесь, что все обязательные поля заполнены.

Как выполнить произвольный SQL запрос через xPDO?

Класс xPDO (базовый ORM в MODX) позволяет выполнять прямые запросы с помощью метода query(). Это может быть полезно для сложных выборок, неудобных через getCollection.


$sql = "SELECT * FROM modx_site_content WHERE published = 1 LIMIT 10";
$result = $modx->query($sql);
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
    echo $row['pagetitle'].'<br>';
}
    

Результат - список заголовков опубликованных ресурсов. Проблемы: имена таблиц могут различаться в зависимости от префикса. Рекомендуется использовать $modx->getTableName() для получения правильного имени. Также следует избегать SQL-инъекций, используя подготовленные выражения.

Ошибка:

Выполнение запроса с пользовательскими данными без экранирования - уязвимость. Используйте $modx->prepare() и execute() вместо прямого query.

Как создать свой процессор (класс modProcessor) для обработки формы?

Процессоры - стандартный способ обработки данных в MODX. Создаётся класс, наследующий modProcessor, и реализуется метод process(). Процессоры легко вызываются через $modx->runProcessor().


// Файл: core/components/myapp/processors/web/form/save.class.php
class myappWebFormSaveProcessor extends modProcessor {
    public function process() {
        $name = $this->getProperty('name');
        $email = $this->getProperty('email');
        // валидация и сохранение в БД
        return $this->success('Форма сохранена', array('id' => 1));
    }
}
// Вызов процессора
$response = $modx->runProcessor('web/form/save', $_POST, array('processors_path' => MODX_CORE_PATH.'components/myapp/processors/'));
if ($response->isError()) {
    echo $response->getMessage();
} else {
    echo $response->getMessage();
}
    

Проблемы: неправильный путь к процессору или отсутствие класса. Убедитесь, что файл существует и путь зарегистрирован. Также возможна ошибка при отсутствии прав доступа - процессоры проверяют policy.

Ошибка:

Вызов несуществующего процессора - ответ 'Processor not found'. Проверьте путь и конфигурацию.

Расширенные примеры работы с классами MODX

Ниже приведены более сложные и редко встречающиеся в документации сценарии использования классов MODX.

Создание сервисного класса для работы с API

В MODX можно зарегистрировать свой сервис через метод getService(). Сервисный класс подключается один раз и сохраняет состояние.

Пример

// Файл: core/components/myapp/model/myapp/myapp.class.php
class MyApp {
    private $modx;
    private $config = array();

    public function __construct(modX &$modx, array $config = array()) {
        $this->modx =& $modx;
        $this->config = $config;
    }

    public function getItems($limit = 10) {
        $c = $this->modx->newQuery('modResource');
        $c->where(array('published' => 1));
        $c->limit($limit);
        return $this->modx->getCollection('modResource', $c);
    }
}
// Регистрация сервиса
$myapp = $modx->getService('myapp', 'MyApp', MODX_CORE_PATH.'components/myapp/model/myapp/', $config);
$items = $myapp->getItems(5);
foreach ($items as $item) {
    echo $item->get('pagetitle').'<br>';
}

Результат - вывод пяти опубликованных ресурсов. Проблемы: путь к классу должен быть корректен, класс должен быть определён до вызова getService. Ошибка Class not found - проверьте autoload или include.

Работа с системными событиями через класс modEventHandler

События в MODX позволяют подключать свою логику в различных точках системы. Создание обработчика осуществляется через класс modPlugin и присоединение к событию.

Пример

$modx->addEventListener('OnBeforeDocFormSave', 'myPlugin');
function myPlugin($event) {
    $resource =& $event->params['resource'];
    $resource->set('pagetitle', 'Превью: '.$resource->get('pagetitle'));
}

Этот код меняет заголовок ресурса перед сохранением. Проблемы: если функция не определена, вызовет ошибку. Лучше использовать класс-плагин с методом run().

Пример

class MyPlugin {
    public function run($event) {
        $resource =& $event->params['resource'];
        // логика
    }
}
$modx->addEventListener('OnBeforeDocFormSave', array('MyPlugin', 'run'));

Использование xPDO для сложных JOIN-запросов

ORM xPDO поддерживает построение запросов с объединением таблиц. Пример получения ресурсов вместе с полями пользователя-автора.

Пример

$c = $modx->newQuery('modResource');
$c->innerJoin('modUser', 'Author', 'modResource.createdby = Author.id');
$c->select(array('modResource.*', 'Author.username'));
$c->where(array('modResource.published' => 1));
$resources = $modx->getCollection('modResource', $c);
foreach ($resources as $resource) {
    echo $resource->get('pagetitle').' - автор: '.$resource->get('username').'<br>';
}

Результат - заголовки ресурсов с никами авторов. Проблемы: неправильные имена таблиц или полей. Используйте $modx->getAlias() для уточнения. При использовании большого количества JOIN может упасть производительность - рекомендуется индексировать поля.

Создание своего класса модели с наследованием modResource

Иногда нужно расширить стандартный класс ресурса. Для этого создаётся новый класс, наследующий modResource, и регистрируется в системе.

Пример

class MyResource extends modResource {
    public function getPageTitle() {
        return 'Спец: '.$this->get('pagetitle');
    }
}
// После регистрации в расширении можно использовать:
$resource = $modx->getObject('MyResource', 10);
echo $resource->getPageTitle();

Требуется настроить xPDO так, чтобы класс был известен. Обычно это делается через файл map и схему. Подробнее - в документации по созданию пользовательских моделей.

Классы MODX в PHP - comments

En
Modx php class (php)