| [ 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; 13 14 use Twig\Error\RuntimeError; 15 use Twig\Extension\ExtensionInterface; 16 use Twig\Extension\GlobalsInterface; 17 use Twig\Extension\InitRuntimeInterface; 18 use Twig\Extension\StagingExtension; 19 use Twig\NodeVisitor\NodeVisitorInterface; 20 use Twig\TokenParser\TokenParserInterface; 21 22 /** 23 * @author Fabien Potencier <fabien@symfony.com> 24 * 25 * @internal 26 */ 27 final class ExtensionSet 28 { 29 private $extensions; 30 private $initialized = false; 31 private $runtimeInitialized = false; 32 private $staging; 33 private $parsers; 34 private $visitors; 35 private $filters; 36 private $tests; 37 private $functions; 38 private $unaryOperators; 39 private $binaryOperators; 40 private $globals; 41 private $functionCallbacks = []; 42 private $filterCallbacks = []; 43 private $lastModified = 0; 44 45 public function __construct() 46 { 47 $this->staging = new StagingExtension(); 48 } 49 50 /** 51 * Initializes the runtime environment. 52 * 53 * @deprecated since Twig 2.7 54 */ 55 public function initRuntime(Environment $env) 56 { 57 if ($this->runtimeInitialized) { 58 return; 59 } 60 61 $this->runtimeInitialized = true; 62 63 foreach ($this->extensions as $extension) { 64 if ($extension instanceof InitRuntimeInterface) { 65 $extension->initRuntime($env); 66 } 67 } 68 } 69 70 public function hasExtension(string $class): bool 71 { 72 $class = ltrim($class, '\\'); 73 if (!isset($this->extensions[$class]) && class_exists($class, false)) { 74 // For BC/FC with namespaced aliases 75 $class = (new \ReflectionClass($class))->name; 76 } 77 78 return isset($this->extensions[$class]); 79 } 80 81 public function getExtension(string $class): ExtensionInterface 82 { 83 $class = ltrim($class, '\\'); 84 if (!isset($this->extensions[$class]) && class_exists($class, false)) { 85 // For BC/FC with namespaced aliases 86 $class = (new \ReflectionClass($class))->name; 87 } 88 89 if (!isset($this->extensions[$class])) { 90 throw new RuntimeError(sprintf('The "%s" extension is not enabled.', $class)); 91 } 92 93 return $this->extensions[$class]; 94 } 95 96 /** 97 * @param ExtensionInterface[] $extensions 98 */ 99 public function setExtensions(array $extensions) 100 { 101 foreach ($extensions as $extension) { 102 $this->addExtension($extension); 103 } 104 } 105 106 /** 107 * @return ExtensionInterface[] 108 */ 109 public function getExtensions(): array 110 { 111 return $this->extensions; 112 } 113 114 public function getSignature(): string 115 { 116 return json_encode(array_keys($this->extensions)); 117 } 118 119 public function isInitialized(): bool 120 { 121 return $this->initialized || $this->runtimeInitialized; 122 } 123 124 public function getLastModified(): int 125 { 126 if (0 !== $this->lastModified) { 127 return $this->lastModified; 128 } 129 130 foreach ($this->extensions as $extension) { 131 $r = new \ReflectionObject($extension); 132 if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModified) { 133 $this->lastModified = $extensionTime; 134 } 135 } 136 137 return $this->lastModified; 138 } 139 140 public function addExtension(ExtensionInterface $extension) 141 { 142 $class = \get_class($extension); 143 144 if ($this->initialized) { 145 throw new \LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $class)); 146 } 147 148 if (isset($this->extensions[$class])) { 149 throw new \LogicException(sprintf('Unable to register extension "%s" as it is already registered.', $class)); 150 } 151 152 $this->extensions[$class] = $extension; 153 } 154 155 public function addFunction(TwigFunction $function) 156 { 157 if ($this->initialized) { 158 throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $function->getName())); 159 } 160 161 $this->staging->addFunction($function); 162 } 163 164 /** 165 * @return TwigFunction[] 166 */ 167 public function getFunctions(): array 168 { 169 if (!$this->initialized) { 170 $this->initExtensions(); 171 } 172 173 return $this->functions; 174 } 175 176 /** 177 * @return TwigFunction|false 178 */ 179 public function getFunction(string $name) 180 { 181 if (!$this->initialized) { 182 $this->initExtensions(); 183 } 184 185 if (isset($this->functions[$name])) { 186 return $this->functions[$name]; 187 } 188 189 foreach ($this->functions as $pattern => $function) { 190 $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); 191 192 if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) { 193 array_shift($matches); 194 $function->setArguments($matches); 195 196 return $function; 197 } 198 } 199 200 foreach ($this->functionCallbacks as $callback) { 201 if (false !== $function = $callback($name)) { 202 return $function; 203 } 204 } 205 206 return false; 207 } 208 209 public function registerUndefinedFunctionCallback(callable $callable) 210 { 211 $this->functionCallbacks[] = $callable; 212 } 213 214 public function addFilter(TwigFilter $filter) 215 { 216 if ($this->initialized) { 217 throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $filter->getName())); 218 } 219 220 $this->staging->addFilter($filter); 221 } 222 223 /** 224 * @return TwigFilter[] 225 */ 226 public function getFilters(): array 227 { 228 if (!$this->initialized) { 229 $this->initExtensions(); 230 } 231 232 return $this->filters; 233 } 234 235 /** 236 * @return TwigFilter|false 237 */ 238 public function getFilter(string $name) 239 { 240 if (!$this->initialized) { 241 $this->initExtensions(); 242 } 243 244 if (isset($this->filters[$name])) { 245 return $this->filters[$name]; 246 } 247 248 foreach ($this->filters as $pattern => $filter) { 249 $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); 250 251 if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) { 252 array_shift($matches); 253 $filter->setArguments($matches); 254 255 return $filter; 256 } 257 } 258 259 foreach ($this->filterCallbacks as $callback) { 260 if (false !== $filter = $callback($name)) { 261 return $filter; 262 } 263 } 264 265 return false; 266 } 267 268 public function registerUndefinedFilterCallback(callable $callable) 269 { 270 $this->filterCallbacks[] = $callable; 271 } 272 273 public function addNodeVisitor(NodeVisitorInterface $visitor) 274 { 275 if ($this->initialized) { 276 throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.'); 277 } 278 279 $this->staging->addNodeVisitor($visitor); 280 } 281 282 /** 283 * @return NodeVisitorInterface[] 284 */ 285 public function getNodeVisitors(): array 286 { 287 if (!$this->initialized) { 288 $this->initExtensions(); 289 } 290 291 return $this->visitors; 292 } 293 294 public function addTokenParser(TokenParserInterface $parser) 295 { 296 if ($this->initialized) { 297 throw new \LogicException('Unable to add a token parser as extensions have already been initialized.'); 298 } 299 300 $this->staging->addTokenParser($parser); 301 } 302 303 /** 304 * @return TokenParserInterface[] 305 */ 306 public function getTokenParsers(): array 307 { 308 if (!$this->initialized) { 309 $this->initExtensions(); 310 } 311 312 return $this->parsers; 313 } 314 315 public function getGlobals(): array 316 { 317 if (null !== $this->globals) { 318 return $this->globals; 319 } 320 321 $globals = []; 322 foreach ($this->extensions as $extension) { 323 if (!$extension instanceof GlobalsInterface) { 324 continue; 325 } 326 327 $extGlobals = $extension->getGlobals(); 328 if (!\is_array($extGlobals)) { 329 throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension))); 330 } 331 332 $globals = array_merge($globals, $extGlobals); 333 } 334 335 if ($this->initialized) { 336 $this->globals = $globals; 337 } 338 339 return $globals; 340 } 341 342 public function addTest(TwigTest $test) 343 { 344 if ($this->initialized) { 345 throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $test->getName())); 346 } 347 348 $this->staging->addTest($test); 349 } 350 351 /** 352 * @return TwigTest[] 353 */ 354 public function getTests(): array 355 { 356 if (!$this->initialized) { 357 $this->initExtensions(); 358 } 359 360 return $this->tests; 361 } 362 363 /** 364 * @return TwigTest|false 365 */ 366 public function getTest(string $name) 367 { 368 if (!$this->initialized) { 369 $this->initExtensions(); 370 } 371 372 if (isset($this->tests[$name])) { 373 return $this->tests[$name]; 374 } 375 376 foreach ($this->tests as $pattern => $test) { 377 $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); 378 379 if ($count) { 380 if (preg_match('#^'.$pattern.'$#', $name, $matches)) { 381 array_shift($matches); 382 $test->setArguments($matches); 383 384 return $test; 385 } 386 } 387 } 388 389 return false; 390 } 391 392 public function getUnaryOperators(): array 393 { 394 if (!$this->initialized) { 395 $this->initExtensions(); 396 } 397 398 return $this->unaryOperators; 399 } 400 401 public function getBinaryOperators(): array 402 { 403 if (!$this->initialized) { 404 $this->initExtensions(); 405 } 406 407 return $this->binaryOperators; 408 } 409 410 private function initExtensions() 411 { 412 $this->parsers = []; 413 $this->filters = []; 414 $this->functions = []; 415 $this->tests = []; 416 $this->visitors = []; 417 $this->unaryOperators = []; 418 $this->binaryOperators = []; 419 420 foreach ($this->extensions as $extension) { 421 $this->initExtension($extension); 422 } 423 $this->initExtension($this->staging); 424 // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception 425 $this->initialized = true; 426 } 427 428 private function initExtension(ExtensionInterface $extension) 429 { 430 // filters 431 foreach ($extension->getFilters() as $filter) { 432 $this->filters[$filter->getName()] = $filter; 433 } 434 435 // functions 436 foreach ($extension->getFunctions() as $function) { 437 $this->functions[$function->getName()] = $function; 438 } 439 440 // tests 441 foreach ($extension->getTests() as $test) { 442 $this->tests[$test->getName()] = $test; 443 } 444 445 // token parsers 446 foreach ($extension->getTokenParsers() as $parser) { 447 if (!$parser instanceof TokenParserInterface) { 448 throw new \LogicException('getTokenParsers() must return an array of \Twig\TokenParser\TokenParserInterface.'); 449 } 450 451 $this->parsers[] = $parser; 452 } 453 454 // node visitors 455 foreach ($extension->getNodeVisitors() as $visitor) { 456 $this->visitors[] = $visitor; 457 } 458 459 // operators 460 if ($operators = $extension->getOperators()) { 461 if (!\is_array($operators)) { 462 throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', \get_class($extension), \is_object($operators) ? \get_class($operators) : \gettype($operators).(\is_resource($operators) ? '' : '#'.$operators))); 463 } 464 465 if (2 !== \count($operators)) { 466 throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators))); 467 } 468 469 $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]); 470 $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]); 471 } 472 } 473 } 474 475 class_alias('Twig\ExtensionSet', 'Twig_ExtensionSet');
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 |