[TASK] Streamline expressionLanguage usage in core
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Documentation / Changelog / 9.4 / Feature-85828-MoveSymfonyExpressionLanguageHandlingIntoEXTcore.rst
1 .. include:: ../../Includes.txt
2
3 =========================================================================
4 Feature: #85828 - Move symfony expression language handling into EXT:core
5 =========================================================================
6
7 See :issue:`85828`
8
9 Description
10 ===========
11
12 The symfony expression language handling has been moved out of EXT:form into EXT:core.
13 Thus, it is available to be used throughout the core and also for extension developers.
14
15 To use the expression language, a provider definition is required which implements the
16 :php:`\TYPO3\CMS\Core\ExpressionLanguage\ProviderInterface`.
17 The core comes with a :php:`\TYPO3\CMS\Core\ExpressionLanguage\DefaultProvider` class which can be used directly.
18 For a custom implementation the :php:`\TYPO3\CMS\Core\ExpressionLanguage\AbstractProvider` class can be extended.
19
20 The provider can provide additional variables and expression functions to extend the expression language.
21 For a custom implementation check out the :php:`\TYPO3\CMS\Form\Domain\Condition\ConditionProvider` class.
22
23 An example with the DefaultProvider:
24
25 .. code-block:: php
26
27    $resolver = GeneralUtility::makeInstance(
28       Resolver::class,
29       'default',
30       [
31          'foo' => 1,
32          'bar' => 2,
33       ]
34    );
35    $resolver->evaluate('1 < 2'); // result is true
36    $resolver->evaluate('foo < bar'); // result is true
37    $resolver->evaluate('bar < foo'); // result is false
38
39
40 An example with a custom Provider:
41
42 First you have to configure a provider, create a file in your extension with the path and name :file:`EXT:my_ext\Configuration\ExpressionLanguage.php`:
43
44 .. code-block:: php
45
46    <?php
47       return [
48          'my-context-identifier' => [
49             \TYPO3\CMS\MyExt\ExpressionLanguage\MyCustomProvider::class,
50          ]
51       ];
52
53
54 Next implement your provider class :php:`\TYPO3\CMS\MyExt\ExpressionLanguage\MyCustomProvider::class`
55
56 .. code-block:: php
57
58    class MyCustomProvider extends \TYPO3\CMS\Core\ExpressionLanguage\AbstractProvider
59    {
60       public function __construct(ServerRequestInterface $request)
61       {
62          $this->expressionLanguageVariables = [
63             'foo' => 1,
64             'bar' => 2,
65          ];
66          $this->expressionLanguageProviders = [
67             // We use the existing Typo3ConditionsFunctions...
68             Typo3ConditionFunctionsProvider::class,
69             // ... and our custom function provider
70             MyCustomFunctionsProvider::class
71          ];
72       }
73    }
74
75
76 Next implement your provider class :php:`\TYPO3\CMS\MyExt\ExpressionLanguage\MyCustomFunctionProvider::class`
77
78 .. code-block:: php
79
80    class MyCustomFunctionProvider implements ExpressionFunctionProviderInterface
81    {
82       public function getFunctions()
83       {
84          return [
85             $this->getFooFunction(),
86          ];
87       }
88
89       protected function getFooFunction(): ExpressionFunction
90       {
91          return new ExpressionFunction('compatVersion', function ($str) {
92             // Not implemented, we only use the evaluator
93          }, function ($arguments, $str) {
94             return $str === 'foo';
95          });
96       }
97    }
98
99
100 And now we use it:
101
102 .. code-block:: php
103
104    $resolver = GeneralUtility::makeInstance(
105       Resolver::class,
106       'my-context-identifier',
107       [
108          'baz' => 3,
109       ]
110    );
111    $resolver->evaluate('1 < 2'); // result is true
112    $resolver->evaluate('foo < bar'); // result is true
113    $resolver->evaluate('bar < baz'); // result is true
114    $resolver->evaluate('bar < foo'); // result is false
115    $resolver->evaluate('foo("foo")'); // result is true
116    $resolver->evaluate('foo("bar")'); // result is false
117
118
119 Impact
120 ======
121
122 The expression language can now be used in other scopes and has no dependency to EXT:form.
123
124 .. index:: Backend, Frontend, PHP-API, ext:core