uiComponentFactory = $uiComponentFactory; $this->blockFactory = $blockFactory; $this->contextFactory = $contextFactory; } /** * {@inheritdoc} */ public function getType() { return self::TYPE; } /** * Creates UI Component object based on scheduled data and add it to the layout * * @param ReaderContext $readerContext * @param GeneratorContext $generatorContext * @return $this */ public function process(ReaderContext $readerContext, GeneratorContext $generatorContext) { $scheduledStructure = $readerContext->getScheduledStructure(); $scheduledElements = $scheduledStructure->getElements(); if (!$scheduledElements) { return $this; } $structure = $generatorContext->getStructure(); $layout = $generatorContext->getLayout(); // Instantiate blocks and collect all actions data /** @var $blocks \Magento\Framework\View\Element\AbstractBlock[] */ $blocks = []; foreach ($scheduledElements as $elementName => $element) { list($elementType, $data) = $element; if ($elementType !== Element::TYPE_UI_COMPONENT) { continue; } $block = $this->generateComponent($structure, $elementName, $data, $layout); $blocks[$elementName] = $block; $layout->setBlock($elementName, $block); $scheduledStructure->unsetElement($elementName); } return $this; } /** * Create component object * * @param DataStructure $structure * @param string $elementName * @param string $data * @param LayoutInterface $layout * @return ContainerInterface */ protected function generateComponent(DataStructure $structure, $elementName, $data, LayoutInterface $layout) { $attributes = $data['attributes']; if (!empty($attributes['group'])) { $structure->addToParentGroup($elementName, $attributes['group']); } $context = $this->contextFactory->create( [ 'namespace' => $elementName, 'pageLayout' => $layout ] ); /** * Structure is required for custom component factory like a 'htmlContent' */ $component = $this->uiComponentFactory->create( $elementName, null, ['context' => $context, 'structure' => $structure] ); $this->prepareComponent($component); /** @var ContainerInterface $blockContainer */ $blockContainer = $this->blockFactory->createBlock(static::CONTAINER, ['component' => $component]); return $blockContainer; } /** * Call prepare method in the component UI * * @param UiComponentInterface $component * @return void */ protected function prepareComponent(UiComponentInterface $component) { $childComponents = $component->getChildComponents(); if (!empty($childComponents)) { foreach ($childComponents as $child) { $this->prepareComponent($child); } } $component->prepare(); } }