forked from symfony/symfony
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merged branch gajdaw/finder_search_by_contents (PR symfony#4011)
Commits ------- 218813c [Finder] contains(), notContains() 33e119a Merge branch 'master' of https://github.com/symfony/symfony into finder_search_by_contents 082d86e [Finder] content(), notContent() methods Discussion ---------- [Finder] search by contents Bug fix: no Feature addition: yes Backwards compatibility break: no Symfony2 tests pass: yes Fixes the following tickets: - Todo: - Sometimes I need to search for files containing some text: ``` $finder ->content('lorem')->notContent('ipsum') ->content('/^Begining/m')->notContent('/the end$/m'); ``` I don't know how to tests exceptions thrown by `file_get_contents()` calls. --------------------------------------------------------------------------- by gajdaw at 2012-04-19T15:53:05Z To keep it as close as possible to `name` and `notName`.
- Loading branch information
Showing
9 changed files
with
290 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Finder\Iterator; | ||
|
||
/** | ||
* FilecontentFilterIterator filters files by their contents using patterns (regexps or strings). | ||
* | ||
* @author Fabien Potencier <[email protected]> | ||
* @author Włodzimierz Gajda <[email protected]> | ||
*/ | ||
class FilecontentFilterIterator extends MultiplePcreFilterIterator | ||
{ | ||
|
||
/** | ||
* Filters the iterator values. | ||
* | ||
* @return Boolean true if the value should be kept, false otherwise | ||
*/ | ||
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; | ||
} | ||
|
||
// 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; | ||
} | ||
} | ||
} else { | ||
$exclude = false; | ||
} | ||
|
||
return $match && !$exclude; | ||
} | ||
|
||
/** | ||
* Converts string to regexp if necessary. | ||
* | ||
* @param string $str Pattern: string or regexp | ||
* | ||
* @return string regexp corresponding to a given string or regexp | ||
*/ | ||
protected function toRegex($str) | ||
{ | ||
if (preg_match('/^([^a-zA-Z0-9\\\\]).+?\\1[ims]?$/', $str)) { | ||
return $str; | ||
} | ||
|
||
return sprintf('/%s/', preg_quote($str, '/')); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,32 +18,8 @@ | |
* | ||
* @author Fabien Potencier <[email protected]> | ||
*/ | ||
class FilenameFilterIterator extends \FilterIterator | ||
class FilenameFilterIterator extends MultiplePcreFilterIterator | ||
{ | ||
private $matchRegexps; | ||
private $noMatchRegexps; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param \Iterator $iterator The Iterator to filter | ||
* @param array $matchPatterns An array of patterns that need to match | ||
* @param array $noMatchPatterns An array of patterns that need to not match | ||
*/ | ||
public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns) | ||
{ | ||
$this->matchRegexps = array(); | ||
foreach ($matchPatterns as $pattern) { | ||
$this->matchRegexps[] = $this->toRegex($pattern); | ||
} | ||
|
||
$this->noMatchRegexps = array(); | ||
foreach ($noMatchPatterns as $pattern) { | ||
$this->noMatchRegexps[] = $this->toRegex($pattern); | ||
} | ||
|
||
parent::__construct($iterator); | ||
} | ||
|
||
/** | ||
* Filters the iterator values. | ||
|
@@ -81,7 +57,17 @@ public function accept() | |
return $match && !$exclude; | ||
} | ||
|
||
private function toRegex($str) | ||
/** | ||
* Converts glob to regexp. | ||
* | ||
* PCRE patterns are left unchanged. | ||
* Glob strings are transformed with Glob::toRegex(). | ||
* | ||
* @param string $str Pattern: glob or regexp | ||
* | ||
* @return string regexp corresponding to a given glob or regexp | ||
*/ | ||
protected function toRegex($str) | ||
{ | ||
if (preg_match('/^([^a-zA-Z0-9\\\\]).+?\\1[ims]?$/', $str)) { | ||
return $str; | ||
|
57 changes: 57 additions & 0 deletions
57
src/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Finder\Iterator; | ||
|
||
use Symfony\Component\Finder\Glob; | ||
|
||
/** | ||
* MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings). | ||
* | ||
* @author Fabien Potencier <[email protected]> | ||
*/ | ||
abstract class MultiplePcreFilterIterator extends \FilterIterator | ||
{ | ||
protected $matchRegexps; | ||
protected $noMatchRegexps; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param \Iterator $iterator The Iterator to filter | ||
* @param array $matchPatterns An array of patterns that need to match | ||
* @param array $noMatchPatterns An array of patterns that need to not match | ||
*/ | ||
public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns) | ||
{ | ||
$this->matchRegexps = array(); | ||
foreach ($matchPatterns as $pattern) { | ||
$this->matchRegexps[] = $this->toRegex($pattern); | ||
} | ||
|
||
$this->noMatchRegexps = array(); | ||
foreach ($noMatchPatterns as $pattern) { | ||
$this->noMatchRegexps[] = $this->toRegex($pattern); | ||
} | ||
|
||
parent::__construct($iterator); | ||
} | ||
|
||
/** | ||
* Converts string into regexp. | ||
* | ||
* @param string $str Pattern | ||
* | ||
* @return string regexp corresponding to a given string | ||
*/ | ||
abstract protected function toRegex($str); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dolor sit amet | ||
DOLOR SIT AMET |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
ipsum dolor sit amet | ||
IPSUM DOLOR SIT AMET |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
lorem ipsum dolor sit amet | ||
LOREM IPSUM DOLOR SIT AMET |
41 changes: 41 additions & 0 deletions
41
src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* 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\FilecontentFilterIterator; | ||
|
||
class FilecontentFilterIteratorTest extends IteratorTestCase | ||
{ | ||
|
||
public function testAccept() | ||
{ | ||
$inner = new ContentInnerNameIterator(array('test.txt')); | ||
|
||
$iterator = new FilecontentFilterIterator($inner, array(), array()); | ||
|
||
$this->assertIterator(array('test.txt'), $iterator); | ||
} | ||
|
||
} | ||
|
||
class ContentInnerNameIterator extends \ArrayIterator | ||
{ | ||
public function current() | ||
{ | ||
return new \SplFileInfo(parent::current()); | ||
} | ||
|
||
public function getFilename() | ||
{ | ||
return parent::current(); | ||
} | ||
} |