From b550c86bf80b5dd891de73018cfb64f24ffe15d1 Mon Sep 17 00:00:00 2001 From: Rich Vigorito Date: Fri, 9 Jun 2017 10:28:25 -0700 Subject: [PATCH 01/12] add support for multiple annotations per function --- src/Metadata/RouteScanner.php | 127 ++++++++++++++++++---------------- src/Routing/Generator.php | 7 +- 2 files changed, 72 insertions(+), 62 deletions(-) diff --git a/src/Metadata/RouteScanner.php b/src/Metadata/RouteScanner.php index fbc042f..809e63d 100644 --- a/src/Metadata/RouteScanner.php +++ b/src/Metadata/RouteScanner.php @@ -76,17 +76,16 @@ public function parseController($class) $classAnnotations = $this->reader->getClassAnnotations($reflectionClass); $controllerMetadata = []; - $middleware = []; // find entity parameters and plugins foreach ($classAnnotations as $annotation) { // controller attributes if ($annotation instanceof \ProAI\Annotations\Annotations\Controller) { $prefix = $annotation->prefix; - $middleware = $this->addMiddleware($middleware, $annotation->middleware); + $middleware = $annotation->middleware; } if ($annotation instanceof \ProAI\Annotations\Annotations\Middleware) { - $middleware = $this->addMiddleware($middleware, $annotation->value); + $middleware = $annotation->value; } // resource controller @@ -107,10 +106,13 @@ public function parseController($class) // find routes foreach ($reflectionClass->getMethods() as $reflectionMethod) { + $name = $reflectionMethod->getName(); $methodAnnotations = $this->reader->getMethodAnnotations($reflectionMethod); + $routeMetadata = []; + // controller method is resource route if (! empty($resource) && in_array($name, $resource['methods'])) { $routeMetadata = [ @@ -124,8 +126,10 @@ public function parseController($class) } // controller method is route - if ($route = $this->hasHttpMethodAnnotation($name, $methodAnnotations)) { - $routeMetadata = [ + if ($routes = $this->hasHttpMethodAnnotation($name, $methodAnnotations)) { + $routeMetadata = []; + foreach($routes as $route){ + $routeMetadata[] = [ 'uri' => $route['uri'], 'controller' => $class, 'controllerMethod' => $name, @@ -133,27 +137,39 @@ public function parseController($class) 'as' => $route['as'], 'middleware' => $route['middleware'] ]; + } } // add more route options to route metadata - if (! empty($routeMetadata)) { - if (! empty($middleware)) { - $routeMetadata['middleware'] = $middleware; + if (! empty($routeMetadata)) { + if(!isset($routeMetadata[0])){ + $temp = []; + $temp[] = $routeMetadata; + $routeMetadatas = $temp; + } else { + $routeMetadatas = $routeMetadata; } + $idx = 0; + foreach($routeMetadatas as $routeMetadata){ + $idx++; - // add other method annotations - foreach ($methodAnnotations as $annotation) { + // add other method annotations + foreach ($methodAnnotations as $annotation) { if ($annotation instanceof \ProAI\Annotations\Annotations\Middleware) { - $middleware = $this->addMiddleware($middleware, $routeMetadata['middleware']); + $routeMetadata['middleware'] = $annotation->value; } - } + } - // add global prefix and middleware - if (! empty($prefix)) { + // add global prefix and middleware + if (! empty($prefix)) { $routeMetadata['uri'] = $prefix.'/'.$routeMetadata['uri']; - } + } + if (! empty($middleware) && empty($routeMetadata['middleware'])) { + $routeMetadata['middleware'] = $middleware; + } - $controllerMetadata[$name] = $routeMetadata; + $controllerMetadata[$name.$idx] = $routeMetadata; + } } } @@ -211,74 +227,69 @@ protected function getResourcePath($method) */ protected function hasHttpMethodAnnotation($name, $methodAnnotations) { + + $scrapAnnotation = function ($httpMethod,$annotation){ + // options + $as = (! empty($annotation->as)) ? $annotation->as : ''; + $middleware = (! empty($annotation->middleware)) ? $annotation->middleware : ''; + + $uri = (empty($annotation->value)) ? str_replace("_", "-", snake_case($name)) : $annotation->value; + return [ + 'uri' => $uri, + 'httpMethod' => $httpMethod, + 'as' => $as, + 'middleware' => $middleware + ]; + + }; + + + $return = []; + foreach ($methodAnnotations as $annotation) { // check for http method annotation if ($annotation instanceof \ProAI\Annotations\Annotations\Get) { $httpMethod = 'GET'; - break; + $return[] = $scrapAnnotation($httpMethod,$annotation); + // break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Post) { $httpMethod = 'POST'; - break; + $return[] = $scrapAnnotation($httpMethod,$annotation); + //break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Options) { $httpMethod = 'OPTIONS'; - break; + $return[] = $scrapAnnotation($httpMethod,$annotation); + // break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Put) { $httpMethod = 'PUT'; - break; + $return[] = $scrapAnnotation($httpMethod,$annotation); + //break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Patch) { $httpMethod = 'PATCH'; - break; + $return[] = $scrapAnnotation($httpMethod,$annotation); + // break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Delete) { $httpMethod = 'DELETE'; - break; + $return[] = $scrapAnnotation($httpMethod,$annotation); + //break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Any) { $httpMethod = 'ANY'; - break; + $return[] = $scrapAnnotation($httpMethod,$annotation); + //break; } } - // http method found - if (! empty($httpMethod)) { - // options - $as = (! empty($annotation->as)) ? $annotation->as : ''; - - $uri = (empty($annotation->value)) ? str_replace("_", "-", snake_case($name)) : $annotation->value; - - return [ - 'uri' => $uri, - 'httpMethod' => $httpMethod, - 'as' => $as, - 'middleware' => $this->addMiddleware([], $annotation->middleware) - ]; - } - - return null; - } - - /** - * Add middleware - * - * @param array $middleware - * @param array $newMiddleware - * @return array - */ - protected function addMiddleware($middleware, $newMiddleware) - { - if (! empty($newMiddleware)) { - $newMiddleware = (is_array($newMiddleware)) - ? $newMiddleware - : [$newMiddleware]; - - return array_merge($middleware, $newMiddleware); + if(count($return) > 0){ + return $return; + } else { + return false; } - - return $middleware; } } diff --git a/src/Routing/Generator.php b/src/Routing/Generator.php index d0eeb3c..12b4773 100644 --- a/src/Routing/Generator.php +++ b/src/Routing/Generator.php @@ -100,11 +100,10 @@ public function generateRoutes($metadata) // middleware option if (! empty($routeMetadata['middleware'])) { - $middleware = implode("', '",$routeMetadata['middleware']); - if (count($routeMetadata['middleware']) > 1) { - $middleware = "['".$middleware."']"; + if (is_array($routeMetadata['middleware'])) { + $middleware = "['".implode("', '",$routeMetadata['middleware'])."']"; } else { - $middleware = "'".$middleware."'"; + $middleware = "'".$routeMetadata['middleware']."'"; } $options[] = "'middleware' => ".$middleware; } From 103f544e221b79d7133d4d3c9fde984093f06904 Mon Sep 17 00:00:00 2001 From: Rich Vigorito Date: Fri, 9 Jun 2017 10:31:25 -0700 Subject: [PATCH 02/12] change variable name scrap->parse --- src/Metadata/RouteScanner.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Metadata/RouteScanner.php b/src/Metadata/RouteScanner.php index 809e63d..efc9697 100644 --- a/src/Metadata/RouteScanner.php +++ b/src/Metadata/RouteScanner.php @@ -228,7 +228,7 @@ protected function getResourcePath($method) protected function hasHttpMethodAnnotation($name, $methodAnnotations) { - $scrapAnnotation = function ($httpMethod,$annotation){ + $parseAnnotation = function ($httpMethod,$annotation){ // options $as = (! empty($annotation->as)) ? $annotation->as : ''; $middleware = (! empty($annotation->middleware)) ? $annotation->middleware : ''; @@ -250,37 +250,37 @@ protected function hasHttpMethodAnnotation($name, $methodAnnotations) // check for http method annotation if ($annotation instanceof \ProAI\Annotations\Annotations\Get) { $httpMethod = 'GET'; - $return[] = $scrapAnnotation($httpMethod,$annotation); + $return[] = $parseAnnotation($httpMethod,$annotation); // break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Post) { $httpMethod = 'POST'; - $return[] = $scrapAnnotation($httpMethod,$annotation); + $return[] = $parseAnnotation($httpMethod,$annotation); //break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Options) { $httpMethod = 'OPTIONS'; - $return[] = $scrapAnnotation($httpMethod,$annotation); + $return[] = $parseAnnotation($httpMethod,$annotation); // break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Put) { $httpMethod = 'PUT'; - $return[] = $scrapAnnotation($httpMethod,$annotation); + $return[] = $parseAnnotation($httpMethod,$annotation); //break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Patch) { $httpMethod = 'PATCH'; - $return[] = $scrapAnnotation($httpMethod,$annotation); + $return[] = $parseAnnotation($httpMethod,$annotation); // break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Delete) { $httpMethod = 'DELETE'; - $return[] = $scrapAnnotation($httpMethod,$annotation); + $return[] = $parseAnnotation($httpMethod,$annotation); //break; } if ($annotation instanceof \ProAI\Annotations\Annotations\Any) { $httpMethod = 'ANY'; - $return[] = $scrapAnnotation($httpMethod,$annotation); + $return[] = $parseAnnotation($httpMethod,$annotation); //break; } From 756fdcb1ee13ab8c4bdf279dc73155df66bbd269 Mon Sep 17 00:00:00 2001 From: richvigorito Date: Fri, 9 Jun 2017 10:42:14 -0700 Subject: [PATCH 03/12] Create composer.json adding my name to this fork --- composer.json | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 7310064..9349e3d 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "proai/lumen-annotations", + "name": "richvigorito/lumen-annotations", "description": "Route and event binding annotations for Laravel Lumen", "keywords": ["laravel","lumen","route","routes","router","annotations","event","event binding"], "homepage": "http://github.com/proai/lumen-annotations", @@ -8,7 +8,11 @@ { "name": "Markus J. Wetzel", "email": "markuswetzel@gmx.net" - } + }, + { + "name": "Rich Vigorito", + "email": "richv@ocp.org" + }, ], "require": { "php": ">=5.5.9", @@ -16,7 +20,7 @@ }, "autoload": { "psr-4": { - "ProAI\\Annotations\\": "src/" + "RV\\Annotations\\": "src/" } }, "extra": { From efce39e80bebc4ee3bc1f8785beef774bf0aa899 Mon Sep 17 00:00:00 2001 From: richvigorito Date: Fri, 9 Jun 2017 10:45:34 -0700 Subject: [PATCH 04/12] Create composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9349e3d..600f2ec 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "richvigorito/lumen-annotations", + "name": "rv/lumen-annotations", "description": "Route and event binding annotations for Laravel Lumen", "keywords": ["laravel","lumen","route","routes","router","annotations","event","event binding"], "homepage": "http://github.com/proai/lumen-annotations", From 5e8a85f02f2f5a63d0b490590b3b399247b52fa7 Mon Sep 17 00:00:00 2001 From: richvigorito Date: Fri, 9 Jun 2017 10:52:12 -0700 Subject: [PATCH 05/12] Create composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 600f2ec..5111cfd 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "rv/lumen-annotations", + "name": "proai/lumen-annotations", "description": "Route and event binding annotations for Laravel Lumen", "keywords": ["laravel","lumen","route","routes","router","annotations","event","event binding"], "homepage": "http://github.com/proai/lumen-annotations", @@ -20,7 +20,7 @@ }, "autoload": { "psr-4": { - "RV\\Annotations\\": "src/" + "ProAI\\Annotations\\": "src/" } }, "extra": { From 82dc62d987275dc7c2686e26ac9399a014735971 Mon Sep 17 00:00:00 2001 From: richvigorito Date: Fri, 9 Jun 2017 11:12:56 -0700 Subject: [PATCH 06/12] Create composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5111cfd..af76901 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "proai/lumen-annotations", + "name": "richvigorito/lumen-annotations", "description": "Route and event binding annotations for Laravel Lumen", "keywords": ["laravel","lumen","route","routes","router","annotations","event","event binding"], "homepage": "http://github.com/proai/lumen-annotations", From 92be79dcde2980c53b8e4f13cf29ee9eb9f868af Mon Sep 17 00:00:00 2001 From: richvigorito Date: Fri, 9 Jun 2017 11:20:35 -0700 Subject: [PATCH 07/12] Update composer.json --- composer.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/composer.json b/composer.json index af76901..95226f2 100644 --- a/composer.json +++ b/composer.json @@ -22,10 +22,5 @@ "psr-4": { "ProAI\\Annotations\\": "src/" } - }, - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } } } From 0fbcca231c8e2201ac4ec55be7d54cc54d1a4782 Mon Sep 17 00:00:00 2001 From: richvigorito Date: Fri, 9 Jun 2017 11:22:53 -0700 Subject: [PATCH 08/12] Create composer.json --- composer.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 95226f2..8c0fe31 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "richvigorito/lumen-annotations", "description": "Route and event binding annotations for Laravel Lumen", "keywords": ["laravel","lumen","route","routes","router","annotations","event","event binding"], - "homepage": "http://github.com/proai/lumen-annotations", + "homepage": "http://github.com/richvigorito/lumen-annotations", "license": "MIT", "authors": [ { @@ -22,5 +22,10 @@ "psr-4": { "ProAI\\Annotations\\": "src/" } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } } } From a9b4d86915cccec1228f045402e491e5d142bc40 Mon Sep 17 00:00:00 2001 From: richvigorito Date: Fri, 9 Jun 2017 11:28:36 -0700 Subject: [PATCH 09/12] Update composer.json remove extra comma --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8c0fe31..3c482c2 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ { "name": "Rich Vigorito", "email": "richv@ocp.org" - }, + } ], "require": { "php": ">=5.5.9", From eb85bde0f7a26c48ed44996a79c39973858b8e88 Mon Sep 17 00:00:00 2001 From: richvigorito Date: Wed, 26 Sep 2018 13:36:09 -0700 Subject: [PATCH 10/12] Update composer.json --- composer.json | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 3c482c2..7310064 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,13 @@ { - "name": "richvigorito/lumen-annotations", + "name": "proai/lumen-annotations", "description": "Route and event binding annotations for Laravel Lumen", "keywords": ["laravel","lumen","route","routes","router","annotations","event","event binding"], - "homepage": "http://github.com/richvigorito/lumen-annotations", + "homepage": "http://github.com/proai/lumen-annotations", "license": "MIT", "authors": [ { "name": "Markus J. Wetzel", "email": "markuswetzel@gmx.net" - }, - { - "name": "Rich Vigorito", - "email": "richv@ocp.org" } ], "require": { From aa2895e65cce73b7580ab06d30f37410add823d3 Mon Sep 17 00:00:00 2001 From: Rich Vigorito Date: Tue, 3 Sep 2019 13:28:16 -0700 Subject: [PATCH 11/12] VGS-825 fix metadata for middleware not being able to append --- src/Metadata/RouteScanner.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Metadata/RouteScanner.php b/src/Metadata/RouteScanner.php index efc9697..e389863 100644 --- a/src/Metadata/RouteScanner.php +++ b/src/Metadata/RouteScanner.php @@ -153,12 +153,17 @@ public function parseController($class) foreach($routeMetadatas as $routeMetadata){ $idx++; - // add other method annotations - foreach ($methodAnnotations as $annotation) { - if ($annotation instanceof \ProAI\Annotations\Annotations\Middleware) { - $routeMetadata['middleware'] = $annotation->value; - } + // add other method annotations + foreach ($methodAnnotations as $annotation) { + if ($annotation instanceof \ProAI\Annotations\Annotations\Middleware) { + if (!empty($middleware) && isset($routeMetadata['middleware'])) { + $routeMetadata['middleware'] = [$middleware, $annotation->value]; + continue; + } + + $routeMetadata['middleware'] = $annotation->value; } + } // add global prefix and middleware if (! empty($prefix)) { From b93a0573a27390ca8c626464670a092877380330 Mon Sep 17 00:00:00 2001 From: Rich Vigorito Date: Mon, 11 Nov 2019 10:10:06 -0800 Subject: [PATCH 12/12] changes for laravel54 upgrdae --- src/Filesystem/ClassFinder.php | 126 ++++++++++++++++++++++ src/Metadata/ClassFinder.php | 2 +- src/Providers/MetadataServiceProvider.php | 2 +- 3 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/Filesystem/ClassFinder.php diff --git a/src/Filesystem/ClassFinder.php b/src/Filesystem/ClassFinder.php new file mode 100644 index 0000000..7699ee5 --- /dev/null +++ b/src/Filesystem/ClassFinder.php @@ -0,0 +1,126 @@ +in($directory)->name('*.php') as $file) { + $classes[] = $this->findClass($file->getRealPath()); + } + return array_filter($classes); + } + /** + * Extract the class name from the file at the given path. + * + * @param string $path + * @return string|null + */ + public function findClass($path) + { + $namespace = null; + $tokens = token_get_all(file_get_contents($path)); + foreach ($tokens as $key => $token) { + if ($this->tokenIsNamespace($token)) { + $namespace = $this->getNamespace($key + 2, $tokens); + } elseif ($this->tokenIsClassOrInterface($token)) { + return ltrim($namespace.'\\'.$this->getClass($key + 2, $tokens), '\\'); + } + } + } + /** + * Find the namespace in the tokens starting at a given key. + * + * @param int $key + * @param array $tokens + * @return string|null + */ + protected function getNamespace($key, array $tokens) + { + $namespace = null; + $tokenCount = count($tokens); + for ($i = $key; $i < $tokenCount; $i++) { + if ($this->isPartOfNamespace($tokens[$i])) { + $namespace .= $tokens[$i][1]; + } elseif ($tokens[$i] == ';') { + return $namespace; + } + } + } + /** + * Find the class in the tokens starting at a given key. + * + * @param int $key + * @param array $tokens + * @return string|null + */ + protected function getClass($key, array $tokens) + { + $class = null; + $tokenCount = count($tokens); + for ($i = $key; $i < $tokenCount; $i++) { + if ($this->isPartOfClass($tokens[$i])) { + $class .= $tokens[$i][1]; + } elseif ($this->isWhitespace($tokens[$i])) { + return $class; + } + } + } + /** + * Determine if the given token is a namespace keyword. + * + * @param array|string $token + * @return bool + */ + protected function tokenIsNamespace($token) + { + return is_array($token) && $token[0] == T_NAMESPACE; + } + /** + * Determine if the given token is a class or interface keyword. + * + * @param array|string $token + * @return bool + */ + protected function tokenIsClassOrInterface($token) + { + return is_array($token) && ($token[0] == T_CLASS || $token[0] == T_INTERFACE); + } + /** + * Determine if the given token is part of the namespace. + * + * @param array|string $token + * @return bool + */ + protected function isPartOfNamespace($token) + { + return is_array($token) && ($token[0] == T_STRING || $token[0] == T_NS_SEPARATOR); + } + /** + * Determine if the given token is part of the class. + * + * @param array|string $token + * @return bool + */ + protected function isPartOfClass($token) + { + return is_array($token) && $token[0] == T_STRING; + } + /** + * Determine if the given token is whitespace. + * + * @param array|string $token + * @return bool + */ + protected function isWhitespace($token) + { + return is_array($token) && $token[0] == T_WHITESPACE; + } +} diff --git a/src/Metadata/ClassFinder.php b/src/Metadata/ClassFinder.php index 7521a4c..0d37226 100644 --- a/src/Metadata/ClassFinder.php +++ b/src/Metadata/ClassFinder.php @@ -3,7 +3,7 @@ namespace ProAI\Annotations\Metadata; use Illuminate\Console\AppNamespaceDetectorTrait; -use Illuminate\Filesystem\ClassFinder as FilesystemClassFinder; +use ProAI\Annotations\Filesystem\ClassFinder as FilesystemClassFinder; class ClassFinder { diff --git a/src/Providers/MetadataServiceProvider.php b/src/Providers/MetadataServiceProvider.php index 36fefeb..173bc88 100644 --- a/src/Providers/MetadataServiceProvider.php +++ b/src/Providers/MetadataServiceProvider.php @@ -4,7 +4,7 @@ use Illuminate\Support\ServiceProvider; use ProAI\Annotations\Metadata\ClassFinder; -use Illuminate\Filesystem\ClassFinder as FilesystemClassFinder; +use ProAI\Annotations\Filesystem\ClassFinder as FilesystemClassFinder; use ProAI\Annotations\Metadata\AnnotationLoader; use Doctrine\Common\Annotations\AnnotationReader;