merged branch gajdaw/finder_current_fix (PR #4335)
Commits -------3eb67fc
[2.1][Component][Finder] $this->current() fix Discussion ---------- [2.1][Component][Finder] $this->current() fix Bug fix: yes Feature addition: no Backwards compatibility break: no Symfony2 tests pass: [![Build Status](https://secure.travis-ci.org/gajdaw/symfony.png?branch=master)](http://travis-ci.org/gajdaw/symfony) Fixes the following tickets: - Todo: - License of the code: MIT One method to resolve `->in("ftp://...")` problem is to create `RecursiveDirectoryFtpIterator`. (Details: [issue 3585](https://github.com/symfony/symfony/issues/3585)) I think that all filters should access the information about current item calling `current()` or `getInnerIterator()`. Otherwise it will not work if we replace `RecursiveDirectoryIterator` with ftp iterator inside `Finder`. I'm not sure if that should go to 2.0 or 2.1 branch. --------------------------------------------------------------------------- by travisbot at 2012-05-19T09:20:19Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1373361) (merged 9f247921 into58b92453
). --------------------------------------------------------------------------- by gajdaw at 2012-05-19T10:51:10Z Probably it should go to master branch, because it improves commit done to master:f2fea97460
--------------------------------------------------------------------------- by travisbot at 2012-05-19T11:26:14Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1373982) (merged f9d1db8c into58b92453
). --------------------------------------------------------------------------- by travisbot at 2012-05-19T11:51:25Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1374031) (merged f1b4b4f7 into58b92453
). --------------------------------------------------------------------------- by travisbot at 2012-05-19T12:48:17Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1374303) (merged b6d073da into58b92453
). --------------------------------------------------------------------------- by travisbot at 2012-05-19T13:28:18Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1374568) (merged fd144c96 into58b92453
). --------------------------------------------------------------------------- by travisbot at 2012-05-19T13:35:38Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1374609) (merged 89a8d851 into58b92453
). --------------------------------------------------------------------------- by travisbot at 2012-05-21T04:31:46Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1385764) (merged 0d5b8322 into58b92453
). --------------------------------------------------------------------------- by travisbot at 2012-05-21T07:21:56Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1386545) (merged3eb67fca
into1407f112
). --------------------------------------------------------------------------- by stof at 2012-06-09T13:24:14Z seems good
This commit is contained in:
commit
092b5dde62
@ -43,7 +43,7 @@ class ExcludeDirectoryFilterIterator extends \FilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
$path = $this->isDir() ? $this->getSubPathname() : $this->getSubPath();
|
||||
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
|
||||
$path = strtr($path, '\\', '/');
|
||||
foreach ($this->patterns as $pattern) {
|
||||
if (preg_match($pattern, $path)) {
|
||||
|
@ -43,9 +43,10 @@ class FileTypeFilterIterator extends \FilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $this->isFile()) {
|
||||
$fileinfo = $this->current();
|
||||
if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
|
||||
return false;
|
||||
} elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $this->isDir()) {
|
||||
} elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,15 @@ class FilecontentFilterIterator extends MultiplePcreFilterIterator
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->isDir() || !$this->isReadable()) {
|
||||
$fileinfo = $this->current();
|
||||
|
||||
if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$content = @file_get_contents($filename = $this->getRealpath());
|
||||
if (false === $content) {
|
||||
throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath()));
|
||||
$content = $fileinfo->getContents();
|
||||
if (!$content) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// should at least not match one rule to exclude
|
||||
|
@ -28,7 +28,7 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
$filename = $this->getFilename();
|
||||
$filename = $this->current()->getFilename();
|
||||
|
||||
// should at least not match one rule to exclude
|
||||
foreach ($this->noMatchRegexps as $regex) {
|
||||
|
@ -40,11 +40,12 @@ class SizeRangeFilterIterator extends \FilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
if (!$this->isFile()) {
|
||||
$fileinfo = $this->current();
|
||||
if (!$fileinfo->isFile()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$filesize = $this->getSize();
|
||||
$filesize = $fileinfo->getSize();
|
||||
foreach ($this->comparators as $compare) {
|
||||
if (!$compare->test($filesize)) {
|
||||
return false;
|
||||
|
@ -54,4 +54,22 @@ class SplFileInfo extends \SplFileInfo
|
||||
{
|
||||
return $this->relativePathname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the file
|
||||
*
|
||||
* @return string the contents of the file
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
$level = error_reporting(0);
|
||||
$content = file_get_contents($this->getRealpath());
|
||||
error_reporting($level);
|
||||
if (false === $content) {
|
||||
$error = error_get_last();
|
||||
throw new \RuntimeException($error['message']);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Finder\Tests\Iterator;
|
||||
|
||||
use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
|
||||
use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
|
||||
|
||||
class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
|
||||
{
|
||||
@ -20,7 +21,7 @@ class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
|
||||
*/
|
||||
public function testAccept($directories, $expected)
|
||||
{
|
||||
$inner = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(sys_get_temp_dir().'/symfony2_finder', \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
|
||||
$inner = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator(sys_get_temp_dir().'/symfony2_finder', \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
$iterator = new ExcludeDirectoryFilterIterator($inner, $directories);
|
||||
|
||||
|
@ -18,73 +18,176 @@ class FilecontentFilterIteratorTest extends IteratorTestCase
|
||||
|
||||
public function testAccept()
|
||||
{
|
||||
$inner = new ContentInnerNameIterator(array('test.txt'));
|
||||
$inner = new MockFileListIterator(array('test.txt'));
|
||||
$iterator = new FilecontentFilterIterator($inner, array(), array());
|
||||
$this->assertIterator(array('test.txt'), $iterator);
|
||||
}
|
||||
|
||||
public function testDirectory()
|
||||
{
|
||||
$inner = new ContentInnerNameIterator(array('directory'));
|
||||
$inner = new MockFileListIterator(array('directory'));
|
||||
$iterator = new FilecontentFilterIterator($inner, array('directory'), array());
|
||||
$this->assertIterator(array(), $iterator);
|
||||
}
|
||||
|
||||
public function testUnreadableFile()
|
||||
{
|
||||
$inner = new ContentInnerNameIterator(array('file r-'));
|
||||
$inner = new MockFileListIterator(array('file r-'));
|
||||
$iterator = new FilecontentFilterIterator($inner, array('file r-'), array());
|
||||
$this->assertIterator(array(), $iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
* @dataProvider getTestFilterData
|
||||
*/
|
||||
public function testFileGetContents()
|
||||
public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
|
||||
{
|
||||
$inner = new ContentInnerNameIterator(array('file r+'));
|
||||
$iterator = new FilecontentFilterIterator($inner, array('file r+'), array());
|
||||
$array = iterator_to_array($iterator);
|
||||
$iterator = new FilecontentFilterIterator($inner, $matchPatterns, $noMatchPatterns);
|
||||
$this->assertIterator($resultArray, $iterator);
|
||||
}
|
||||
|
||||
public function getTestFilterData()
|
||||
{
|
||||
$inner = new MockFileListIterator();
|
||||
|
||||
$inner[] = new MockSplFileInfo(array(
|
||||
'name' => 'a.txt',
|
||||
'contents' => 'Lorem ipsum...',
|
||||
'type' => 'file',
|
||||
'mode' => 'r+')
|
||||
);
|
||||
|
||||
$inner[] = new MockSplFileInfo(array(
|
||||
'name' => 'b.yml',
|
||||
'contents' => 'dolor sit...',
|
||||
'type' => 'file',
|
||||
'mode' => 'r+')
|
||||
);
|
||||
|
||||
$inner[] = new MockSplFileInfo(array(
|
||||
'name' => 'some/other/dir/third.php',
|
||||
'contents' => 'amet...',
|
||||
'type' => 'file',
|
||||
'mode' => 'r+')
|
||||
);
|
||||
|
||||
$inner[] = new MockSplFileInfo(array(
|
||||
'name' => 'unreadable-file.txt',
|
||||
'contents' => false,
|
||||
'type' => 'file',
|
||||
'mode' => 'r+')
|
||||
);
|
||||
|
||||
return array(
|
||||
array($inner, array('.'), array(), array('a.txt', 'b.yml', 'some/other/dir/third.php')),
|
||||
array($inner, array('ipsum'), array(), array('a.txt')),
|
||||
array($inner, array('i', 'amet'), array('Lorem', 'amet'), array('b.yml')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ContentInnerNameIterator extends \ArrayIterator
|
||||
class MockSplFileInfo extends \SplFileInfo
|
||||
{
|
||||
public function current()
|
||||
{
|
||||
return new \SplFileInfo(parent::current());
|
||||
}
|
||||
const TYPE_DIRECTORY = 1;
|
||||
const TYPE_FILE = 2;
|
||||
const TYPE_UNKNOWN = 3;
|
||||
|
||||
public function getFilename()
|
||||
private $contents = null;
|
||||
private $mode = null;
|
||||
private $type = null;
|
||||
|
||||
public function __construct($param)
|
||||
{
|
||||
return parent::current();
|
||||
if (is_string($param)) {
|
||||
parent::__construct($param);
|
||||
} elseif (is_array($param)) {
|
||||
|
||||
$defaults = array(
|
||||
'name' => 'file.txt',
|
||||
'contents' => null,
|
||||
'mode' => null,
|
||||
'type' => null
|
||||
);
|
||||
$defaults = array_merge($defaults, $param);
|
||||
parent::__construct($defaults['name']);
|
||||
$this->setContents($defaults['contents']);
|
||||
$this->setMode($defaults['mode']);
|
||||
$this->setType($defaults['type']);
|
||||
} else {
|
||||
throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param));
|
||||
}
|
||||
}
|
||||
|
||||
public function isFile()
|
||||
{
|
||||
$name = parent::current();
|
||||
if ($this->type === null) {
|
||||
return preg_match('/file/', $this->getFilename());
|
||||
};
|
||||
|
||||
return preg_match('/file/', $name);
|
||||
return self::TYPE_FILE === $this->type;
|
||||
}
|
||||
|
||||
public function isDir()
|
||||
{
|
||||
$name = parent::current();
|
||||
if ($this->type === null) {
|
||||
return preg_match('/directory/', $this->getFilename());
|
||||
}
|
||||
|
||||
return preg_match('/directory/', $name);
|
||||
}
|
||||
|
||||
public function getRealpath()
|
||||
{
|
||||
return parent::current();
|
||||
return self::TYPE_DIRECTORY === $this->type;
|
||||
}
|
||||
|
||||
public function isReadable()
|
||||
{
|
||||
$name = parent::current();
|
||||
if ($this->mode === null) {
|
||||
return preg_match('/r\+/', $this->getFilename());
|
||||
}
|
||||
|
||||
return preg_match('/r\+/', $name);
|
||||
return preg_match('/r\+/', $this->mode);
|
||||
}
|
||||
|
||||
public function getContents()
|
||||
{
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
public function setContents($contents)
|
||||
{
|
||||
$this->contents = $contents;
|
||||
}
|
||||
|
||||
public function setMode($mode)
|
||||
{
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
public function setType($type)
|
||||
{
|
||||
if (is_string($type)) {
|
||||
switch ($type) {
|
||||
case 'directory':
|
||||
$this->type = self::TYPE_DIRECTORY;
|
||||
case 'd':
|
||||
$this->type = self::TYPE_DIRECTORY;
|
||||
break;
|
||||
case 'file':
|
||||
$this->type = self::TYPE_FILE;
|
||||
case 'f':
|
||||
$this->type = self::TYPE_FILE;
|
||||
break;
|
||||
default:
|
||||
$this->type = self::TYPE_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MockFileListIterator extends \ArrayIterator
|
||||
{
|
||||
public function __construct(array $filesArray = array())
|
||||
{
|
||||
$files = array_map(function($file){ return new MockSplFileInfo($file); }, $filesArray);
|
||||
parent::__construct($files);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user