Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c36dfc1

Browse files
committed
[Component][Finder] ->path(), ->notPath() methods (with basic tests)
1 parent 2a23dbd commit c36dfc1

15 files changed

+459
-105
lines changed

src/Symfony/Component/Finder/Adapter/AbstractAdapter.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ abstract class AbstractAdapter implements AdapterInterface
3131
protected $dates = array();
3232
protected $filters = array();
3333
protected $sort = false;
34+
protected $paths = array();
35+
protected $notPaths = array();
3436

3537
/**
3638
* {@inheritdoc}
@@ -171,4 +173,25 @@ public function setSort($sort)
171173

172174
return $this;
173175
}
176+
177+
/**
178+
* {@inheritdoc}
179+
*/
180+
public function setPath(array $paths)
181+
{
182+
$this->paths = $paths;
183+
184+
return $this;
185+
}
186+
187+
/**
188+
* {@inheritdoc}
189+
*/
190+
public function setNotPath(array $notPaths)
191+
{
192+
$this->notPaths = $notPaths;
193+
194+
return $this;
195+
}
196+
174197
}

src/Symfony/Component/Finder/Adapter/PhpAdapter.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ public function searchInDirectory($dir)
7373
$iterator = $iteratorAggregate->getIterator();
7474
}
7575

76+
if ($this->paths || $this->notPaths) {
77+
$iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
78+
}
79+
7680
return $iterator;
7781
}
7882

src/Symfony/Component/Finder/Finder.php

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class Finder implements \IteratorAggregate, \Countable
5252
private $contains = array();
5353
private $notContains = array();
5454
private $adapters = array();
55+
private $paths = array();
56+
private $notPaths = array();
5557

5658
private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
5759

@@ -283,6 +285,52 @@ public function notContains($pattern)
283285
return $this;
284286
}
285287

288+
/**
289+
* Adds rules that filenames must match.
290+
*
291+
* You can use patterns (delimited with / sign) or simple strings.
292+
*
293+
* $finder->path('some/special/dir')
294+
* $finder->path('/some\/special\/dir/') // same as above
295+
*
296+
* Use only / as dirname separator.
297+
*
298+
* @param string $pattern A pattern (a regexp or a string)
299+
*
300+
* @return Finder The current Finder instance
301+
*
302+
* @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
303+
*/
304+
public function path($pattern)
305+
{
306+
$this->paths[] = $pattern;
307+
308+
return $this;
309+
}
310+
311+
/**
312+
* Adds rules that filenames must not match.
313+
*
314+
* You can use patterns (delimited with / sign) or simple strings.
315+
*
316+
* $finder->notPath('some/special/dir')
317+
* $finder->notPath('/some\/special\/dir/') // same as above
318+
*
319+
* Use only / as dirname separator.
320+
*
321+
* @param string $pattern A pattern (a regexp or a string)
322+
*
323+
* @return Finder The current Finder instance
324+
*
325+
* @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
326+
*/
327+
public function notPath($pattern)
328+
{
329+
$this->notPaths[] = $pattern;
330+
331+
return $this;
332+
}
333+
286334
/**
287335
* Adds tests for file sizes.
288336
*
@@ -682,6 +730,8 @@ private function buildAdapter(AdapterInterface $adapter)
682730
->setSizes($this->sizes)
683731
->setDates($this->dates)
684732
->setFilters($this->filters)
685-
->setSort($this->sort);
733+
->setSort($this->sort)
734+
->setPath($this->paths)
735+
->setNotPath($this->notPaths);
686736
}
687737
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Finder\Iterator;
13+
14+
/**
15+
* PathFilterIterator filters files by path patterns (e.g. some/special/dir).
16+
*
17+
* @author Fabien Potencier <[email protected]>
18+
* @author Włodzimierz Gajda <[email protected]>
19+
*/
20+
class PathFilterIterator extends MultiplePcreFilterIterator
21+
{
22+
23+
/**
24+
* Filters the iterator values.
25+
*
26+
* @return Boolean true if the value should be kept, false otherwise
27+
*/
28+
public function accept()
29+
{
30+
$filename = $this->current()->getRelativePathname();
31+
32+
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
33+
$filename = strtr($filename, '\\', '/');
34+
}
35+
36+
// should at least not match one rule to exclude
37+
foreach ($this->noMatchRegexps as $regex) {
38+
if (preg_match($regex, $filename)) {
39+
return false;
40+
}
41+
}
42+
43+
// should at least match one rule
44+
$match = true;
45+
if ($this->matchRegexps) {
46+
$match = false;
47+
foreach ($this->matchRegexps as $regex) {
48+
if (preg_match($regex, $filename)) {
49+
return true;
50+
}
51+
}
52+
}
53+
54+
return $match;
55+
}
56+
57+
/**
58+
* Converts strings to regexp.
59+
*
60+
* PCRE patterns are left unchanged.
61+
*
62+
* Default conversion:
63+
* 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/'
64+
*
65+
* Use only / as directory separator (on Windows also).
66+
*
67+
* @param string $str Pattern: regexp or dirname.
68+
*
69+
* @return string regexp corresponding to a given string or regexp
70+
*/
71+
protected function toRegex($str)
72+
{
73+
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
74+
}
75+
}

