[ Index ] |
PHP Cross Reference of phpBB-3.2.11-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 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');
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |