Плагины в Modx. Краткое пояснение

Я с Modx'ом достаточно давно работаю. Делал различные интересные штуки, в принципе было все понятно и интересно, но был один затык — плагины. И как я вижу, плагины не используют многие даже матерые программисты. И очень зря. Потому как умея с ними работать, вам во-первых не придется изменять отлаженный код движка. Во-вторых, вы свое решение можете кидать из проекта в проект и делиться им с сообществом. Ну и в третьих — вы получаете сногсшибательную гибкость при работе с Modx. Если вы поймете их устройство, для вас откроется новый мир)
Сразу оговорюсь, что текст не претендует на научный труд) Звезды так сложились, что я за сегодняшний день меня дважды спрашивали как работать с плагинами, поэтому и решил накатать небольшую заметку.
Прежде всего, что такое событие и плагин?

Рассмотрим простой пример:

# file 1.php
<?php
$a = $_GET[a];
echo $a;



Допустим, нам нужно чтобы к $a прибавлялась единичка. Что вы делаем: в третью строку добавляем $a++; и все хорошо. А теперь представьте, что у нас код не три строчки, а 35 тысяч, разбросанный на сотни файлов. Да и еще (!) который обновляется путем перезаписывания файлов! В этом случае, в нужном месте было бы логично вставить вызов пустой функции, в которую мы можем передать какие-то значения, сделать что-либо с ними, а потом передать их. В этом случае наша дополнительная логика не переатрется. И нужно будет копировать не все файлы а нашими изменениями, а только тело самой функции.
Наш подправленный скрипт:

# file 1.php
<?php
include 'func.php';
$a = $_GET[a];
$a = func($a);
echo $a;

#file func.php
function func($a)
{
return $a++;
}


Теперь, если разработчик добавит что-либо в свой скрипт 1.php — ваша логика прибавления еденички не будет стерта. Если это понятно, то переходим к простой мысли, которую я хотел донести:
Событие — это вызов той самой функции, о которой я писал. Плагин — это своего рода подключаемый файл func.php, в котором описываются наша доплнительная логика.

Как определить в какой момент вызывается событие, что передается и что выдается?

Ответ на этот вопрос очень прост — НИКАК!) Документации даже по системным событиям очень мало, не говоря уже о событиях сторонних модулей типа Shk или MS2. Однако, не стоит расстраиваться)
Во-первых, большинство названий событий говорят сами за себя и достаточно понятно сгруппированы. Допустим, есть у нас раздел Documents. В нем 16 событий (число может отличаться). Первый: onAfterMoveDocument — после перемещения документа. Когда может быть полезно? Допустим, при после перемещения документа, нам нужно обновить кэш.

Код плагина:

global $modx;
if ($modx->Event->name=="onAfterMoveDocument") $modx->clearCahche();

Следующий: OnBeforeDocFormDelete — понятно из названия, что это событие возникает ДО удаления документа.
Допустим, нам нужно заперетить удаление документа с id=8;

Код плагина:

global $modx;
if ($modx->Event->name=="OnBeforeDocFormDelete") {
$p = $modx->Event->params;
if ($p["id"]==8) exit('Данный документ находится под защитой плагина!');;
}

И т.д. названия событий говорят сами за себя. А теперь посмотрим на предыдущий пример чуть долее внимательно. В частности на строчку $p = $modx->Event->params;
Через нее мы можем получить параметры, которые передаются в плагин. Но, важно знать еще один нюанс: помимо тех параметров, которые передаются в плагин, зачастую мы ИМЕЕМ доступ и к другим глобальным переменным: $_POST, $_GET, $_SEESSION etc.

А узнать что именно передается можно несколькими способами:
1) Посмотреть в документации
2) Найти код вызова события в теле вызываемого сниппета или в теле движка modx
3) Через exit(var_dump($modx->Event->params));

Давайте разберем простой плагин, который будет ставить текст-заглушку на пустые документы
.

global $modx; //По-моему не обязательно, но уже на автомате ставлю

// Проверку имени можно не писать если в вашем плагине только одно событие. Если больше, то нужно разграничить либо ифом, либо кейсом (кому как удобнее)
if ($modx->Event->name=="OnLoadDocumentObject") 
{
// При событиях с документами зачастую нам доступен объект $modx->documentObject.
if ($modx->documentObject["content"]==''){
$fish = $modx->getChunk('fishText'); // получаем текст "рыбы" из чанка
$modx->documentObject["content"]=$fish; //передаем в контент нашу рыбу
}
}

Собственно вот такой небольшой опус.
Что осталось за кадром? Да собственно только ваша фантазия и опыт. потому что всего не опишешь. Эксперементируйте и удачи в работе!

P.S. Я рассматривал примеры на Evo, но в Revo все аналогично

Предыдущая работа

Оставить комментарий