[ Index ]

PHP Cross Reference of phpBB-3.2.11-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      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 = [], $rootPath = null)
  38      {
  39          $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).\DIRECTORY_SEPARATOR;
  40          if (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 getSource($name)
 140      {
 141          @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
 142  
 143          if (null === ($path = $this->findTemplate($name)) || false === $path) {
 144              return '';
 145          }
 146  
 147          return file_get_contents($path);
 148      }
 149  
 150      public function getSourceContext($name)
 151      {
 152          if (null === ($path = $this->findTemplate($name)) || false === $path) {
 153              return new Source('', $name, '');
 154          }
 155  
 156          return new Source(file_get_contents($path), $name, $path);
 157      }
 158  
 159      public function getCacheKey($name)
 160      {
 161          if (null === ($path = $this->findTemplate($name)) || false === $path) {
 162              return '';
 163          }
 164          $len = \strlen($this->rootPath);
 165          if (0 === strncmp($this->rootPath, $path, $len)) {
 166              return substr($path, $len);
 167          }
 168  
 169          return $path;
 170      }
 171  
 172      public function exists($name)
 173      {
 174          $name = $this->normalizeName($name);
 175  
 176          if (isset($this->cache[$name])) {
 177              return true;
 178          }
 179  
 180          try {
 181              return null !== ($path = $this->findTemplate($name, false)) && false !== $path;
 182          } catch (LoaderError $e) {
 183              @trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', \get_class($this)), E_USER_DEPRECATED);
 184  
 185              return false;
 186          }
 187      }
 188  
 189      public function isFresh($name, $time)
 190      {
 191          // false support to be removed in 3.0
 192          if (null === ($path = $this->findTemplate($name)) || false === $path) {
 193              return false;
 194          }
 195  
 196          return filemtime($path) < $time;
 197      }
 198  
 199      /**
 200       * Checks if the template can be found.
 201       *
 202       * @param string $name The template name
 203       *
 204       * @return string|false|null The template name or false/null
 205       */
 206      protected function findTemplate($name)
 207      {
 208          $throw = \func_num_args() > 1 ? func_get_arg(1) : true;
 209          $name = $this->normalizeName($name);
 210  
 211          if (isset($this->cache[$name])) {
 212              return $this->cache[$name];
 213          }
 214  
 215          if (isset($this->errorCache[$name])) {
 216              if (!$throw) {
 217                  return false;
 218              }
 219  
 220              throw new LoaderError($this->errorCache[$name]);
 221          }
 222  
 223          try {
 224              $this->validateName($name);
 225  
 226              list($namespace, $shortname) = $this->parseName($name);
 227          } catch (LoaderError $e) {
 228              if (!$throw) {
 229                  return false;
 230              }
 231  
 232              throw $e;
 233          }
 234  
 235          if (!isset($this->paths[$namespace])) {
 236              $this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
 237  
 238              if (!$throw) {
 239                  return false;
 240              }
 241  
 242              throw new LoaderError($this->errorCache[$name]);
 243          }
 244  
 245          foreach ($this->paths[$namespace] as $path) {
 246              if (!$this->isAbsolutePath($path)) {
 247                  $path = $this->rootPath.$path;
 248              }
 249  
 250              if (is_file($path.'/'.$shortname)) {
 251                  if (false !== $realpath = realpath($path.'/'.$shortname)) {
 252                      return $this->cache[$name] = $realpath;
 253                  }
 254  
 255                  return $this->cache[$name] = $path.'/'.$shortname;
 256              }
 257          }
 258  
 259          $this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
 260  
 261          if (!$throw) {
 262              return false;
 263          }
 264  
 265          throw new LoaderError($this->errorCache[$name]);
 266      }
 267  
 268      protected function parseName($name, $default = self::MAIN_NAMESPACE)
 269      {
 270          if (isset($name[0]) && '@' == $name[0]) {
 271              if (false === $pos = strpos($name, '/')) {
 272                  throw new LoaderError(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
 273              }
 274  
 275              $namespace = substr($name, 1, $pos - 1);
 276              $shortname = substr($name, $pos + 1);
 277  
 278              return [$namespace, $shortname];
 279          }
 280  
 281          return [$default, $name];
 282      }
 283  
 284      protected function normalizeName($name)
 285      {
 286          return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
 287      }
 288  
 289      protected function validateName($name)
 290      {
 291          if (false !== strpos($name, "\0")) {
 292              throw new LoaderError('A template name cannot contain NUL bytes.');
 293          }
 294  
 295          $name = ltrim($name, '/');
 296          $parts = explode('/', $name);
 297          $level = 0;
 298          foreach ($parts as $part) {
 299              if ('..' === $part) {
 300                  --$level;
 301              } elseif ('.' !== $part) {
 302                  ++$level;
 303              }
 304  
 305              if ($level < 0) {
 306                  throw new LoaderError(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
 307              }
 308          }
 309      }
 310  
 311      private function isAbsolutePath($file)
 312      {
 313          return strspn($file, '/\\', 0, 1)
 314              || (\strlen($file) > 3 && ctype_alpha($file[0])
 315                  && ':' === substr($file, 1, 1)
 316                  && strspn($file, '/\\', 2, 1)
 317              )
 318              || null !== parse_url($file, PHP_URL_SCHEME)
 319          ;
 320      }
 321  }
 322  
 323  class_alias('Twig\Loader\FilesystemLoader', 'Twig_Loader_Filesystem');


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1