2013-09-05 18:08:17 +00:00
|
|
|
<!--
|
|
|
|
tagline: Modify and extend Composer's functionality
|
|
|
|
-->
|
|
|
|
|
|
|
|
# Setting up and using plugins
|
|
|
|
|
|
|
|
## Synopsis
|
|
|
|
|
|
|
|
You may wish to alter or expand Composer's functionality with your own. For
|
|
|
|
example if your environment poses special requirements on the behaviour of
|
|
|
|
Composer which do not apply to the majority of its users or if you wish to
|
|
|
|
accomplish something with composer in a way that is not desired by most users.
|
|
|
|
|
|
|
|
In these cases you could consider creating a plugin to handle your
|
|
|
|
specific logic.
|
|
|
|
|
|
|
|
## Creating a Plugin
|
|
|
|
|
2015-06-02 18:09:57 +00:00
|
|
|
A plugin is a regular Composer package which ships its code as part of the
|
2013-09-05 18:08:17 +00:00
|
|
|
package and may also depend on further packages.
|
|
|
|
|
|
|
|
### Plugin Package
|
|
|
|
|
|
|
|
The package file is the same as any other package file but with the following
|
|
|
|
requirements:
|
|
|
|
|
2015-06-02 18:09:57 +00:00
|
|
|
1. The [type][1] attribute must be `composer-plugin`.
|
|
|
|
2. The [extra][2] attribute must contain an element `class` defining the
|
2013-09-05 18:08:17 +00:00
|
|
|
class name of the plugin (including namespace). If a package contains
|
2015-06-02 18:09:57 +00:00
|
|
|
multiple plugins, this can be array of class names.
|
|
|
|
3. You must require the special package called `composer-plugin-api`
|
|
|
|
to define which Plugin API versions your plugin is compatible with.
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2015-06-02 18:09:57 +00:00
|
|
|
The required version of the `composer-plugin-api` follows the same [rules][7]
|
|
|
|
as a normal package's, except for the `1.0`, `1.0.0` and `1.0.0.0` _exact_
|
|
|
|
values. In only these three cases, Composer will assume your plugin
|
|
|
|
actually meant `^1.0` instead. This was introduced to maintain BC with
|
|
|
|
the old style of declaring the Plugin API version.
|
|
|
|
|
|
|
|
In other words, `"require": { "composer-plugin-api": "1.0.0" }` means
|
|
|
|
`"require": { "composer-plugin-api": "^1.0" }`.
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2015-06-02 18:09:57 +00:00
|
|
|
The current composer plugin API version is 1.0.0.
|
|
|
|
|
|
|
|
An example of a valid plugin `composer.json` file (with the autoloading
|
|
|
|
part omitted):
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
```json
|
|
|
|
{
|
|
|
|
"name": "my/plugin-package",
|
|
|
|
"type": "composer-plugin",
|
|
|
|
"require": {
|
2015-06-02 18:09:57 +00:00
|
|
|
"composer-plugin-api": "~1.0"
|
|
|
|
},
|
|
|
|
"extra": {
|
|
|
|
"class": "My\\Plugin"
|
2013-09-05 18:08:17 +00:00
|
|
|
}
|
2014-05-19 10:17:07 +00:00
|
|
|
}
|
|
|
|
```
|
2013-09-05 18:08:17 +00:00
|
|
|
|
|
|
|
### Plugin Class
|
|
|
|
|
|
|
|
Every plugin has to supply a class which implements the
|
|
|
|
[`Composer\Plugin\PluginInterface`][3]. The `activate()` method of the plugin
|
|
|
|
is called after the plugin is loaded and receives an instance of
|
|
|
|
[`Composer\Composer`][4] as well as an instance of
|
|
|
|
[`Composer\IO\IOInterface`][5]. Using these two objects all configuration can
|
|
|
|
be read and all internal objects and state can be manipulated as desired.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
```php
|
|
|
|
<?php
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
namespace phpDocumentor\Composer;
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
use Composer\Composer;
|
|
|
|
use Composer\IO\IOInterface;
|
|
|
|
use Composer\Plugin\PluginInterface;
|
|
|
|
|
|
|
|
class TemplateInstallerPlugin implements PluginInterface
|
|
|
|
{
|
|
|
|
public function activate(Composer $composer, IOInterface $io)
|
2013-09-05 18:08:17 +00:00
|
|
|
{
|
2014-05-19 10:17:07 +00:00
|
|
|
$installer = new TemplateInstaller($io, $composer);
|
|
|
|
$composer->getInstallationManager()->addInstaller($installer);
|
2013-09-05 18:08:17 +00:00
|
|
|
}
|
2014-05-19 10:17:07 +00:00
|
|
|
}
|
|
|
|
```
|
2013-09-05 18:08:17 +00:00
|
|
|
|
|
|
|
## Event Handler
|
|
|
|
|
|
|
|
Furthermore plugins may implement the
|
|
|
|
[`Composer\EventDispatcher\EventSubscriberInterface`][6] in order to have its
|
|
|
|
event handlers automatically registered with the `EventDispatcher` when the
|
|
|
|
plugin is loaded.
|
|
|
|
|
2015-03-04 23:50:10 +00:00
|
|
|
Plugin can subscribe to any of the available [script events](scripts.md#event-names).
|
2013-11-27 11:55:12 +00:00
|
|
|
|
2013-09-05 18:08:17 +00:00
|
|
|
Example:
|
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
```php
|
|
|
|
<?php
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
namespace Naderman\Composer\AWS;
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
use Composer\Composer;
|
|
|
|
use Composer\EventDispatcher\EventSubscriberInterface;
|
|
|
|
use Composer\IO\IOInterface;
|
|
|
|
use Composer\Plugin\PluginInterface;
|
|
|
|
use Composer\Plugin\PluginEvents;
|
|
|
|
use Composer\Plugin\PreFileDownloadEvent;
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
class AwsPlugin implements PluginInterface, EventSubscriberInterface
|
|
|
|
{
|
|
|
|
protected $composer;
|
|
|
|
protected $io;
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
public function activate(Composer $composer, IOInterface $io)
|
|
|
|
{
|
|
|
|
$this->composer = $composer;
|
|
|
|
$this->io = $io;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getSubscribedEvents()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
PluginEvents::PRE_FILE_DOWNLOAD => array(
|
|
|
|
array('onPreFileDownload', 0)
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
public function onPreFileDownload(PreFileDownloadEvent $event)
|
|
|
|
{
|
|
|
|
$protocol = parse_url($event->getProcessedUrl(), PHP_URL_SCHEME);
|
2013-09-05 18:08:17 +00:00
|
|
|
|
2014-05-19 10:17:07 +00:00
|
|
|
if ($protocol === 's3') {
|
|
|
|
$awsClient = new AwsClient($this->io, $this->composer->getConfig());
|
|
|
|
$s3RemoteFilesystem = new S3RemoteFilesystem($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient);
|
|
|
|
$event->setRemoteFilesystem($s3RemoteFilesystem);
|
2013-09-05 18:08:17 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-19 10:17:07 +00:00
|
|
|
}
|
|
|
|
```
|
2013-09-05 18:08:17 +00:00
|
|
|
|
|
|
|
## Using Plugins
|
|
|
|
|
|
|
|
Plugin packages are automatically loaded as soon as they are installed and will
|
|
|
|
be loaded when composer starts up if they are found in the current project's
|
|
|
|
list of installed packages. Additionally all plugin packages installed in the
|
|
|
|
`COMPOSER_HOME` directory using the composer global command are loaded before
|
|
|
|
local project plugins are loaded.
|
|
|
|
|
|
|
|
> You may pass the `--no-plugins` option to composer commands to disable all
|
2015-03-04 23:50:10 +00:00
|
|
|
> installed plugins. This may be particularly helpful if any of the plugins
|
2013-09-05 18:08:17 +00:00
|
|
|
> causes errors and you wish to update or uninstall it.
|
|
|
|
|
|
|
|
[1]: ../04-schema.md#type
|
|
|
|
[2]: ../04-schema.md#extra
|
|
|
|
[3]: https://github.com/composer/composer/blob/master/src/Composer/Plugin/PluginInterface.php
|
|
|
|
[4]: https://github.com/composer/composer/blob/master/src/Composer/Composer.php
|
|
|
|
[5]: https://github.com/composer/composer/blob/master/src/Composer/IO/IOInterface.php
|
|
|
|
[6]: https://github.com/composer/composer/blob/master/src/Composer/EventDispatcher/EventSubscriberInterface.php
|
2015-06-02 18:09:57 +00:00
|
|
|
[7]: ../01-basic-usage.md#package-versions
|