Структура дополнения

В предыдущих версиях XF было очень мало стандартов и соглашений, касающихся разработки дополнений. Мы сделали многие изменения в XF 2.0. Давайте посмотрим на некоторые изменения:

Идентификаторы дополнений и путь дополнений

Каждое установленное дополнение должно иметь уникальный идентификатор, и этот идентификатор указывает, где в файловой системе дополнение должно хранить свои файлы. Существует два возможных формата идентификатора дополнения.

Первый «простой» тип должен состоять из одного слова и не содержать специальных символов. Например, Demo.

Простые идентификаторы дополнений должны соответствовать следующим правилам:

  • Должен содержать только буквы a-z или A-Z
  • Может содержать 0-9, но не в начале идентификатора
  • Не может содержать специальные символы, такие как косая черта, тире или нижнее подчеркивание

Второй содержит префикс поставщика, поэтому, если вы выпускаете дополнения под определенным брендом или компанией, идентификатор дополнения может указывать на это. Например, SomeVendor/Demo.

Идентификатор дополнения типа поставщика должен соответствовать следующим правилам:

  • Должен содержать только буквы a-z или A-Z
  • Может содержать один символ /, но не в начале или в конце
  • Может содержать 0–9, но не в начале любой части идентификатора дополнения

Как только вы определились с идентификатором Вашего дополнения, мы точно знаем, где будут храниться файлы этого дополнения. Все дополнения XF 2.0 хранятся в подкаталоге каталога src/addons.

Если у вас простой идентификатор дополнения, например, Demo, файлы для Вашего дополнения будут храниться в следующем месте: src/addons/Demo.

Если у вас есть идентификатор дополнения на основе поставщика, например, SomeVendor/Demo, файлы будут храниться в следующем месте: src/addons/SomeVendor/Demo.

Выбранный Вами идентификатор дополнения также станет префиксом пространства имен Вашего класса (дополнительную информацию смотрите в разделе Пространства имен).

Рекомендуемый формат строки версии

Сам XF использует принцип MAJOR.MINOR.PATCH (например, 2.0.0 для первого стабильного выпуска XF2) для своей нумерации версий, и мы рекомендуем использовать аналогичный подход для управления версиями Ваших собственных дополнений. В общих чертах, увеличьте

  • MAJOR версию, когда вы вносите серьезные изменения в функции, особенно изменения, которые нарушают обратную совместимость
  • MINOR версию, когда вы добавляете функциональность, желательно обратно совместимой, и
  • PATCH версию при исправлении ошибок с обратной совместимостью

Рекомендуемый формат идентификатора версии

Идентификаторы версии для дополнения - это базовые целые числа, которые используются для внутреннего сравнения версий. Это позволяет нам легче определять, когда одна версия старше другой. Каждая версия Вашего дополнения должна увеличивать идентификатор версии как минимум на 1, но соглашение, которое мы используем внутри самого XF, потенциально полезно также для дополнения. Наши идентификаторы версий имеют формат aabbccde.

  • aa представляет основную (major) версию
  • bb представляет дополнительную (minor) версию
  • cc представляет версию патча (patch)
  • d представляет состояние, например, 1 для альфа (alpha) релизов, 3 для бета (beta) релизов, 5 для кандидатов (rc) в релизы и 7 для стабильных (stable) релизов
  • e представляет версию состояния (state)

Например, дополнение со строкой версии 1.7.3 релиз-кандидат 4 будет иметь идентификатор 1070354. Последний стабильный выпуск XF2 будет иметь идентификатор 2000070. Версия 1.5.0 бета 3 XF имела идентификатор 1050033. Стабильная версия 99.99.99 будет иметь идентификатор 99999970... и, возможно, вам стоит немного притормозить 😉

Общие файлы и каталоги дополнений

В каталоге дополнения есть несколько файлов и каталогов, которые имеют особое назначение и значение.

Файл addon.json

addon.json - это файл, который содержит ряд частей информации, которые необходимы, чтобы помочь XF 2.0 идентифицировать дополнение и отображать информацию о ней в Admin CP. Как минимум, ваш файл addon.json должен выглядеть так:

{
    "title": "My Add-on by Some Company",
    "version_string": "2.0.0",
    "version_id": 2000070,
    "dev": "Some Company"
}

Базовый файл будет создан автоматически при создании дополнения.

Включение действительного файла addon.json обязательно для распознавания Вашего дополнения, но вы всегда можете проверить свой файл addon.json.

Свойства

Свойство Описание
legacy_addon_id Используется для включения автоматической обработки изменений идентификатора дополнения при обновлении с XenForo 1 до XenForo 2.
title Название дополнения. Это будет отображаться в панели администратора.
description Описание дополнения. Это будет отображаться в панели администратора.
version_id Внутренний идентификатор, используемый XenForo для отслеживания обновлений Вашего дополнения. Это должно увеличиваться с каждым выпуском.
version_string Удобочитаемая версия дополнения. Это будет отображаться в панели администратора вместо свойства version_id.
dev Имя разработчика дополнения. Это будет отображаться в панели администратора.
dev_url Если установлено, имя разработчика будет отображаться в панели администратора в виде гиперссылки с этой целью (href).
faq_url Если задано, гиперссылка на часто задаваемые вопросы будет отображаться в панели администратора с этой целью (href).
support_url Если установлено, в панели администратора будет отображаться гиперссылка на поддержку, указанная в качестве цели (href).
extra_urls Это позволяет отображать ссылки на другие вещи, связанные с дополнением (например, ссылку на отчеты об ошибках, руководство - что угодно).
Массив объектов JSON, где ключ - это текст ссылки, а значение - цель ссылки (href).
require Набор требований, которые необходимо выполнить для XenForo, чтобы разрешить установку дополнения. Смотрите 'свойство требований' для получения дополнительной информации.
icon Иконка ресурса. Это может быть имя иконки Font Awesome (например, fa-shopping-bag или путь к файлу изображения.)
Свойство требований

