vendor/ibexa/product-catalog/src/bundle/EventSubscriber/MainMenuSubscriber.php line 88

Open in your IDE?
  1. <?php
  2. /**
  3.  * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4.  * @license For full copyright and license information view LICENSE file distributed with this source code.
  5.  */
  6. declare(strict_types=1);
  7. namespace Ibexa\Bundle\ProductCatalog\EventSubscriber;
  8. use Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent;
  9. use Ibexa\Bundle\Commerce\Eshop\Api\Configuration\CommerceSiteConfig;
  10. use Ibexa\Contracts\Core\Repository\ContentService;
  11. use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
  12. use Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException;
  13. use Ibexa\Contracts\ProductCatalog\Permission\Policy\Commerce\AdministrateCurrencies;
  14. use Ibexa\Contracts\ProductCatalog\Permission\Policy\CustomerGroup\View as ViewCustomerGroup;
  15. use Ibexa\Contracts\ProductCatalog\Permission\Policy\Product\View as ViewProduct;
  16. use Ibexa\Contracts\ProductCatalog\Permission\Policy\ProductType\View as ViewProductType;
  17. use Ibexa\Contracts\ProductCatalog\PermissionResolverInterface;
  18. use Ibexa\Contracts\Taxonomy\Service\TaxonomyServiceInterface;
  19. use Ibexa\ProductCatalog\Config\ConfigProviderInterface;
  20. use JMS\TranslationBundle\Model\Message;
  21. use JMS\TranslationBundle\Translation\TranslationContainerInterface;
  22. use Knp\Menu\ItemInterface;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. final class MainMenuSubscriber implements EventSubscriberInterfaceTranslationContainerInterface
  25. {
  26.     // Main Menu / Product catalog
  27.     public const ITEM_PRODUCT_CATALOG 'main__product_catalog';
  28.     // Main Menu / Product catalog / Products
  29.     public const ITEM_PRODUCT_CATALOG_PRODUCTS 'main__product_catalog__products';
  30.     // Main Menu / Product catalog / Catalogs
  31.     public const ITEM_PRODUCT_CATALOG_CATALOGS 'main__product_catalog__catalogs';
  32.     // Main Menu / Product catalog / Product Categories
  33.     public const ITEM_PRODUCT_CATALOG_CATEGORIES 'main__product_catalog__categories';
  34.     // Main Menu / Product catalog / Settings
  35.     public const ITEM_PRODUCT_GROUP_SETTINGS 'main__product_catalog__group_settings';
  36.     // Main Menu / Product catalog / Settings / Product Types
  37.     public const ITEM_PRODUCT_CATALOG_PRODUCT_TYPES 'main__product_catalog__product_types';
  38.     // Main Menu / Product catalog / Settings / Attribute Groups
  39.     public const ITEM_PRODUCT_CATALOG_ATTRIBUTE_GROUPS 'main__product_catalog__attribute_groups';
  40.     // Main Menu / Product catalog / Settings / Attributes
  41.     public const ITEM_PRODUCT_CATALOG_ATTRIBUTES 'main__product_catalog__attributes';
  42.     // Main Menu / Product catalog / Customer Groups
  43.     public const ITEM_PRODUCT_CATALOG_CUSTOMER_GROUPS 'main__product_catalog__customer_groups';
  44.     // Main Menu / Product catalog / Currencies
  45.     public const ITEM_PRODUCT_CATALOG_CURRENCIES 'main__product_catalog__currencies';
  46.     // Main Menu / eCommerce
  47.     public const ITEM_COMMERCE 'main__commerce';
  48.     private PermissionResolverInterface $permissionResolver;
  49.     private ConfigProviderInterface $configProvider;
  50.     private ?CommerceSiteConfig $commerceSiteConfig;
  51.     private TaxonomyServiceInterface $taxonomyService;
  52.     private ContentService $contentService;
  53.     private string $productTaxonomyName;
  54.     public function __construct(
  55.         PermissionResolverInterface $permissionResolver,
  56.         ConfigProviderInterface $configProvider,
  57.         ?CommerceSiteConfig $commerceSiteConfig,
  58.         TaxonomyServiceInterface $taxonomyService,
  59.         ContentService $contentService,
  60.         string $productTaxonomyName
  61.     ) {
  62.         $this->permissionResolver $permissionResolver;
  63.         $this->configProvider $configProvider;
  64.         $this->commerceSiteConfig $commerceSiteConfig;
  65.         $this->taxonomyService $taxonomyService;
  66.         $this->contentService $contentService;
  67.         $this->productTaxonomyName $productTaxonomyName;
  68.     }
  69.     public static function getSubscribedEvents(): array
  70.     {
  71.         return [
  72.             ConfigureMenuEvent::MAIN_MENU => ['onConfigureMainMenu'15],
  73.         ];
  74.     }
  75.     public function onConfigureMainMenu(ConfigureMenuEvent $event): void
  76.     {
  77.         $menu $event->getMenu();
  78.         $this->addCommerceMenu($menu);
  79.         if ($this->configProvider->getEngineAlias() === null) {
  80.             return;
  81.         }
  82.         $productCatalogRoot $menu->addChild(
  83.             self::ITEM_PRODUCT_CATALOG,
  84.             [
  85.                 'attributes' => [
  86.                     'data-tooltip-placement' => 'right',
  87.                     'data-tooltip-extra-class' => 'ibexa-tooltip--navigation',
  88.                 ],
  89.                 'extras' => [
  90.                     'icon' => 'product-catalog',
  91.                     'orderNumber' => 80,
  92.                     'routes' => [
  93.                         [
  94.                             'pattern' => $this->getProductCatalogRoutePattern(),
  95.                         ],
  96.                     ],
  97.                 ],
  98.             ]
  99.         );
  100.         if ($this->canViewProducts()) {
  101.             $productCatalogRoot->addChild(
  102.                 self::ITEM_PRODUCT_CATALOG_PRODUCTS,
  103.                 [
  104.                     'route' => 'ibexa.product_catalog.product.list',
  105.                     'extras' => [
  106.                         'routes' => [
  107.                             [
  108.                                 'pattern' => '~^ibexa\.product_catalog\.product\.~',
  109.                             ],
  110.                         ],
  111.                         'orderNumber' => 10,
  112.                     ],
  113.                 ]
  114.             );
  115.             $productCatalogRoot->addChild(
  116.                 self::ITEM_PRODUCT_CATALOG_CATALOGS,
  117.                 [
  118.                     'route' => 'ibexa.product_catalog.catalog.list',
  119.                     'extras' => [
  120.                         'routes' => [
  121.                             [
  122.                                 'pattern' => '~^ibexa\.product_catalog\.catalog\.~',
  123.                             ],
  124.                         ],
  125.                         'orderNumber' => 20,
  126.                     ],
  127.                 ]
  128.             );
  129.             if ($this->configProvider->getEngineType() === 'local') {
  130.                 try {
  131.                     $entry $this->taxonomyService->loadRootEntry($this->productTaxonomyName);
  132.                     $rootContent $this->contentService->loadContentInfo($entry->content->id);
  133.                     $productCatalogRoot->addChild(
  134.                         self::ITEM_PRODUCT_CATALOG_CATEGORIES,
  135.                         [
  136.                             'route' => 'ibexa.content.view',
  137.                             'routeParameters' => [
  138.                                 'contentId' => $rootContent->id,
  139.                                 'locationId' => $rootContent->mainLocationId,
  140.                             ],
  141.                             'extras' => [
  142.                                 'translation_domain' => 'ibexa_menu',
  143.                                 'orderNumber' => 25,
  144.                                 'taxonomy' => $this->productTaxonomyName,
  145.                             ],
  146.                         ]
  147.                     );
  148.                 } catch (UnauthorizedException|NotFoundException $exception) {
  149.                     // ignore
  150.                 }
  151.             }
  152.         }
  153.         if ($this->canViewProductTypes()) {
  154.             $groupSettingsRoot $productCatalogRoot->addChild(
  155.                 self::ITEM_PRODUCT_GROUP_SETTINGS,
  156.                 [
  157.                     'extras' => [
  158.                         'orderNumber' => 30,
  159.                     ],
  160.                 ],
  161.             );
  162.             $groupSettingsRoot->addChild(
  163.                 self::ITEM_PRODUCT_CATALOG_PRODUCT_TYPES,
  164.                 [
  165.                     'route' => 'ibexa.product_catalog.product_type.list',
  166.                     'extras' => [
  167.                         'routes' => [
  168.                             [
  169.                                 'pattern' => '~^ibexa\.product_catalog\.product_type\.~',
  170.                             ],
  171.                         ],
  172.                         'orderNumber' => 40,
  173.                     ],
  174.                 ]
  175.             );
  176.             $groupSettingsRoot->addChild(
  177.                 self::ITEM_PRODUCT_CATALOG_ATTRIBUTE_GROUPS,
  178.                 [
  179.                     'route' => 'ibexa.product_catalog.attribute_group.list',
  180.                     'extras' => [
  181.                         'routes' => [
  182.                             [
  183.                                 'pattern' => '~^ibexa\.product_catalog\.attribute_group\.~',
  184.                             ],
  185.                         ],
  186.                         'orderNumber' => 20,
  187.                     ],
  188.                 ]
  189.             );
  190.             $groupSettingsRoot->addChild(
  191.                 self::ITEM_PRODUCT_CATALOG_ATTRIBUTES,
  192.                 [
  193.                     'route' => 'ibexa.product_catalog.attribute_definition.list',
  194.                     'extras' => [
  195.                         'routes' => [
  196.                             [
  197.                                 'pattern' => '~^ibexa\.product_catalog\.attribute_definition\.~',
  198.                             ],
  199.                         ],
  200.                         'orderNumber' => 30,
  201.                     ],
  202.                 ]
  203.             );
  204.         }
  205.         $rootElement $menu->getChild(self::ITEM_COMMERCE) ?? $productCatalogRoot;
  206.         if ($this->canViewCustomerGroups()) {
  207.             $rootElement->addChild(
  208.                 self::ITEM_PRODUCT_CATALOG_CUSTOMER_GROUPS,
  209.                 [
  210.                     'route' => 'ibexa.product_catalog.customer_group.list',
  211.                     'extras' => [
  212.                         'routes' => [
  213.                             [
  214.                                 'pattern' => '~^ibexa\.product_catalog\.customer_group\.~',
  215.                             ],
  216.                         ],
  217.                         'orderNumber' => 40,
  218.                     ],
  219.                 ]
  220.             );
  221.         }
  222.         if ($this->canAdministrateCurrencies()) {
  223.             $rootElement->addChild(
  224.                 self::ITEM_PRODUCT_CATALOG_CURRENCIES,
  225.                 [
  226.                     'route' => 'ibexa.product_catalog.currency.list',
  227.                     'extras' => [
  228.                         'routes' => [
  229.                             [
  230.                                 'pattern' => '~^ibexa\.product_catalog\.currency\.~',
  231.                             ],
  232.                         ],
  233.                         'orderNumber' => 50,
  234.                     ],
  235.                 ]
  236.             );
  237.         }
  238.     }
  239.     public static function getTranslationMessages(): array
  240.     {
  241.         return [
  242.             (new Message(self::ITEM_PRODUCT_CATALOG'ibexa_menu'))->setDesc('Product catalog'),
  243.             (new Message(self::ITEM_PRODUCT_CATALOG_PRODUCTS'ibexa_menu'))->setDesc('Products'),
  244.             (new Message(self::ITEM_PRODUCT_CATALOG_CATALOGS'ibexa_menu'))->setDesc('Catalogs'),
  245.             (new Message(self::ITEM_PRODUCT_GROUP_SETTINGS'ibexa_menu'))->setDesc('Settings'),
  246.             (new Message(self::ITEM_PRODUCT_CATALOG_PRODUCT_TYPES'ibexa_menu'))->setDesc('Product Types'),
  247.             (new Message(self::ITEM_PRODUCT_CATALOG_ATTRIBUTE_GROUPS'ibexa_menu'))->setDesc('Attribute Groups'),
  248.             (new Message(self::ITEM_PRODUCT_CATALOG_ATTRIBUTES'ibexa_menu'))->setDesc('Attributes'),
  249.             (new Message(self::ITEM_PRODUCT_CATALOG_CUSTOMER_GROUPS'ibexa_menu'))->setDesc('Customer Groups'),
  250.             (new Message(self::ITEM_PRODUCT_CATALOG_CURRENCIES'ibexa_menu'))->setDesc('Currencies'),
  251.             (new Message(self::ITEM_COMMERCE'ibexa_menu'))->setDesc('Commerce'),
  252.             (new Message(self::ITEM_PRODUCT_CATALOG_CATEGORIES'ibexa_menu'))->setDesc('Categories'),
  253.         ];
  254.     }
  255.     private function addCommerceMenu(ItemInterface $menu): void
  256.     {
  257.         if (!$this->isCommerceEnabled()) {
  258.             return;
  259.         }
  260.         $menu->addChild(
  261.             self::ITEM_COMMERCE,
  262.             [
  263.                 'attributes' => [
  264.                     'data-tooltip-placement' => 'right',
  265.                     'data-tooltip-extra-class' => 'ibexa-tooltip--navigation',
  266.                 ],
  267.                 'extras' => [
  268.                     'icon' => 'cart-full',
  269.                     'orderNumber' => 100,
  270.                 ],
  271.             ]
  272.         );
  273.     }
  274.     private function canViewProducts(): bool
  275.     {
  276.         return $this->permissionResolver->canUser(new ViewProduct());
  277.     }
  278.     private function canViewCustomerGroups(): bool
  279.     {
  280.         return $this->permissionResolver->canUser(new ViewCustomerGroup());
  281.     }
  282.     private function canViewProductTypes(): bool
  283.     {
  284.         return $this->permissionResolver->canUser(new ViewProductType());
  285.     }
  286.     private function canAdministrateCurrencies(): bool
  287.     {
  288.         return $this->permissionResolver->canUser(new AdministrateCurrencies());
  289.     }
  290.     private function getProductCatalogRoutePattern(): string
  291.     {
  292.         return $this->isCommerceEnabled() ?
  293.             '~^ibexa\.product_catalog\.(?!(customer_group|currency))~' :
  294.             '~^ibexa\.product_catalog\.~';
  295.     }
  296.     private function isCommerceEnabled(): bool
  297.     {
  298.         return $this->commerceSiteConfig !== null && $this->commerceSiteConfig->isCommerceEnabled();
  299.     }
  300. }