1<?php 2 3declare(strict_types=1); 4 5/* 6 * This file is part of the TYPO3 CMS project. 7 * 8 * It is free software; you can redistribute it and/or modify it under 9 * the terms of the GNU General Public License, either version 2 10 * of the License, or any later version. 11 * 12 * For the full copyright and license information, please read the 13 * LICENSE.txt file that was distributed with this source code. 14 * 15 * The TYPO3 project - inspiring people to share! 16 */ 17 18namespace TYPO3\CMS\Core\ExpressionLanguage; 19 20use Symfony\Component\ExpressionLanguage\ExpressionLanguage; 21use TYPO3\CMS\Core\Utility\GeneralUtility; 22 23/** 24 * Class Resolver 25 */ 26class Resolver 27{ 28 /** 29 * @var ProviderInterface 30 */ 31 protected $provider; 32 33 /** 34 * @var \Symfony\Component\ExpressionLanguage\ExpressionLanguage 35 */ 36 protected $expressionLanguage; 37 38 /** 39 * @var array 40 */ 41 public $expressionLanguageVariables = []; 42 43 /** 44 * @param string $context 45 * @param array $variables 46 */ 47 public function __construct(string $context, array $variables) 48 { 49 $functionProviderInstances = []; 50 $providers = GeneralUtility::makeInstance(ProviderConfigurationLoader::class)->getExpressionLanguageProviders()[$context] ?? []; 51 // Always add default provider 52 array_unshift($providers, DefaultProvider::class); 53 $providers = array_unique($providers); 54 $functionProviders = []; 55 $generalVariables = []; 56 foreach ($providers as $provider) { 57 /** @var ProviderInterface $providerInstance */ 58 $providerInstance = GeneralUtility::makeInstance($provider); 59 $functionProviders[] = $providerInstance->getExpressionLanguageProviders(); 60 $generalVariables[] = $providerInstance->getExpressionLanguageVariables(); 61 } 62 $functionProviders = array_merge(...$functionProviders); 63 $generalVariables = array_replace_recursive(...$generalVariables); 64 $this->expressionLanguageVariables = array_replace_recursive($generalVariables, $variables); 65 foreach ($functionProviders as $functionProvider) { 66 $functionProviderInstances[] = GeneralUtility::makeInstance($functionProvider); 67 } 68 $this->expressionLanguage = new ExpressionLanguage(null, $functionProviderInstances); 69 } 70 71 /** 72 * Evaluate an expression. 73 * 74 * @param string $condition The expression to parse 75 * @return bool 76 */ 77 public function evaluate(string $condition): bool 78 { 79 // The TypoScript [ELSE] condition is not known by the Symfony Expression Language 80 // and must not be evaluated. If/else logic is handled in TypoScriptParser. 81 if (strtoupper($condition) === 'ELSE') { 82 return false; 83 } 84 85 return (bool)$this->expressionLanguage->evaluate($condition, $this->expressionLanguageVariables); 86 } 87 88 /** 89 * Compiles an expression source code. 90 * 91 * @param string $condition The expression to compile 92 * @return string 93 */ 94 public function compile(string $condition): string 95 { 96 return (string)$this->expressionLanguage->compile($condition, array_keys($this->expressionLanguageVariables)); 97 } 98} 99