Chapter 16. Plugins

16.1. Events

Reflect uses a Symfony EventDispatcher Component to allow you to easily extend the features list.

The EventDispatcher component allow Reflect components to communicate with each other by dispatching events and listening to them.

16.1.1. Event Dispatcher

Reflect implement interface Bartlett\Reflect\Event\DispatcherInterface. You can add event listeners and event subscribers to this object.

listeners

Callable functions that are registered on an event dispatcher for specific events.

subscribers

Classes that tell an event dispatcher what methods to listen to and what functions on the class to invoke when the event is triggered. Event subscribers subscribe event listeners to an event dispatcher.

16.1.2. Getting an EventDispatcher

You can get the EventDispatcher of Bartlett\Reflect\Event\DispatcherInterface by calling the getEventDispatcher() method.

Here is an example :

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

$ed = $reflect->getEventDispatcher();

16.1.3. Adding Event Listeners

After you have the event dispatcher, you can register event listeners that listen to specific events.

Example 16.1. Add a listener that will echo out files when they are parsed

<?php

use Bartlett\Reflect;
use Symfony\Component\EventDispatcher\GenericEvent;

$reflect = new Reflect;

$reflect->getEventDispatcher()->addListener(
    'reflect.progress',
    function (GenericEvent $e) {
        printf(
            'Parsing Data source "%s" in progress ... File "%s"' . PHP_EOL,
            $e['source'],
            $e['file']->getPathname()
        );
    }
);

Example 16.2. Add a listener that will exploit each AST of file parsed

<?php

use Bartlett\Reflect;
use Symfony\Component\EventDispatcher\GenericEvent;

$reflect = new Reflect;

$reflect->getEventDispatcher()->addListener(
    'reflect.success',
    function (GenericEvent $e) {
        $ast = unserialize($e['ast']);
        printf(
            'Parsing Data source "%s", file "%s". AST = %s' . PHP_EOL,
            $e['source'],
            $e['file']->getPathname(),
            print_r($ast, true)
        );

    }
);

16.1.4. Event Subscribers

Event subscribers are classes that implement interface Symfony\Component\EventDispatcher\EventSubscriberInterface. They are used to register one or more event listeners to methods of the class. Event subscribers tell event dispatcher exactly which events to listen to and what method to invoke on the class.

Reflect plugins follow the event subscribers behaviors. Have a look on AnalyserPlugin :

<?php
class AnalyserPlugin implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            'reflect.complete' => 'onReflectComplete',
        );
    }
}

This plugin registers event listeners to the reflect.complete event of a Reflect parse request.

When the reflect.complete event is emitted, the onReflectComplete instance method of the plugin is invoked.

16.1.5. Events lifecycle

Event Action Informations available

reflect.progess

Before to parse a new file of the data source.

source data source identifier or its alias file current file parsed in the data source

reflect.success

After parsing the current file ( A cached request will not trigger this event )

source data source identifier or its alias file current file parsed in the data source ast the Abstract Syntax Tree result of PHP-Parser

reflect.cache

A previous cached request was found and return the AST.

source data source identifier or its alias file current file parsed in the data source ast the Abstract Syntax Tree result of PHP-Parser

reflect.error

When PHP Parser raise an error

source data source identifier or its alias file current file parsed in the data source error PHP Parser error message

reflect.complete

When a parse request is over.

source data source identifier or its alias

16.2. Console Commands

If your plugin should be accessible on the command line, and provides some new commands, you have to register them with the static getCommands() method.

Have a look on AnalyserPlugin, that provide two new commands: analyser:list and analyser:run.

<?php
class AnalyserPlugin implements EventSubscriberInterface
{
    public static function getCommands()
    {
        $commands   = array();
        $commands[] = new AnalyserListCommand;
        $commands[] = new AnalyserRunCommand;

        return $commands;
    }
[Caution]

If your plugin must not provide console command, your getCommands() static method should return an empty php array.

16.3. Register Plugins

[Important]

Don’t forget to register a plugin with addSubscriber() method, if you want to use it.

Example 16.3. Register the cache plugin

<?php

use Bartlett\Reflect;
use Bartlett\Reflect\Plugin\Cache\CachePlugin;

$reflect = new Reflect;

$reflect->addSubscriber( new CachePlugin($cache) );

Learn more about the cache plugin, see Section 8.2.1, “Cache Plugin”