Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Block.php
Go to the documentation of this file.
1 <?php
7 
13 
17 class Block implements Layout\ReaderInterface
18 {
22  const TYPE_BLOCK = 'block';
23  const TYPE_REFERENCE_BLOCK = 'referenceBlock';
29  const TYPE_ARGUMENTS = 'arguments';
30  const TYPE_ACTION = 'action';
36  const ATTRIBUTE_GROUP = 'group';
37  const ATTRIBUTE_CLASS = 'class';
38  const ATTRIBUTE_TEMPLATE = 'template';
39  const ATTRIBUTE_TTL = 'ttl';
40  const ATTRIBUTE_DISPLAY = 'display';
41  const ATTRIBUTE_ACL = 'aclResource';
45  protected $attributes = [
51  ];
52 
56  protected $helper;
57 
61  protected $argumentParser;
62 
66  protected $readerPool;
67 
71  protected $scopeType;
72 
77 
81  private $conditionReader;
82 
87  private $deprecatedAttributeAcl = 'acl';
88 
99  public function __construct(
101  Layout\Argument\Parser $argumentParser,
104  Condition $conditionReader,
105  $scopeType = null
106  ) {
107  $this->helper = $helper;
108  $this->argumentParser = $argumentParser;
109  $this->readerPool = $readerPool;
110  $this->scopeType = $scopeType;
111  $this->argumentInterpreter = $argumentInterpreter;
112  $this->conditionReader = $conditionReader;
113  }
114 
120  public function getSupportedNodes()
121  {
123  }
124 
133  public function interpret(Context $readerContext, Element $currentElement)
134  {
135  $scheduledStructure = $readerContext->getScheduledStructure();
136  switch ($currentElement->getName()) {
137  case self::TYPE_BLOCK:
138  $this->scheduleBlock($scheduledStructure, $currentElement);
139  break;
141  $this->scheduleReference($scheduledStructure, $currentElement);
142  break;
143  default:
144  break;
145  }
146  $this->readerPool->interpret($readerContext, $currentElement);
147  return $this;
148  }
149 
157  protected function scheduleBlock(
158  ScheduledStructure $scheduledStructure,
159  Element $currentElement
160  ) {
161  $elementName = $this->helper->scheduleStructure(
162  $scheduledStructure,
163  $currentElement,
164  $currentElement->getParent()
165  );
166  $data = $scheduledStructure->getStructureElementData($elementName, []);
167  $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement);
168  $this->updateScheduledData($currentElement, $data);
169  $this->evaluateArguments($currentElement, $data);
170  $data['attributes'] = array_merge(
171  $data['attributes'],
172  ['visibilityConditions' => $this->conditionReader->parseConditions($currentElement)]
173  );
174  $scheduledStructure->setStructureElementData($elementName, $data);
175  }
176 
184  protected function mergeBlockAttributes(array $elementData, Element $currentElement)
185  {
186  $currentElement = $this->replaceDeprecatedAclKey($currentElement);
187  if (isset($elementData['attributes'])) {
188  $elementData['attributes'] = $this->replaceDeprecatedAclKey($elementData['attributes']);
189  $keys = array_keys($elementData['attributes']);
190  foreach ($keys as $key) {
191  if (isset($currentElement[$key])) {
192  $elementData['attributes'][$key] = (string)$currentElement[$key];
193  }
194  }
195  } else {
196  $elementData['attributes'] = [
197  self::ATTRIBUTE_CLASS => (string)$currentElement[self::ATTRIBUTE_CLASS],
198  self::ATTRIBUTE_GROUP => (string)$currentElement[self::ATTRIBUTE_GROUP],
199  self::ATTRIBUTE_TEMPLATE => (string)$currentElement[self::ATTRIBUTE_TEMPLATE],
200  self::ATTRIBUTE_TTL => (string)$currentElement[self::ATTRIBUTE_TTL],
201  self::ATTRIBUTE_DISPLAY => (string)$currentElement[self::ATTRIBUTE_DISPLAY],
202  self::ATTRIBUTE_ACL => (string)$currentElement[self::ATTRIBUTE_ACL],
203  ];
204  }
205  return $elementData['attributes'];
206  }
207 
215  private function replaceDeprecatedAclKey($data)
216  {
217  if (isset($data[$this->deprecatedAttributeAcl])) {
218  $data[self::ATTRIBUTE_ACL] = (string)$data[$this->deprecatedAttributeAcl];
219  }
220 
221  return $data;
222  }
223 
231  protected function scheduleReference(
232  ScheduledStructure $scheduledStructure,
233  Element $currentElement
234  ) {
235  $elementName = $currentElement->getAttribute('name');
236  $elementRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN);
237  if ($elementRemove) {
238  $scheduledStructure->setElementToRemoveList($elementName);
239  return;
240  } elseif ($currentElement->getAttribute('remove')) {
241  $scheduledStructure->unsetElementFromListToRemove($elementName);
242  }
243  $data = $scheduledStructure->getStructureElementData($elementName, []);
244  $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement);
245  $this->updateScheduledData($currentElement, $data);
246  $this->evaluateArguments($currentElement, $data);
247  $scheduledStructure->setStructureElementData($elementName, $data);
248  }
249 
257  protected function updateScheduledData($currentElement, array &$data)
258  {
259  $actions = $this->getActions($currentElement);
260  $arguments = $this->getArguments($currentElement);
261  $data['actions'] = isset($data['actions'])
262  ? array_merge($data['actions'], $actions)
263  : $actions;
264  $data['arguments'] = isset($data['arguments'])
265  ? array_replace_recursive($data['arguments'], $arguments)
266  : $arguments;
267  return $data;
268  }
269 
276  protected function getAttributes(Element $blockElement)
277  {
278  $attributes = [];
279  foreach ($this->attributes as $attributeName) {
280  $attributes[$attributeName] = (string)$blockElement->getAttribute($attributeName);
281  }
282  return $attributes;
283  }
284 
291  protected function getActions(Element $blockElement)
292  {
293  $actions = [];
295  foreach ($this->getElementsByType($blockElement, self::TYPE_ACTION) as $actionElement) {
296  $configPath = $actionElement->getAttribute('ifconfig');
297  $methodName = $actionElement->getAttribute('method');
298  $actionArguments = $this->parseArguments($actionElement);
299  $actions[] = [$methodName, $actionArguments, $configPath, $this->scopeType];
300  }
301  return $actions;
302  }
303 
310  protected function getArguments(Element $blockElement)
311  {
312  $arguments = $this->getElementsByType($blockElement, self::TYPE_ARGUMENTS);
313  // We have only one declaration of <arguments> node in block or its reference
314  $argumentElement = reset($arguments);
315  return $argumentElement ? $this->parseArguments($argumentElement) : [];
316  }
317 
325  protected function getElementsByType(Element $element, $type)
326  {
327  $elements = [];
329  foreach ($element as $childElement) {
330  if ($childElement->getName() === $type) {
331  $elements[] = $childElement;
332  }
333  }
334  return $elements;
335  }
336 
343  protected function parseArguments(Element $node)
344  {
345  $nodeDom = dom_import_simplexml($node);
346  $result = [];
347  foreach ($nodeDom->childNodes as $argumentNode) {
348  if ($argumentNode instanceof \DOMElement && $argumentNode->nodeName == 'argument') {
349  $argumentName = $argumentNode->getAttribute('name');
350  $result[$argumentName] = $this->argumentParser->parse($argumentNode);
351  }
352  }
353  return $result;
354  }
355 
363  protected function evaluateArguments(Element $blockElement, array &$data)
364  {
365  $arguments = $this->getArguments($blockElement);
366  foreach ($arguments as $argumentName => $argumentData) {
367  if (isset($argumentData['updater'])) {
368  continue;
369  }
370  $result = $this->argumentInterpreter->evaluate($argumentData);
371  if (is_array($result)) {
372  $data['arguments'][$argumentName] = isset($data['arguments'][$argumentName])
373  ? array_replace_recursive($data['arguments'][$argumentName], $result)
374  : $result;
375  } else {
376  $data['arguments'][$argumentName] = $result;
377  }
378  }
379  }
380 }
getArguments(Element $blockElement)
Definition: Block.php:310
scheduleBlock(ScheduledStructure $scheduledStructure, Element $currentElement)
Definition: Block.php:157
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
evaluateArguments(Element $blockElement, array &$data)
Definition: Block.php:363
$type
Definition: item.phtml:13
scheduleReference(ScheduledStructure $scheduledStructure, Element $currentElement)
Definition: Block.php:231
updateScheduledData($currentElement, array &$data)
Definition: Block.php:257
interpret(Context $readerContext, Element $currentElement)
Definition: Block.php:133
mergeBlockAttributes(array $elementData, Element $currentElement)
Definition: Block.php:184
$arguments
__construct(Layout\ScheduledStructure\Helper $helper, Layout\Argument\Parser $argumentParser, Layout\ReaderPool $readerPool, InterpreterInterface $argumentInterpreter, Condition $conditionReader, $scopeType=null)
Definition: Block.php:99
getAttributes(Element $blockElement)
Definition: Block.php:276
$elementName
Definition: gallery.phtml:10
$element
Definition: element.phtml:12