插件由一个唯一的代码标识,例如,名为
Acme.Blog的插件位于plugins/acme/blog目录中。
本文介绍了插件及其注册功能。
注册过程允许插件声明其功能,例如 CMS 组件或后端导航和页面。
以下是插件可以实现的一些示例。
插件位于应用目录的 plugins 目录中。下面是一个插件目录结构的示例。
├── plugins
| └── acme ← Author Name
| └── blog ← Plugin Name
| ├── classes
| ├── components
| ├── controllers
| ├── models
| ├── updates
| └── Plugin.php ← Registration File
并非所有插件目录都是必需的。唯一必需的文件是下面描述的 Plugin.php。如果您的插件只提供单一组件,您的插件目录可以大大简化,像这样。
├── plugins
| └── acme
| └── blog
| ├── components
| └── Plugin.php
插件命名空间至关重要,尤其当您打算将插件发布到 October CMS Marketplace 时。当您在 Marketplace 上注册为作者时,系统会要求您提供作者代码,该代码将用作所有插件的根命名空间。您只能在注册时指定一次作者代码。Marketplace 提供的默认作者代码由作者的姓和名组成:JohnSmith。注册后,此代码无法更改。您的所有插件命名空间都应定义在根命名空间下,例如 JohnSmith\Blog。
create:plugin 命令会生成一个插件文件夹和该插件的基本文件。第一个参数指定作者和插件名称。
php artisan create:plugin Acme.Blog该 Plugin.php 文件,称为插件注册文件,是一个初始化脚本,用于声明插件的核心功能和信息。注册文件可以提供以下内容:
注册脚本应该使用插件命名空间。注册脚本应该定义一个名为 Plugin 的类,该类扩展 System\Classes\PluginBase 类。插件注册类中唯一必需的方法是 pluginDetails。下面是一个插件注册文件示例。
namespace Acme\Blog;
class Plugin extends \System\Classes\PluginBase
{
public function pluginDetails()
{
return [
'name' => 'Blog Plugin',
'description' => 'Provides some really cool blog features.',
'author' => 'ACME Corporation',
'icon' => 'icon-leaf'
];
}
public function registerComponents()
{
return [
\Acme\Blog\Components\Post::class => 'blogPost'
];
}
}pluginDetails 是插件注册类中一个必需的方法。它应该返回一个包含以下键的数组:
| Key | Description |
|---|---|
| name | the plugin name, required. |
| description | the plugin description, required. |
| author | the plugin author name, required. |
| icon | a name of the plugin icon. The full list of available icons can be found in the available icon documentation. Any icon names provided by this font are valid, for example icon-glass, icon-music, optional. |
| iconSvg | an SVG icon to be used in place of the standard icon. The SVG icon should be a rectangle and can support colors, optional. |
| homepage | a link to the author's website address, optional. |
| hint | a shorter code used for routing controller URLs in the admin panel, optional. |
插件注册文件可以包含两个方法 boot 和 register。 利用这些方法你可以做任何想做的事情,比如注册路由或将处理程序附加到事件。
register 方法会在插件注册时立即被调用。boot 方法会在请求被路由之前被调用。因此,如果您的操作依赖于另一个插件,您应该使用 boot 方法。例如,在 boot 方法中您可以扩展模型。
public function boot()
{
User::extend(function($model) {
$model->hasOne['author'] = \Acme\Blog\Models\Author::class;
});
}该
boot方法是可选的,将其保持未定义状态有助于提升性能。此外,只有该boot方法支持通过应用程序容器进行依赖注入。
:::
插件也可以提供一个名为 init.php 的文件,其中包含自定义初始化逻辑。下面是一些示例内容。
App::before({
// Logic when the request starts, after routes are registered
});
App::after({
// Logic the request has finished, after the response is sent
});一个插件可以通过在插件注册文件中定义一个 $require 属性来依赖其他插件,该属性应包含一个被视为依赖项的插件名称数组。依赖于 Acme.User 插件的插件可以通过以下方式声明此依赖项:
namespace Acme\Blog;
class Plugin extends \System\Classes\PluginBase
{
/**
* @var array require these plugins
*/
public $require = ['Acme.User'];
// ...
}依赖项定义将影响插件的运行方式以及更新过程如何应用迁移。安装过程将尝试自动安装所有依赖项,但是如果系统中检测到某个插件缺少其任何依赖项,它将被禁用以防止系统错误。
依赖项定义可能很复杂,但应注意防止循环引用。依赖图应始终是有向的,并且循环依赖被视为设计错误。
插件维护变更日志是一种良好实践,用于记录代码中的任何变更或改进。 除了记录变更说明, 此过程还具有有用的能力,可以 执行 迁移和种子文件 按其正确的顺序。
更改日志存储在一个名为 version.yaml 的 YAML 文件中,该文件位于插件的 updates 目录内,并与迁移文件和种子文件共存。此示例显示了一个典型的插件 updates 目录结构:
├── plugins
| └── author
| └── myplugin
| ├── updates
| | ├── version.yaml ← Version File
| | ├── create_tables.php ← Database Script
| | ├── seed_the_database.php
| | └── create_another_table.php
| └── Plugin.php
更新是按特定顺序应用的,基于插件注册文件中定义的依赖关系。具有依赖关系的插件,在其所有依赖项都被首先更新之前,将不会被更新。
namespace Acme\Blog;
class Plugin extends \System\Classes\PluginBase
{
public $require = ['Acme.User'];
}在上述示例中 Acme.Blog 插件将不会更新直到 Acme.User 插件完全更新。
此 version.yaml 文件,也称插件版本文件,包含版本注释并按正确的顺序引用数据库脚本。请阅读 数据库结构 文章,以了解有关迁移文件的信息。如果您要提交插件到 Marketplace,则此文件是必需的。以下是一个插件版本文件的示例。
v1.0.1: First version
v1.0.2: Second version
v1.0.3:
- Update with a migration and seed
- create_tables.php
- seed_the_database.php
v2.0.0: Important update
v2.0.1: Latest version
version.yaml文件应始终将第一行用于描述更改的文本更新,其余行用于更新脚本。对于更详细的更新,请考虑使用专门的更新日志文件。
如上所示,应该有一个表示版本号的键,后跟更新消息,该消息可以是字符串,也可以是包含更新消息的数组。对于引用迁移或种子文件的更新,作为脚本文件名的行可以放置在任何位置。一个没有关联更新文件的注释示例。
v1.0.1: A single comment that uses no update scripts.有时,插件需要引入可能破坏已在使用该插件的网站的功能。为了防止这些更改自动部署,您应该增加版本字符串的主版本号段 (major.minor.patch)。下面是一个重要更新注释的示例。
v2.1.0: This is an important update from v1 that contains breaking changes.当从版本 v1 标记新版本 v2 时则更改不会作为常规更新的一部分进行部署。用户必须再次安装插件才能通过 Composer 接收最新版本。
正如之前所描述的,更新还定义了何时迁移和种子文件应该被应用。一条带有注释和更新的更新行:
v1.1.1:
- This update will execute the two scripts below.
- some_upgrade_file.php
- some_seeding_file.php更新文件名应使用 snake_case 而其所在的 PHP 类应使用 CamelCase。对于名为 some_upgrade_file.php 的文件,相应的类将是 SomeUpgradeFile。
<?php namespace Acme\Blog\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
/**
* some_upgrade_file.php
*/
class SomeUpgradeFile extends Migration
{
///
}