merged branch alebo/ticket_4922 (PR #4993)
Commits
-------
ae6016c
[Finder] Workaround for FilterIterator-FilesystemIterator-rewind issue
Discussion
----------
[Finder] Workaround for the problem with rewind of FilterIterator with inner FilesystemIterator.
Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #4922
Todo: -
License of the code: MIT
Documentation PR: -
---------------------------------------------------------------------------
by stof at 2012-07-20T10:28:05Z
Please add some tests
---------------------------------------------------------------------------
by alebo at 2012-07-24T09:50:36Z
Any feedback yet? The new commit includes tests.
This commit is contained in:
commit
7b1d6b806e
@ -19,7 +19,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CustomFilterIterator extends \FilterIterator
|
||||
class CustomFilterIterator extends FilterIterator
|
||||
{
|
||||
private $filters = array();
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class DateRangeFilterIterator extends \FilterIterator
|
||||
class DateRangeFilterIterator extends FilterIterator
|
||||
{
|
||||
private $comparators = array();
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class DepthRangeFilterIterator extends \FilterIterator
|
||||
class DepthRangeFilterIterator extends FilterIterator
|
||||
{
|
||||
private $minDepth = 0;
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ExcludeDirectoryFilterIterator extends \FilterIterator
|
||||
class ExcludeDirectoryFilterIterator extends FilterIterator
|
||||
{
|
||||
private $patterns;
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class FileTypeFilterIterator extends \FilterIterator
|
||||
class FileTypeFilterIterator extends FilterIterator
|
||||
{
|
||||
const ONLY_FILES = 1;
|
||||
const ONLY_DIRECTORIES = 2;
|
||||
|
39
src/Symfony/Component/Finder/Iterator/FilterIterator.php
Normal file
39
src/Symfony/Component/Finder/Iterator/FilterIterator.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Alex Bogomazov
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Finder\Iterator;
|
||||
|
||||
/**
|
||||
* This iterator just overrides the rewind method in order to correct a PHP bug.
|
||||
*
|
||||
* @author Alex Bogomazov
|
||||
*/
|
||||
abstract class FilterIterator extends \FilterIterator
|
||||
{
|
||||
/**
|
||||
* This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after
|
||||
* rewind in some cases.
|
||||
* @see FilterIterator::rewind()
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$iterator = $this;
|
||||
while ($iterator instanceof \OuterIterator) {
|
||||
if ($iterator->getInnerIterator() instanceof \FilesystemIterator) {
|
||||
$iterator->getInnerIterator()->next();
|
||||
$iterator->getInnerIterator()->rewind();
|
||||
}
|
||||
$iterator = $iterator->getInnerIterator();
|
||||
}
|
||||
|
||||
parent::rewind();
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class MultiplePcreFilterIterator extends \FilterIterator
|
||||
abstract class MultiplePcreFilterIterator extends FilterIterator
|
||||
{
|
||||
protected $matchRegexps;
|
||||
protected $noMatchRegexps;
|
||||
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class SizeRangeFilterIterator extends \FilterIterator
|
||||
class SizeRangeFilterIterator extends FilterIterator
|
||||
{
|
||||
private $comparators = array();
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Alex Bogomazov
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Finder\Tests\Iterator;
|
||||
|
||||
class FilterIteratorTest extends RealIteratorTestCase
|
||||
{
|
||||
public function testFilterFilesystemIterators()
|
||||
{
|
||||
$tmpDir = sys_get_temp_dir().'/symfony2_finder';
|
||||
|
||||
|
||||
$i = new \FilesystemIterator($tmpDir);
|
||||
|
||||
// it is expected that there are test.py test.php in the tmpDir
|
||||
$i = $this->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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user