From 0c353e68b09587e42f9d33cf9b1573a1e199d060 Mon Sep 17 00:00:00 2001 From: Tom Shafer Date: Fri, 4 Dec 2015 20:46:30 -0500 Subject: [PATCH] Applied fixes from StyleCI --- src/AnnotationFinder.php | 21 +- src/AnnotationScanner.php | 235 +++++----- src/AnnotationsServiceProvider.php | 123 ++--- src/Console/EventScanCommand.php | 15 +- src/Console/ModelScanCommand.php | 17 +- src/Console/RouteScanCommand.php | 18 +- .../Eloquent/Annotations/Annotations/Bind.php | 14 +- .../InvalidBindingResolverException.php | 10 +- src/Database/Eloquent/Annotations/Scanner.php | 37 +- src/Events/Annotations/Annotations/Hears.php | 10 +- src/Events/Annotations/Scanner.php | 116 +++-- src/NamespaceToPathConverterTrait.php | 25 +- src/Routing/Annotations/AbstractPath.php | 67 +-- src/Routing/Annotations/AnnotationSet.php | 109 ++--- .../Annotations/Annotations/Annotation.php | 227 ++++----- src/Routing/Annotations/Annotations/Any.php | 11 +- .../Annotations/Annotations/Controller.php | 108 +++-- .../Annotations/Annotations/Delete.php | 11 +- src/Routing/Annotations/Annotations/Get.php | 11 +- .../Annotations/Annotations/Middleware.php | 71 ++- .../Annotations/Annotations/Options.php | 11 +- src/Routing/Annotations/Annotations/Patch.php | 11 +- src/Routing/Annotations/Annotations/Post.php | 11 +- src/Routing/Annotations/Annotations/Put.php | 11 +- .../Annotations/Annotations/Resource.php | 134 +++--- src/Routing/Annotations/Annotations/Route.php | 33 +- src/Routing/Annotations/Annotations/Where.php | 51 +-- .../Annotations/EndpointCollection.php | 41 +- src/Routing/Annotations/EndpointInterface.php | 73 +-- src/Routing/Annotations/EndpointTrait.php | 126 +++-- src/Routing/Annotations/MethodEndpoint.php | 286 ++++++------ src/Routing/Annotations/Path.php | 60 +-- src/Routing/Annotations/ResourceEndpoint.php | 433 +++++++++--------- src/Routing/Annotations/ResourcePath.php | 102 +++-- src/Routing/Annotations/Scanner.php | 197 ++++---- tests/AnnotationsServiceProviderTest.php | 94 ++-- tests/Models/ModelAnnotationScannerTest.php | 49 +- .../Models/fixtures/annotations/AnyModel.php | 10 +- .../Routing/RoutingAnnotationScannerTest.php | 75 +-- .../fixtures/annotations/AnyController.php | 16 +- .../fixtures/annotations/BasicController.php | 44 +- 41 files changed, 1577 insertions(+), 1547 deletions(-) diff --git a/src/AnnotationFinder.php b/src/AnnotationFinder.php index 526527c..a0c1aa4 100644 --- a/src/AnnotationFinder.php +++ b/src/AnnotationFinder.php @@ -1,9 +1,11 @@ -app = $app; } - /** * Determine if the application routes have been scanned. * @@ -35,7 +36,7 @@ public function routesAreScanned() */ public function getScannedRoutesPath() { - return $this->app['path.storage'] . '/framework/routes.scanned.php'; + return $this->app['path.storage'].'/framework/routes.scanned.php'; } /** @@ -55,7 +56,7 @@ public function eventsAreScanned() */ public function getScannedEventsPath() { - return $this->app['path.storage'] . '/framework/events.scanned.php'; + return $this->app['path.storage'].'/framework/events.scanned.php'; } /** @@ -65,7 +66,7 @@ public function getScannedEventsPath() */ public function modelsAreScanned() { - return $this->app['files']->exists($this->getScannedModelsPath()); + return $this->app['files']->exists($this->getScannedModelsPath()); } /** @@ -75,6 +76,6 @@ public function modelsAreScanned() */ public function getScannedModelsPath() { - return $this->app['path.storage'] . '/framework/models.scanned.php'; + return $this->app['path.storage'].'/framework/models.scanned.php'; } -} \ No newline at end of file +} diff --git a/src/AnnotationScanner.php b/src/AnnotationScanner.php index 2454e99..e290c45 100644 --- a/src/AnnotationScanner.php +++ b/src/AnnotationScanner.php @@ -1,133 +1,132 @@ -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) - { + /** + * 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; - } + } + + /** + * 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; + } } diff --git a/src/AnnotationsServiceProvider.php b/src/AnnotationsServiceProvider.php index 4fce55a..85a439f 100644 --- a/src/AnnotationsServiceProvider.php +++ b/src/AnnotationsServiceProvider.php @@ -1,17 +1,19 @@ -addRoutingAnnotations($this->app->make('annotations.route.scanner')); - if ( ! $this->app->routesAreCached()) - { + if (!$this->app->routesAreCached()) { $this->loadAnnotatedRoutes(); } @@ -129,15 +130,13 @@ public function boot() */ protected function registerCommands() { - foreach (array_keys($this->commands) as $command) - { + foreach (array_keys($this->commands) as $command) { $method = "register{$command}Command"; call_user_func_array([$this, $method], []); } $this->commands(array_values($this->commands)); } - /** * Register the command. * @@ -145,8 +144,7 @@ protected function registerCommands() */ protected function registerEventScanCommand() { - $this->app->singleton('command.event.scan', function ($app) - { + $this->app->singleton('command.event.scan', function ($app) { return new EventScanCommand($app['files'], $this); }); } @@ -158,8 +156,7 @@ protected function registerEventScanCommand() */ protected function registerRouteScanCommand() { - $this->app->singleton('command.route.scan', function ($app) - { + $this->app->singleton('command.route.scan', function ($app) { return new RouteScanCommand($app['files'], $this); }); } @@ -171,8 +168,7 @@ protected function registerRouteScanCommand() */ protected function registerModelScanCommand() { - $this->app->singleton('command.model.scan', function ($app) - { + $this->app->singleton('command.model.scan', function ($app) { return new ModelScanCommand($app['files'], $this); }); } @@ -184,13 +180,12 @@ protected function registerModelScanCommand() */ protected function registerRouteScanner() { - $this->app->bindShared('annotations.route.scanner', function ($app) - { + $this->app->bindShared('annotations.route.scanner', function ($app) { $scanner = new RouteScanner([]); $scanner->addAnnotationNamespace( 'Collective\Annotations\Routing\Annotations\Annotations', - __DIR__ . '/Routing/Annotations/Annotations' + __DIR__.'/Routing/Annotations/Annotations' ); return $scanner; @@ -204,13 +199,12 @@ protected function registerRouteScanner() */ protected function registerEventScanner() { - $this->app->bindShared('annotations.event.scanner', function ($app) - { + $this->app->bindShared('annotations.event.scanner', function ($app) { $scanner = new EventScanner([]); $scanner->addAnnotationNamespace( 'Collective\Annotations\Events\Annotations\Annotations', - __DIR__ . '/Events/Annotations/Annotations' + __DIR__.'/Events/Annotations/Annotations' ); return $scanner; @@ -224,13 +218,12 @@ protected function registerEventScanner() */ protected function registerModelScanner() { - $this->app->bindShared('annotations.model.scanner', function ($app) - { + $this->app->bindShared('annotations.model.scanner', function ($app) { $scanner = new ModelScanner([]); $scanner->addAnnotationNamespace( 'Collective\Annotations\Database\Eloquent\Annotations\Annotations', - __DIR__ . '/Database/Eloquent/Annotations/Annotations' + __DIR__.'/Database/Eloquent/Annotations/Annotations' ); return $scanner; @@ -238,7 +231,7 @@ protected function registerModelScanner() } /** - * Add annotation classes to the event scanner + * Add annotation classes to the event scanner. * * @param RouteScanner $scanner */ @@ -247,7 +240,7 @@ public function addEventAnnotations(EventScanner $scanner) } /** - * Add annotation classes to the route scanner + * Add annotation classes to the route scanner. * * @param RouteScanner $scanner */ @@ -256,7 +249,7 @@ public function addRoutingAnnotations(RouteScanner $scanner) } /** - * Add annotation classes to the model scanner + * Add annotation classes to the model scanner. * * @param ModelScanner $scanner */ @@ -271,15 +264,13 @@ public function addModelAnnotations(ModelScanner $scanner) */ public function loadAnnotatedEvents() { - if ($this->app->environment('local') && $this->scanWhenLocal) - { + if ($this->app->environment('local') && $this->scanWhenLocal) { $this->scanEvents(); } $scans = $this->eventScans(); - if ( ! empty($scans) && $this->finder->eventsAreScanned()) - { + if (!empty($scans) && $this->finder->eventsAreScanned()) { $this->loadScannedEvents(); } } @@ -293,8 +284,7 @@ protected function scanEvents() { $scans = $this->eventScans(); - if (empty($scans)) - { + if (empty($scans)) { return; } @@ -303,7 +293,7 @@ protected function scanEvents() $scanner->setClassesToScan($scans); file_put_contents( - $this->finder->getScannedEventsPath(), 'getEventDefinitions() + $this->finder->getScannedEventsPath(), 'getEventDefinitions() ); } @@ -320,21 +310,19 @@ protected function loadScannedEvents() } /** - * Load the annotated routes + * Load the annotated routes. * * @return void */ protected function loadAnnotatedRoutes() { - if ($this->app->environment('local') && $this->scanWhenLocal) - { + if ($this->app->environment('local') && $this->scanWhenLocal) { $this->scanRoutes(); } $scans = $this->routeScans(); - if ( ! empty($scans) && $this->finder->routesAreScanned()) - { + if (!empty($scans) && $this->finder->routesAreScanned()) { $this->loadScannedRoutes(); } } @@ -348,8 +336,7 @@ protected function scanRoutes() { $scans = $this->routeScans(); - if (empty($scans)) - { + if (empty($scans)) { return; } @@ -358,7 +345,7 @@ protected function scanRoutes() $scanner->setClassesToScan($scans); file_put_contents( - $this->finder->getScannedRoutesPath(), 'getRouteDefinitions() + $this->finder->getScannedRoutesPath(), 'getRouteDefinitions() ); } @@ -369,8 +356,7 @@ protected function scanRoutes() */ protected function loadScannedRoutes() { - $this->app->booted(function () - { + $this->app->booted(function () { $router = $this->app['Illuminate\Contracts\Routing\Registrar']; require $this->finder->getScannedRoutesPath(); @@ -378,21 +364,19 @@ protected function loadScannedRoutes() } /** - * Load the annotated models + * Load the annotated models. * * @return void */ protected function loadAnnotatedModels() { - if ($this->app->environment('local') && $this->scanWhenLocal) - { + if ($this->app->environment('local') && $this->scanWhenLocal) { $this->scanModels(); } $scans = $this->modelScans(); - if ( ! empty($scans) && $this->finder->modelsAreScanned()) - { + if (!empty($scans) && $this->finder->modelsAreScanned()) { $this->loadScannedModels(); } } @@ -406,8 +390,7 @@ protected function scanModels() { $scans = $this->modelScans(); - if (empty($scans)) - { + if (empty($scans)) { return; } @@ -416,7 +399,7 @@ protected function scanModels() $scanner->setClassesToScan($scans); file_put_contents( - $this->finder->getScannedModelsPath(), 'getModelDefinitions() + $this->finder->getScannedModelsPath(), 'getModelDefinitions() ); } @@ -427,8 +410,7 @@ protected function scanModels() */ protected function loadScannedModels() { - $this->app->booted(function () - { + $this->app->booted(function () { $router = $this->app['Illuminate\Contracts\Routing\Registrar']; require $this->finder->getScannedModelsPath(); @@ -442,8 +424,7 @@ protected function loadScannedModels() */ public function eventScans() { - if ($this->scanEverything) - { + if ($this->scanEverything) { return $this->getAllClasses(); } @@ -457,19 +438,17 @@ public function eventScans() */ public function routeScans() { - if ($this->scanEverything) - { + if ($this->scanEverything) { return $this->getAllClasses(); } $classes = $this->scanRoutes; // scan the controllers namespace if the flag is set - if ($this->scanControllers) - { + if ($this->scanControllers) { $classes = array_merge( $classes, - $this->getClassesFromNamespace($this->getAppNamespace() . 'Http\\Controllers') + $this->getClassesFromNamespace($this->getAppNamespace().'Http\\Controllers') ); } @@ -483,8 +462,7 @@ public function routeScans() */ public function modelScans() { - if ($this->scanEverything) - { + if ($this->scanEverything) { return $this->getAllClasses(); } @@ -492,9 +470,9 @@ public function modelScans() } /** - * Convert the given namespace to a file path + * Convert the given namespace to a file path. * - * @param string $namespace the namespace to convert + * @param string $namespace the namespace to convert * * @return string */ @@ -503,8 +481,7 @@ public function convertNamespaceToPath($namespace) // remove the app namespace from the namespace if it is there $appNamespace = $this->getAppNamespace(); - if (substr($namespace, 0, strlen($appNamespace)) == $appNamespace) - { + if (substr($namespace, 0, strlen($appNamespace)) == $appNamespace) { $namespace = substr($namespace, strlen($appNamespace)); } @@ -514,16 +491,16 @@ public function convertNamespaceToPath($namespace) /** * Get a list of the classes in a namespace. Leaving the second argument - * will scan for classes within the project's app directory + * will scan for classes within the project's app directory. * - * @param string $namespace the namespace to search - * @param null $base + * @param string $namespace the namespace to search + * @param null $base * * @return array */ public function getClassesFromNamespace($namespace, $base = null) { - $directory = ($base ?: $this->app->make('path')) . '/' . $this->convertNamespaceToPath($namespace); + $directory = ($base ?: $this->app->make('path')).'/'.$this->convertNamespaceToPath($namespace); return $this->app->make('Illuminate\Filesystem\ClassFinder')->findClasses($directory); } diff --git a/src/Console/EventScanCommand.php b/src/Console/EventScanCommand.php index 5cf0dd3..b69d20a 100644 --- a/src/Console/EventScanCommand.php +++ b/src/Console/EventScanCommand.php @@ -1,13 +1,15 @@ -laravel['path.storage'].'/framework/models.scanned.php'; } - } diff --git a/src/Console/RouteScanCommand.php b/src/Console/RouteScanCommand.php index d8d4345..2fa7b02 100644 --- a/src/Console/RouteScanCommand.php +++ b/src/Console/RouteScanCommand.php @@ -1,13 +1,15 @@ -info('Routes scanned!'); - if ($this->option('list')) - { + if ($this->option('list')) { $this->call('route:list'); } } @@ -110,5 +111,4 @@ protected function getOptions() ['list', null, InputOption::VALUE_NONE, 'List all registered routes'], ]; } - } diff --git a/src/Database/Eloquent/Annotations/Annotations/Bind.php b/src/Database/Eloquent/Annotations/Annotations/Bind.php index d237b9a..3b60da5 100644 --- a/src/Database/Eloquent/Annotations/Annotations/Bind.php +++ b/src/Database/Eloquent/Annotations/Annotations/Bind.php @@ -1,10 +1,12 @@ -binding = $values['value']; } - } diff --git a/src/Database/Eloquent/Annotations/InvalidBindingResolverException.php b/src/Database/Eloquent/Annotations/InvalidBindingResolverException.php index 449cd5e..969edcd 100644 --- a/src/Database/Eloquent/Annotations/InvalidBindingResolverException.php +++ b/src/Database/Eloquent/Annotations/InvalidBindingResolverException.php @@ -1,7 +1,9 @@ -scan = $scan; - foreach (Finder::create()->files()->in(__DIR__ . '/Annotations') as $file) - { + foreach (Finder::create()->files()->in(__DIR__.'/Annotations') as $file) { AnnotationRegistry::registerFile($file->getRealPath()); } } @@ -27,8 +28,9 @@ public function __construct(array $scan) /** * Convert the scanned annotations into route definitions. * - * @return string * @throws InvalidBindingResolverException + * + * @return string */ public function getModelDefinitions() { @@ -36,17 +38,14 @@ public function getModelDefinitions() $reader = $this->getReader(); - foreach ($this->getClassesToScan() as $class) - { + foreach ($this->getClassesToScan() as $class) { $annotations = $reader->getClassAnnotations($class); - if ( count($annotations) > 0 && ! $this->extendsEloquent($class)) - { - throw new InvalidBindingResolverException('Class [' . $class->name . '] is not a subclass of [Illuminate\Database\Eloquent\Model].'); + if (count($annotations) > 0 && !$this->extendsEloquent($class)) { + throw new InvalidBindingResolverException('Class ['.$class->name.'] is not a subclass of [Illuminate\Database\Eloquent\Model].'); } - foreach ($annotations as $annotation) - { + foreach ($annotations as $annotation) { $output .= $this->buildBinding($annotation->binding, $class->name); } } @@ -55,7 +54,7 @@ public function getModelDefinitions() } /** - * Determine if a class extends Eloquent + * Determine if a class extends Eloquent. * * @param ReflectionClass $class * @@ -69,13 +68,13 @@ protected function extendsEloquent(ReflectionClass $class) /** * Build the event listener for the class and method. * - * @param string $binding - * @param string $class + * @param string $binding + * @param string $class * * @return string */ protected function buildBinding($binding, $class) { - return sprintf('$router->model(\'%s\', \'%s\');', $binding, $class) . PHP_EOL; + return sprintf('$router->model(\'%s\', \'%s\');', $binding, $class).PHP_EOL; } } diff --git a/src/Events/Annotations/Annotations/Hears.php b/src/Events/Annotations/Annotations/Hears.php index 387ab38..abf793b 100644 --- a/src/Events/Annotations/Annotations/Hears.php +++ b/src/Events/Annotations/Annotations/Hears.php @@ -1,10 +1,12 @@ -scan = $scan; - - foreach (Finder::create()->files()->in(__DIR__.'/Annotations') as $file) - { - AnnotationRegistry::registerFile($file->getRealPath()); - } - } - - /** - * Convert the scanned annotations into route definitions. - * - * @return string - */ - public function getEventDefinitions() - { - $output = ''; - - $reader = $this->getReader(); - - foreach ($this->getClassesToScan() as $class) - { - foreach ($class->getMethods() as $method) - { - foreach ($reader->getMethodAnnotations($method) as $annotation) - { - $output .= $this->buildListener($class->name, $method->name, $annotation->events); - } - } - } - - return trim($output); - } - - /** - * Build the event listener for the class and method. - * - * @param string $class - * @param string $method - * @param array $events - * @return string - */ - protected function buildListener($class, $method, $events) - { - return sprintf('$events->listen(%s, \''.$class.'@'.$method.'\');', var_export($events, true)).PHP_EOL; - } - +class Scanner extends AnnotationScanner +{ + /** + * Create a new event scanner instance. + * + * @param array $scan + * + * @return void + */ + public function __construct(array $scan) + { + $this->scan = $scan; + + foreach (Finder::create()->files()->in(__DIR__.'/Annotations') as $file) { + AnnotationRegistry::registerFile($file->getRealPath()); + } + } + + /** + * Convert the scanned annotations into route definitions. + * + * @return string + */ + public function getEventDefinitions() + { + $output = ''; + + $reader = $this->getReader(); + + foreach ($this->getClassesToScan() as $class) { + foreach ($class->getMethods() as $method) { + foreach ($reader->getMethodAnnotations($method) as $annotation) { + $output .= $this->buildListener($class->name, $method->name, $annotation->events); + } + } + } + + return trim($output); + } + + /** + * Build the event listener for the class and method. + * + * @param string $class + * @param string $method + * @param array $events + * + * @return string + */ + protected function buildListener($class, $method, $events) + { + return sprintf('$events->listen(%s, \''.$class.'@'.$method.'\');', var_export($events, true)).PHP_EOL; + } } diff --git a/src/NamespaceToPathConverterTrait.php b/src/NamespaceToPathConverterTrait.php index 232ca32..895d992 100644 --- a/src/NamespaceToPathConverterTrait.php +++ b/src/NamespaceToPathConverterTrait.php @@ -1,31 +1,32 @@ -getAppNamespace(); // remove the app namespace from the namespace if it is there - if (substr($namespace, 0, strlen($appNamespace)) == $appNamespace) - { + if (substr($namespace, 0, strlen($appNamespace)) == $appNamespace) { $namespace = substr($namespace, strlen($appNamespace)); } - $path = str_replace('\\', '/', trim($namespace, ' \\') ); + $path = str_replace('\\', '/', trim($namespace, ' \\')); // trim and return the path - return ( $base ?: app_path() ) . '/' . $path; + return ($base ?: app_path()).'/'.$path; } } diff --git a/src/Routing/Annotations/AbstractPath.php b/src/Routing/Annotations/AbstractPath.php index 7c188e4..7de09a9 100644 --- a/src/Routing/Annotations/AbstractPath.php +++ b/src/Routing/Annotations/AbstractPath.php @@ -1,40 +1,41 @@ -class = $reader->getClassAnnotations($class); - $this->method = $this->getMethodAnnotations($class, $reader); - } - - /** - * Get the method annotations for a given class. - * - * @param \ReflectionClass $class - * @param \Doctrine\Common\Annotations\SimpleAnnotationReader $reader - * @return array - */ - protected function getMethodAnnotations(ReflectionClass $class, SimpleAnnotationReader $reader) - { - $annotations = []; - - foreach ($class->getMethods() as $method) - { - $results = $reader->getMethodAnnotations($method); - - if (count($results) > 0) - $annotations[$method->name] = $results; - } - - return $annotations; - } +use Doctrine\Common\Annotations\SimpleAnnotationReader; +use ReflectionClass; +class AnnotationSet +{ + /** + * The class annotations. + * + * @var array + */ + public $class; + + /** + * The method annotations. + * + * @var array + */ + public $method; + + /** + * Create a new annotation set instance. + * + * @param \ReflectionClass $class + * @param \Doctrine\Common\Annotations\SimpleAnnotationReader $reader + * + * @return void + */ + public function __construct(ReflectionClass $class, SimpleAnnotationReader $reader) + { + $this->class = $reader->getClassAnnotations($class); + $this->method = $this->getMethodAnnotations($class, $reader); + } + + /** + * Get the method annotations for a given class. + * + * @param \ReflectionClass $class + * @param \Doctrine\Common\Annotations\SimpleAnnotationReader $reader + * + * @return array + */ + protected function getMethodAnnotations(ReflectionClass $class, SimpleAnnotationReader $reader) + { + $annotations = []; + + foreach ($class->getMethods() as $method) { + $results = $reader->getMethodAnnotations($method); + + if (count($results) > 0) { + $annotations[$method->name] = $results; + } + } + + return $annotations; + } } diff --git a/src/Routing/Annotations/Annotations/Annotation.php b/src/Routing/Annotations/Annotations/Annotation.php index a057359..c0c50e7 100644 --- a/src/Routing/Annotations/Annotations/Annotation.php +++ b/src/Routing/Annotations/Annotations/Annotation.php @@ -1,124 +1,133 @@ -values = $values; - } +abstract class Annotation implements ArrayAccess +{ + /** + * The value array. + * + * @var array + */ + protected $values; - /** - * Apply the annotation's settings to the given endpoint. - * - * @param \Collective\Annotations\Routing\Annotations\MethodEndpoint $endpoint - * @param \ReflectionMethod $method - * @return void - */ - public function modify(MethodEndpoint $endpoint, ReflectionMethod $method) - { - // - } + /** + * Create a new annotation instance. + * + * @param array $values + * + * @return void + */ + public function __construct(array $values) + { + $this->values = $values; + } - /** - * Apply the annotation's settings to the given endpoint collection. - * - * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints - * @param \ReflectionClass $class - * @return void - */ - public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) - { - // - } + /** + * Apply the annotation's settings to the given endpoint. + * + * @param \Collective\Annotations\Routing\Annotations\MethodEndpoint $endpoint + * @param \ReflectionMethod $method + * + * @return void + */ + public function modify(MethodEndpoint $endpoint, ReflectionMethod $method) + { + // + } - /** - * Determine if the value at a given offset exists. - * - * @param string $offset - * @return bool - */ - public function offsetExists($offset) - { - return array_key_exists($offset, $this->values); - } + /** + * Apply the annotation's settings to the given endpoint collection. + * + * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints + * @param \ReflectionClass $class + * + * @return void + */ + public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) + { + // + } - /** - * Get the value at a given offset. - * - * @param string $offset - * @return mixed - */ - public function offsetGet($offset) - { - return $this->values[$offset]; - } + /** + * Determine if the value at a given offset exists. + * + * @param string $offset + * + * @return bool + */ + public function offsetExists($offset) + { + return array_key_exists($offset, $this->values); + } - /** - * Set the value at a given offset. - * - * @param string $offset - * @param mixed $value - * @return void - */ - public function offsetSet($offset, $value) - { - $this->values[$offset] = $value; - } + /** + * Get the value at a given offset. + * + * @param string $offset + * + * @return mixed + */ + public function offsetGet($offset) + { + return $this->values[$offset]; + } - /** - * Remove the value at a given offset. - * - * @param string $offset - * @return void - */ - public function offsetUnset($offset) - { - unset($this->values[$offset]); - } + /** + * Set the value at a given offset. + * + * @param string $offset + * @param mixed $value + * + * @return void + */ + public function offsetSet($offset, $value) + { + $this->values[$offset] = $value; + } - /** - * Dynamically get a property on the annotation. - * - * @param string $key - * @return mixed - */ - public function __get($key) - { - if ($this->offsetExists($key)) - { - return $this->values[$key]; - } - } + /** + * Remove the value at a given offset. + * + * @param string $offset + * + * @return void + */ + public function offsetUnset($offset) + { + unset($this->values[$offset]); + } - /** - * Dynamically set a property on the annotation. - * - * @param string $key - * @param mixed $value - * @return void - */ - public function __set($key, $value) - { - $this->values[$key] = $value; - } + /** + * Dynamically get a property on the annotation. + * + * @param string $key + * + * @return mixed + */ + public function __get($key) + { + if ($this->offsetExists($key)) { + return $this->values[$key]; + } + } + /** + * Dynamically set a property on the annotation. + * + * @param string $key + * @param mixed $value + * + * @return void + */ + public function __set($key, $value) + { + $this->values[$key] = $value; + } } diff --git a/src/Routing/Annotations/Annotations/Any.php b/src/Routing/Annotations/Annotations/Any.php index 4fe0d1b..32099da 100644 --- a/src/Routing/Annotations/Annotations/Any.php +++ b/src/Routing/Annotations/Annotations/Any.php @@ -1,10 +1,11 @@ -prefix) $this->prefixEndpoints($endpoints); - - if ($this->domain) $this->setEndpointDomains($endpoints); - } +class Controller extends Annotation +{ + /** + * {@inheritdoc} + */ + public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) + { + if ($this->prefix) { + $this->prefixEndpoints($endpoints); + } - /** - * Set the prefixes on the endpoints. - * - * @param EndpointCollection $endpoints - * @return void - */ - protected function prefixEndpoints(EndpointCollection $endpoints) - { - foreach ($endpoints->getAllPaths() as $path) - { - $path->path = $this->trimPath($this->prefix, $path->path); - } - } + if ($this->domain) { + $this->setEndpointDomains($endpoints); + } + } - /** - * Set the domain on the endpoints. - * - * @param EndpointCollection $endpoints - * @return void - */ - protected function setEndpointDomains(EndpointCollection $endpoints) - { - foreach ($endpoints->getAllPaths() as $path) - { - if (is_null($path->domain)) $path->domain = $this->domain; - } - } + /** + * Set the prefixes on the endpoints. + * + * @param EndpointCollection $endpoints + * + * @return void + */ + protected function prefixEndpoints(EndpointCollection $endpoints) + { + foreach ($endpoints->getAllPaths() as $path) { + $path->path = $this->trimPath($this->prefix, $path->path); + } + } - /** - * Trim the path slashes for a given prefix and path. - * - * @param string $prefix - * @param string $path - * @return string - */ - protected function trimPath($prefix, $path) - { - return trim(trim($prefix, '/').'/'.trim($path, '/'), '/'); - } + /** + * Set the domain on the endpoints. + * + * @param EndpointCollection $endpoints + * + * @return void + */ + protected function setEndpointDomains(EndpointCollection $endpoints) + { + foreach ($endpoints->getAllPaths() as $path) { + if (is_null($path->domain)) { + $path->domain = $this->domain; + } + } + } + /** + * Trim the path slashes for a given prefix and path. + * + * @param string $prefix + * @param string $path + * + * @return string + */ + protected function trimPath($prefix, $path) + { + return trim(trim($prefix, '/').'/'.trim($path, '/'), '/'); + } } diff --git a/src/Routing/Annotations/Annotations/Delete.php b/src/Routing/Annotations/Annotations/Delete.php index 6ec76b4..8f78100 100644 --- a/src/Routing/Annotations/Annotations/Delete.php +++ b/src/Routing/Annotations/Annotations/Delete.php @@ -1,10 +1,11 @@ -hasPaths()) - { - foreach ($endpoint->getPaths() as $path) - { - $path->middleware = array_merge($path->middleware, (array) $this->value); - } - } - else - { - $endpoint->middleware = array_merge($endpoint->middleware, (array) $this->value); - } - } - - /** - * {@inheritdoc} - */ - public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) - { - foreach ($endpoints as $endpoint) - { - foreach ((array) $this->value as $middleware) - { - $endpoint->classMiddleware[] = [ - 'name' => $middleware, 'only' => (array) $this->only, 'except' => (array) $this->except - ]; - } - } - } +class Middleware 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) $this->value); + } + } else { + $endpoint->middleware = array_merge($endpoint->middleware, (array) $this->value); + } + } + /** + * {@inheritdoc} + */ + public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) + { + foreach ($endpoints as $endpoint) { + foreach ((array) $this->value as $middleware) { + $endpoint->classMiddleware[] = [ + 'name' => $middleware, 'only' => (array) $this->only, 'except' => (array) $this->except, + ]; + } + } + } } diff --git a/src/Routing/Annotations/Annotations/Options.php b/src/Routing/Annotations/Annotations/Options.php index 745f684..ba1598e 100644 --- a/src/Routing/Annotations/Annotations/Options.php +++ b/src/Routing/Annotations/Annotations/Options.php @@ -1,10 +1,11 @@ -push(new ResourceEndpoint([ - 'reflection' => $class, 'name' => $this->value, 'names' => (array) $this->names, - 'only' => (array) $this->only, 'except' => (array) $this->except, - 'middleware' => $this->getMiddleware($endpoints), - ])); - } +class Resource extends Annotation +{ + /** + * All of the resource controller methods. + * + * @var array + */ + protected $methods = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy']; - /** - * Get all of the middleware defined on the resource method endpoints. - * - * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints - * @return array - */ - protected function getMiddleware(EndpointCollection $endpoints) - { - return $this->extractFromEndpoints($endpoints, 'middleware'); - } + /** + * {@inheritdoc} + */ + public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) + { + $endpoints->push(new ResourceEndpoint([ + 'reflection' => $class, 'name' => $this->value, 'names' => (array) $this->names, + 'only' => (array) $this->only, 'except' => (array) $this->except, + 'middleware' => $this->getMiddleware($endpoints), + ])); + } - /** - * Extract method items from endpoints for the given key. - * - * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints - * @param string $key - * @return array - */ - protected function extractFromEndpoints(EndpointCollection $endpoints, $key) - { - $items = [ - 'index' => [], 'create' => [], 'store' => [], 'show' => [], - 'edit' => [], 'update' => [], 'destroy' => [] - ]; + /** + * Get all of the middleware defined on the resource method endpoints. + * + * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints + * + * @return array + */ + protected function getMiddleware(EndpointCollection $endpoints) + { + return $this->extractFromEndpoints($endpoints, 'middleware'); + } - foreach ($this->getEndpointsWithResourceMethods($endpoints, $key) as $endpoint) - $items[$endpoint->method] = array_merge($items[$endpoint->method], $endpoint->{$key}); + /** + * Extract method items from endpoints for the given key. + * + * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints + * @param string $key + * + * @return array + */ + protected function extractFromEndpoints(EndpointCollection $endpoints, $key) + { + $items = [ + 'index' => [], 'create' => [], 'store' => [], 'show' => [], + 'edit' => [], 'update' => [], 'destroy' => [], + ]; - return $items; - } + foreach ($this->getEndpointsWithResourceMethods($endpoints, $key) as $endpoint) { + $items[$endpoint->method] = array_merge($items[$endpoint->method], $endpoint->{$key}); + } - /** - * Get all of the resource method endpoints with pathless filters. - * - * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints - * @return array - */ - protected function getEndpointsWithResourceMethods(EndpointCollection $endpoints) - { - return Collection::make($endpoints)->filter(function($endpoint) - { - return ($endpoint instanceof MethodEndpoint && - in_array($endpoint->method, $this->methods)); + return $items; + } - })->all(); - } + /** + * Get all of the resource method endpoints with pathless filters. + * + * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints + * + * @return array + */ + protected function getEndpointsWithResourceMethods(EndpointCollection $endpoints) + { + return Collection::make($endpoints)->filter(function ($endpoint) { + return ($endpoint instanceof MethodEndpoint && + in_array($endpoint->method, $this->methods)); + })->all(); + } } diff --git a/src/Routing/Annotations/Annotations/Route.php b/src/Routing/Annotations/Annotations/Route.php index a54b1ef..e2a821a 100644 --- a/src/Routing/Annotations/Annotations/Route.php +++ b/src/Routing/Annotations/Annotations/Route.php @@ -1,20 +1,21 @@ -addPath(new Path( - strtolower(class_basename(get_class($this))), $this->domain, $this->value, - $this->as, (array) $this->middleware, (array) $this->where - )); - } +use Collective\Annotations\Routing\Annotations\MethodEndpoint; +use Collective\Annotations\Routing\Annotations\Path; +use ReflectionMethod; +abstract class Route extends Annotation +{ + /** + * {@inheritdoc} + */ + public function modify(MethodEndpoint $endpoint, ReflectionMethod $method) + { + $endpoint->addPath(new Path( + strtolower(class_basename(get_class($this))), $this->domain, $this->value, + $this->as, (array) $this->middleware, (array) $this->where + )); + } } diff --git a/src/Routing/Annotations/Annotations/Where.php b/src/Routing/Annotations/Annotations/Where.php index 3ad27fb..a6b91f9 100644 --- a/src/Routing/Annotations/Annotations/Where.php +++ b/src/Routing/Annotations/Annotations/Where.php @@ -1,35 +1,34 @@ -getPaths() as $path) - { - $path->where = array_merge($path->where, (array) $this->value); - } - } - - /** - * {@inheritdoc} - */ - public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) - { - foreach ($endpoints->getAllPaths() as $path) - { - $path->where = array_merge($path->where, $this->value); - } - } +class Where extends Annotation +{ + /** + * {@inheritdoc} + */ + public function modify(MethodEndpoint $endpoint, ReflectionMethod $method) + { + foreach ($endpoint->getPaths() as $path) { + $path->where = array_merge($path->where, (array) $this->value); + } + } + /** + * {@inheritdoc} + */ + public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class) + { + foreach ($endpoints->getAllPaths() as $path) { + $path->where = array_merge($path->where, $this->value); + } + } } diff --git a/src/Routing/Annotations/EndpointCollection.php b/src/Routing/Annotations/EndpointCollection.php index a61c8d1..dd9968e 100644 --- a/src/Routing/Annotations/EndpointCollection.php +++ b/src/Routing/Annotations/EndpointCollection.php @@ -1,27 +1,26 @@ -getPaths() as $path) - { - $paths[] = $path; - } - } +class EndpointCollection extends Collection +{ + /** + * Get all of the paths for the given endpoint collection. + * + * @return array + */ + public function getAllPaths() + { + $paths = []; - return $paths; - } + foreach ($this as $endpoint) { + foreach ($endpoint->getPaths() as $path) { + $paths[] = $path; + } + } + return $paths; + } } diff --git a/src/Routing/Annotations/EndpointInterface.php b/src/Routing/Annotations/EndpointInterface.php index 245ac37..2422830 100644 --- a/src/Routing/Annotations/EndpointInterface.php +++ b/src/Routing/Annotations/EndpointInterface.php @@ -1,42 +1,45 @@ -method; - } + /** + * Get the controller method for the given endpoint path. + * + * @param \Collective\Annotations\Routing\Annotations\AbstractPath $path + * + * @return string + */ + public function getMethodForPath(AbstractPath $path) + { + return $path->method; + } - /** - * Add the given path definition to the endpoint. - * - * @param \Collective\Annotations\Routing\Annotations\AbstractPath $path - * @return void - */ - public function addPath(AbstractPath $path) - { - $this->paths[] = $path; - } + /** + * Add the given path definition to the endpoint. + * + * @param \Collective\Annotations\Routing\Annotations\AbstractPath $path + * + * @return void + */ + public function addPath(AbstractPath $path) + { + $this->paths[] = $path; + } - /** - * Implode the given list into a comma separated string. - * - * @param array $array - * @return string - */ - protected function implodeArray(array $array) - { - $results = []; + /** + * Implode the given list into a comma separated string. + * + * @param array $array + * + * @return string + */ + protected function implodeArray(array $array) + { + $results = []; - foreach ($array as $key => $value) - { - if (is_string($key)) - { - $results[] = "'".$key."' => '".$value."'"; - } - else - { - $results[] = "'".$value."'"; - } - } - - return count($results) > 0 ? implode(', ', $results) : ''; - } + foreach ($array as $key => $value) { + if (is_string($key)) { + $results[] = "'".$key."' => '".$value."'"; + } else { + $results[] = "'".$value."'"; + } + } + return count($results) > 0 ? implode(', ', $results) : ''; + } } diff --git a/src/Routing/Annotations/MethodEndpoint.php b/src/Routing/Annotations/MethodEndpoint.php index 8ef815b..d4aae73 100644 --- a/src/Routing/Annotations/MethodEndpoint.php +++ b/src/Routing/Annotations/MethodEndpoint.php @@ -1,152 +1,154 @@ - $value) - $this->{$key} = $value; - } - - /** - * Transform the endpoint into a route definition. - * - * @return string - */ - public function toRouteDefinition() - { - $routes = []; - - foreach ($this->paths as $path) - { - $routes[] = sprintf( - $this->getTemplate(), $path->verb, $path->path, $this->uses, var_export($path->as, true), - $this->getMiddleware($path), $this->implodeArray($path->where), var_export($path->domain, true) - ); - } - - return implode(PHP_EOL.PHP_EOL, $routes); - } - - /** - * Get the middleware for the path. - * - * @param \Collective\Annotations\Routing\Annotations\AbstractPath $path - * @return array - */ - protected function getMiddleware(AbstractPath $path) - { - $classMiddleware = $this->getClassMiddlewareForPath($path)->all(); - - return $this->implodeArray( - array_merge($classMiddleware, $path->middleware, $this->middleware) - ); - } - - /** - * Get the class middleware for the given path. - * - * @param \Collective\Annotations\Routing\Annotations\AbstractPath $path - * @return array - */ - protected function getClassMiddlewareForPath(AbstractPath $path) - { - return Collection::make($this->classMiddleware)->filter(function($m) - { - return $this->middlewareAppliesToMethod($this->method, $m); - }) - ->map(function($m) - { - return $m['name']; - }); - } - - /** - * Determine if the endpoint has any paths. - * - * @return bool - */ - public function hasPaths() - { - return count($this->paths) > 0; - } - - /** - * Get all of the path definitions for an endpoint. - * - * @return array - */ - public function getPaths() - { - return $this->paths; - } - - /** - * Get the template for the endpoint. - * - * @return string - */ - protected function getTemplate() - { - return '$router->%s(\'%s\', [ +class MethodEndpoint implements EndpointInterface +{ + use EndpointTrait; + + /** + * The ReflectionClass instance for the controller class. + * + * @var \ReflectionClass + */ + public $reflection; + + /** + * The method that handles the route. + * + * @var string + */ + public $method; + + /** + * The route paths for the definition. + * + * @var array[Path] + */ + public $paths = []; + + /** + * The controller and method that handles the route. + * + * @var string + */ + public $uses; + + /** + * All of the class level "inherited" middleware defined for the pathless endpoint. + * + * @var array + */ + public $classMiddleware = []; + + /** + * All of the middleware defined for the pathless endpoint. + * + * @var array + */ + public $middleware = []; + + /** + * Create a new route definition instance. + * + * @param array $attributes + * + * @return void + */ + public function __construct(array $attributes = []) + { + foreach ($attributes as $key => $value) { + $this->{$key} = $value; + } + } + + /** + * Transform the endpoint into a route definition. + * + * @return string + */ + public function toRouteDefinition() + { + $routes = []; + + foreach ($this->paths as $path) { + $routes[] = sprintf( + $this->getTemplate(), $path->verb, $path->path, $this->uses, var_export($path->as, true), + $this->getMiddleware($path), $this->implodeArray($path->where), var_export($path->domain, true) + ); + } + + return implode(PHP_EOL.PHP_EOL, $routes); + } + + /** + * Get the middleware for the path. + * + * @param \Collective\Annotations\Routing\Annotations\AbstractPath $path + * + * @return array + */ + protected function getMiddleware(AbstractPath $path) + { + $classMiddleware = $this->getClassMiddlewareForPath($path)->all(); + + return $this->implodeArray( + array_merge($classMiddleware, $path->middleware, $this->middleware) + ); + } + + /** + * Get the class middleware for the given path. + * + * @param \Collective\Annotations\Routing\Annotations\AbstractPath $path + * + * @return array + */ + protected function getClassMiddlewareForPath(AbstractPath $path) + { + return Collection::make($this->classMiddleware)->filter(function ($m) { + return $this->middlewareAppliesToMethod($this->method, $m); + }) + ->map(function ($m) { + return $m['name']; + }); + } + + /** + * Determine if the endpoint has any paths. + * + * @return bool + */ + public function hasPaths() + { + return count($this->paths) > 0; + } + + /** + * Get all of the path definitions for an endpoint. + * + * @return array + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Get the template for the endpoint. + * + * @return string + */ + protected function getTemplate() + { + return '$router->%s(\'%s\', [ \'uses\' => \'%s\', \'as\' => %s, \'middleware\' => [%s], \'where\' => [%s], \'domain\' => %s, ]);'; - } - + } } diff --git a/src/Routing/Annotations/Path.php b/src/Routing/Annotations/Path.php index f09dd49..38de57d 100644 --- a/src/Routing/Annotations/Path.php +++ b/src/Routing/Annotations/Path.php @@ -1,33 +1,35 @@ -as = $as; - $this->verb = $verb; - $this->where = $where; - $this->domain = $domain; - $this->middleware = $middleware; - $this->path = $path == '/' ? '/' : trim($path, '/'); - } +class Path extends AbstractPath +{ + /** + * The name of the route. + * + * @var string + */ + public $as; + /** + * Create a new Route Path instance. + * + * @param string $verb + * @param string $domain + * @param string $path + * @param string $as + * @param array $middleware + * @param array $where + * + * @return void + */ + public function __construct($verb, $domain, $path, $as, $middleware = [], $where = []) + { + $this->as = $as; + $this->verb = $verb; + $this->where = $where; + $this->domain = $domain; + $this->middleware = $middleware; + $this->path = $path == '/' ? '/' : trim($path, '/'); + } } diff --git a/src/Routing/Annotations/ResourceEndpoint.php b/src/Routing/Annotations/ResourceEndpoint.php index 43098a7..2b9566c 100644 --- a/src/Routing/Annotations/ResourceEndpoint.php +++ b/src/Routing/Annotations/ResourceEndpoint.php @@ -1,226 +1,223 @@ - $value) - { - $this->{$key} = $value; - } - - $this->buildPaths(); - } - - /** - * Build all of the paths for the resource endpoint. - * - * @return void - */ - protected function buildPaths() - { - foreach ($this->getIncludedMethods() as $method) - { - $this->paths[] = new ResourcePath($method); - } - } - - /** - * Get the methods to be included in the resource. - * - * @return array - */ - protected function getIncludedMethods() - { - if ($this->only) - { - return $this->only; - } - elseif ($this->except) - { - return array_diff($this->methods, $this->except); - } - - return $this->methods; - } - - /** - * Transform the endpoint into a route definition. - * - * @return string - */ - public function toRouteDefinition() - { - $routes = []; - - foreach ($this->paths as $path) - { - $routes[] = sprintf( - $this->getTemplate(), 'Resource: '.$this->name.'@'.$path->method, - $this->implodeArray($this->getMiddleware($path)), - var_export($path->path, true), $this->implodeArray($path->where), - var_export($path->domain, true), var_export($this->name, true), - var_export($this->reflection->name, true), $this->implodeArray([$path->method]), - $this->implodeArray($this->getNames($path)) - ); - } - - return implode(PHP_EOL.PHP_EOL, $routes); - } - - /** - * Get all of the middleware for the given path. - * - * This will also merge in any of the middleware applied at the route level. - * - * @param ResourcePath $path - * @return array - */ - protected function getMiddleware(ResourcePath $path) - { - $classMiddleware = $this->getClassMiddlewareForPath($path)->all(); - - return array_merge($classMiddleware, array_get($this->middleware, $path->method, [])); - } - - /** - * Get the class middleware for the given path. - * - * @param ResourcePath $path - * @return array - */ - protected function getClassMiddlewareForPath(ResourcePath $path) - { - return Collection::make($this->classMiddleware)->filter(function($m) use ($path) - { - return $this->middlewareAppliesToMethod($path->method, $m); - }) - ->map(function($m) - { - return $m['name']; - }); - } - - /** - * Get the names for the given path. - * - * @param ResourcePath $path - * @return array - */ - protected function getNames(ResourcePath $path) - { - return isset($this->names[$path->method]) ? [$path->method => $this->names[$path->method]] : []; - } - - /** - * Determine if the endpoint has any paths. - * - * @return bool - */ - public function hasPaths() - { - return count($this->paths) > 0; - } - - /** - * Get all of the path definitions for an endpoint. - * - * @return array[AbstractPath] - */ - public function getPaths() - { - return $this->paths; - } - - /** - * Get the template for the endpoint. - * - * @return string - */ - protected function getTemplate() - { - return '// %s +class ResourceEndpoint implements EndpointInterface +{ + use EndpointTrait; + + /** + * All of the resource controller methods. + * + * @var array + */ + protected $methods = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy']; + + /** + * The ReflectionClass instance for the controller class. + * + * @var \ReflectionClass + */ + public $reflection; + + /** + * The route paths for the definition. + * + * This corresponds to a path for each applicable resource method. + * + * @var array[ResourcePath] + */ + public $paths; + + /** + * The name of the resource. + * + * @var string + */ + public $name; + + /** + * The array of route names for the resource. + * + * @var array + */ + public $names = []; + + /** + * The only methods that should be included. + * + * @var array + */ + public $only = []; + + /** + * The methods that should not be included. + * + * @var array + */ + public $except = []; + + /** + * The class level "inherited" middleware that apply to the resource. + * + * @var array + */ + public $classMiddleware = []; + + /** + * The middleware that was applied at the method level. + * + * This array is keyed by resource method name (index, create, etc). + * + * @var array + */ + public $middleware = []; + + /** + * Create a new route definition instance. + * + * @param array $attributes + * + * @return void + */ + public function __construct(array $attributes = []) + { + foreach ($attributes as $key => $value) { + $this->{$key} = $value; + } + + $this->buildPaths(); + } + + /** + * Build all of the paths for the resource endpoint. + * + * @return void + */ + protected function buildPaths() + { + foreach ($this->getIncludedMethods() as $method) { + $this->paths[] = new ResourcePath($method); + } + } + + /** + * Get the methods to be included in the resource. + * + * @return array + */ + protected function getIncludedMethods() + { + if ($this->only) { + return $this->only; + } elseif ($this->except) { + return array_diff($this->methods, $this->except); + } + + return $this->methods; + } + + /** + * Transform the endpoint into a route definition. + * + * @return string + */ + public function toRouteDefinition() + { + $routes = []; + + foreach ($this->paths as $path) { + $routes[] = sprintf( + $this->getTemplate(), 'Resource: '.$this->name.'@'.$path->method, + $this->implodeArray($this->getMiddleware($path)), + var_export($path->path, true), $this->implodeArray($path->where), + var_export($path->domain, true), var_export($this->name, true), + var_export($this->reflection->name, true), $this->implodeArray([$path->method]), + $this->implodeArray($this->getNames($path)) + ); + } + + return implode(PHP_EOL.PHP_EOL, $routes); + } + + /** + * Get all of the middleware for the given path. + * + * This will also merge in any of the middleware applied at the route level. + * + * @param ResourcePath $path + * + * @return array + */ + protected function getMiddleware(ResourcePath $path) + { + $classMiddleware = $this->getClassMiddlewareForPath($path)->all(); + + return array_merge($classMiddleware, array_get($this->middleware, $path->method, [])); + } + + /** + * Get the class middleware for the given path. + * + * @param ResourcePath $path + * + * @return array + */ + protected function getClassMiddlewareForPath(ResourcePath $path) + { + return Collection::make($this->classMiddleware)->filter(function ($m) use ($path) { + return $this->middlewareAppliesToMethod($path->method, $m); + }) + ->map(function ($m) { + return $m['name']; + }); + } + + /** + * Get the names for the given path. + * + * @param ResourcePath $path + * + * @return array + */ + protected function getNames(ResourcePath $path) + { + return isset($this->names[$path->method]) ? [$path->method => $this->names[$path->method]] : []; + } + + /** + * Determine if the endpoint has any paths. + * + * @return bool + */ + public function hasPaths() + { + return count($this->paths) > 0; + } + + /** + * Get all of the path definitions for an endpoint. + * + * @return array[AbstractPath] + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Get the template for the endpoint. + * + * @return string + */ + protected function getTemplate() + { + return '// %s $router->group([\'middleware\' => [%s], \'prefix\' => %s, \'where\' => [%s], \'domain\' => %s], function() use ($router) { $router->resource(%s, %s, [\'only\' => [%s], \'names\' => [%s]]); });'; - } - + } } diff --git a/src/Routing/Annotations/ResourcePath.php b/src/Routing/Annotations/ResourcePath.php index 09c2100..53f0fed 100644 --- a/src/Routing/Annotations/ResourcePath.php +++ b/src/Routing/Annotations/ResourcePath.php @@ -1,51 +1,53 @@ -method = $method; - $this->verb = $this->getVerb($method); - } - - /** - * Get the verb for the given resource method. - * - * @param string $method - * @return string - */ - protected function getVerb($method) - { - switch ($method) - { - case 'index': - case 'create': - case 'show': - case 'edit': - return 'get'; - - case 'store': - return 'post'; - - case 'update': - return 'put'; - - case 'destroy': - return 'delete'; - } - } - +method = $method; + $this->verb = $this->getVerb($method); + } + + /** + * Get the verb for the given resource method. + * + * @param string $method + * + * @return string + */ + protected function getVerb($method) + { + switch ($method) { + case 'index': + case 'create': + case 'show': + case 'edit': + return 'get'; + + case 'store': + return 'post'; + + case 'update': + return 'put'; + + case 'destroy': + return 'delete'; + } + } } diff --git a/src/Routing/Annotations/Scanner.php b/src/Routing/Annotations/Scanner.php index 458251e..f84824c 100644 --- a/src/Routing/Annotations/Scanner.php +++ b/src/Routing/Annotations/Scanner.php @@ -1,104 +1,109 @@ -scan = $scan; - - foreach (Finder::create()->files()->in(__DIR__.'/Annotations') as $file) - { - AnnotationRegistry::registerFile($file->getRealPath()); - } - } - - /** - * Convert the scanned annotations into route definitions. - * - * @return string - */ - public function getRouteDefinitions() - { - $output = ''; - - foreach ($this->getEndpointsInClasses($this->getReader()) as $endpoint) - { - $output .= $endpoint->toRouteDefinition().PHP_EOL.PHP_EOL; - } - - return trim($output); - } - - /** - * Scan the directory and generate the route manifest. - * - * @param \Doctrine\Common\Annotations\SimpleAnnotationReader $reader - * @return \Collective\Annotations\Routing\Annotations\EndpointCollection - */ - protected function getEndpointsInClasses(SimpleAnnotationReader $reader) - { - $endpoints = new EndpointCollection; - - foreach ($this->getClassesToScan() as $class) - { - $endpoints = $endpoints->merge($this->getEndpointsInClass( - $class, new AnnotationSet($class, $reader) - )); - } - - return $endpoints; - } - - /** - * Build the Endpoints for the given class. - * - * @param \ReflectionClass $class - * @param \Collective\Annotations\Routing\Annotations\AnnotationSet $annotations - * @return \Collective\Annotations\Routing\Annotations\EndpointCollection - */ - protected function getEndpointsInClass(ReflectionClass $class, AnnotationSet $annotations) - { - $endpoints = new EndpointCollection; - - foreach ($annotations->method as $method => $methodAnnotations) - $this->addEndpoint($endpoints, $class, $method, $methodAnnotations); - - foreach ($annotations->class as $annotation) - $annotation->modifyCollection($endpoints, $class); - - return $endpoints; - } - - /** - * Create a new endpoint in the collection. - * - * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints - * @param \ReflectionClass $class - * @param string $method - * @param array $annotations - * @return void - */ - protected function addEndpoint(EndpointCollection $endpoints, ReflectionClass $class, +class Scanner extends AnnotationScanner +{ + /** + * Create a new scanner instance. + * + * @param array $scan + * + * @return void + */ + public function __construct(array $scan) + { + $this->scan = $scan; + + foreach (Finder::create()->files()->in(__DIR__.'/Annotations') as $file) { + AnnotationRegistry::registerFile($file->getRealPath()); + } + } + + /** + * Convert the scanned annotations into route definitions. + * + * @return string + */ + public function getRouteDefinitions() + { + $output = ''; + + foreach ($this->getEndpointsInClasses($this->getReader()) as $endpoint) { + $output .= $endpoint->toRouteDefinition().PHP_EOL.PHP_EOL; + } + + return trim($output); + } + + /** + * Scan the directory and generate the route manifest. + * + * @param \Doctrine\Common\Annotations\SimpleAnnotationReader $reader + * + * @return \Collective\Annotations\Routing\Annotations\EndpointCollection + */ + protected function getEndpointsInClasses(SimpleAnnotationReader $reader) + { + $endpoints = new EndpointCollection(); + + foreach ($this->getClassesToScan() as $class) { + $endpoints = $endpoints->merge($this->getEndpointsInClass( + $class, new AnnotationSet($class, $reader) + )); + } + + return $endpoints; + } + + /** + * Build the Endpoints for the given class. + * + * @param \ReflectionClass $class + * @param \Collective\Annotations\Routing\Annotations\AnnotationSet $annotations + * + * @return \Collective\Annotations\Routing\Annotations\EndpointCollection + */ + protected function getEndpointsInClass(ReflectionClass $class, AnnotationSet $annotations) + { + $endpoints = new EndpointCollection(); + + foreach ($annotations->method as $method => $methodAnnotations) { + $this->addEndpoint($endpoints, $class, $method, $methodAnnotations); + } + + foreach ($annotations->class as $annotation) { + $annotation->modifyCollection($endpoints, $class); + } + + return $endpoints; + } + + /** + * Create a new endpoint in the collection. + * + * @param \Collective\Annotations\Routing\Annotations\EndpointCollection $endpoints + * @param \ReflectionClass $class + * @param string $method + * @param array $annotations + * + * @return void + */ + protected function addEndpoint(EndpointCollection $endpoints, ReflectionClass $class, $method, array $annotations) - { - $endpoints->push($endpoint = new MethodEndpoint([ - 'reflection' => $class, 'method' => $method, 'uses' => $class->name.'@'.$method - ])); - - foreach ($annotations as $annotation) - $annotation->modify($endpoint, $class->getMethod($method)); - } - + { + $endpoints->push($endpoint = new MethodEndpoint([ + 'reflection' => $class, 'method' => $method, 'uses' => $class->name.'@'.$method, + ])); + + foreach ($annotations as $annotation) { + $annotation->modify($endpoint, $class->getMethod($method)); + } + } } diff --git a/tests/AnnotationsServiceProviderTest.php b/tests/AnnotationsServiceProviderTest.php index 855379c..774db92 100644 --- a/tests/AnnotationsServiceProviderTest.php +++ b/tests/AnnotationsServiceProviderTest.php @@ -1,67 +1,67 @@ app = m::mock('Illuminate\Contracts\Foundation\Application'); - $this->provider = new AnnotationsServiceProvider( $this->app ); - } +class AnnotationsServiceProviderTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + $this->app = m::mock('Illuminate\Contracts\Foundation\Application'); + $this->provider = new AnnotationsServiceProvider($this->app); + } - public function tearDown() - { - m::close(); - } + public function tearDown() + { + m::close(); + } - public function testConvertNamespaceToPath() - { - $this->provider = new AnnotationsServiceProviderAppNamespaceStub( $this->app ); - $class = 'App\\Foo'; + public function testConvertNamespaceToPath() + { + $this->provider = new AnnotationsServiceProviderAppNamespaceStub($this->app); + $class = 'App\\Foo'; - $result = $this->provider->convertNamespaceToPath($class); + $result = $this->provider->convertNamespaceToPath($class); - $this->assertEquals('Foo', $result); - } + $this->assertEquals('Foo', $result); + } - public function testConvertNamespaceToPathWithoutRootNamespace() - { - $this->provider = new AnnotationsServiceProviderAppNamespaceStub( $this->app ); - $this->provider->appNamespace = 'Foo'; - $class = 'App\\Foo'; + public function testConvertNamespaceToPathWithoutRootNamespace() + { + $this->provider = new AnnotationsServiceProviderAppNamespaceStub($this->app); + $this->provider->appNamespace = 'Foo'; + $class = 'App\\Foo'; - $result = $this->provider->convertNamespaceToPath($class); + $result = $this->provider->convertNamespaceToPath($class); - $this->assertEquals('App/Foo', $result); - } + $this->assertEquals('App/Foo', $result); + } - public function testGetClassesFromNamespace() - { - $this->provider = new AnnotationsServiceProviderAppNamespaceStub( $this->app ); - $this->provider->appNamespace = 'App'; + public function testGetClassesFromNamespace() + { + $this->provider = new AnnotationsServiceProviderAppNamespaceStub($this->app); + $this->provider->appNamespace = 'App'; - $this->app->shouldReceive( 'make' ) - ->with( 'Illuminate\Filesystem\ClassFinder' )->once() - ->andReturn( $classFinder = m::mock() ); + $this->app->shouldReceive('make') + ->with('Illuminate\Filesystem\ClassFinder')->once() + ->andReturn($classFinder = m::mock()); - $classFinder->shouldReceive('findClasses') - ->with('path/to/app/Base')->once() - ->andReturn( ['classes'] ); + $classFinder->shouldReceive('findClasses') + ->with('path/to/app/Base')->once() + ->andReturn(['classes']); - $results = $this->provider->getClassesFromNamespace( 'App\\Base', 'path/to/app' ); + $results = $this->provider->getClassesFromNamespace('App\\Base', 'path/to/app'); - $this->assertEquals( ['classes'], $results ); - } + $this->assertEquals(['classes'], $results); + } } +class AnnotationsServiceProviderAppNamespaceStub extends AnnotationsServiceProvider +{ + public $appNamespace = 'App'; -class AnnotationsServiceProviderAppNamespaceStub extends AnnotationsServiceProvider { - public $appNamespace = 'App'; - - public function getAppNamespace() - { - return $this->appNamespace; - } + public function getAppNamespace() + { + return $this->appNamespace; + } } diff --git a/tests/Models/ModelAnnotationScannerTest.php b/tests/Models/ModelAnnotationScannerTest.php index 5581a3d..32512d0 100644 --- a/tests/Models/ModelAnnotationScannerTest.php +++ b/tests/Models/ModelAnnotationScannerTest.php @@ -2,32 +2,33 @@ use Collective\Annotations\Database\Eloquent\Annotations\Scanner; -class ModelAnnotationScannerTest extends PHPUnit_Framework_TestCase { +class ModelAnnotationScannerTest extends PHPUnit_Framework_TestCase +{ + public function testProperRouteDefinitionsAreGenerated() + { + require_once __DIR__.'/fixtures/annotations/AnyModel.php'; + $scanner = $this->makeScanner(['App\User']); - public function testProperRouteDefinitionsAreGenerated() - { - require_once __DIR__.'/fixtures/annotations/AnyModel.php'; - $scanner = $this->makeScanner( ['App\User'] ); + $definition = str_replace(PHP_EOL, "\n", $scanner->getModelDefinitions()); + $this->assertEquals(trim(file_get_contents(__DIR__.'/results/annotation.php')), $definition); + } - $definition = str_replace(PHP_EOL, "\n", $scanner->getModelDefinitions()); - $this->assertEquals(trim(file_get_contents(__DIR__.'/results/annotation.php')), $definition); - } + /** + * Construct a route annotation scanner. + * + * @param array $paths + * + * @return + */ + protected function makeScanner($paths) + { + $scanner = Scanner::create($paths); - /** - * Construct a route annotation scanner - * - * @param array $paths - * @return - */ - protected function makeScanner( $paths ) - { - $scanner = Scanner::create( $paths ); + $scanner->addAnnotationNamespace( + 'Collective\Annotations\Database\Eloquent\Annotations\Annotations', + realpath(__DIR__.'/../../src/Database/Eloquent//Annotations/Annotations') + ); - $scanner->addAnnotationNamespace( - 'Collective\Annotations\Database\Eloquent\Annotations\Annotations', - realpath(__DIR__.'/../../src/Database/Eloquent//Annotations/Annotations') - ); - - return $scanner; - } + return $scanner; + } } diff --git a/tests/Models/fixtures/annotations/AnyModel.php b/tests/Models/fixtures/annotations/AnyModel.php index ce1bc6e..78a016a 100644 --- a/tests/Models/fixtures/annotations/AnyModel.php +++ b/tests/Models/fixtures/annotations/AnyModel.php @@ -1,10 +1,12 @@ -makeScanner( ['App\Http\Controllers\BasicController'] ); - - $definition = str_replace(PHP_EOL, "\n", $scanner->getRouteDefinitions()); - $this->assertEquals(trim(file_get_contents(__DIR__.'/results/annotation-basic.php')), $definition); - } - - public function testAnyAnnotation() - { - require_once __DIR__.'/fixtures/annotations/AnyController.php'; - $scanner = $this->makeScanner( ['App\Http\Controllers\AnyController'] ); - - $definition = str_replace(PHP_EOL, "\n", $scanner->getRouteDefinitions()); - $this->assertEquals(trim(file_get_contents(__DIR__.'/results/annotation-any.php')), $definition); - } - - /** - * Construct a route annotation scanner - * - * @param array $paths - * @return - */ - protected function makeScanner( $paths ) - { - $scanner = Scanner::create( $paths ); - - $scanner->addAnnotationNamespace( - 'Collective\Annotations\Routing\Annotations\Annotations', - realpath(__DIR__.'/../../src/Routing/Annotations/Annotations') - ); - - return $scanner; - } +class RoutingAnnotationScannerTest extends PHPUnit_Framework_TestCase +{ + public function testProperRouteDefinitionsAreGenerated() + { + require_once __DIR__.'/fixtures/annotations/BasicController.php'; + $scanner = $this->makeScanner(['App\Http\Controllers\BasicController']); + + $definition = str_replace(PHP_EOL, "\n", $scanner->getRouteDefinitions()); + $this->assertEquals(trim(file_get_contents(__DIR__.'/results/annotation-basic.php')), $definition); + } + + public function testAnyAnnotation() + { + require_once __DIR__.'/fixtures/annotations/AnyController.php'; + $scanner = $this->makeScanner(['App\Http\Controllers\AnyController']); + + $definition = str_replace(PHP_EOL, "\n", $scanner->getRouteDefinitions()); + $this->assertEquals(trim(file_get_contents(__DIR__.'/results/annotation-any.php')), $definition); + } + + /** + * Construct a route annotation scanner. + * + * @param array $paths + * + * @return + */ + protected function makeScanner($paths) + { + $scanner = Scanner::create($paths); + + $scanner->addAnnotationNamespace( + 'Collective\Annotations\Routing\Annotations\Annotations', + realpath(__DIR__.'/../../src/Routing/Annotations/Annotations') + ); + + return $scanner; + } } diff --git a/tests/Routing/fixtures/annotations/AnyController.php b/tests/Routing/fixtures/annotations/AnyController.php index 0cc41f5..1ecb24a 100644 --- a/tests/Routing/fixtures/annotations/AnyController.php +++ b/tests/Routing/fixtures/annotations/AnyController.php @@ -1,9 +1,13 @@ -