I have done following plugin to filter the products by a custom attribute 'promotion_on', it works, but pagination does not reflect filtration (it shows full product lists' (without filtration) product page links -all)
<?php
namespace Iwdat\CatalogExt\Plugin\Catalog\Model\ResourceModel\Product;
class CollectionPlugin
{
/**
* @param Collection $subject
* @param bool $printQuery
* @param bool $logQuery
*/
private $requestobj;
public function __construct(\Magento\Framework\App\Request\Http $request)
{
$this->requestobj = $request;
}
public function beforeLoad(\Magento\Catalog\Model\ResourceModel\Product\Collection $subject, $printQuery = false, $logQuery = false)
{
$thisRoute = $this->requestobj->getRouteName();
if (!$subject->isLoaded()) {
// you can do your customzation/custom logic with $subject object
if($thisRoute == 'offersx')
$subject->addAttributeToFilter('promotion_on', 1);
}
return $subject;//[$printQuery, $logQuery];
}
}
?>
I tried overriding ResourceModel FullText/Collection , still no change in results.
<?php
namespace Iwdat\CatalogExt\Model\ResourceModel\Fulltext;
use Magento\CatalogSearch\Model\Search\RequestGenerator;
use Magento\Framework\DB\Select;
use Magento\Framework\Exception\StateException;
use Magento\Framework\Search\Adapter\Mysql\TemporaryStorage;
use Magento\Framework\Search\Response\QueryResponse;
use Magento\Framework\Search\Request\EmptyRequestDataException;
use Magento\Framework\Search\Request\NonExistingRequestNameException;
use Magento\Framework\Api\Search\SearchResultFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\App\ObjectManager;
/**
* Fulltext Collection
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Collection extends \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection
{
/**
* @var QueryResponse
* @deprecated
*/
protected $queryResponse;
/**
* Catalog search data
*
* @var \Magento\Search\Model\QueryFactory
* @deprecated
*/
protected $queryFactory = null;
/**
* @var \Magento\Framework\Search\Request\Builder
* @deprecated
*/
private $requestBuilder;
/**
* @var \Magento\Search\Model\SearchEngine
* @deprecated
*/
private $searchEngine;
/**
* @var string
*/
private $queryText;
/**
* @var string|null
*/
private $order = null;
/**
* @var string
*/
private $searchRequestName;
/**
* @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory
*/
private $temporaryStorageFactory;
/**
* @var \Magento\Search\Api\SearchInterface
*/
private $search;
/**
* @var \Magento\Framework\Api\Search\SearchCriteriaBuilder
*/
private $searchCriteriaBuilder;
/**
* @var \Magento\Framework\Api\Search\SearchResultInterface
*/
private $searchResult;
/**
* @var SearchResultFactory
*/
private $searchResultFactory;
/**
* @var \Magento\Framework\Api\FilterBuilder
*/
private $filterBuilder;
/**
* @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Eav\Model\Config $eavConfig
* @param \Magento\Framework\App\ResourceConnection $resource
* @param \Magento\Eav\Model\EntityFactory $eavEntityFactory
* @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper
* @param \Magento\Framework\Validator\UniversalFactory $universalFactory
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\Module\Manager $moduleManager
* @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory
* @param \Magento\Catalog\Model\ResourceModel\Url $catalogUrl
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Framework\Stdlib\DateTime $dateTime
* @param \Magento\Customer\Api\GroupManagementInterface $groupManagement
* @param \Magento\Search\Model\QueryFactory $catalogSearchData
* @param \Magento\Framework\Search\Request\Builder $requestBuilder
* @param \Magento\Search\Model\SearchEngine $searchEngine
* @param \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory
* @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
* @param string $searchRequestName
* @param SearchResultFactory $searchResultFactory
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\Framework\Data\Collection\EntityFactory $entityFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Eav\Model\Config $eavConfig,
\Magento\Framework\App\ResourceConnection $resource,
\Magento\Eav\Model\EntityFactory $eavEntityFactory,
\Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
\Magento\Framework\Validator\UniversalFactory $universalFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Module\Manager $moduleManager,
\Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Catalog\Model\Product\OptionFactory $productOptionFactory,
\Magento\Catalog\Model\ResourceModel\Url $catalogUrl,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
\Magento\Customer\Model\Session $customerSession,
\Magento\Framework\Stdlib\DateTime $dateTime,
\Magento\Customer\Api\GroupManagementInterface $groupManagement,
\Magento\Search\Model\QueryFactory $catalogSearchData,
\Magento\Framework\Search\Request\Builder $requestBuilder,
\Magento\Search\Model\SearchEngine $searchEngine,
\Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory,
\Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
$searchRequestName = 'catalog_view_container',
SearchResultFactory $searchResultFactory = null
) {
$this->queryFactory = $catalogSearchData;
if ($searchResultFactory === null) {
$this->searchResultFactory = \Magento\Framework\App\ObjectManager::getInstance()
->get('Magento\Framework\Api\Search\SearchResultFactory');
}
parent::__construct(
$entityFactory,
$logger,
$fetchStrategy,
$eventManager,
$eavConfig,
$resource,
$eavEntityFactory,
$resourceHelper,
$universalFactory,
$storeManager,
$moduleManager,
$catalogProductFlatState,
$scopeConfig,
$productOptionFactory,
$catalogUrl,
$localeDate,
$customerSession,
$dateTime,
$groupManagement,
$catalogSearchData,
$requestBuilder,
$searchEngine,
$temporaryStorageFactory,
$connection,
$searchRequestName,
$searchResultFactory
);
$this->requestBuilder = $requestBuilder;
$this->searchEngine = $searchEngine;
$this->temporaryStorageFactory = $temporaryStorageFactory;
$this->searchRequestName = $searchRequestName;
}
/**
* @inheritdoc
*/
protected function _renderFiltersBefore()
{
$this->getSearchCriteriaBuilder();
$this->getFilterBuilder();
$this->getSearch();
if ($this->queryText) {
$this->filterBuilder->setField('search_term');
$this->filterBuilder->setValue($this->queryText);
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
}
$priceRangeCalculation = $this->_scopeConfig->getValue(
\Magento\Catalog\Model\Layer\Filter\Dynamic\AlgorithmFactory::XML_PATH_RANGE_CALCULATION,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
if ($priceRangeCalculation) {
$this->filterBuilder->setField('price_dynamic_algorithm');
$this->filterBuilder->setValue($priceRangeCalculation);
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
}
// ADDING CUSTOM FILTER START
$this->filterBuilder->setField('promotion_on');
$this->filterBuilder->setValue(1);
$this->filterBuilder->setConditionType('eq');
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
// ADDING CUSTOM FILTER END
$searchCriteria = $this->searchCriteriaBuilder->create();
$searchCriteria->setRequestName($this->searchRequestName);
try {
$this->searchResult = $this->getSearch()->search($searchCriteria);
} catch (EmptyRequestDataException $e) {
/** @var \Magento\Framework\Api\Search\SearchResultInterface $searchResult */
$this->searchResult = $this->searchResultFactory->create()->setItems([]);
} catch (NonExistingRequestNameException $e) {
$this->_logger->error($e->getMessage());
throw new LocalizedException(__('Sorry, something went wrong. You can find out more in the error log.'));
}
$temporaryStorage = $this->temporaryStorageFactory->create();
$table = $temporaryStorage->storeApiDocuments($this->searchResult->getItems());
$this->getSelect()->joinInner(
[
'search_result' => $table->getName(),
],
'e.entity_id = search_result.' . TemporaryStorage::FIELD_ENTITY_ID,
[]
);
$this->_totalRecords = $this->searchResult->getTotalCount();
if ($this->order && 'relevance' === $this->order['field']) {
$this->getSelect()->order('search_result.'. TemporaryStorage::FIELD_SCORE . ' ' . $this->order['dir']);
}
//return parent::_renderFiltersBefore();
return \Magento\Catalog\Model\ResourceModel\Product\Collection::_renderFiltersBefore();
}
/**
* @deprecated
* @return \Magento\Framework\Api\Search\SearchCriteriaBuilder
*/
private function getSearchCriteriaBuilder()
{
if ($this->searchCriteriaBuilder === null) {
$this->searchCriteriaBuilder = ObjectManager::getInstance()
->get('\Magento\Framework\Api\Search\SearchCriteriaBuilder');
}
return $this->searchCriteriaBuilder;
}
/**
* @deprecated
* @return \Magento\Framework\Api\FilterBuilder
*/
private function getFilterBuilder()
{
if ($this->filterBuilder === null) {
$this->filterBuilder = ObjectManager::getInstance()->get('\Magento\Framework\Api\FilterBuilder');
}
return $this->filterBuilder;
}
/**
* @deprecated
* @return \Magento\Search\Api\SearchInterface
*/
private function getSearch()
{
if ($this->search === null) {
$this->search = ObjectManager::getInstance()->get('\Magento\Search\Api\SearchInterface');
}
return $this->search;
}
/**
* Return field faceted data from faceted search result
*
* @param string $field
* @return array
* @throws StateException
*/
public function getFacetedData($field)
{
$this->_renderFilters();
$result = [];
$aggregations = $this->searchResult->getAggregations();
// This behavior is for case with empty object when we got EmptyRequestDataException
if (null !== $aggregations) {
$bucket = $aggregations->getBucket($field . RequestGenerator::BUCKET_SUFFIX);
if ($bucket) {
foreach ($bucket->getValues() as $value) {
$metrics = $value->getMetrics();
$result[$metrics['value']] = $metrics;
}
} else {
throw new StateException(__('Bucket does not exist'));
}
}
return $result;
}
}
?>
etc/frontend/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\ResourceModel\Product\Collection">
<plugin name="beforeproductCollectionPlugin" type="Iwdat\CatalogExt\Plugin\Catalog\Model\ResourceModel\Product\CollectionPlugin" />
</type>
<preference for="Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection" type="Iwdat\CatalogExt\Model\ResourceModel\Fulltext\Collection" />
</config>
etc/search_request.xml
<requests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Search/etc/search_request.xsd">
<request query="catalog_view_container" index="catalogsearch_fulltext">
<queries>
<query xsi:type="boolQuery" name="catalog_view_container" boost="1">
<queryReference clause="should" ref="active_query"/>
</query>
<query name="active_query" xsi:type="filteredQuery">
<filterReference clause="must" ref="active_query_filter"/>
</query>
</queries>
<filters>
<filter xsi:type="termFilter" name="active_query_filter" field="promotion_on" value="1"/>
</filters>
<from>0</from>
<size>10000</size>
</request>
</requests>
I do appreciate if anyone can guide me on how to resolve this, to apply pagination to filtered product collection, not to the full product collection.
Thanks and Best Regards
Indunil