diff --git a/CHANGELOG b/CHANGELOG index 2fc4b9347..6522bb120 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ # 3.15.0 (2024-XX-XX) + * Add support for accessing class constants with the dot operator * Add `Profile::getStartTime()` and `Profile::getEndTime()` * Fix "ignore missing" when used on an "embed" tag * Fix the possibility to override an aliased block (via use) diff --git a/doc/templates.rst b/doc/templates.rst index 97e8b5926..1da89bcf2 100644 --- a/doc/templates.rst +++ b/doc/templates.rst @@ -76,8 +76,8 @@ Twig templates have access to variables provided by the PHP application and variables created in templates via the :doc:`set ` tag. These variables can be manipulated and displayed in the template. -Use a dot (``.``) to access attributes of a variable (methods or properties of a -PHP object, or items of a PHP array): +Use a dot (``.``) to access attributes of a variable (methods, properties +or constants of a PHP object, or items of a PHP array): .. code-block:: twig @@ -767,8 +767,8 @@ The following operators don't fit into any of the other categories: * ``.``, ``[]``: Gets an attribute of a variable. - The (``.``) operator abstracts getting an attribute of a variable (methods - or properties of a PHP object, or items of a PHP array): + The (``.``) operator abstracts getting an attribute of a variable (methods, + properties or constants of a PHP object, or items of a PHP array): .. code-block:: twig @@ -803,6 +803,7 @@ The following operators don't fit into any of the other categories: * check if ``user`` is a PHP array or a ArrayObject/ArrayAccess object and ``name`` a valid element; * if not, and if ``user`` is a PHP object, check that ``name`` is a valid property; + * if not, and if ``user`` is a PHP object, check that ``name`` is a class constant; * if not, and if ``user`` is a PHP object, check the following methods and call the first valid one: ``name()``, ``getName()``, ``isName()``, or ``hasName()``; diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index fe5ed184d..9472a2b54 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -1675,6 +1675,18 @@ final class CoreExtension extends AbstractExtension return $object->$item; } + + if (\defined($object::class.'::'.$item)) { + if ($isDefinedTest) { + return true; + } + + if ($sandboxed) { + $env->getExtension(SandboxExtension::class)->checkPropertyAllowed($object, $item, $lineno, $source); + } + + return \constant($object::class.'::'.$item); + } } static $cache = []; diff --git a/tests/Fixtures/expressions/const.test b/tests/Fixtures/expressions/const.test new file mode 100644 index 000000000..336fc6001 --- /dev/null +++ b/tests/Fixtures/expressions/const.test @@ -0,0 +1,10 @@ +--TEST-- +Twig supports accessing constants +--TEMPLATE-- +{{ foo.BAR_NAME }} +--DATA-- +return ['foo' => new Twig\Tests\TwigTestFoo()] +--CONFIG-- +return ['strict_variables' => false] +--EXPECT-- +bar