Свойство require - это стандартный способ заблокировать установку или обновление дополнения, если среда не поддерживает или не соответствует требованиям.

вы можете использовать его, чтобы потребовать, чтобы сначала были установлены другие дополнения, присутствовали или были включены определенные расширения PHP и/или для обеспечения минимальной версии PHP.

Вот пример фрагмента:

...
  "require": {
      "XF": [2000010, "XenForo 2.0.0+"],
      "php": ["5.4.0", "PHP 5.4.0+"],
      "php-ext/json": ["*", "JSON extension"]
  }
...

Каждое требование представляет собой именованный массив:

  • Имя массива - это идентификатор продукта (например, XF или php).
  • Первый элемент массива - это версия продукта (например, 2000010 или 5.4.0). вы можете использовать * для обозначения любой версии продукта.
  • Второй элемент - это читаемый человеком текст этого требования, и он используется в сообщениях (например, XenForo 2.0.0+ или PHP 5.4.0+).

Вот сводка поддерживаемых идентификаторов продуктов:

Наименование Продукта/Требования Относится к... Значение
XF Установленная версия XenForo. Идентификатор версии XenForo, например, 200010.
вы можете получить текущую версию XenForo, проверив верхнюю часть файла /src/XF.php на предмет определения $versionId или распечатав значение \XF::$versionId.
php Версия PHP. Версия PHP, например, 5.4.0.
Рекомендуется держать это значение как можно ниже; обновление версии PHP может быть довольно сложной задачей, особенно если другие дополнения конфликтуют с более новыми версиями PHP.
php-ext/(extension name) Расширение PHP - где (имя расширения) - это имя расширения. Версия расширения PHP.
Это проверяется с помощью функции PHP version_compare, поэтому она работает даже для строк версии в официальном полном формате PHP, например 7.1.19-1+ubuntu16.04.1+deb.sury.org+1.
(any addon ID) Любое дополнение XenForo, например Demo/Addon.
Если вы не уверены в идентификаторе дополнения, проверьте его файл addon.json.
Идентификатор версии дополнения.
вы можете обратиться к рекомендуемому формату идентификатора версии для получения дополнительной информации.

Файл hashes.json

hashes.json - это новый способ добавить поддержку системы проверки работоспособности файлов, и самое приятное то, что она создается автоматически!

В рамках процесса сборки (подробнее об этом позже) мы проведем быструю инвентаризацию всех файлов Вашего дополнения и запишем рассчитанный хэш содержимого файла.

Файл Setup.php

Setup.php- это новый дом для любого кода, который вам нужно запустить во время установки, обновления или удаления Вашего дополнения.

Мы более подробно рассмотрим, как создать класс установки ниже.

Каталог _data

Каталог _data- это место, где хранятся основные данные для Вашего дополнения. Каждый дополнительный тип данных будет иметь свой собственный XML-файл (а не один для всех типов). Хэши для этих файлов включены в hashes.json, чтобы мы могли убедиться, что дополнение имеет полные и согласованные данные, прежде чем разрешить установку дополнения.

Каталог _output

Каталог _output не требуется для успешной установки дополнения, и его не следует включать при релизе дополнения. Этот каталог предназначен исключительно для целей разработки и используется только в том случае, если включен режим разработки (смотрите Включение режима разработки).

Каждый элемент дополнительных данных хранится в отдельном файле. В основном они хранятся как файлы JSON, но в случае фраз они хранятся как файлы TXT, а для шаблонов они хранятся как файлы HTML/CSS/LESS. Все типы шаблонов доступны для редактирования непосредственно в файловой системе, и изменения, внесенные в эти файлы, автоматически записываются обратно в базу данных при загрузке.

Класс установки

Чтобы создать класс установки для дополнения, все, что вам нужно сделать, это создать файл с именем Setup.php в корне каталога дополнения.

Класс Setup должен расширять \XF\AddOn\AbstractSetup, что требует, как минимум, реализации методов install(), upgrade() и uninstall(). Вот как может выглядеть простой класс установки дополнения:

<?php

namespace Demo;

class Setup extends \XF\AddOn\AbstractSetup
{
    public function install(array $stepParams = [])
    {
        $this->schemaManager()->createTable('xf_demo', function(\XF\Db\Schema\Create $table)
        {
            $table->addColumn('demo_id', 'int');
        });
    }

    public function upgrade(array $stepParams = [])
    {
        if ($this->addOn->version_id < 1000170)
        {
            $this->schemaManager()->alterTable('xf_demo', function(\XF\Db\Schema\Alter $table)
            {
                $table->addColumn('foo', 'varchar', 10)->setDefault('');
            });
        }
    }

    public function uninstall(array $stepParams = [])
    {
        $this->schemaManager()->dropTable('xf_demo');
    }
}

Класс Setup также поддерживает выполнение каждого действия на разных этапах. Для реализации этого поведения ваш класс установки может использовать StepRunnerInstallTrait, StepRunnerUpgradeTrait и/или StepRunnerUninstallTrait трейты. Они автоматически реализуют необходимые методы, и вам просто нужно добавить соответствующие шаги, например, installStep1(), upgrade1000170Step1(), upgrade1000170Step2() и uninstallStep1(), где 1000170 и т. д. в методах обновления - это идентификаторы версии дополнения (смотрите Рекомендуемый формат идентификатора версии).