В этой статье я постараюсь очень подробно разобрать процесс создания простого модуля для DLE с кешированием и собственными шаблонами. Сначала разберём модуль без шаблона, а после дополним его собственным шаблоном. Итогом статьи будет работоспособный модуль без админки, вызываемый в любом месте сайта через строку подключения.
Вступление
На написание данного поста меня натолкнул один вопрос на сайте dle-faq. ru. Точнее заставил задуматься, почему люди усложняют себе жизнь постоянными правками движка там, где это по большому счёту не нужно. Причина оказалась очень проста - мало кто умеет и знает как правильно написать свой модуль для DLE, хотя это довольно таки просто на самом деле.
Сразу стоит оговориться, что я человек, имеющий слабое знание даже основ php (что не мешает мне делать качественные модули для dle), поэтому статья для опытного программиста скорее всего не будет представлять интерес, а вот для новичка - будет крайне полезна.
С чего начать?
Конечно же начинать лучше с идеи или исходя из конкретной потребности!
В нашем случаи будем рассматривать необходимость вывода в профиле пользователя в любом месте сайта количество новостей определённого пользователя в определённых категориях.
Таким образом мы уже определили пару переменных, которые будут в нашем модуле - это имя пользователя и id категории.
Естественно результат работы модуля лучше кешировать т. к. лишние запросы в БД нам совершенно не нужны. Так же нам не нужен шаблон модуля, но для примера я приведу код модуля и с шаблоном, т. к. правильное подключение шаблона тоже очень важно и при более или менее сложном модуле экономит много ресурсов за счёт уменьшения кода самого модуля.
Круг задач определён, можно приступать к написанию кода. Вспоминаем что у DLE есть API. и вполне логичным кажется использование готового API для этой задачи, но я крайне не рекомендую вообще его использовать даже (особенно!) в сложных модулях.
Почему не стоит использовать DLE_API
Всё просто - это крайне кривая штука, которая не развивается аж с версии 8.2 (на момент написания текущая версия движка - 10.0 и по сравнению с предыдущей версией пофиксили лишь баг с невозможностью регистрации пользователя через api, никаких доработок не производилось).
Использование dle_api значительно увеличивает расход оперативной памяти. что совсем, совсем не хорошо.
Методы, описанные в dle_api расходятся с оригинальным функционалом.
Общий совет. если вам нужна какой то метод или функция из dle_api - просто скопируйте её в свой модуль.
Возможно моих скромных наработок хватит на набор методов и функций, которые можно будет использовать в дальнейшем, но это тема для отдельной статьи.
Пишем код
Прежде, чем писать любой модуль (кроме файлов, отвечающих за ajax), нужно в обязательном порядке, в самом начале прописать одну строку:
Это не позволит пользователю обратиться к файлу модуля напрямую, а значит он не сможет передать собственные параметры в модуль и взломать сайт через этот модуль. Думаю важность этого момента трудно переоценить, но тем не менее я очень часто натыкаюсь на отсутствие подобной конструкции в коде модуля.
Конфигурация и кеширование
Я решил остановиться на этом моменте подробно, т. к. это один из самых частых вопросов, которые задаются, если человек решил написать свой модуль.
Конфигурацию модуля лучше всего записывать в массив - это даст возможность беспроблемного создания кеша для каждого вызова модуля с разным набором конфигурации, в нашем случаи для каждого пользователя.
Объясню почему. Допустим мы написали модуль, он кешируется, и строка создания кеша выглядит следующим образом:
где:
- $var1.$var2.$var3.$var4 - переменные модуля.
- $myModule - текст, который должен записаться в кеш.
Тут всё замечательно ровно до тех пор, пока не понадобится добавить новую переменную. Как правило автор просто забывает прописать эту новую переменную в строку формирования и получения кеша и потом гадает над причинами неработоспособности или неправильной работы модуля (что негативно сказывается на его психологическом равновесии). Таким образом конфиг модуля лучше писать так:
а строка создания кеша будет такая:
Таким образом нам вообще не придётся лазить в этот код никогда, всё будет происходить автоматом.
Используйте префиксы и суффиксы кеша - это позволит гарантировать автоматическую очистку кеша, а так же позволит (при необходимости) создавать отдельные кеши для разных групп пользователей.
Для наглядности поясню взгляните на картинку:
В DLE есть много дефолтных префиксов. но нас интересуют лишь те, которые автоматически чистятся при определённых условиях, поэтому приведу список таких префиксов:
- news, rss, comm - при добавлении новости или комментария.
Значит в нашем случаи нужен префикс archives т. к. кеш модуля надо сбрасывать только при добавлении или удалении новости (он мне просто понравился, можно использовать и calendar и rss). Код конфига и создания кеша тут приводить не буду дабы не захламлять статью, весь код модуля можно посмотреть ниже.
Текст кеша - это результат работы модуля, который будет записан в кеш, тут всё просто.
ID кеша или его имя - сюда лучше всего передавать переменную $cacheName, о которой писалось выше и переменную $config['skin'] - это для того, чтобы иметь разные кеши для разных шаблонов сайта.
Суффикс кеша - может принимать два значения true или false, если передано значение true, то для каждой группы пользователей будет создаваться свой кеш-файл, это бывает нужно, если разным группам пользователей нужно показывать разный контент.
Универсальная заготовка для модуля с кешем, без шаблона
Учитывая всё выше написанное мы можем создать простую заготовку для модуля, который будет использовать кеш, но не будет в своей работе использовать шаблон. Всего 15 строк кода!
Всё довольно просто, правда?
Запрос в БД и проверки.
Ранее мы определили, что нам потребуется две переменные - имя юзера и id категории, а для выборки нужных значений нам необходимо будет составить запрос в БД.
Заведём две переменные: $userName и $caId - эти переменные будут передаваться в модуль через строку подключения.
Однако для нормальной работы модуля нужно проверять данные (ведь от кривых рук спасения практически не существует).
Небольшое отступление.
Я советую использовать однообразный тип переменных модуля и переменных конфига модуля, т. е.
или
выглядит гораздо более читабельным, чем
Однако использование нижней черты я не практикую в dle, т. к. разок из-за этого сработал фильтр в dle и модуль не отработал, хотя возможно это лишь единичный случай.
Самая простая проверка - условие if else:
т. е. мы просто проверяем передана ли переменная через строку подключения, если передана (т. е. не пустая) - прогоняем её значение через $db->safesql - это обезопасит нас от "неправильных" логинов пользователей, т. к. значение переменной будет вставлено в запрос к БД.
Переменную $catId фильтровать не нужно, т. к. она кроме как цифрой никак не задаётся и глупо писать что-то другое в строке подключения. Однако должно быть какое-то дефолтное значение, поэтому проверка нужна и её мы можем прописать непосредственно в конфиге модуля:
С переменными разобрались, теперь запрос в БД.
В нашем случаи необходимо всего одно значение из БД и использовать полноценный запрос, а потом его разбирать - не имеет смысла, поэтому мы будем использовать метод super_query. он по умолчанию возвращает одномерный массив.
Наш итоговый запрос будет таким:
Где:
$myConfig['catId'] - id категории.
$myConfig['userName'] - имя пользователя.
ниже пропишем отладочный код:
Вызов модуля осуществляем так:
Если переменные указаны правильно - результатом отладки будет массив с данными, состоящий из одного элемента count
где:
155 - количество новостей у указанного пользователя в указанной категории
Теперь можно вывести результат по нормальному:
Тут следует отметить, что если в кеш будет записан один нолик - dle его не будет "считать кешем" и создаст новый, поэтому нужно писать туда что-то, отличное от нуля.
Итоговый код нашего модуля будет таким:
Всего 20 строк кода - и получаем готовое решение конкретной проблемы.
Код модуля вполне рабочий и его можно использовать в реальном проекте, однако приведён этот код для ознакомления с принципами правильного написания модулей для DLE.
На этом можно было бы закончить, но выше я обещал показать код модуля с использованием собственного шаблона.
Универсальная заготовка для модуля с кешем и собственным шаблоном
В целом тот же модуль, что мы написали без шаблона вполне легко перетащить и на "шаблонный" модуль, однако в нашем случаи это не имеет смысла, т. к. модуль выводит всего одну цифру. Собственный шаблон в модуле лучше использовать когда необходимо вывести несколько значений с разным оформлением в разных местах сайта.