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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

FilesystemLoader.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 8.62 KiB


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