From 96f2ff123f4d8f4f01727086786b949d4a45816f Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Fri, 17 Mar 2023 10:42:55 +0100 Subject: [PATCH 1/3] Refactor shared methodExcludedByOptions static method to trait --- .../Routing/ControllerDispatcher.php | 15 +-------------- .../ControllerMiddlewareFilterTrait.php | 19 +++++++++++++++++++ src/Illuminate/Routing/Route.php | 4 ++-- 3 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 src/Illuminate/Routing/ControllerMiddlewareFilterTrait.php diff --git a/src/Illuminate/Routing/ControllerDispatcher.php b/src/Illuminate/Routing/ControllerDispatcher.php index d3b0bc88c4d2..84c907353771 100644 --- a/src/Illuminate/Routing/ControllerDispatcher.php +++ b/src/Illuminate/Routing/ControllerDispatcher.php @@ -7,7 +7,7 @@ class ControllerDispatcher implements ControllerDispatcherContract { - use RouteDependencyResolverTrait; + use ControllerMiddlewareFilterTrait, RouteDependencyResolverTrait; /** * The container instance. @@ -78,17 +78,4 @@ public function getMiddleware($controller, $method) return static::methodExcludedByOptions($method, $data['options']); })->pluck('middleware')->all(); } - - /** - * Determine if the given options exclude a particular method. - * - * @param string $method - * @param array $options - * @return bool - */ - public static function methodExcludedByOptions($method, array $options) - { - return (isset($options['only']) && ! in_array($method, (array) $options['only'])) || - (! empty($options['except']) && in_array($method, (array) $options['except'])); - } } diff --git a/src/Illuminate/Routing/ControllerMiddlewareFilterTrait.php b/src/Illuminate/Routing/ControllerMiddlewareFilterTrait.php new file mode 100644 index 000000000000..8b1a6a5e0eb3 --- /dev/null +++ b/src/Illuminate/Routing/ControllerMiddlewareFilterTrait.php @@ -0,0 +1,19 @@ +reject(function ($middleware) use ($method) { - return $this->controllerDispatcher()::methodExcludedByOptions( + return static::methodExcludedByOptions( $method, ['only' => $middleware->only, 'except' => $middleware->except] ); })->map->middleware->values()->all(); From 0206ec979b2a9a5010295e4aa3ccb1dc038075b6 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 17 Mar 2023 09:08:50 -0500 Subject: [PATCH 2/3] formatting --- src/Illuminate/Routing/CallableDispatcher.php | 2 +- .../Routing/ControllerDispatcher.php | 2 +- ...it.php => FiltersControllerMiddleware.php} | 2 +- .../Routing/ResolvesRouteDependencies.php | 117 ++++++++++++++++++ src/Illuminate/Routing/Route.php | 2 +- .../Routing/RouteDependencyResolverTrait.php | 114 +---------------- tests/Routing/ImplicitRouteBindingTest.php | 2 +- 7 files changed, 126 insertions(+), 115 deletions(-) rename src/Illuminate/Routing/{ControllerMiddlewareFilterTrait.php => FiltersControllerMiddleware.php} (92%) create mode 100644 src/Illuminate/Routing/ResolvesRouteDependencies.php diff --git a/src/Illuminate/Routing/CallableDispatcher.php b/src/Illuminate/Routing/CallableDispatcher.php index e85ee04bc1ce..737e76dfed7a 100644 --- a/src/Illuminate/Routing/CallableDispatcher.php +++ b/src/Illuminate/Routing/CallableDispatcher.php @@ -8,7 +8,7 @@ class CallableDispatcher implements CallableDispatcherContract { - use RouteDependencyResolverTrait; + use ResolvesRouteDependencies; /** * The container instance. diff --git a/src/Illuminate/Routing/ControllerDispatcher.php b/src/Illuminate/Routing/ControllerDispatcher.php index 84c907353771..06f6a194e159 100644 --- a/src/Illuminate/Routing/ControllerDispatcher.php +++ b/src/Illuminate/Routing/ControllerDispatcher.php @@ -7,7 +7,7 @@ class ControllerDispatcher implements ControllerDispatcherContract { - use ControllerMiddlewareFilterTrait, RouteDependencyResolverTrait; + use FiltersControllerMiddleware, ResolvesRouteDependencies; /** * The container instance. diff --git a/src/Illuminate/Routing/ControllerMiddlewareFilterTrait.php b/src/Illuminate/Routing/FiltersControllerMiddleware.php similarity index 92% rename from src/Illuminate/Routing/ControllerMiddlewareFilterTrait.php rename to src/Illuminate/Routing/FiltersControllerMiddleware.php index 8b1a6a5e0eb3..ba14d653e60f 100644 --- a/src/Illuminate/Routing/ControllerMiddlewareFilterTrait.php +++ b/src/Illuminate/Routing/FiltersControllerMiddleware.php @@ -2,7 +2,7 @@ namespace Illuminate\Routing; -trait ControllerMiddlewareFilterTrait +trait FiltersControllerMiddleware { /** * Determine if the given options exclude a particular method. diff --git a/src/Illuminate/Routing/ResolvesRouteDependencies.php b/src/Illuminate/Routing/ResolvesRouteDependencies.php new file mode 100644 index 000000000000..f5fc2fcb2a31 --- /dev/null +++ b/src/Illuminate/Routing/ResolvesRouteDependencies.php @@ -0,0 +1,117 @@ +resolveMethodDependencies( + $parameters, new ReflectionMethod($instance, $method) + ); + } + + /** + * Resolve the given method's type-hinted dependencies. + * + * @param array $parameters + * @param \ReflectionFunctionAbstract $reflector + * @return array + */ + public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector) + { + $instanceCount = 0; + + $values = array_values($parameters); + + $skippableValue = new stdClass; + + foreach ($reflector->getParameters() as $key => $parameter) { + $instance = $this->transformDependency($parameter, $parameters, $skippableValue); + + if ($instance !== $skippableValue) { + $instanceCount++; + + $this->spliceIntoParameters($parameters, $key, $instance); + } elseif (! isset($values[$key - $instanceCount]) && + $parameter->isDefaultValueAvailable()) { + $this->spliceIntoParameters($parameters, $key, $parameter->getDefaultValue()); + } + } + + return $parameters; + } + + /** + * Attempt to transform the given parameter into a class instance. + * + * @param \ReflectionParameter $parameter + * @param array $parameters + * @param object $skippableValue + * @return mixed + */ + protected function transformDependency(ReflectionParameter $parameter, $parameters, $skippableValue) + { + $className = Reflector::getParameterClassName($parameter); + + // If the parameter has a type-hinted class, we will check to see if it is already in + // the list of parameters. If it is we will just skip it as it is probably a model + // binding and we do not want to mess with those; otherwise, we resolve it here. + if ($className && ! $this->alreadyInParameters($className, $parameters)) { + $isEnum = (new ReflectionClass($className))->isEnum(); + + return $parameter->isDefaultValueAvailable() + ? ($isEnum ? $parameter->getDefaultValue() : null) + : $this->container->make($className); + } + + return $skippableValue; + } + + /** + * Determine if an object of the given class is in a list of parameters. + * + * @param string $class + * @param array $parameters + * @return bool + */ + protected function alreadyInParameters($class, array $parameters) + { + return ! is_null(Arr::first($parameters, fn ($value) => $value instanceof $class)); + } + + /** + * Splice the given value into the parameter list. + * + * @param array $parameters + * @param string $offset + * @param mixed $value + * @return void + */ + protected function spliceIntoParameters(array &$parameters, $offset, $value) + { + array_splice( + $parameters, $offset, 0, [$value] + ); + } +} diff --git a/src/Illuminate/Routing/Route.php b/src/Illuminate/Routing/Route.php index 869faeb69c3b..14f5483be54f 100755 --- a/src/Illuminate/Routing/Route.php +++ b/src/Illuminate/Routing/Route.php @@ -22,7 +22,7 @@ class Route { - use CreatesRegularExpressionRouteConstraints, ControllerMiddlewareFilterTrait, Macroable, RouteDependencyResolverTrait; + use CreatesRegularExpressionRouteConstraints, FiltersControllerMiddleware, Macroable, ResolvesRouteDependencies; /** * The URI pattern the route responds to. diff --git a/src/Illuminate/Routing/RouteDependencyResolverTrait.php b/src/Illuminate/Routing/RouteDependencyResolverTrait.php index 80109eb38421..c2a4ec553c3d 100644 --- a/src/Illuminate/Routing/RouteDependencyResolverTrait.php +++ b/src/Illuminate/Routing/RouteDependencyResolverTrait.php @@ -2,116 +2,10 @@ namespace Illuminate\Routing; -use Illuminate\Support\Arr; -use Illuminate\Support\Reflector; -use ReflectionClass; -use ReflectionFunctionAbstract; -use ReflectionMethod; -use ReflectionParameter; -use stdClass; - +/** + * @deprecated + */ trait RouteDependencyResolverTrait { - /** - * Resolve the object method's type-hinted dependencies. - * - * @param array $parameters - * @param object $instance - * @param string $method - * @return array - */ - protected function resolveClassMethodDependencies(array $parameters, $instance, $method) - { - if (! method_exists($instance, $method)) { - return $parameters; - } - - return $this->resolveMethodDependencies( - $parameters, new ReflectionMethod($instance, $method) - ); - } - - /** - * Resolve the given method's type-hinted dependencies. - * - * @param array $parameters - * @param \ReflectionFunctionAbstract $reflector - * @return array - */ - public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector) - { - $instanceCount = 0; - - $values = array_values($parameters); - - $skippableValue = new stdClass; - - foreach ($reflector->getParameters() as $key => $parameter) { - $instance = $this->transformDependency($parameter, $parameters, $skippableValue); - - if ($instance !== $skippableValue) { - $instanceCount++; - - $this->spliceIntoParameters($parameters, $key, $instance); - } elseif (! isset($values[$key - $instanceCount]) && - $parameter->isDefaultValueAvailable()) { - $this->spliceIntoParameters($parameters, $key, $parameter->getDefaultValue()); - } - } - - return $parameters; - } - - /** - * Attempt to transform the given parameter into a class instance. - * - * @param \ReflectionParameter $parameter - * @param array $parameters - * @param object $skippableValue - * @return mixed - */ - protected function transformDependency(ReflectionParameter $parameter, $parameters, $skippableValue) - { - $className = Reflector::getParameterClassName($parameter); - - // If the parameter has a type-hinted class, we will check to see if it is already in - // the list of parameters. If it is we will just skip it as it is probably a model - // binding and we do not want to mess with those; otherwise, we resolve it here. - if ($className && ! $this->alreadyInParameters($className, $parameters)) { - $isEnum = (new ReflectionClass($className))->isEnum(); - - return $parameter->isDefaultValueAvailable() - ? ($isEnum ? $parameter->getDefaultValue() : null) - : $this->container->make($className); - } - - return $skippableValue; - } - - /** - * Determine if an object of the given class is in a list of parameters. - * - * @param string $class - * @param array $parameters - * @return bool - */ - protected function alreadyInParameters($class, array $parameters) - { - return ! is_null(Arr::first($parameters, fn ($value) => $value instanceof $class)); - } - - /** - * Splice the given value into the parameter list. - * - * @param array $parameters - * @param string $offset - * @param mixed $value - * @return void - */ - protected function spliceIntoParameters(array &$parameters, $offset, $value) - { - array_splice( - $parameters, $offset, 0, [$value] - ); - } + use ResolvesRouteDependencies; } diff --git a/tests/Routing/ImplicitRouteBindingTest.php b/tests/Routing/ImplicitRouteBindingTest.php index 675196a11364..18bb7a2ff2c1 100644 --- a/tests/Routing/ImplicitRouteBindingTest.php +++ b/tests/Routing/ImplicitRouteBindingTest.php @@ -9,7 +9,7 @@ use Illuminate\Routing\Route; use PHPUnit\Framework\TestCase; -include 'Enums.php'; +include_once 'Enums.php'; class ImplicitRouteBindingTest extends TestCase { From 8c7a26ad5f00b1e55783340ffefb10ddfb3563b7 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 17 Mar 2023 09:14:54 -0500 Subject: [PATCH 3/3] fix test --- tests/Routing/RoutingRouteTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Routing/RoutingRouteTest.php b/tests/Routing/RoutingRouteTest.php index e9d58b075e2b..ff25733fb7b6 100644 --- a/tests/Routing/RoutingRouteTest.php +++ b/tests/Routing/RoutingRouteTest.php @@ -1895,7 +1895,7 @@ public function testImplicitBindingsWithOptionalParameterWithNoKeyInUri() public function testImplicitBindingsWithOptionalParameterUsingEnumIsAlwaysCastedToEnum() { - include_once 'enums.php'; + include_once 'Enums.php'; $router = $this->getRouter(); $router->get('foo/{bar?}', [