ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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 
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($sizes)
Adds tests for file sizes.
Definition: Finder.php:203
$size
Definition: RandomTest.php:84
depth($level)
Adds tests for the directory depth.
Definition: Finder.php:157
ignoreVCS(bool $ignoreVCS)
Definition: Finder.php:233
__construct(Filesystem $filesystem)
Finder constructor.
Definition: Finder.php:62
addVCSPattern(array $pattern)
Definition: Finder.php:249
sort(\Closure $closure)
Sorts files and directories by an anonymous function.
Definition: Finder.php:278
searchInDirectory(string $dir)
Definition: Finder.php:359
exclude(array $directories)
Definition: Finder.php:105
Class MetadataType.
date(string $date)
Adds tests for file dates.
Definition: Finder.php:181
append(iterable $iterator)
Appends an existing set of files/directories to the finder.
Definition: Finder.php:330
Class FlySystemFileAccessTest.
in(array $directories)
Definition: Finder.php:127
sortByName(bool $useNaturalSort=false)
Definition: Finder.php:290