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()
|
public function accept()
|
||||||
{
|
{
|
||||||
// should at least match one rule
|
if (!$this->matchRegexps && !$this->noMatchRegexps) {
|
||||||
if ($this->matchRegexps) {
|
return true;
|
||||||
$match = false;
|
}
|
||||||
foreach ($this->matchRegexps as $regex) {
|
|
||||||
$content = file_get_contents($this->getRealpath());
|
$content = file_get_contents($this->getRealpath());
|
||||||
if (false === $content) {
|
if (false === $content) {
|
||||||
throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath()));
|
throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath()));
|
||||||
}
|
}
|
||||||
if (preg_match($regex, $content)) {
|
|
||||||
$match = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$match = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// should at least not match one rule to exclude
|
// should at least not match one rule to exclude
|
||||||
if ($this->noMatchRegexps) {
|
|
||||||
$exclude = false;
|
|
||||||
foreach ($this->noMatchRegexps as $regex) {
|
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)) {
|
if (preg_match($regex, $content)) {
|
||||||
$exclude = true;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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)
|
protected function toRegex($str)
|
||||||
{
|
{
|
||||||
if (preg_match('/^([^a-zA-Z0-9\\\\]).+?\\1[ims]?$/', $str)) {
|
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
|
||||||
return $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sprintf('/%s/', preg_quote($str, '/'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,33 +28,27 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator
|
|||||||
*/
|
*/
|
||||||
public function accept()
|
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
|
// should at least match one rule
|
||||||
|
$match = true;
|
||||||
if ($this->matchRegexps) {
|
if ($this->matchRegexps) {
|
||||||
$match = false;
|
$match = false;
|
||||||
foreach ($this->matchRegexps as $regex) {
|
foreach ($this->matchRegexps as $regex) {
|
||||||
if (preg_match($regex, $this->getFilename())) {
|
if (preg_match($regex, $filename)) {
|
||||||
$match = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$match = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// should at least not match one rule to exclude
|
return $match;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,10 +63,6 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator
|
|||||||
*/
|
*/
|
||||||
protected function toRegex($str)
|
protected function toRegex($str)
|
||||||
{
|
{
|
||||||
if (preg_match('/^([^a-zA-Z0-9\\\\]).+?\\1[ims]?$/', $str)) {
|
return $this->isRegex($str) ? $str : Glob::toRegex($str);
|
||||||
return $str;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Glob::toRegex($str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,31 @@ abstract class MultiplePcreFilterIterator extends \FilterIterator
|
|||||||
parent::__construct($iterator);
|
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.
|
* 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