[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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');
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |