Редактирование ресурсов через процессор MODx
Подробная и наглядная инструкция по редактирование ресурсов в MODx через процессор, при помощи метода runProcessor.
Оглавление
- Пролог
- Получаем данные ресурса через процессор get
- Изменяем данные ресурса через процессор update
- Пишем парсер
В этой статье я решил поделиться примером работы с процессорами ресурсов в MODx. И в итоге, я не просто покажу как вызывать процессоры, мы даже напишем совсем примитивный, но вполне себе рабочий парсер, который можно будет запускать как через Cron, так и любым удобным для вас способом. Фактически, это пример откроет вам весь функционал процессоров.
Пролог
Одна из моих первых рабочих задач на MODx, заключалась в написании скрипта парсинга, который должен был по определенному URL считывать информацию и обновлять её на сайте. Тогда я решил свою задачу с помощью PDO или xPDO. Получал объект обновляемого ресурса через $modx->getObject
, изменял необходимые поля с помощью метода set()
, и сохранял ресурс методом save()
.
Фактически, этого было достаточно на тот момент. Но для более грамотного управления ресурсами (да и практически всей динамикой в MODx), умные дядьки написали процессоры. Это php скрипты, в которых выполняются определенные функции. Когда вы через менеджер MODx создаете, удаляете, публикуете, изменяете или делайте еще много других процедур с ресурсами, срабатывают те самые — процессоры.
Есть очень важное отличие в использовании процессоров при управлении любыми объектами в MODx, нежели чем использовать PDO, xPDO или вообще писать свои SQL запросы. В процессорах с помощью метода modX.invokeEvent
, активируются системные события, это позволит скриптам правильно отрабатывать при взаимодействии с объектами в MODx. Вы сможете смело писать плагины, не переживая что, то или иное событие может не запуститься.
В MODx есть система «Прав доступа». Она нужна для проверок, имеет ли пользователь право проводить определённые операции с объектами системы. Так что, если вы используете процессоры, будет произведена проверка на ту или иную проводимую пользователем операцию. Всегда логируйте результат работы процессоров:
if ($response->isError()) {
return print_r($modx->error->failure($response->getMessage()));
}
Получаем данные ресурса через процессор get
Так как мы изменяем данные уже существующего ресурса, нам нужно их для начала получить. И для этого тоже есть процессор. Я буду работать в очень крутом дополнении MODx — modalConsole, которую написал Сергей Шлоков. Пишем следующий код:
$id = 1;
// Получаем поля ресурса с идентификатором 1
$properties = ['id' => $id];
$response = $modx->runProcessor('resource/get', $properties);
if ($response->isError()) {
return print_r($modx->error->failure($response->getMessage()));
}
$data = $response->response['object'];
print_r($data);
В этом коде, мы с помощью метода runProcessor
, запустили процессор ресурса — get
, передали в него свойства в виде идентификатора искомого ресурса, проверили что в ответе нет ошибок и в переменную $data
записали массив полей ресурса:
Array
(
[id] => 1
[type] => document
[contentType] => text/html
[pagetitle] => Главная
[longtitle] =>
[description] =>
[alias] => glavnaya
[alias_visible] => 1
[link_attributes] =>
[published] => 1
[pub_date] =>
[unpub_date] =>
[parent] => 0
[isfolder] =>
[introtext] =>
[content] =>
[richtext] => 1
[template] => 2
[menuindex] => 0
[searchable] => 1
[cacheable] => 1
[createdby] => 1
[createdon] => 2020-04-13 21:07:42
[editedby] => 1
[editedon] => 2020-04-21 15:43:45
[deleted] =>
[deletedon] => 0
[deletedby] => 0
[publishedon] => 2020-04-21 1:15 pm
[publishedby] => 1
[menutitle] =>
[donthit] =>
[privateweb] =>
[privatemgr] =>
[content_dispo] => 0
[hidemenu] =>
[class_key] => modDocument
[context_key] => web
[content_type] => 1
[uri] => glavnaya
[uri_override] => 0
[hide_children_in_tree] => 0
[show_in_tree] => 1
[properties] =>
[canpublish] => 1
)
Изменяем данные ресурса через процессор update
Теперь, когда у нас есть массив данных изменяемого ресурса, мы можем изменить его поля. Для этого дополним наш код:
// Обновляем поля ресурса
$response = $modx->runProcessor('resource/update', [
'id' => $data['id'],
'content' => 'Тест',
]);
И при попытке выполнить код, изменение ресурса не произойдет, а мы получим ошибки. Дело в том, что процессор update
, требует обязательно указать контекст ресурса, в котором происходят изменения. Сделаем это:
$response = $modx->runProcessor('resource/update', [
// Указываем обязательное поле context_key для обновления ресурса
'id' => $data['id'],
'context_key' => $data['context_key'],
// Меняем нужные нам поля
'content' => 'Тест',
]);
Выполняем код и он опять не сработает. В логах, php нам любезно сообщит что нужно указать поля ресурса pagetitle
, parent
, и class_key
. Я, если честно, не вникал зачем MODx требует указывать и эти поля, но у нас ведь никаких проблем с этим нет. Мы получили все поля ресурса и можем их же и указать при обновлении ресурса:
$response = $modx->runProcessor('resource/update', [
// Указываем обязательные поля
'id' => $data['id'],
'parent' => $data['parent'],
'class_key' => $data['class_key'],
'context_key' => $data['context_key'],
'pagetitle' => $data['pagetitle'],
// Меняем нужные нам поля
'content' => 'тест',
]);
if ($response->isError()) {
return print_r($modx->error->failure($response->getMessage()));
}
И вот теперь при выполнении кода, значение поля контент уже изменится на — «Тест». Изменится оно в базе, изменится в менеджере MODx, но на фронте — нет. Потому что нужно почистить кэш. Но не будем же мы чистить весь кэш сайта? Я покажу как чистить кэш чуть более оптимизировано. Дописываем в скрипт следующий код:
// Очищаем только кэш ресурса с идентификатором 1
$options = [
'objects' => null,
'extensions' => [
$id . '.cache.php'
]
];
// Очищаем только файлы кэша которые расположены по пути указанном ниже
$paths = [
'resource/web/resources/',
];
// Чистим кэш по настройкам выше
$modx->cacheManager->clearCache($paths, $options);
Ну и теперь кэш ресурса который мы редактируем очистится автоматически, а при обращении к страничке на фронте сгенерируется новый. Вот теперь база для написания парсинга готова!
Нужно быть крайне осторожным с очисткой кэша. При очистки кэша одной страницы, на других может остаться старая информация. Это может негативно сказаться при работе сниппетов и других элементов, которые строят динамические данные. В моем примере, я очищаю кэш только главной страницы, потому что изменяю лишь её контент. А он зачастую не участвует вызовах на других страницах сайта.
Пишем парсер
Это удивительно конечно, но фактически парсер мы уже написали. Теперь нам осталось придумать откуда и как цеплять контент и подставлять его в нужные нам поля ресурса. Я воспользуюсь самым обычным способ парсинга, через функцию php — file_get_contents
:
// Формируем данные для парсинга
$url = 'https://www.php.net/';
$content = file_get_contents($url);
$getBlock = explode('<div class="download">', $content);
$html = explode('</div>', $getBlock [1]);
Я парсю главную страницу сайта php.net и вырезаю блок «Download», который и буду сохранять у себя на сайте.
Финальный код парсера
Полный код нашего мини-парсера:
$id = 1;
$properties = ['id' => $id];
$response = $modx->runProcessor('resource/get', $properties);
if ($response->isError()) {
return print_r($modx->error->failure($response->getMessage()));
}
$data = $response->response['object'];
// Формируем данные для парсинга
$url = 'https://www.php.net/';
$content = file_get_contents($url);
$getBlock = explode('<div class="download">', $content);
$html = explode('</div>', $getBlock[1]);
$response = $modx->runProcessor('resource/update', [
'id' => $data['id'],
'parent' => $data['parent'],
'class_key' => $data['class_key'],
'context_key' => $data['context_key'],
'alias' => $data['alias'],
'pagetitle' => $data['pagetitle'],
// Меняем нужные нам поля
'content' => $html[0],
]);
if ($response->isError()) {
return print_r($modx->error->failure($response->getMessage()));
}
$options = [
'objects' => null,
'extensions' => [
$id . '.cache.php'
]
];
$paths = [
'resource/web/resources/',
];
$modx->cacheManager->clearCache($paths, $options);
Если сайт php.net еще не изменил разметку, можете попробовать запустить этот скрипт на своем тестовом сайте и в ресурсе с идентификатором 1 появится информация с сайта php.net.
Эпилог
Этот пример дает вам практически полную базу знаний в использовании процессоров для обновления ресурсов. При определённых знаниях в PHP или взаимодействиями с некоторыми библиотеками, можно создать хороший парсер, который будет складывать информацию в нужные вам ресурсы, в нужные поля, очищать кэш либо у указанных ресурсов, либо у всех. Все зависит от настроек, которые вы выставите. Ну, а скрипт выше — это база с которой стоит начинать редактирование ресурсов через процессоры MODx.
Время запросов: 0,1159 s
Количество запросов: 28
Источник: cache