From ce9df0237c57f45316f417869d85697128f8b4ae Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Thu, 2 Mar 2017 09:03:45 +0000 Subject: [PATCH] [Routing] Ignore hidden directories when loading routes from annotations --- .../Loader/AnnotationDirectoryLoader.php | 41 ++++++++++++++++++- .../Loader/AnnotationDirectoryLoaderTest.php | 25 +++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php index f66b928971..7b8467a81c 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php @@ -38,7 +38,15 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader $collection = new RouteCollection(); $collection->addResource(new DirectoryResource($dir, '/\.php$/')); - $files = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY)); + $files = iterator_to_array(new \RecursiveIteratorIterator( + new RecursiveCallbackFilterIterator( + new \RecursiveDirectoryIterator($dir), + function (\SplFileInfo $current) { + return '.' !== substr($current->getBasename(), 0, 1); + } + ), + \RecursiveIteratorIterator::LEAVES_ONLY + )); usort($files, function (\SplFileInfo $a, \SplFileInfo $b) { return (string) $a > (string) $b ? 1 : -1; }); @@ -79,3 +87,34 @@ class AnnotationDirectoryLoader extends AnnotationFileLoader return is_dir($path) && (!$type || 'annotation' === $type); } } + +/** + * @internal To be removed as RecursiveCallbackFilterIterator is available since PHP 5.4 + */ +class RecursiveCallbackFilterIterator extends \FilterIterator implements \RecursiveIterator +{ + private $iterator; + private $callback; + + public function __construct(\RecursiveIterator $iterator, $callback) + { + $this->iterator = $iterator; + $this->callback = $callback; + parent::__construct($iterator); + } + + public function accept() + { + return call_user_func($this->callback, $this->current(), $this->key(), $this->iterator); + } + + public function hasChildren() + { + return $this->iterator->hasChildren(); + } + + public function getChildren() + { + return new static($this->iterator->getChildren(), $this->callback); + } +} diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php index 29126ba4f2..8d832f0c1c 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationDirectoryLoaderTest.php @@ -40,6 +40,22 @@ class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses'); } + public function testLoadIgnoresHiddenDirectories() + { + $this->expectAnnotationsToBeReadFrom(array( + 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', + 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass', + )); + + $this->reader + ->expects($this->any()) + ->method('getMethodAnnotations') + ->will($this->returnValue(array())) + ; + + $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses'); + } + public function testSupports() { $fixturesDir = __DIR__.'/../Fixtures'; @@ -50,4 +66,13 @@ class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest $this->assertTrue($this->loader->supports($fixturesDir, 'annotation'), '->supports() checks the resource type if specified'); $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports() checks the resource type if specified'); } + + private function expectAnnotationsToBeReadFrom(array $classes) + { + $this->reader->expects($this->exactly(count($classes))) + ->method('getClassAnnotation') + ->with($this->callback(function (\ReflectionClass $class) use ($classes) { + return in_array($class->getName(), $classes); + })); + } }