diff --git a/src/module-elasticsuite-catalog/Model/ResourceModel/Product/FilterableAttribute/Category/Collection.php b/src/module-elasticsuite-catalog/Model/ResourceModel/Product/FilterableAttribute/Category/Collection.php index 433d952a7..cb465f8b0 100644 --- a/src/module-elasticsuite-catalog/Model/ResourceModel/Product/FilterableAttribute/Category/Collection.php +++ b/src/module-elasticsuite-catalog/Model/ResourceModel/Product/FilterableAttribute/Category/Collection.php @@ -174,4 +174,35 @@ private function getAdditionalTableFields() return array_diff($tableFields, $this->overridenColumns); } + + /** + * Specify attribute set filter + * + * @param array|int $setId Attribute Set Id(s) + * + * @return $this + */ + public function setAttributeSetFilter($setId) + { + if (is_array($setId)) { + if (!empty($setId)) { + $this->join( + ['entity_attribute' => $this->getTable('eav_entity_attribute')], + 'entity_attribute.attribute_id = main_table.attribute_id', + [] + ); + $this->addFieldToFilter('entity_attribute.attribute_set_id', ['in' => $setId]); + $this->addAttributeGrouping(); + } + } elseif ($setId) { + $this->join( + ['entity_attribute' => $this->getTable('eav_entity_attribute')], + 'entity_attribute.attribute_id = main_table.attribute_id', + [] + ); + $this->addFieldToFilter('entity_attribute.attribute_set_id', $setId); + } + + return $this; + } } diff --git a/src/module-elasticsuite-catalog/Plugin/Ui/Category/Form/DataProviderPlugin.php b/src/module-elasticsuite-catalog/Plugin/Ui/Category/Form/DataProviderPlugin.php index c8e41738a..155038aab 100644 --- a/src/module-elasticsuite-catalog/Plugin/Ui/Category/Form/DataProviderPlugin.php +++ b/src/module-elasticsuite-catalog/Plugin/Ui/Category/Form/DataProviderPlugin.php @@ -15,6 +15,10 @@ use Magento\Catalog\Api\Data\CategoryInterface; use Smile\ElasticsuiteCatalog\Model\Attribute\Source\FilterDisplayMode; use Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\FilterableAttribute\Category\CollectionFactory as AttributeCollectionFactory; +use Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\CollectionFactory as FulltextCollectionFactory; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Catalog\Model\Product\Visibility; +use Smile\ElasticsuiteCore\Search\Request\QueryInterface; use Magento\Catalog\Model\Category\DataProvider as CategoryDataProvider; @@ -32,14 +36,31 @@ class DataProviderPlugin */ private $attributeCollectionFactory; + /** + * @var FulltextCollectionFactory + */ + private $fulltextCollectionFactory; + + /** + * @var \Magento\Store\Model\StoreManagerInterface + */ + private $storeManager; + /** * DataProviderPlugin constructor. * * @param AttributeCollectionFactory $attributeCollectionFactory Attribute Collection Factory. + * @param FulltextCollectionFactory $fulltextCollectionFactory Fulltext Collection Factory. + * @param StoreManagerInterface $storeManager Store Manager. */ - public function __construct(AttributeCollectionFactory $attributeCollectionFactory) - { + public function __construct( + AttributeCollectionFactory $attributeCollectionFactory, + FulltextCollectionFactory $fulltextCollectionFactory, + StoreManagerInterface $storeManager + ) { $this->attributeCollectionFactory = $attributeCollectionFactory; + $this->fulltextCollectionFactory = $fulltextCollectionFactory; + $this->storeManager = $storeManager; } /** @@ -116,6 +137,66 @@ private function getFilterableAttributeList($currentCategory) return $attributesList; } + /** + * Retrieve default store view id. + * + * @return int + */ + private function getDefaultStoreId() + { + $store = $this->storeManager->getDefaultStoreView(); + + if (null === $store) { + // Occurs when current user does not have access to default website (due to AdminGWS ACLS on Magento EE). + $store = !empty($this->storeManager->getWebsites()) ? current($this->storeManager->getWebsites())->getDefaultStore() : null; + } + + return $store ? $store->getId() : 0; + } + + /** + * Get store id for the current category. + * + * @param CategoryInterface $category Category. + * + * @return int + */ + private function getStoreId(CategoryInterface $category) + { + $storeId = $category->getStoreId(); + + if ($storeId === 0) { + $defaultStoreId = $this->getDefaultStoreId(); + $categoryStoreIds = array_filter($category->getStoreIds()); + $storeId = current($categoryStoreIds); + if (in_array($defaultStoreId, $categoryStoreIds)) { + $storeId = $defaultStoreId; + } + } + + return $storeId; + } + + /** + * Return the query filter to be to applied for the category. + * + * @param CategoryInterface $category Category + * + * @return QueryInterface + */ + private function getQueryFilter(CategoryInterface $category) + { + $query = null; + + $category->setIsActive(true); + + if ($category->getIsVirtualCategory() || $category->getId()) { + $query = $category->getVirtualRule()->getCategorySearchQuery($category); + } + + return $query; + } + /** * Retrieve attribute collection pre-filtered with only attribute filterable. * @@ -132,6 +213,25 @@ private function getAttributes($category) ->addStoreLabel($category->getStoreId()) ->setOrder('position', 'ASC'); + $storeId = $this->getStoreId($category); + + if ($storeId) { + /** @var \Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection $fulltextCollection */ + $fulltextCollection = $this->fulltextCollectionFactory->create(); + $fulltextCollection->setStoreId($storeId) + ->setVisibility([Visibility::VISIBILITY_IN_CATALOG, Visibility::VISIBILITY_BOTH]); + + $queryFilter = $this->getQueryFilter($category); + if ($queryFilter !== null) { + $fulltextCollection->addQueryFilter($queryFilter); + } + + $attributeSetIds = array_keys($fulltextCollection->getProductCountByAttributeSetId()); + if (!empty($attributeSetIds)) { + $collection->setAttributeSetFilter($attributeSetIds); + } + } + return $collection->getItems(); } }