![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/framework/Filter/VariableResolver/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Framework\Filter\VariableResolver; use Magento\Email\Model\AbstractTemplate; use Magento\Framework\DataObject; use Magento\Framework\Filter\Template; use Magento\Framework\Filter\Template\Tokenizer\VariableFactory; use Magento\Framework\Filter\VariableResolverInterface; /** * Resolves variables allowing only scalar values */ class StrictResolver implements VariableResolverInterface { /** * @var VariableFactory */ private $variableTokenizerFactory; /** * @param VariableFactory $variableTokenizerFactory */ public function __construct(VariableFactory $variableTokenizerFactory) { $this->variableTokenizerFactory = $variableTokenizerFactory; } /** * @inheritDoc */ public function resolve(string $value, Template $filter, array $templateVariables) { if (empty($value)) { return null; } $tokenizer = $this->variableTokenizerFactory->create(); $tokenizer->setString($value); $stackArgs = $tokenizer->tokenize(); $result = null; $last = 0; for ($i = 0, $count = count($stackArgs); $i < $count; $i++) { if ($i === 0 && isset($templateVariables[$stackArgs[$i]['name']])) { // Getting of template value $stackArgs[$i]['variable'] = &$templateVariables[$stackArgs[$i]['name']]; } elseif ($this->shouldHandleDataAccess($i, $stackArgs)) { $this->handleDataAccess($i, $filter, $templateVariables, $stackArgs); $last = $i; } } if (isset($stackArgs[$last]['variable']) && (is_scalar($stackArgs[$last]['variable']) || is_array($stackArgs[$last]['variable'])) ) { // If value for construction exists set it $result = $stackArgs[$last]['variable']; } return $result; } /** * Handle variable access at a given index * * @param int $i * @param Template $filter * @param array $templateVariables * @param array $stackArgs */ private function handleDataAccess(int $i, Template $filter, array $templateVariables, array &$stackArgs): void { // If data object calling methods or getting properties if ($stackArgs[$i]['type'] == 'property') { if (is_array($stackArgs[$i - 1]['variable'])) { $stackArgs[$i]['variable'] = $stackArgs[$i - 1]['variable'][$stackArgs[$i]['name']]; } else { // Strict mode should not call getter methods except DataObject's getData $stackArgs[$i]['variable'] = $stackArgs[$i - 1]['variable'] ->getData($stackArgs[$i]['name']); } } elseif ($stackArgs[$i]['type'] == 'method' && substr($stackArgs[$i]['name'] ?? '', 0, 3) == 'get') { $this->handleGetterMethod($i, $filter, $templateVariables, $stackArgs); } } /** * Handle getter method access at a given stack index * * @param int $i * @param Template $filter * @param array $templateVariables * @param array $stackArgs */ private function handleGetterMethod(int $i, Template $filter, array $templateVariables, array &$stackArgs): void { if ($stackArgs[$i]['name'] === 'getUrl' && $stackArgs[$i - 1]['variable'] instanceof AbstractTemplate ) { $stackArgs[$i]['args'] = $this->getStackArgs( $stackArgs[$i]['args'], $filter, $templateVariables ); $stackArgs[$i]['args'][0] = $templateVariables['store']; $stackArgs[$i]['variable'] = $stackArgs[$i - 1]['variable']->getUrl( ...$stackArgs[$i]['args'] ); } else { $dataKey = $this->extractDataKeyFromGetter($stackArgs[$i]['name']); $stackArgs[$i]['variable'] = $stackArgs[$i - 1]['variable']->getData($dataKey); } } /** * Loops over a set of stack args to process variables into array argument values * * @param array $stack * @param Template $filter * @param array $templateVariables * @return array */ private function getStackArgs($stack, Template $filter, array $templateVariables): array { foreach ($stack as $i => $value) { if (is_array($value)) { $stack[$i] = $this->getStackArgs($value, $filter, $templateVariables); } elseif (substr((string)$value, 0, 1) === '$') { $stack[$i] = $this->resolve(substr($value, 1), $filter, $templateVariables); } } return $stack; } /** * Extract the DataObject key name from a getter method name in the same way as DataObject does internally * * @param string $method * @return string */ private function extractDataKeyFromGetter(string $method) { return strtolower(ltrim(trim(preg_replace('/([A-Z]|[0-9]+)/', '_$1', substr($method, 3))), '_')); } /** * Return if the given index should be processed for data access * * @param int $i * @param array $stackArgs * @return bool */ private function shouldHandleDataAccess(int $i, array &$stackArgs): bool { return isset($stackArgs[$i - 1]['variable']) && ( $stackArgs[$i - 1]['variable'] instanceof DataObject || $stackArgs[$i - 1]['variable'] instanceof AbstractTemplate || is_array($stackArgs[$i - 1]['variable']) ); } }