deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr

This commit is contained in:
Fabien Potencier
2016-12-17 21:03:08 +01:00
parent 2c92684f15
commit 014ab1f8e1
3 changed files with 56 additions and 121 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
* 1.29.1 (2017-XX-XX) * 1.29.1 (2017-XX-XX)
* n/a * deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr
* 1.29.0 (2016-12-13) * 1.29.0 (2016-12-13)
+4
View File
@@ -23,6 +23,10 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
public function compile(Twig_Compiler $compiler) public function compile(Twig_Compiler $compiler)
{ {
if ($this->getAttribute('disable_c_ext')) {
@trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED);
}
if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) { if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
$compiler->raw('twig_template_get_attributes($this, '); $compiler->raw('twig_template_get_attributes($this, ');
} else { } else {
+51 -120
View File
@@ -22,18 +22,11 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
/** /**
* @dataProvider getAttributeExceptions * @dataProvider getAttributeExceptions
*/ */
public function testGetAttributeExceptions($template, $message, $useExt) public function testGetAttributeExceptions($template, $message)
{ {
$name = 'index_'.($useExt ? 1 : 0); $templates = array('index' => $template);
$templates = array(
$name => $template.$useExt, // appending $useExt makes the template content unique
);
$env = new Twig_Environment(new Twig_Loader_Array($templates), array('strict_variables' => true)); $env = new Twig_Environment(new Twig_Loader_Array($templates), array('strict_variables' => true));
if (!$useExt) { $template = $env->loadTemplate('index');
$env->addNodeVisitor(new CExtDisablingNodeVisitor());
}
$template = $env->loadTemplate($name);
$context = array( $context = array(
'string' => 'foo', 'string' => 'foo',
@@ -49,50 +42,41 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
$template->render($context); $template->render($context);
$this->fail('Accessing an invalid attribute should throw an exception.'); $this->fail('Accessing an invalid attribute should throw an exception.');
} catch (Twig_Error_Runtime $e) { } catch (Twig_Error_Runtime $e) {
$this->assertSame(sprintf($message, $name), $e->getMessage()); $this->assertSame(sprintf($message, 'index'), $e->getMessage());
} }
} }
public function getAttributeExceptions() public function getAttributeExceptions()
{ {
$tests = array( return array(
array('{{ string["a"] }}', 'Impossible to access a key ("a") on a string variable ("foo") in "%s" at line 1.', false), array('{{ string["a"] }}', 'Impossible to access a key ("a") on a string variable ("foo") in "%s" at line 1.'),
array('{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1.', false), array('{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1.'),
array('{{ empty_array["a"] }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.', false), array('{{ empty_array["a"] }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.'),
array('{{ array["a"] }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.', false), array('{{ array["a"] }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.'),
array('{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1.', false), array('{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1.'),
array('{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1.', false), array('{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1.'),
array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1.', false), array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1.'),
array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1.', false), array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1.'),
array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1.', false), array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1.'),
array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.', false), array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.'),
array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.', false), array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.'),
array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1.', false), array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1.'),
array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.', false), array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.'),
array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.', false), array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.'),
array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false), array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.'),
array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1.', false), array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1.'),
); );
if (function_exists('twig_template_get_attributes')) {
foreach (array_slice($tests, 0) as $test) {
$test[2] = true;
$tests[] = $test;
}
}
return $tests;
} }
/** /**
* @dataProvider getGetAttributeWithSandbox * @dataProvider getGetAttributeWithSandbox
*/ */
public function testGetAttributeWithSandbox($object, $item, $allowed, $useExt) public function testGetAttributeWithSandbox($object, $item, $allowed)
{ {
$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
$policy = new Twig_Sandbox_SecurityPolicy(array(), array(), array(/*method*/), array(/*prop*/), array()); $policy = new Twig_Sandbox_SecurityPolicy(array(), array(), array(/*method*/), array(/*prop*/), array());
$twig->addExtension(new Twig_Extension_Sandbox($policy, !$allowed)); $twig->addExtension(new Twig_Extension_Sandbox($policy, !$allowed));
$template = new Twig_TemplateTest($twig, $useExt); $template = new Twig_TemplateTest($twig);
try { try {
$template->getAttribute($object, $item, array(), 'any'); $template->getAttribute($object, $item, array(), 'any');
@@ -111,35 +95,25 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
public function getGetAttributeWithSandbox() public function getGetAttributeWithSandbox()
{ {
$tests = array( return array(
array(new Twig_TemplatePropertyObject(), 'defined', false, false), array(new Twig_TemplatePropertyObject(), 'defined', false),
array(new Twig_TemplatePropertyObject(), 'defined', true, false), array(new Twig_TemplatePropertyObject(), 'defined', true),
array(new Twig_TemplateMethodObject(), 'defined', false, false), array(new Twig_TemplateMethodObject(), 'defined', false),
array(new Twig_TemplateMethodObject(), 'defined', true, false), array(new Twig_TemplateMethodObject(), 'defined', true),
); );
if (function_exists('twig_template_get_attributes')) {
foreach (array_slice($tests, 0) as $test) {
$test[3] = true;
$tests[] = $test;
}
}
return $tests;
} }
/** /**
* @dataProvider getGetAttributeWithTemplateAsObject
* @group legacy * @group legacy
*/ */
public function testGetAttributeWithTemplateAsObject($useExt) public function testGetAttributeWithTemplateAsObject()
{ {
// to be removed in 2.0 // to be removed in 2.0
$twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock()); $twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock());
//$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface')->getMock()); //$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface')->getMock());
$template = new Twig_TemplateTest($twig, $useExt, 'index.twig'); $template = new Twig_TemplateTest($twig, 'index.twig');
$template1 = new Twig_TemplateTest($twig, false, 'index1.twig'); $template1 = new Twig_TemplateTest($twig, 'index1.twig');
$this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'string')); $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'string'));
$this->assertEquals('some_string', $template->getAttribute($template1, 'string')); $this->assertEquals('some_string', $template->getAttribute($template1, 'string'));
@@ -159,19 +133,6 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
$this->assertFalse($template->getAttribute($template1, 'displayWithErrorHandling', array(), Twig_Template::METHOD_CALL, true)); $this->assertFalse($template->getAttribute($template1, 'displayWithErrorHandling', array(), Twig_Template::METHOD_CALL, true));
} }
public function getGetAttributeWithTemplateAsObject()
{
$bools = array(
array(false),
);
if (function_exists('twig_template_get_attributes')) {
$bools[] = array(true);
}
return $bools;
}
/** /**
* @group legacy * @group legacy
* @expectedDeprecation Calling "getString" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. * @expectedDeprecation Calling "getString" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0.
@@ -199,8 +160,8 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
$twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock()); $twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock());
//$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface')->getMock()); //$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface')->getMock());
$template = new Twig_TemplateTest($twig, false, 'index.twig'); $template = new Twig_TemplateTest($twig, 'index.twig');
$template1 = new Twig_TemplateTest($twig, false, 'index1.twig'); $template1 = new Twig_TemplateTest($twig, 'index1.twig');
$this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'string')); $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'string'));
$this->assertEquals('some_string', $template->getAttribute($template1, 'string')); $this->assertEquals('some_string', $template->getAttribute($template1, 'string'));
@@ -244,20 +205,14 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
{ {
$twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock()); $twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock());
$template = new Twig_TemplateTest($twig, false, 'index.twig'); $template = new Twig_TemplateTest($twig, 'index.twig');
$template->renderBlock('unknown', array()); $template->renderBlock('unknown', array());
$template->displayBlock('unknown', array()); $template->displayBlock('unknown', array());
} }
/** public function testGetAttributeOnArrayWithConfusableKey()
* @dataProvider getTestsDependingOnExtensionAvailability
*/
public function testGetAttributeOnArrayWithConfusableKey($useExt = false)
{ {
$template = new Twig_TemplateTest( $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()),
$useExt
);
$array = array('Zero', 'One', -1 => 'MinusOne', '' => 'EmptyString', '1.5' => 'FloatButString', '01' => 'IntegerButStringWithLeadingZeros'); $array = array('Zero', 'One', -1 => 'MinusOne', '' => 'EmptyString', '1.5' => 'FloatButString', '01' => 'IntegerButStringWithLeadingZeros');
@@ -280,21 +235,12 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
$this->assertSame('EmptyString', $template->getAttribute($array, null), 'null is treated as "" when accessing an array (equals PHP behavior)'); $this->assertSame('EmptyString', $template->getAttribute($array, null), 'null is treated as "" when accessing an array (equals PHP behavior)');
} }
public function getTestsDependingOnExtensionAvailability()
{
if (function_exists('twig_template_get_attributes')) {
return array(array(false), array(true));
}
return array(array(false));
}
/** /**
* @dataProvider getGetAttributeTests * @dataProvider getGetAttributeTests
*/ */
public function testGetAttribute($defined, $value, $object, $item, $arguments, $type, $useExt = false) public function testGetAttribute($defined, $value, $object, $item, $arguments, $type)
{ {
$template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), $useExt); $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
$this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type));
} }
@@ -302,9 +248,9 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
/** /**
* @dataProvider getGetAttributeTests * @dataProvider getGetAttributeTests
*/ */
public function testGetAttributeStrict($defined, $value, $object, $item, $arguments, $type, $useExt = false, $exceptionMessage = null) public function testGetAttributeStrict($defined, $value, $object, $item, $arguments, $type, $exceptionMessage = null)
{ {
$template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true)), $useExt); $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true)));
if ($defined) { if ($defined) {
$this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type));
@@ -324,9 +270,9 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
/** /**
* @dataProvider getGetAttributeTests * @dataProvider getGetAttributeTests
*/ */
public function testGetAttributeDefined($defined, $value, $object, $item, $arguments, $type, $useExt = false) public function testGetAttributeDefined($defined, $value, $object, $item, $arguments, $type)
{ {
$template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), $useExt); $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
$this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true)); $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true));
} }
@@ -334,19 +280,16 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
/** /**
* @dataProvider getGetAttributeTests * @dataProvider getGetAttributeTests
*/ */
public function testGetAttributeDefinedStrict($defined, $value, $object, $item, $arguments, $type, $useExt = false) public function testGetAttributeDefinedStrict($defined, $value, $object, $item, $arguments, $type)
{ {
$template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true)), $useExt); $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true)));
$this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true)); $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true));
} }
/** public function testGetAttributeCallExceptions()
* @dataProvider getTestsDependingOnExtensionAvailability
*/
public function testGetAttributeCallExceptions($useExt = false)
{ {
$template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), $useExt); $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()));
$object = new Twig_TemplateMagicMethodExceptionObject(); $object = new Twig_TemplateMagicMethodExceptionObject();
@@ -470,34 +413,22 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
// tests when input is not an array or object // tests when input is not an array or object
$tests = array_merge($tests, array( $tests = array_merge($tests, array(
array(false, null, 42, 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a integer variable ("42") in "index.twig".'), array(false, null, 42, 'a', array(), $anyType, 'Impossible to access an attribute ("a") on a integer variable ("42") in "index.twig".'),
array(false, null, 'string', 'a', array(), $anyType, false, 'Impossible to access an attribute ("a") on a string variable ("string") in "index.twig".'), array(false, null, 'string', 'a', array(), $anyType, 'Impossible to access an attribute ("a") on a string variable ("string") in "index.twig".'),
array(false, null, array(), 'a', array(), $anyType, false, 'Key "a" does not exist as the array is empty in "index.twig".'), array(false, null, array(), 'a', array(), $anyType, 'Key "a" does not exist as the array is empty in "index.twig".'),
)); ));
// add twig_template_get_attributes tests
if (function_exists('twig_template_get_attributes')) {
foreach (array_slice($tests, 0) as $test) {
$test = array_pad($test, 7, null);
$test[6] = true;
$tests[] = $test;
}
}
return $tests; return $tests;
} }
} }
class Twig_TemplateTest extends Twig_Template class Twig_TemplateTest extends Twig_Template
{ {
protected $useExtGetAttribute = false;
private $name; private $name;
public function __construct(Twig_Environment $env, $useExtGetAttribute = false, $name = 'index.twig') public function __construct(Twig_Environment $env, $name = 'index.twig')
{ {
parent::__construct($env); parent::__construct($env);
$this->useExtGetAttribute = $useExtGetAttribute;
self::$cache = array(); self::$cache = array();
$this->name = $name; $this->name = $name;
} }
@@ -543,7 +474,7 @@ class Twig_TemplateTest extends Twig_Template
public function getAttribute($object, $item, array $arguments = array(), $type = Twig_Template::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false) public function getAttribute($object, $item, array $arguments = array(), $type = Twig_Template::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
{ {
if ($this->useExtGetAttribute) { if (function_exists('twig_template_get_attributes')) {
return twig_template_get_attributes($this, $object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck); return twig_template_get_attributes($this, $object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck);
} else { } else {
return parent::getAttribute($object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck); return parent::getAttribute($object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck);