diff --git a/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php b/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php index 508d11bf3c..5e54d6fedd 100644 --- a/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php +++ b/src/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php @@ -38,4 +38,12 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator { return new SplFileInfo(parent::current()->getPathname(), $this->getSubPath(), $this->getSubPathname()); } + + public function rewind() + { + // @see https://bugs.php.net/bug.php?id=49104 + parent::next(); + + parent::rewind(); + } } diff --git a/src/Symfony/Component/Finder/Tests/FinderTest.php b/src/Symfony/Component/Finder/Tests/FinderTest.php index ec7db1ec06..4f419698e9 100644 --- a/src/Symfony/Component/Finder/Tests/FinderTest.php +++ b/src/Symfony/Component/Finder/Tests/FinderTest.php @@ -459,4 +459,30 @@ class FinderTest extends Iterator\RealIteratorTestCase $this->assertEquals(1, count($finder)); } + + /** + * Searching in multiple locations with sub directories involves + * AppendIterator which does an unnecessary rewind which leaves + * FilterIterator with inner FilesystemIterator in an ivalid state. + * + * @see https://bugs.php.net/bug.php?id=49104 + */ + public function testMultipleLocationsWithSubDirectories() + { + $locations = array( + __DIR__.'/Fixtures/one', + self::$files[8], + ); + + $finder = new Finder(); + $finder->in($locations)->depth('< 10')->name('*.neon'); + + $expected = array( + __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon', + __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon', + ); + + $this->assertIterator($expected, $finder); + $this->assertIteratorInForeach($expected, $finder); + } } diff --git a/src/Symfony/Component/Finder/Tests/Fixtures/one/a b/src/Symfony/Component/Finder/Tests/Fixtures/one/a new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon b/src/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon b/src/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php b/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php index 8810ce757d..845fc2c513 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php @@ -29,4 +29,41 @@ abstract class IteratorTestCase extends \PHPUnit_Framework_TestCase $this->assertEquals($expected, array_values($values)); } + + /** + * Same as IteratorTestCase::assertIterator with foreach usage + * + * @param array $expected + * @param \Traversable $iterator + */ + protected function assertIteratorInForeach($expected, \Traversable $iterator) + { + $values = array(); + foreach ($iterator as $file) { + $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file); + $values[] = $file->getPathname(); + } + + sort($values); + sort($expected); + + $this->assertEquals($expected, array_values($values)); + } + + /** + * Same as IteratorTestCase::assertOrderedIterator with foreach usage + * + * @param array $expected + * @param \Traversable $iterator + */ + protected function assertOrderedIteratorInForeach($expected, \Traversable $iterator) + { + $values = array(); + foreach ($iterator as $file) { + $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file); + $values[] = $file->getPathname(); + } + + $this->assertEquals($expected, array_values($values)); + } }