[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/twig/twig/src/ -> Environment.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\Cache\CacheInterface;
  15  use Twig\Cache\FilesystemCache;
  16  use Twig\Cache\NullCache;
  17  use Twig\Error\Error;
  18  use Twig\Error\LoaderError;
  19  use Twig\Error\RuntimeError;
  20  use Twig\Error\SyntaxError;
  21  use Twig\Extension\CoreExtension;
  22  use Twig\Extension\EscaperExtension;
  23  use Twig\Extension\ExtensionInterface;
  24  use Twig\Extension\OptimizerExtension;
  25  use Twig\Loader\ArrayLoader;
  26  use Twig\Loader\ChainLoader;
  27  use Twig\Loader\LoaderInterface;
  28  use Twig\Node\ModuleNode;
  29  use Twig\Node\Node;
  30  use Twig\NodeVisitor\NodeVisitorInterface;
  31  use Twig\RuntimeLoader\RuntimeLoaderInterface;
  32  use Twig\TokenParser\TokenParserInterface;
  33  
  34  /**
  35   * Stores the Twig configuration and renders templates.
  36   *
  37   * @author Fabien Potencier <fabien@symfony.com>
  38   */
  39  class Environment
  40  {
  41      public const VERSION = '2.16.0';
  42      public const VERSION_ID = 21600;
  43      public const MAJOR_VERSION = 2;
  44      public const MINOR_VERSION = 16;
  45      public const RELEASE_VERSION = 0;
  46      public const EXTRA_VERSION = '';
  47  
  48      private $charset;
  49      private $loader;
  50      private $debug;
  51      private $autoReload;
  52      private $cache;
  53      private $lexer;
  54      private $parser;
  55      private $compiler;
  56      private $baseTemplateClass;
  57      private $globals = [];
  58      private $resolvedGlobals;
  59      private $loadedTemplates;
  60      private $strictVariables;
  61      private $templateClassPrefix = '__TwigTemplate_';
  62      private $originalCache;
  63      private $extensionSet;
  64      private $runtimeLoaders = [];
  65      private $runtimes = [];
  66      private $optionsHash;
  67  
  68      /**
  69       * Constructor.
  70       *
  71       * Available options:
  72       *
  73       *  * debug: When set to true, it automatically set "auto_reload" to true as
  74       *           well (default to false).
  75       *
  76       *  * charset: The charset used by the templates (default to UTF-8).
  77       *
  78       *  * base_template_class: The base template class to use for generated
  79       *                         templates (default to \Twig\Template).
  80       *
  81       *  * cache: An absolute path where to store the compiled templates,
  82       *           a \Twig\Cache\CacheInterface implementation,
  83       *           or false to disable compilation cache (default).
  84       *
  85       *  * auto_reload: Whether to reload the template if the original source changed.
  86       *                 If you don't provide the auto_reload option, it will be
  87       *                 determined automatically based on the debug value.
  88       *
  89       *  * strict_variables: Whether to ignore invalid variables in templates
  90       *                      (default to false).
  91       *
  92       *  * autoescape: Whether to enable auto-escaping (default to html):
  93       *                  * false: disable auto-escaping
  94       *                  * html, js: set the autoescaping to one of the supported strategies
  95       *                  * name: set the autoescaping strategy based on the template name extension
  96       *                  * PHP callback: a PHP callback that returns an escaping strategy based on the template "name"
  97       *
  98       *  * optimizations: A flag that indicates which optimizations to apply
  99       *                   (default to -1 which means that all optimizations are enabled;
 100       *                   set it to 0 to disable).
 101       */
 102      public function __construct(LoaderInterface $loader, $options = [])
 103      {
 104          $this->setLoader($loader);
 105  
 106          $options = array_merge([
 107              'debug' => false,
 108              'charset' => 'UTF-8',
 109              'base_template_class' => Template::class,
 110              'strict_variables' => false,
 111              'autoescape' => 'html',
 112              'cache' => false,
 113              'auto_reload' => null,
 114              'optimizations' => -1,
 115          ], $options);
 116  
 117          $this->debug = (bool) $options['debug'];
 118          $this->setCharset($options['charset']);
 119          $this->baseTemplateClass = '\\'.ltrim($options['base_template_class'], '\\');
 120          if ('\\'.Template::class !== $this->baseTemplateClass && '\Twig_Template' !== $this->baseTemplateClass) {
 121              @trigger_error('The "base_template_class" option on '.__CLASS__.' is deprecated since Twig 2.7.0.', \E_USER_DEPRECATED);
 122          }
 123          $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
 124          $this->strictVariables = (bool) $options['strict_variables'];
 125          $this->setCache($options['cache']);
 126          $this->extensionSet = new ExtensionSet();
 127  
 128          $this->addExtension(new CoreExtension());
 129          $this->addExtension(new EscaperExtension($options['autoescape']));
 130          $this->addExtension(new OptimizerExtension($options['optimizations']));
 131      }
 132  
 133      /**
 134       * Gets the base template class for compiled templates.
 135       *
 136       * @return string The base template class name
 137       */
 138      public function getBaseTemplateClass()
 139      {
 140          if (1 > \func_num_args() || \func_get_arg(0)) {
 141              @trigger_error('The '.__METHOD__.' is deprecated since Twig 2.7.0.', \E_USER_DEPRECATED);
 142          }
 143  
 144          return $this->baseTemplateClass;
 145      }
 146  
 147      /**
 148       * Sets the base template class for compiled templates.
 149       *
 150       * @param string $class The base template class name
 151       */
 152      public function setBaseTemplateClass($class)
 153      {
 154          @trigger_error('The '.__METHOD__.' is deprecated since Twig 2.7.0.', \E_USER_DEPRECATED);
 155  
 156          $this->baseTemplateClass = $class;
 157          $this->updateOptionsHash();
 158      }
 159  
 160      /**
 161       * Enables debugging mode.
 162       */
 163      public function enableDebug()
 164      {
 165          $this->debug = true;
 166          $this->updateOptionsHash();
 167      }
 168  
 169      /**
 170       * Disables debugging mode.
 171       */
 172      public function disableDebug()
 173      {
 174          $this->debug = false;
 175          $this->updateOptionsHash();
 176      }
 177  
 178      /**
 179       * Checks if debug mode is enabled.
 180       *
 181       * @return bool true if debug mode is enabled, false otherwise
 182       */
 183      public function isDebug()
 184      {
 185          return $this->debug;
 186      }
 187  
 188      /**
 189       * Enables the auto_reload option.
 190       */
 191      public function enableAutoReload()
 192      {
 193          $this->autoReload = true;
 194      }
 195  
 196      /**
 197       * Disables the auto_reload option.
 198       */
 199      public function disableAutoReload()
 200      {
 201          $this->autoReload = false;
 202      }
 203  
 204      /**
 205       * Checks if the auto_reload option is enabled.
 206       *
 207       * @return bool true if auto_reload is enabled, false otherwise
 208       */
 209      public function isAutoReload()
 210      {
 211          return $this->autoReload;
 212      }
 213  
 214      /**
 215       * Enables the strict_variables option.
 216       */
 217      public function enableStrictVariables()
 218      {
 219          $this->strictVariables = true;
 220          $this->updateOptionsHash();
 221      }
 222  
 223      /**
 224       * Disables the strict_variables option.
 225       */
 226      public function disableStrictVariables()
 227      {
 228          $this->strictVariables = false;
 229          $this->updateOptionsHash();
 230      }
 231  
 232      /**
 233       * Checks if the strict_variables option is enabled.
 234       *
 235       * @return bool true if strict_variables is enabled, false otherwise
 236       */
 237      public function isStrictVariables()
 238      {
 239          return $this->strictVariables;
 240      }
 241  
 242      /**
 243       * Gets the current cache implementation.
 244       *
 245       * @param bool $original Whether to return the original cache option or the real cache instance
 246       *
 247       * @return CacheInterface|string|false A Twig\Cache\CacheInterface implementation,
 248       *                                     an absolute path to the compiled templates,
 249       *                                     or false to disable cache
 250       */
 251      public function getCache($original = true)
 252      {
 253          return $original ? $this->originalCache : $this->cache;
 254      }
 255  
 256      /**
 257       * Sets the current cache implementation.
 258       *
 259       * @param CacheInterface|string|false $cache A Twig\Cache\CacheInterface implementation,
 260       *                                           an absolute path to the compiled templates,
 261       *                                           or false to disable cache
 262       */
 263      public function setCache($cache)
 264      {
 265          if (\is_string($cache)) {
 266              $this->originalCache = $cache;
 267              $this->cache = new FilesystemCache($cache, $this->autoReload ? FilesystemCache::FORCE_BYTECODE_INVALIDATION : 0);
 268          } elseif (false === $cache) {
 269              $this->originalCache = $cache;
 270              $this->cache = new NullCache();
 271          } elseif ($cache instanceof CacheInterface) {
 272              $this->originalCache = $this->cache = $cache;
 273          } else {
 274              throw new \LogicException('Cache can only be a string, false, or a \Twig\Cache\CacheInterface implementation.');
 275          }
 276      }
 277  
 278      /**
 279       * Gets the template class associated with the given string.
 280       *
 281       * The generated template class is based on the following parameters:
 282       *
 283       *  * The cache key for the given template;
 284       *  * The currently enabled extensions;
 285       *  * Whether the Twig C extension is available or not;
 286       *  * PHP version;
 287       *  * Twig version;
 288       *  * Options with what environment was created.
 289       *
 290       * @param string   $name  The name for which to calculate the template class name
 291       * @param int|null $index The index if it is an embedded template
 292       *
 293       * @return string The template class name
 294       *
 295       * @internal
 296       */
 297      public function getTemplateClass($name, $index = null)
 298      {
 299          $key = $this->getLoader()->getCacheKey($name).$this->optionsHash;
 300  
 301          return $this->templateClassPrefix.hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $key).(null === $index ? '' : '___'.$index);
 302      }
 303  
 304      /**
 305       * Renders a template.
 306       *
 307       * @param string|TemplateWrapper $name    The template name
 308       * @param array                  $context An array of parameters to pass to the template
 309       *
 310       * @return string The rendered template
 311       *
 312       * @throws LoaderError  When the template cannot be found
 313       * @throws SyntaxError  When an error occurred during compilation
 314       * @throws RuntimeError When an error occurred during rendering
 315       */
 316      public function render($name, array $context = [])
 317      {
 318          return $this->load($name)->render($context);
 319      }
 320  
 321      /**
 322       * Displays a template.
 323       *
 324       * @param string|TemplateWrapper $name    The template name
 325       * @param array                  $context An array of parameters to pass to the template
 326       *
 327       * @throws LoaderError  When the template cannot be found
 328       * @throws SyntaxError  When an error occurred during compilation
 329       * @throws RuntimeError When an error occurred during rendering
 330       */
 331      public function display($name, array $context = [])
 332      {
 333          $this->load($name)->display($context);
 334      }
 335  
 336      /**
 337       * Loads a template.
 338       *
 339       * @param string|TemplateWrapper $name The template name
 340       *
 341       * @throws LoaderError  When the template cannot be found
 342       * @throws RuntimeError When a previously generated cache is corrupted
 343       * @throws SyntaxError  When an error occurred during compilation
 344       *
 345       * @return TemplateWrapper
 346       */
 347      public function load($name)
 348      {
 349          if ($name instanceof TemplateWrapper) {
 350              return $name;
 351          }
 352  
 353          if ($name instanceof Template) {
 354              @trigger_error('Passing a \Twig\Template instance to '.__METHOD__.' is deprecated since Twig 2.7.0, use \Twig\TemplateWrapper instead.', \E_USER_DEPRECATED);
 355  
 356              return new TemplateWrapper($this, $name);
 357          }
 358  
 359          return new TemplateWrapper($this, $this->loadTemplate($name));
 360      }
 361  
 362      /**
 363       * Loads a template internal representation.
 364       *
 365       * This method is for internal use only and should never be called
 366       * directly.
 367       *
 368       * @param string $name  The template name
 369       * @param int    $index The index if it is an embedded template
 370       *
 371       * @return Template A template instance representing the given template name
 372       *
 373       * @throws LoaderError  When the template cannot be found
 374       * @throws RuntimeError When a previously generated cache is corrupted
 375       * @throws SyntaxError  When an error occurred during compilation
 376       *
 377       * @internal
 378       */
 379      public function loadTemplate($name, $index = null)
 380      {
 381          return $this->loadClass($this->getTemplateClass($name), $name, $index);
 382      }
 383  
 384      /**
 385       * @internal
 386       */
 387      public function loadClass($cls, $name, $index = null)
 388      {
 389          $mainCls = $cls;
 390          if (null !== $index) {
 391              $cls .= '___'.$index;
 392          }
 393  
 394          if (isset($this->loadedTemplates[$cls])) {
 395              return $this->loadedTemplates[$cls];
 396          }
 397  
 398          if (!class_exists($cls, false)) {
 399              $key = $this->cache->generateKey($name, $mainCls);
 400  
 401              if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
 402                  $this->cache->load($key);
 403              }
 404  
 405              $source = null;
 406              if (!class_exists($cls, false)) {
 407                  $source = $this->getLoader()->getSourceContext($name);
 408                  $content = $this->compileSource($source);
 409                  $this->cache->write($key, $content);
 410                  $this->cache->load($key);
 411  
 412                  if (!class_exists($mainCls, false)) {
 413                      /* Last line of defense if either $this->bcWriteCacheFile was used,
 414                       * $this->cache is implemented as a no-op or we have a race condition
 415                       * where the cache was cleared between the above calls to write to and load from
 416                       * the cache.
 417                       */
 418                      eval('?>'.$content);
 419                  }
 420  
 421                  if (!class_exists($cls, false)) {
 422                      throw new RuntimeError(sprintf('Failed to load Twig template "%s", index "%s": cache might be corrupted.', $name, $index), -1, $source);
 423                  }
 424              }
 425          }
 426  
 427          // to be removed in 3.0
 428          $this->extensionSet->initRuntime($this);
 429  
 430          return $this->loadedTemplates[$cls] = new $cls($this);
 431      }
 432  
 433      /**
 434       * Creates a template from source.
 435       *
 436       * This method should not be used as a generic way to load templates.
 437       *
 438       * @param string $template The template source
 439       * @param string $name     An optional name of the template to be used in error messages
 440       *
 441       * @return TemplateWrapper A template instance representing the given template name
 442       *
 443       * @throws LoaderError When the template cannot be found
 444       * @throws SyntaxError When an error occurred during compilation
 445       */
 446      public function createTemplate($template, string $name = null)
 447      {
 448          $hash = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $template, false);
 449          if (null !== $name) {
 450              $name = sprintf('%s (string template %s)', $name, $hash);
 451          } else {
 452              $name = sprintf('__string_template__%s', $hash);
 453          }
 454  
 455          $loader = new ChainLoader([
 456              new ArrayLoader([$name => $template]),
 457              $current = $this->getLoader(),
 458          ]);
 459  
 460          $this->setLoader($loader);
 461          try {
 462              return new TemplateWrapper($this, $this->loadTemplate($name));
 463          } finally {
 464              $this->setLoader($current);
 465          }
 466      }
 467  
 468      /**
 469       * Returns true if the template is still fresh.
 470       *
 471       * Besides checking the loader for freshness information,
 472       * this method also checks if the enabled extensions have
 473       * not changed.
 474       *
 475       * @param string $name The template name
 476       * @param int    $time The last modification time of the cached template
 477       *
 478       * @return bool true if the template is fresh, false otherwise
 479       */
 480      public function isTemplateFresh($name, $time)
 481      {
 482          return $this->extensionSet->getLastModified() <= $time && $this->getLoader()->isFresh($name, $time);
 483      }
 484  
 485      /**
 486       * Tries to load a template consecutively from an array.
 487       *
 488       * Similar to load() but it also accepts instances of \Twig\Template and
 489       * \Twig\TemplateWrapper, and an array of templates where each is tried to be loaded.
 490       *
 491       * @param string|TemplateWrapper|array $names A template or an array of templates to try consecutively
 492       *
 493       * @return TemplateWrapper|Template
 494       *
 495       * @throws LoaderError When none of the templates can be found
 496       * @throws SyntaxError When an error occurred during compilation
 497       */
 498      public function resolveTemplate($names)
 499      {
 500          if (!\is_array($names)) {
 501              $names = [$names];
 502          }
 503  
 504          $count = \count($names);
 505          foreach ($names as $name) {
 506              if ($name instanceof Template) {
 507                  return $name;
 508              }
 509              if ($name instanceof TemplateWrapper) {
 510                  return $name;
 511              }
 512  
 513              if (1 !== $count && !$this->getLoader()->exists($name)) {
 514                  continue;
 515              }
 516  
 517              return $this->loadTemplate($name);
 518          }
 519  
 520          throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
 521      }
 522  
 523      public function setLexer(Lexer $lexer)
 524      {
 525          $this->lexer = $lexer;
 526      }
 527  
 528      /**
 529       * Tokenizes a source code.
 530       *
 531       * @return TokenStream
 532       *
 533       * @throws SyntaxError When the code is syntactically wrong
 534       */
 535      public function tokenize(Source $source)
 536      {
 537          if (null === $this->lexer) {
 538              $this->lexer = new Lexer($this);
 539          }
 540  
 541          return $this->lexer->tokenize($source);
 542      }
 543  
 544      public function setParser(Parser $parser)
 545      {
 546          $this->parser = $parser;
 547      }
 548  
 549      /**
 550       * Converts a token stream to a node tree.
 551       *
 552       * @return ModuleNode
 553       *
 554       * @throws SyntaxError When the token stream is syntactically or semantically wrong
 555       */
 556      public function parse(TokenStream $stream)
 557      {
 558          if (null === $this->parser) {
 559              $this->parser = new Parser($this);
 560          }
 561  
 562          return $this->parser->parse($stream);
 563      }
 564  
 565      public function setCompiler(Compiler $compiler)
 566      {
 567          $this->compiler = $compiler;
 568      }
 569  
 570      /**
 571       * Compiles a node and returns the PHP code.
 572       *
 573       * @return string The compiled PHP source code
 574       */
 575      public function compile(Node $node)
 576      {
 577          if (null === $this->compiler) {
 578              $this->compiler = new Compiler($this);
 579          }
 580  
 581          return $this->compiler->compile($node)->getSource();
 582      }
 583  
 584      /**
 585       * Compiles a template source code.
 586       *
 587       * @return string The compiled PHP source code
 588       *
 589       * @throws SyntaxError When there was an error during tokenizing, parsing or compiling
 590       */
 591      public function compileSource(Source $source)
 592      {
 593          try {
 594              return $this->compile($this->parse($this->tokenize($source)));
 595          } catch (Error $e) {
 596              $e->setSourceContext($source);
 597              throw $e;
 598          } catch (\Exception $e) {
 599              throw new SyntaxError(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e);
 600          }
 601      }
 602  
 603      public function setLoader(LoaderInterface $loader)
 604      {
 605          $this->loader = $loader;
 606      }
 607  
 608      /**
 609       * Gets the Loader instance.
 610       *
 611       * @return LoaderInterface
 612       */
 613      public function getLoader()
 614      {
 615          return $this->loader;
 616      }
 617  
 618      /**
 619       * Sets the default template charset.
 620       *
 621       * @param string $charset The default charset
 622       */
 623      public function setCharset($charset)
 624      {
 625          if ('UTF8' === $charset = null === $charset ? null : strtoupper($charset)) {
 626              // iconv on Windows requires "UTF-8" instead of "UTF8"
 627              $charset = 'UTF-8';
 628          }
 629  
 630          $this->charset = $charset;
 631      }
 632  
 633      /**
 634       * Gets the default template charset.
 635       *
 636       * @return string The default charset
 637       */
 638      public function getCharset()
 639      {
 640          return $this->charset;
 641      }
 642  
 643      /**
 644       * Returns true if the given extension is registered.
 645       *
 646       * @param string $class The extension class name
 647       *
 648       * @return bool Whether the extension is registered or not
 649       */
 650      public function hasExtension($class)
 651      {
 652          return $this->extensionSet->hasExtension($class);
 653      }
 654  
 655      /**
 656       * Adds a runtime loader.
 657       */
 658      public function addRuntimeLoader(RuntimeLoaderInterface $loader)
 659      {
 660          $this->runtimeLoaders[] = $loader;
 661      }
 662  
 663      /**
 664       * Gets an extension by class name.
 665       *
 666       * @param string $class The extension class name
 667       *
 668       * @return ExtensionInterface
 669       */
 670      public function getExtension($class)
 671      {
 672          return $this->extensionSet->getExtension($class);
 673      }
 674  
 675      /**
 676       * Returns the runtime implementation of a Twig element (filter/function/test).
 677       *
 678       * @param string $class A runtime class name
 679       *
 680       * @return object The runtime implementation
 681       *
 682       * @throws RuntimeError When the template cannot be found
 683       */
 684      public function getRuntime($class)
 685      {
 686          if (isset($this->runtimes[$class])) {
 687              return $this->runtimes[$class];
 688          }
 689  
 690          foreach ($this->runtimeLoaders as $loader) {
 691              if (null !== $runtime = $loader->load($class)) {
 692                  return $this->runtimes[$class] = $runtime;
 693              }
 694          }
 695  
 696          throw new RuntimeError(sprintf('Unable to load the "%s" runtime.', $class));
 697      }
 698  
 699      public function addExtension(ExtensionInterface $extension)
 700      {
 701          $this->extensionSet->addExtension($extension);
 702          $this->updateOptionsHash();
 703      }
 704  
 705      /**
 706       * Registers an array of extensions.
 707       *
 708       * @param array $extensions An array of extensions
 709       */
 710      public function setExtensions(array $extensions)
 711      {
 712          $this->extensionSet->setExtensions($extensions);
 713          $this->updateOptionsHash();
 714      }
 715  
 716      /**
 717       * Returns all registered extensions.
 718       *
 719       * @return ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
 720       */
 721      public function getExtensions()
 722      {
 723          return $this->extensionSet->getExtensions();
 724      }
 725  
 726      public function addTokenParser(TokenParserInterface $parser)
 727      {
 728          $this->extensionSet->addTokenParser($parser);
 729      }
 730  
 731      /**
 732       * Gets the registered Token Parsers.
 733       *
 734       * @return TokenParserInterface[]
 735       *
 736       * @internal
 737       */
 738      public function getTokenParsers()
 739      {
 740          return $this->extensionSet->getTokenParsers();
 741      }
 742  
 743      /**
 744       * Gets registered tags.
 745       *
 746       * @return TokenParserInterface[]
 747       *
 748       * @internal
 749       */
 750      public function getTags()
 751      {
 752          $tags = [];
 753          foreach ($this->getTokenParsers() as $parser) {
 754              $tags[$parser->getTag()] = $parser;
 755          }
 756  
 757          return $tags;
 758      }
 759  
 760      public function addNodeVisitor(NodeVisitorInterface $visitor)
 761      {
 762          $this->extensionSet->addNodeVisitor($visitor);
 763      }
 764  
 765      /**
 766       * Gets the registered Node Visitors.
 767       *
 768       * @return NodeVisitorInterface[]
 769       *
 770       * @internal
 771       */
 772      public function getNodeVisitors()
 773      {
 774          return $this->extensionSet->getNodeVisitors();
 775      }
 776  
 777      public function addFilter(TwigFilter $filter)
 778      {
 779          $this->extensionSet->addFilter($filter);
 780      }
 781  
 782      /**
 783       * Get a filter by name.
 784       *
 785       * Subclasses may override this method and load filters differently;
 786       * so no list of filters is available.
 787       *
 788       * @param string $name The filter name
 789       *
 790       * @return TwigFilter|false
 791       *
 792       * @internal
 793       */
 794      public function getFilter($name)
 795      {
 796          return $this->extensionSet->getFilter($name);
 797      }
 798  
 799      public function registerUndefinedFilterCallback(callable $callable)
 800      {
 801          $this->extensionSet->registerUndefinedFilterCallback($callable);
 802      }
 803  
 804      /**
 805       * Gets the registered Filters.
 806       *
 807       * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
 808       *
 809       * @return TwigFilter[]
 810       *
 811       * @see registerUndefinedFilterCallback
 812       *
 813       * @internal
 814       */
 815      public function getFilters()
 816      {
 817          return $this->extensionSet->getFilters();
 818      }
 819  
 820      public function addTest(TwigTest $test)
 821      {
 822          $this->extensionSet->addTest($test);
 823      }
 824  
 825      /**
 826       * Gets the registered Tests.
 827       *
 828       * @return TwigTest[]
 829       *
 830       * @internal
 831       */
 832      public function getTests()
 833      {
 834          return $this->extensionSet->getTests();
 835      }
 836  
 837      /**
 838       * Gets a test by name.
 839       *
 840       * @param string $name The test name
 841       *
 842       * @return TwigTest|false
 843       *
 844       * @internal
 845       */
 846      public function getTest($name)
 847      {
 848          return $this->extensionSet->getTest($name);
 849      }
 850  
 851      public function addFunction(TwigFunction $function)
 852      {
 853          $this->extensionSet->addFunction($function);
 854      }
 855  
 856      /**
 857       * Get a function by name.
 858       *
 859       * Subclasses may override this method and load functions differently;
 860       * so no list of functions is available.
 861       *
 862       * @param string $name function name
 863       *
 864       * @return TwigFunction|false
 865       *
 866       * @internal
 867       */
 868      public function getFunction($name)
 869      {
 870          return $this->extensionSet->getFunction($name);
 871      }
 872  
 873      public function registerUndefinedFunctionCallback(callable $callable)
 874      {
 875          $this->extensionSet->registerUndefinedFunctionCallback($callable);
 876      }
 877  
 878      /**
 879       * Gets registered functions.
 880       *
 881       * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback.
 882       *
 883       * @return TwigFunction[]
 884       *
 885       * @see registerUndefinedFunctionCallback
 886       *
 887       * @internal
 888       */
 889      public function getFunctions()
 890      {
 891          return $this->extensionSet->getFunctions();
 892      }
 893  
 894      /**
 895       * Registers a Global.
 896       *
 897       * New globals can be added before compiling or rendering a template;
 898       * but after, you can only update existing globals.
 899       *
 900       * @param string $name  The global name
 901       * @param mixed  $value The global value
 902       */
 903      public function addGlobal($name, $value)
 904      {
 905          if ($this->extensionSet->isInitialized() && !\array_key_exists($name, $this->getGlobals())) {
 906              throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
 907          }
 908  
 909          if (null !== $this->resolvedGlobals) {
 910              $this->resolvedGlobals[$name] = $value;
 911          } else {
 912              $this->globals[$name] = $value;
 913          }
 914      }
 915  
 916      /**
 917       * Gets the registered Globals.
 918       *
 919       * @return array An array of globals
 920       *
 921       * @internal
 922       */
 923      public function getGlobals()
 924      {
 925          if ($this->extensionSet->isInitialized()) {
 926              if (null === $this->resolvedGlobals) {
 927                  $this->resolvedGlobals = array_merge($this->extensionSet->getGlobals(), $this->globals);
 928              }
 929  
 930              return $this->resolvedGlobals;
 931          }
 932  
 933          return array_merge($this->extensionSet->getGlobals(), $this->globals);
 934      }
 935  
 936      /**
 937       * Merges a context with the defined globals.
 938       *
 939       * @param array $context An array representing the context
 940       *
 941       * @return array The context merged with the globals
 942       */
 943      public function mergeGlobals(array $context)
 944      {
 945          // we don't use array_merge as the context being generally
 946          // bigger than globals, this code is faster.
 947          foreach ($this->getGlobals() as $key => $value) {
 948              if (!\array_key_exists($key, $context)) {
 949                  $context[$key] = $value;
 950              }
 951          }
 952  
 953          return $context;
 954      }
 955  
 956      /**
 957       * Gets the registered unary Operators.
 958       *
 959       * @return array An array of unary operators
 960       *
 961       * @internal
 962       */
 963      public function getUnaryOperators()
 964      {
 965          return $this->extensionSet->getUnaryOperators();
 966      }
 967  
 968      /**
 969       * Gets the registered binary Operators.
 970       *
 971       * @return array An array of binary operators
 972       *
 973       * @internal
 974       */
 975      public function getBinaryOperators()
 976      {
 977          return $this->extensionSet->getBinaryOperators();
 978      }
 979  
 980      private function updateOptionsHash()
 981      {
 982          $this->optionsHash = implode(':', [
 983              $this->extensionSet->getSignature(),
 984              \PHP_MAJOR_VERSION,
 985              \PHP_MINOR_VERSION,
 986              self::VERSION,
 987              (int) $this->debug,
 988              $this->baseTemplateClass,
 989              (int) $this->strictVariables,
 990          ]);
 991      }
 992  }
 993  
 994  class_alias('Twig\Environment', 'Twig_Environment');


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