: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if (isset($this->filters[$name])) {
return $this->filters[$name];
foreach ($this->filters as $pattern => $filter) {
$pattern = \str_replace('\\*', '(.*?)', \preg_quote($pattern, '#'), $count);
if (\preg_match('#^' . $pattern . '$#', $name, $matches)) {
$filter->setArguments($matches);
foreach ($this->filterCallbacks as $callback) {
if (\false !== ($filter = \call_user_func($callback, $name))) {
public function registerUndefinedFilterCallback($callable)
$this->filterCallbacks[] = $callable;
* Gets the registered Filters.
* Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
* @return \Twig_FilterInterface[]
* @see registerUndefinedFilterCallback
public function getFilters()
if (!$this->extensionInitialized) {
* @param string|TwigTest $name The test name or a \Twig_SimpleTest instance
* @param \Twig_TestInterface|TwigTest $test A \Twig_TestInterface instance or a \Twig_SimpleTest instance
public function addTest($name, $test = null)
if (!$name instanceof \WPML\Core\Twig\TwigTest && !($test instanceof \WPML\Core\Twig\TwigTest || $test instanceof \WPML\Core\Twig_TestInterface)) {
throw new \LogicException('A test must be an instance of \\Twig_TestInterface or \\Twig_SimpleTest.');
if ($name instanceof \WPML\Core\Twig\TwigTest) {
$name = $test->getName();
@\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);
if ($this->extensionInitialized) {
throw new \LogicException(\sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
$this->staging->addTest($name, $test);
* Gets the registered Tests.
* @return \Twig_TestInterface[]
public function getTests()
if (!$this->extensionInitialized) {
* @param string $name The test name
* @return \Twig_Test|false
public function getTest($name)
if (!$this->extensionInitialized) {
if (isset($this->tests[$name])) {
return $this->tests[$name];
foreach ($this->tests as $pattern => $test) {
$pattern = \str_replace('\\*', '(.*?)', \preg_quote($pattern, '#'), $count);
if (\preg_match('#^' . $pattern . '$#', $name, $matches)) {
$test->setArguments($matches);
* @param string|TwigFunction $name The function name or a \Twig_SimpleFunction instance
* @param \Twig_FunctionInterface|TwigFunction $function
public function addFunction($name, $function = null)
if (!$name instanceof \WPML\Core\Twig\TwigFunction && !($function instanceof \WPML\Core\Twig\TwigFunction || $function instanceof \WPML\Core\Twig_FunctionInterface)) {
throw new \LogicException('A function must be an instance of \\Twig_FunctionInterface or \\Twig_SimpleFunction.');
if ($name instanceof \WPML\Core\Twig\TwigFunction) {
$name = $function->getName();
@\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);
if ($this->extensionInitialized) {
throw new \LogicException(\sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
$this->staging->addFunction($name, $function);
* Get a function by name.
* Subclasses may override this method and load functions differently;
* so no list of functions is available.
* @param string $name function name
* @return \Twig_Function|false
public function getFunction($name)
if (!$this->extensionInitialized) {
if (isset($this->functions[$name])) {
return $this->functions[$name];
foreach ($this->functions as $pattern => $function) {
$pattern = \str_replace('\\*', '(.*?)', \preg_quote($pattern, '#'), $count);
if (\preg_match('#^' . $pattern . '$#', $name, $matches)) {
$function->setArguments($matches);
foreach ($this->functionCallbacks as $callback) {
if (\false !== ($function = \call_user_func($callback, $name))) {
public function registerUndefinedFunctionCallback($callable)
$this->functionCallbacks[] = $callable;
* Gets registered functions.
* Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback.
* @return \Twig_FunctionInterface[]
* @see registerUndefinedFunctionCallback
public function getFunctions()
if (!$this->extensionInitialized) {
* 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) {
$this->globals[$name] = $value;
$this->staging->addGlobal($name, $value);
* Gets the registered Globals.
* @return array An array of globals
public function getGlobals()
if (!$this->runtimeInitialized && !$this->extensionInitialized) {
return $this->initGlobals();
if (null === $this->globals) {
$this->globals = $this->initGlobals();
* 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)) {
* Gets the registered unary Operators.
* @return array An array of unary operators
public function getUnaryOperators()
if (!$this->extensionInitialized) {
return $this->unaryOperators;
* Gets the registered binary Operators.
* @return array An array of binary operators
public function getBinaryOperators()
if (!$this->extensionInitialized) {
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);
protected function initGlobals()
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[] = $this->staging->getGlobals();
return \call_user_func_array('array_merge', $globals);
protected function initExtensions()
if ($this->extensionInitialized) {
$this->parsers = new \WPML\Core\Twig_TokenParserBroker([], [], \false);
$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;
protected function initExtension(\WPML\Core\Twig\Extension\ExtensionInterface $extension)
foreach ($extension->getFilters() as $name => $filter) {
if ($filter instanceof \WPML\Core\Twig\TwigFilter) {
$name = $filter->getName();
@\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;
foreach ($extension->getFunctions() as $name => $function) {
if ($function instanceof \WPML\Core\Twig\TwigFunction) {
$name = $function->getName();
@\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;
foreach ($extension->getTests() as $name => $test) {
if ($test instanceof \WPML\Core\Twig\TwigTest) {
$name = $test->getName();
@\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;
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);
throw new \LogicException('getTokenParsers() must return an array of \\Twig_TokenParserInterface or \\Twig_TokenParserBrokerInterface instances.');
foreach ($extension->getNodeVisitors() as $visitor) {
$this->visitors[] = $visitor;
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');