: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
public function isTemplateFresh($name, $time)
if (0 === $this->lastModifiedExtension) {
foreach ($this->extensions as $extension) {
$r = new \ReflectionObject($extension);
if (\file_exists($r->getFileName()) && ($extensionTime = \filemtime($r->getFileName())) > $this->lastModifiedExtension) {
$this->lastModifiedExtension = $extensionTime;
return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time);
* Tries to load a template consecutively from an array.
* Similar to load() but it also accepts instances of \Twig\Template and
* \Twig\TemplateWrapper, and an array of templates where each is tried to be loaded.
* @param string|Template|\Twig\TemplateWrapper|array $names A template or an array of templates to try consecutively
* @return TemplateWrapper|Template
* @throws LoaderError When none of the templates can be found
* @throws SyntaxError When an error occurred during compilation
public function resolveTemplate($names)
if (!\is_array($names)) {
foreach ($names as $name) {
if ($name instanceof \WPML\Core\Twig\Template) {
if ($name instanceof \WPML\Core\Twig\TemplateWrapper) {
return $this->loadTemplate($name);
} catch (\WPML\Core\Twig\Error\LoaderError $e) {
if (1 === \count($names)) {
throw new \WPML\Core\Twig\Error\LoaderError(\sprintf('Unable to find one of the following templates: "%s".', \implode('", "', $names)));
* Clears the internal template cache.
* @deprecated since 1.18.3 (to be removed in 2.0)
public function clearTemplateCache()
@\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);
$this->loadedTemplates = [];
* Clears the template cache files on the filesystem.
* @deprecated since 1.22 (to be removed in 2.0)
public function clearCacheFiles()
@\trigger_error(\sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
if (\is_string($this->originalCache)) {
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->originalCache), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
@\unlink($file->getPathname());
* Gets the Lexer instance.
* @return \Twig_LexerInterface
* @deprecated since 1.25 (to be removed in 2.0)
public function getLexer()
@\trigger_error(\sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);
if (null === $this->lexer) {
$this->lexer = new \WPML\Core\Twig\Lexer($this);
public function setLexer(\WPML\Core\Twig_LexerInterface $lexer)
* Tokenizes a source code.
* @param string|Source $source The template source code
* @param string $name The template name (deprecated)
* @throws SyntaxError When the code is syntactically wrong
public function tokenize($source, $name = null)
if (!$source instanceof \WPML\Core\Twig\Source) {
@\trigger_error(\sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
$source = new \WPML\Core\Twig\Source($source, $name);
if (null === $this->lexer) {
$this->lexer = new \WPML\Core\Twig\Lexer($this);
return $this->lexer->tokenize($source);
* Gets the Parser instance.
* @return \Twig_ParserInterface
* @deprecated since 1.25 (to be removed in 2.0)
public function getParser()
@\trigger_error(\sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);
if (null === $this->parser) {
$this->parser = new \WPML\Core\Twig\Parser($this);
public function setParser(\WPML\Core\Twig_ParserInterface $parser)
* Converts a token stream to a node tree.
* @throws SyntaxError When the token stream is syntactically or semantically wrong
public function parse(\WPML\Core\Twig\TokenStream $stream)
if (null === $this->parser) {
$this->parser = new \WPML\Core\Twig\Parser($this);
return $this->parser->parse($stream);
* Gets the Compiler instance.
* @return \Twig_CompilerInterface
* @deprecated since 1.25 (to be removed in 2.0)
public function getCompiler()
@\trigger_error(\sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);
if (null === $this->compiler) {
$this->compiler = new \WPML\Core\Twig\Compiler($this);
public function setCompiler(\WPML\Core\Twig_CompilerInterface $compiler)
$this->compiler = $compiler;
* Compiles a node and returns the PHP code.
* @return string The compiled PHP source code
public function compile(\WPML\Core\Twig_NodeInterface $node)
if (null === $this->compiler) {
$this->compiler = new \WPML\Core\Twig\Compiler($this);
return $this->compiler->compile($node)->getSource();
* Compiles a template source code.
* @param string|Source $source The template source code
* @param string $name The template name (deprecated)
* @return string The compiled PHP source code
* @throws SyntaxError When there was an error during tokenizing, parsing or compiling
public function compileSource($source, $name = null)
if (!$source instanceof \WPML\Core\Twig\Source) {
@\trigger_error(\sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
$source = new \WPML\Core\Twig\Source($source, $name);
return $this->compile($this->parse($this->tokenize($source)));
} catch (\WPML\Core\Twig\Error\Error $e) {
$e->setSourceContext($source);
} catch (\Exception $e) {
throw new \WPML\Core\Twig\Error\SyntaxError(\sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e);
public function setLoader(\WPML\Core\Twig\Loader\LoaderInterface $loader)
if (!$loader instanceof \WPML\Core\Twig\Loader\SourceContextLoaderInterface && 0 !== \strpos(\get_class($loader), 'Mock_')) {
@\trigger_error(\sprintf('Twig loader "%s" should implement Twig\\Loader\\SourceContextLoaderInterface since version 1.27.', \get_class($loader)), \E_USER_DEPRECATED);
* Gets the Loader instance.
* @return LoaderInterface
public function getLoader()
if (null === $this->loader) {
throw new \LogicException('You must set a loader first.');
* Sets the default template charset.
* @param string $charset The default charset
public function setCharset($charset)
$this->charset = \strtoupper($charset);
* Gets the default template charset.
* @return string The default charset
public function getCharset()
* Initializes the runtime environment.
* @deprecated since 1.23 (to be removed in 2.0)
public function initRuntime()
$this->runtimeInitialized = \true;
foreach ($this->getExtensions() as $name => $extension) {
if (!$extension instanceof \WPML\Core\Twig\Extension\InitRuntimeInterface) {
$m = new \ReflectionMethod($extension, 'initRuntime');
$parentClass = $m->getDeclaringClass()->getName();
if ('Twig_Extension' !== $parentClass && 'WPML\\Core\\Twig\\Extension\\AbstractExtension' !== $parentClass) {
@\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);
$extension->initRuntime($this);
* Returns true if the given extension is registered.
* @param string $class The extension class name
* @return bool Whether the extension is registered or not
public function hasExtension($class)
$class = \ltrim($class, '\\');
if (!isset($this->extensionsByClass[$class]) && \class_exists($class, \false)) {
// For BC/FC with namespaced aliases
$class = new \ReflectionClass($class);
if (isset($this->extensions[$class])) {
if ($class !== \get_class($this->extensions[$class])) {
@\trigger_error(\sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), \E_USER_DEPRECATED);
return isset($this->extensionsByClass[$class]);
public function addRuntimeLoader(\WPML\Core\Twig\RuntimeLoader\RuntimeLoaderInterface $loader)
$this->runtimeLoaders[] = $loader;
* Gets an extension by class name.
* @param string $class The extension class name
* @return ExtensionInterface
public function getExtension($class)
$class = \ltrim($class, '\\');
if (!isset($this->extensionsByClass[$class]) && \class_exists($class, \false)) {
// For BC/FC with namespaced aliases
$class = new \ReflectionClass($class);
if (isset($this->extensions[$class])) {
if ($class !== \get_class($this->extensions[$class])) {
@\trigger_error(\sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), \E_USER_DEPRECATED);
return $this->extensions[$class];
if (!isset($this->extensionsByClass[$class])) {
throw new \WPML\Core\Twig\Error\RuntimeError(\sprintf('The "%s" extension is not enabled.', $class));
return $this->extensionsByClass[$class];
* Returns the runtime implementation of a Twig element (filter/function/test).
* @param string $class A runtime class name
* @return object The runtime implementation
* @throws RuntimeError When the template cannot be found
public function getRuntime($class)
if (isset($this->runtimes[$class])) {
return $this->runtimes[$class];
foreach ($this->runtimeLoaders as $loader) {
if (null !== ($runtime = $loader->load($class))) {
return $this->runtimes[$class] = $runtime;
throw new \WPML\Core\Twig\Error\RuntimeError(\sprintf('Unable to load the "%s" runtime.', $class));
public function addExtension(\WPML\Core\Twig\Extension\ExtensionInterface $extension)
if ($this->extensionInitialized) {
throw new \LogicException(\sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
$class = \get_class($extension);
if ($class !== $extension->getName()) {
if (isset($this->extensions[$extension->getName()])) {
unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
@\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.', $extension->getName()), \E_USER_DEPRECATED);
$this->lastModifiedExtension = 0;
$this->extensionsByClass[$class] = $extension;
$this->extensions[$extension->getName()] = $extension;
$this->updateOptionsHash();
* Removes an extension by name.
* This method is deprecated and you should not use it.
* @param string $name The extension name
* @deprecated since 1.12 (to be removed in 2.0)
public function removeExtension($name)
@\trigger_error(\sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
if ($this->extensionInitialized) {
throw new \LogicException(\sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
$class = \ltrim($name, '\\');
if (!isset($this->extensionsByClass[$class]) && \class_exists($class, \false)) {
// For BC/FC with namespaced aliases
$class = new \ReflectionClass($class);
if (isset($this->extensions[$class])) {
if ($class !== \get_class($this->extensions[$class])) {
@\trigger_error(\sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), \E_USER_DEPRECATED);
unset($this->extensions[$class]);
unset($this->extensions[$class]);
$this->updateOptionsHash();
* Registers an array of extensions.
* @param array $extensions An array of extensions
public function setExtensions(array $extensions)
foreach ($extensions as $extension) {
$this->addExtension($extension);
* Returns all registered extensions.
* @return ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
public function getExtensions()
return $this->extensions;
public function addTokenParser(\WPML\Core\Twig\TokenParser\TokenParserInterface $parser)
if ($this->extensionInitialized) {
throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
$this->staging->addTokenParser($parser);
* Gets the registered Token Parsers.
* @return \Twig_TokenParserBrokerInterface
public function getTokenParsers()
if (!$this->extensionInitialized) {
* Be warned that this method cannot return tags defined by \Twig_TokenParserBrokerInterface classes.
* @return TokenParserInterface[]
public function getTags()
foreach ($this->getTokenParsers()->getParsers() as $parser) {
if ($parser instanceof \WPML\Core\Twig\TokenParser\TokenParserInterface) {
$tags[$parser->getTag()] = $parser;
public function addNodeVisitor(\WPML\Core\Twig\NodeVisitor\NodeVisitorInterface $visitor)
if ($this->extensionInitialized) {
throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
$this->staging->addNodeVisitor($visitor);
* Gets the registered Node Visitors.
* @return NodeVisitorInterface[]
public function getNodeVisitors()
if (!$this->extensionInitialized) {
* @param string|TwigFilter $name The filter name or a \Twig_SimpleFilter instance
* @param \Twig_FilterInterface|TwigFilter $filter
public function addFilter($name, $filter = null)
if (!$name instanceof \WPML\Core\Twig\TwigFilter && !($filter instanceof \WPML\Core\Twig\TwigFilter || $filter instanceof \WPML\Core\Twig_FilterInterface)) {
throw new \LogicException('A filter must be an instance of \\Twig_FilterInterface or \\Twig_SimpleFilter.');
if ($name instanceof \WPML\Core\Twig\TwigFilter) {
$name = $filter->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_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), \E_USER_DEPRECATED);
if ($this->extensionInitialized) {
throw new \LogicException(\sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
$this->staging->addFilter($name, $filter);
* Subclasses may override this method and load filters differently;
* so no list of filters is available.
* @param string $name The filter name
* @return \Twig_Filter|false
public function getFilter($name)
if (!$this->extensionInitialized) {