[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/twig/twig/src/Loader/ -> FilesystemLoader.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of Twig.
   5   *
   6   * (c) Fabien Potencier
   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 Twig\Loader;
  13  
  14  use Twig\Error\LoaderError;
  15  use Twig\Source;
  16  
  17  /**
  18   * Loads template from the filesystem.
  19   *
  20   * @author Fabien Potencier <fabien@symfony.com>
  21   */
  22  class FilesystemLoader implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
  23  {
  24      /** Identifier of the main namespace. */
  25      public const MAIN_NAMESPACE = '__main__';
  26  
  27      protected $paths = [];
  28      protected $cache = [];
  29      protected $errorCache = [];
  30  
  31      private $rootPath;
  32  
  33      /**
  34       * @param string|array $paths    A path or an array of paths where to look for templates
  35       * @param string|null  $rootPath The root path common to all relative paths (null for getcwd())
  36       */
  37      public function __construct($paths = [], string $rootPath = null)
  38      {
  39          $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).\DIRECTORY_SEPARATOR;
  40          if (null !== $rootPath && false !== ($realPath = realpath($rootPath))) {
  41              $this->rootPath = $realPath.\DIRECTORY_SEPARATOR;
  42          }
  43  
  44          if ($paths) {
  45              $this->setPaths($paths);
  46          }
  47      }
  48  
  49      /**
  50       * Returns the paths to the templates.
  51       *
  52       * @param string $namespace A path namespace
  53       *
  54       * @return array The array of paths where to look for templates
  55       */
  56      public function getPaths($namespace = self::MAIN_NAMESPACE)
  57      {
  58          return isset($this->paths[$namespace]) ? $this->paths[$namespace] : [];
  59      }
  60  
  61      /**
  62       * Returns the path namespaces.
  63       *
  64       * The main namespace is always defined.
  65       *
  66       * @return array The array of defined namespaces
  67       */
  68      public function getNamespaces()
  69      {
  70          return array_keys($this->paths);
  71      }
  72  
  73      /**
  74       * Sets the paths where templates are stored.
  75       *
  76       * @param string|array $paths     A path or an array of paths where to look for templates
  77       * @param string       $namespace A path namespace
  78       */
  79      public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
  80      {
  81          if (!\is_array($paths)) {
  82              $paths = [$paths];
  83          }
  84  
  85          $this->paths[$namespace] = [];
  86          foreach ($paths as $path) {
  87              $this->addPath($path, $namespace);
  88          }
  89      }
  90  
  91      /**
  92       * Adds a path where templates are stored.
  93       *
  94       * @param string $path      A path where to look for templates
  95       * @param string $namespace A path namespace
  96       *
  97       * @throws LoaderError
  98       */
  99      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');


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1