Skip to content

Commit

Permalink
merged branch gajdaw/finder_current_fix (PR #4335)
Browse files Browse the repository at this point in the history
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](symfony/symfony#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 into 58b92453).

---------------------------------------------------------------------------

by gajdaw at 2012-05-19T10:51:10Z

Probably it should go to master branch, because it improves commit done to master:

symfony/symfony@f2fea97

---------------------------------------------------------------------------

by travisbot at 2012-05-19T11:26:14Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1373982) (merged f9d1db8c into 58b92453).

---------------------------------------------------------------------------

by travisbot at 2012-05-19T11:51:25Z

This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1374031) (merged f1b4b4f7 into 58b92453).

---------------------------------------------------------------------------

by travisbot at 2012-05-19T12:48:17Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1374303) (merged b6d073da into 58b92453).

---------------------------------------------------------------------------

by travisbot at 2012-05-19T13:28:18Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1374568) (merged fd144c96 into 58b92453).

---------------------------------------------------------------------------

by travisbot at 2012-05-19T13:35:38Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1374609) (merged 89a8d851 into 58b92453).

---------------------------------------------------------------------------

by travisbot at 2012-05-21T04:31:46Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1385764) (merged 0d5b8322 into 58b92453).

---------------------------------------------------------------------------

by travisbot at 2012-05-21T07:21:56Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1386545) (merged 3eb67fca into 1407f112).

---------------------------------------------------------------------------

by stof at 2012-06-09T13:24:14Z

seems good
  • Loading branch information
fabpot committed Jun 19, 2012
2 parents 9ee9a90 + 25382fa commit 05c884e
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Iterator/ExcludeDirectoryFilterIterator.php
Expand Up @@ -43,7 +43,7 @@ public function __construct(\Iterator $iterator, array $directories)
*/
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)) {
Expand Down
5 changes: 3 additions & 2 deletions Iterator/FileTypeFilterIterator.php
Expand Up @@ -43,9 +43,10 @@ public function __construct(\Iterator $iterator, $mode)
*/
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;
}

Expand Down
10 changes: 6 additions & 4 deletions Iterator/FilecontentFilterIterator.php
Expand Up @@ -30,13 +30,15 @@ public function accept()
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
Expand Down
2 changes: 1 addition & 1 deletion Iterator/FilenameFilterIterator.php
Expand Up @@ -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) {
Expand Down
5 changes: 3 additions & 2 deletions Iterator/SizeRangeFilterIterator.php
Expand Up @@ -40,11 +40,12 @@ public function __construct(\Iterator $iterator, array $comparators)
*/
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;
Expand Down
18 changes: 18 additions & 0 deletions SplFileInfo.php
Expand Up @@ -54,4 +54,22 @@ public function getRelativePathname()
{
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;
}
}
3 changes: 2 additions & 1 deletion Tests/Iterator/ExcludeDirectoryFileIteratorTest.php
Expand Up @@ -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
{
Expand All @@ -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);

Expand Down
151 changes: 127 additions & 24 deletions Tests/Iterator/FilecontentFilterIteratorTest.php
Expand Up @@ -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;

private $contents = null;
private $mode = null;
private $type = null;

public function getFilename()
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);
return self::TYPE_DIRECTORY === $this->type;
}

public function getRealpath()
public function isReadable()
{
return parent::current();
if ($this->mode === null) {
return preg_match('/r\+/', $this->getFilename());
}

return preg_match('/r\+/', $this->mode);
}

public function isReadable()
public function getContents()
{
return $this->contents;
}

public function setContents($contents)
{
$name = parent::current();
$this->contents = $contents;
}

public function setMode($mode)
{
$this->mode = $mode;
}

return preg_match('/r\+/', $name);
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);
}
}

0 comments on commit 05c884e

Please sign in to comment.