ILIAS  release_7 Revision v7.30-3-g800a261c036
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
155 public function depth($level) : self
156 {
157 $clone = clone $this;
158 $clone->depths[] = new Comparator\NumberComparator((string) $level);
159
160 return $clone;
161 }
162
177 public function date(string $date) : self
178 {
179 $clone = clone $this;
180 $clone->dates[] = new Comparator\DateComparator($date);
181
182 return $clone;
183 }
184
197 public function size($sizes) : self
198 {
199 if (!is_array($sizes)) {
200 $sizes = [$sizes];
201 }
202
203 $clone = clone $this;
204
205 foreach ($sizes as $size) {
206 $clone->sizes[] = new Comparator\NumberComparator((string) $size);
207 }
208
209 return $clone;
210 }
211
215 public function reverseSorting() : self
216 {
217 $clone = clone $this;
218 $clone->reverseSorting = true;
219
220 return $clone;
221 }
222
227 public function ignoreVCS(bool $ignoreVCS) : self
228 {
229 $clone = clone $this;
230 if ($ignoreVCS) {
231 $clone->ignore |= static::IGNORE_VCS_FILES;
232 } else {
233 $clone->ignore &= ~static::IGNORE_VCS_FILES;
234 }
235
236 return $clone;
237 }
238
243 public function addVCSPattern(array $pattern) : self
244 {
245 array_walk($pattern, function ($p) {
246 if (!is_string($p)) {
247 if (is_object($p)) {
248 throw new \InvalidArgumentException(sprintf('Invalid pattern given: %s', get_class($p)));
249 }
250
251 throw new \InvalidArgumentException(sprintf('Invalid pattern given: %s', gettype($p)));
252 }
253 });
254
255 $clone = clone $this;
256 foreach ($pattern as $p) {
257 $clone->vcsPatterns[] = $p;
258 }
259
260 $clone->vcsPatterns = array_unique($clone->vcsPatterns);
261
262 return $clone;
263 }
264
272 public function sort(\Closure $closure) : self
273 {
274 $clone = clone $this;
275 $clone->sort = $closure;
276
277 return $clone;
278 }
279
284 public function sortByName(bool $useNaturalSort = false) : self
285 {
286 $clone = clone $this;
288 if ($useNaturalSort) {
290 }
291
292 return $clone;
293 }
294
298 public function sortByType() : self
299 {
300 $clone = clone $this;
302
303 return $clone;
304 }
305
309 public function sortByTime() : self
310 {
311 $clone = clone $this;
313
314 return $clone;
315 }
316
324 public function append(iterable $iterator) : self
325 {
326 $clone = clone $this;
327
328 if ($iterator instanceof \IteratorAggregate) {
329 $clone->iterators[] = $iterator->getIterator();
330 } elseif ($iterator instanceof \Iterator) {
331 $clone->iterators[] = $iterator;
332 } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
333 $it = new \ArrayIterator();
334 foreach ($iterator as $file) {
335 if ($file instanceof MetadataType) {
336 $it->append($file);
337 } else {
338 throw new \InvalidArgumentException('Finder::append() method wrong argument type in passed iterator.');
339 }
340 }
341 $clone->iterators[] = $it;
342 } else {
343 throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
344 }
345
346 return $clone;
347 }
348
353 private function searchInDirectory(string $dir) : \Iterator
354 {
355 if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES&$this->ignore)) {
356 $this->exclude = array_merge($this->exclude, $this->vcsPatterns);
357 }
358
359 $iterator = new Iterator\RecursiveDirectoryIterator($this->filesystem, $dir);
360
361 if ($this->exclude) {
362 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
363 }
364
365 $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
366
367 if ($this->depths) {
368 $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->depths);
369 }
370
371 if ($this->mode) {
372 $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
373 }
374
375 if ($this->dates) {
376 $iterator = new Iterator\DateRangeFilterIterator($this->filesystem, $iterator, $this->dates);
377 }
378
379 if ($this->sizes) {
380 $iterator = new Iterator\SizeRangeFilterIterator($this->filesystem, $iterator, $this->sizes);
381 }
382
383 if ($this->sort || $this->reverseSorting) {
384 $iteratorAggregate = new Iterator\SortableIterator(
385 $this->filesystem,
386 $iterator,
387 $this->sort,
388 $this->reverseSorting
389 );
390 $iterator = $iteratorAggregate->getIterator();
391 }
392
393 return $iterator;
394 }
395
400 public function getIterator()
401 {
402 if (0 === count($this->dirs) && 0 === count($this->iterators)) {
403 throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
404 }
405
406 if (1 === count($this->dirs) && 0 === count($this->iterators)) {
407 return $this->searchInDirectory($this->dirs[0]);
408 }
409
410 $iterator = new \AppendIterator();
411 foreach ($this->dirs as $dir) {
412 $iterator->append($this->searchInDirectory($dir));
413 }
414
415 foreach ($this->iterators as $it) {
416 $iterator->append($it);
417 }
418
419 return $iterator;
420 }
421
425 public function count()
426 {
427 return iterator_count($this->getIterator());
428 }
429}
$size
Definition: RandomTest.php:84
An exception for terminatinating execution or to throw for unit testing.
Class Metadata This class holds all default metadata send by the filesystem adapters.
Definition: Metadata.php:17
append(iterable $iterator)
Appends an existing set of files/directories to the finder.
Definition: Finder.php:324
searchInDirectory(string $dir)
Definition: Finder.php:353
size($sizes)
Adds tests for file sizes.
Definition: Finder.php:197
__construct(Filesystem $filesystem)
Finder constructor.
Definition: Finder.php:62
exclude(array $directories)
Definition: Finder.php:105
addVCSPattern(array $pattern)
Definition: Finder.php:243
sort(\Closure $closure)
Sorts files and directories by an anonymous function.
Definition: Finder.php:272
ignoreVCS(bool $ignoreVCS)
Definition: Finder.php:227
depth($level)
Adds tests for the directory depth.
Definition: Finder.php:155
in(array $directories)
Definition: Finder.php:127
date(string $date)
Adds tests for file dates.
Definition: Finder.php:177
sortByName(bool $useNaturalSort=false)
Definition: Finder.php:284
Interface Filesystem The filesystem interface provides the public interface for the Filesystem servic...
Definition: Filesystem.php:22
Class MetadataType The possible metadata types of the filesystem metadata.
Class FlySystemFileAccessTest \Provider\FlySystem @runTestsInSeparateProcesses @preserveGlobalState d...