[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/twig/twig/src/ -> ExtensionSet.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;
  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');


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