From cc6f82769bd886ed2a0ddf745b1f1354cd62ecd0 Mon Sep 17 00:00:00 2001 From: nicoweb Date: Sat, 8 Sep 2018 14:42:42 +0200 Subject: [PATCH 1/2] [Controller][ServiceValueResolver] Making method access case insensitive --- .../ArgumentResolver/ServiceValueResolver.php | 9 +++++++++ .../ServiceValueResolverTest.php | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php index 7bc195f233..3294ec862e 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php @@ -47,6 +47,10 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface $controller = ltrim($controller, '\\'); } + if (!$this->container->has($controller) && false !== $i = strrpos($controller, ':')) { + $controller = substr($controller, 0, $i).strtolower(substr($controller, $i)); + } + return $this->container->has($controller) && $this->container->get($controller)->has($argument->getName()); } @@ -63,6 +67,11 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface $controller = ltrim($controller, '\\'); } + if (!$this->container->has($controller)) { + $i = strrpos($controller, ':'); + $controller = substr($controller, 0, $i).strtolower(substr($controller, $i)); + } + yield $this->container->get($controller)->get($argument->getName()); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php index 7d34172ce3..f6a3689638 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php @@ -66,6 +66,24 @@ class ServiceValueResolverTest extends TestCase $this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument)); } + public function testExistingControllerWithMethodNameStartUppercase() + { + $resolver = new ServiceValueResolver(new ServiceLocator(array( + 'App\\Controller\\Mine::method' => function () { + return new ServiceLocator(array( + 'dummy' => function () { + return new DummyService(); + }, + )); + }, + ))); + $request = $this->requestWithAttributes(array('_controller' => 'App\\Controller\\Mine::Method')); + $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null); + + $this->assertTrue($resolver->supports($request, $argument)); + $this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument)); + } + public function testControllerNameIsAnArray() { $resolver = new ServiceValueResolver(new ServiceLocator(array( From d638237f098af218c150abd070e30ab9075f7724 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 9 Sep 2018 11:07:24 +0200 Subject: [PATCH 2/2] [Debug] fix detecting overriden final/internal methods implemented using traits --- .../Component/Debug/DebugClassLoader.php | 20 +++++++++---------- .../Debug/Tests/DebugClassLoaderTest.php | 15 ++++++-------- .../Tests/Fixtures/ExtendedFinalMethod.php | 2 ++ .../Debug/Tests/Fixtures/FinalMethod.php | 7 +++++++ .../Tests/Fixtures/FinalMethod2Trait.php | 10 ++++++++++ .../Debug/Tests/phpt/debug_class_loader.phpt | 1 + 6 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index dff57e69bd..32cbd31607 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -247,25 +247,23 @@ class DebugClassLoader continue; } - // Method from a trait - if ($method->getFilename() !== $refl->getFileName()) { - continue; - } - if ($isClass && $parent && isset(self::$finalMethods[$parent][$method->name])) { list($declaringClass, $message) = self::$finalMethods[$parent][$method->name]; @trigger_error(sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED); } - foreach ($parentAndTraits as $use) { - if (isset(self::$internalMethods[$use][$method->name])) { - list($declaringClass, $message) = self::$internalMethods[$use][$method->name]; - if (\strncmp($ns, $declaringClass, $len)) { - @trigger_error(sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED); - } + if (isset(self::$internalMethods[$name][$method->name])) { + list($declaringClass, $message) = self::$internalMethods[$name][$method->name]; + if (\strncmp($ns, $declaringClass, $len)) { + @trigger_error(sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED); } } + // Method from a trait + if ($method->getFilename() !== $refl->getFileName()) { + continue; + } + // Detect method annotations if (false === $doc = $method->getDocComment()) { continue; diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index 0219f53350..cd89c06e58 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -312,24 +312,21 @@ class DebugClassLoaderTest extends TestCase public function testExtendedFinalMethod() { - set_error_handler(function () { return false; }); - $e = error_reporting(0); - trigger_error('', E_USER_NOTICE); + $deprecations = array(); + set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; }); + $e = error_reporting(E_USER_DEPRECATED); class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true); error_reporting($e); restore_error_handler(); - $lastError = error_get_last(); - unset($lastError['file'], $lastError['line']); - $xError = array( - 'type' => E_USER_DEPRECATED, - 'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".', + 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".', + 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".', ); - $this->assertSame($xError, $lastError); + $this->assertSame($xError, $deprecations); } public function testExtendedDeprecatedMethodDoesntTriggerAnyNotice() diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php b/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php index 2bd337e5a2..050d19ff5e 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php @@ -4,6 +4,8 @@ namespace Symfony\Component\Debug\Tests\Fixtures; class ExtendedFinalMethod extends FinalMethod { + use FinalMethod2Trait; + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php index 92ec421863..98a47524c4 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php @@ -11,6 +11,13 @@ class FinalMethod { } + /** + * @final + */ + public function finalMethod2() + { + } + public function anotherMethod() { } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php new file mode 100644 index 0000000000..8547f3afed --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php @@ -0,0 +1,10 @@ + --EXPECTF-- The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod". +The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".