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()
|
public function accept()
|
||||||
{
|
{
|
||||||
$path = $this->isDir() ? $this->getSubPathname() : $this->getSubPath();
|
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
|
||||||
$path = strtr($path, '\\', '/');
|
$path = strtr($path, '\\', '/');
|
||||||
foreach ($this->patterns as $pattern) {
|
foreach ($this->patterns as $pattern) {
|
||||||
if (preg_match($pattern, $path)) {
|
if (preg_match($pattern, $path)) {
|
||||||
|
@ -43,9 +43,10 @@ class FileTypeFilterIterator extends \FilterIterator
|
|||||||
*/
|
*/
|
||||||
public function accept()
|
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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,13 +30,15 @@ class FilecontentFilterIterator extends MultiplePcreFilterIterator
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isDir() || !$this->isReadable()) {
|
$fileinfo = $this->current();
|
||||||
|
|
||||||
|
if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = @file_get_contents($filename = $this->getRealpath());
|
$content = $fileinfo->getContents();
|
||||||
if (false === $content) {
|
if (!$content) {
|
||||||
throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath()));
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// should at least not match one rule to exclude
|
// should at least not match one rule to exclude
|
||||||
|
@ -28,7 +28,7 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator
|
|||||||
*/
|
*/
|
||||||
public function accept()
|
public function accept()
|
||||||
{
|
{
|
||||||
$filename = $this->getFilename();
|
$filename = $this->current()->getFilename();
|
||||||
|
|
||||||
// should at least not match one rule to exclude
|
// should at least not match one rule to exclude
|
||||||
foreach ($this->noMatchRegexps as $regex) {
|
foreach ($this->noMatchRegexps as $regex) {
|
||||||
|
@ -40,11 +40,12 @@ class SizeRangeFilterIterator extends \FilterIterator
|
|||||||
*/
|
*/
|
||||||
public function accept()
|
public function accept()
|
||||||
{
|
{
|
||||||
if (!$this->isFile()) {
|
$fileinfo = $this->current();
|
||||||
|
if (!$fileinfo->isFile()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filesize = $this->getSize();
|
$filesize = $fileinfo->getSize();
|
||||||
foreach ($this->comparators as $compare) {
|
foreach ($this->comparators as $compare) {
|
||||||
if (!$compare->test($filesize)) {
|
if (!$compare->test($filesize)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -54,4 +54,22 @@ class SplFileInfo extends \SplFileInfo
|
|||||||
{
|
{
|
||||||
return $this->relativePathname;
|
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;
|
namespace Symfony\Component\Finder\Tests\Iterator;
|
||||||
|
|
||||||
use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
|
use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
|
||||||
|
use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
|
||||||
|
|
||||||
class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
|
class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
|
||||||
{
|
{
|
||||||
@ -20,7 +21,7 @@ class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
|
|||||||
*/
|
*/
|
||||||
public function testAccept($directories, $expected)
|
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);
|
$iterator = new ExcludeDirectoryFilterIterator($inner, $directories);
|
||||||
|
|
||||||
|
@ -18,73 +18,176 @@ class FilecontentFilterIteratorTest extends IteratorTestCase
|
|||||||
|
|
||||||
public function testAccept()
|
public function testAccept()
|
||||||
{
|
{
|
||||||
$inner = new ContentInnerNameIterator(array('test.txt'));
|
$inner = new MockFileListIterator(array('test.txt'));
|
||||||
$iterator = new FilecontentFilterIterator($inner, array(), array());
|
$iterator = new FilecontentFilterIterator($inner, array(), array());
|
||||||
$this->assertIterator(array('test.txt'), $iterator);
|
$this->assertIterator(array('test.txt'), $iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDirectory()
|
public function testDirectory()
|
||||||
{
|
{
|
||||||
$inner = new ContentInnerNameIterator(array('directory'));
|
$inner = new MockFileListIterator(array('directory'));
|
||||||
$iterator = new FilecontentFilterIterator($inner, array('directory'), array());
|
$iterator = new FilecontentFilterIterator($inner, array('directory'), array());
|
||||||
$this->assertIterator(array(), $iterator);
|
$this->assertIterator(array(), $iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUnreadableFile()
|
public function testUnreadableFile()
|
||||||
{
|
{
|
||||||
$inner = new ContentInnerNameIterator(array('file r-'));
|
$inner = new MockFileListIterator(array('file r-'));
|
||||||
$iterator = new FilecontentFilterIterator($inner, array('file r-'), array());
|
$iterator = new FilecontentFilterIterator($inner, array('file r-'), array());
|
||||||
$this->assertIterator(array(), $iterator);
|
$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, $matchPatterns, $noMatchPatterns);
|
||||||
$iterator = new FilecontentFilterIterator($inner, array('file r+'), array());
|
$this->assertIterator($resultArray, $iterator);
|
||||||
$array = iterator_to_array($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()
|
const TYPE_DIRECTORY = 1;
|
||||||
{
|
const TYPE_FILE = 2;
|
||||||
return new \SplFileInfo(parent::current());
|
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()
|
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()
|
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 self::TYPE_DIRECTORY === $this->type;
|
||||||
{
|
|
||||||
return parent::current();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isReadable()
|
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