![]() 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/View/Layout/Reader/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\View\Layout\Reader; use Magento\Framework\Data\Argument\InterpreterInterface; use Magento\Framework\View\Layout; use Magento\Framework\View\Layout\Element; use Magento\Framework\View\Layout\ScheduledStructure; use Magento\Framework\View\Layout\Reader\Visibility\Condition; /** * Block structure reader */ class Block implements Layout\ReaderInterface { /**#@+ * Supported types */ const TYPE_BLOCK = 'block'; const TYPE_REFERENCE_BLOCK = 'referenceBlock'; /**#@-*/ /**#@+ * Supported subtypes for blocks */ const TYPE_ARGUMENTS = 'arguments'; const TYPE_ACTION = 'action'; /**#@-*/ /**#@+ * Names of block attributes in layout */ const ATTRIBUTE_GROUP = 'group'; const ATTRIBUTE_CLASS = 'class'; const ATTRIBUTE_TEMPLATE = 'template'; const ATTRIBUTE_TTL = 'ttl'; const ATTRIBUTE_DISPLAY = 'display'; const ATTRIBUTE_ACL = 'aclResource'; /**#@-*/ /**#@-*/ protected $attributes = [ self::ATTRIBUTE_GROUP, self::ATTRIBUTE_CLASS, self::ATTRIBUTE_TEMPLATE, self::ATTRIBUTE_TTL, self::ATTRIBUTE_DISPLAY ]; /** * @var \Magento\Framework\View\Layout\ScheduledStructure\Helper */ protected $helper; /** * @var \Magento\Framework\View\Layout\Argument\Parser */ protected $argumentParser; /** * @var \Magento\Framework\View\Layout\ReaderPool */ protected $readerPool; /** * @var string */ protected $scopeType; /** * @var InterpreterInterface */ protected $argumentInterpreter; /** * @var Condition */ private $conditionReader; /** * @deprecated 101.0.0 * @var string */ private $deprecatedAttributeAcl = 'acl'; /** * Constructor * * @param Layout\ScheduledStructure\Helper $helper * @param Layout\Argument\Parser $argumentParser * @param Layout\ReaderPool $readerPool * @param InterpreterInterface $argumentInterpreter * @param Condition $conditionReader * @param string|null $scopeType */ public function __construct( Layout\ScheduledStructure\Helper $helper, Layout\Argument\Parser $argumentParser, Layout\ReaderPool $readerPool, InterpreterInterface $argumentInterpreter, Condition $conditionReader, $scopeType = null ) { $this->helper = $helper; $this->argumentParser = $argumentParser; $this->readerPool = $readerPool; $this->scopeType = $scopeType; $this->argumentInterpreter = $argumentInterpreter; $this->conditionReader = $conditionReader; } /** * @inheritdoc */ public function getSupportedNodes() { return [self::TYPE_BLOCK, self::TYPE_REFERENCE_BLOCK]; } /** * @inheritdoc */ public function interpret(Context $readerContext, Element $currentElement) { $scheduledStructure = $readerContext->getScheduledStructure(); switch ($currentElement->getName()) { case self::TYPE_BLOCK: $this->scheduleBlock($scheduledStructure, $currentElement); break; case self::TYPE_REFERENCE_BLOCK: $this->scheduleReference($scheduledStructure, $currentElement); break; default: break; } $this->readerPool->interpret($readerContext, $currentElement); return $this; } /** * Process block element their attributes and children * * @param ScheduledStructure $scheduledStructure * @param Element $currentElement * @return void */ protected function scheduleBlock( ScheduledStructure $scheduledStructure, Element $currentElement ) { $elementName = $this->helper->scheduleStructure( $scheduledStructure, $currentElement, $currentElement->getParent() ); $data = $scheduledStructure->getStructureElementData($elementName, []); $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement); $this->updateScheduledData($currentElement, $data); $this->evaluateArguments($currentElement, $data); $data['attributes'] = array_merge( $data['attributes'], ['visibilityConditions' => $this->conditionReader->parseConditions($currentElement)] ); $scheduledStructure->setStructureElementData($elementName, $data); } /** * Merge Block attributes * * @param array $elementData * @param Element $currentElement * @return array */ protected function mergeBlockAttributes(array $elementData, Element $currentElement) { $currentElement = $this->replaceDeprecatedAclKey($currentElement); if (isset($elementData['attributes'])) { $elementData['attributes'] = $this->replaceDeprecatedAclKey($elementData['attributes']); $keys = array_keys($elementData['attributes']); foreach ($keys as $key) { if (isset($currentElement[$key])) { $elementData['attributes'][$key] = (string)$currentElement[$key]; } } } else { $elementData['attributes'] = [ self::ATTRIBUTE_CLASS => (string)$currentElement[self::ATTRIBUTE_CLASS], self::ATTRIBUTE_GROUP => (string)$currentElement[self::ATTRIBUTE_GROUP], self::ATTRIBUTE_TEMPLATE => (string)$currentElement[self::ATTRIBUTE_TEMPLATE], self::ATTRIBUTE_TTL => (string)$currentElement[self::ATTRIBUTE_TTL], self::ATTRIBUTE_DISPLAY => (string)$currentElement[self::ATTRIBUTE_DISPLAY], self::ATTRIBUTE_ACL => (string)$currentElement[self::ATTRIBUTE_ACL], ]; } return $elementData['attributes']; } /** * Replaces old ACL attribute key to new. * * @param array|Element $data * * @return array|Element */ private function replaceDeprecatedAclKey($data) { if (isset($data[$this->deprecatedAttributeAcl])) { $data[self::ATTRIBUTE_ACL] = (string)$data[$this->deprecatedAttributeAcl]; } return $data; } /** * Schedule reference data * * @param ScheduledStructure $scheduledStructure * @param Element $currentElement * @return void */ protected function scheduleReference( ScheduledStructure $scheduledStructure, Element $currentElement ) { $elementName = $currentElement->getAttribute('name'); $elementRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN); if ($elementRemove) { $scheduledStructure->setElementToRemoveList($elementName); return; } elseif ($currentElement->getAttribute('remove')) { $scheduledStructure->unsetElementFromListToRemove($elementName); } $data = $scheduledStructure->getStructureElementData($elementName, []); $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement); $this->updateScheduledData($currentElement, $data); $this->evaluateArguments($currentElement, $data); $scheduledStructure->setStructureElementData($elementName, $data); } /** * Update data for scheduled element * * @param Element $currentElement * @param array $data * @return array */ protected function updateScheduledData($currentElement, array &$data) { $actions = $this->getActions($currentElement); $arguments = $this->getArguments($currentElement); $data['actions'] = isset($data['actions']) ? array_merge($data['actions'], $actions) : $actions; $data['arguments'] = isset($data['arguments']) ? array_replace_recursive($data['arguments'], $arguments) : $arguments; return $data; } /** * Get block attributes * * @param Element $blockElement * @return array */ protected function getAttributes(Element $blockElement) { $attributes = []; foreach ($this->attributes as $attributeName) { $attributes[$attributeName] = (string)$blockElement->getAttribute($attributeName); } return $attributes; } /** * Get actions for block element * * @param Element $blockElement * @return array[] */ protected function getActions(Element $blockElement) { $actions = []; /** @var $actionElement Element */ foreach ($this->getElementsByType($blockElement, self::TYPE_ACTION) as $actionElement) { $configPath = $actionElement->getAttribute('ifconfig'); $methodName = $actionElement->getAttribute('method'); $actionArguments = $this->parseArguments($actionElement); $actions[] = [$methodName, $actionArguments, $configPath, $this->scopeType]; } return $actions; } /** * Get block arguments * * @param Element $blockElement * @return array */ protected function getArguments(Element $blockElement) { $arguments = $this->getElementsByType($blockElement, self::TYPE_ARGUMENTS); // We have only one declaration of <arguments> node in block or its reference $argumentElement = reset($arguments); return $argumentElement ? $this->parseArguments($argumentElement) : []; } /** * Get elements by type * * @param Element $element * @param string $type * @return array */ protected function getElementsByType(Element $element, $type) { $elements = []; /** @var $childElement Element */ foreach ($element as $childElement) { if ($childElement->getName() === $type) { $elements[] = $childElement; } } return $elements; } /** * Parse argument nodes and return their array representation * * @param Element $node * @return array */ protected function parseArguments(Element $node) { $nodeDom = dom_import_simplexml($node); $result = []; foreach ($nodeDom->childNodes as $argumentNode) { if ($argumentNode instanceof \DOMElement && $argumentNode->nodeName == 'argument') { $argumentName = $argumentNode->getAttribute('name'); $result[$argumentName] = $this->argumentParser->parse($argumentNode); } } return $result; } /** * Compute argument values * * @param Element $blockElement * @param array $data * @return void */ protected function evaluateArguments(Element $blockElement, array &$data) { $arguments = $this->getArguments($blockElement); foreach ($arguments as $argumentName => $argumentData) { if (isset($argumentData['updater'])) { continue; } $result = $this->argumentInterpreter->evaluate($argumentData); if (is_array($result)) { $data['arguments'][$argumentName] = isset($data['arguments'][$argumentName]) ? array_replace_recursive($data['arguments'][$argumentName], $result) : $result; } else { $data['arguments'][$argumentName] = $result; } } } }