Skip to content

Commit

Permalink
Merge branch 'custom-annotations' of https://github.com/tedslittlerob…
Browse files Browse the repository at this point in the history
…ot/annotations into 5.0

Signed-off-by: Adam Engebretson <adam@enge.me>

Conflicts:
	src/AnnotationsServiceProvider.php
  • Loading branch information
adamgoose committed Feb 25, 2015
2 parents 8faf055 + 65f4b8a commit b0aadc0
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 127 deletions.
67 changes: 67 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,70 @@ public function routeScans() {
return $classes;
}
```

## Custom Annotations

If you want to register your own annotations, create a namespace containing subclasses of `Collective\Annotations\Routing\Annotations\Annotations\Annotation` - let's say `App\Http\Annotations`.

Then, in your annotations service provider, override the `addRoutingAnnotations( RouteScanner $scanner )` method, and register your routing annotations namespace:

```php
<?php namespace App\Providers;

use Collective\Annotations\Routing\Annotations\Scanner as RouteScanner;

/* ... then, in the class definition ... */

/**
* Add annotation classes to the route scanner
*
* @param RouteScanner $namespace
*/
public function addRoutingAnnotations( RouteScanner $scanner )
{
$scanner->addAnnotationNamespace( 'App\Http\Annotations' );
}
```

Your annotation classes must must have the `@Annotation` class annotation (see the following example).

There is an equivalent method for event annotations: `addEventAnnotations( EventScanner $scanner )`.

### Custom Annotation Example

Here is an example to make an `@Auth` annotation. It provides the same functionality as using the annotation `@Middleware("auth")`.

In a namespace - in this example, `App\Annotations`:

```php
<?php namespace App\Http\Annotations;

use Collective\Annotations\Routing\Annotations\Annotations\Annotation;
use Collective\Annotations\Routing\Annotations\MethodEndpoint;
use ReflectionMethod;

