merged branch vicb/finder/regex (PR #4028)
Commits
-------
f728463
[Finder] Fixes in the iterators
Discussion
----------
[Finder] Fixes in the iterators
fix: #4023
ref: #4011
- Fix regex detection
- call `file_get_contents()` only once (vs once per pattern)
[![Build Status](https://secure.travis-ci.org/vicb/symfony.png?branch=finder/regex)](http://travis-ci.org/vicb/symfony)
@gajdaw thoughts ?
This commit is contained in:
commit
736886688f
@ -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, '/').'/';
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user