Содержание
Создание пакета дополнения CMS
InstantCMS 2 использует механизм пакетов для установки любых дополнений (компонентов, виджетов, шаблонов, патчей и т.п.) и обновлений. Пакет - это упакованные в zip архив файлы заданной структуры. Файл должен иметь расширение zip.
Типы пакетов
Пакеты могут быть нескольких типов и в зависимости от них CMS выполняет те или иные действия.
Пакет установки компонента
Такой пакет предполагает, что будет выполнен процесс установки компонента. Т.е. подразумевается, что компонент ранее не был установлен. При таком типе пакета CMS сама заполняет таблицу cms_controllers.
Пакет обновления компонента
Такой пакет предполагает, что в нем находятся только файлы обновления с предыдущей версии. Пакет может устанавливаться только если обновляемый компонент уже установлен. Установщик автоматически увеличит версию компонента и обновит массив опций в таблице cms_controllers.
Пакет установки виджета
Этот пакет предполагает, что устанавливаемое дополнение это виджет. CMS сама добавляет запись в таблицу cms_widgets на основе данных файла манифеста.
Пакет обновления виджета
Алгоритм действия аналогичен пакету обновления компонента с тем отличием, что используется таблица cms_widgets для изменения данных.
Пакет общего назначения
Движок распознает такой пакет в случае, если в файле манифеста (о нем ниже) отсутствуют блоки [install] или [update]. При установке такого пакета CMS ничего делать не будет в плане автоматического создания записей в таблицах cms_controllers и cms_widgets. Разработчик дополнения в этом случае сам должен позаботиться об этом.
Структура пакета
Внутри архива дерево файлов выглядит в общем случае вот так:
В дереве обязательно должны присутствовать:
- файл manifest.ЯЗЫК.ini
Необязательны в архиве следующие файлы:
- папка package;
- файл install.sql;
- файл icon.png;
- файл install.php;
- файлы manifest.ЯЗЫК.ini на языках, отличных от русского.
Структура папки package
Структура папки package полностью совпадает со структурой папок на самом сайте. Таким образом в нее копируется вся структура папок вашего дополнения так, как она есть на самом сайте, начиная с его корня.
Файл иконки дополнения
Файл должен находиться в корне архива и иметь название, указанное в файле manifest. Никаких ограничений на тип файла и его размер нет. Но, разумеется, нужно учитывать, что огромные изображения испортят внешний вид страницы информации о пакете.
Файл install.sql
В этом файле описываются все необходимые sql запросы, которые наполняют какие-либо таблицы или создают новые, необходимые вашему дополнению. В sql запросах префикс таблиц должен быть заменен на {#}. Например, если оригинальный запрос имеет такой вид:
INSERT INTO `cms_controllers` (`title`, `name`, `is_enabled`, `options`, `author`, `url`, `version`, `is_backend`) VALUES ('Микроформат Open Graph', 'opengraph', 1, '---\nenabled_ctypes:\nis_https_available: null\ndefault_image:\n', 'InstantMedia Team', 'https://instantmedia.ru/', '1.1.0', 1);
то в этом файле этот запрос должен выглядеть так:
INSERT INTO `{#}controllers` (`title`, `name`, `is_enabled`, `options`, `author`, `url`, `version`, `is_backend`) VALUES ('Микроформат Open Graph', 'opengraph', 1, '---\nenabled_ctypes:\nis_https_available: null\ndefault_image:\n', 'InstantMedia Team', 'https://instantmedia.ru/', '1.1.0', 1);
Обратите внимание, что в версиях InstantCMS выше 2.3.0 в этом файле нет необходимости писать sql запросы, добавляющие записи в таблицы cms_widgets
и cms_controllers
, достаточно указать в файле манифеста тип дополнения. При установке дополнения движок сам добавит нужные записи в эти таблицы на основе данных в файле манифеста и далее автоматически будет следить за версионностью при установке пакетов обновлений.
Файл install.php
В этом файле должна быть определена функция install_package без аргументов. Внутри функции вы можете выполнять любые действия, вызвав нужные объекты классов системы. Конечно же, в этом файле вы можете создать сколь угодно своих функций и обращаться к ним из функции install_package. Функция install_package должна возвращать:
- true, если все заданное в ней выполнено успешно;
- false, если при выполнении кода произошла какая-то ошибка;
- текст ошибки, который будет показан пользователю при установке дополнения.
В случае ответа false или текста ошибки InstantCMS не создаст записи в таблицах cms_widgets
и cms_controllers
и дополнение будет считаться неустановленным.
Дополнительно, в этом файле может быть определена функция с именем «after_install_package», которая вызывается, когда дополнение уже успешно установлено. Эта функция необязательна.
Файл manifest.*.ini
Этот файл имеет синтаксис обычного ini файла, например такого, как php.ini. Название файла должно иметь следующую структуру:
manifest.{название языка}.ini
Т.е. в зависимости от того, какие языки поддерживает ваше дополнение, вы можете создать для каждого из них свой файл манифеста. Файл manifest.ru.ini будет использоваться по умолчанию. Например, для английской локализации название файла будет выглядеть как manifest.en.ini.
В файле могут быть обозначены следующие блоки:
- [info]
- [version]
- [depends]
- [author]
- [description]
- [package_controllers]
а также, в случае типизирования пакета:
- [install] или
- [update]
Блок [info]
Это обязательный блок
title = "Название вашего дополнения, не более 64 символов" image = "Название иконки дополнения вместе с расширением файла, например icon.png" addon_id = "id вашего дополнения в официальном каталоге дополнений" image_hint = "Название поясняющего изображения, например hint.png"
Отметим, что строка addon_id необязательна, но крайне рекомендуем её указать. В этом случае у владельца сайта, где ваше дополнение будет установлено, в каталоге дополнений в админке будет видно, что пакет установлен, будет отслеживаться версионность и работать уведомления о новых версиях.
Опция image_hint поддерживается в версиях InstantCMS выше 2.12.2. Работает только для пакетов виджетов. Если указана, то она будет показана в списке виджетов под названием. После установки перемещается в директорию upload/package-images/widgets/
.
Блок [version]
Это обязательный блок
major = "первая цифра версии" minor = "вторая цифра версии" build = "третья цифра версии" date = "дата релиза дополнения, например 20251231"
Блок [depends]
Это необязательный блок
core = "версия InstantCMS, ниже которой дополнение работать не будет" php = "версия PHP, ниже которой дополнение работать не будет" package = "версия уже установленного дополнения"
например,
core = "2.16.0" package = "1.5.7" php = "8.3.0" php_ext[imagick] = "*"
Опция package нужна лишь при типе пакета «обновление компонента» или «обновление виджета». Если она указана, то обновление не установится, если уже установленная версия дополнения имеет версию ниже заданной здесь. Это полезно, чтобы наверняка знать, что обновление, например, под цифрой 2.0.5 должно обязательно устанавливаться на версию 2.0.4. Опция php работает с InstantCMS 2.17.0.
Параметры, поддерживаемые с версии InstantCMS 2.6.0.
dependent_type = "тип дополнения, от которого зависит устанавливаемое и которое должно быть уже установлено" dependent_name = "имя зависимого дополнения" dependent_controller = "название контроллера зависимого дополнения" dependent_version = "версия зависимого дополнения, ниже которой нельзя установить текущий пакет" dependent_url = "ссылка на страницу зависимого контроллера" dependent_title = "название зависимого контроллера"
Указав вышеперечисленные параметры, вы можете распространять пакеты, которые не установятся в админке, если условия не соблюдены. Например, вы создали некий компонент. Распространяете его. После вы решили сделать отдельно виджет для него. В пакете установки этого виджета укажите в зависимостях наличие вашего компонента. Например, параметры для зависимого от контроллера виджета могут выглядеть так:
dependent_type = "component" dependent_name = "video" dependent_version = "2.2" dependent_url = "https://instantcms.ru/addons/instantvideo2.html" dependent_title = "InstantVideo2"
В этом случае, если не установлен компонент InstantVideo2 или он установлен, но ниже версии 2.2, пакет виджета не сможет установиться.
В случае, если ваше дополнение зависит от наличия установленного виджета (например, ваш пакет распространяет дополнительный шаблон к нему), то параметры могут быть такими:
dependent_type = "widget" dependent_name = "promo" dependent_controller = "video" dependent_version = "2.0" dependent_url = "https://instantcms.ru/addons/instantvideo2.html" dependent_title = "Промо видео для InstantVideo2"
В этом случае при установке дополнения будет требоваться наличие виджета «Промо видео для InstantVideo2» версии не ниже 2.0.
Стоит отметить, что параметр dependent_version
необязателен, и версионность проверятся только при его наличии.
Параметры, поддерживаемые с версии InstantCMS 2.17.0.
php_ext[imagick] = "*" php_ext[gd] = "8.3.6"
Такими конструкциями вы можете указать для дополнения зависимые модули PHP и их требуемые версии. Символ звёздочки - означает любую версию. В данном примере дополнению будет требоваться два модуля: imagick и gd. imagick требуется любой версии, gd - не ниже 8.3.6.
Блок [author]
Это необязательный, но желательный блок, чтобы пользователи знали к кому обращаться по вопросам дополнения.
name = "Наименование разработчика: бренд или просто какое-то имя, не более 128 символов" url = "Если есть, адрес сайта c http://, не более 250 символов" email = "email разработчика, если есть"
Блок [description]
Это необязательный блок
text[] = "Описание дополнения" text[] = "Строк может быть одна или" text[] = "несколько"
Блок [install] или [update]
В файле может быть только один из указанных блоков, т.е. либо [install], либо [update]. По ним CMS определяет тип: установка или обновление. Внутри блока (одинаков для обоих типов) обязательно должны быть определены следующие опции:
type = "можно указать только component или widget или system" name = "системное имя" controller = "опция для виджета, может быть не заполнено или вовсе отсутствовать, если виджету контроллер не нужен"
Например, для пакета установки компонента video блок может выглядеть так:
[install] type = "component" name = "video"
а для обновления вот так:
[update] type = "component" name = "video"
Для установки виджета, привязанному к определенному компоненту опции могут быть такими:
[install] type = "widget" name = "related" controller = "video"
Аналогично и в случае обновления.
Блок [package_controllers]
Если ваш пакет включает в себя несколько контроллеров, то их нужно перечислить в этом блоке, например:
[package_controllers] controller[] = "video" controller[] = "channels"
Это необходимо, для корректного заполнения эвентов в базе данных на основе манифестов.
Видео туториал
Видео-туториал по созданию инсталлятора дополнений.
Удаление компонентов
Начиная с версии InstantCMS 2.4.0 доступен механизм удаления сторонних компонентов. По умолчанию экшен удаления выполняет удаление записи о компоненте в таблице cms_controllers. Разработчики компонентов могут дополнить механизм по умолчанию двумя способами:
- создать метод с названием deleteController в своей модели и описать там инструкции по удалению, обратные тем, что выполнялись при установке;
- создать в бэкенде своего контроллера специальный экшен «delete_component», где так же описать действия по удалению данных компонента.
Вы можете не дополнять и не реализовывать механизм удаления, если в вашем компоненте это не нужно. В этом случае при удалении просто удалится запись в таблице cms_controllers.
В случае с методом модели, код может быть выглядеть так:
public function deleteController($id) { // здесь вы пишите некий код, который, например, удаляет таблицы, созданные компонентом при установке // удаляете записи интеграции с другими компонентами, например // из ленты активности, rss и других компонентов, используемых вами // вы должны обязательно вызвать родительский метод, чтобы запись в таблице cms_controllers удалилась return parent::deleteController($id); }
Экшен бэкенда контроллера следует использовать, если вы хотите при удалении компонента каких-то действий от пользователя. Экшен создается как обычный экшен контроллера бэкенда. Название экшена должно быть строго «delete_component». Параметры в него не передаются. Финальным результатом, помимо действий, необходимых для вашего компонента, должно быть удаление записи в таблице cms_controllers.
$this->model->deleteController($controller_id);