Skip to content

附加组件结构#

在早期版本的XF中,围绕附加组件开发的标准和惯例非常少。我们在XF 2.0中做了很多改变。让我们看看一些变化:

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

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

第一种“简单”类型应该是一个单词,不包含任何特殊字符。例如,Demo

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

  • 只能包含a-z或A-Z
  • 可以包含0-9,但不能以数字开头
  • 不能包含任何特殊字符,如斜杠、破折号或下划线

第二种包含一个供应商前缀,因此如果您在特定品牌或公司下发布附加组件,附加组件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原则(例如,第一个稳定的XF2版本的版本号为2.0.0)进行版本编号,我们建议您对自己的附加组件版本控制采取类似的方法。简而言之,当您进行以下更改时,递增版本号:

  • 当您进行重大功能更改时,尤其是破坏向后兼容性的更改时,递增MAJOR版本
  • 当您以向后兼容的方式添加功能时,递增MINOR版本
  • 当您进行向后兼容的错误修复时,递增PATCH版本

推荐的版本ID格式#

附加组件的版本ID是用于内部版本比较的基本整数。它使我们更容易检测一个版本是否比另一个版本旧。每个附加组件版本应至少将版本ID增加1,但我们在XF内部使用的一个约定可能对附加组件也有用。我们的版本ID格式为aabbccde

  • aa代表主版本
  • bb代表次版本
  • cc代表补丁版本
  • d代表状态,例如1表示alpha版本,3表示beta版本,5表示发布候选版本,7表示稳定版本
  • e代表状态版本

例如,版本字符串为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文件应如下所示:

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时自动处理附加组件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对象数组,其中键是链接文本,值是链接目标(href)。
require 一组要求,XenForo需要满足这些要求才能安装附加组件。有关更多信息,请参见'要求属性'
icon 资源的图标。这可以是Font Awesome图标名称(例如fa-shopping-bag,或图像文件的路径。)
要求属性#

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

以下是一个示例片段:

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

每个要求都是一个命名的数组:

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

以下是支持的产品ID的摘要:

产品/要求名称 指的是...
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类的示例:

Setup.php
<?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 traits。这些自动实现所需的方法,您只需添加相关的步骤,例如installStep1()upgrade1000170Step1()upgrade1000170Step2()uninstallStep1(),其中1000170等在升级方法中是附加组件版本ID(请参见推荐的版本ID格式)。