bug #21832 [Routing] Ignore hidden directories when loading routes from annotations (jakzal)

This PR was merged into the 2.7 branch.

Discussion
----------

[Routing] Ignore hidden directories when loading routes from annotations

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #21497
| License       | MIT
| Doc PR        | -

The problem surfaced after implementing #18869. Therefore it doesn't exist on 2.7, but I'd still merge it there to avoid conflicts when merging between branches. Without this fix, the oldest branch the added test will fail is 3.2.

Commits
-------

ce9df0237c [Routing] Ignore hidden directories when loading routes from annotations
This commit is contained in:
Fabien Potencier 2017-03-02 07:54:09 -08:00
commit c579b96cef
2 changed files with 65 additions and 1 deletions

View File

@ -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);
}
}

View File

@ -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);
}));
}
}