/**
* @Annotation
*/
class Auth extends Annotation {

/**
* {@inheritdoc}
*/
public function modify(MethodEndpoint $endpoint, ReflectionMethod $method)
{
if ($endpoint->hasPaths())
{
foreach ($endpoint->getPaths() as $path)
{
$path->middleware = array_merge($path->middleware, (array) 'auth');
}
}
else
{
$endpoint->middleware = array_merge($endpoint->middleware, (array) 'auth');
}
}

}
```
132 changes: 132 additions & 0 deletions src/AnnotationScanner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php namespace Collective\Annotations;

use Collective\Annotations\NamespaceToPathConverterTrait;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\SimpleAnnotationReader;
use ReflectionClass;
use Symfony\Component\Finder\Finder;

abstract class AnnotationScanner {

use NamespaceToPathConverterTrait;

/**
* Namespaces to check for annotation reader annotation classes.
*
* @var string
*/
protected $namespaces = [];

/**
* The paths to scan for annotations.
*
* @var array
*/
protected $scan = [];

/**
* Create a new scanner instance.
*
* @param array $scan
* @return void
*/
public function __construct(array $scan)
{
$this->scan = $scan;
}

/**
* Create a new scanner instance.
*
* @param array $scan
* @return static
*/
public static function create(array $scan)
{
return new static($scan);
}

/**
* Get all of the ReflectionClass instances in the scan array.
*
* @return array
*/
protected function getClassesToScan()
{
$classes = [];

foreach ($this->scan as $class)
{
try
{
$classes[] = new ReflectionClass($class);
}
catch (Exception $e)
{
//
}
}

return $classes;
}

/**
* Set the classes to scan
*
* @param array $scans
*/
public function setClassesToScan( array $scans )
{
$this->scan = $scans;
}

/**
* Add an annotation namespace for the SimpleAnnotationReader instance.
*
* If the second parameter is null, it will assume the namespace is PSR-4'd
* inside your app folder.
*
* @param string $namespace
* @param string $path
*/
public function addAnnotationNamespace($namespace, $path = null)
{
$this->namespaces[] = $namespace;

return $this->registerAnnotationsPathWithRegistry(
$path ?: $this->getPathFromNamespace( $namespace )
);
}

/**
* Register the annotator files with the annotation registry
*
* @param string $path
* @return $this
*/
public function registerAnnotationsPathWithRegistry( $path )
{
foreach (Finder::create()->files()->in( $path ) as $file)
{
AnnotationRegistry::registerFile($file->getRealPath());
}

return $this;
}

/**
* Get an annotation reader instance.
*
* @return \Doctrine\Common\Annotations\SimpleAnnotationReader
*/
protected function getReader()
{
$reader = new SimpleAnnotationReader;

foreach ($this->namespaces as $namespace)
$reader->addNamespace($namespace);

return $reader;
}

}
69 changes: 67 additions & 2 deletions src/AnnotationsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public function __construct(Application $app)
*/
public function register()
{
$this->registerRouteScanner();
$this->registerEventScanner();

$this->registerCommands();
}

Expand All @@ -84,8 +87,12 @@ public function register()
*/
public function boot()
{
$this->addEventAnnotations( $this->app->make('annotations.event.scanner') );

$this->loadAnnotatedEvents();

$this->addRoutingAnnotations( $this->app->make('annotations.route.scanner') );

if ( ! $this->app->routesAreCached())
{
$this->loadAnnotatedRoutes();
Expand Down Expand Up @@ -134,6 +141,60 @@ protected function registerRouteScanCommand()
});
}

/**
* Register the scanner.
*
* @return void
*/
protected function registerRouteScanner()
{
$this->app->bindShared('annotations.route.scanner', function ($app)
{
$scanner = new RouteScanner([]);

$scanner->addAnnotationNamespace(
'Collective\Annotations\Routing\Annotations\Annotations',
__DIR__.'/Routing/Annotations/Annotations'
);

return $scanner;
});
}

/**
* Register the scanner.
*
* @return void
*/
protected function registerEventScanner()
{
$this->app->bindShared('annotations.event.scanner', function ($app)
{
$scanner = new EventScanner([]);

$scanner->addAnnotationNamespace(
'Collective\Annotations\Events\Annotations\Annotations',
__DIR__.'/Events/Annotations/Annotations'
);

return $scanner;
});
}

/**
* Add annotation classes to the event scanner
*
* @param RouteScanner $namespace
*/
public function addEventAnnotations( EventScanner $scanner ) {}

/**
* Add annotation classes to the route scanner
*
* @param RouteScanner $namespace
*/
public function addRoutingAnnotations( RouteScanner $scanner ) {}

/**
* Load the annotated events.
*
Expand Down Expand Up @@ -168,7 +229,9 @@ protected function scanEvents()
return;
}

$scanner = new EventScanner($scans);
$scanner = $this->app->make('annotations.event.scanner');

$scanner->setClassesToScan($scans);

file_put_contents(
$this->finder->getScannedEventsPath(), '<?php ' . $scanner->getEventDefinitions()
Expand Down Expand Up @@ -221,7 +284,9 @@ protected function scanRoutes()
return;
}

$scanner = new RouteScanner($scans);
$scanner = $this->app->make('annotations.route.scanner');

$scanner->setClassesToScan($scans);

file_put_contents(
$this->finder->getScannedRoutesPath(), '<?php ' . $scanner->getRouteDefinitions()
Expand Down
10 changes: 6 additions & 4 deletions src/Console/EventScanCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ protected function getEventDefinitions()
{
$provider = 'Collective\Annotations\AnnotationsServiceProvider';

return '<?php '.PHP_EOL.PHP_EOL.Scanner::create(
$this->laravel->getProvider($provider)->eventScans()
)->getEventDefinitions().PHP_EOL;
$scanner = $this->laravel->make('annotations.event.scanner');

$scanner->setClassesToScan($this->laravel->getProvider($provider)->eventScans());

return '<?php '.PHP_EOL.PHP_EOL.$scanner->getEventDefinitions().PHP_EOL;
}

/**
Expand All @@ -89,4 +91,4 @@ protected function getOptions()
];
}

}
}
10 changes: 6 additions & 4 deletions src/Console/RouteScanCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ protected function getRouteDefinitions()
{
$provider = 'Collective\Annotations\AnnotationsServiceProvider';

return '<?php '.PHP_EOL.PHP_EOL.Scanner::create(
$this->laravel->getProvider($provider)->routeScans()
)->getRouteDefinitions().PHP_EOL;
$scanner = $this->laravel->make('annotations.route.scanner');

$scanner->setClassesToScan($this->laravel->getProvider($provider)->routeScans());

return '<?php '.PHP_EOL.PHP_EOL.$scanner->getRouteDefinitions().PHP_EOL;
}

/**
Expand Down Expand Up @@ -103,4 +105,4 @@ protected function getOptions()
];
}

}
}
Loading

0 comments on commit b0aadc0

Please sign in to comment.