附加组件结构

在以前的 XF 版本中,很少有关于附加组件开发的标准和约定。 在 XF 2.0 的功能中,我们已经做了很多修改。 让我们来看看其中的一些变化:

附加组件 ID 和附加组件路径

每个安装的附加组件都必须有一个唯一的 ID,这个 ID 决定了附加组件应该在文件系统中的哪个位置保存其文件。附加组件的 ID 有两种可能的格式。

第一个 "简単" 类型应该是一个単字,不包含任何特殊字符。例如,Demo

简単的附加组件 ID 必须遵守以下规则:

  • 必须只包含 a-z 或 A-Z。
  • 可以包含 0-9,但不能放在 ID 开头。
  • 不能包含任何特殊字符,例如斜线、破折号或下划线。

第二个包含一个供应商前缀,所以如果你在一个特定的品牌或公司下发布附加组件,附加组件 ID 可以表明这一点。例如,SomeVendor/Demo

供应商类型的附加 ID 应遵守以下规则:

  • 必须只包含 a-z 或 A-Z
  • 可包含一个 / 字符,但不能在开头或结尾处
  • 可以包含 0-9,但不在附加组件 ID 的任何一个部分的开头

一旦您决定了附加组件的 ID,我们就知道这个附加组件的文件将保存在哪里。 所有 XF 2.0 附加组件都保存在 src/addons 目录的子目录中。

如果你有一个简単的附加组件 ID,例如 Demo,你的附加组件文件将保存在以下位置: src/addons/Demo

如果你有一个基于厂商的附加组件 ID,例如 SomeVendor/Demo,文件将保存在以下位置: src/addons/SomeVendor/Demo

您选择的附加组件 ID 也将成为您的类别命名空间前缀(更多信息请参见 命名空间)。

建议版本字符串格式

XF 本身使用 MAJOR.MINOR.PATCH 原则(例如 2.0.0 代表第一个稳定的 XF2 版本)来进行版本编号,我们建议对您自己的附加组件的版本编号采取类似的方法。 基本上,在版本号中增加

  • MAJOR 版本,当你做了重大的功能改变,特别是破坏了向后兼容性的改变
  • MINOR 版本,当你添加功能时,最好是以向后兼容的方式添加
  • PATCH 版本,当你进行向后兼容的 Bug 修复时使用

建议版本 ID 格式

附加组件的版本 ID 是基本的整数,用于内部版本比较。 它让我们可以更容易地检测到一个版本比另一个版本旧。 您的附加组件每个版本都应该将版本号 ID 至少增加 1,但我们内部对 XF 本身使用的惯例,对附加组件也有潜在的作用。 我们的版本 ID 的格式为 aabbccde

  • aa 代表 MAJOR 版本
  • bb 代表 MINOR 版本
  • cc 代表 PATCH 版本
  • d 代表状态,例如 1 代表 alpha 版本,3 代表 beta 版本,5 代表候选版本,7 代表稳定版本
  • e 代表版本 Level 状态

例如,一个版本号是 1.7.3 候选版本 4 它的附加组件 ID 为 "1070354"。 最终稳定版 XF2 的ID为 2000070。 XF 的 1.5.0 Beta 3 版本的 ID 为 1050033。 稳定版 99.99.99 会有一个ID为 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 文件

属性

Property Description
legacy_addon_id 当从 XenForo 1 升级至 XenForo 2 时,用来开启自动处理附加组件 ID 更改。
title 附加组件的标题。 这将显示在管理面板中。
description 附加组件的描述。这将显示在管理面板中。
version_id XenForo 用来追踪附加组件更新的内部 ID。 每次发布时必须递增。
version_string 人类可以读懂的附加组件版本。 这将在管理面板中显示,而不是 version_id 属性。
dev 附加组件开发者的名字。这将显示在管理面板中。
dev_url 如果设置了,开发者的名字将以超链接的形式显示在管理面板中,并以 (href) 此为目标。
faq_url 如果设置了,一个 FAQ 的超链接将显示在管理面板中,并以 (href) 此为目标。
support_url 如果设置了,支援帮助的超链接将显示在管理面板中,并以 (href) 此为目标。
extra_urls 这允许您显示与附加组件相关的其他内容链接(可能是错误报告链接,手册 - 随您喜欢)。
一个 JSON 物件的数组,其中 key 是链接文本,value 是链接目标 (href)。
require XenForo 允许安装附加组件时需要满足的一系列要求。 更多信息请参见 'require 属性'
icon 资源的图标。 这可以是一个 Font Awesome 图标名称(例如 fa-shopping-bag,或一个图像文件的路径)。
require 属性

