Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Environment.php

Zuletzt modifiziert: 09.10.2024, 12:57 - Dateigröße: 43.81 KiB


 0001  <?php
 0002   
 0003  /*
 0004   * This file is part of Twig.
 0005   *
 0006   * (c) 2009 Fabien Potencier
 0007   *
 0008   * For the full copyright and license information, please view the LICENSE
 0009   * file that was distributed with this source code.
 0010   */
 0011   
 0012  /**
 0013   * Stores the Twig configuration.
 0014   *
 0015   * @author Fabien Potencier <fabien@symfony.com>
 0016   */
 0017  class Twig_Environment
 0018  {
 0019      const VERSION = '1.24.2';
 0020   
 0021      protected $charset;
 0022      protected $loader;
 0023      protected $debug;
 0024      protected $autoReload;
 0025      protected $cache;
 0026      protected $lexer;
 0027      protected $parser;
 0028      protected $compiler;
 0029      protected $baseTemplateClass;
 0030      protected $extensions;
 0031      protected $parsers;
 0032      protected $visitors;
 0033      protected $filters;
 0034      protected $tests;
 0035      protected $functions;
 0036      protected $globals;
 0037      protected $runtimeInitialized = false;
 0038      protected $extensionInitialized = false;
 0039      protected $loadedTemplates;
 0040      protected $strictVariables;
 0041      protected $unaryOperators;
 0042      protected $binaryOperators;
 0043      protected $templateClassPrefix = '__TwigTemplate_';
 0044      protected $functionCallbacks = array();
 0045      protected $filterCallbacks = array();
 0046      protected $staging;
 0047   
 0048      private $originalCache;
 0049      private $bcWriteCacheFile = false;
 0050      private $bcGetCacheFilename = false;
 0051      private $lastModifiedExtension = 0;
 0052   
 0053      /**
 0054       * Constructor.
 0055       *
 0056       * Available options:
 0057       *
 0058       *  * debug: When set to true, it automatically set "auto_reload" to true as
 0059       *           well (default to false).
 0060       *
 0061       *  * charset: The charset used by the templates (default to UTF-8).
 0062       *
 0063       *  * base_template_class: The base template class to use for generated
 0064       *                         templates (default to Twig_Template).
 0065       *
 0066       *  * cache: An absolute path where to store the compiled templates,
 0067       *           a Twig_Cache_Interface implementation,
 0068       *           or false to disable compilation cache (default).
 0069       *
 0070       *  * auto_reload: Whether to reload the template if the original source changed.
 0071       *                 If you don't provide the auto_reload option, it will be
 0072       *                 determined automatically based on the debug value.
 0073       *
 0074       *  * strict_variables: Whether to ignore invalid variables in templates
 0075       *                      (default to false).
 0076       *
 0077       *  * autoescape: Whether to enable auto-escaping (default to html):
 0078       *                  * false: disable auto-escaping
 0079       *                  * true: equivalent to html
 0080       *                  * html, js: set the autoescaping to one of the supported strategies
 0081       *                  * filename: set the autoescaping strategy based on the template filename extension
 0082       *                  * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename"
 0083       *
 0084       *  * optimizations: A flag that indicates which optimizations to apply
 0085       *                   (default to -1 which means that all optimizations are enabled;
 0086       *                   set it to 0 to disable).
 0087       *
 0088       * @param Twig_LoaderInterface $loader  A Twig_LoaderInterface instance
 0089       * @param array                $options An array of options
 0090       */
 0091      public function __construct(Twig_LoaderInterface $loader = null, $options = array())
 0092      {
 0093          if (null !== $loader) {
 0094              $this->setLoader($loader);
 0095          } else {
 0096              @trigger_error('Not passing a Twig_LoaderInterface as the first constructor argument of Twig_Environment is deprecated since version 1.21.', E_USER_DEPRECATED);
 0097          }
 0098   
 0099          $options = array_merge(array(
 0100              'debug' => false,
 0101              'charset' => 'UTF-8',
 0102              'base_template_class' => 'Twig_Template',
 0103              'strict_variables' => false,
 0104              'autoescape' => 'html',
 0105              'cache' => false,
 0106              'auto_reload' => null,
 0107              'optimizations' => -1,
 0108          ), $options);
 0109   
 0110          $this->debug = (bool) $options['debug'];
 0111          $this->charset = strtoupper($options['charset']);
 0112          $this->baseTemplateClass = $options['base_template_class'];
 0113          $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
 0114          $this->strictVariables = (bool) $options['strict_variables'];
 0115          $this->setCache($options['cache']);
 0116   
 0117          $this->addExtension(new Twig_Extension_Core());
 0118          $this->addExtension(new Twig_Extension_Escaper($options['autoescape']));
 0119          $this->addExtension(new Twig_Extension_Optimizer($options['optimizations']));
 0120          $this->staging = new Twig_Extension_Staging();
 0121   
 0122          // For BC
 0123          if (is_string($this->originalCache)) {
 0124              $r = new ReflectionMethod($this, 'writeCacheFile');
 0125              if ($r->getDeclaringClass()->getName() !== __CLASS__) {
 0126                  @trigger_error('The Twig_Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
 0127   
 0128                  $this->bcWriteCacheFile = true;
 0129              }
 0130   
 0131              $r = new ReflectionMethod($this, 'getCacheFilename');
 0132              if ($r->getDeclaringClass()->getName() !== __CLASS__) {
 0133                  @trigger_error('The Twig_Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
 0134   
 0135                  $this->bcGetCacheFilename = true;
 0136              }
 0137          }
 0138      }
 0139   
 0140      /**
 0141       * Gets the base template class for compiled templates.
 0142       *
 0143       * @return string The base template class name
 0144       */
 0145      public function getBaseTemplateClass()
 0146      {
 0147          return $this->baseTemplateClass;
 0148      }
 0149   
 0150      /**
 0151       * Sets the base template class for compiled templates.
 0152       *
 0153       * @param string $class The base template class name
 0154       */
 0155      public function setBaseTemplateClass($class)
 0156      {
 0157          $this->baseTemplateClass = $class;
 0158      }
 0159   
 0160      /**
 0161       * Enables debugging mode.
 0162       */
 0163      public function enableDebug()
 0164      {
 0165          $this->debug = true;
 0166      }
 0167   
 0168      /**
 0169       * Disables debugging mode.
 0170       */
 0171      public function disableDebug()
 0172      {
 0173          $this->debug = false;
 0174      }
 0175   
 0176      /**
 0177       * Checks if debug mode is enabled.
 0178       *
 0179       * @return bool true if debug mode is enabled, false otherwise
 0180       */
 0181      public function isDebug()
 0182      {
 0183          return $this->debug;
 0184      }
 0185   
 0186      /**
 0187       * Enables the auto_reload option.
 0188       */
 0189      public function enableAutoReload()
 0190      {
 0191          $this->autoReload = true;
 0192      }
 0193   
 0194      /**
 0195       * Disables the auto_reload option.
 0196       */
 0197      public function disableAutoReload()
 0198      {
 0199          $this->autoReload = false;
 0200      }
 0201   
 0202      /**
 0203       * Checks if the auto_reload option is enabled.
 0204       *
 0205       * @return bool true if auto_reload is enabled, false otherwise
 0206       */
 0207      public function isAutoReload()
 0208      {
 0209          return $this->autoReload;
 0210      }
 0211   
 0212      /**
 0213       * Enables the strict_variables option.
 0214       */
 0215      public function enableStrictVariables()
 0216      {
 0217          $this->strictVariables = true;
 0218      }
 0219   
 0220      /**
 0221       * Disables the strict_variables option.
 0222       */
 0223      public function disableStrictVariables()
 0224      {
 0225          $this->strictVariables = false;
 0226      }
 0227   
 0228      /**
 0229       * Checks if the strict_variables option is enabled.
 0230       *
 0231       * @return bool true if strict_variables is enabled, false otherwise
 0232       */
 0233      public function isStrictVariables()
 0234      {
 0235          return $this->strictVariables;
 0236      }
 0237   
 0238      /**
 0239       * Gets the current cache implementation.
 0240       *
 0241       * @param bool $original Whether to return the original cache option or the real cache instance
 0242       *
 0243       * @return Twig_CacheInterface|string|false A Twig_CacheInterface implementation,
 0244       *                                          an absolute path to the compiled templates,
 0245       *                                          or false to disable cache
 0246       */
 0247      public function getCache($original = true)
 0248      {
 0249          return $original ? $this->originalCache : $this->cache;
 0250      }
 0251   
 0252      /**
 0253       * Sets the current cache implementation.
 0254       *
 0255       * @param Twig_CacheInterface|string|false $cache A Twig_CacheInterface implementation,
 0256       *                                                an absolute path to the compiled templates,
 0257       *                                                or false to disable cache
 0258       */
 0259      public function setCache($cache)
 0260      {
 0261          if (is_string($cache)) {
 0262              $this->originalCache = $cache;
 0263              $this->cache = new Twig_Cache_Filesystem($cache);
 0264          } elseif (false === $cache) {
 0265              $this->originalCache = $cache;
 0266              $this->cache = new Twig_Cache_Null();
 0267          } elseif (null === $cache) {
 0268              @trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
 0269              $this->originalCache = false;
 0270              $this->cache = new Twig_Cache_Null();
 0271          } elseif ($cache instanceof Twig_CacheInterface) {
 0272              $this->originalCache = $this->cache = $cache;
 0273          } else {
 0274              throw new LogicException(sprintf('Cache can only be a string, false, or a Twig_CacheInterface implementation.'));
 0275          }
 0276      }
 0277   
 0278      /**
 0279       * Gets the cache filename for a given template.
 0280       *
 0281       * @param string $name The template name
 0282       *
 0283       * @return string|false The cache file name or false when caching is disabled
 0284       *
 0285       * @deprecated since 1.22 (to be removed in 2.0)
 0286       */
 0287      public function getCacheFilename($name)
 0288      {
 0289          @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 0290   
 0291          $key = $this->cache->generateKey($name, $this->getTemplateClass($name));
 0292   
 0293          return !$key ? false : $key;
 0294      }
 0295   
 0296      /**
 0297       * Gets the template class associated with the given string.
 0298       *
 0299       * The generated template class is based on the following parameters:
 0300       *
 0301       *  * The cache key for the given template;
 0302       *  * The currently enabled extensions;
 0303       *  * Whether the Twig C extension is available or not.
 0304       *
 0305       * @param string   $name  The name for which to calculate the template class name
 0306       * @param int|null $index The index if it is an embedded template
 0307       *
 0308       * @return string The template class name
 0309       */
 0310      public function getTemplateClass($name, $index = null)
 0311      {
 0312          $key = $this->getLoader()->getCacheKey($name);
 0313          $key .= json_encode(array_keys($this->extensions));
 0314          $key .= function_exists('twig_template_get_attributes');
 0315   
 0316          return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '_'.$index);
 0317      }
 0318   
 0319      /**
 0320       * Gets the template class prefix.
 0321       *
 0322       * @return string The template class prefix
 0323       *
 0324       * @deprecated since 1.22 (to be removed in 2.0)
 0325       */
 0326      public function getTemplateClassPrefix()
 0327      {
 0328          @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 0329   
 0330          return $this->templateClassPrefix;
 0331      }
 0332   
 0333      /**
 0334       * Renders a template.
 0335       *
 0336       * @param string $name    The template name
 0337       * @param array  $context An array of parameters to pass to the template
 0338       *
 0339       * @return string The rendered template
 0340       *
 0341       * @throws Twig_Error_Loader  When the template cannot be found
 0342       * @throws Twig_Error_Syntax  When an error occurred during compilation
 0343       * @throws Twig_Error_Runtime When an error occurred during rendering
 0344       */
 0345      public function render($name, array $context = array())
 0346      {
 0347          return $this->loadTemplate($name)->render($context);
 0348      }
 0349   
 0350      /**
 0351       * Displays a template.
 0352       *
 0353       * @param string $name    The template name
 0354       * @param array  $context An array of parameters to pass to the template
 0355       *
 0356       * @throws Twig_Error_Loader  When the template cannot be found
 0357       * @throws Twig_Error_Syntax  When an error occurred during compilation
 0358       * @throws Twig_Error_Runtime When an error occurred during rendering
 0359       */
 0360      public function display($name, array $context = array())
 0361      {
 0362          $this->loadTemplate($name)->display($context);
 0363      }
 0364   
 0365      /**
 0366       * Loads a template by name.
 0367       *
 0368       * @param string $name  The template name
 0369       * @param int    $index The index if it is an embedded template
 0370       *
 0371       * @return Twig_TemplateInterface A template instance representing the given template name
 0372       *
 0373       * @throws Twig_Error_Loader When the template cannot be found
 0374       * @throws Twig_Error_Syntax When an error occurred during compilation
 0375       */
 0376      public function loadTemplate($name, $index = null)
 0377      {
 0378          $cls = $this->getTemplateClass($name, $index);
 0379   
 0380          if (isset($this->loadedTemplates[$cls])) {
 0381              return $this->loadedTemplates[$cls];
 0382          }
 0383   
 0384          if (!class_exists($cls, false)) {
 0385              if ($this->bcGetCacheFilename) {
 0386                  $key = $this->getCacheFilename($name);
 0387              } else {
 0388                  $key = $this->cache->generateKey($name, $cls);
 0389              }
 0390   
 0391              if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
 0392                  $this->cache->load($key);
 0393              }
 0394   
 0395              if (!class_exists($cls, false)) {
 0396                  $content = $this->compileSource($this->getLoader()->getSource($name), $name);
 0397                  if ($this->bcWriteCacheFile) {
 0398                      $this->writeCacheFile($key, $content);
 0399                  } else {
 0400                      $this->cache->write($key, $content);
 0401                  }
 0402   
 0403                  eval('?>'.$content);
 0404              }
 0405          }
 0406   
 0407          if (!$this->runtimeInitialized) {
 0408              $this->initRuntime();
 0409          }
 0410   
 0411          return $this->loadedTemplates[$cls] = new $cls($this);
 0412      }
 0413   
 0414      /**
 0415       * Creates a template from source.
 0416       *
 0417       * This method should not be used as a generic way to load templates.
 0418       *
 0419       * @param string $template The template name
 0420       *
 0421       * @return Twig_Template A template instance representing the given template name
 0422       *
 0423       * @throws Twig_Error_Loader When the template cannot be found
 0424       * @throws Twig_Error_Syntax When an error occurred during compilation
 0425       */
 0426      public function createTemplate($template)
 0427      {
 0428          $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false));
 0429   
 0430          $loader = new Twig_Loader_Chain(array(
 0431              new Twig_Loader_Array(array($name => $template)),
 0432              $current = $this->getLoader(),
 0433          ));
 0434   
 0435          $this->setLoader($loader);
 0436          try {
 0437              $template = $this->loadTemplate($name);
 0438          } catch (Exception $e) {
 0439              $this->setLoader($current);
 0440   
 0441              throw $e;
 0442          } catch (Throwable $e) {
 0443              $this->setLoader($current);
 0444   
 0445              throw $e;
 0446          }
 0447          $this->setLoader($current);
 0448   
 0449          return $template;
 0450      }
 0451   
 0452      /**
 0453       * Returns true if the template is still fresh.
 0454       *
 0455       * Besides checking the loader for freshness information,
 0456       * this method also checks if the enabled extensions have
 0457       * not changed.
 0458       *
 0459       * @param string $name The template name
 0460       * @param int    $time The last modification time of the cached template
 0461       *
 0462       * @return bool true if the template is fresh, false otherwise
 0463       */
 0464      public function isTemplateFresh($name, $time)
 0465      {
 0466          if (0 === $this->lastModifiedExtension) {
 0467              foreach ($this->extensions as $extension) {
 0468                  $r = new ReflectionObject($extension);
 0469                  if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
 0470                      $this->lastModifiedExtension = $extensionTime;
 0471                  }
 0472              }
 0473          }
 0474   
 0475          return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time);
 0476      }
 0477   
 0478      /**
 0479       * Tries to load a template consecutively from an array.
 0480       *
 0481       * Similar to loadTemplate() but it also accepts Twig_TemplateInterface instances and an array
 0482       * of templates where each is tried to be loaded.
 0483       *
 0484       * @param string|Twig_Template|array $names A template or an array of templates to try consecutively
 0485       *
 0486       * @return Twig_Template
 0487       *
 0488       * @throws Twig_Error_Loader When none of the templates can be found
 0489       * @throws Twig_Error_Syntax When an error occurred during compilation
 0490       */
 0491      public function resolveTemplate($names)
 0492      {
 0493          if (!is_array($names)) {
 0494              $names = array($names);
 0495          }
 0496   
 0497          foreach ($names as $name) {
 0498              if ($name instanceof Twig_Template) {
 0499                  return $name;
 0500              }
 0501   
 0502              try {
 0503                  return $this->loadTemplate($name);
 0504              } catch (Twig_Error_Loader $e) {
 0505              }
 0506          }
 0507   
 0508          if (1 === count($names)) {
 0509              throw $e;
 0510          }
 0511   
 0512          throw new Twig_Error_Loader(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
 0513      }
 0514   
 0515      /**
 0516       * Clears the internal template cache.
 0517       *
 0518       * @deprecated since 1.18.3 (to be removed in 2.0)
 0519       */
 0520      public function clearTemplateCache()
 0521      {
 0522          @trigger_error(sprintf('The %s method is deprecated since version 1.18.3 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 0523   
 0524          $this->loadedTemplates = array();
 0525      }
 0526   
 0527      /**
 0528       * Clears the template cache files on the filesystem.
 0529       *
 0530       * @deprecated since 1.22 (to be removed in 2.0)
 0531       */
 0532      public function clearCacheFiles()
 0533      {
 0534          @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 0535   
 0536          if (is_string($this->originalCache)) {
 0537              foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->originalCache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
 0538                  if ($file->isFile()) {
 0539                      @unlink($file->getPathname());
 0540                  }
 0541              }
 0542          }
 0543      }
 0544   
 0545      /**
 0546       * Gets the Lexer instance.
 0547       *
 0548       * @return Twig_LexerInterface A Twig_LexerInterface instance
 0549       */
 0550      public function getLexer()
 0551      {
 0552          if (null === $this->lexer) {
 0553              $this->lexer = new Twig_Lexer($this);
 0554          }
 0555   
 0556          return $this->lexer;
 0557      }
 0558   
 0559      /**
 0560       * Sets the Lexer instance.
 0561       *
 0562       * @param Twig_LexerInterface $lexer A Twig_LexerInterface instance
 0563       */
 0564      public function setLexer(Twig_LexerInterface $lexer)
 0565      {
 0566          $this->lexer = $lexer;
 0567      }
 0568   
 0569      /**
 0570       * Tokenizes a source code.
 0571       *
 0572       * @param string $source The template source code
 0573       * @param string $name   The template name
 0574       *
 0575       * @return Twig_TokenStream A Twig_TokenStream instance
 0576       *
 0577       * @throws Twig_Error_Syntax When the code is syntactically wrong
 0578       */
 0579      public function tokenize($source, $name = null)
 0580      {
 0581          return $this->getLexer()->tokenize($source, $name);
 0582      }
 0583   
 0584      /**
 0585       * Gets the Parser instance.
 0586       *
 0587       * @return Twig_ParserInterface A Twig_ParserInterface instance
 0588       */
 0589      public function getParser()
 0590      {
 0591          if (null === $this->parser) {
 0592              $this->parser = new Twig_Parser($this);
 0593          }
 0594   
 0595          return $this->parser;
 0596      }
 0597   
 0598      /**
 0599       * Sets the Parser instance.
 0600       *
 0601       * @param Twig_ParserInterface $parser A Twig_ParserInterface instance
 0602       */
 0603      public function setParser(Twig_ParserInterface $parser)
 0604      {
 0605          $this->parser = $parser;
 0606      }
 0607   
 0608      /**
 0609       * Converts a token stream to a node tree.
 0610       *
 0611       * @param Twig_TokenStream $stream A token stream instance
 0612       *
 0613       * @return Twig_Node_Module A node tree
 0614       *
 0615       * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong
 0616       */
 0617      public function parse(Twig_TokenStream $stream)
 0618      {
 0619          return $this->getParser()->parse($stream);
 0620      }
 0621   
 0622      /**
 0623       * Gets the Compiler instance.
 0624       *
 0625       * @return Twig_CompilerInterface A Twig_CompilerInterface instance
 0626       */
 0627      public function getCompiler()
 0628      {
 0629          if (null === $this->compiler) {
 0630              $this->compiler = new Twig_Compiler($this);
 0631          }
 0632   
 0633          return $this->compiler;
 0634      }
 0635   
 0636      /**
 0637       * Sets the Compiler instance.
 0638       *
 0639       * @param Twig_CompilerInterface $compiler A Twig_CompilerInterface instance
 0640       */
 0641      public function setCompiler(Twig_CompilerInterface $compiler)
 0642      {
 0643          $this->compiler = $compiler;
 0644      }
 0645   
 0646      /**
 0647       * Compiles a node and returns the PHP code.
 0648       *
 0649       * @param Twig_NodeInterface $node A Twig_NodeInterface instance
 0650       *
 0651       * @return string The compiled PHP source code
 0652       */
 0653      public function compile(Twig_NodeInterface $node)
 0654      {
 0655          return $this->getCompiler()->compile($node)->getSource();
 0656      }
 0657   
 0658      /**
 0659       * Compiles a template source code.
 0660       *
 0661       * @param string $source The template source code
 0662       * @param string $name   The template name
 0663       *
 0664       * @return string The compiled PHP source code
 0665       *
 0666       * @throws Twig_Error_Syntax When there was an error during tokenizing, parsing or compiling
 0667       */
 0668      public function compileSource($source, $name = null)
 0669      {
 0670          try {
 0671              $compiled = $this->compile($this->parse($this->tokenize($source, $name)), $source);
 0672   
 0673              if (isset($source[0])) {
 0674                  $compiled .= '/* '.str_replace(array('*/', "\r\n", "\r", "\n"), array('*//* ', "\n", "\n", "*/\n/* "), $source)."*/\n";
 0675              }
 0676   
 0677              return $compiled;
 0678          } catch (Twig_Error $e) {
 0679              $e->setTemplateFile($name);
 0680              throw $e;
 0681          } catch (Exception $e) {
 0682              throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
 0683          }
 0684      }
 0685   
 0686      /**
 0687       * Sets the Loader instance.
 0688       *
 0689       * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance
 0690       */
 0691      public function setLoader(Twig_LoaderInterface $loader)
 0692      {
 0693          $this->loader = $loader;
 0694      }
 0695   
 0696      /**
 0697       * Gets the Loader instance.
 0698       *
 0699       * @return Twig_LoaderInterface A Twig_LoaderInterface instance
 0700       */
 0701      public function getLoader()
 0702      {
 0703          if (null === $this->loader) {
 0704              throw new LogicException('You must set a loader first.');
 0705          }
 0706   
 0707          return $this->loader;
 0708      }
 0709   
 0710      /**
 0711       * Sets the default template charset.
 0712       *
 0713       * @param string $charset The default charset
 0714       */
 0715      public function setCharset($charset)
 0716      {
 0717          $this->charset = strtoupper($charset);
 0718      }
 0719   
 0720      /**
 0721       * Gets the default template charset.
 0722       *
 0723       * @return string The default charset
 0724       */
 0725      public function getCharset()
 0726      {
 0727          return $this->charset;
 0728      }
 0729   
 0730      /**
 0731       * Initializes the runtime environment.
 0732       *
 0733       * @deprecated since 1.23 (to be removed in 2.0)
 0734       */
 0735      public function initRuntime()
 0736      {
 0737          $this->runtimeInitialized = true;
 0738   
 0739          foreach ($this->getExtensions() as $name => $extension) {
 0740              if (!$extension instanceof Twig_Extension_InitRuntimeInterface) {
 0741                  $m = new ReflectionMethod($extension, 'initRuntime');
 0742   
 0743                  if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
 0744                      @trigger_error(sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig_Extension_InitRuntimeInterface if needed (not recommended).', $name), E_USER_DEPRECATED);
 0745                  }
 0746              }
 0747   
 0748              $extension->initRuntime($this);
 0749          }
 0750      }
 0751   
 0752      /**
 0753       * Returns true if the given extension is registered.
 0754       *
 0755       * @param string $name The extension name
 0756       *
 0757       * @return bool Whether the extension is registered or not
 0758       */
 0759      public function hasExtension($name)
 0760      {
 0761          return isset($this->extensions[$name]);
 0762      }
 0763   
 0764      /**
 0765       * Gets an extension by name.
 0766       *
 0767       * @param string $name The extension name
 0768       *
 0769       * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
 0770       */
 0771      public function getExtension($name)
 0772      {
 0773          if (!isset($this->extensions[$name])) {
 0774              throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name));
 0775          }
 0776   
 0777          return $this->extensions[$name];
 0778      }
 0779   
 0780      /**
 0781       * Registers an extension.
 0782       *
 0783       * @param Twig_ExtensionInterface $extension A Twig_ExtensionInterface instance
 0784       */
 0785      public function addExtension(Twig_ExtensionInterface $extension)
 0786      {
 0787          $name = $extension->getName();
 0788   
 0789          if ($this->extensionInitialized) {
 0790              throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $name));
 0791          }
 0792   
 0793          if (isset($this->extensions[$name])) {
 0794              @trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $name), E_USER_DEPRECATED);
 0795          }
 0796   
 0797          $this->lastModifiedExtension = 0;
 0798   
 0799          $this->extensions[$name] = $extension;
 0800      }
 0801   
 0802      /**
 0803       * Removes an extension by name.
 0804       *
 0805       * This method is deprecated and you should not use it.
 0806       *
 0807       * @param string $name The extension name
 0808       *
 0809       * @deprecated since 1.12 (to be removed in 2.0)
 0810       */
 0811      public function removeExtension($name)
 0812      {
 0813          @trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 0814   
 0815          if ($this->extensionInitialized) {
 0816              throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
 0817          }
 0818   
 0819          unset($this->extensions[$name]);
 0820      }
 0821   
 0822      /**
 0823       * Registers an array of extensions.
 0824       *
 0825       * @param array $extensions An array of extensions
 0826       */
 0827      public function setExtensions(array $extensions)
 0828      {
 0829          foreach ($extensions as $extension) {
 0830              $this->addExtension($extension);
 0831          }
 0832      }
 0833   
 0834      /**
 0835       * Returns all registered extensions.
 0836       *
 0837       * @return array An array of extensions
 0838       */
 0839      public function getExtensions()
 0840      {
 0841          return $this->extensions;
 0842      }
 0843   
 0844      /**
 0845       * Registers a Token Parser.
 0846       *
 0847       * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance
 0848       */
 0849      public function addTokenParser(Twig_TokenParserInterface $parser)
 0850      {
 0851          if ($this->extensionInitialized) {
 0852              throw new LogicException('Unable to add a token parser as extensions have already been initialized.');
 0853          }
 0854   
 0855          $this->staging->addTokenParser($parser);
 0856      }
 0857   
 0858      /**
 0859       * Gets the registered Token Parsers.
 0860       *
 0861       * @return Twig_TokenParserBrokerInterface A broker containing token parsers
 0862       *
 0863       * @internal
 0864       */
 0865      public function getTokenParsers()
 0866      {
 0867          if (!$this->extensionInitialized) {
 0868              $this->initExtensions();
 0869          }
 0870   
 0871          return $this->parsers;
 0872      }
 0873   
 0874      /**
 0875       * Gets registered tags.
 0876       *
 0877       * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
 0878       *
 0879       * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
 0880       *
 0881       * @internal
 0882       */
 0883      public function getTags()
 0884      {
 0885          $tags = array();
 0886          foreach ($this->getTokenParsers()->getParsers() as $parser) {
 0887              if ($parser instanceof Twig_TokenParserInterface) {
 0888                  $tags[$parser->getTag()] = $parser;
 0889              }
 0890          }
 0891   
 0892          return $tags;
 0893      }
 0894   
 0895      /**
 0896       * Registers a Node Visitor.
 0897       *
 0898       * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance
 0899       */
 0900      public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
 0901      {
 0902          if ($this->extensionInitialized) {
 0903              throw new LogicException('Unable to add a node visitor as extensions have already been initialized.');
 0904          }
 0905   
 0906          $this->staging->addNodeVisitor($visitor);
 0907      }
 0908   
 0909      /**
 0910       * Gets the registered Node Visitors.
 0911       *
 0912       * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
 0913       *
 0914       * @internal
 0915       */
 0916      public function getNodeVisitors()
 0917      {
 0918          if (!$this->extensionInitialized) {
 0919              $this->initExtensions();
 0920          }
 0921   
 0922          return $this->visitors;
 0923      }
 0924   
 0925      /**
 0926       * Registers a Filter.
 0927       *
 0928       * @param string|Twig_SimpleFilter               $name   The filter name or a Twig_SimpleFilter instance
 0929       * @param Twig_FilterInterface|Twig_SimpleFilter $filter A Twig_FilterInterface instance or a Twig_SimpleFilter instance
 0930       */
 0931      public function addFilter($name, $filter = null)
 0932      {
 0933          if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) {
 0934              throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter');
 0935          }
 0936   
 0937          if ($name instanceof Twig_SimpleFilter) {
 0938              $filter = $name;
 0939              $name = $filter->getName();
 0940          } else {
 0941              @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), E_USER_DEPRECATED);
 0942          }
 0943   
 0944          if ($this->extensionInitialized) {
 0945              throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
 0946          }
 0947   
 0948          $this->staging->addFilter($name, $filter);
 0949      }
 0950   
 0951      /**
 0952       * Get a filter by name.
 0953       *
 0954       * Subclasses may override this method and load filters differently;
 0955       * so no list of filters is available.
 0956       *
 0957       * @param string $name The filter name
 0958       *
 0959       * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist
 0960       *
 0961       * @internal
 0962       */
 0963      public function getFilter($name)
 0964      {
 0965          if (!$this->extensionInitialized) {
 0966              $this->initExtensions();
 0967          }
 0968   
 0969          if (isset($this->filters[$name])) {
 0970              return $this->filters[$name];
 0971          }
 0972   
 0973          foreach ($this->filters as $pattern => $filter) {
 0974              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
 0975   
 0976              if ($count) {
 0977                  if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
 0978                      array_shift($matches);
 0979                      $filter->setArguments($matches);
 0980   
 0981                      return $filter;
 0982                  }
 0983              }
 0984          }
 0985   
 0986          foreach ($this->filterCallbacks as $callback) {
 0987              if (false !== $filter = call_user_func($callback, $name)) {
 0988                  return $filter;
 0989              }
 0990          }
 0991   
 0992          return false;
 0993      }
 0994   
 0995      public function registerUndefinedFilterCallback($callable)
 0996      {
 0997          $this->filterCallbacks[] = $callable;
 0998      }
 0999   
 1000      /**
 1001       * Gets the registered Filters.
 1002       *
 1003       * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
 1004       *
 1005       * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
 1006       *
 1007       * @see registerUndefinedFilterCallback
 1008       *
 1009       * @internal
 1010       */
 1011      public function getFilters()
 1012      {
 1013          if (!$this->extensionInitialized) {
 1014              $this->initExtensions();
 1015          }
 1016   
 1017          return $this->filters;
 1018      }
 1019   
 1020      /**
 1021       * Registers a Test.
 1022       *
 1023       * @param string|Twig_SimpleTest             $name The test name or a Twig_SimpleTest instance
 1024       * @param Twig_TestInterface|Twig_SimpleTest $test A Twig_TestInterface instance or a Twig_SimpleTest instance
 1025       */
 1026      public function addTest($name, $test = null)
 1027      {
 1028          if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) {
 1029              throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest');
 1030          }
 1031   
 1032          if ($name instanceof Twig_SimpleTest) {
 1033              $test = $name;
 1034              $name = $test->getName();
 1035          } else {
 1036              @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleTest" instead when defining test "%s".', __METHOD__, $name), E_USER_DEPRECATED);
 1037          }
 1038   
 1039          if ($this->extensionInitialized) {
 1040              throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
 1041          }
 1042   
 1043          $this->staging->addTest($name, $test);
 1044      }
 1045   
 1046      /**
 1047       * Gets the registered Tests.
 1048       *
 1049       * @return Twig_TestInterface[] An array of Twig_TestInterface instances
 1050       *
 1051       * @internal
 1052       */
 1053      public function getTests()
 1054      {
 1055          if (!$this->extensionInitialized) {
 1056              $this->initExtensions();
 1057          }
 1058   
 1059          return $this->tests;
 1060      }
 1061   
 1062      /**
 1063       * Gets a test by name.
 1064       *
 1065       * @param string $name The test name
 1066       *
 1067       * @return Twig_Test|false A Twig_Test instance or false if the test does not exist
 1068       *
 1069       * @internal
 1070       */
 1071      public function getTest($name)
 1072      {
 1073          if (!$this->extensionInitialized) {
 1074              $this->initExtensions();
 1075          }
 1076   
 1077          if (isset($this->tests[$name])) {
 1078              return $this->tests[$name];
 1079          }
 1080   
 1081          return false;
 1082      }
 1083   
 1084      /**
 1085       * Registers a Function.
 1086       *
 1087       * @param string|Twig_SimpleFunction                 $name     The function name or a Twig_SimpleFunction instance
 1088       * @param Twig_FunctionInterface|Twig_SimpleFunction $function A Twig_FunctionInterface instance or a Twig_SimpleFunction instance
 1089       */
 1090      public function addFunction($name, $function = null)
 1091      {
 1092          if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) {
 1093              throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction');
 1094          }
 1095   
 1096          if ($name instanceof Twig_SimpleFunction) {
 1097              $function = $name;
 1098              $name = $function->getName();
 1099          } else {
 1100              @trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFunction" instead when defining function "%s".', __METHOD__, $name), E_USER_DEPRECATED);
 1101          }
 1102   
 1103          if ($this->extensionInitialized) {
 1104              throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
 1105          }
 1106   
 1107          $this->staging->addFunction($name, $function);
 1108      }
 1109   
 1110      /**
 1111       * Get a function by name.
 1112       *
 1113       * Subclasses may override this method and load functions differently;
 1114       * so no list of functions is available.
 1115       *
 1116       * @param string $name function name
 1117       *
 1118       * @return Twig_Function|false A Twig_Function instance or false if the function does not exist
 1119       *
 1120       * @internal
 1121       */
 1122      public function getFunction($name)
 1123      {
 1124          if (!$this->extensionInitialized) {
 1125              $this->initExtensions();
 1126          }
 1127   
 1128          if (isset($this->functions[$name])) {
 1129              return $this->functions[$name];
 1130          }
 1131   
 1132          foreach ($this->functions as $pattern => $function) {
 1133              $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
 1134   
 1135              if ($count) {
 1136                  if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
 1137                      array_shift($matches);
 1138                      $function->setArguments($matches);
 1139   
 1140                      return $function;
 1141                  }
 1142              }
 1143          }
 1144   
 1145          foreach ($this->functionCallbacks as $callback) {
 1146              if (false !== $function = call_user_func($callback, $name)) {
 1147                  return $function;
 1148              }
 1149          }
 1150   
 1151          return false;
 1152      }
 1153   
 1154      public function registerUndefinedFunctionCallback($callable)
 1155      {
 1156          $this->functionCallbacks[] = $callable;
 1157      }
 1158   
 1159      /**
 1160       * Gets registered functions.
 1161       *
 1162       * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback.
 1163       *
 1164       * @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances
 1165       *
 1166       * @see registerUndefinedFunctionCallback
 1167       *
 1168       * @internal
 1169       */
 1170      public function getFunctions()
 1171      {
 1172          if (!$this->extensionInitialized) {
 1173              $this->initExtensions();
 1174          }
 1175   
 1176          return $this->functions;
 1177      }
 1178   
 1179      /**
 1180       * Registers a Global.
 1181       *
 1182       * New globals can be added before compiling or rendering a template;
 1183       * but after, you can only update existing globals.
 1184       *
 1185       * @param string $name  The global name
 1186       * @param mixed  $value The global value
 1187       */
 1188      public function addGlobal($name, $value)
 1189      {
 1190          if ($this->extensionInitialized || $this->runtimeInitialized) {
 1191              if (null === $this->globals) {
 1192                  $this->globals = $this->initGlobals();
 1193              }
 1194   
 1195              if (!array_key_exists($name, $this->globals)) {
 1196                  // The deprecation notice must be turned into the following exception in Twig 2.0
 1197                  @trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), E_USER_DEPRECATED);
 1198                  //throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
 1199              }
 1200          }
 1201   
 1202          if ($this->extensionInitialized || $this->runtimeInitialized) {
 1203              // update the value
 1204              $this->globals[$name] = $value;
 1205          } else {
 1206              $this->staging->addGlobal($name, $value);
 1207          }
 1208      }
 1209   
 1210      /**
 1211       * Gets the registered Globals.
 1212       *
 1213       * @return array An array of globals
 1214       *
 1215       * @internal
 1216       */
 1217      public function getGlobals()
 1218      {
 1219          if (!$this->runtimeInitialized && !$this->extensionInitialized) {
 1220              return $this->initGlobals();
 1221          }
 1222   
 1223          if (null === $this->globals) {
 1224              $this->globals = $this->initGlobals();
 1225          }
 1226   
 1227          return $this->globals;
 1228      }
 1229   
 1230      /**
 1231       * Merges a context with the defined globals.
 1232       *
 1233       * @param array $context An array representing the context
 1234       *
 1235       * @return array The context merged with the globals
 1236       */
 1237      public function mergeGlobals(array $context)
 1238      {
 1239          // we don't use array_merge as the context being generally
 1240          // bigger than globals, this code is faster.
 1241          foreach ($this->getGlobals() as $key => $value) {
 1242              if (!array_key_exists($key, $context)) {
 1243                  $context[$key] = $value;
 1244              }
 1245          }
 1246   
 1247          return $context;
 1248      }
 1249   
 1250      /**
 1251       * Gets the registered unary Operators.
 1252       *
 1253       * @return array An array of unary operators
 1254       *
 1255       * @internal
 1256       */
 1257      public function getUnaryOperators()
 1258      {
 1259          if (!$this->extensionInitialized) {
 1260              $this->initExtensions();
 1261          }
 1262   
 1263          return $this->unaryOperators;
 1264      }
 1265   
 1266      /**
 1267       * Gets the registered binary Operators.
 1268       *
 1269       * @return array An array of binary operators
 1270       *
 1271       * @internal
 1272       */
 1273      public function getBinaryOperators()
 1274      {
 1275          if (!$this->extensionInitialized) {
 1276              $this->initExtensions();
 1277          }
 1278   
 1279          return $this->binaryOperators;
 1280      }
 1281   
 1282      /**
 1283       * @deprecated since 1.23 (to be removed in 2.0)
 1284       */
 1285      public function computeAlternatives($name, $items)
 1286      {
 1287          @trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
 1288   
 1289          return Twig_Error_Syntax::computeAlternatives($name, $items);
 1290      }
 1291   
 1292      /**
 1293       * @internal
 1294       */
 1295      protected function initGlobals()
 1296      {
 1297          $globals = array();
 1298          foreach ($this->extensions as $name => $extension) {
 1299              if (!$extension instanceof Twig_Extension_GlobalsInterface) {
 1300                  $m = new ReflectionMethod($extension, 'getGlobals');
 1301   
 1302                  if ('Twig_Extension' !== $m->getDeclaringClass()->getName()) {
 1303                      @trigger_error(sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig_Extension_GlobalsInterface is deprecated since version 1.23.', $name), E_USER_DEPRECATED);
 1304                  }
 1305              }
 1306   
 1307              $extGlob = $extension->getGlobals();
 1308              if (!is_array($extGlob)) {
 1309                  throw new UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', get_class($extension)));
 1310              }
 1311   
 1312              $globals[] = $extGlob;
 1313          }
 1314   
 1315          $globals[] = $this->staging->getGlobals();
 1316   
 1317          return call_user_func_array('array_merge', $globals);
 1318      }
 1319   
 1320      /**
 1321       * @internal
 1322       */
 1323      protected function initExtensions()
 1324      {
 1325          if ($this->extensionInitialized) {
 1326              return;
 1327          }
 1328   
 1329          $this->extensionInitialized = true;
 1330          $this->parsers = new Twig_TokenParserBroker(array(), array(), false);
 1331          $this->filters = array();
 1332          $this->functions = array();
 1333          $this->tests = array();
 1334          $this->visitors = array();
 1335          $this->unaryOperators = array();
 1336          $this->binaryOperators = array();
 1337   
 1338          foreach ($this->extensions as $extension) {
 1339              $this->initExtension($extension);
 1340          }
 1341          $this->initExtension($this->staging);
 1342      }
 1343   
 1344      /**
 1345       * @internal
 1346       */
 1347      protected function initExtension(Twig_ExtensionInterface $extension)
 1348      {
 1349          // filters
 1350          foreach ($extension->getFilters() as $name => $filter) {
 1351              if ($filter instanceof Twig_SimpleFilter) {
 1352                  $name = $filter->getName();
 1353              } else {
 1354                  @trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use Twig_SimpleFilter instead.', get_class($filter), $name), E_USER_DEPRECATED);
 1355              }
 1356   
 1357              $this->filters[$name] = $filter;
 1358          }
 1359   
 1360          // functions
 1361          foreach ($extension->getFunctions() as $name => $function) {
 1362              if ($function instanceof Twig_SimpleFunction) {
 1363                  $name = $function->getName();
 1364              } else {
 1365                  @trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use Twig_SimpleFunction instead.', get_class($function), $name), E_USER_DEPRECATED);
 1366              }
 1367   
 1368              $this->functions[$name] = $function;
 1369          }
 1370   
 1371          // tests
 1372          foreach ($extension->getTests() as $name => $test) {
 1373              if ($test instanceof Twig_SimpleTest) {
 1374                  $name = $test->getName();
 1375              } else {
 1376                  @trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use Twig_SimpleTest instead.', get_class($test), $name), E_USER_DEPRECATED);
 1377              }
 1378   
 1379              $this->tests[$name] = $test;
 1380          }
 1381   
 1382          // token parsers
 1383          foreach ($extension->getTokenParsers() as $parser) {
 1384              if ($parser instanceof Twig_TokenParserInterface) {
 1385                  $this->parsers->addTokenParser($parser);
 1386              } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
 1387                  @trigger_error('Registering a Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', E_USER_DEPRECATED);
 1388   
 1389                  $this->parsers->addTokenParserBroker($parser);
 1390              } else {
 1391                  throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
 1392              }
 1393          }
 1394   
 1395          // node visitors
 1396          foreach ($extension->getNodeVisitors() as $visitor) {
 1397              $this->visitors[] = $visitor;
 1398          }
 1399   
 1400          // operators
 1401          if ($operators = $extension->getOperators()) {
 1402              if (2 !== count($operators)) {
 1403                  throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension)));
 1404              }
 1405   
 1406              $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
 1407              $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
 1408          }
 1409      }
 1410   
 1411      /**
 1412       * @deprecated since 1.22 (to be removed in 2.0)
 1413       */
 1414      protected function writeCacheFile($file, $content)
 1415      {
 1416          $this->cache->write($file, $content);
 1417      }
 1418  }
 1419