vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php line 61

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Finder\Iterator;
  11. use Symfony\Component\Finder\Exception\AccessDeniedException;
  12. use Symfony\Component\Finder\SplFileInfo;
  13. /**
  14.  * Extends the \RecursiveDirectoryIterator to support relative paths.
  15.  *
  16.  * @author Victor Berchet <victor@suumit.com>
  17.  */
  18. class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
  19. {
  20.     /**
  21.      * @var bool
  22.      */
  23.     private $ignoreUnreadableDirs;
  24.     /**
  25.      * @var bool
  26.      */
  27.     private $rewindable;
  28.     // these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations
  29.     private $rootPath;
  30.     private $subPath;
  31.     private $directorySeparator '/';
  32.     /**
  33.      * @throws \RuntimeException
  34.      */
  35.     public function __construct(string $pathint $flagsbool $ignoreUnreadableDirs false)
  36.     {
  37.         if ($flags & (self::CURRENT_AS_PATHNAME self::CURRENT_AS_SELF)) {
  38.             throw new \RuntimeException('This iterator only support returning current as fileinfo.');
  39.         }
  40.         parent::__construct($path$flags);
  41.         $this->ignoreUnreadableDirs $ignoreUnreadableDirs;
  42.         $this->rootPath $path;
  43.         if ('/' !== \DIRECTORY_SEPARATOR && !($flags self::UNIX_PATHS)) {
  44.             $this->directorySeparator = \DIRECTORY_SEPARATOR;
  45.         }
  46.     }
  47.     /**
  48.      * Return an instance of SplFileInfo with support for relative paths.
  49.      *
  50.      * @return SplFileInfo File information
  51.      */
  52.     public function current()
  53.     {
  54.         // the logic here avoids redoing the same work in all iterations
  55.         if (null === $subPathname $this->subPath) {
  56.             $subPathname $this->subPath = (string) $this->getSubPath();
  57.         }
  58.         if ('' !== $subPathname) {
  59.             $subPathname .= $this->directorySeparator;
  60.         }
  61.         $subPathname .= $this->getFilename();
  62.         return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname$this->subPath$subPathname);
  63.     }
  64.     /**
  65.      * @return \RecursiveIterator
  66.      *
  67.      * @throws AccessDeniedException
  68.      */
  69.     public function getChildren()
  70.     {
  71.         try {
  72.             $children parent::getChildren();
  73.             if ($children instanceof self) {
  74.                 // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore
  75.                 $children->ignoreUnreadableDirs $this->ignoreUnreadableDirs;
  76.                 // performance optimization to avoid redoing the same work in all children
  77.                 $children->rewindable = &$this->rewindable;
  78.                 $children->rootPath $this->rootPath;
  79.             }
  80.             return $children;
  81.         } catch (\UnexpectedValueException $e) {
  82.             if ($this->ignoreUnreadableDirs) {
  83.                 // If directory is unreadable and finder is set to ignore it, a fake empty content is returned.
  84.                 return new \RecursiveArrayIterator([]);
  85.             } else {
  86.                 throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
  87.             }
  88.         }
  89.     }
  90.     /**
  91.      * Do nothing for non rewindable stream.
  92.      */
  93.     public function rewind()
  94.     {
  95.         if (false === $this->isRewindable()) {
  96.             return;
  97.         }
  98.         parent::rewind();
  99.     }
  100.     /**
  101.      * Checks if the stream is rewindable.
  102.      *
  103.      * @return bool true when the stream is rewindable, false otherwise
  104.      */
  105.     public function isRewindable()
  106.     {
  107.         if (null !== $this->rewindable) {
  108.             return $this->rewindable;
  109.         }
  110.         if (false !== $stream = @opendir($this->getPath())) {
  111.             $infos stream_get_meta_data($stream);
  112.             closedir($stream);
  113.             if ($infos['seekable']) {
  114.                 return $this->rewindable true;
  115.             }
  116.         }
  117.         return $this->rewindable false;
  118.     }
  119. }