Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Finder.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 25.21 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\Finder;
 013   
 014  use Symfony\Component\Finder\Adapter\AdapterInterface;
 015  use Symfony\Component\Finder\Adapter\GnuFindAdapter;
 016  use Symfony\Component\Finder\Adapter\BsdFindAdapter;
 017  use Symfony\Component\Finder\Adapter\PhpAdapter;
 018  use Symfony\Component\Finder\Comparator\DateComparator;
 019  use Symfony\Component\Finder\Comparator\NumberComparator;
 020  use Symfony\Component\Finder\Exception\ExceptionInterface;
 021  use Symfony\Component\Finder\Iterator\CustomFilterIterator;
 022  use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
 023  use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
 024  use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
 025  use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
 026  use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
 027  use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
 028  use Symfony\Component\Finder\Iterator\SortableIterator;
 029   
 030  /**
 031   * Finder allows to build rules to find files and directories.
 032   *
 033   * It is a thin wrapper around several specialized iterator classes.
 034   *
 035   * All rules may be invoked several times.
 036   *
 037   * All methods return the current Finder object to allow easy chaining:
 038   *
 039   * $finder = Finder::create()->files()->name('*.php')->in(__DIR__);
 040   *
 041   * @author Fabien Potencier <fabien@symfony.com>
 042   */
 043  class Finder implements \IteratorAggregate, \Countable
 044  {
 045      const IGNORE_VCS_FILES = 1;
 046      const IGNORE_DOT_FILES = 2;
 047   
 048      private $mode = 0;
 049      private $names = array();
 050      private $notNames = array();
 051      private $exclude = array();
 052      private $filters = array();
 053      private $depths = array();
 054      private $sizes = array();
 055      private $followLinks = false;
 056      private $sort = false;
 057      private $ignore = 0;
 058      private $dirs = array();
 059      private $dates = array();
 060      private $iterators = array();
 061      private $contains = array();
 062      private $notContains = array();
 063      private $adapters = null;
 064      private $paths = array();
 065      private $notPaths = array();
 066      private $ignoreUnreadableDirs = false;
 067   
 068      private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
 069   
 070      /**
 071       * Constructor.
 072       */
 073      public function __construct()
 074      {
 075          $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
 076      }
 077   
 078      /**
 079       * Creates a new Finder.
 080       *
 081       * @return Finder A new Finder instance
 082       */
 083      public static function create()
 084      {
 085          return new static();
 086      }
 087   
 088      /**
 089       * Registers a finder engine implementation.
 090       *
 091       * @param AdapterInterface $adapter  An adapter instance
 092       * @param int              $priority Highest is selected first
 093       *
 094       * @return Finder The current Finder instance
 095       *
 096       * @deprecated since 2.8, to be removed in 3.0.
 097       */
 098      public function addAdapter(AdapterInterface $adapter, $priority = 0)
 099      {
 100          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 101   
 102          $this->initDefaultAdapters();
 103   
 104          $this->adapters[$adapter->getName()] = array(
 105              'adapter' => $adapter,
 106              'priority' => $priority,
 107              'selected' => false,
 108          );
 109   
 110          return $this->sortAdapters();
 111      }
 112   
 113      /**
 114       * Sets the selected adapter to the best one according to the current platform the code is run on.
 115       *
 116       * @return Finder The current Finder instance
 117       *
 118       * @deprecated since 2.8, to be removed in 3.0.
 119       */
 120      public function useBestAdapter()
 121      {
 122          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 123   
 124          $this->initDefaultAdapters();
 125   
 126          $this->resetAdapterSelection();
 127   
 128          return $this->sortAdapters();
 129      }
 130   
 131      /**
 132       * Selects the adapter to use.
 133       *
 134       * @param string $name
 135       *
 136       * @return Finder The current Finder instance
 137       *
 138       * @throws \InvalidArgumentException
 139       *
 140       * @deprecated since 2.8, to be removed in 3.0.
 141       */
 142      public function setAdapter($name)
 143      {
 144          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 145   
 146          $this->initDefaultAdapters();
 147   
 148          if (!isset($this->adapters[$name])) {
 149              throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
 150          }
 151   
 152          $this->resetAdapterSelection();
 153          $this->adapters[$name]['selected'] = true;
 154   
 155          return $this->sortAdapters();
 156      }
 157   
 158      /**
 159       * Removes all adapters registered in the finder.
 160       *
 161       * @return Finder The current Finder instance
 162       *
 163       * @deprecated since 2.8, to be removed in 3.0.
 164       */
 165      public function removeAdapters()
 166      {
 167          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 168   
 169          $this->adapters = array();
 170   
 171          return $this;
 172      }
 173   
 174      /**
 175       * Returns registered adapters ordered by priority without extra information.
 176       *
 177       * @return AdapterInterface[]
 178       *
 179       * @deprecated since 2.8, to be removed in 3.0.
 180       */
 181      public function getAdapters()
 182      {
 183          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 184   
 185          $this->initDefaultAdapters();
 186   
 187          return array_values(array_map(function (array $adapter) {
 188              return $adapter['adapter'];
 189          }, $this->adapters));
 190      }
 191   
 192      /**
 193       * Restricts the matching to directories only.
 194       *
 195       * @return Finder|SplFileInfo[] The current Finder instance
 196       */
 197      public function directories()
 198      {
 199          $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
 200   
 201          return $this;
 202      }
 203   
 204      /**
 205       * Restricts the matching to files only.
 206       *
 207       * @return Finder|SplFileInfo[] The current Finder instance
 208       */
 209      public function files()
 210      {
 211          $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
 212   
 213          return $this;
 214      }
 215   
 216      /**
 217       * Adds tests for the directory depth.
 218       *
 219       * Usage:
 220       *
 221       *   $finder->depth('> 1') // the Finder will start matching at level 1.
 222       *   $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
 223       *
 224       * @param int $level The depth level expression
 225       *
 226       * @return Finder|SplFileInfo[] The current Finder instance
 227       *
 228       * @see DepthRangeFilterIterator
 229       * @see NumberComparator
 230       */
 231      public function depth($level)
 232      {
 233          $this->depths[] = new Comparator\NumberComparator($level);
 234   
 235          return $this;
 236      }
 237   
 238      /**
 239       * Adds tests for file dates (last modified).
 240       *
 241       * The date must be something that strtotime() is able to parse:
 242       *
 243       *   $finder->date('since yesterday');
 244       *   $finder->date('until 2 days ago');
 245       *   $finder->date('> now - 2 hours');
 246       *   $finder->date('>= 2005-10-15');
 247       *
 248       * @param string $date A date range string
 249       *
 250       * @return Finder|SplFileInfo[] The current Finder instance
 251       *
 252       * @see strtotime
 253       * @see DateRangeFilterIterator
 254       * @see DateComparator
 255       */
 256      public function date($date)
 257      {
 258          $this->dates[] = new Comparator\DateComparator($date);
 259   
 260          return $this;
 261      }
 262   
 263      /**
 264       * Adds rules that files must match.
 265       *
 266       * You can use patterns (delimited with / sign), globs or simple strings.
 267       *
 268       * $finder->name('*.php')
 269       * $finder->name('/\.php$/') // same as above
 270       * $finder->name('test.php')
 271       *
 272       * @param string $pattern A pattern (a regexp, a glob, or a string)
 273       *
 274       * @return Finder|SplFileInfo[] The current Finder instance
 275       *
 276       * @see FilenameFilterIterator
 277       */
 278      public function name($pattern)
 279      {
 280          $this->names[] = $pattern;
 281   
 282          return $this;
 283      }
 284   
 285      /**
 286       * Adds rules that files must not match.
 287       *
 288       * @param string $pattern A pattern (a regexp, a glob, or a string)
 289       *
 290       * @return Finder|SplFileInfo[] The current Finder instance
 291       *
 292       * @see FilenameFilterIterator
 293       */
 294      public function notName($pattern)
 295      {
 296          $this->notNames[] = $pattern;
 297   
 298          return $this;
 299      }
 300   
 301      /**
 302       * Adds tests that file contents must match.
 303       *
 304       * Strings or PCRE patterns can be used:
 305       *
 306       * $finder->contains('Lorem ipsum')
 307       * $finder->contains('/Lorem ipsum/i')
 308       *
 309       * @param string $pattern A pattern (string or regexp)
 310       *
 311       * @return Finder|SplFileInfo[] The current Finder instance
 312       *
 313       * @see FilecontentFilterIterator
 314       */
 315      public function contains($pattern)
 316      {
 317          $this->contains[] = $pattern;
 318   
 319          return $this;
 320      }
 321   
 322      /**
 323       * Adds tests that file contents must not match.
 324       *
 325       * Strings or PCRE patterns can be used:
 326       *
 327       * $finder->notContains('Lorem ipsum')
 328       * $finder->notContains('/Lorem ipsum/i')
 329       *
 330       * @param string $pattern A pattern (string or regexp)
 331       *
 332       * @return Finder|SplFileInfo[] The current Finder instance
 333       *
 334       * @see FilecontentFilterIterator
 335       */
 336      public function notContains($pattern)
 337      {
 338          $this->notContains[] = $pattern;
 339   
 340          return $this;
 341      }
 342   
 343      /**
 344       * Adds rules that filenames must match.
 345       *
 346       * You can use patterns (delimited with / sign) or simple strings.
 347       *
 348       * $finder->path('some/special/dir')
 349       * $finder->path('/some\/special\/dir/') // same as above
 350       *
 351       * Use only / as dirname separator.
 352       *
 353       * @param string $pattern A pattern (a regexp or a string)
 354       *
 355       * @return Finder|SplFileInfo[] The current Finder instance
 356       *
 357       * @see FilenameFilterIterator
 358       */
 359      public function path($pattern)
 360      {
 361          $this->paths[] = $pattern;
 362   
 363          return $this;
 364      }
 365   
 366      /**
 367       * Adds rules that filenames must not match.
 368       *
 369       * You can use patterns (delimited with / sign) or simple strings.
 370       *
 371       * $finder->notPath('some/special/dir')
 372       * $finder->notPath('/some\/special\/dir/') // same as above
 373       *
 374       * Use only / as dirname separator.
 375       *
 376       * @param string $pattern A pattern (a regexp or a string)
 377       *
 378       * @return Finder|SplFileInfo[] The current Finder instance
 379       *
 380       * @see FilenameFilterIterator
 381       */
 382      public function notPath($pattern)
 383      {
 384          $this->notPaths[] = $pattern;
 385   
 386          return $this;
 387      }
 388   
 389      /**
 390       * Adds tests for file sizes.
 391       *
 392       * $finder->size('> 10K');
 393       * $finder->size('<= 1Ki');
 394       * $finder->size(4);
 395       *
 396       * @param string $size A size range string
 397       *
 398       * @return Finder|SplFileInfo[] The current Finder instance
 399       *
 400       * @see SizeRangeFilterIterator
 401       * @see NumberComparator
 402       */
 403      public function size($size)
 404      {
 405          $this->sizes[] = new Comparator\NumberComparator($size);
 406   
 407          return $this;
 408      }
 409   
 410      /**
 411       * Excludes directories.
 412       *
 413       * @param string|array $dirs A directory path or an array of directories
 414       *
 415       * @return Finder|SplFileInfo[] The current Finder instance
 416       *
 417       * @see ExcludeDirectoryFilterIterator
 418       */
 419      public function exclude($dirs)
 420      {
 421          $this->exclude = array_merge($this->exclude, (array) $dirs);
 422   
 423          return $this;
 424      }
 425   
 426      /**
 427       * Excludes "hidden" directories and files (starting with a dot).
 428       *
 429       * @param bool $ignoreDotFiles Whether to exclude "hidden" files or not
 430       *
 431       * @return Finder|SplFileInfo[] The current Finder instance
 432       *
 433       * @see ExcludeDirectoryFilterIterator
 434       */
 435      public function ignoreDotFiles($ignoreDotFiles)
 436      {
 437          if ($ignoreDotFiles) {
 438              $this->ignore |= static::IGNORE_DOT_FILES;
 439          } else {
 440              $this->ignore &= ~static::IGNORE_DOT_FILES;
 441          }
 442   
 443          return $this;
 444      }
 445   
 446      /**
 447       * Forces the finder to ignore version control directories.
 448       *
 449       * @param bool $ignoreVCS Whether to exclude VCS files or not
 450       *
 451       * @return Finder|SplFileInfo[] The current Finder instance
 452       *
 453       * @see ExcludeDirectoryFilterIterator
 454       */
 455      public function ignoreVCS($ignoreVCS)
 456      {
 457          if ($ignoreVCS) {
 458              $this->ignore |= static::IGNORE_VCS_FILES;
 459          } else {
 460              $this->ignore &= ~static::IGNORE_VCS_FILES;
 461          }
 462   
 463          return $this;
 464      }
 465   
 466      /**
 467       * Adds VCS patterns.
 468       *
 469       * @see ignoreVCS()
 470       *
 471       * @param string|string[] $pattern VCS patterns to ignore
 472       */
 473      public static function addVCSPattern($pattern)
 474      {
 475          foreach ((array) $pattern as $p) {
 476              self::$vcsPatterns[] = $p;
 477          }
 478   
 479          self::$vcsPatterns = array_unique(self::$vcsPatterns);
 480      }
 481   
 482      /**
 483       * Sorts files and directories by an anonymous function.
 484       *
 485       * The anonymous function receives two \SplFileInfo instances to compare.
 486       *
 487       * This can be slow as all the matching files and directories must be retrieved for comparison.
 488       *
 489       * @param \Closure $closure An anonymous function
 490       *
 491       * @return Finder|SplFileInfo[] The current Finder instance
 492       *
 493       * @see SortableIterator
 494       */
 495      public function sort(\Closure $closure)
 496      {
 497          $this->sort = $closure;
 498   
 499          return $this;
 500      }
 501   
 502      /**
 503       * Sorts files and directories by name.
 504       *
 505       * This can be slow as all the matching files and directories must be retrieved for comparison.
 506       *
 507       * @return Finder|SplFileInfo[] The current Finder instance
 508       *
 509       * @see SortableIterator
 510       */
 511      public function sortByName()
 512      {
 513          $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
 514   
 515          return $this;
 516      }
 517   
 518      /**
 519       * Sorts files and directories by type (directories before files), then by name.
 520       *
 521       * This can be slow as all the matching files and directories must be retrieved for comparison.
 522       *
 523       * @return Finder|SplFileInfo[] The current Finder instance
 524       *
 525       * @see SortableIterator
 526       */
 527      public function sortByType()
 528      {
 529          $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
 530   
 531          return $this;
 532      }
 533   
 534      /**
 535       * Sorts files and directories by the last accessed time.
 536       *
 537       * This is the time that the file was last accessed, read or written to.
 538       *
 539       * This can be slow as all the matching files and directories must be retrieved for comparison.
 540       *
 541       * @return Finder|SplFileInfo[] The current Finder instance
 542       *
 543       * @see SortableIterator
 544       */
 545      public function sortByAccessedTime()
 546      {
 547          $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
 548   
 549          return $this;
 550      }
 551   
 552      /**
 553       * Sorts files and directories by the last inode changed time.
 554       *
 555       * This is the time that the inode information was last modified (permissions, owner, group or other metadata).
 556       *
 557       * On Windows, since inode is not available, changed time is actually the file creation time.
 558       *
 559       * This can be slow as all the matching files and directories must be retrieved for comparison.
 560       *
 561       * @return Finder|SplFileInfo[] The current Finder instance
 562       *
 563       * @see SortableIterator
 564       */
 565      public function sortByChangedTime()
 566      {
 567          $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
 568   
 569          return $this;
 570      }
 571   
 572      /**
 573       * Sorts files and directories by the last modified time.
 574       *
 575       * This is the last time the actual contents of the file were last modified.
 576       *
 577       * This can be slow as all the matching files and directories must be retrieved for comparison.
 578       *
 579       * @return Finder|SplFileInfo[] The current Finder instance
 580       *
 581       * @see SortableIterator
 582       */
 583      public function sortByModifiedTime()
 584      {
 585          $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
 586   
 587          return $this;
 588      }
 589   
 590      /**
 591       * Filters the iterator with an anonymous function.
 592       *
 593       * The anonymous function receives a \SplFileInfo and must return false
 594       * to remove files.
 595       *
 596       * @param \Closure $closure An anonymous function
 597       *
 598       * @return Finder|SplFileInfo[] The current Finder instance
 599       *
 600       * @see CustomFilterIterator
 601       */
 602      public function filter(\Closure $closure)
 603      {
 604          $this->filters[] = $closure;
 605   
 606          return $this;
 607      }
 608   
 609      /**
 610       * Forces the following of symlinks.
 611       *
 612       * @return Finder|SplFileInfo[] The current Finder instance
 613       */
 614      public function followLinks()
 615      {
 616          $this->followLinks = true;
 617   
 618          return $this;
 619      }
 620   
 621      /**
 622       * Tells finder to ignore unreadable directories.
 623       *
 624       * By default, scanning unreadable directories content throws an AccessDeniedException.
 625       *
 626       * @param bool $ignore
 627       *
 628       * @return Finder|SplFileInfo[] The current Finder instance
 629       */
 630      public function ignoreUnreadableDirs($ignore = true)
 631      {
 632          $this->ignoreUnreadableDirs = (bool) $ignore;
 633   
 634          return $this;
 635      }
 636   
 637      /**
 638       * Searches files and directories which match defined rules.
 639       *
 640       * @param string|array $dirs A directory path or an array of directories
 641       *
 642       * @return Finder|SplFileInfo[] The current Finder instance
 643       *
 644       * @throws \InvalidArgumentException if one of the directories does not exist
 645       */
 646      public function in($dirs)
 647      {
 648          $resolvedDirs = array();
 649   
 650          foreach ((array) $dirs as $dir) {
 651              if (is_dir($dir)) {
 652                  $resolvedDirs[] = $dir;
 653              } elseif ($glob = glob($dir, (defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR)) {
 654                  $resolvedDirs = array_merge($resolvedDirs, $glob);
 655              } else {
 656                  throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
 657              }
 658          }
 659   
 660          $this->dirs = array_merge($this->dirs, $resolvedDirs);
 661   
 662          return $this;
 663      }
 664   
 665      /**
 666       * Returns an Iterator for the current Finder configuration.
 667       *
 668       * This method implements the IteratorAggregate interface.
 669       *
 670       * @return \Iterator|SplFileInfo[] An iterator
 671       *
 672       * @throws \LogicException if the in() method has not been called
 673       */
 674      public function getIterator()
 675      {
 676          if (0 === count($this->dirs) && 0 === count($this->iterators)) {
 677              throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
 678          }
 679   
 680          if (1 === count($this->dirs) && 0 === count($this->iterators)) {
 681              return $this->searchInDirectory($this->dirs[0]);
 682          }
 683   
 684          $iterator = new \AppendIterator();
 685          foreach ($this->dirs as $dir) {
 686              $iterator->append($this->searchInDirectory($dir));
 687          }
 688   
 689          foreach ($this->iterators as $it) {
 690              $iterator->append($it);
 691          }
 692   
 693          return $iterator;
 694      }
 695   
 696      /**
 697       * Appends an existing set of files/directories to the finder.
 698       *
 699       * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array.
 700       *
 701       * @param mixed $iterator
 702       *
 703       * @return Finder|SplFileInfo[] The finder
 704       *
 705       * @throws \InvalidArgumentException When the given argument is not iterable.
 706       */
 707      public function append($iterator)
 708      {
 709          if ($iterator instanceof \IteratorAggregate) {
 710              $this->iterators[] = $iterator->getIterator();
 711          } elseif ($iterator instanceof \Iterator) {
 712              $this->iterators[] = $iterator;
 713          } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
 714              $it = new \ArrayIterator();
 715              foreach ($iterator as $file) {
 716                  $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
 717              }
 718              $this->iterators[] = $it;
 719          } else {
 720              throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
 721          }
 722   
 723          return $this;
 724      }
 725   
 726      /**
 727       * Counts all the results collected by the iterators.
 728       *
 729       * @return int
 730       */
 731      public function count()
 732      {
 733          return iterator_count($this->getIterator());
 734      }
 735   
 736      /**
 737       * @return Finder The current Finder instance
 738       */
 739      private function sortAdapters()
 740      {
 741          uasort($this->adapters, function (array $a, array $b) {
 742              if ($a['selected'] || $b['selected']) {
 743                  return $a['selected'] ? -1 : 1;
 744              }
 745   
 746              return $a['priority'] > $b['priority'] ? -1 : 1;
 747          });
 748   
 749          return $this;
 750      }
 751   
 752      /**
 753       * @param $dir
 754       *
 755       * @return \Iterator
 756       */
 757      private function searchInDirectory($dir)
 758      {
 759          if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
 760              $this->exclude = array_merge($this->exclude, self::$vcsPatterns);
 761          }
 762   
 763          if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
 764              $this->notPaths[] = '#(^|/)\..+(/|$)#';
 765          }
 766   
 767          if ($this->adapters) {
 768              foreach ($this->adapters as $adapter) {
 769                  if ($adapter['adapter']->isSupported()) {
 770                      try {
 771                          return $this
 772                              ->buildAdapter($adapter['adapter'])
 773                              ->searchInDirectory($dir);
 774                      } catch (ExceptionInterface $e) {
 775                      }
 776                  }
 777              }
 778          }
 779   
 780          $minDepth = 0;
 781          $maxDepth = PHP_INT_MAX;
 782   
 783          foreach ($this->depths as $comparator) {
 784              switch ($comparator->getOperator()) {
 785                  case '>':
 786                      $minDepth = $comparator->getTarget() + 1;
 787                      break;
 788                  case '>=':
 789                      $minDepth = $comparator->getTarget();
 790                      break;
 791                  case '<':
 792                      $maxDepth = $comparator->getTarget() - 1;
 793                      break;
 794                  case '<=':
 795                      $maxDepth = $comparator->getTarget();
 796                      break;
 797                  default:
 798                      $minDepth = $maxDepth = $comparator->getTarget();
 799              }
 800          }
 801   
 802          $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
 803   
 804          if ($this->followLinks) {
 805              $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
 806          }
 807   
 808          $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);
 809   
 810          if ($this->exclude) {
 811              $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
 812          }
 813   
 814          $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
 815   
 816          if ($minDepth > 0 || $maxDepth < PHP_INT_MAX) {
 817              $iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth);
 818          }
 819   
 820          if ($this->mode) {
 821              $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
 822          }
 823   
 824          if ($this->names || $this->notNames) {
 825              $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
 826          }
 827   
 828          if ($this->contains || $this->notContains) {
 829              $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
 830          }
 831   
 832          if ($this->sizes) {
 833              $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
 834          }
 835   
 836          if ($this->dates) {
 837              $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
 838          }
 839   
 840          if ($this->filters) {
 841              $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
 842          }
 843   
 844          if ($this->paths || $this->notPaths) {
 845              $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
 846          }
 847   
 848          if ($this->sort) {
 849              $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
 850              $iterator = $iteratorAggregate->getIterator();
 851          }
 852   
 853          return $iterator;
 854      }
 855   
 856      /**
 857       * @param AdapterInterface $adapter
 858       *
 859       * @return AdapterInterface
 860       */
 861      private function buildAdapter(AdapterInterface $adapter)
 862      {
 863          return $adapter
 864              ->setFollowLinks($this->followLinks)
 865              ->setDepths($this->depths)
 866              ->setMode($this->mode)
 867              ->setExclude($this->exclude)
 868              ->setNames($this->names)
 869              ->setNotNames($this->notNames)
 870              ->setContains($this->contains)
 871              ->setNotContains($this->notContains)
 872              ->setSizes($this->sizes)
 873              ->setDates($this->dates)
 874              ->setFilters($this->filters)
 875              ->setSort($this->sort)
 876              ->setPath($this->paths)
 877              ->setNotPath($this->notPaths)
 878              ->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
 879      }
 880   
 881      /**
 882       * Unselects all adapters.
 883       */
 884      private function resetAdapterSelection()
 885      {
 886          $this->adapters = array_map(function (array $properties) {
 887              $properties['selected'] = false;
 888   
 889              return $properties;
 890          }, $this->adapters);
 891      }
 892   
 893      private function initDefaultAdapters()
 894      {
 895          if (null === $this->adapters) {
 896              $this->adapters = array();
 897              $this
 898                  ->addAdapter(new GnuFindAdapter())
 899                  ->addAdapter(new BsdFindAdapter())
 900                  ->addAdapter(new PhpAdapter(), -50)
 901                  ->setAdapter('php')
 902              ;
 903          }
 904      }
 905  }
 906