From 5c202497105301b17af9e902c62006079fdba4a5 Mon Sep 17 00:00:00 2001 From: Natalia Sekulich Date: Wed, 29 Apr 2026 09:01:24 +0300 Subject: [PATCH 1/5] ZIG-233 Add menu graphql resolver. Fix issues --- .php-cs-fixer.php | 2 +- Api/Data/ItemInterface.php | 2 +- Api/Data/ItemSearchResultsInterface.php | 2 +- Api/Data/MenuInterface.php | 2 +- Api/Data/MenuSearchResultsInterface.php | 2 +- Api/ItemRepositoryInterface.php | 2 +- Api/MenuRepositoryInterface.php | 10 ++- Controller/Adminhtml/Item.php | 2 +- Controller/Adminhtml/Item/Delete.php | 6 +- Controller/Adminhtml/Item/Edit.php | 8 +- Controller/Adminhtml/Item/Index.php | 2 +- Controller/Adminhtml/Item/InlineEdit.php | 2 +- Controller/Adminhtml/Item/MassDelete.php | 4 +- Controller/Adminhtml/Item/NewAction.php | 2 +- Controller/Adminhtml/Item/Save.php | 8 +- Controller/Adminhtml/Menu.php | 2 +- Controller/Adminhtml/Menu/Delete.php | 6 +- Controller/Adminhtml/Menu/Edit.php | 8 +- Controller/Adminhtml/Menu/Index.php | 2 +- Controller/Adminhtml/Menu/InlineEdit.php | 2 +- Controller/Adminhtml/Menu/MassDelete.php | 4 +- Controller/Adminhtml/Menu/NewAction.php | 2 +- Controller/Adminhtml/Menu/Save.php | 8 +- Model/DataBuilder/ItemCategory.php | 63 ++++++++++++++ Model/Item.php | 2 +- Model/Item/DataProvider.php | 2 +- Model/ItemRepository.php | 11 ++- Model/ItemSearchResults.php | 6 +- Model/Menu.php | 2 +- Model/Menu/DataProvider.php | 2 +- Model/MenuRepository.php | 24 +++-- Model/MenuSearchResults.php | 6 +- Model/Resolver/NavigationMenu.php | 87 +++++++++++++++++++ Model/ResourceModel/Item.php | 34 +++++++- Model/ResourceModel/Item/Collection.php | 14 +-- Model/ResourceModel/Item/Grid/Collection.php | 4 +- .../Item/Relation/Store/ReadHandler.php | 5 +- .../Item/Relation/Store/SaveHandler.php | 5 +- Model/ResourceModel/Menu.php | 17 +++- Model/ResourceModel/Menu/Collection.php | 4 +- Model/ResourceModel/Menu/Grid/Collection.php | 4 +- Model/SearchCriteria/ItemStoreFilter.php | 4 +- Model/Source/EntityType.php | 6 +- Model/Source/Menu.php | 7 +- Ui/Component/Listing/ItemActions.php | 2 +- Ui/Component/Listing/ItemStatus.php | 7 +- Ui/Component/Listing/MenuActions.php | 2 +- composer.json | 1 + etc/di.xml | 7 ++ etc/schema.graphqls | 31 +++++-- grumphp.yml | 2 +- registration.php | 4 +- 52 files changed, 342 insertions(+), 113 deletions(-) create mode 100644 Model/DataBuilder/ItemCategory.php create mode 100644 Model/Resolver/NavigationMenu.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 61a570b..4470646 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -1,7 +1,7 @@ getRequest()->getParam('id'); if (!$entityId) { $this->messageManager->addErrorMessage( - __('We can not find a Item to delete.')->render() + __('We can not find a Item to delete.')->render(), ); return $resultRedirect->setPath('*/*/'); @@ -32,7 +32,7 @@ public function execute(): ResultInterface try { $this->repository->deleteById($entityId); $this->messageManager->addSuccessMessage( - __('You deleted the Item')->render() + __('You deleted the Item')->render(), ); return $resultRedirect->setPath('*/*/'); diff --git a/Controller/Adminhtml/Item/Edit.php b/Controller/Adminhtml/Item/Edit.php index 1247554..e23ccfd 100644 --- a/Controller/Adminhtml/Item/Edit.php +++ b/Controller/Adminhtml/Item/Edit.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -41,7 +41,7 @@ public function execute(): ResultInterface $entity = $this->repository->getById($entityId); } catch (NoSuchEntityException $e) { $this->messageManager->addErrorMessage( - __('This Item no longer exists')->render() + __('This Item no longer exists')->render(), ); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); @@ -56,11 +56,11 @@ public function execute(): ResultInterface $resultPage->setActiveMenu('Mygento_Navigation::item'); $resultPage->addBreadcrumb( $entityId ? __('Edit Item')->render() : __('New Item')->render(), - $entityId ? __('Edit Item')->render() : __('New Item')->render() + $entityId ? __('Edit Item')->render() : __('New Item')->render(), ); $resultPage->getConfig()->getTitle()->prepend(__('Item')->render()); $resultPage->getConfig()->getTitle()->prepend( - $entityId ? $entity->getTitle() : __('New Item')->render() + $entityId ? $entity->getTitle() : __('New Item')->render(), ); return $resultPage; diff --git a/Controller/Adminhtml/Item/Index.php b/Controller/Adminhtml/Item/Index.php index 64ede35..1840532 100644 --- a/Controller/Adminhtml/Item/Index.php +++ b/Controller/Adminhtml/Item/Index.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Controller/Adminhtml/Item/InlineEdit.php b/Controller/Adminhtml/Item/InlineEdit.php index d0e7525..2541f9b 100644 --- a/Controller/Adminhtml/Item/InlineEdit.php +++ b/Controller/Adminhtml/Item/InlineEdit.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Controller/Adminhtml/Item/MassDelete.php b/Controller/Adminhtml/Item/MassDelete.php index 406a074..02b56f8 100644 --- a/Controller/Adminhtml/Item/MassDelete.php +++ b/Controller/Adminhtml/Item/MassDelete.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -40,7 +40,7 @@ public function execute(): ResultInterface $this->repository->delete($entity); } $this->messageManager->addSuccessMessage( - __('A total of %1 record(s) have been deleted.', $collectionSize)->render() + __('A total of %1 record(s) have been deleted.', $collectionSize)->render(), ); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); diff --git a/Controller/Adminhtml/Item/NewAction.php b/Controller/Adminhtml/Item/NewAction.php index ba82101..864674d 100644 --- a/Controller/Adminhtml/Item/NewAction.php +++ b/Controller/Adminhtml/Item/NewAction.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Controller/Adminhtml/Item/Save.php b/Controller/Adminhtml/Item/Save.php index cdf96f0..8ebcd57 100644 --- a/Controller/Adminhtml/Item/Save.php +++ b/Controller/Adminhtml/Item/Save.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -52,7 +52,7 @@ public function execute(): ResultInterface } catch (NoSuchEntityException $e) { if (!$entity->getId()) { $this->messageManager->addErrorMessage( - __('This Item no longer exists')->render() + __('This Item no longer exists')->render(), ); return $resultRedirect->setPath('*/*/'); @@ -67,7 +67,7 @@ public function execute(): ResultInterface try { $this->repository->save($entity); $this->messageManager->addSuccessMessage( - __('You saved the Item')->render() + __('You saved the Item')->render(), ); $this->dataPersistor->clear('navigation_item'); if ($this->getRequest()->getParam('back')) { @@ -80,7 +80,7 @@ public function execute(): ResultInterface } catch (\Exception $e) { $this->messageManager->addExceptionMessage( $e, - __('Something went wrong while saving the Item')->render() + __('Something went wrong while saving the Item')->render(), ); } $this->dataPersistor->set('navigation_item', $data); diff --git a/Controller/Adminhtml/Menu.php b/Controller/Adminhtml/Menu.php index 1081e04..f1222b4 100644 --- a/Controller/Adminhtml/Menu.php +++ b/Controller/Adminhtml/Menu.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Controller/Adminhtml/Menu/Delete.php b/Controller/Adminhtml/Menu/Delete.php index 96fbd03..f0d25bd 100644 --- a/Controller/Adminhtml/Menu/Delete.php +++ b/Controller/Adminhtml/Menu/Delete.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -23,7 +23,7 @@ public function execute(): ResultInterface $entityId = (int) $this->getRequest()->getParam('id'); if (!$entityId) { $this->messageManager->addErrorMessage( - __('We can not find a Menu to delete.')->render() + __('We can not find a Menu to delete.')->render(), ); return $resultRedirect->setPath('*/*/'); @@ -32,7 +32,7 @@ public function execute(): ResultInterface try { $this->repository->deleteById($entityId); $this->messageManager->addSuccessMessage( - __('You deleted the Menu')->render() + __('You deleted the Menu')->render(), ); return $resultRedirect->setPath('*/*/'); diff --git a/Controller/Adminhtml/Menu/Edit.php b/Controller/Adminhtml/Menu/Edit.php index cf98391..edbe111 100644 --- a/Controller/Adminhtml/Menu/Edit.php +++ b/Controller/Adminhtml/Menu/Edit.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -41,7 +41,7 @@ public function execute(): ResultInterface $entity = $this->repository->getById($entityId); } catch (NoSuchEntityException $e) { $this->messageManager->addErrorMessage( - __('This Menu no longer exists')->render() + __('This Menu no longer exists')->render(), ); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); @@ -56,11 +56,11 @@ public function execute(): ResultInterface $resultPage->setActiveMenu('Mygento_Navigation::menu'); $resultPage->addBreadcrumb( $entityId ? __('Edit Menu')->render() : __('New Menu')->render(), - $entityId ? __('Edit Menu')->render() : __('New Menu')->render() + $entityId ? __('Edit Menu')->render() : __('New Menu')->render(), ); $resultPage->getConfig()->getTitle()->prepend(__('Menu')->render()); $resultPage->getConfig()->getTitle()->prepend( - $entityId ? $entity->getTitle() : __('New Menu')->render() + $entityId ? $entity->getTitle() : __('New Menu')->render(), ); return $resultPage; diff --git a/Controller/Adminhtml/Menu/Index.php b/Controller/Adminhtml/Menu/Index.php index eaf04b9..1fc3dee 100644 --- a/Controller/Adminhtml/Menu/Index.php +++ b/Controller/Adminhtml/Menu/Index.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Controller/Adminhtml/Menu/InlineEdit.php b/Controller/Adminhtml/Menu/InlineEdit.php index d335033..479c59a 100644 --- a/Controller/Adminhtml/Menu/InlineEdit.php +++ b/Controller/Adminhtml/Menu/InlineEdit.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Controller/Adminhtml/Menu/MassDelete.php b/Controller/Adminhtml/Menu/MassDelete.php index 611724e..ce6495c 100644 --- a/Controller/Adminhtml/Menu/MassDelete.php +++ b/Controller/Adminhtml/Menu/MassDelete.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -40,7 +40,7 @@ public function execute(): ResultInterface $this->repository->delete($entity); } $this->messageManager->addSuccessMessage( - __('A total of %1 record(s) have been deleted.', $collectionSize)->render() + __('A total of %1 record(s) have been deleted.', $collectionSize)->render(), ); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); diff --git a/Controller/Adminhtml/Menu/NewAction.php b/Controller/Adminhtml/Menu/NewAction.php index dc37803..5520e48 100644 --- a/Controller/Adminhtml/Menu/NewAction.php +++ b/Controller/Adminhtml/Menu/NewAction.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Controller/Adminhtml/Menu/Save.php b/Controller/Adminhtml/Menu/Save.php index ad3b97d..4a20326 100644 --- a/Controller/Adminhtml/Menu/Save.php +++ b/Controller/Adminhtml/Menu/Save.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -52,7 +52,7 @@ public function execute(): ResultInterface } catch (NoSuchEntityException $e) { if (!$entity->getId()) { $this->messageManager->addErrorMessage( - __('This Menu no longer exists')->render() + __('This Menu no longer exists')->render(), ); return $resultRedirect->setPath('*/*/'); @@ -67,7 +67,7 @@ public function execute(): ResultInterface try { $this->repository->save($entity); $this->messageManager->addSuccessMessage( - __('You saved the Menu')->render() + __('You saved the Menu')->render(), ); $this->dataPersistor->clear('navigation_menu'); if ($this->getRequest()->getParam('back')) { @@ -80,7 +80,7 @@ public function execute(): ResultInterface } catch (\Exception $e) { $this->messageManager->addExceptionMessage( $e, - __('Something went wrong while saving the Menu')->render() + __('Something went wrong while saving the Menu')->render(), ); } $this->dataPersistor->set('navigation_menu', $data); diff --git a/Model/DataBuilder/ItemCategory.php b/Model/DataBuilder/ItemCategory.php new file mode 100644 index 0000000..a1ca4c0 --- /dev/null +++ b/Model/DataBuilder/ItemCategory.php @@ -0,0 +1,63 @@ +getCategories($targetEntityIds); + if (empty($categories)) { + return $itemsData; + } + foreach ($itemsData as &$item) { + $itemCategory = $categories[$item['target_entity_id']] ?? null; + if (!empty($itemCategory)) { + $item['link'] = $this->getCategoryUrlKey($itemCategory->getUrlKey()); + $item['image'] = $itemCategory->getImage(); //todo check after implementation + } + } + + return $itemsData; + } + + private function getCategoryUrlKey(?string $urlKey): ?string + { + if (!$urlKey) { + return null; + } + $suffix = $this->scopeConfig->getValue('catalog/seo/category_url_suffix'); + + return $urlKey . $suffix; + } + + private function getCategories(array $ids): array + { + /** @var Collection $collection */ + $collection = $this->categoryCollection->create(); + $collection->addFieldToFilter('entity_id', $ids); + $collection->addFieldToSelect(['url_key', 'image']); + + return $collection->getItems(); + } +} diff --git a/Model/Item.php b/Model/Item.php index f486e08..4ecee23 100644 --- a/Model/Item.php +++ b/Model/Item.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Model/Item/DataProvider.php b/Model/Item/DataProvider.php index 3ff4455..f1c8bf5 100644 --- a/Model/Item/DataProvider.php +++ b/Model/Item/DataProvider.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Model/ItemRepository.php b/Model/ItemRepository.php index 7c85b19..4d58248 100644 --- a/Model/ItemRepository.php +++ b/Model/ItemRepository.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -33,8 +33,7 @@ public function __construct( private readonly ItemSearchResultsInterfaceFactory $searchResultsFactory, private readonly StoreManagerInterface $storeManager, private readonly CollectionProcessorInterface $collectionProcessor, - ) { - } + ) {} /** * @throws NoSuchEntityException @@ -45,7 +44,7 @@ public function getById(int $entityId): ItemInterface $this->resource->load($entity, $entityId); if (!$entity->getId()) { throw new NoSuchEntityException( - __('A Navigation Item with id "%1" does not exist', $entityId) + __('A Navigation Item with id "%1" does not exist', $entityId), ); } @@ -66,7 +65,7 @@ public function save(ItemInterface $entity): ItemInterface } catch (\Exception $exception) { throw new CouldNotSaveException( __('Could not save the Navigation Item'), - $exception + $exception, ); } @@ -82,7 +81,7 @@ public function delete(ItemInterface $entity): bool $this->resource->delete($entity); } catch (\Exception $exception) { throw new CouldNotDeleteException( - __($exception->getMessage()) + __($exception->getMessage()), ); } diff --git a/Model/ItemSearchResults.php b/Model/ItemSearchResults.php index 0071cf0..50a0aeb 100644 --- a/Model/ItemSearchResults.php +++ b/Model/ItemSearchResults.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -11,6 +11,4 @@ use Magento\Framework\Api\SearchResults; use Mygento\Navigation\Api\Data\ItemSearchResultsInterface; -class ItemSearchResults extends SearchResults implements ItemSearchResultsInterface -{ -} +class ItemSearchResults extends SearchResults implements ItemSearchResultsInterface {} diff --git a/Model/Menu.php b/Model/Menu.php index 3641b06..218aaba 100644 --- a/Model/Menu.php +++ b/Model/Menu.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Model/Menu/DataProvider.php b/Model/Menu/DataProvider.php index f33f5d1..a73acac 100644 --- a/Model/Menu/DataProvider.php +++ b/Model/Menu/DataProvider.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Model/MenuRepository.php b/Model/MenuRepository.php index a880dc4..8261ed3 100644 --- a/Model/MenuRepository.php +++ b/Model/MenuRepository.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -31,8 +31,7 @@ public function __construct( private readonly MenuInterfaceFactory $entityFactory, private readonly MenuSearchResultsInterfaceFactory $searchResultsFactory, private readonly CollectionProcessorInterface $collectionProcessor, - ) { - } + ) {} /** * @throws NoSuchEntityException @@ -43,7 +42,7 @@ public function getById(int $entityId): MenuInterface $this->resource->load($entity, $entityId); if (!$entity->getId()) { throw new NoSuchEntityException( - __('A Navigation Menu with id "%1" does not exist', $entityId) + __('A Navigation Menu with id "%1" does not exist', $entityId), ); } @@ -60,7 +59,7 @@ public function save(MenuInterface $entity): MenuInterface } catch (\Exception $exception) { throw new CouldNotSaveException( __('Could not save the Navigation Menu'), - $exception + $exception, ); } @@ -76,7 +75,7 @@ public function delete(MenuInterface $entity): bool $this->resource->delete($entity); } catch (\Exception $exception) { throw new CouldNotDeleteException( - __($exception->getMessage()) + __($exception->getMessage()), ); } @@ -92,6 +91,19 @@ public function deleteById(int $entityId): bool return $this->delete($this->getById($entityId)); } + public function getByCode(string $code): MenuInterface + { + $entity = $this->entityFactory->create(); + $this->resource->loadByCode($entity, $code); + if (!$entity->getId()) { + throw new NoSuchEntityException( + __('A menu with code "%1" does not exist', $code), + ); + } + + return $entity; + } + public function getList(SearchCriteriaInterface $criteria): MenuSearchResultsInterface { /** @var \Mygento\Navigation\Model\ResourceModel\Menu\Collection $collection */ diff --git a/Model/MenuSearchResults.php b/Model/MenuSearchResults.php index f7cc2a1..0712451 100644 --- a/Model/MenuSearchResults.php +++ b/Model/MenuSearchResults.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -11,6 +11,4 @@ use Magento\Framework\Api\SearchResults; use Mygento\Navigation\Api\Data\MenuSearchResultsInterface; -class MenuSearchResults extends SearchResults implements MenuSearchResultsInterface -{ -} +class MenuSearchResults extends SearchResults implements MenuSearchResultsInterface {} diff --git a/Model/Resolver/NavigationMenu.php b/Model/Resolver/NavigationMenu.php new file mode 100644 index 0000000..6e5c3ad --- /dev/null +++ b/Model/Resolver/NavigationMenu.php @@ -0,0 +1,87 @@ +dataBuilders = $dataBuilders; + } + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @param Field $field + * @param $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * + * @throws GraphQlNoSuchEntityException + * @return array + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + ?array $value = null, + ?array $args = null, + ) { + $code = $args['code'] ?? null; + + try { + $menu = $this->menuRepository->getByCode($code); + } catch (LocalizedException $e) { + throw new GraphQlNoSuchEntityException(__('Product menu "%1" not found or disabled', $code)); + } + $storeId = (int) $context->getExtensionAttributes()->getStore()->getId(); + $targetEntityIds = []; + $itemsByType = []; + $itemsData = $this->itemResource->getItemsWithTargetEntityId((int) $menu->getId(), $storeId); + foreach ($itemsData as $item) { + $targetEntityIds[$item['entity_type']][$item['target_entity_id']] = $item['target_entity_id']; + $itemsByType[$item['entity_type']][] = $item; + } + $preparedItems = $this->prepareItems($itemsByType, $targetEntityIds); + + return [ + 'code' => $code, + 'items' => $preparedItems, + ]; + } + + private function prepareItems(array $itemsByType, array $targetEntityIds): array + { + $preparedItems = []; + foreach ($itemsByType as $type => $items) { + $dataBuilder = $this->dataBuilders[$type] ?? null; + if ($dataBuilder && method_exists($dataBuilder, 'addData')) { + $items = $dataBuilder->addData($items, $targetEntityIds[$type]); + } + $preparedItems = array_merge($preparedItems, $items); + } + + return $preparedItems; + } +} diff --git a/Model/ResourceModel/Item.php b/Model/ResourceModel/Item.php index 36c13b9..822902d 100644 --- a/Model/ResourceModel/Item.php +++ b/Model/ResourceModel/Item.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -82,13 +82,43 @@ public function lookupStoreIds(int $id): array ->join( ['e' => $this->getMainTable()], 'es.entity_id = e.' . $linkField, - [] + [], ) ->where('e.' . $entityMetadata->getIdentifierField() . ' = :entity_id'); return $connection->fetchCol($select, ['entity_id' => (int) $id]); } + public function getItemsWithTargetEntityId(int $menuId, int $storeId): array + { + $connection = $this->getConnection(); + $entityMetadata = $this->metadataPool->getMetadata(ItemInterface::class); + $linkField = $entityMetadata->getLinkField(); + $select = $connection->select()->distinct() + ->from( + ['e' => $this->getMainTable()], + [ + 'entity_id', + 'entity_type', + 'name', + 'sort_order', + 'target_entity_id' => new \Zend_Db_Expr( + "JSON_UNQUOTE(JSON_EXTRACT(entity_slug, '$.target_entity_id'))", + ), + ], + ) + ->joinInner( + ['es' => $this->getMainTable() . '_store'], + 'store_id = ' . $storeId . ' AND es.entity_id = e.' . $linkField, + [], + ) + ->where('e.is_active = 1') + ->where('e.menu = ?', $menuId) + ->order('e.sort_order ASC'); + + return $connection->fetchAll($select); + } + /** * Initialize resource model */ diff --git a/Model/ResourceModel/Item/Collection.php b/Model/ResourceModel/Item/Collection.php index cf80a3d..ecb1c18 100644 --- a/Model/ResourceModel/Item/Collection.php +++ b/Model/ResourceModel/Item/Collection.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -43,7 +43,7 @@ public function __construct( $fetchStrategy, $eventManager, $connection, - $resource + $resource, ); } @@ -54,7 +54,7 @@ protected function _construct() { $this->_init( Item::class, - ItemResource::class + ItemResource::class, ); } @@ -69,7 +69,7 @@ protected function _afterLoad() $connection = $this->getConnection(); $select = $connection->select()->from( - ['entity_store' => $this->getTable($this->getMainTable() . '_store')] + ['entity_store' => $this->getTable($this->getMainTable() . '_store')], )->where('entity_store.entity_id IN (?)', $linkedIds); $result = $connection->fetchAll($select); @@ -79,11 +79,11 @@ protected function _afterLoad() $stores = []; foreach ($result as $r) { - $stores[] = $r['store_id']; + $stores[$r['entity_id']][] = $r['store_id']; } foreach ($this as $item) { - $item->setData('store_id', $stores); + $item->setData('store_id', $stores[$item->getId()]); } return parent::_afterLoad(); @@ -103,7 +103,7 @@ protected function _renderFiltersBefore() $this->getSelect()->join( ['store_table' => $this->getMainTable() . '_store'], 'main_table.' . $linkField . ' = store_table.entity_id', - [] + [], )->group('main_table.' . $linkField); parent::_renderFiltersBefore(); diff --git a/Model/ResourceModel/Item/Grid/Collection.php b/Model/ResourceModel/Item/Grid/Collection.php index 94cc43b..ad5ead9 100644 --- a/Model/ResourceModel/Item/Grid/Collection.php +++ b/Model/ResourceModel/Item/Grid/Collection.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -48,7 +48,7 @@ public function __construct( $fetchStrategy, $eventManager, $connection, - $resource + $resource, ); $this->_eventPrefix = $eventPrefix; $this->_eventObject = $eventObject; diff --git a/Model/ResourceModel/Item/Relation/Store/ReadHandler.php b/Model/ResourceModel/Item/Relation/Store/ReadHandler.php index 5af1a6d..874ca43 100644 --- a/Model/ResourceModel/Item/Relation/Store/ReadHandler.php +++ b/Model/ResourceModel/Item/Relation/Store/ReadHandler.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -16,8 +16,7 @@ class ReadHandler implements ExtensionInterface { public function __construct( private readonly Item $resource, - ) { - } + ) {} /** * @inheritDoc diff --git a/Model/ResourceModel/Item/Relation/Store/SaveHandler.php b/Model/ResourceModel/Item/Relation/Store/SaveHandler.php index c9d344e..f86af9f 100644 --- a/Model/ResourceModel/Item/Relation/Store/SaveHandler.php +++ b/Model/ResourceModel/Item/Relation/Store/SaveHandler.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -18,8 +18,7 @@ class SaveHandler implements ExtensionInterface public function __construct( private readonly Item $resource, private readonly MetadataPool $metadataPool, - ) { - } + ) {} /** * @inheritDoc diff --git a/Model/ResourceModel/Menu.php b/Model/ResourceModel/Menu.php index 2511a2b..20e8e64 100644 --- a/Model/ResourceModel/Menu.php +++ b/Model/ResourceModel/Menu.php @@ -2,12 +2,13 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ namespace Mygento\Navigation\Model\ResourceModel; +use Magento\Framework\Model\AbstractModel; use Magento\Framework\Model\ResourceModel\Db\AbstractDb; class Menu extends AbstractDb @@ -15,6 +16,20 @@ class Menu extends AbstractDb public const TABLE_NAME = 'mygento_navigation_menu'; public const TABLE_PRIMARY_KEY = 'entity_id'; + public function loadByCode(AbstractModel $object, string $code): AbstractModel + { + $connection = $this->getConnection(); + $select = $connection->select() + ->from($this->getMainTable()) + ->where('code = :code'); + + $data = $connection->fetchRow($select, [':code' => $code]); + + $object->setData($data); + + return $object; + } + /** * Initialize resource model */ diff --git a/Model/ResourceModel/Menu/Collection.php b/Model/ResourceModel/Menu/Collection.php index ce66995..af0454b 100644 --- a/Model/ResourceModel/Menu/Collection.php +++ b/Model/ResourceModel/Menu/Collection.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -24,7 +24,7 @@ protected function _construct() { $this->_init( Menu::class, - MenuResource::class + MenuResource::class, ); } } diff --git a/Model/ResourceModel/Menu/Grid/Collection.php b/Model/ResourceModel/Menu/Grid/Collection.php index ecbbf4d..5ae18f1 100644 --- a/Model/ResourceModel/Menu/Grid/Collection.php +++ b/Model/ResourceModel/Menu/Grid/Collection.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -45,7 +45,7 @@ public function __construct( $fetchStrategy, $eventManager, $connection, - $resource + $resource, ); $this->_eventPrefix = $eventPrefix; $this->_eventObject = $eventObject; diff --git a/Model/SearchCriteria/ItemStoreFilter.php b/Model/SearchCriteria/ItemStoreFilter.php index 6fb49ac..9ea847c 100644 --- a/Model/SearchCriteria/ItemStoreFilter.php +++ b/Model/SearchCriteria/ItemStoreFilter.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -22,7 +22,7 @@ public function apply(Filter $filter, AbstractDb $collection): bool { $collection->addFilter( ItemInterface::STORE_ID, - ['in' => $filter->getValue()] + ['in' => $filter->getValue()], ); return true; diff --git a/Model/Source/EntityType.php b/Model/Source/EntityType.php index 843ad40..545e694 100644 --- a/Model/Source/EntityType.php +++ b/Model/Source/EntityType.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -12,9 +12,7 @@ class EntityType implements OptionSourceInterface { - public function __construct(private array $types = []) - { - } + public function __construct(private array $types = []) {} public function toOptionArray(): array { diff --git a/Model/Source/Menu.php b/Model/Source/Menu.php index e7f56fb..6902de6 100644 --- a/Model/Source/Menu.php +++ b/Model/Source/Menu.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -17,15 +17,14 @@ class Menu implements OptionSourceInterface public function __construct( private MenuRepositoryInterface $repo, private SearchCriteriaBuilder $builder, - ) { - } + ) {} public function toOptionArray(): array { $result = []; $data = $this->repo->getList($this->builder->create())->getItems(); - foreach($data as $i) { + foreach ($data as $i) { $result[] = ['value' => $i->getEntityId(), 'label' => $i->getCode()]; } diff --git a/Ui/Component/Listing/ItemActions.php b/Ui/Component/Listing/ItemActions.php index 9c2939c..d10e6e6 100644 --- a/Ui/Component/Listing/ItemActions.php +++ b/Ui/Component/Listing/ItemActions.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/Ui/Component/Listing/ItemStatus.php b/Ui/Component/Listing/ItemStatus.php index a47be17..d175562 100644 --- a/Ui/Component/Listing/ItemStatus.php +++ b/Ui/Component/Listing/ItemStatus.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ @@ -41,8 +41,9 @@ private function getOptionText($item) { $statusesArray = [ 1 => __('Active'), - 2 => __('Inactive') + 2 => __('Inactive'), ]; - return isset($statusesArray[$item]) ? $statusesArray[$item]: null; + + return $statusesArray[$item] ?? null; } } diff --git a/Ui/Component/Listing/MenuActions.php b/Ui/Component/Listing/MenuActions.php index 94891ba..a5e348b 100644 --- a/Ui/Component/Listing/MenuActions.php +++ b/Ui/Component/Listing/MenuActions.php @@ -2,7 +2,7 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ diff --git a/composer.json b/composer.json index ded0711..876b965 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "mygento" ], "require": { + "mygento/module-base": "~2.4.0" }, "require-dev": { "mygento/coding-standard": "v2.4.x-dev" diff --git a/etc/di.xml b/etc/di.xml index 86f4ac3..4cd3b21 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -109,4 +109,11 @@ Mygento\Navigation\Model\ResourceModel\Item + + + + Mygento\Navigation\Model\DataBuilder\ItemCategory + + + diff --git a/etc/schema.graphqls b/etc/schema.graphqls index b42e38e..548e1c0 100644 --- a/etc/schema.graphqls +++ b/etc/schema.graphqls @@ -1,8 +1,23 @@ -type NavigationItem @doc(description: "Item") { - menu: Int @doc(description: "Menu ID") - is_active: Boolean! @doc(description: "Is_active") - name: String! @doc(description: "Name") - entity_type: String! @doc(description: "Link Type") - entity_slug: String @doc(description: "Link Identifier") - sort_order: Int! @doc(description: "Link Sort Order") -} \ No newline at end of file +type NavigationMenuItem @doc(description: "Item") { +# menu: Int @doc(description: "Menu ID") +# is_active: Boolean! @doc(description: "Is_active") +# name: String! @doc(description: "Name") +# entity_type: String! @doc(description: "Link Type") +# entity_slug: String @doc(description: "Link Identifier") +# sort_order: Int! @doc(description: "Link Sort Order") + sort_order: Int! @doc(description: "Item Sort Order") + name: String! @doc(description: "Item name") + image: String @doc(description: "Item image") + link: String @doc(description: "Item link") +} + +type Query { + navigationMenu( + code: String!, + ): NavigationMenu @resolver(class: "Mygento\\Navigation\\Model\\Resolver\\NavigationMenu") +} + +type NavigationMenu { + code: String! + items: [NavigationMenuItem!] @doc(description: "List of items in menu") +} diff --git a/grumphp.yml b/grumphp.yml index 90582de..45a8e36 100644 --- a/grumphp.yml +++ b/grumphp.yml @@ -17,6 +17,6 @@ grumphp: warning_severity: 0 xmllint: phpstan: - autoload_file: 'vendor/mygento/coding-standard/stan/autoload.php' +# autoload_file: 'vendor/mygento/coding-standard/stan/autoload.php' ignore_patterns: ['Test'] level: 1 diff --git a/registration.php b/registration.php index 3371711..9c4c163 100644 --- a/registration.php +++ b/registration.php @@ -2,12 +2,12 @@ /** * @author Mygento Team - * @copyright 2023 Mygento (https://www.mygento.com) + * @copyright 2023-2026 Mygento (https://www.mygento.com) * @package Mygento_Navigation */ \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Mygento_Navigation', - __DIR__ + __DIR__, ); From 7b1e8fce1d91ae42dcde781e86bfee3f4f4c16d8 Mon Sep 17 00:00:00 2001 From: Natalia Sekulich Date: Wed, 29 Apr 2026 19:48:00 +0300 Subject: [PATCH 2/5] ZIG-233 Remove customization --- Model/DataBuilder/ItemCategory.php | 63 ------------------------------ Model/Resolver/NavigationMenu.php | 37 +++++++++++++++--- Model/ResourceModel/Item.php | 2 + etc/di.xml | 7 ---- etc/schema.graphqls | 8 ---- 5 files changed, 34 insertions(+), 83 deletions(-) delete mode 100644 Model/DataBuilder/ItemCategory.php diff --git a/Model/DataBuilder/ItemCategory.php b/Model/DataBuilder/ItemCategory.php deleted file mode 100644 index a1ca4c0..0000000 --- a/Model/DataBuilder/ItemCategory.php +++ /dev/null @@ -1,63 +0,0 @@ -getCategories($targetEntityIds); - if (empty($categories)) { - return $itemsData; - } - foreach ($itemsData as &$item) { - $itemCategory = $categories[$item['target_entity_id']] ?? null; - if (!empty($itemCategory)) { - $item['link'] = $this->getCategoryUrlKey($itemCategory->getUrlKey()); - $item['image'] = $itemCategory->getImage(); //todo check after implementation - } - } - - return $itemsData; - } - - private function getCategoryUrlKey(?string $urlKey): ?string - { - if (!$urlKey) { - return null; - } - $suffix = $this->scopeConfig->getValue('catalog/seo/category_url_suffix'); - - return $urlKey . $suffix; - } - - private function getCategories(array $ids): array - { - /** @var Collection $collection */ - $collection = $this->categoryCollection->create(); - $collection->addFieldToFilter('entity_id', $ids); - $collection->addFieldToSelect(['url_key', 'image']); - - return $collection->getItems(); - } -} diff --git a/Model/Resolver/NavigationMenu.php b/Model/Resolver/NavigationMenu.php index 6e5c3ad..cf53725 100644 --- a/Model/Resolver/NavigationMenu.php +++ b/Model/Resolver/NavigationMenu.php @@ -27,7 +27,7 @@ public function __construct( private Item $itemResource, array $dataBuilders = [], ) { - $this->dataBuilders = $dataBuilders; + $this->dataBuilders = $this->prepareDataBuilders($dataBuilders); } /** @@ -52,7 +52,7 @@ public function resolve( try { $menu = $this->menuRepository->getByCode($code); - } catch (LocalizedException $e) { + } catch (LocalizedException) { throw new GraphQlNoSuchEntityException(__('Product menu "%1" not found or disabled', $code)); } $storeId = (int) $context->getExtensionAttributes()->getStore()->getId(); @@ -75,13 +75,40 @@ private function prepareItems(array $itemsByType, array $targetEntityIds): array { $preparedItems = []; foreach ($itemsByType as $type => $items) { - $dataBuilder = $this->dataBuilders[$type] ?? null; - if ($dataBuilder && method_exists($dataBuilder, 'addData')) { - $items = $dataBuilder->addData($items, $targetEntityIds[$type]); + $dataBuilders = $this->dataBuilders[$type] ?? []; + foreach ($dataBuilders as $dataBuilder) { + if ($dataBuilder && method_exists($dataBuilder, 'addData')) { + $items = $dataBuilder->addData($items, $targetEntityIds[$type]); + } } $preparedItems = array_merge($preparedItems, $items); } return $preparedItems; } + + private function prepareDataBuilders(array $dataBuilders): array + { + $buildersByType = []; + foreach ($dataBuilders as $builderConfig) { + if (!isset($builderConfig['entity_type'], $builderConfig['class'], $builderConfig['sortOrder'])) { + continue; + } + + $buildersByType[$builderConfig['entity_type']][] = [ + 'class' => $builderConfig['class'], + 'sortOrder' => $builderConfig['sortOrder'], + ]; + } + + foreach ($buildersByType as $type => $builders) { + usort($builders, function ($a, $b) { + return $a['sortOrder'] <=> $b['sortOrder']; + }); + + $buildersByType[$type] = array_column($builders, 'class'); + } + + return $buildersByType; + } } diff --git a/Model/ResourceModel/Item.php b/Model/ResourceModel/Item.php index 822902d..e781c38 100644 --- a/Model/ResourceModel/Item.php +++ b/Model/ResourceModel/Item.php @@ -102,6 +102,8 @@ public function getItemsWithTargetEntityId(int $menuId, int $storeId): array 'entity_type', 'name', 'sort_order', + //todo check and apply changes after implementation main logic for saving entities + // is based on the assumption that entity_slug contains json like {"target_entity_id": "2"} 'target_entity_id' => new \Zend_Db_Expr( "JSON_UNQUOTE(JSON_EXTRACT(entity_slug, '$.target_entity_id'))", ), diff --git a/etc/di.xml b/etc/di.xml index 4cd3b21..86f4ac3 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -109,11 +109,4 @@ Mygento\Navigation\Model\ResourceModel\Item - - - - Mygento\Navigation\Model\DataBuilder\ItemCategory - - - diff --git a/etc/schema.graphqls b/etc/schema.graphqls index 548e1c0..da146f5 100644 --- a/etc/schema.graphqls +++ b/etc/schema.graphqls @@ -1,14 +1,6 @@ type NavigationMenuItem @doc(description: "Item") { -# menu: Int @doc(description: "Menu ID") -# is_active: Boolean! @doc(description: "Is_active") -# name: String! @doc(description: "Name") -# entity_type: String! @doc(description: "Link Type") -# entity_slug: String @doc(description: "Link Identifier") -# sort_order: Int! @doc(description: "Link Sort Order") sort_order: Int! @doc(description: "Item Sort Order") name: String! @doc(description: "Item name") - image: String @doc(description: "Item image") - link: String @doc(description: "Item link") } type Query { From c345ab0f68847dabf37e87e45e05d525ce5ec794 Mon Sep 17 00:00:00 2001 From: Natalia Sekulich Date: Tue, 5 May 2026 15:25:10 +0300 Subject: [PATCH 3/5] ZIG-233 Add image uploader to menu item --- Controller/Adminhtml/Item/Save.php | 24 ++++++ Controller/Adminhtml/Item/Upload.php | 38 +++++++++ Model/FileInfo.php | 81 +++++++++++++++++++ Model/Item/DataProvider.php | 34 +++++++- Model/Resolver/NavigationMenu.php | 3 + Model/ResourceModel/Item.php | 1 + etc/adminhtml/di.xml | 26 ++++++ etc/db_schema.xml | 1 + etc/schema.graphqls | 1 + .../ui_component/navigation_item_edit.xml | 30 +++++++ 10 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 Controller/Adminhtml/Item/Upload.php create mode 100644 Model/FileInfo.php diff --git a/Controller/Adminhtml/Item/Save.php b/Controller/Adminhtml/Item/Save.php index 8ebcd57..7f65058 100644 --- a/Controller/Adminhtml/Item/Save.php +++ b/Controller/Adminhtml/Item/Save.php @@ -14,6 +14,7 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Registry; +use Mygento\Base\Model\ImageUploader; use Mygento\Navigation\Api\Data\ItemInterfaceFactory; use Mygento\Navigation\Api\ItemRepositoryInterface; use Mygento\Navigation\Controller\Adminhtml\Item; @@ -23,6 +24,7 @@ class Save extends Item public function __construct( private readonly DataPersistorInterface $dataPersistor, private readonly ItemInterfaceFactory $entityFactory, + private ImageUploader $imageUploader, ItemRepositoryInterface $repository, Registry $coreRegistry, Context $context, @@ -63,6 +65,7 @@ public function execute(): ResultInterface $data['entity_id'] = null; } $entity->setData($data); + $entity->setImage($this->processImage($data, 'image') ?? ''); try { $this->repository->save($entity); @@ -87,4 +90,25 @@ public function execute(): ResultInterface return $resultRedirect->setPath('*/*/edit', ['id' => $this->getRequest()->getParam('id')]); } + + private function processImage(array $data, string $key): ?string + { + $value = $data[$key] ?? null; + if (!$value) { + return null; + } + if (!is_array($value)) { + return null; + } + $imageName = $value['0']['name'] ?? null; + if (!$imageName) { + return null; + } + if ($imageName && !isset($value[0]['tmp_name'])) { + return $imageName; + } + + return $this->imageUploader->getBasePath() + . '/' . $this->imageUploader->moveFileFromTmp($imageName); + } } diff --git a/Controller/Adminhtml/Item/Upload.php b/Controller/Adminhtml/Item/Upload.php new file mode 100644 index 0000000..b74f143 --- /dev/null +++ b/Controller/Adminhtml/Item/Upload.php @@ -0,0 +1,38 @@ +_request->getParam('param_name', 'image'); + + try { + $result = $this->imageUploader->saveFileToTmpDir($imageId); + } catch (\Exception $e) { + $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; + } + + return $this->resultJsonFactory->create()->setData($result); + } +} diff --git a/Model/FileInfo.php b/Model/FileInfo.php new file mode 100644 index 0000000..b5c9d8e --- /dev/null +++ b/Model/FileInfo.php @@ -0,0 +1,81 @@ +storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA); + + return rtrim($mediaBaseUrl, '/') . '/' . $fileName; + } + + public function getMediaUrl(string $fileName): string + { + return UrlInterface::URL_TYPE_MEDIA . '/' . $fileName; + } + + public function isExist(string $fileName): bool + { + $filePath = $this->getFilePath($fileName); + + return $this->getMediaDirectory()->isExist($filePath); + } + + public function getStat($fileName): array + { + $filePath = $this->getFilePath($fileName); + + return $this->getMediaDirectory()->stat($filePath); + } + + public function getMimeType($fileName) + { + if ($this->getMediaDirectory()->getDriver() instanceof ExtendedDriverInterface) { + return $this->mediaDirectory->getDriver()->getMetadata($fileName)['mimetype']; + } + + return $this->mime->getMimeType( + $this->getMediaDirectory()->getAbsolutePath( + $this->getFilePath($fileName), + ), + ); + } + + private function getFilePath(string $fileName): string + { + return ltrim($fileName, '/'); + } + + private function getMediaDirectory(): WriteInterface + { + if ($this->mediaDirectory === null) { + $this->mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + } + + return $this->mediaDirectory; + } +} diff --git a/Model/Item/DataProvider.php b/Model/Item/DataProvider.php index f1c8bf5..d0954f4 100644 --- a/Model/Item/DataProvider.php +++ b/Model/Item/DataProvider.php @@ -11,6 +11,7 @@ use Magento\Framework\App\Request\DataPersistorInterface; use Magento\Ui\DataProvider\Modifier\PoolInterface; use Magento\Ui\DataProvider\ModifierPoolDataProvider; +use Mygento\Navigation\Model\FileInfo; use Mygento\Navigation\Model\ResourceModel\Item\Collection; use Mygento\Navigation\Model\ResourceModel\Item\CollectionFactory; @@ -19,12 +20,12 @@ class DataProvider extends ModifierPoolDataProvider /** @var Collection */ protected $collection; - private DataPersistorInterface $dataPersistor; private array $loadedData = []; public function __construct( + private FileInfo $fileInfo, + private DataPersistorInterface $dataPersistor, CollectionFactory $collectionFactory, - DataPersistorInterface $dataPersistor, string $name, string $primaryFieldName, string $requestFieldName, @@ -35,7 +36,6 @@ public function __construct( parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool); $this->collection = $collectionFactory->create(); - $this->dataPersistor = $dataPersistor; } public function getData(): array @@ -45,7 +45,9 @@ public function getData(): array } $items = $this->collection->getItems(); foreach ($items as $model) { - $this->loadedData[$model->getId()] = $model->getData(); + $data = $model->getData(); + $data['image'] = $this->getImageData($data, 'image'); + $this->loadedData[$model->getId()] = $data; } $data = $this->dataPersistor->get('navigation_item'); if (!empty($data)) { @@ -57,4 +59,28 @@ public function getData(): array return $this->loadedData; } + + private function getImageData(array $data, string $key): ?array + { + $imageFileName = $data[$key]; + if (!$imageFileName) { + return null; + } + $result = null; + + if ($this->fileInfo->isExist($imageFileName)) { + $stat = $this->fileInfo->getStat($imageFileName); + $mime = $this->fileInfo->getMimeType($imageFileName); + $result = [ + [ + 'name' => $imageFileName, + 'url' => $this->fileInfo->getUrl($imageFileName), + 'size' => $stat['size'], + 'type' => $mime, + ], + ]; + } + + return $result; + } } diff --git a/Model/Resolver/NavigationMenu.php b/Model/Resolver/NavigationMenu.php index cf53725..dcc93f6 100644 --- a/Model/Resolver/NavigationMenu.php +++ b/Model/Resolver/NavigationMenu.php @@ -16,6 +16,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Mygento\Navigation\Api\MenuRepositoryInterface; +use Mygento\Navigation\Model\FileInfo; use Mygento\Navigation\Model\ResourceModel\Item; class NavigationMenu implements ResolverInterface @@ -25,6 +26,7 @@ class NavigationMenu implements ResolverInterface public function __construct( private MenuRepositoryInterface $menuRepository, private Item $itemResource, + private FileInfo $fileInfo, array $dataBuilders = [], ) { $this->dataBuilders = $this->prepareDataBuilders($dataBuilders); @@ -60,6 +62,7 @@ public function resolve( $itemsByType = []; $itemsData = $this->itemResource->getItemsWithTargetEntityId((int) $menu->getId(), $storeId); foreach ($itemsData as $item) { + $item['image'] = $item['image'] ? $this->fileInfo->getMediaUrl($item['image']) : null; $targetEntityIds[$item['entity_type']][$item['target_entity_id']] = $item['target_entity_id']; $itemsByType[$item['entity_type']][] = $item; } diff --git a/Model/ResourceModel/Item.php b/Model/ResourceModel/Item.php index e781c38..f61c4eb 100644 --- a/Model/ResourceModel/Item.php +++ b/Model/ResourceModel/Item.php @@ -102,6 +102,7 @@ public function getItemsWithTargetEntityId(int $menuId, int $storeId): array 'entity_type', 'name', 'sort_order', + 'image', //todo check and apply changes after implementation main logic for saving entities // is based on the assumption that entity_slug contains json like {"target_entity_id": "2"} 'target_entity_id' => new \Zend_Db_Expr( diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml index dfeecf2..033730c 100644 --- a/etc/adminhtml/di.xml +++ b/etc/adminhtml/di.xml @@ -11,4 +11,30 @@ + + + mygentonav/tmp/item + mygentonav/item + + jpg + jpeg + png + + + image/jpg + image/jpeg + image/png + + + + + + Mygento\Navigation\Model\ImageUploader + + + + + Mygento\Navigation\Model\ImageUploader + + \ No newline at end of file diff --git a/etc/db_schema.xml b/etc/db_schema.xml index 2487bbe..1b963f5 100644 --- a/etc/db_schema.xml +++ b/etc/db_schema.xml @@ -14,6 +14,7 @@ + diff --git a/etc/schema.graphqls b/etc/schema.graphqls index da146f5..11bcd26 100644 --- a/etc/schema.graphqls +++ b/etc/schema.graphqls @@ -1,6 +1,7 @@ type NavigationMenuItem @doc(description: "Item") { sort_order: Int! @doc(description: "Item Sort Order") name: String! @doc(description: "Item name") + image: String @doc(description: "Item image") } type Query { diff --git a/view/adminhtml/ui_component/navigation_item_edit.xml b/view/adminhtml/ui_component/navigation_item_edit.xml index b1a672f..5b2c3a5 100644 --- a/view/adminhtml/ui_component/navigation_item_edit.xml +++ b/view/adminhtml/ui_component/navigation_item_edit.xml @@ -119,6 +119,36 @@ + + + + item + + + + ui/form/element/uploader/image + string + + true + + + + + true + + + + Magento_Catalog/image-preview + Media Gallery + navigation/item + jpg jpeg png + 4194304 + false + + + + + From e433d864fa968826231c7b42bf8d4ec69d1c2957 Mon Sep 17 00:00:00 2001 From: Natalia Sekulich Date: Tue, 5 May 2026 17:02:43 +0300 Subject: [PATCH 4/5] ZIG-233 Add leading slash --- Model/FileInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Model/FileInfo.php b/Model/FileInfo.php index b5c9d8e..41771bf 100644 --- a/Model/FileInfo.php +++ b/Model/FileInfo.php @@ -35,7 +35,7 @@ public function getUrl(string $fileName): string public function getMediaUrl(string $fileName): string { - return UrlInterface::URL_TYPE_MEDIA . '/' . $fileName; + return '/' . UrlInterface::URL_TYPE_MEDIA . '/' . $fileName; } public function isExist(string $fileName): bool From a22e145a6c08f20ed01ca08e2eaf98df38d0bdca Mon Sep 17 00:00:00 2001 From: Dmitrii Gromov Date: Tue, 2 Jun 2026 14:03:08 +0300 Subject: [PATCH 5/5] ZIG-274 - link resolver --- .jeeves.yaml | 2 +- Api/Data/ItemInterface.php | 10 +-- Controller/Adminhtml/Item/Save.php | 9 +++ Model/Builder/CustomLink.php | 26 ++++++++ Model/Builder/DataBuilderInterface.php | 16 +++++ Model/Builder/LinkBuilder.php | 63 ++++++++++++++++++ Model/EntityLabelResolver.php | 49 ++++++++++++++ Model/Item.php | 12 ++-- Model/Item/DataProvider.php | 6 ++ Model/Resolver/NavigationMenu.php | 11 ++-- Model/ResourceModel/Item.php | 6 +- etc/adminhtml/di.xml | 14 +++- etc/db_schema.xml | 2 +- etc/db_schema_whitelist.json | 26 ++++++++ etc/di.xml | 44 +++++++++++++ etc/schema.graphqls | 1 + .../navigation_block_select_grid.xml | 6 ++ .../ui_component/navigation_item_edit.xml | 64 +++++++++++++++++-- .../ui_component/navigation_item_listing.xml | 4 +- .../navigation_page_select_grid.xml | 6 ++ .../navigation_product_select_grid.xml | 8 ++- .../web/js/form/element/entity-type.js | 24 +++++++ .../web/js/form/element/selected-label.js | 21 ++++++ view/adminhtml/web/js/grid/single-select.js | 31 ++++++++- 24 files changed, 427 insertions(+), 34 deletions(-) create mode 100644 Model/Builder/CustomLink.php create mode 100644 Model/Builder/DataBuilderInterface.php create mode 100644 Model/Builder/LinkBuilder.php create mode 100644 Model/EntityLabelResolver.php create mode 100644 etc/db_schema_whitelist.json create mode 100644 view/adminhtml/web/js/form/element/entity-type.js create mode 100644 view/adminhtml/web/js/form/element/selected-label.js diff --git a/.jeeves.yaml b/.jeeves.yaml index c75a08f..2d5f830 100644 --- a/.jeeves.yaml +++ b/.jeeves.yaml @@ -42,7 +42,7 @@ Mygento: unsigned: true default: 0 source: 'Mygento\Navigation\Model\Source\EntityType' - entity_slug: + entity_identifier: type: varchar nullable: true comment: 'Link Identifier' diff --git a/Api/Data/ItemInterface.php b/Api/Data/ItemInterface.php index 8225717..8132069 100644 --- a/Api/Data/ItemInterface.php +++ b/Api/Data/ItemInterface.php @@ -15,7 +15,7 @@ interface ItemInterface public const IS_ACTIVE = 'is_active'; public const NAME = 'name'; public const ENTITY_TYPE = 'entity_type'; - public const ENTITY_SLUG = 'entity_slug'; + public const ENTITY_IDENTIFIER = 'entity_identifier'; public const SORT_ORDER = 'sort_order'; public const STORE_ID = 'store_id'; @@ -71,14 +71,14 @@ public function getEntityType(): string; public function setEntityType(string $entityType): self; /** - * Get entity slug + * Get entity identifier */ - public function getEntitySlug(): ?string; + public function getEntityIdentifier(): ?string; /** - * Set entity slug + * Set entity identifier */ - public function setEntitySlug(?string $entitySlug): self; + public function setEntityIdentifier(?string $entityIdentifier): self; /** * Get sort order diff --git a/Controller/Adminhtml/Item/Save.php b/Controller/Adminhtml/Item/Save.php index 7f65058..201cd7a 100644 --- a/Controller/Adminhtml/Item/Save.php +++ b/Controller/Adminhtml/Item/Save.php @@ -67,6 +67,15 @@ public function execute(): ResultInterface $entity->setData($data); $entity->setImage($this->processImage($data, 'image') ?? ''); + if (empty($data['entity_identifier'])) { + $this->messageManager->addErrorMessage( + __('The Entity Identifier is required. Please assign an entity.')->render(), + ); + $this->dataPersistor->set('navigation_item', $data); + + return $resultRedirect->setPath('*/*/edit', ['id' => $entity->getId()]); + } + try { $this->repository->save($entity); $this->messageManager->addSuccessMessage( diff --git a/Model/Builder/CustomLink.php b/Model/Builder/CustomLink.php new file mode 100644 index 0000000..bbffd0b --- /dev/null +++ b/Model/Builder/CustomLink.php @@ -0,0 +1,26 @@ +getRequestPaths($entityIds, $storeId); + foreach ($items as &$item) { + $entityId = (int) ($item['entity_identifier'] ?? 0); + $path = $requestPaths[$entityId] ?? sprintf($this->targetPathPattern, $entityId); + $item['link'] = $this->urlBuilder->getDirectUrl($path, ['_scope' => $storeId]); + } + unset($item); + + return $items; + } + + private function getRequestPaths(array $entityIds, int $storeId): array + { + $ids = array_map('intval', $entityIds); + if (!$ids) { + return []; + } + + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->from( + ['ur' => $this->resourceConnection->getTableName(self::TABLE_URL_REWRITE)], + ['entity_id', 'request_path'], + ) + ->where('ur.entity_type = ?', $this->urlRewriteEntityType) + ->where('ur.store_id = ?', $storeId) + ->where('ur.redirect_type = ?', 0) + ->where('ur.is_autogenerated = ?', 1) + ->where('ur.metadata IS NULL') + ->where('ur.entity_id IN (?)', $ids) + ->order('ur.url_rewrite_id ASC'); + + return $connection->fetchPairs($select); + } +} diff --git a/Model/EntityLabelResolver.php b/Model/EntityLabelResolver.php new file mode 100644 index 0000000..a1d7b45 --- /dev/null +++ b/Model/EntityLabelResolver.php @@ -0,0 +1,49 @@ + sprintf( + '[Page ID: %d] %s', + $entityId, + $this->pageRepository->getById($entityId)->getTitle(), + ), + 'cms_block' => sprintf( + '[Block ID: %d] %s', + $entityId, + $this->blockRepository->getById($entityId)->getTitle(), + ), + 'catalog_product' => sprintf( + '[Product ID: %d] %s', + $entityId, + $this->productRepository->getById($entityId)->getName(), + ), + default => null, + }; + } catch (LocalizedException $e) { + return null; + } + } +} diff --git a/Model/Item.php b/Model/Item.php index 4ecee23..53f94df 100644 --- a/Model/Item.php +++ b/Model/Item.php @@ -98,19 +98,19 @@ public function setEntityType(string $entityType): self } /** - * Get entity slug + * Get entity identifier */ - public function getEntitySlug(): ?string + public function getEntityIdentifier(): ?string { - return $this->getData(self::ENTITY_SLUG); + return $this->getData(self::ENTITY_IDENTIFIER); } /** - * Set entity slug + * Set entity identifier */ - public function setEntitySlug(?string $entitySlug): self + public function setEntityIdentifier(?string $entityIdentifier): self { - return $this->setData(self::ENTITY_SLUG, $entitySlug); + return $this->setData(self::ENTITY_IDENTIFIER, $entityIdentifier); } /** diff --git a/Model/Item/DataProvider.php b/Model/Item/DataProvider.php index d0954f4..621be6e 100644 --- a/Model/Item/DataProvider.php +++ b/Model/Item/DataProvider.php @@ -11,6 +11,7 @@ use Magento\Framework\App\Request\DataPersistorInterface; use Magento\Ui\DataProvider\Modifier\PoolInterface; use Magento\Ui\DataProvider\ModifierPoolDataProvider; +use Mygento\Navigation\Model\EntityLabelResolver; use Mygento\Navigation\Model\FileInfo; use Mygento\Navigation\Model\ResourceModel\Item\Collection; use Mygento\Navigation\Model\ResourceModel\Item\CollectionFactory; @@ -25,6 +26,7 @@ class DataProvider extends ModifierPoolDataProvider public function __construct( private FileInfo $fileInfo, private DataPersistorInterface $dataPersistor, + private EntityLabelResolver $labelResolver, CollectionFactory $collectionFactory, string $name, string $primaryFieldName, @@ -47,6 +49,10 @@ public function getData(): array foreach ($items as $model) { $data = $model->getData(); $data['image'] = $this->getImageData($data, 'image'); + $data['entity_label'] = $this->labelResolver->resolve( + $data['entity_type'], + $data['entity_identifier'], + ); $this->loadedData[$model->getId()] = $data; } $data = $this->dataPersistor->get('navigation_item'); diff --git a/Model/Resolver/NavigationMenu.php b/Model/Resolver/NavigationMenu.php index dcc93f6..3a67644 100644 --- a/Model/Resolver/NavigationMenu.php +++ b/Model/Resolver/NavigationMenu.php @@ -16,6 +16,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Mygento\Navigation\Api\MenuRepositoryInterface; +use Mygento\Navigation\Model\Builder\DataBuilderInterface; use Mygento\Navigation\Model\FileInfo; use Mygento\Navigation\Model\ResourceModel\Item; @@ -63,10 +64,10 @@ public function resolve( $itemsData = $this->itemResource->getItemsWithTargetEntityId((int) $menu->getId(), $storeId); foreach ($itemsData as $item) { $item['image'] = $item['image'] ? $this->fileInfo->getMediaUrl($item['image']) : null; - $targetEntityIds[$item['entity_type']][$item['target_entity_id']] = $item['target_entity_id']; + $targetEntityIds[$item['entity_type']][$item['entity_identifier']] = $item['entity_identifier']; $itemsByType[$item['entity_type']][] = $item; } - $preparedItems = $this->prepareItems($itemsByType, $targetEntityIds); + $preparedItems = $this->prepareItems($itemsByType, $targetEntityIds, $storeId); return [ 'code' => $code, @@ -74,14 +75,14 @@ public function resolve( ]; } - private function prepareItems(array $itemsByType, array $targetEntityIds): array + private function prepareItems(array $itemsByType, array $targetEntityIds, int $storeId): array { $preparedItems = []; foreach ($itemsByType as $type => $items) { $dataBuilders = $this->dataBuilders[$type] ?? []; foreach ($dataBuilders as $dataBuilder) { - if ($dataBuilder && method_exists($dataBuilder, 'addData')) { - $items = $dataBuilder->addData($items, $targetEntityIds[$type]); + if ($dataBuilder instanceof DataBuilderInterface) { + $items = $dataBuilder->addData($items, $targetEntityIds[$type], $storeId); } } $preparedItems = array_merge($preparedItems, $items); diff --git a/Model/ResourceModel/Item.php b/Model/ResourceModel/Item.php index f61c4eb..0794ee4 100644 --- a/Model/ResourceModel/Item.php +++ b/Model/ResourceModel/Item.php @@ -103,11 +103,7 @@ public function getItemsWithTargetEntityId(int $menuId, int $storeId): array 'name', 'sort_order', 'image', - //todo check and apply changes after implementation main logic for saving entities - // is based on the assumption that entity_slug contains json like {"target_entity_id": "2"} - 'target_entity_id' => new \Zend_Db_Expr( - "JSON_UNQUOTE(JSON_EXTRACT(entity_slug, '$.target_entity_id'))", - ), + 'entity_identifier', ], ) ->joinInner( diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml index 033730c..1d3e267 100644 --- a/etc/adminhtml/di.xml +++ b/etc/adminhtml/di.xml @@ -37,4 +37,16 @@ Mygento\Navigation\Model\ImageUploader - \ No newline at end of file + + + Magento\Catalog\Ui\DataProvider\Product\ProductCollectionFactory + + Magento\Catalog\Ui\DataProvider\Product\AddWebsitesFieldToCollection + + + Magento\Catalog\Ui\DataProvider\Product\AddStoreFieldToCollection + + Magento\Ui\DataProvider\Modifier\Pool + + + diff --git a/etc/db_schema.xml b/etc/db_schema.xml index 1b963f5..3bfbd4b 100644 --- a/etc/db_schema.xml +++ b/etc/db_schema.xml @@ -13,7 +13,7 @@ - + diff --git a/etc/db_schema_whitelist.json b/etc/db_schema_whitelist.json new file mode 100644 index 0000000..1e202ec --- /dev/null +++ b/etc/db_schema_whitelist.json @@ -0,0 +1,26 @@ +{ + "mygento_navigation_menu": { + "column": { + "entity_id": true, + "code": true + } + }, + "mygento_navigation_item": { + "column": { + "entity_id": true, + "menu": true, + "is_active": true, + "name": true, + "entity_type": true, + "entity_slug": true, + "entity_identifier": true, + "sort_order": true + } + }, + "mygento_navigation_item_store": { + "column": { + "entity_id": true, + "store_id": true + } + } +} diff --git a/etc/di.xml b/etc/di.xml index 86f4ac3..72aa2db 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -109,4 +109,48 @@ Mygento\Navigation\Model\ResourceModel\Item + + + category + catalog/category/view/id/%d + + + + + product + catalog/product/view/id/%d + + + + + cms-page + cms/page/view/page_id/%d + + + + + + + catalog_category + Mygento\Navigation\Model\Builder\Category + 10 + + + catalog_product + Mygento\Navigation\Model\Builder\Product + 20 + + + cms_page + Mygento\Navigation\Model\Builder\CmsPage + 30 + + + custom + Mygento\Navigation\Model\Builder\CustomLink + 40 + + + + diff --git a/etc/schema.graphqls b/etc/schema.graphqls index 11bcd26..80c8ed5 100644 --- a/etc/schema.graphqls +++ b/etc/schema.graphqls @@ -1,6 +1,7 @@ type NavigationMenuItem @doc(description: "Item") { sort_order: Int! @doc(description: "Item Sort Order") name: String! @doc(description: "Item name") + link: String @doc(description: "Link") image: String @doc(description: "Item image") } diff --git a/view/adminhtml/ui_component/navigation_block_select_grid.xml b/view/adminhtml/ui_component/navigation_block_select_grid.xml index fbecdbe..c3b6d1e 100644 --- a/view/adminhtml/ui_component/navigation_block_select_grid.xml +++ b/view/adminhtml/ui_component/navigation_block_select_grid.xml @@ -87,6 +87,12 @@ + + + title + navigation_item_edit.navigation_item_edit.general.entity_label + + block_id diff --git a/view/adminhtml/ui_component/navigation_item_edit.xml b/view/adminhtml/ui_component/navigation_item_edit.xml index 5b2c3a5..a1346cd 100644 --- a/view/adminhtml/ui_component/navigation_item_edit.xml +++ b/view/adminhtml/ui_component/navigation_item_edit.xml @@ -149,11 +149,16 @@ - + item catalog_category + + navigation_item_edit.navigation_item_edit.general.entity_identifier + navigation_item_edit.navigation_item_edit.general.entity_label + navigation_item_edit.navigation_item_edit.general.catalog_category_entity + @@ -191,6 +196,10 @@ false + + navigation_item_edit.navigation_item_edit.general.entity_identifier + hide + @@ -221,6 +230,10 @@ false + + navigation_item_edit.navigation_item_edit.general.entity_identifier + show + @@ -251,6 +264,10 @@ false + + navigation_item_edit.navigation_item_edit.general.entity_identifier + hide + @@ -281,6 +298,10 @@ false + + navigation_item_edit.navigation_item_edit.general.entity_identifier + hide + @@ -311,6 +332,10 @@ false + + navigation_item_edit.navigation_item_edit.general.entity_identifier + hide + @@ -341,6 +366,10 @@ true + + navigation_item_edit.navigation_item_edit.general.entity_identifier + hide + @@ -359,6 +388,31 @@ + + + + item + + + + + true + + text + + false + entity_identifier + + + + + text + + false + true + entity_label + + @@ -372,7 +426,7 @@ ui/grid/filters/elements/ui-select - category_ids + entity_identifier field false @@ -531,7 +585,7 @@ false ${ $.ns }.${ $.ns }.columns.ids true - page_id + entity_identifier navigation_page_select_grid false @@ -559,7 +613,7 @@ false ${ $.ns }.${ $.ns }.columns.ids true - block_id + entity_identifier navigation_block_select_grid false @@ -587,7 +641,7 @@ false ${ $.ns }.${ $.ns }.columns.ids true - entity_id + entity_identifier navigation_product_select_grid false diff --git a/view/adminhtml/ui_component/navigation_item_listing.xml b/view/adminhtml/ui_component/navigation_item_listing.xml index 537f01b..c24e709 100644 --- a/view/adminhtml/ui_component/navigation_item_listing.xml +++ b/view/adminhtml/ui_component/navigation_item_listing.xml @@ -165,14 +165,14 @@ - + text text text - + diff --git a/view/adminhtml/ui_component/navigation_page_select_grid.xml b/view/adminhtml/ui_component/navigation_page_select_grid.xml index 2a33a79..fd13e7b 100644 --- a/view/adminhtml/ui_component/navigation_page_select_grid.xml +++ b/view/adminhtml/ui_component/navigation_page_select_grid.xml @@ -87,6 +87,12 @@ + + + title + navigation_item_edit.navigation_item_edit.general.entity_label + + page_id diff --git a/view/adminhtml/ui_component/navigation_product_select_grid.xml b/view/adminhtml/ui_component/navigation_product_select_grid.xml index a7cfa86..f3a59a7 100644 --- a/view/adminhtml/ui_component/navigation_product_select_grid.xml +++ b/view/adminhtml/ui_component/navigation_product_select_grid.xml @@ -24,7 +24,7 @@ Magento_Catalog::products - + id entity_id @@ -84,6 +84,12 @@ + + + name + navigation_item_edit.navigation_item_edit.general.entity_label + + entity_id diff --git a/view/adminhtml/web/js/form/element/entity-type.js b/view/adminhtml/web/js/form/element/entity-type.js new file mode 100644 index 0000000..27636c8 --- /dev/null +++ b/view/adminhtml/web/js/form/element/entity-type.js @@ -0,0 +1,24 @@ +define([ + 'Magento_Ui/js/form/element/select', + 'uiRegistry' +], function (Select, registry) { + 'use strict'; + + return Select.extend({ + defaults: { + clearTargets: [] + }, + + onUpdate: function () { + this.clearTargets.forEach(function (target) { + registry.get(target, function (component) { + if (component) { + component.clear(); + } + }); + }); + + return this._super(); + } + }); +}); diff --git a/view/adminhtml/web/js/form/element/selected-label.js b/view/adminhtml/web/js/form/element/selected-label.js new file mode 100644 index 0000000..9842069 --- /dev/null +++ b/view/adminhtml/web/js/form/element/selected-label.js @@ -0,0 +1,21 @@ +define([ + 'Magento_Ui/js/form/element/abstract' +], function (Abstract) { + 'use strict'; + + return Abstract.extend({ + initialize: function () { + this._super(); + this.value.subscribe(this.updateVisibility, this); + this.updateVisibility(this.value()); + + return this; + }, + + updateVisibility: function (value) { + this.visible(!!value); + + return this; + } + }); +}); diff --git a/view/adminhtml/web/js/grid/single-select.js b/view/adminhtml/web/js/grid/single-select.js index f47f334..25950be 100644 --- a/view/adminhtml/web/js/grid/single-select.js +++ b/view/adminhtml/web/js/grid/single-select.js @@ -1,7 +1,8 @@ define([ 'Magento_Ui/js/grid/columns/multiselect', - 'underscore' -], function (Select, _) { + 'underscore', + 'uiRegistry' +], function (Select, _, registry) { 'use strict'; return Select.extend({ @@ -9,6 +10,8 @@ define([ headerTmpl: 'ui/grid/columns/text', bodyTmpl: 'Mygento_Navigation/grid/single-select', label: '', + labelField: '', + labelTarget: '', extendedSelections: [], lastSelected: null, listens: { @@ -61,10 +64,34 @@ define([ select: function (id) { this._super(); this.lastSelected(id); + this.exportLabel(id); return this; }, + exportLabel: function (id) { + if (!this.labelField || !this.labelTarget) { + return; + } + + const query = { + [this.indexField]: id + }; + const row = _.findWhere(this.rows(), query); + + if (!row) { + return; + } + + const label = `[ID: ${id}] ${row[this.labelField]}`; + + registry.get(this.labelTarget, function (field) { + if (field) { + field.value(label); + } + }); + }, + /** @inheritdoc */ _setSelection: function (id, isIndex, select) { var selected = this.selected;