diff --git a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php index cff773d3e7..40759c04f5 100644 --- a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php @@ -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)) { diff --git a/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php index 96b6867a30..da62ecf4a9 100644 --- a/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php @@ -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; } diff --git a/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php index ffe3ddb7a8..953f9c3733 100644 --- a/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php @@ -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 diff --git a/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php index 03189e3a8a..109b5f0029 100644 --- a/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php @@ -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) { diff --git a/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php index 0b672c1062..b9b80441be 100644 --- a/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php @@ -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; diff --git a/src/Symfony/Component/Finder/SplFileInfo.php b/src/Symfony/Component/Finder/SplFileInfo.php index 6fe003a79c..e9d4f7b72f 100644 --- a/src/Symfony/Component/Finder/SplFileInfo.php +++ b/src/Symfony/Component/Finder/SplFileInfo.php @@ -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; + } } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php index cd8b2155d9..a0c522bfe5 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php @@ -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); diff --git a/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php index 38bc6c9e3a..f80e6a57aa 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php @@ -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); + } }