214-697-723 |
info@mainsource.ru |
(812) 946-31-81
Все контакты
Автор статьи Синцов Роман
Дорабатываем своими руками модуль «Комментарии» для UMI.CMS. Делаем по новому.
Спустя годы разработки приложений, управляемых на ,
я как-то взглянул на одну из своих старых статей, в которой речь шла о выводе комментариев,
и понял, что вводил в заблуждение своих читателей, такой вариант реализации без использования API UMI я настоятельно не рекомендую использовать.
И сейчас решил исправиться и все-таки написать, как же правильно произвести кастомизацию модуля «Комментарии».
От чего в первую очередь хочу уберечь разработчиков UMI: ни в коем случае не правим код существующих классов и методов, как это было описано
в предыдущей статье. Иначе вы мгновенно лишитесь возможности обновить свою систему управления. Почему это важно?
Ну... потому что не бывает идеальных продуктов, регулярно выходят обновления, а не давно появился сервис .
А теперь представьте, как будет обидно разработчику, если все его труды будут затёрты при обновлении, а как уж будет обидно владельцу сайта.
Поэтому не экономим свое время, а сразу делаем все правильно.
Теперь, давайте вспомним, в чем заключалась наша задача: мы хотим поменять порядок вывода комментариев на странице.
Чтобы нам было интереснее, я приведу пример кода для редакции 2.7 и для редакции 2.8 с использованием класса selector.
Вот так выглядит модуль, встроенный на страницу сайта.
Исходный код модуля комментариев находится в classes/modules/comments. Метод, с работой которого мы будем разбираться,
находится в файле class.php. Ищем функцию вставки комментариев:
public function insert($parent_element_id = false, $template = "default") {
Копируем его полностью. Далее, находим в этой же папке файл __custom.php — он как раз предназначен для размещения
своей бизнес-логики, подробнее почему и зачем так, вы можете прочитать в документации UMI.CMS.
Вставляем в тело класса __custom_comments скопированный нами ранее метод insert.
Теперь мы можем смело редактировать и видоизменять этот метод на свое усмотрение, при обновлении он будет работать.
Но для того чтобы у нас не возникло конфликта с уже существующим методом insert, требуется переименовать скопированный
нами метод. На самом деле мы могли бы назвать этот метод любым удобным для нас способом, но исходя из собственного
опыта, имеет смысл переименовать метод так, чтобы было понятно, что он является «метаморфозой» базового метода данного
модуля. Отсюда предлагаю несколько вариантов, которые нравятся лично мне:
custom_insert()
customInsert()
_insert()
Лично я предпочитаю именовать все методы как раз в виде customInsert()
(), но в случае
базовых, я использую подчеркивание, так что в нашем примере метод будет называться _insert().
Подробнее о наименованиях можно почитать
.
Для того, чтобы можно было использовать наш метод, и результат его выполнения был доступен простому посетителю сайта,
необходимо добавить соответствующие права на его выполнение, создав в текущей папке файл
permissions.custom.php, добавив в него следующий код:
Поскольку наш основной класс comments наследуется от класса def_module (это также верно и для других модулей),
то требуется обязательно это учитывать, так как наш кастомный класс использует методы этого класса. Отсюда: для того, чтобы ваш
метод _insert() заработал, необходимо сразу внести правки. Тут возможны два варианта: либо сделать кастомный класс наследуемым от def_module
abstract class __custom_comments extends def_module
либо заменить все указатели self на def_module.
Я предпочитаю вариант добавления для класса extends def_module.
Теперь давайте попробуем разобраться, как нам использовать в шаблонах соответствующий метод. Вот пример для tpl-шаблонизатора:
В случае с tpl у вас должен быть оформленный шаблон для комментариев в папке tpls/comments/default.tpl.
В случае xslt вам нужно в теле шаблона вставить свою верстку, или, если у вас установлен шаблон
«современного магазина», взять код из xsltTpls/modules/comments/comments-list.xsl.
Ну, или поиском найти в папке xsltTpls строку вида
udata[@module = 'comments' and @method = 'insert']
и скопировать от туда содержимое, а также содержимое этого шаблона
Если уже есть шаблоны, то можно просто переименовать существующие методы. Более подробно о шаблонах в рамках статьи я не буду рассказывать.
Убедитесь, что после этого комментарии и форма добавления комментариев продолжают отобржаться на сайте так же, как и раньше.
Если же этого не происходит, значит что-то вы сделали не верно.
Теперь давайте вернемся к нашему методу _insert(). Для того, чтобы передавать в него параметр для выбора сортировки
комментариев (прямого и обратного) добавляем новую переменную — $sort — и установим ей сразу значение по умолчанию.
public function insert($parent_element_id = false, $template = "default", $sort = 0) {
В нашем случае:
$sort = 0 — комментарии выводятся в порядке по умолчанию;
$sort = 1 — комментарии выводятся в обратном порядке.
Далее давайте рассмотрим два варианта реализации для версии 2.7 (в настоящий момент такой вариант актуален и для 2.8.4.4, пояснения дам ниже).
Собственно, если внимательно смотреть документацию по API UMI, вы увидите, что делает этот .
Чтобы нам реализовать требуемый функционал, удаляем эту строку и добавляем такой код:
Важно: чтобы эта замечательная вещь работала как в случае xslt, так и в случае tpl, требуется также добавить следующий код в метод, в самое начало:
if (getRequest('sort') != null) $sort = getRequest('sort');
Этот код нам нужен для xslt-шаблонизатора. Если при вызове метода передается параметр sort, то нужно его учитывать.
Как это использовать в шаблоне, будет рассказано ниже.
В новой редакции UMI 2.8.4.4 для реализации используется устаревший класс umiSelection & umiSelectionsParser (deprecated).
Это вероятно связано с тем, что разработчики не успели переписать код своих методов, но надо понимать, что потенциально при
очередном обновлении они могут окончательно отказаться от использования этих классов в пользу selector. В связи с этим рекомендую
использовать для своей логики новый класс.
Ощущаете насколько упростился код? Теперь дам краткие пояснения к этой выборке.
Выбираем все элементы иерархии типа комментарии: $sel->types('hierarchy-type')->name('comments', 'comment'). Кроме этого
нам нужно выбрать все комментарии для конкретной страницы $sel->where('hierarchy')->page($parent_element_id)->childs(1).
Далее в зависимости от значения sort задаем тип сортировки.
В отличии от предыдущей выборки $result содержит не идентификаторы (id) элементов, а сами элементы, поэтому правим код в цикле по $result.
Было:
Вы должны увидеть примерно такую картину после изменений.
Что хочется отметить... Да, такой вариант немного более трудоемкий, чем предложенный в предыдущем решении,
но зато вы избавлены от проблем потери своего кода после обновлений CMS.