$this->initExtensions(); } return $this->functions; } /** * Registers a Global. * * New globals can be added before compiling or rendering a template; * but after, you can only update existing globals. * * @param string $name The global name * @param mixed $value The global value */ public function addGlobal($name, $value) { if ($this->extensionInitialized || $this->runtimeInitialized) { if (null === $this->globals) { $this->globals = $this->initGlobals(); } if (!\array_key_exists($name, $this->globals)) { // The deprecation notice must be turned into the following exception in Twig 2.0 @\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); //throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name)); } } if ($this->extensionInitialized || $this->runtimeInitialized) { // update the value $this->globals[$name] = $value; } else { $this->staging->addGlobal($name, $value); } } /** * Gets the registered Globals. * * @return array An array of globals * * @internal */ public function getGlobals() { if (!$this->runtimeInitialized && !$this->extensionInitialized) { return $this->initGlobals(); } if (null === $this->globals) { $this->globals = $this->initGlobals(); } return $this->globals; } /** * Merges a context with the defined globals. * * @param array $context An array representing the context * * @return array The context merged with the globals */ public function mergeGlobals(array $context) { // we don't use array_merge as the context being generally // bigger than globals, this code is faster. foreach ($this->getGlobals() as $key => $value) { if (!\array_key_exists($key, $context)) { $context[$key] = $value; } } return $context; } /** * Gets the registered unary Operators. * * @return array An array of unary operators * * @internal */ public function getUnaryOperators() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->unaryOperators; } /** * Gets the registered binary Operators. * * @return array An array of binary operators * * @internal */ public function getBinaryOperators() { if (!$this->extensionInitialized) { $this->initExtensions(); } return $this->binaryOperators; } /** * @deprecated since 1.23 (to be removed in 2.0) */ public function computeAlternatives($name, $items) { @\trigger_error(\sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED); return \WPML\Core\Twig\Error\SyntaxError::computeAlternatives($name, $items); } /** * @internal */ protected function initGlobals() { $globals = []; foreach ($this->extensions as $name => $extension) { if (!$extension instanceof \WPML\Core\Twig\Extension\GlobalsInterface) { $m = new \ReflectionMethod($extension, 'getGlobals'); $parentClass = $m->getDeclaringClass()->getName(); if ('Twig_Extension' !== $parentClass && 'WPML\\Core\\Twig\\Extension\\AbstractExtension' !== $parentClass) { @\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); } } $extGlob = $extension->getGlobals(); if (!\is_array($extGlob)) { throw new \UnexpectedValueException(\sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension))); } $globals[] = $extGlob; } $globals[] = $this->staging->getGlobals(); return \call_user_func_array('array_merge', $globals); } /** * @internal */ protected function initExtensions() { if ($this->extensionInitialized) { return; } $this->parsers = new \WPML\Core\Twig_TokenParserBroker([], [], \false); $this->filters = []; $this->functions = []; $this->tests = []; $this->visitors = []; $this->unaryOperators = []; $this->binaryOperators = []; foreach ($this->extensions as $extension) { $this->initExtension($extension); } $this->initExtension($this->staging); // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception $this->extensionInitialized = \true; } /** * @internal */ protected function initExtension(\WPML\Core\Twig\Extension\ExtensionInterface $extension) { // filters foreach ($extension->getFilters() as $name => $filter) { if ($filter instanceof \WPML\Core\Twig\TwigFilter) { $name = $filter->getName(); } else { @\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); } $this->filters[$name] = $filter; } // functions foreach ($extension->getFunctions() as $name => $function) { if ($function instanceof \WPML\Core\Twig\TwigFunction) { $name = $function->getName(); } else { @\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); } $this->functions[$name] = $function; } // tests foreach ($extension->getTests() as $name => $test) { if ($test instanceof \WPML\Core\Twig\TwigTest) { $name = $test->getName(); } else { @\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); } $this->tests[$name] = $test; } // token parsers foreach ($extension->getTokenParsers() as $parser) { if ($parser instanceof \WPML\Core\Twig\TokenParser\TokenParserInterface) { $this->parsers->addTokenParser($parser); } elseif ($parser instanceof \WPML\Core\Twig_TokenParserBrokerInterface) { @\trigger_error('Registering a \\Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', \E_USER_DEPRECATED); $this->parsers->addTokenParserBroker($parser); } else { throw new \LogicException('getTokenParsers() must return an array of \\Twig_TokenParserInterface or \\Twig_TokenParserBrokerInterface instances.'); } } // node visitors foreach ($extension->getNodeVisitors() as $visitor) { $this->visitors[] = $visitor; } // operators if ($operators = $extension->getOperators()) { if (!\is_array($operators)) { 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))); } if (2 !== \count($operators)) { throw new \InvalidArgumentException(\sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators))); } $this->unaryOperators = \array_merge($this->unaryOperators, $operators[0]); $this->binaryOperators = \array_merge($this->binaryOperators, $operators[1]); } } /** * @deprecated since 1.22 (to be removed in 2.0) */ protected function writeCacheFile($file, $content) { $this->cache->write($file, $content); } private function updateOptionsHash() { $hashParts = \array_merge(\array_keys($this->extensions), [(int) \function_exists('WPML\\Core\\twig_template_get_attributes'), \PHP_MAJOR_VERSION, \PHP_MINOR_VERSION, self::VERSION, (int) $this->debug, $this->baseTemplateClass, (int) $this->strictVariables]); $this->optionsHash = \implode(':', $hashParts); } } \class_alias('WPML\\Core\\Twig\\Environment', 'WPML\\Core\\Twig_Environment');