Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
FilesystemLoader.php
001 <?php
002
003 /*
004 * This file is part of Twig.
005 *
006 * (c) Fabien Potencier
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 Twig\Loader;
013
014 use Twig\Error\LoaderError;
015 use Twig\Source;
016
017 /**
018 * Loads template from the filesystem.
019 *
020 * @author Fabien Potencier <fabien@symfony.com>
021 */
022 class FilesystemLoader implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
023 {
024 /** Identifier of the main namespace. */
025 public const MAIN_NAMESPACE = '__main__';
026
027 protected $paths = [];
028 protected $cache = [];
029 protected $errorCache = [];
030
031 private $rootPath;
032
033 /**
034 * @param string|array $paths A path or an array of paths where to look for templates
035 * @param string|null $rootPath The root path common to all relative paths (null for getcwd())
036 */
037 public function __construct($paths = [], string $rootPath = null)
038 {
039 $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).\DIRECTORY_SEPARATOR;
040 if (null !== $rootPath && false !== ($realPath = realpath($rootPath))) {
041 $this->rootPath = $realPath.\DIRECTORY_SEPARATOR;
042 }
043
044 if ($paths) {
045 $this->setPaths($paths);
046 }
047 }
048
049 /**
050 * Returns the paths to the templates.
051 *
052 * @param string $namespace A path namespace
053 *
054 * @return array The array of paths where to look for templates
055 */
056 public function getPaths($namespace = self::MAIN_NAMESPACE)
057 {
058 return isset($this->paths[$namespace]) ? $this->paths[$namespace] : [];
059 }
060
061 /**
062 * Returns the path namespaces.
063 *
064 * The main namespace is always defined.
065 *
066 * @return array The array of defined namespaces
067 */
068 public function getNamespaces()
069 {
070 return array_keys($this->paths);
071 }
072
073 /**
074 * Sets the paths where templates are stored.
075 *
076 * @param string|array $paths A path or an array of paths where to look for templates
077 * @param string $namespace A path namespace
078 */
079 public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
080 {
081 if (!\is_array($paths)) {
082 $paths = [$paths];
083 }
084
085 $this->paths[$namespace] = [];
086 foreach ($paths as $path) {
087 $this->addPath($path, $namespace);
088 }
089 }
090
091 /**
092 * Adds a path where templates are stored.
093 *
094 * @param string $path A path where to look for templates
095 * @param string $namespace A path namespace
096 *
097 * @throws LoaderError
098 */
099 public function addPath($path, $namespace = self::MAIN_NAMESPACE)
100 {
101 // invalidate the cache
102 $this->cache = $this->errorCache = [];
103
104 $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
105 if (!is_dir($checkPath)) {
106 throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
107 }
108
109 $this->paths[$namespace][] = rtrim($path, '/\\');
110 }
111
112 /**
113 * Prepends a path where templates are stored.
114 *
115 * @param string $path A path where to look for templates
116 * @param string $namespace A path namespace
117 *
118 * @throws LoaderError
119 */
120 public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
121 {
122 // invalidate the cache
123 $this->cache = $this->errorCache = [];
124
125 $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
126 if (!is_dir($checkPath)) {
127 throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
128 }
129
130 $path = rtrim($path, '/\\');
131
132 if (!isset($this->paths[$namespace])) {
133 $this->paths[$namespace][] = $path;
134 } else {
135 array_unshift($this->paths[$namespace], $path);
136 }
137 }
138
139 public function getSourceContext($name)
140 {
141 if (null === ($path = $this->findTemplate($name)) || false === $path) {
142 return new Source('', $name, '');
143 }
144
145 return new Source(file_get_contents($path), $name, $path);
146 }
147
148 public function getCacheKey($name)
149 {
150 if (null === ($path = $this->findTemplate($name)) || false === $path) {
151 return '';
152 }
153 $len = \strlen($this->rootPath);
154 if (0 === strncmp($this->rootPath, $path, $len)) {
155 return substr($path, $len);
156 }
157
158 return $path;
159 }
160
161 public function exists($name)
162 {
163 $name = $this->normalizeName($name);
164
165 if (isset($this->cache[$name])) {
166 return true;
167 }
168
169 return null !== ($path = $this->findTemplate($name, false)) && false !== $path;
170 }
171
172 public function isFresh($name, $time)
173 {
174 // false support to be removed in 3.0
175 if (null === ($path = $this->findTemplate($name)) || false === $path) {
176 return false;
177 }
178
179 return filemtime($path) < $time;
180 }
181
182 /**
183 * Checks if the template can be found.
184 *
185 * In Twig 3.0, findTemplate must return a string or null (returning false won't work anymore).
186 *
187 * @param string $name The template name
188 * @param bool $throw Whether to throw an exception when an error occurs
189 *
190 * @return string|false|null The template name or false/null
191 */
192 protected function findTemplate($name, $throw = true)
193 {
194 $name = $this->normalizeName($name);
195
196 if (isset($this->cache[$name])) {
197 return $this->cache[$name];
198 }
199
200 if (isset($this->errorCache[$name])) {
201 if (!$throw) {
202 return false;
203 }
204
205 throw new LoaderError($this->errorCache[$name]);
206 }
207
208 try {
209 list($namespace, $shortname) = $this->parseName($name);
210
211 $this->validateName($shortname);
212 } catch (LoaderError $e) {
213 if (!$throw) {
214 return false;
215 }
216
217 throw $e;
218 }
219
220 if (!isset($this->paths[$namespace])) {
221 $this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
222
223 if (!$throw) {
224 return false;
225 }
226
227 throw new LoaderError($this->errorCache[$name]);
228 }
229
230 foreach ($this->paths[$namespace] as $path) {
231 if (!$this->isAbsolutePath($path)) {
232 $path = $this->rootPath.$path;
233 }
234
235 if (is_file($path.'/'.$shortname)) {
236 if (false !== $realpath = realpath($path.'/'.$shortname)) {
237 return $this->cache[$name] = $realpath;
238 }
239
240 return $this->cache[$name] = $path.'/'.$shortname;
241 }
242 }
243
244 $this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
245
246 if (!$throw) {
247 return false;
248 }
249
250 throw new LoaderError($this->errorCache[$name]);
251 }
252
253 private function normalizeName($name)
254 {
255 return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
256 }
257
258 private function parseName($name, $default = self::MAIN_NAMESPACE)
259 {
260 if (isset($name[0]) && '@' == $name[0]) {
261 if (false === $pos = strpos($name, '/')) {
262 throw new LoaderError(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
263 }
264
265 $namespace = substr($name, 1, $pos - 1);
266 $shortname = substr($name, $pos + 1);
267
268 return [$namespace, $shortname];
269 }
270
271 return [$default, $name];
272 }
273
274 private function validateName($name)
275 {
276 if (false !== strpos($name, "\0")) {
277 throw new LoaderError('A template name cannot contain NUL bytes.');
278 }
279
280 $name = ltrim($name, '/');
281 $parts = explode('/', $name);
282 $level = 0;
283 foreach ($parts as $part) {
284 if ('..' === $part) {
285 --$level;
286 } elseif ('.' !== $part) {
287 ++$level;
288 }
289
290 if ($level < 0) {
291 throw new LoaderError(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
292 }
293 }
294 }
295
296 private function isAbsolutePath($file)
297 {
298 return strspn($file, '/\\', 0, 1)
299 || (\strlen($file) > 3 && ctype_alpha($file[0])
300 && ':' === $file[1]
301 && strspn($file, '/\\', 2, 1)
302 )
303 || null !== parse_url($file, \PHP_URL_SCHEME)
304 ;
305 }
306 }
307
308 class_alias('Twig\Loader\FilesystemLoader', 'Twig_Loader_Filesystem');
309