From ae6016c6fc9f78ffd78f16c68988a67eed9b36ba Mon Sep 17 00:00:00 2001 From: Alex Bogomazov Date: Fri, 20 Jul 2012 13:02:47 +0300 Subject: [PATCH] [Finder] Workaround for FilterIterator-FilesystemIterator-rewind issue --- .../Finder/Iterator/CustomFilterIterator.php | 2 +- .../Iterator/DateRangeFilterIterator.php | 2 +- .../Iterator/DepthRangeFilterIterator.php | 2 +- .../ExcludeDirectoryFilterIterator.php | 2 +- .../Iterator/FileTypeFilterIterator.php | 2 +- .../Finder/Iterator/FilterIterator.php | 39 ++++++++++++++++ .../Iterator/MultiplePcreFilterIterator.php | 2 +- .../Iterator/SizeRangeFilterIterator.php | 2 +- .../Component/Finder/Tests/FinderTest.php | 19 ++++++++ .../Tests/Iterator/FilterIteratorTest.php | 46 +++++++++++++++++++ 10 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 src/Symfony/Component/Finder/Iterator/FilterIterator.php create mode 100644 src/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php diff --git a/src/Symfony/Component/Finder/Iterator/CustomFilterIterator.php b/src/Symfony/Component/Finder/Iterator/CustomFilterIterator.php index dd870e2bd4..8ff5739693 100644 --- a/src/Symfony/Component/Finder/Iterator/CustomFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/CustomFilterIterator.php @@ -19,7 +19,7 @@ namespace Symfony\Component\Finder\Iterator; * * @author Fabien Potencier */ -class CustomFilterIterator extends \FilterIterator +class CustomFilterIterator extends FilterIterator { private $filters = array(); diff --git a/src/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php index 8ed17b414b..1664793331 100644 --- a/src/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator; * * @author Fabien Potencier */ -class DateRangeFilterIterator extends \FilterIterator +class DateRangeFilterIterator extends FilterIterator { private $comparators = array(); diff --git a/src/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php index 7d58c38457..832125393f 100644 --- a/src/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator; * * @author Fabien Potencier */ -class DepthRangeFilterIterator extends \FilterIterator +class DepthRangeFilterIterator extends FilterIterator { private $minDepth = 0; diff --git a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php index 40759c04f5..42c8ce760d 100644 --- a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator; * * @author Fabien Potencier */ -class ExcludeDirectoryFilterIterator extends \FilterIterator +class ExcludeDirectoryFilterIterator extends FilterIterator { private $patterns; diff --git a/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php index da62ecf4a9..5b7bbb10b9 100644 --- a/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator; * * @author Fabien Potencier */ -class FileTypeFilterIterator extends \FilterIterator +class FileTypeFilterIterator extends FilterIterator { const ONLY_FILES = 1; const ONLY_DIRECTORIES = 2; diff --git a/src/Symfony/Component/Finder/Iterator/FilterIterator.php b/src/Symfony/Component/Finder/Iterator/FilterIterator.php new file mode 100644 index 0000000000..7e51f5fd33 --- /dev/null +++ b/src/Symfony/Component/Finder/Iterator/FilterIterator.php @@ -0,0 +1,39 @@ +getInnerIterator() instanceof \FilesystemIterator) { + $iterator->getInnerIterator()->next(); + $iterator->getInnerIterator()->rewind(); + } + $iterator = $iterator->getInnerIterator(); + } + + parent::rewind(); + } +} diff --git a/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php b/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php index 42199abebd..12584b186e 100644 --- a/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator; * * @author Fabien Potencier */ -abstract class MultiplePcreFilterIterator extends \FilterIterator +abstract class MultiplePcreFilterIterator extends FilterIterator { protected $matchRegexps; protected $noMatchRegexps; diff --git a/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php index b9b80441be..89a4fc434c 100644 --- a/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator; * * @author Fabien Potencier */ -class SizeRangeFilterIterator extends \FilterIterator +class SizeRangeFilterIterator extends FilterIterator { private $comparators = array(); diff --git a/src/Symfony/Component/Finder/Tests/FinderTest.php b/src/Symfony/Component/Finder/Tests/FinderTest.php index 05ed82fd46..f4f84c3583 100644 --- a/src/Symfony/Component/Finder/Tests/FinderTest.php +++ b/src/Symfony/Component/Finder/Tests/FinderTest.php @@ -440,4 +440,23 @@ class FinderTest extends Iterator\RealIteratorTestCase $this->assertIterator(array(), $finder); } + /** + * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator + * with inner FilesystemIterator in an ivalid state. + */ + public function testMultipleLocations() + { + $tmpDir = sys_get_temp_dir() . '/symfony2_finder'; + + $locations = array( + $tmpDir . '/', + $tmpDir . '/toto/', + ); + + // it is expected that there are test.py test.php in the tmpDir + $finder = new Finder(); + $finder->in($locations)->depth('< 1')->name('test.php'); + + $this->assertEquals(1, count($finder)); + } } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php new file mode 100644 index 0000000000..b458586233 --- /dev/null +++ b/src/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php @@ -0,0 +1,46 @@ +getMockForAbstractClass('Symfony\Component\Finder\Iterator\FilterIterator', array($i)); + $i->expects($this->any())->method('accept')->will($this->returnCallback(function () use ($i) { + return (bool)preg_match('/\.php/', (string)$i->current()); + })); + + $c = 0; + foreach ($i as $item) { + $c++; + } + // This works + $this->assertEquals(1, $c); + + + $i->rewind(); + + $c = 0; + foreach ($i as $item) { + $c++; + } + // This would fail with \FilterIterator but works with Symfony\Component\Finder\Iterator\FilterIterator + $this->assertEquals(1, $c); + } +}