[ Index ]

PHP Cross Reference of phpBB-3.3.7-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          // For BC/FC with namespaced aliases
 153          $class = (new \ReflectionClass($class))->name;
 154          $this->extensions[$class] = $extension;
 155      }
 156  
 157      public function addFunction(TwigFunction $function)
 158      {
 159          if ($this->initialized) {
 160              throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $function->getName()));
 161          }
 162  
 163          $this->staging->addFunction($function);
 164      }
 165  
 166      /**
 167       * @return TwigFunction[]
 168       */
 169      public function getFunctions(): array
 170      {
 171          if (!$this->initialized) {
 172              $this->initExtensions();
 173          }
 174  
 175          return $this->functions;
 176      }
 177  
 178      /**
 179       * @return TwigFunction|false
 180       */
 181      public function getFunction(string $name)
 182      {
 183          if (!$this->initialized) {
 184              $this->initExtensions();
 185          }
 186  
 187          if (isset($this->functions[$name])) {
 188              return $this->functions[$name];
 189          }
 190  
 191          foreach ($this->functions as $pattern => $function) {
 192              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
 193  
 194              if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) {
 195                  array_shift($matches);
 196                  $function->setArguments($matches);
 197  
 198                  return $function;
 199              }
 200          }
 201  
 202          foreach ($this->functionCallbacks as $callback) {
 203              if (false !== $function = $callback($name)) {
 204                  return $function;
 205              }
 206          }
 207  
 208          return false;
 209      }
 210  
 211      public function registerUndefinedFunctionCallback(callable $callable)
 212      {
 213          $this->functionCallbacks[] = $callable;
 214      }
 215  
 216      public function addFilter(TwigFilter $filter)
 217      {
 218          if ($this->initialized) {
 219              throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $filter->getName()));
 220          }
 221  
 222          $this->staging->addFilter($filter);
 223      }
 224  
 225      /**
 226       * @return TwigFilter[]
 227       */
 228      public function getFilters(): array
 229      {
 230          if (!$this->initialized) {
 231              $this->initExtensions();
 232          }
 233  
 234          return $this->filters;
 235      }
 236  
 237      /**
 238       * @return TwigFilter|false
 239       */
 240      public function getFilter(string $name)
 241      {
 242          if (!$this->initialized) {
 243              $this->initExtensions();
 244          }
 245  
 246          if (isset($this->filters[$name])) {
 247              return $this->filters[$name];
 248          }
 249  
 250          foreach ($this->filters as $pattern => $filter) {
 251              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
 252  
 253              if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) {
 254                  array_shift($matches);
 255                  $filter->setArguments($matches);
 256  
 257                  return $filter;
 258              }
 259          }
 260  
 261          foreach ($this->filterCallbacks as $callback) {
 262              if (false !== $filter = $callback($name)) {
 263                  return $filter;
 264              }
 265          }
 266  
 267          return false;
 268      }
 269  
 270      public function registerUndefinedFilterCallback(callable $callable)
 271      {
 272          $this->filterCallbacks[] = $callable;
 273      }
 274  
 275      public function addNodeVisitor(NodeVisitorInterface $visitor)
 276      {
 277          if ($this->initialized) {
 278              throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
 279          }
 280  
 281          $this->staging->addNodeVisitor($visitor);
 282      }
 283  
 284      /**
 285       * @return NodeVisitorInterface[]
 286       */
 287      public function getNodeVisitors(): array
 288      {
 289          if (!$this->initialized) {
 290              $this->initExtensions();
 291          }
 292  
 293          return $this->visitors;
 294      }
 295  
 296      public function addTokenParser(TokenParserInterface $parser)
 297      {
 298          if ($this->initialized) {
 299              throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
 300          }
 301  
 302          $this->staging->addTokenParser($parser);
 303      }
 304  
 305      /**
 306       * @return TokenParserInterface[]
 307       */
 308      public function getTokenParsers(): array
 309      {
 310          if (!$this->initialized) {
 311              $this->initExtensions();
 312          }
 313  
 314          return $this->parsers;
 315      }
 316  
 317      public function getGlobals(): array
 318      {
 319          if (null !== $this->globals) {
 320              return $this->globals;
 321          }
 322  
 323          $globals = [];
 324          foreach ($this->extensions as $extension) {
 325              if (!$extension instanceof GlobalsInterface) {
 326                  continue;
 327              }
 328  
 329              $extGlobals = $extension->getGlobals();
 330              if (!\is_array($extGlobals)) {
 331                  throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension)));
 332              }
 333  
 334              $globals = array_merge($globals, $extGlobals);
 335          }
 336  
 337          if ($this->initialized) {
 338              $this->globals = $globals;
 339          }
 340  
 341          return $globals;
 342      }
 343  
 344      public function addTest(TwigTest $test)
 345      {
 346          if ($this->initialized) {
 347              throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $test->getName()));
 348          }
 349  
 350          $this->staging->addTest($test);
 351      }
 352  
 353      /**
 354       * @return TwigTest[]
 355       */
 356      public function getTests(): array
 357      {
 358          if (!$this->initialized) {
 359              $this->initExtensions();
 360          }
 361  
 362          return $this->tests;
 363      }
 364  
 365      /**
 366       * @return TwigTest|false
 367       */
 368      public function getTest(string $name)
 369      {
 370          if (!$this->initialized) {
 371              $this->initExtensions();
 372          }
 373  
 374          if (isset($this->tests[$name])) {
 375              return $this->tests[$name];
 376          }
 377  
 378          foreach ($this->tests as $pattern => $test) {
 379              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
 380  
 381              if ($count) {
 382                  if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
 383                      array_shift($matches);
 384                      $test->setArguments($matches);
 385  
 386                      return $test;
 387                  }
 388              }
 389          }
 390  
 391          return false;
 392      }
 393  
 394      public function getUnaryOperators(): array
 395      {
 396          if (!$this->initialized) {
 397              $this->initExtensions();
 398          }
 399  
 400          return $this->unaryOperators;
 401      }
 402  
 403      public function getBinaryOperators(): array
 404      {
 405          if (!$this->initialized) {
 406              $this->initExtensions();
 407          }
 408  
 409          return $this->binaryOperators;
 410      }
 411  
 412      private function initExtensions()
 413      {
 414          $this->parsers = [];
 415          $this->filters = [];
 416          $this->functions = [];
 417          $this->tests = [];
 418          $this->visitors = [];
 419          $this->unaryOperators = [];
 420          $this->binaryOperators = [];
 421  
 422          foreach ($this->extensions as $extension) {
 423              $this->initExtension($extension);
 424          }
 425          $this->initExtension($this->staging);
 426          // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception
 427          $this->initialized = true;
 428      }
 429  
 430      private function initExtension(ExtensionInterface $extension)
 431      {
 432          // filters
 433          foreach ($extension->getFilters() as $filter) {
 434              $this->filters[$filter->getName()] = $filter;
 435          }
 436  
 437          // functions
 438          foreach ($extension->getFunctions() as $function) {
 439              $this->functions[$function->getName()] = $function;
 440          }
 441  
 442          // tests
 443          foreach ($extension->getTests() as $test) {
 444              $this->tests[$test->getName()] = $test;
 445          }
 446  
 447          // token parsers
 448          foreach ($extension->getTokenParsers() as $parser) {
 449              if (!$parser instanceof TokenParserInterface) {
 450                  throw new \LogicException('getTokenParsers() must return an array of \Twig\TokenParser\TokenParserInterface.');
 451              }
 452  
 453              $this->parsers[] = $parser;
 454          }
 455  
 456          // node visitors
 457          foreach ($extension->getNodeVisitors() as $visitor) {
 458              $this->visitors[] = $visitor;
 459          }
 460  
 461          // operators
 462          if ($operators = $extension->getOperators()) {
 463              if (!\is_array($operators)) {
 464                  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)));
 465              }
 466  
 467              if (2 !== \count($operators)) {
 468                  throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators)));
 469              }
 470  
 471              $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
 472              $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
 473          }
 474      }
 475  }
 476  
 477  class_alias('Twig\ExtensionSet', 'Twig_ExtensionSet');


Generated: Thu Mar 24 21:31:15 2022 Cross-referenced by PHPXref 0.7.1