如果环境不支援或不满足要求,require 属性是阻止附加组件安装或升级的标准方法。 你可以用它来要求先安装其他附加组件,要求某些 PHP 扩展必须存在或激活,和/或 强制执行一个最低的 PHP 版本。

这是一个示例片段:

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

每个 require,都是一个命名数组。

  • 数组的名称是产品 ID (如 XFphp )。
  • 第一个数组元素是产品的版本 (如 20000105.4.0 )。 你可以使用 * 来表示产品的任何版本。
  • 第二个数组元素是该 require 人类可以阅读的文本,这是在消息中使用的内容(例如 XenForo 2.0.0+PHP 5.4.0+)。

下面是受支援的产品 ID 的概述:

产品 / Require 名称 参考...
XF XenForo 的安装版本。 XenForo 版本 ID,例如 200010
你可以通过检查 /src/XF.php 文件顶部的 $versionId 定义或者打印 /XF::$versionId 的值来获取当前 XenForo 的版本。
php PHP 版本。 PHP 版本,例如 5.4.0
建议你尽可能降低这个值;更新一个 PHP 版本可能是一个相当复杂的工作 - 特别是当其他附加组件与新的 PHP 版本冲突时。
php-ext / (extension name) 一个 PHP 扩展 - 其中 (extension name) 是扩展的名称。 PHP 扩展版本。
这是用 PHP 的 version_compare 函数来检查的,所以它甚至适用于官方完整 PHP 格式的版本字符串,比如 7.1.19-1+ubuntu16.04.1+deb.sury.org+1
(any addon ID) 任何 XenForo 附加组件,如 Demo/Addon。如果您不确定某个附加组件的 ID,请查看它的 addon.json 文件。 附加组件的版本 ID。
您可以参考 建议版本 ID 格式 了解更多信息。

hashes.json 文件

hashes.json 是为文件健检系统添加支援的新方法,而且最好的部分是 - 它是自动生成的!

作为构建过程的一部分(稍后会有更多说明),我们将对您所有附加组件的文件进行快速清点,并将计算出的文件内容哈希码写入其中。

Setup.php 文件

Setup.php 是您安装、升级或卸载附加组件时需要运行的任何代码的新主页。

下面 我们将详细介绍如何创建一个 Setup 类。

_data 目录

_data 目录是保存您的附加组件主要数据的地方。 每个附加组件的数据类型都会有自己的 XML 文件(而不是所有类型的単个文件)。这些文件的哈希值被包含在 hashes.json 中,因此我们可以在允许安装附加组件之前确保附加组件拥有完整和一致的数据。

_output 目录

_output 目录不是成功安装附加组件所必需的,而且在发布附加组件时也不应该包括在内。 这个目录纯粹是为了开发目的,只有在激活开发模式时才会使用(参见 激活开发模式)。

每项附加组件数据都保存在一个単独的文件中。 大多数情况下,它们被保存成 JSON 文件,但对于短语,它们被保存为 TXT 文件,对于模板,它们被保存为 HTML/CSS/LESS 文件。 所有的模板类型都可以在文件系统中直接编辑,对这些文件的修改会在加载时自动写回数据库。

Setup 类

要为您的附加组件创建一个 Setup 类,您需要做的就是在您附加组件目录的根目录下创建一个名为 Setup.php 的文件。

Setup 类应该继承 /XF/AddOn/AbstractSetup,它至少需要实作 install()upgrade()uninstall() 方法。 下面是一个简単的附加组件 Setup 类的样子。

<?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 类也支援在不同的步骤中运行每个操作。 为了实现这种行为,您的 Setup 类可以使用 StepRunnerInstallTraitStepRunnerUpgradeTrait 和/或 StepRunnerUninstallTrait 特性。 这些都会自动实作所需的方法,你只需要添加相关的步骤,例如 installStep1()upgrade1000170Step1()upgrade1000170Step2()uninstallStep1(),其中升级方法中的 1000170 等... 是附加组件的版本 ID (参见建议版本 ID 格式)。