src/Symfony/Component/Finder/Tests/FinderTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,4 +646,65 @@ private function buildTestData(array $tests)
646646

647647
return $data;
648648
}
649+
650+
/**
651+
* @dataProvider getTestPathData
652+
*/
653+
public function testPath($matchPatterns, $noMatchPatterns, $expected)
654+
{
655+
$finder = new Finder();
656+
$finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
657+
->path($matchPatterns)
658+
->notPath($noMatchPatterns);
659+
660+
$this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
661+
}
662+
663+
public function getTestPathData()
664+
{
665+
return array(
666+
array('', '', array()),
667+
668+
array('/^A\/B\/C/', '/C$/',
669+
array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat')
670+
),
671+
672+
array('/^A\/B/', 'foobar',
673+
array(
674+
'A'.DIRECTORY_SEPARATOR.'B',
675+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
676+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
677+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
678+
)
679+
),
680+
681+
array('A/B/C', 'foobar',
682+
array(
683+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
684+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
685+
'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
686+
'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
687+
)
688+
),
689+
690+
array('A/B', 'foobar',
691+
array(
692+
//dirs
693+
'A'.DIRECTORY_SEPARATOR.'B',
694+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
695+
'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
696+
'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
697+
698+
//files
699+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
700+
'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
701+
'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
702+
'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
703+
)
704+
),
705+
706+
707+
);
708+
}
709+
649710
}

src/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat

Whitespace-only changes.

src/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat

Whitespace-only changes.

src/Symfony/Component/Finder/Tests/Fixtures/A/a.dat

Whitespace-only changes.

src/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy

Whitespace-only changes.

src/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy

Whitespace-only changes.

src/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy

Whitespace-only changes.

src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php

Lines changed: 2 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Finder\Tests\Iterator;
1313

1414
use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
15+
use Symfony\Component\Finder\Tests\Iterator\MockSplFileInfo;
16+
use Symfony\Component\Finder\Tests\Iterator\MockFileListIterator;
1517

1618
class FilecontentFilterIteratorTest extends IteratorTestCase
1719
{
@@ -85,107 +87,3 @@ public function getTestFilterData()
8587
);
8688
}
8789
}
88-
89-
class MockSplFileInfo extends \SplFileInfo
90-
{
91-
const TYPE_DIRECTORY = 1;
92-
const TYPE_FILE = 2;
93-
const TYPE_UNKNOWN = 3;
94-
95-
private $contents = null;
96-
private $mode = null;
97-
private $type = null;
98-
99-
public function __construct($param)
100-
{
101-
if (is_string($param)) {
102-
parent::__construct($param);
103-
} elseif (is_array($param)) {
104-
105-
$defaults = array(
106-
'name' => 'file.txt',
107-
'contents' => null,
108-
'mode' => null,
109-
'type' => null
110-
);
111-
$defaults = array_merge($defaults, $param);
112-
parent::__construct($defaults['name']);
113-
$this->setContents($defaults['contents']);
114-
$this->setMode($defaults['mode']);
115-
$this->setType($defaults['type']);
116-
} else {
117-
throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param));
118-
}
119-
}
120-
121-
public function isFile()
122-
{
123-
if ($this->type === null) {
124-
return preg_match('/file/', $this->getFilename());
125-
};
126-
127-
return self::TYPE_FILE === $this->type;
128-
}
129-
130-
public function isDir()
131-
{
132-
if ($this->type === null) {
133-
return preg_match('/directory/', $this->getFilename());
134-
}
135-
136-
return self::TYPE_DIRECTORY === $this->type;
137-
}
138-
139-
public function isReadable()
140-
{
141-
if ($this->mode === null) {
142-
return preg_match('/r\+/', $this->getFilename());
143-
}
144-
145-
return preg_match('/r\+/', $this->mode);
146-
}
147-
148-
public function getContents()
149-
{
150-
return $this->contents;
151-
}
152-
153-
public function setContents($contents)
154-
{
155-
$this->contents = $contents;
156-
}
157-
158-
public function setMode($mode)
159-
{
160-
$this->mode = $mode;
161-
}
162-
163-
public function setType($type)
164-
{
165-
if (is_string($type)) {
166-
switch ($type) {
167-
case 'directory':
168-
case 'd':
169-
$this->type = self::TYPE_DIRECTORY;
170-
break;
171-
case 'file':
172-
case 'f':
173-
$this->type = self::TYPE_FILE;
174-
break;
175-
default:
176-
$this->type = self::TYPE_UNKNOWN;
177-
}
178-
} else {
179-
$this->type = $type;
180-
}
181-
}
182-
}
183-
184-
class MockFileListIterator extends \ArrayIterator
185-
{
186-
public function __construct(array $filesArray = array())
187-
{
188-
$files = array_map(function($file){ return new MockSplFileInfo($file); }, $filesArray);
189-
parent::__construct($files);
190-
}
191-
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Finder\Tests\Iterator;
13+
14+
class MockFileListIterator extends \ArrayIterator
15+
{
16+
public function __construct(array $filesArray = array())
17+
{
18+
$files = array_map(function($file){ return new MockSplFileInfo($file); }, $filesArray);
19+
parent::__construct($files);
20+
}
21+
}

0 commit comments

Comments
 (0)