diff --git a/vendor/magento/module-admin-gws/Model/Plugin/IsCategoryAuthorizedForDifferentStoreUserRole.php b/vendor/magento/module-admin-gws/Model/Plugin/IsCategoryAuthorizedForDifferentStoreUserRole.php index 89dd3308a871..f91a34164f39 100644 --- a/vendor/magento/module-admin-gws/Model/Plugin/IsCategoryAuthorizedForDifferentStoreUserRole.php +++ b/vendor/magento/module-admin-gws/Model/Plugin/IsCategoryAuthorizedForDifferentStoreUserRole.php @@ -57,15 +57,9 @@ public function beforeAuthorizeSavingOf( if ($this->userContext->getUserId() && $this->userContext->getUserType() === UserContextInterface::USER_TYPE_ADMIN ) { - if (!$this->adminRole->getIsAll()) { - $parentIds = $category->getParentIds(); - if (empty($parentIds)) { - $parentIds = [$category->getParentId()]; - } - $allowedCategoriesIds = array_keys($this->adminRole->getAllowedRootCategories()); - if (empty(array_intersect($parentIds, $allowedCategoriesIds))) { - throw new AuthorizationException(__('Not allowed to edit the category\'s design attributes')); - } + $categoryPath = $category->getPath(); + if (!$this->adminRole->hasExclusiveCategoryAccess($categoryPath)) { + throw new AuthorizationException(__('Not allowed to edit the category\'s design attributes')); } } } diff --git a/vendor/magento/module-admin-gws/Model/Role.php b/vendor/magento/module-admin-gws/Model/Role.php index 3f42feb21e5f..218eeb907b42 100644 --- a/vendor/magento/module-admin-gws/Model/Role.php +++ b/vendor/magento/module-admin-gws/Model/Role.php @@ -8,7 +8,11 @@ namespace Magento\AdminGws\Model; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; +use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; +use Magento\Store\Model\ResourceModel\Group\CollectionFactory as GroupCollectionFactory; +use Magento\Store\Model\ResourceModel\Store\CollectionFactory as StoreCollectionFactory; +use Magento\Store\Model\ResourceModel\Website\CollectionFactory as WebsiteCollectionFactory; use Magento\Store\Model\StoreManagerInterface; /** @@ -16,6 +20,7 @@ * * @api * @since 100.0.2 + * @SuppressWarnings(PHPMD.TooManyFields) */ class Role extends DataObject { @@ -85,18 +90,60 @@ class Role extends DataObject */ protected $_storeManager; + /** + * @var WebsiteCollectionFactory + */ + private $websiteCollectionFactory; + + /** + * @var GroupCollectionFactory + */ + private $groupCollectionFactory; + + /** + * @var StoreCollectionFactory + */ + private $storeCollectionFactory; + + /** + * @var array + */ + private $allWebsiteIds = []; + + /** + * @var array + */ + private $allGroupIds = []; + + /** + * @var array + */ + private $allStoreIds = []; + /** * @param StoreManagerInterface $storeManager * @param CollectionFactory $categoryCollectionFactory * @param array $data + * @param WebsiteCollectionFactory|null $websiteCollectionFactory + * @param GroupCollectionFactory|null $groupCollectionFactory + * @param StoreCollectionFactory|null $storeCollectionFactory */ public function __construct( - StoreManagerInterface $storeManager, - CollectionFactory $categoryCollectionFactory, - array $data = [] + StoreManagerInterface $storeManager, + CollectionFactory $categoryCollectionFactory, + array $data = [], + ?WebsiteCollectionFactory $websiteCollectionFactory = null, + ?GroupCollectionFactory $groupCollectionFactory = null, + ?StoreCollectionFactory $storeCollectionFactory = null, ) { $this->_categoryCollectionFactory = $categoryCollectionFactory; $this->_storeManager = $storeManager; + $this->websiteCollectionFactory = $websiteCollectionFactory + ?? ObjectManager::getInstance()->get(WebsiteCollectionFactory::class); + $this->groupCollectionFactory = $groupCollectionFactory + ?? ObjectManager::getInstance()->get(GroupCollectionFactory::class); + $this->storeCollectionFactory = $storeCollectionFactory + ?? ObjectManager::getInstance()->get(StoreCollectionFactory::class); parent::__construct($data); } @@ -112,27 +159,47 @@ public function setAdminRole($role) if ($role) { $this->_adminRole = $role; + $this->setAllWebsiteGroupStoreIds(); + // find role disallowed data - foreach ($this->_storeManager->getWebsites(true) as $websiteId => $website) { + foreach ($this->allWebsiteIds as $websiteId) { if (!in_array($websiteId, $this->getRelevantWebsiteIds())) { $this->_disallowedWebsiteIds[] = $websiteId; } } - foreach ($this->_storeManager->getStores(true) as $storeId => $store) { + foreach ($this->allStoreIds as $storeId) { if (!in_array($storeId, $this->getStoreIds())) { - $this->_disallowedStores[] = $store; + $this->_disallowedStores[] = $this->_storeManager->getStore($storeId); $this->_disallowedStoreIds[] = $storeId; } } - foreach ($this->_storeManager->getGroups(true) as $groupId => $group) { + foreach ($this->allGroupIds as $groupId) { if (!in_array($groupId, $this->getStoreGroupIds())) { - $this->_disallowedStoreGroups[] = $group; + $this->_disallowedStoreGroups[] = $this->_storeManager->getGroup($groupId); $this->_disallowedStoreGroupIds[] = $groupId; } } } } + /** + * Get and set all website, group and store ids only once + * + * @return void + */ + private function setAllWebsiteGroupStoreIds() + { + if (empty($this->allWebsiteIds)) { + $this->allWebsiteIds = $this->websiteCollectionFactory->create()->getAllIds(); + } + if (empty($this->allGroupIds)) { + $this->allGroupIds = $this->groupCollectionFactory->create()->getAllIds(); + } + if (empty($this->allStoreIds)) { + $this->allStoreIds = $this->storeCollectionFactory->create()->getAllIds(); + } + } + /** * Check whether GWS permissions are applicable * diff --git a/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/Block/Adminhtml/Category/Merchandiser/Grid.php b/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/Block/Adminhtml/Category/Merchandiser/Grid.php index b4b323a37467..67d4ce4252b5 100644 --- a/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/Block/Adminhtml/Category/Merchandiser/Grid.php +++ b/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/Block/Adminhtml/Category/Merchandiser/Grid.php @@ -39,7 +39,8 @@ public function __construct(AdminRole $adminRole) */ public function afterAddColumn(CategoryProductsGrid $subject, $result, $columnId): void { - if (! $this->adminRole->getIsAll()) { + $categoryPath = $subject->getCategory()->getPath(); + if (!$this->adminRole->hasExclusiveCategoryAccess($categoryPath)) { $this->restrictCategoryProductsEdit($subject, $columnId); } } diff --git a/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/ViewModel/MerchandiserViewModel.php b/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/ViewModel/MerchandiserViewModel.php index 3448b40589ac..3840109575f4 100644 --- a/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/ViewModel/MerchandiserViewModel.php +++ b/vendor/magento/module-admin-gws/Plugin/VisualMerchandiser/ViewModel/MerchandiserViewModel.php @@ -7,6 +7,9 @@ namespace Magento\AdminGws\Plugin\VisualMerchandiser\ViewModel; +use Magento\Catalog\Model\CategoryRepository; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\VisualMerchandiser\ViewModel\MerchandiserViewModel as ViewModel; use Magento\AdminGws\Model\Role as AdminRole; @@ -17,13 +20,29 @@ class MerchandiserViewModel */ private $adminRole; + /** + * @var RequestInterface + */ + private $request; + + /** + * @var CategoryRepository + */ + private $categoryRepository; + /** * @param AdminRole $adminRole + * @param RequestInterface $request + * @param CategoryRepository $categoryRepository */ public function __construct( - AdminRole $adminRole + AdminRole $adminRole, + RequestInterface $request, + CategoryRepository $categoryRepository ) { $this->adminRole = $adminRole; + $this->request = $request; + $this->categoryRepository = $categoryRepository; } /** @@ -34,11 +53,16 @@ public function __construct( * @return string|void * * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @throws NoSuchEntityException */ public function afterGetSortable(ViewModel $subject, string $result) { - if (!$this->adminRole->getIsAll()) { - $result = ViewModel::SORTABLE_DISABLED; + $categoryId = (int)$this->request->getParam('id'); + if ($categoryId) { + $category = $this->categoryRepository->get($categoryId); + if (!$this->adminRole->hasExclusiveCategoryAccess($category->getPath())) { + $result = ViewModel::SORTABLE_DISABLED; + } } return $result; }