Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / symfony / finder / Iterator / RecursiveDirectoryIterator.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Finder\Iterator;
13
14 use Symfony\Component\Finder\Exception\AccessDeniedException;
15 use Symfony\Component\Finder\SplFileInfo;
16
17 /**
18  * Extends the \RecursiveDirectoryIterator to support relative paths.
19  *
20  * @author Victor Berchet <victor@suumit.com>
21  */
22 class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
23 {
24     /**
25      * @var bool
26      */
27     private $ignoreUnreadableDirs;
28
29     /**
30      * @var bool
31      */
32     private $rewindable;
33
34     // these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations
35     private $rootPath;
36     private $subPath;
37     private $directorySeparator = '/';
38
39     /**
40      * @param string $path
41      * @param int    $flags
42      * @param bool   $ignoreUnreadableDirs
43      *
44      * @throws \RuntimeException
45      */
46     public function __construct($path, $flags, $ignoreUnreadableDirs = false)
47     {
48         if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
49             throw new \RuntimeException('This iterator only support returning current as fileinfo.');
50         }
51
52         parent::__construct($path, $flags);
53         $this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
54         $this->rootPath = $path;
55         if ('/' !== \DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) {
56             $this->directorySeparator = \DIRECTORY_SEPARATOR;
57         }
58     }
59
60     /**
61      * Return an instance of SplFileInfo with support for relative paths.
62      *
63      * @return SplFileInfo File information
64      */
65     public function current()
66     {
67         // the logic here avoids redoing the same work in all iterations
68
69         if (null === $subPathname = $this->subPath) {
70             $subPathname = $this->subPath = (string) $this->getSubPath();
71         }
72         if ('' !== $subPathname) {
73             $subPathname .= $this->directorySeparator;
74         }
75         $subPathname .= $this->getFilename();
76
77         return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname);
78     }
79
80     /**
81      * @return \RecursiveIterator
82      *
83      * @throws AccessDeniedException
84      */
85     public function getChildren()
86     {
87         try {
88             $children = parent::getChildren();
89
90             if ($children instanceof self) {
91                 // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore
92                 $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
93
94                 // performance optimization to avoid redoing the same work in all children
95                 $children->rewindable = &$this->rewindable;
96                 $children->rootPath = $this->rootPath;
97             }
98
99             return $children;
100         } catch (\UnexpectedValueException $e) {
101             if ($this->ignoreUnreadableDirs) {
102                 // If directory is unreadable and finder is set to ignore it, a fake empty content is returned.
103                 return new \RecursiveArrayIterator(array());
104             } else {
105                 throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
106             }
107         }
108     }
109
110     /**
111      * Do nothing for non rewindable stream.
112      */
113     public function rewind()
114     {
115         if (false === $this->isRewindable()) {
116             return;
117         }
118
119         // @see https://bugs.php.net/68557
120         if (\PHP_VERSION_ID < 50523 || \PHP_VERSION_ID >= 50600 && \PHP_VERSION_ID < 50607) {
121             parent::next();
122         }
123
124         parent::rewind();
125     }
126
127     /**
128      * Checks if the stream is rewindable.
129      *
130      * @return bool true when the stream is rewindable, false otherwise
131      */
132     public function isRewindable()
133     {
134         if (null !== $this->rewindable) {
135             return $this->rewindable;
136         }
137
138         // workaround for an HHVM bug, should be removed when https://github.com/facebook/hhvm/issues/7281 is fixed
139         if ('' === $this->getPath()) {
140             return $this->rewindable = false;
141         }
142
143         if (false !== $stream = @opendir($this->getPath())) {
144             $infos = stream_get_meta_data($stream);
145             closedir($stream);
146
147             if ($infos['seekable']) {
148                 return $this->rewindable = true;
149             }
150         }
151
152         return $this->rewindable = false;
153     }
154 }