From f72846305e6b5d093950dd38176733bcd4897fa9 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Fri, 20 Apr 2012 11:31:46 +0200 Subject: [PATCH] [Finder] Fixes in the iterators --- .../Iterator/FilecontentFilterIterator.php | 57 +++++++--------- .../Iterator/FilenameFilterIterator.php | 38 ++++------- .../Iterator/MultiplePcreFilterIterator.php | 25 +++++++ .../MultiplePcreFilterIteratorTest.php | 65 +++++++++++++++++++ 4 files changed, 127 insertions(+), 58 deletions(-) create mode 100644 src/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php diff --git a/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php index f056288b0a..9deb722bf9 100644 --- a/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php @@ -26,41 +26,34 @@ class FilecontentFilterIterator extends MultiplePcreFilterIterator */ public function accept() { - // should at least match one rule - if ($this->matchRegexps) { - $match = false; - foreach ($this->matchRegexps as $regex) { - $content = file_get_contents($this->getRealpath()); - if (false === $content) { - throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath())); - } - if (preg_match($regex, $content)) { - $match = true; - break; - } - } - } else { - $match = true; + if (!$this->matchRegexps && !$this->noMatchRegexps) { + return true; + } + + $content = file_get_contents($this->getRealpath()); + if (false === $content) { + throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath())); } // should at least not match one rule to exclude - if ($this->noMatchRegexps) { - $exclude = false; - foreach ($this->noMatchRegexps as $regex) { - $content = file_get_contents($this->getRealpath()); - if (false === $content) { - throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath())); - } - if (preg_match($regex, $content)) { - $exclude = true; - break; - } + foreach ($this->noMatchRegexps as $regex) { + if (preg_match($regex, $content)) { + return false; } - } else { - $exclude = false; } - return $match && !$exclude; + // should at least match one rule + $match = true; + if ($this->matchRegexps) { + $match = false; + foreach ($this->matchRegexps as $regex) { + if (preg_match($regex, $content)) { + return true; + } + } + } + + return $match; } /** @@ -72,10 +65,6 @@ class FilecontentFilterIterator extends MultiplePcreFilterIterator */ protected function toRegex($str) { - if (preg_match('/^([^a-zA-Z0-9\\\\]).+?\\1[ims]?$/', $str)) { - return $str; - } - - return sprintf('/%s/', preg_quote($str, '/')); + return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/'; } } diff --git a/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php index 9b9bfe8512..03189e3a8a 100644 --- a/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php @@ -28,33 +28,27 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator */ public function accept() { + $filename = $this->getFilename(); + + // should at least not match one rule to exclude + foreach ($this->noMatchRegexps as $regex) { + if (preg_match($regex, $filename)) { + return false; + } + } + // should at least match one rule + $match = true; if ($this->matchRegexps) { $match = false; foreach ($this->matchRegexps as $regex) { - if (preg_match($regex, $this->getFilename())) { - $match = true; - break; + if (preg_match($regex, $filename)) { + return true; } } - } else { - $match = true; } - // should at least not match one rule to exclude - if ($this->noMatchRegexps) { - $exclude = false; - foreach ($this->noMatchRegexps as $regex) { - if (preg_match($regex, $this->getFilename())) { - $exclude = true; - break; - } - } - } else { - $exclude = false; - } - - return $match && !$exclude; + return $match; } /** @@ -69,10 +63,6 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator */ protected function toRegex($str) { - if (preg_match('/^([^a-zA-Z0-9\\\\]).+?\\1[ims]?$/', $str)) { - return $str; - } - - return Glob::toRegex($str); + return $this->isRegex($str) ? $str : Glob::toRegex($str); } } diff --git a/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php b/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php index 7c2600af28..05202ead96 100644 --- a/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php @@ -44,6 +44,31 @@ abstract class MultiplePcreFilterIterator extends \FilterIterator parent::__construct($iterator); } + /** + * Checks whether the string is a regex. + * + * @param string $str + * + * @return Boolean Whether the given string is a regex + */ + protected function isRegex($str) { + + if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) { + $start = substr($m[1], 0, 1); + $end = substr($m[1], -1); + + if ($start === $end) { + return !preg_match('/[[:alnum:] \\\\]/', $start); + } + + if ($start === '{' && $end === '}') { + return true; + } + } + + return false; + } + /** * Converts string into regexp. * diff --git a/src/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php new file mode 100644 index 0000000000..46c94a4191 --- /dev/null +++ b/src/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php @@ -0,0 +1,65 @@ + + * + * 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; + +use Symfony\Component\Finder\Iterator\MultiplePcreFilterIterator; + +class MultiplePcreFilterIteratorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getIsRegexFixtures + */ + public function testIsRegex($string, $isRegex, $message) + { + $testIterator = new TestMultiplePcreFilterIterator(); + $this->assertEquals($isRegex, $testIterator->isRegex($string), $message); + } + + public function getIsRegexFixtures() + { + return array( + array('foo', false, 'string'), + array(' foo ', false, '" " is not a valid delimiter'), + array('\\foo\\', false, '"\\" is not a valid delimiter'), + array('afooa', false, '"a" is not a valid delimiter'), + array('//', false, 'the pattern should contain at least 1 character'), + array('/a/', true, 'valid regex'), + array('/foo/', true, 'valid regex'), + array('/foo/i', true, 'valid regex with a single modifier'), + array('/foo/imsxu', true, 'valid regex with multiple modifiers'), + array('#foo#', true, '"#" is a valid delimiter'), + array('{foo}', true, '"{,}" is a valid delimiter pair'), + ); + } +} + +class TestMultiplePcreFilterIterator extends MultiplePcreFilterIterator +{ + public function __construct() + { + } + + public function accept() + { + throw new \BadFunctionCallException('Not implemented'); + } + + public function isRegex($str) + { + return parent::isRegex($str); + } + + public function toRegex($str) + { + throw new \BadFunctionCallException('Not implemented'); + } +} \ No newline at end of file