mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-15 11:56:50 +00:00
changed the way globals behave to be more BC with 1.11 and to avoid speed problems at runtime introduced in 4487387 (closes #932)
* Globals are now managed by themselves, independently of other elements contained in extensions * A global variable value can now be changed after the runtime has been initialized (to be more BC with the way Twig 1.11 works) * Extensions are not initialized anymore when rendering a template that is already in the cache (like in Twig 1.11)
This commit is contained in:
@@ -964,16 +964,24 @@ class Twig_Environment
|
||||
/**
|
||||
* 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) {
|
||||
throw new LogicException(sprintf('Unable to add global "%s" as extensions have already been initialized.', $name));
|
||||
if (($this->extensionInitialized || $this->runtimeInitialized) && !array_key_exists($name, $this->globals)) {
|
||||
throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
|
||||
}
|
||||
|
||||
$this->staging->addGlobal($name, $value);
|
||||
if ($this->extensionInitialized || $this->runtimeInitialized) {
|
||||
// update the value
|
||||
$this->globals[$name] = $value;
|
||||
} else {
|
||||
$this->staging->addGlobal($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -983,8 +991,8 @@ class Twig_Environment
|
||||
*/
|
||||
public function getGlobals()
|
||||
{
|
||||
if (!$this->extensionInitialized) {
|
||||
$this->initExtensions();
|
||||
if (null === $this->globals || !($this->runtimeInitialized || $this->extensionInitialized)) {
|
||||
$this->initGlobals();
|
||||
}
|
||||
|
||||
return $this->globals;
|
||||
@@ -1052,6 +1060,15 @@ class Twig_Environment
|
||||
return array_keys($alternatives);
|
||||
}
|
||||
|
||||
protected function initGlobals()
|
||||
{
|
||||
$this->globals = array();
|
||||
foreach ($this->extensions as $extension) {
|
||||
$this->globals = array_merge($this->globals, $extension->getGlobals());
|
||||
}
|
||||
$this->globals = array_merge($this->globals, $this->staging->getGlobals());
|
||||
}
|
||||
|
||||
protected function initExtensions()
|
||||
{
|
||||
if ($this->extensionInitialized) {
|
||||
@@ -1063,7 +1080,6 @@ class Twig_Environment
|
||||
$this->filters = array();
|
||||
$this->functions = array();
|
||||
$this->tests = array();
|
||||
$this->globals = array();
|
||||
$this->visitors = array();
|
||||
$this->unaryOperators = array();
|
||||
$this->binaryOperators = array();
|
||||
@@ -1112,9 +1128,6 @@ class Twig_Environment
|
||||
$this->tests[$name] = $test;
|
||||
}
|
||||
|
||||
// globals
|
||||
$this->globals = array_merge($this->globals, $extension->getGlobals());
|
||||
|
||||
// token parsers
|
||||
foreach ($extension->getTokenParsers() as $parser) {
|
||||
if ($parser instanceof Twig_TokenParserInterface) {
|
||||
|
||||
@@ -33,6 +33,111 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
|
||||
return $filename;
|
||||
}
|
||||
|
||||
public function testGlobals()
|
||||
{
|
||||
// globals can be added after calling getGlobals
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
$twig->addGlobal('foo', 'foo');
|
||||
$globals = $twig->getGlobals();
|
||||
$twig->addGlobal('foo', 'bar');
|
||||
$globals = $twig->getGlobals();
|
||||
$this->assertEquals('bar', $globals['foo']);
|
||||
|
||||
// globals can be modified after runtime init
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
$twig->addGlobal('foo', 'foo');
|
||||
$globals = $twig->getGlobals();
|
||||
$twig->initRuntime();
|
||||
$twig->addGlobal('foo', 'bar');
|
||||
$globals = $twig->getGlobals();
|
||||
$this->assertEquals('bar', $globals['foo']);
|
||||
|
||||
// globals can be modified after extensions init
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
$twig->addGlobal('foo', 'foo');
|
||||
$globals = $twig->getGlobals();
|
||||
$twig->getFunctions();
|
||||
$twig->addGlobal('foo', 'bar');
|
||||
$globals = $twig->getGlobals();
|
||||
$this->assertEquals('bar', $globals['foo']);
|
||||
|
||||
// globals can be modified after extensions and runtime init
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
$twig->addGlobal('foo', 'foo');
|
||||
$globals = $twig->getGlobals();
|
||||
$twig->getFunctions();
|
||||
$twig->initRuntime();
|
||||
$twig->addGlobal('foo', 'bar');
|
||||
$globals = $twig->getGlobals();
|
||||
$this->assertEquals('bar', $globals['foo']);
|
||||
|
||||
// globals cannot be added after runtime init
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
$twig->addGlobal('foo', 'foo');
|
||||
$globals = $twig->getGlobals();
|
||||
$twig->initRuntime();
|
||||
try {
|
||||
$twig->addGlobal('bar', 'bar');
|
||||
$this->fail();
|
||||
} catch (LogicException $e) {
|
||||
$this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
|
||||
}
|
||||
|
||||
// globals cannot be added after extensions init
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
$twig->addGlobal('foo', 'foo');
|
||||
$globals = $twig->getGlobals();
|
||||
$twig->getFunctions();
|
||||
try {
|
||||
$twig->addGlobal('bar', 'bar');
|
||||
$this->fail();
|
||||
} catch (LogicException $e) {
|
||||
$this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
|
||||
}
|
||||
|
||||
// globals cannot be added after extensions and runtime init
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
$twig->addGlobal('foo', 'foo');
|
||||
$globals = $twig->getGlobals();
|
||||
$twig->getFunctions();
|
||||
$twig->initRuntime();
|
||||
try {
|
||||
$twig->addGlobal('bar', 'bar');
|
||||
$this->fail();
|
||||
} catch (LogicException $e) {
|
||||
$this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
|
||||
}
|
||||
}
|
||||
|
||||
public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
|
||||
{
|
||||
$options = array('cache' => sys_get_temp_dir().'/twig', 'auto_reload' => false, 'debug' => false);
|
||||
|
||||
// force compilation
|
||||
$twig = new Twig_Environment(new Twig_Loader_String(), $options);
|
||||
$cache = $twig->getCacheFilename('{{ foo }}');
|
||||
if (!is_dir(dirname($cache))) {
|
||||
mkdir(dirname($cache), 0777, true);
|
||||
}
|
||||
file_put_contents($cache, $twig->compileSource('{{ foo }}', '{{ foo }}'));
|
||||
|
||||
// check that extensions won't be initialized when rendering a template that is already in the cache
|
||||
$twig = $this
|
||||
->getMockBuilder('Twig_Environment')
|
||||
->setConstructorArgs(array(new Twig_Loader_String(), $options))
|
||||
->setMethods(array('initExtensions'))
|
||||
->getMock()
|
||||
;
|
||||
|
||||
$twig->expects($this->never())->method('initExtensions');
|
||||
|
||||
// render template
|
||||
$output = $twig->render('{{ foo }}', array('foo' => 'bar'));
|
||||
$this->assertEquals('bar', $output);
|
||||
|
||||
unlink($cache);
|
||||
}
|
||||
|
||||
public function testAddExtension()
|
||||
{
|
||||
$twig = new Twig_Environment(new Twig_Loader_String());
|
||||
|
||||
Reference in New Issue
Block a user