ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
Finder.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types=1);
3 
5 
9 
17 final class Finder implements \IteratorAggregate, \Countable
18 {
19  const IGNORE_VCS_FILES = 1;
20  const IGNORE_DOT_FILES = 2;
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($sizes)
Adds tests for file sizes.
Definition: Finder.php:197
$size
Definition: RandomTest.php:84
depth($level)
Adds tests for the directory depth.
Definition: Finder.php:155
ignoreVCS(bool $ignoreVCS)
Definition: Finder.php:227
__construct(Filesystem $filesystem)
Finder constructor.
Definition: Finder.php:62
addVCSPattern(array $pattern)
Definition: Finder.php:243
sort(\Closure $closure)
Sorts files and directories by an anonymous function.
Definition: Finder.php:272
searchInDirectory(string $dir)
Definition: Finder.php:353
exclude(array $directories)
Definition: Finder.php:105
Class MetadataType The possible metadata types of the filesystem metadata.
date(string $date)
Adds tests for file dates.
Definition: Finder.php:177
append(iterable $iterator)
Appends an existing set of files/directories to the finder.
Definition: Finder.php:324
Class FlySystemFileAccessTest disabled disabled disabled.
in(array $directories)
Definition: Finder.php:127
sortByName(bool $useNaturalSort=false)
Definition: Finder.php:284