有時需要在包的安裝過程中執(zhí)行其它的動作,例如:將它安裝在默認(rèn)的 vendor
以外的其它目錄。
在這些情況下,你可以考慮創(chuàng)建一個自定義安裝程序來處理特定的邏輯。
假設(shè)你的項(xiàng)目已經(jīng)有了一個自定義的安裝模塊,那么如何根據(jù) 安裝類型 正確調(diào)用你包文件中的安裝程序就成為了一個問題。
參見見下一章,如何通過指令創(chuàng)建自定義安裝程序。
任何自定義安裝程序都要通過 type 屬性來識別。一旦被確認(rèn),它將完全覆蓋默認(rèn)的安裝程序,并執(zhí)行自己的安裝邏輯。
一個實(shí)際用例:
phpDocumentor 的特殊模板需要安裝在 /vendor 以外的其它目錄中。 因此他們選擇 phpdocumentor-template
安裝類型 并為此類型創(chuàng)建了一個插件,以便將他們的模板發(fā)送到正確的目錄中。
在這樣一個模板包的例子中 composer.json 將使用以下設(shè)置:
{
"name": "phpdocumentor/template-responsive",
"type": "phpdocumentor-template",
"require": {
"phpdocumentor/template-installer-plugin": "*"
}
}
重要提示: 為了確保這個模板安裝程序在安裝模板包之前就已存在,模板包必須寫入對此安裝程序包的依賴。
一個自定義安裝程序通常是以 Composer 插件的形式存在,并包含有一個類,它實(shí)現(xiàn)了 Composer\Installer\InstallerInterface
這個接口。
一個基本的安裝程序插件必須由3個文件組成:
My\Project\Composer\Plugin.php
,其中的類必須實(shí)現(xiàn) Composer\Plugin\PluginInterface
接口。My\Project\Composer\Installer.php
,其中的類必須實(shí)現(xiàn) Composer\Installer\InstallerInterface
接口。此處的包文件和普通資源包是相同的,但需要滿足以下條件:
composer-plugin
。class
元素,它定義了插件類的名稱(包含命名空間)。如果這個包有多個插件類,可以使用數(shù)組的形式進(jìn)行定義。實(shí)例:
{
"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 的插件,它必須實(shí)現(xiàn) Composer\Plugin\PluginInterface
這個接口。它可以在 activate()
方法中注冊自定義安裝程序。
這個類可以被放在任何位置、使用任何名字,只要能夠根據(jù) extra.class
中的定義被自動加載即可。
實(shí)例:
<?php
namespace phpDocumentor\Composer;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
class TemplateInstallerPlugin implements PluginInterface
{
public function activate(Composer $composer, IOInterface $io)
{
$installer = new TemplateInstaller($io, $composer);
$composer->getInstallationManager()->addInstaller($installer);
}
}
這個類用于執(zhí)行自定義的安裝過程,它必須實(shí)現(xiàn) Composer\Installer\InstallerInterface
這個接口(或者繼承了另一個實(shí)現(xiàn)此接口的安裝程序類)。它將會對安裝類型中定義的字符串執(zhí)行 supports()
方法驗(yàn)證,一旦通過就采用對應(yīng)的安裝程序。
注意: 請慎重選擇你的 安裝類型 名稱,建議遵循這樣的格式:vendor-type
。例如:phpdocumentor-template
。
InstallerInterface 類定義了以下方法(請查閱源碼以獲得更詳細(xì)的信息):
實(shí)例:
<?php
namespace phpDocumentor\Composer;
use Composer\Package\PackageInterface;
use Composer\Installer\LibraryInstaller;
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;
}
}
這個例子演示了,簡單的繼承 Composer\Installer\LibraryInstaller
類來剝離 phpdocumentor/template-
前綴,并用剩余的部分重新組裝了一個完全不同的安裝路徑。
并非安裝在 /vendor
目錄,任何使用這個安裝程序的資源包,將被放置在 /data/templates/<stripped name>
目錄中。
更多建議: