123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Ui\Component\Layout;
- use Magento\Framework\View\Element\UiComponent\BlockWrapperInterface;
- use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
- use Magento\Framework\View\Element\UiComponentFactory;
- use Magento\Framework\View\Element\UiComponentInterface;
- use Magento\Framework\View\Element\ComponentVisibilityInterface;
- use Magento\Ui\Component\Layout\Tabs\TabInterface;
- /**
- * Class Tabs
- */
- class Tabs extends \Magento\Framework\View\Layout\Generic
- {
- /**
- * @var string
- */
- protected $navContainerName;
- /**
- * @var array
- */
- protected $structure = [];
- /**
- * @var int
- */
- protected $sortIncrement = 10;
- /**
- * Constructor
- *
- * @param UiComponentFactory $uiComponentFactory
- * @param null|string $navContainerName
- * @param array $data
- */
- public function __construct(UiComponentFactory $uiComponentFactory, $navContainerName = null, $data = [])
- {
- $this->navContainerName = $navContainerName;
- parent::__construct($uiComponentFactory, $data);
- }
- /**
- * Build
- *
- * @param UiComponentInterface $component
- * @return array
- */
- public function build(UiComponentInterface $component)
- {
- $this->component = $component;
- $this->namespace = $component->getContext()->getNamespace();
- $this->addNavigationBlock();
- // Initialization of structure components
- $this->initSections();
- $this->initAreas();
- return parent::build($component);
- }
- /**
- * Add children data
- *
- * @param array $topNode
- * @param UiComponentInterface $component
- * @param string $componentType
- * @return void
- * @throws \Magento\Framework\Exception\LocalizedException
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
- */
- protected function addChildren(array &$topNode, UiComponentInterface $component, $componentType)
- {
- $childrenAreas = [];
- $collectedComponents = [];
- foreach ($component->getChildComponents() as $childComponent) {
- if ($childComponent instanceof DataSourceInterface) {
- continue;
- }
- if ($childComponent instanceof BlockWrapperInterface) {
- $this->addWrappedBlock($childComponent, $childrenAreas);
- continue;
- }
- if ($childComponent instanceof ComponentVisibilityInterface && !$childComponent->isComponentVisible()) {
- continue;
- }
- $name = $childComponent->getName();
- $config = $childComponent->getData('config');
- $collectedComponents[$name] = true;
- [$childComponent, $structure] = $this->buildChildComponentStructure($config, $childComponent);
- $tabComponent = $this->createTabComponent($childComponent, $name);
- if (isset($structure[$name]['dataScope']) && $structure[$name]['dataScope']) {
- $dataScope = $structure[$name]['dataScope'];
- unset($structure[$name]['dataScope']);
- } else {
- $dataScope = 'data.' . $name;
- }
- $childrenAreas[$name] = [
- 'type' => $tabComponent->getComponentName(),
- 'dataScope' => $dataScope,
- 'config' => $config,
- 'insertTo' => [
- $this->namespace . '.sections' => [
- 'position' => $this->getNextSortIncrement()
- ]
- ],
- 'children' => $structure,
- ];
- }
- $this->structure[static::AREAS_KEY]['children'] = $childrenAreas;
- $topNode = $this->structure;
- }
- /**
- * Build child components structure of the tab
- *
- * @param array $config
- * @param UiComponentInterface $childComponent
- * @return array
- */
- private function buildChildComponentStructure(array $config, $childComponent): array
- {
- $name = $childComponent->getName();
- if (isset($config['is_collection']) && $config['is_collection'] === true) {
- $label = $childComponent->getData('config/label');
- $this->component->getContext()->addComponentDefinition(
- 'collection',
- [
- 'component' => 'Magento_Ui/js/form/components/collection',
- 'extends' => $this->namespace
- ]
- );
- /**
- * @var UiComponentInterface $childComponent
- * @var array $structure
- */
- [$childComponent, $structure] = $this->prepareChildComponents($childComponent, $name);
- $childrenStructure = $structure[$name]['children'];
- $structure[$name]['children'] = [
- $name . '_collection' => [
- 'type' => 'collection',
- 'config' => [
- 'active' => 1,
- 'removeLabel' => __('Remove %1', $label),
- 'addLabel' => __('Add New %1', $label),
- 'removeMessage' => $childComponent->getData('config/removeMessage'),
- 'itemTemplate' => 'item_template',
- ],
- 'children' => [
- 'item_template' => ['type' => $this->namespace,
- 'isTemplate' => true,
- 'component' => 'Magento_Ui/js/form/components/collection/item',
- 'childType' => 'group',
- 'config' => [
- 'label' => __('New %1', $label),
- ],
- 'children' => $childrenStructure
- ]
- ]
- ]
- ];
- } else {
- /**
- * @var UiComponentInterface $childComponent
- * @var array $structure
- */
- [$childComponent, $structure] = $this->prepareChildComponents($childComponent, $name);
- }
- return [$childComponent, $structure];
- }
- /**
- * Add wrapped layout block
- *
- * @param BlockWrapperInterface $childComponent
- * @param array $areas
- * @return void
- */
- protected function addWrappedBlock(BlockWrapperInterface $childComponent, array &$areas)
- {
- $name = $childComponent->getName();
- /** @var TabInterface $block */
- $block = $childComponent->getBlock();
- if (!$block->canShowTab()) {
- return;
- }
- if (!$block instanceof TabInterface) {
- parent::addWrappedBlock($childComponent, $areas);
- }
- $block->setData('target_form', $this->namespace);
- $config = [];
- if ($block->isAjaxLoaded()) {
- $config['url'] = $block->getTabUrl();
- } else {
- $config['content'] = $childComponent->getData('config/content') ?: $block->toHtml();
- }
- $tabComponent = $this->createTabComponent($childComponent, $name);
- $areas[$name] = [
- 'type' => $tabComponent->getComponentName(),
- 'dataScope' => $name,
- 'insertTo' => [
- $this->namespace . '.sections' => [
- 'position' => $block->hasSortOrder() ? $block->getSortOrder() : $this->getNextSortIncrement()
- ]
- ],
- 'config' => [
- 'label' => $block->getTabTitle()
- ],
- 'children' => [
- $name => [
- 'type' => 'html_content',
- 'dataScope' => $name,
- 'config' => $config,
- ]
- ],
- ];
- }
- /**
- * Create tab component
- *
- * @param UiComponentInterface $childComponent
- * @param string $name
- * @return UiComponentInterface
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- protected function createTabComponent(UiComponentInterface $childComponent, $name)
- {
- $tabComponent = $this->uiComponentFactory->create(
- $name,
- 'tab',
- [
- 'context' => $this->component->getContext(),
- 'components' => [$childComponent->getName() => $childComponent]
- ]
- );
- $tabComponent->prepare();
- $this->component->addComponent($name, $tabComponent);
- return $tabComponent;
- }
- /**
- * To prepare the structure of child components
- *
- * @param UiComponentInterface $component
- * @param string $parentName
- * @return array
- */
- protected function prepareChildComponents(UiComponentInterface $component, $parentName)
- {
- $name = $component->getName();
- $childComponents = $component->getChildComponents();
- $childrenStructure = [];
- foreach ($childComponents as $childName => $child) {
- $isVisible = $child->getData('config/visible');
- if ($isVisible !== null && $isVisible == 0) {
- continue;
- }
- /**
- * @var UiComponentInterface $childComponent
- * @var array $childStructure
- */
- list($childComponent, $childStructure) = $this->prepareChildComponents($child, $component->getName());
- $childrenStructure = array_merge($childrenStructure, $childStructure);
- $component->addComponent($childName, $childComponent);
- }
- $structure = [
- $name => [
- 'type' => $component->getComponentName(),
- 'name' => $component->getName(),
- 'children' => $childrenStructure
- ]
- ];
- list($config, $dataScope) = $this->prepareConfig((array) $component->getConfiguration(), $name, $parentName);
- if ($dataScope !== false) {
- $structure[$name]['dataScope'] = $dataScope;
- }
- $structure[$name]['config'] = $config;
- return [$component, $structure];
- }
- /**
- * Prepare config
- *
- * @param array $config
- * @param string $name
- * @param string $parentName
- * @return array
- */
- protected function prepareConfig(array $config, $name, $parentName)
- {
- $dataScope = false;
- if (!isset($config['displayArea'])) {
- $config['displayArea'] = 'body';
- }
- if (isset($config['dataScope'])) {
- $dataScope = $config['dataScope'];
- unset($config['dataScope']);
- } elseif ($name !== $parentName) {
- $dataScope = $name;
- }
- return [$config, $dataScope];
- }
- /**
- * Prepare initial structure for sections
- *
- * @return void
- */
- protected function initSections()
- {
- $this->structure[static::SECTIONS_KEY] = [
- 'type' => 'nav',
- 'config' => [
- 'label' => $this->component->getData('label'),
- ],
- 'children' => [],
- ];
- }
- /**
- * Prepare initial structure for areas
- *
- * @return void
- */
- protected function initAreas()
- {
- $this->structure[static::AREAS_KEY] = [
- 'type' => $this->namespace,
- 'config' => [
- 'namespace' => $this->namespace,
- ],
- 'children' => [],
- ];
- }
- /**
- * Add navigation block
- *
- * @return void
- */
- protected function addNavigationBlock()
- {
- $pageLayout = $this->component->getContext()->getPageLayout();
- $navName = 'tabs_nav';
- if ($pageLayout->hasElement($navName)) {
- $navName = $this->component->getName() . '_tabs_nav';
- }
- /** @var \Magento\Ui\Component\Layout\Tabs\Nav $navBlock */
- if (isset($this->navContainerName)) {
- $navBlock = $pageLayout->addBlock(
- \Magento\Ui\Component\Layout\Tabs\Nav::class,
- $navName,
- $this->navContainerName
- );
- } else {
- $navBlock = $pageLayout->addBlock(\Magento\Ui\Component\Layout\Tabs\Nav::class, $navName, 'content');
- }
- $navBlock->setTemplate('Magento_Ui::layout/tabs/nav/default.phtml');
- $navBlock->setData('data_scope', $this->namespace);
- $this->component->getContext()->addComponentDefinition(
- 'nav',
- [
- 'component' => 'Magento_Ui/js/form/components/tab_group',
- 'config' => [
- 'template' => 'ui/tab'
- ],
- 'extends' => $this->namespace
- ]
- );
- }
- /**
- * Get next sort increment
- *
- * @return int
- */
- protected function getNextSortIncrement()
- {
- $this->sortIncrement += 10;
- return $this->sortIncrement;
- }
- }
|