ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
Finder.php
Go to the documentation of this file.
1<?php
2declare(strict_types=1);
3
5
9
17final class Finder implements \IteratorAggregate, \Countable
18{
21
23 private $filesystem;
24
26 private $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg'];
27
29 private $iterators = [];
30
32 protected $dirs = [];
33
35 private $exclude = [];
36
38 private $ignore = 0;
39
42
44 private $reverseSorting = false;
45
47 private $dates = [];
48
50 private $sizes = [];
51
53 private $depths = [];
54
56 private $sort = false;
57
63 {
64 $this->filesystem = $filesystem;
65 $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
66 }
67
71 public function files() : self
72 {
73 $clone = clone $this;
75
76 return $clone;
77 }
78
82 public function directories() : self
83 {
84 $clone = clone $this;
86
87 return $clone;
88 }
89
93 public function allTypes() : self
94 {
95 $clone = clone $this;
97
98 return $clone;
99 }
100
105 public function exclude(array $directories) : self
106 {
107 array_walk($directories, function ($directory) {
108 if (!is_string($directory)) {
109 if (is_object($directory)) {
110 throw new \InvalidArgumentException(sprintf('Invalid directory given: %s', get_class($directory)));
111 }
112
113 throw new \InvalidArgumentException(sprintf('Invalid directory given: %s', gettype($directory)));
114 }
115 });
116
117 $clone = clone $this;
118 $clone->exclude = array_merge($clone->exclude, $directories);
119
120 return $clone;
121 }
122
127 public function in(array $directories) : self
128 {
129 array_walk($directories, function ($directory) {
130 if (!is_string($directory)) {
131 if (is_object($directory)) {
132 throw new \InvalidArgumentException(sprintf('Invalid directory given: %s', get_class($directory)));
133 }
134
135 throw new \InvalidArgumentException(sprintf('Invalid directory given: %s', gettype($directory)));
136 }
137 });
138
139 $clone = clone $this;
140 $clone->dirs = array_unique(array_merge($clone->dirs, $directories));
141
142 return $clone;
143 }
144
157 public function depth($level) : self
158 {
159 $clone = clone $this;
160 $clone->depths[] = new Comparator\NumberComparator((string) $level);
161
162 return $clone;
163 }
164
181 public function date(string $date) : self
182 {
183 $clone = clone $this;
184 $clone->dates[] = new Comparator\DateComparator($date);
185
186 return $clone;
187 }
188
203 public function size($sizes) : self
204 {
205 if (!is_array($sizes)) {
206 $sizes = [$sizes];
207 }
208
209 $clone = clone $this;
210
211 foreach ($sizes as $size) {
212 $clone->sizes[] = new Comparator\NumberComparator((string) $size);
213 }
214
215 return $clone;
216 }
217
221 public function reverseSorting() : self
222 {
223 $clone = clone $this;
224 $clone->reverseSorting = true;
225
226 return $clone;
227 }
228
233 public function ignoreVCS(bool $ignoreVCS) : self
234 {
235 $clone = clone $this;
236 if ($ignoreVCS) {
237 $clone->ignore |= static::IGNORE_VCS_FILES;
238 } else {
239 $clone->ignore &= ~static::IGNORE_VCS_FILES;
240 }
241
242 return $clone;
243 }
244
249 public function addVCSPattern(array $pattern) : self
250 {
251 array_walk($pattern, function ($p) {
252 if (!is_string($p)) {
253 if (is_object($p)) {
254 throw new \InvalidArgumentException(sprintf('Invalid pattern given: %s', get_class($p)));
255 }
256
257 throw new \InvalidArgumentException(sprintf('Invalid pattern given: %s', gettype($p)));
258 }
259 });
260
261 $clone = clone $this;
262 foreach ($pattern as $p) {
263 $clone->vcsPatterns[] = $p;
264 }
265
266 $clone->vcsPatterns = array_unique($clone->vcsPatterns);
267
268 return $clone;
269 }
270
278 public function sort(\Closure $closure) : self
279 {
280 $clone = clone $this;
281 $clone->sort = $closure;
282
283 return $clone;
284 }
285
290 public function sortByName(bool $useNaturalSort = false) : self
291 {
292 $clone = clone $this;
294 if ($useNaturalSort) {
296 }
297
298 return $clone;
299 }
300
304 public function sortByType() : self
305 {
306 $clone = clone $this;
308
309 return $clone;
310 }
311
315 public function sortByTime() : self
316 {
317 $clone = clone $this;
319
320 return $clone;
321 }
322
330 public function append(iterable $iterator) : self
331 {
332 $clone = clone $this;
333
334 if ($iterator instanceof \IteratorAggregate) {
335 $clone->iterators[] = $iterator->getIterator();
336 } elseif ($iterator instanceof \Iterator) {
337 $clone->iterators[] = $iterator;
338 } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
339 $it = new \ArrayIterator();
340 foreach ($iterator as $file) {
341 if ($file instanceof MetadataType) {
342 $it->append($file);
343 } else {
344 throw new \InvalidArgumentException('Finder::append() method wrong argument type in passed iterator.');
345 }
346 }
347 $clone->iterators[] = $it;
348 } else {
349 throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
350 }
351
352 return $clone;
353 }
354
359 private function searchInDirectory(string $dir) : \Iterator
360 {
361 if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
362 $this->exclude = array_merge($this->exclude, $this->vcsPatterns);
363 }
364
365 $iterator = new Iterator\RecursiveDirectoryIterator($this->filesystem, $dir);
366
367 if ($this->exclude) {
368 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
369 }
370
371 $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
372
373 if ($this->depths) {
374 $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->depths);
375 }
376
377 if ($this->mode) {
378 $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
379 }
380
381 if ($this->dates) {
382 $iterator = new Iterator\DateRangeFilterIterator($this->filesystem, $iterator, $this->dates);
383 }
384
385 if ($this->sizes) {
386 $iterator = new Iterator\SizeRangeFilterIterator($this->filesystem, $iterator, $this->sizes);
387 }
388
389 if ($this->sort || $this->reverseSorting) {
390 $iteratorAggregate = new Iterator\SortableIterator(
391 $this->filesystem,
392 $iterator,
393 $this->sort,
394 $this->reverseSorting
395 );
396 $iterator = $iteratorAggregate->getIterator();
397 }
398
399 return $iterator;
400 }
401
406 public function getIterator()
407 {
408 if (0 === count($this->dirs) && 0 === count($this->iterators)) {
409 throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
410 }
411
412 if (1 === count($this->dirs) && 0 === count($this->iterators)) {
413 return $this->searchInDirectory($this->dirs[0]);
414 }
415
416 $iterator = new \AppendIterator();
417 foreach ($this->dirs as $dir) {
418 $iterator->append($this->searchInDirectory($dir));
419 }
420
421 foreach ($this->iterators as $it) {
422 $iterator->append($it);
423 }
424
425 return $iterator;
426 }
427
431 public function count()
432 {
433 return iterator_count($this->getIterator());
434 }
435}
$size
Definition: RandomTest.php:84
An exception for terminatinating execution or to throw for unit testing.
append(iterable $iterator)
Appends an existing set of files/directories to the finder.
Definition: Finder.php:330
searchInDirectory(string $dir)
Definition: Finder.php:359
size($sizes)
Adds tests for file sizes.
Definition: Finder.php:203
__construct(Filesystem $filesystem)
Finder constructor.
Definition: Finder.php:62
exclude(array $directories)
Definition: Finder.php:105
addVCSPattern(array $pattern)
Definition: Finder.php:249
sort(\Closure $closure)
Sorts files and directories by an anonymous function.
Definition: Finder.php:278
ignoreVCS(bool $ignoreVCS)
Definition: Finder.php:233
depth($level)
Adds tests for the directory depth.
Definition: Finder.php:157
in(array $directories)
Definition: Finder.php:127
date(string $date)
Adds tests for file dates.
Definition: Finder.php:181
sortByName(bool $useNaturalSort=false)
Definition: Finder.php:290
Interface Filesystem.
Definition: Filesystem.php:27
Class FlySystemFileAccessTest.