serafim/annotation-listener

This package is abandoned and no longer maintained. No replacement package was suggested.

1.0.10 2016-02-25 13:00 UTC

README

Build Status Quality Latest Stable Version License

What is it?

This fully automated aggregator (listeners) of annotations, provides convenient access information on their context and annotation objects in one place. The component provides the ability to process both individually each annotation and annotation group with class context.

The use consists of 3 parts:

  • Annotation declaration (see http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html)
  • Annotation target (Place where specified the annotation)
  • Listener - Сlass that defines the behavior of the logic for the places specified desired annotation. This class takes an object of reflection where indicated annotation in first argument and annotation object as second argument.

Installation

Using composer composer require serafim/annotation-listener

Laravel 5.1+

  • Register autoloader. Replace in bootstrap/autoload.php (line ~19)
require __DIR__.'/../vendor/autoload.php';

to

$loader = require __DIR__.'/../vendor/autoload.php';
Serafim\AnnotationListener\Reader::loader([$loader, 'loadClass']);
  • Add service provider in config/app.php
    'providers' => [
        Serafim\AnnotationListener\Laravel\ServiceProvider::class,
    ]
  • Publish configs in (optional): php artisan vendor:publish (see result in config/annotation-listener.php)

Usage

  • Create annotation what you want (@Deprecated as example):
/**
 * @Annotation
 */
class Deprecated
{
    /**
     * @var string
     */
    public $value = '%s is deprecated';
}
  • Apply annotation to target context:
/**
 * @Deprecated
 */
class DeprecatedClassExample
{
}
  • Create annotation listener:
use Serafim\AnnotationListener\Listener;

/**
 * @Listener(Deprecated::class)
 */
class DeprecatedAnnotationListener
{
    public function handle($context, $annotation)
    {
        // Take context name (can be instance of ReflectionClass, 
        //   ReflectionProperty or ReflectionMethod)
        $name = ($context instanceof \ReflectionClass)
            ? $context->getName()
            : $context->getDeclaringClass()->getName();
        
        
        // Write log message with annotation value
        \Log::warning(sprintf($annotation->value, $name)); 
        // => Outputs to laravel.log: "DeprecatedClassExample is deprecated"
    }
}

Another example (using with Analogue ORM)

Annotation:

use Doctrine\Common\Annotations\Annotation\Target;

/**
 * @Annotation
 * @Target("CLASS")
 */
class Entities
{
    /**
     * @var array
     */
    public $value = [];
}

Attach annotaion to Mapper:

use Analogue\ORM\EntityMap;

/**
 * @Entities(MyEntity::class)
 */
class MyMapper extends EntityMap { }

Create annotation listener:

use ReflectionClass;
use Analogue\ORM\System\Manager;
use Serafim\AnnotationListener\Listener;
use Serafim\AnnotationListener\ListenerInterface;

/**
 * @Listener(Entities::class)
 */
class EntitiesListener implements ListenerInterface
{
    /**
     * @param ReflectionClass $context
     * @param Entities $annotation
     */
    public function handle($context, $annotation)
    {
        /** @var Manager $orm */
        $orm = app('analogue'); // This is analogue manager

        // Get all entities declared for target mapper
        foreach ($annotation->value as $entity) {
            // Register mapper for target entity 
            // see: https://github.com/analogueorm/analogue/wiki/Configuring-Entity-Maps
            $orm->register($entity, $context->getName());
        }
    }
}

Manual installation without ServiceProvider (using simple file cache)

<?php
use Serafim\AnnotationListener\Finder;
use Serafim\AnnotationListener\Reader;
use Serafim\AnnotationListener\Cache\SimpleFileCache;

/**
 * Register composer loader
 */
$loader = require __DIR__ . '/../vendor/autoload.php';
Reader::loader([$loader, 'loadClass']);

/**
 * Create file cache driver  
 * Note: You can use `null` or `Serafim\AnnotationListener\Cache\NullCache` 
 *   for disable cache
 */
$cache  = new SimpleFileCache(__DIR__ . '/path/to/storage');

/**
 * New annotation listeners finder
 */
$finder = (new Finder($cache))
    ->in(['path/to/annotations'])
    ->exec();