Jens A. Koch

How to create a Composer Plugin…

Composer Plugins

Composer supports plugins. A plugins is directly activated, after it is downloaded.

You would simply need to add the plugin package to the require section of your composer.json.

When the plugin is instantiated the activate() method is called by Composer automatically.

You get access to the Composer instance and the IO.

You can now add your custom functionality: the new stuff your plugin does.

Referencing Composer/Plugin/PluginManager

Composer Plugin Events

A plugin can subscribe to Composer events.

When you want to extend the behavior of Composer itself, you might try combining the plugin with the event system.

Composer provides 4 main categories of events: Command, Installer, Package and Plugin events.
Just take a look at the full list of the event names.

To connect your plugin to the event system you will have to add a description table, explaining
which of your plugin methods should be called on a certain event.
This is done by declaring an array() in the static method getSubscribedEvents().

An array item looks like this:

PackageEvents::PRE_PACKAGE_UPDATE => 'onPrePackageUpdate'

This definition tells Composer, that the internal event PRE_PACKAGE_UPDATE should fire your onPrePackageUpdate() method.

The following example implementation of a Composer plugin contains several event bindings for demonstration purposes.
Each of the methods invoked by the event system will use the IO system to report when they are called.
This should give you an understanding of the order of events during an application run of Composer.

<?php
namespace ComposerPlugin\ComposerExamplePlugin;

use Composer\Composer;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Installer\InstallerEvent;
use Composer\Installer\InstallerEvents;
use Composer\Installer\PackageEvent;
use Composer\Installer\PackageEvents;
use Composer\IO\IOInterface;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\PreFileDownloadEvent;
use Composer\Script\Event;
use Composer\Script\ScriptEvents;

class ComposerExamplePlugin implements PluginInterface, EventSubscriberInterface
{

    /** @type Composer */
    protected $composer;

    /** @type IOInterface */
    protected $io;

    public function activate(Composer $composer, IOInterface $io)
    {
        $this->composer = $composer;
        $this->io = $io;
        $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
    }

/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call. Then the priority defaults to 0.
* * An array composed of the method name to call and the priority.
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset.
*
* Examples:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*/
public static function getSubscribedEvents()
{
    return [
        PluginEvents::COMMAND => 'onCommand',
        PluginEvents::PRE_FILE_DOWNLOAD => 'onPreFileDownload',
        ScriptEvents::PRE_UPDATE_CMD => 'onPreUpdateCmd',
        ScriptEvents::POST_UPDATE_CMD => 'onPostUpdateCmd',
        InstallerEvents::PRE_DEPENDENCIES_SOLVING => 'onPreDependenciesSolving',
        InstallerEvents::POST_DEPENDENCIES_SOLVING => 'onPostDependenciesSolving',
        PackageEvents::PRE_PACKAGE_UPDATE => 'onPrePackageUpdate',
        PackageEvents::POST_PACKAGE_UPDATE => 'onPostPackageUpdate',
        PackageEvents::PRE_PACKAGE_INSTALL => 'onPrePackageInstall',
        PackageEvents::POST_PACKAGE_INSTALL => 'onPostPackageInstall',
    ];
}

public function onCommand(CommandEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPreFileDownload(PreFileDownloadEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPreUpdateCmd(Event $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPostUpdateCmd(Event $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPrePackageUpdate(PackageEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPostPackageUpdate(PackageEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPrePackageInstall(PackageEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPostPackageInstall(PackageEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPreDependenciesSolving(InstallerEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

public function onPostDependenciesSolving(InstallerEvent $event)
{
    $this->io->write(__CLASS__ . '::' . __METHOD__ . "()");
}

}

 

Comments Off on How to create a Composer Plugin…

Comments are closed.