Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #1153 Reducing list of filterable attributes #1164

Merged
merged 1 commit into from
Nov 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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();
}
}