Skip to content

Commit

Permalink
Fixes Smile-SA#1153 Reducing list of filterable attributes
Browse files Browse the repository at this point in the history
to those relevant for the currently assigned products
  • Loading branch information
rbayet committed Nov 7, 2018
1 parent 40feb63 commit 1779ffe
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,37 @@ public function applyCategory()
return $this;
}

/**
* 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;
}

/**
* @SuppressWarnings(PHPMD.CamelCaseMethodName)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
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 Smile\ElasticsuiteCore\Search\Request\QueryInterface;
use Smile\ElasticsuiteCore\Api\Search\ContextInterface;
use Smile\ElasticsuiteCore\Search\Request\Query\Builder as QueryBuilder;

use Magento\Catalog\Model\Category\DataProvider as CategoryDataProvider;

Expand All @@ -32,14 +37,39 @@ class DataProviderPlugin
*/
private $attributeCollectionFactory;

/**
* @var FulltextCollectionFactory
*/
private $fulltextCollectionFactory;

/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;

/**
* @var \Smile\ElasticsuiteCore\Api\Search\ContextInterface
*/
private $searchContext;

/**
* DataProviderPlugin constructor.
*
* @param AttributeCollectionFactory $attributeCollectionFactory Attribute Collection Factory.
* @param AttributeCollectionFactory $attributeCollectionFactory Attribute Collection Factory.
* @param FulltextCollectionFactory $fulltextCollectionFactory Fulltext Collection Factory.
* @param StoreManagerInterface $storeManager Store Manager.
* @param ContextInterface $searchContext Search context.
*/
public function __construct(AttributeCollectionFactory $attributeCollectionFactory)
{
public function __construct(
AttributeCollectionFactory $attributeCollectionFactory,
FulltextCollectionFactory $fulltextCollectionFactory,
StoreManagerInterface $storeManager,
ContextInterface $searchContext
) {
$this->attributeCollectionFactory = $attributeCollectionFactory;
$this->fulltextCollectionFactory = $fulltextCollectionFactory;
$this->storeManager = $storeManager;
$this->searchContext = $searchContext;
}

/**
Expand Down Expand Up @@ -117,7 +147,67 @@ private function getFilterableAttributeList($currentCategory)
}

/**
* Retrieve attribute collection pre-filtered with only attribute filterable.
* 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 category filter param
*
* @param CategoryInterface $category Category.
*
* @return int|QueryInterface
*/
private function getCategoryFilterParam(CategoryInterface $category)
{
$filterParam = $category->getId();

if ($category->getVirtualRule()) { // Implicit dependency to Virtual Categories module.
$category->setIsActive(true);

$filterParam = $category->getVirtualRule()->getCategorySearchQuery($category);
}

return $filterParam;
}

/**
* Retrieve attribute collection pre-filtered with only filterable attributes.
*
* @param CategoryInterface $category Category
*
Expand All @@ -132,6 +222,24 @@ private function getAttributes($category)
->addStoreLabel($category->getStoreId())
->setOrder('position', 'ASC');

$storeId = $this->getStoreId($category);

if ($storeId && $category->getId()) {
// Make a side effect on the context that will be used by the fulltext collection's request builder.
$this->searchContext->setCurrentCategory($category)
->setStoreId($storeId);

/** @var \Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection $fulltextCollection */
$fulltextCollection = $this->fulltextCollectionFactory->create();
$fulltextCollection->setStoreId($storeId)
->addFieldToFilter('category_ids', $this->getCategoryFilterParam($category));

$attributeSetIds = array_keys($fulltextCollection->getProductCountByAttributeSetId());
if (!empty($attributeSetIds)) {
$collection->setAttributeSetFilter($attributeSetIds);
}
}

return $collection->getItems();
}
}

0 comments on commit 1779ffe

Please sign in to comment.