/** * Process queue of structural elements and actually add them to structure, and schedule elements for generation * * The catch is to populate parents first, if they are not in the structure yet. * Since layout updates could come in arbitrary order, a case is possible where an element is declared in reference, * while referenced element itself is not declared yet. * * @param \Magento\Framework\View\Layout\ScheduledStructure $scheduledStructure * @param Layout\Data\Structure $structure * @param string $key in _scheduledStructure represent element name * @return void * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function scheduleElement(Layout\ScheduledStructure $scheduledStructure, Layout\Data\Structure $structure, $key) { $row = $scheduledStructure->getStructureElement($key); $data = $scheduledStructure->getStructureElementData($key); // if we have reference container to not existed element if (!isset($row[self::SCHEDULED_STRUCTURE_INDEX_TYPE])) { $this->logger->critical("Broken reference: missing declaration of the element '{$key}'."); $scheduledStructure->unsetPathElement($key); $scheduledStructure->unsetStructureElement($key); return; } list($type, $alias, $parentName, $siblingName, $isAfter) = $row; $name = $this->_createStructuralElement($structure, $key, $type, $parentName . $alias); if ($parentName) { // recursively populate parent first if ($scheduledStructure->hasStructureElement($parentName)) { $this->scheduleElement($scheduledStructure, $structure, $parentName); } if ($structure->hasElement($parentName)) { try { $structure->setAsChild($name, $parentName, $alias); } catch (\Exception $e) { $this->logger->critical($e); } } else { $scheduledStructure->setElementToBrokenParentList($key); $this->logger->critical("Broken reference: the '{$name}' element cannot be added as child to '{$parentName}', " . 'because the latter doesn\'t exist'); } } // Move from scheduledStructure to scheduledElement $scheduledStructure->unsetStructureElement($key); $scheduledStructure->setElement($name, [$type, $data]); /** * Some elements provide info "after" or "before" which sibling they are supposed to go * Make sure to populate these siblings as well and order them correctly */ if ($siblingName) { if ($scheduledStructure->hasStructureElement($siblingName)) { $this->scheduleElement($scheduledStructure, $structure, $siblingName); } $structure->reorderChildElement($parentName, $name, $siblingName, $isAfter); } }
/** * Schedule reference data * * @param Layout\ScheduledStructure $scheduledStructure * @param Layout\Element $currentElement * @return void */ protected function scheduleReference(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement) { $elementName = $currentElement->getAttribute('name'); $elementRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN); if ($elementRemove) { $scheduledStructure->setElementToRemoveList($elementName); } else { $data = $scheduledStructure->getStructureElementData($elementName, []); $data['attributes'] = $this->mergeBlockAttributes($data, $currentElement); $this->updateScheduledData($currentElement, $data); $this->evaluateArguments($currentElement, $data); $scheduledStructure->setStructureElementData($elementName, $data); } }
/** * Schedule reference data * * @param Layout\ScheduledStructure $scheduledStructure * @param Layout\Element $currentElement * @return void */ protected function scheduleReference(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement) { $elementName = $currentElement->getAttribute('name'); $data = $scheduledStructure->getStructureElementData($elementName, []); $this->updateScheduledData($currentElement, $data); $this->evaluateArguments($currentElement, $data); $scheduledStructure->setStructureElementData($elementName, $data); }
/** * Merge Container attributes * * @param \Magento\Framework\View\Layout\ScheduledStructure $scheduledStructure * @param \Magento\Framework\View\Layout\Element $currentElement * @return void */ protected function mergeContainerAttributes(Layout\ScheduledStructure $scheduledStructure, Layout\Element $currentElement) { $containerName = $currentElement->getAttribute('name'); $elementData = $scheduledStructure->getStructureElementData($containerName); if (isset($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::CONTAINER_OPT_HTML_TAG => (string) $currentElement[self::CONTAINER_OPT_HTML_TAG], self::CONTAINER_OPT_HTML_ID => (string) $currentElement[self::CONTAINER_OPT_HTML_ID], self::CONTAINER_OPT_HTML_CLASS => (string) $currentElement[self::CONTAINER_OPT_HTML_CLASS], self::CONTAINER_OPT_LABEL => (string) $currentElement[self::CONTAINER_OPT_LABEL], self::CONTAINER_OPT_DISPLAY => (string) $currentElement[self::CONTAINER_OPT_DISPLAY]]; } $scheduledStructure->setStructureElementData($containerName, $elementData); }