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 IwdatCatalogExtPluginCatalogModelResourceModelProduct;
class CollectionPlugin
{
/**
* @param Collection $subject
* @param bool $printQuery
* @param bool $logQuery
*/
private $requestobj;
public function __construct(MagentoFrameworkAppRequestHttp $request)
{
$this->requestobj = $request;
}
public function beforeLoad(MagentoCatalogModelResourceModelProductCollection $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 IwdatCatalogExtModelResourceModelFulltext;
use MagentoCatalogSearchModelSearchRequestGenerator;
use MagentoFrameworkDBSelect;
use MagentoFrameworkExceptionStateException;
use MagentoFrameworkSearchAdapterMysqlTemporaryStorage;
use MagentoFrameworkSearchResponseQueryResponse;
use MagentoFrameworkSearchRequestEmptyRequestDataException;
use MagentoFrameworkSearchRequestNonExistingRequestNameException;
use MagentoFrameworkApiSearchSearchResultFactory;
use MagentoFrameworkExceptionLocalizedException;
use MagentoFrameworkAppObjectManager;
/**
* Fulltext Collection
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Collection extends MagentoCatalogSearchModelResourceModelFulltextCollection
{
/**
* @var QueryResponse
* @deprecated
*/
protected $queryResponse;
/**
* Catalog search data
*
* @var MagentoSearchModelQueryFactory
* @deprecated
*/
protected $queryFactory = null;
/**
* @var MagentoFrameworkSearchRequestBuilder
* @deprecated
*/
private $requestBuilder;
/**
* @var MagentoSearchModelSearchEngine
* @deprecated
*/
private $searchEngine;
/**
* @var string
*/
private $queryText;
/**
* @var string|null
*/
private $order = null;
/**
* @var string
*/
private $searchRequestName;
/**
* @var MagentoFrameworkSearchAdapterMysqlTemporaryStorageFactory
*/
private $temporaryStorageFactory;
/**
* @var MagentoSearchApiSearchInterface
*/
private $search;
/**
* @var MagentoFrameworkApiSearchSearchCriteriaBuilder
*/
private $searchCriteriaBuilder;
/**
* @var MagentoFrameworkApiSearchSearchResultInterface
*/
private $searchResult;
/**
* @var SearchResultFactory
*/
private $searchResultFactory;
/**
* @var MagentoFrameworkApiFilterBuilder
*/
private $filterBuilder;
/**
* @param MagentoFrameworkDataCollectionEntityFactory $entityFactory
* @param PsrLogLoggerInterface $logger
* @param MagentoFrameworkDataCollectionDbFetchStrategyInterface $fetchStrategy
* @param MagentoFrameworkEventManagerInterface $eventManager
* @param MagentoEavModelConfig $eavConfig
* @param MagentoFrameworkAppResourceConnection $resource
* @param MagentoEavModelEntityFactory $eavEntityFactory
* @param MagentoCatalogModelResourceModelHelper $resourceHelper
* @param MagentoFrameworkValidatorUniversalFactory $universalFactory
* @param MagentoStoreModelStoreManagerInterface $storeManager
* @param MagentoFrameworkModuleManager $moduleManager
* @param MagentoCatalogModelIndexerProductFlatState $catalogProductFlatState
* @param MagentoFrameworkAppConfigScopeConfigInterface $scopeConfig
* @param MagentoCatalogModelProductOptionFactory $productOptionFactory
* @param MagentoCatalogModelResourceModelUrl $catalogUrl
* @param MagentoFrameworkStdlibDateTimeTimezoneInterface $localeDate
* @param MagentoCustomerModelSession $customerSession
* @param MagentoFrameworkStdlibDateTime $dateTime
* @param MagentoCustomerApiGroupManagementInterface $groupManagement
* @param MagentoSearchModelQueryFactory $catalogSearchData
* @param MagentoFrameworkSearchRequestBuilder $requestBuilder
* @param MagentoSearchModelSearchEngine $searchEngine
* @param MagentoFrameworkSearchAdapterMysqlTemporaryStorageFactory $temporaryStorageFactory
* @param MagentoFrameworkDBAdapterAdapterInterface $connection
* @param string $searchRequestName
* @param SearchResultFactory $searchResultFactory
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
MagentoFrameworkDataCollectionEntityFactory $entityFactory,
PsrLogLoggerInterface $logger,
MagentoFrameworkDataCollectionDbFetchStrategyInterface $fetchStrategy,
MagentoFrameworkEventManagerInterface $eventManager,
MagentoEavModelConfig $eavConfig,
MagentoFrameworkAppResourceConnection $resource,
MagentoEavModelEntityFactory $eavEntityFactory,
MagentoCatalogModelResourceModelHelper $resourceHelper,
MagentoFrameworkValidatorUniversalFactory $universalFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoFrameworkModuleManager $moduleManager,
MagentoCatalogModelIndexerProductFlatState $catalogProductFlatState,
MagentoFrameworkAppConfigScopeConfigInterface $scopeConfig,
MagentoCatalogModelProductOptionFactory $productOptionFactory,
MagentoCatalogModelResourceModelUrl $catalogUrl,
MagentoFrameworkStdlibDateTimeTimezoneInterface $localeDate,
MagentoCustomerModelSession $customerSession,
MagentoFrameworkStdlibDateTime $dateTime,
MagentoCustomerApiGroupManagementInterface $groupManagement,
MagentoSearchModelQueryFactory $catalogSearchData,
MagentoFrameworkSearchRequestBuilder $requestBuilder,
MagentoSearchModelSearchEngine $searchEngine,
MagentoFrameworkSearchAdapterMysqlTemporaryStorageFactory $temporaryStorageFactory,
MagentoFrameworkDBAdapterAdapterInterface $connection = null,
$searchRequestName = 'catalog_view_container',
SearchResultFactory $searchResultFactory = null
) {
$this->queryFactory = $catalogSearchData;
if ($searchResultFactory === null) {
$this->searchResultFactory = MagentoFrameworkAppObjectManager::getInstance()
->get('MagentoFrameworkApiSearchSearchResultFactory');
}
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(
MagentoCatalogModelLayerFilterDynamicAlgorithmFactory::XML_PATH_RANGE_CALCULATION,
MagentoStoreModelScopeInterface::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 MagentoFrameworkApiSearchSearchResultInterface $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 MagentoCatalogModelResourceModelProductCollection::_renderFiltersBefore();
}
/**
* @deprecated
* @return MagentoFrameworkApiSearchSearchCriteriaBuilder
*/
private function getSearchCriteriaBuilder()
{
if ($this->searchCriteriaBuilder === null) {
$this->searchCriteriaBuilder = ObjectManager::getInstance()
->get('MagentoFrameworkApiSearchSearchCriteriaBuilder');
}
return $this->searchCriteriaBuilder;
}
/**
* @deprecated
* @return MagentoFrameworkApiFilterBuilder
*/
private function getFilterBuilder()
{
if ($this->filterBuilder === null) {
$this->filterBuilder = ObjectManager::getInstance()->get('MagentoFrameworkApiFilterBuilder');
}
return $this->filterBuilder;
}
/**
* @deprecated
* @return MagentoSearchApiSearchInterface
*/
private function getSearch()
{
if ($this->search === null) {
$this->search = ObjectManager::getInstance()->get('MagentoSearchApiSearchInterface');
}
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="MagentoCatalogModelResourceModelProductCollection">
<plugin name="beforeproductCollectionPlugin" type="IwdatCatalogExtPluginCatalogModelResourceModelProductCollectionPlugin" />
</type>
<preference for="MagentoCatalogSearchModelResourceModelFulltextCollection" type="IwdatCatalogExtModelResourceModelFulltextCollection" />
</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