发布于 2015-08-09 04:45:24 | 328 次阅读 | 评论: 0 | 来源: 网络整理
有时需要在包的安装过程中执行其它的动作,例如:将它安装在默认的 vendor
以外的其它目录。
在这些情况下,你可以考虑创建一个自定义安装程序来处理特定的逻辑。
假设你的项目已经有了一个自定义的安装模块,那么如何根据 安装类型 正确调用你包文件中的安装程序就成为了一个问题。
参见见下一章,如何通过指令创建自定义安装程序。
任何自定义安装程序都要通过 type 属性来识别。一旦被确认,它将完全覆盖默认的安装程序,并执行自己的安装逻辑。
一个实际用例:
phpDocumentor 的特殊模板需要安装在 /vendor 以外的其它目录中。 因此他们选择
phpdocumentor-template
安装类型 并为此类型创建了一个插件,以便将他们的模板发送到正确的目录中。
在这样一个模板包的例子中 composer.json 将使用以下设置:
{
"name": "phpdocumentor/template-responsive",
"type": "phpdocumentor-template",
"require": {
"phpdocumentor/template-installer-plugin": "*"
}
}
重要提示: 为了确保这个模板安装程序在安装模板包之前就已存在,模板包必须写入对此安装程序包的依赖。
一个自定义安装程序通常是以 Composer 插件的形式存在,并包含有一个类,它实现了 ComposerInstallerInstallerInterface
这个接口。
一个基本的安装程序插件必须由3个文件组成:
MyProjectComposerPlugin.php
,其中的类必须实现 ComposerPluginPluginInterface
接口。MyProjectComposerInstaller.php
,其中的类必须实现 ComposerInstallerInstallerInterface
接口。此处的包文件和普通资源包是相同的,但需要满足以下条件:
实例:
{
"name": "phpdocumentor/template-installer-plugin",
"type": "composer-plugin",
"license": "MIT",
"autoload": {
"psr-0": {"phpDocumentor\Composer": "src/"}
},
"extra": {
"class": "phpDocumentor\Composer\TemplateInstallerPlugin"
},
"require": {
"composer-plugin-api": "1.0.0"
}
}
这个类定义了 Composer 的插件,它必须实现 ComposerPluginPluginInterface
这个接口。它可以在 activate()
方法中注册自定义安装程序。
这个类可以被放在任何位置、使用任何名字,只要能够根据 extra.class
中的定义被自动加载即可。
实例:
<?php
namespace phpDocumentorComposer;
use ComposerComposer;
use ComposerIOIOInterface;
use ComposerPluginPluginInterface;
class TemplateInstallerPlugin implements PluginInterface
{
public function activate(Composer $composer, IOInterface $io)
{
$installer = new TemplateInstaller($io, $composer);
$composer->getInstallationManager()->addInstaller($installer);
}
}
这个类用于执行自定义的安装过程,它必须实现 ComposerInstallerInstallerInterface
这个接口(或者继承了另一个实现此接口的安装程序类)。它将会对 安装类型 中定义的字符串执行 supports()
方法验证,一旦通过就采用对应的安装程序。
注意: 请慎重选择你的 安装类型 名称,建议遵循这样的格式:
vendor-type
。例如:phpdocumentor-template
。
InstallerInterface 类定义了以下方法(请查阅源码以获得更详细的信息):
实例:
<?php
namespace phpDocumentorComposer;
use ComposerPackagePackageInterface;
use ComposerInstallerLibraryInstaller;
class TemplateInstaller extends LibraryInstaller
{
/**
* {@inheritDoc}
*/
public function getPackageBasePath(PackageInterface $package)
{
$prefix = substr($package->getPrettyName(), 0, 23);
if ('phpdocumentor/template-' !== $prefix) {
throw new InvalidArgumentException(
'Unable to install template, phpdocumentor templates '
.'should always start their package name with '
.'"phpdocumentor/template-"'
);
}
return 'data/templates/'.substr($package->getPrettyName(), 23);
}
/**
* {@inheritDoc}
*/
public function supports($packageType)
{
return 'phpdocumentor-template' === $packageType;
}
}
这个例子演示了,简单的继承 ComposerInstallerLibraryInstaller
类来剥离 phpdocumentor/template-
前缀,并用剩余的部分重新组装了一个完全不同的安装路径。
并非安装在
/vendor
目录,任何使用这个安装程序的资源包,将被放置在/data/templates/<stripped name>
目录中。