Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 841 lines (751 sloc) 22.006 kb
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
1 <?php
2
3 /*
782e089 @blue-eyes normalized license messages in PHP files
blue-eyes authored
4 * This file is part of the Symfony package.
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
5 *
db96c6a @fabpot replaced symfony-project.org by symfony.com
fabpot authored
6 * (c) Fabien Potencier <fabien@symfony.com>
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
7 *
782e089 @blue-eyes normalized license messages in PHP files
blue-eyes authored
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
10 */
11
782e089 @blue-eyes normalized license messages in PHP files
blue-eyes authored
12 namespace Symfony\Component\Finder;
13
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
14 use Symfony\Component\Finder\Adapter\AdapterInterface;
15 use Symfony\Component\Finder\Adapter\GnuFindAdapter;
708a23f @jfsimon [Finder] Added bsd adapter (need tests).
jfsimon authored
16 use Symfony\Component\Finder\Adapter\BsdFindAdapter;
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
17 use Symfony\Component\Finder\Adapter\PhpAdapter;
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
18 use Symfony\Component\Finder\Comparator\DateComparator;
19 use Symfony\Component\Finder\Comparator\NumberComparator;
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
20 use Symfony\Component\Finder\Exception\ExceptionInterface;
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
21 use Symfony\Component\Finder\Iterator\CustomFilterIterator;
22 use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
23 use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
24 use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
25 use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
26 use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
27 use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
28 use Symfony\Component\Finder\Iterator\SortableIterator;
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
29
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
30 /**
31 * Finder allows to build rules to find files and directories.
32 *
33 * It is a thin wrapper around several specialized iterator classes.
34 *
35 * All rules may be invoked several times.
36 *
37 * All methods return the current Finder object to allow easy chaining:
38 *
83d148b @fabpot [Finder] added a convenience method Finder::create()
fabpot authored
39 * $finder = Finder::create()->files()->name('*.php')->in(__DIR__);
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
40 *
db96c6a @fabpot replaced symfony-project.org by symfony.com
fabpot authored
41 * @author Fabien Potencier <fabien@symfony.com>
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
42 *
43 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
44 */
5b8658e @ManuelAC Implement Countable
ManuelAC authored
45 class Finder implements \IteratorAggregate, \Countable
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
46 {
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
47 const IGNORE_VCS_FILES = 1;
48 const IGNORE_DOT_FILES = 2;
49
414c1ab @disquedur Remove aligned '=>' and '='
disquedur authored
50 private $mode = 0;
51 private $names = array();
52 private $notNames = array();
53 private $exclude = array();
54 private $filters = array();
55 private $depths = array();
56 private $sizes = array();
4e85ff1 @fabpot [Finder] moved most protected methods and properties to private
fabpot authored
57 private $followLinks = false;
414c1ab @disquedur Remove aligned '=>' and '='
disquedur authored
58 private $sort = false;
59 private $ignore = 0;
60 private $dirs = array();
61 private $dates = array();
62 private $iterators = array();
63 private $contains = array();
4191ecb @gajdaw [Finder] contains(), notContains()
gajdaw authored
64 private $notContains = array();
414c1ab @disquedur Remove aligned '=>' and '='
disquedur authored
65 private $adapters = array();
66 private $paths = array();
67 private $notPaths = array();
9d55e88 @jfsimon [Finder] added Finder::ignoreUnreadableDirs() method
jfsimon authored
68 private $ignoreUnreadableDirs = false;
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
69
fccf904 @fabpot fixed CS
fabpot authored
70 private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
71
83d148b @fabpot [Finder] added a convenience method Finder::create()
fabpot authored
72 /**
73 * Constructor.
74 */
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
75 public function __construct()
76 {
77 $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
78
466bf9a @vicb [Finder] cleanup, fixes, improvements
vicb authored
79 $this
80 ->addAdapter(new GnuFindAdapter())
81 ->addAdapter(new BsdFindAdapter())
82 ->addAdapter(new PhpAdapter(), -50)
2feb8d3 @jfsimon [Finder] adds adapter selection/unselection capabilities
jfsimon authored
83 ->setAdapter('php')
466bf9a @vicb [Finder] cleanup, fixes, improvements
vicb authored
84 ;
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
85 }
86
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
87 /**
83d148b @fabpot [Finder] added a convenience method Finder::create()
fabpot authored
88 * Creates a new Finder.
89 *
90 * @return Finder A new Finder instance
91 *
92 * @api
93 */
fccf904 @fabpot fixed CS
fabpot authored
94 public static function create()
83d148b @fabpot [Finder] added a convenience method Finder::create()
fabpot authored
95 {
5c52af8 @Slamdunk Late static factory method
Slamdunk authored
96 return new static();
83d148b @fabpot [Finder] added a convenience method Finder::create()
fabpot authored
97 }
98
99 /**
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
100 * Registers a finder engine implementation.
101 *
102 * @param AdapterInterface $adapter An adapter instance
5ae5257 @fabpot made phpdoc types consistent with those defined in Hack
fabpot authored
103 * @param int $priority Highest is selected first
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
104 *
105 * @return Finder The current Finder instance
106 */
d245bf7 @hhamon [Finder] fixed typehint of the Finder::addAdapter() method
hhamon authored
107 public function addAdapter(AdapterInterface $adapter, $priority = 0)
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
108 {
109 $this->adapters[$adapter->getName()] = array(
414c1ab @disquedur Remove aligned '=>' and '='
disquedur authored
110 'adapter' => $adapter,
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
111 'priority' => $priority,
2feb8d3 @jfsimon [Finder] adds adapter selection/unselection capabilities
jfsimon authored
112 'selected' => false,
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
113 );
114
115 return $this->sortAdapters();
116 }
117
118 /**
2feb8d3 @jfsimon [Finder] adds adapter selection/unselection capabilities
jfsimon authored
119 * Sets the selected adapter to the best one according to the current platform the code is run on.
120 *
121 * @return Finder The current Finder instance
122 */
123 public function useBestAdapter()
124 {
125 $this->resetAdapterSelection();
126
127 return $this->sortAdapters();
128 }
129
130 /**
131 * Selects the adapter to use.
132 *
133 * @param string $name
134 *
135 * @throws \InvalidArgumentException
136 *
137 * @return Finder The current Finder instance
138 */
139 public function setAdapter($name)
140 {
141 if (!isset($this->adapters[$name])) {
142 throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
143 }
144
145 $this->resetAdapterSelection();
146 $this->adapters[$name]['selected'] = true;
147
148 return $this->sortAdapters();
149 }
150
151 /**
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
152 * Removes all adapters registered in the finder.
153 *
154 * @return Finder The current Finder instance
155 */
156 public function removeAdapters()
157 {
158 $this->adapters = array();
159
160 return $this;
161 }
162
163 /**
164 * Returns registered adapters ordered by priority without extra information.
165 *
166 * @return AdapterInterface[]
167 */
168 public function getAdapters()
169 {
b55a3f2 @fabpot fixed CS for lambdas
fabpot authored
170 return array_values(array_map(function (array $adapter) {
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
171 return $adapter['adapter'];
172 }, $this->adapters));
173 }
174
175 /**
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
176 * Restricts the matching to directories only.
177 *
178 * @return Finder The current Finder instance
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
179 *
180 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
181 */
182 public function directories()
183 {
184 $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
185
186 return $this;
187 }
188
189 /**
190 * Restricts the matching to files only.
191 *
192 * @return Finder The current Finder instance
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
193 *
194 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
195 */
196 public function files()
197 {
198 $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
199
200 return $this;
201 }
202
203 /**
204 * Adds tests for the directory depth.
205 *
206 * Usage:
207 *
208 * $finder->depth('> 1') // the Finder will start matching at level 1.
209 * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
210 *
a464fd6 @fabpot fixed phpdoc @param alignment
fabpot authored
211 * @param int $level The depth level expression
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
212 *
213 * @return Finder The current Finder instance
214 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
215 * @see DepthRangeFilterIterator
216 * @see NumberComparator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
217 *
218 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
219 */
220 public function depth($level)
221 {
222 $this->depths[] = new Comparator\NumberComparator($level);
223
224 return $this;
225 }
226
227 /**
228 * Adds tests for file dates (last modified).
229 *
230 * The date must be something that strtotime() is able to parse:
231 *
232 * $finder->date('since yesterday');
233 * $finder->date('until 2 days ago');
234 * $finder->date('> now - 2 hours');
235 * $finder->date('>= 2005-10-15');
236 *
c959ef6 @King2500 [Finder] Fixed typo in phpdoc comment
King2500 authored
237 * @param string $date A date range string
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
238 *
239 * @return Finder The current Finder instance
240 *
241 * @see strtotime
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
242 * @see DateRangeFilterIterator
243 * @see DateComparator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
244 *
245 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
246 */
247 public function date($date)
248 {
249 $this->dates[] = new Comparator\DateComparator($date);
250
251 return $this;
252 }
253
254 /**
255 * Adds rules that files must match.
256 *
257 * You can use patterns (delimited with / sign), globs or simple strings.
258 *
259 * $finder->name('*.php')
260 * $finder->name('/\.php$/') // same as above
261 * $finder->name('test.php')
262 *
a464fd6 @fabpot fixed phpdoc @param alignment
fabpot authored
263 * @param string $pattern A pattern (a regexp, a glob, or a string)
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
264 *
265 * @return Finder The current Finder instance
266 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
267 * @see FilenameFilterIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
268 *
269 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
270 */
271 public function name($pattern)
272 {
273 $this->names[] = $pattern;
274
275 return $this;
276 }
277
278 /**
279 * Adds rules that files must not match.
280 *
a464fd6 @fabpot fixed phpdoc @param alignment
fabpot authored
281 * @param string $pattern A pattern (a regexp, a glob, or a string)
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
282 *
283 * @return Finder The current Finder instance
284 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
285 * @see FilenameFilterIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
286 *
287 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
288 */
289 public function notName($pattern)
290 {
291 $this->notNames[] = $pattern;
292
293 return $this;
294 }
295
296 /**
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
297 * Adds tests that file contents must match.
298 *
299 * Strings or PCRE patterns can be used:
300 *
4191ecb @gajdaw [Finder] contains(), notContains()
gajdaw authored
301 * $finder->contains('Lorem ipsum')
302 * $finder->contains('/Lorem ipsum/i')
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
303 *
a464fd6 @fabpot fixed phpdoc @param alignment
fabpot authored
304 * @param string $pattern A pattern (string or regexp)
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
305 *
306 * @return Finder The current Finder instance
307 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
308 * @see FilecontentFilterIterator
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
309 */
4191ecb @gajdaw [Finder] contains(), notContains()
gajdaw authored
310 public function contains($pattern)
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
311 {
4191ecb @gajdaw [Finder] contains(), notContains()
gajdaw authored
312 $this->contains[] = $pattern;
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
313
314 return $this;
315 }
316
317 /**
318 * Adds tests that file contents must not match.
319 *
320 * Strings or PCRE patterns can be used:
321 *
4191ecb @gajdaw [Finder] contains(), notContains()
gajdaw authored
322 * $finder->notContains('Lorem ipsum')
323 * $finder->notContains('/Lorem ipsum/i')
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
324 *
a464fd6 @fabpot fixed phpdoc @param alignment
fabpot authored
325 * @param string $pattern A pattern (string or regexp)
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
326 *
327 * @return Finder The current Finder instance
328 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
329 * @see FilecontentFilterIterator
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
330 */
4191ecb @gajdaw [Finder] contains(), notContains()
gajdaw authored
331 public function notContains($pattern)
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
332 {
4191ecb @gajdaw [Finder] contains(), notContains()
gajdaw authored
333 $this->notContains[] = $pattern;
afba636 @gajdaw [Finder] content(), notContent() methods
gajdaw authored
334
335 return $this;
336 }
337
338 /**
7ff1cb6 @gajdaw [Component][Finder] ->path(), ->notPath() methods (with basic tests)
gajdaw authored
339 * Adds rules that filenames must match.
340 *
341 * You can use patterns (delimited with / sign) or simple strings.
342 *
343 * $finder->path('some/special/dir')
344 * $finder->path('/some\/special\/dir/') // same as above
345 *
346 * Use only / as dirname separator.
347 *
348 * @param string $pattern A pattern (a regexp or a string)
349 *
350 * @return Finder The current Finder instance
351 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
352 * @see FilenameFilterIterator
7ff1cb6 @gajdaw [Component][Finder] ->path(), ->notPath() methods (with basic tests)
gajdaw authored
353 */
354 public function path($pattern)
355 {
356 $this->paths[] = $pattern;
357
358 return $this;
359 }
360
361 /**
362 * Adds rules that filenames must not match.
363 *
364 * You can use patterns (delimited with / sign) or simple strings.
365 *
366 * $finder->notPath('some/special/dir')
367 * $finder->notPath('/some\/special\/dir/') // same as above
368 *
369 * Use only / as dirname separator.
370 *
371 * @param string $pattern A pattern (a regexp or a string)
372 *
373 * @return Finder The current Finder instance
374 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
375 * @see FilenameFilterIterator
7ff1cb6 @gajdaw [Component][Finder] ->path(), ->notPath() methods (with basic tests)
gajdaw authored
376 */
377 public function notPath($pattern)
378 {
379 $this->notPaths[] = $pattern;
380
381 return $this;
382 }
383
384 /**
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
385 * Adds tests for file sizes.
386 *
387 * $finder->size('> 10K');
388 * $finder->size('<= 1Ki');
389 * $finder->size(4);
390 *
391 * @param string $size A size range string
392 *
393 * @return Finder The current Finder instance
394 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
395 * @see SizeRangeFilterIterator
396 * @see NumberComparator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
397 *
398 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
399 */
400 public function size($size)
401 {
402 $this->sizes[] = new Comparator\NumberComparator($size);
403
404 return $this;
405 }
406
407 /**
408 * Excludes directories.
409 *
a464fd6 @fabpot fixed phpdoc @param alignment
fabpot authored
410 * @param string|array $dirs A directory path or an array of directories
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
411 *
412 * @return Finder The current Finder instance
413 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
414 * @see ExcludeDirectoryFilterIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
415 *
416 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
417 */
502da7c @brikou made exclude method accept array of dirs
brikou authored
418 public function exclude($dirs)
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
419 {
502da7c @brikou made exclude method accept array of dirs
brikou authored
420 $this->exclude = array_merge($this->exclude, (array) $dirs);
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
421
422 return $this;
423 }
424
425 /**
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
426 * Excludes "hidden" directories and files (starting with a dot).
427 *
879b140 @GrahamCampbell Docblock fixes
GrahamCampbell authored
428 * @param bool $ignoreDotFiles Whether to exclude "hidden" files or not
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
429 *
430 * @return Finder The current Finder instance
431 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
432 * @see ExcludeDirectoryFilterIterator
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
433 *
434 * @api
435 */
436 public function ignoreDotFiles($ignoreDotFiles)
437 {
438 if ($ignoreDotFiles) {
97f661a @kalessil Php Inspections (EA Extended) - static code analysis includes:
kalessil authored
439 $this->ignore |= static::IGNORE_DOT_FILES;
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
440 } else {
97f661a @kalessil Php Inspections (EA Extended) - static code analysis includes:
kalessil authored
441 $this->ignore &= ~static::IGNORE_DOT_FILES;
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
442 }
443
444 return $this;
445 }
446
447 /**
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
448 * Forces the finder to ignore version control directories.
449 *
879b140 @GrahamCampbell Docblock fixes
GrahamCampbell authored
450 * @param bool $ignoreVCS Whether to exclude VCS files or not
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
451 *
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
452 * @return Finder The current Finder instance
453 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
454 * @see ExcludeDirectoryFilterIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
455 *
456 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
457 */
458 public function ignoreVCS($ignoreVCS)
459 {
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
460 if ($ignoreVCS) {
97f661a @kalessil Php Inspections (EA Extended) - static code analysis includes:
kalessil authored
461 $this->ignore |= static::IGNORE_VCS_FILES;
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
462 } else {
97f661a @kalessil Php Inspections (EA Extended) - static code analysis includes:
kalessil authored
463 $this->ignore &= ~static::IGNORE_VCS_FILES;
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
464 }
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
465
466 return $this;
467 }
468
466bf9a @vicb [Finder] cleanup, fixes, improvements
vicb authored
469 /**
470 * Adds VCS patterns.
471 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
472 * @see ignoreVCS()
466bf9a @vicb [Finder] cleanup, fixes, improvements
vicb authored
473 *
474 * @param string|string[] $pattern VCS patterns to ignore
475 */
fccf904 @fabpot fixed CS
fabpot authored
476 public static function addVCSPattern($pattern)
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
477 {
466bf9a @vicb [Finder] cleanup, fixes, improvements
vicb authored
478 foreach ((array) $pattern as $p) {
479 self::$vcsPatterns[] = $p;
480 }
481
482 self::$vcsPatterns = array_unique(self::$vcsPatterns);
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
483 }
484
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
485 /**
486 * Sorts files and directories by an anonymous function.
487 *
488 * The anonymous function receives two \SplFileInfo instances to compare.
489 *
490 * This can be slow as all the matching files and directories must be retrieved for comparison.
491 *
e5dac3c Nsdocblocks
Drak authored
492 * @param \Closure $closure An anonymous function
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
493 *
494 * @return Finder The current Finder instance
495 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
496 * @see SortableIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
497 *
498 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
499 */
500 public function sort(\Closure $closure)
501 {
502 $this->sort = $closure;
503
504 return $this;
505 }
506
507 /**
508 * Sorts files and directories by name.
509 *
510 * This can be slow as all the matching files and directories must be retrieved for comparison.
511 *
512 * @return Finder The current Finder instance
513 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
514 * @see SortableIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
515 *
516 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
517 */
518 public function sortByName()
519 {
520 $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
521
522 return $this;
523 }
524
525 /**
526 * Sorts files and directories by type (directories before files), then by name.
527 *
528 * This can be slow as all the matching files and directories must be retrieved for comparison.
529 *
530 * @return Finder The current Finder instance
531 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
532 * @see SortableIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
533 *
534 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
535 */
536 public function sortByType()
537 {
538 $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
539
540 return $this;
dc525b5 @ruimarinho [Finder] Added sortBy options based on accessed, changed and modified…
ruimarinho authored
541 }
542
543 /**
544 * Sorts files and directories by the last accessed time.
545 *
546 * This is the time that the file was last accessed, read or written to.
547 *
548 * This can be slow as all the matching files and directories must be retrieved for comparison.
549 *
550 * @return Finder The current Finder instance
551 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
552 * @see SortableIterator
dc525b5 @ruimarinho [Finder] Added sortBy options based on accessed, changed and modified…
ruimarinho authored
553 *
554 * @api
555 */
556 public function sortByAccessedTime()
557 {
558 $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
559
560 return $this;
561 }
562
563 /**
564 * Sorts files and directories by the last inode changed time.
565 *
566 * This is the time that the inode information was last modified (permissions, owner, group or other metadata).
567 *
568 * On Windows, since inode is not available, changed time is actually the file creation time.
569 *
570 * This can be slow as all the matching files and directories must be retrieved for comparison.
571 *
572 * @return Finder The current Finder instance
573 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
574 * @see SortableIterator
dc525b5 @ruimarinho [Finder] Added sortBy options based on accessed, changed and modified…
ruimarinho authored
575 *
576 * @api
577 */
578 public function sortByChangedTime()
579 {
580 $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
581
582 return $this;
583 }
584
585 /**
586 * Sorts files and directories by the last modified time.
587 *
588 * This is the last time the actual contents of the file were last modified.
589 *
590 * This can be slow as all the matching files and directories must be retrieved for comparison.
591 *
592 * @return Finder The current Finder instance
593 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
594 * @see SortableIterator
dc525b5 @ruimarinho [Finder] Added sortBy options based on accessed, changed and modified…
ruimarinho authored
595 *
596 * @api
597 */
598 public function sortByModifiedTime()
599 {
600 $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
601
602 return $this;
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
603 }
604
605 /**
606 * Filters the iterator with an anonymous function.
607 *
608 * The anonymous function receives a \SplFileInfo and must return false
609 * to remove files.
610 *
e5dac3c Nsdocblocks
Drak authored
611 * @param \Closure $closure An anonymous function
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
612 *
613 * @return Finder The current Finder instance
614 *
37b7288 @hhamon Fixes various phpdoc and coding standards.
hhamon authored
615 * @see CustomFilterIterator
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
616 *
617 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
618 */
619 public function filter(\Closure $closure)
620 {
621 $this->filters[] = $closure;
622
623 return $this;
624 }
625
626 /**
627 * Forces the following of symlinks.
628 *
629 * @return Finder The current Finder instance
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
630 *
631 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
632 */
633 public function followLinks()
634 {
635 $this->followLinks = true;
636
637 return $this;
638 }
639
640 /**
9d55e88 @jfsimon [Finder] added Finder::ignoreUnreadableDirs() method
jfsimon authored
641 * Tells finder to ignore unreadable directories.
642 *
643 * By default, scanning unreadable directories content throws an AccessDeniedException.
644 *
879b140 @GrahamCampbell Docblock fixes
GrahamCampbell authored
645 * @param bool $ignore
9d55e88 @jfsimon [Finder] added Finder::ignoreUnreadableDirs() method
jfsimon authored
646 *
647 * @return Finder The current Finder instance
648 */
649 public function ignoreUnreadableDirs($ignore = true)
650 {
02dc690 @fabpot made types consistent with those defined in Hack
fabpot authored
651 $this->ignoreUnreadableDirs = (bool) $ignore;
9d55e88 @jfsimon [Finder] added Finder::ignoreUnreadableDirs() method
jfsimon authored
652
653 return $this;
654 }
655
656 /**
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
657 * Searches files and directories which match defined rules.
658 *
a464fd6 @fabpot fixed phpdoc @param alignment
fabpot authored
659 * @param string|array $dirs A directory path or an array of directories
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
660 *
661 * @return Finder The current Finder instance
662 *
b43123d @jakzal [Finder] Added support for GLOB patterns in the directories passed to…
jakzal authored
663 * @throws \InvalidArgumentException if one of the directories does not exist
4309fee @fabpot [Finder] tagged the guaranteed BC API
fabpot authored
664 *
665 * @api
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
666 */
667 public function in($dirs)
668 {
b43123d @jakzal [Finder] Added support for GLOB patterns in the directories passed to…
jakzal authored
669 $resolvedDirs = array();
670
671 foreach ((array) $dirs as $dir) {
672 if (is_dir($dir)) {
673 $resolvedDirs[] = $dir;
a0c9d35 @dosten [Finder] Only use GLOB_BRACE when available
dosten authored
674 } elseif ($glob = glob($dir, (defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR)) {
b43123d @jakzal [Finder] Added support for GLOB patterns in the directories passed to…
jakzal authored
675 $resolvedDirs = array_merge($resolvedDirs, $glob);
676 } else {
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
677 throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
678 }
679 }
680
b43123d @jakzal [Finder] Added support for GLOB patterns in the directories passed to…
jakzal authored
681 $this->dirs = array_merge($this->dirs, $resolvedDirs);
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
682
683 return $this;
684 }
685
686 /**
687 * Returns an Iterator for the current Finder configuration.
688 *
689 * This method implements the IteratorAggregate interface.
690 *
691 * @return \Iterator An iterator
692 *
693 * @throws \LogicException if the in() method has not been called
694 */
695 public function getIterator()
696 {
ff6fa82 @vicb [Finder] fluid, calling in() not required after append()
vicb authored
697 if (0 === count($this->dirs) && 0 === count($this->iterators)) {
698 throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
699 }
700
707b2fc @fabpot [Finder] added Finder::append() method to be able to combine several …
fabpot authored
701 if (1 === count($this->dirs) && 0 === count($this->iterators)) {
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
702 return $this->searchInDirectory($this->dirs[0]);
703 }
704
705 $iterator = new \AppendIterator();
706 foreach ($this->dirs as $dir) {
707 $iterator->append($this->searchInDirectory($dir));
708 }
709
707b2fc @fabpot [Finder] added Finder::append() method to be able to combine several …
fabpot authored
710 foreach ($this->iterators as $it) {
711 $iterator->append($it);
712 }
713
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
714 return $iterator;
715 }
716
707b2fc @fabpot [Finder] added Finder::append() method to be able to combine several …
fabpot authored
717 /**
718 * Appends an existing set of files/directories to the finder.
719 *
720 * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array.
721 *
722 * @param mixed $iterator
ff6fa82 @vicb [Finder] fluid, calling in() not required after append()
vicb authored
723 *
724 * @return Finder The finder
725 *
726 * @throws \InvalidArgumentException When the given argument is not iterable.
707b2fc @fabpot [Finder] added Finder::append() method to be able to combine several …
fabpot authored
727 */
728 public function append($iterator)
729 {
730 if ($iterator instanceof \IteratorAggregate) {
731 $this->iterators[] = $iterator->getIterator();
732 } elseif ($iterator instanceof \Iterator) {
733 $this->iterators[] = $iterator;
734 } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
735 $it = new \ArrayIterator();
736 foreach ($iterator as $file) {
737 $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
738 }
739 $this->iterators[] = $it;
740 } else {
741 throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
742 }
ff6fa82 @vicb [Finder] fluid, calling in() not required after append()
vicb authored
743
744 return $this;
707b2fc @fabpot [Finder] added Finder::append() method to be able to combine several …
fabpot authored
745 }
aa975c9 @fabpot fixed CS
fabpot authored
746
5b8658e @ManuelAC Implement Countable
ManuelAC authored
747 /**
748 * Counts all the results collected by the iterators.
749 *
750 * @return int
751 */
752 public function count()
753 {
754 return iterator_count($this->getIterator());
755 }
707b2fc @fabpot [Finder] added Finder::append() method to be able to combine several …
fabpot authored
756
2feb8d3 @jfsimon [Finder] adds adapter selection/unselection capabilities
jfsimon authored
757 /**
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
758 * @return Finder The current Finder instance
759 */
760 private function sortAdapters()
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
761 {
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
762 uasort($this->adapters, function (array $a, array $b) {
2feb8d3 @jfsimon [Finder] adds adapter selection/unselection capabilities
jfsimon authored
763 if ($a['selected'] || $b['selected']) {
764 return $a['selected'] ? -1 : 1;
765 }
766
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
767 return $a['priority'] > $b['priority'] ? -1 : 1;
768 });
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
769
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
770 return $this;
771 }
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
772
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
773 /**
774 * @param $dir
775 *
776 * @return \Iterator
466bf9a @vicb [Finder] cleanup, fixes, improvements
vicb authored
777 *
778 * @throws \RuntimeException When none of the adapters are supported
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
779 */
780 private function searchInDirectory($dir)
781 {
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
782 if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
6ab7e2c @fabpot [Finder] replaced static by self on a private variable
fabpot authored
783 $this->exclude = array_merge($this->exclude, self::$vcsPatterns);
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
784 }
785
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
786 if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
2b13acd @gajdaw fix issue 4911
gajdaw authored
787 $this->notPaths[] = '#(^|/)\..+(/|$)#';
42709a7 @fabpot [Finder] added a way to ignore all 'hidden' files
fabpot authored
788 }
789
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
790 foreach ($this->adapters as $adapter) {
466bf9a @vicb [Finder] cleanup, fixes, improvements
vicb authored
791 if ($adapter['adapter']->isSupported()) {
792 try {
793 return $this
794 ->buildAdapter($adapter['adapter'])
795 ->searchInDirectory($dir);
616e2f8 @fabpot fixed CS
fabpot authored
796 } catch (ExceptionInterface $e) {
797 }
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
798 }
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
799 }
800
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
801 throw new \RuntimeException('No supported adapter found.');
802 }
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
803
5259120 @jfsimon [2.2] [WIP] [Finder] Adding native finders implementations
jfsimon authored
804 /**
805 * @param AdapterInterface $adapter
806 *
807 * @return AdapterInterface
808 */
809 private function buildAdapter(AdapterInterface $adapter)
810 {
811 return $adapter
812 ->setFollowLinks($this->followLinks)
813 ->setDepths($this->depths)
814 ->setMode($this->mode)
815 ->setExclude($this->exclude)
816 ->setNames($this->names)
817 ->setNotNames($this->notNames)
818 ->setContains($this->contains)
819 ->setNotContains($this->notContains)
820 ->setSizes($this->sizes)
821 ->setDates($this->dates)
822 ->setFilters($this->filters)
7ff1cb6 @gajdaw [Component][Finder] ->path(), ->notPath() methods (with basic tests)
gajdaw authored
823 ->setSort($this->sort)
824 ->setPath($this->paths)
9d55e88 @jfsimon [Finder] added Finder::ignoreUnreadableDirs() method
jfsimon authored
825 ->setNotPath($this->notPaths)
826 ->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
827 }
2feb8d3 @jfsimon [Finder] adds adapter selection/unselection capabilities
jfsimon authored
828
829 /**
830 * Unselects all adapters.
831 */
832 private function resetAdapterSelection()
833 {
834 $this->adapters = array_map(function (array $properties) {
835 $properties['selected'] = false;
836
837 return $properties;
838 }, $this->adapters);
839 }
8e50d17 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
840 }
Something went wrong with that request. Please try again.