Zend certified PHP/Magento developer

Show all the Products in product filters magento 2.4.6

I create an attribute name [show_category] with yes/no values if it’s set to yes then the product show on the category page but if it’s select no, then product not shown on category page.

I create a module and override the file ModelResourceModelFulltextcollection.php

Using this module, I stop showing products which have the attribute show_category to no in frontend.

But now I want to show all the products in product filter, either the product with show_category to no or with yes.

Here is the code which I have use to show the products on category page :

File path : TestCatModelResourceModelFulltextcollection.php

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace TestCatModelResourceModelFulltext;
use MagentoCatalogSearchModelResourceModelFulltextCollectionDefaultFilterStrategyApplyChecker;
use MagentoCatalogSearchModelResourceModelFulltextCollectionDefaultFilterStrategyApplyCheckerInterface;
use MagentoCatalogSearchModelResourceModelFulltextCollectionTotalRecordsResolverInterface;
use MagentoCatalogSearchModelResourceModelFulltextCollectionTotalRecordsResolverFactory;
use MagentoCatalogSearchModelResourceModelFulltextCollectionSearchCriteriaResolverInterface;
use MagentoCatalogSearchModelResourceModelFulltextCollectionSearchCriteriaResolverFactory;
use MagentoCatalogSearchModelResourceModelFulltextCollectionSearchResultApplierFactory;
use MagentoCatalogSearchModelResourceModelFulltextCollectionSearchResultApplierInterface;
use MagentoFrameworkDataCollectionDbSizeResolverInterfaceFactory;
use MagentoFrameworkDBSelect;
use MagentoFrameworkApiSearchSearchResultInterface;
use MagentoCatalogSearchModelSearchRequestGenerator;
use MagentoFrameworkEntityManagerMetadataPool;
use MagentoFrameworkExceptionStateException;
use MagentoFrameworkSearchRequestEmptyRequestDataException;
use MagentoFrameworkSearchRequestNonExistingRequestNameException;
use MagentoFrameworkApiSearchSearchResultFactory;
use MagentoFrameworkExceptionLocalizedException;
use MagentoFrameworkAppObjectManager;
use MagentoCatalogModelResourceModelProductCollectionProductLimitationFactory;
use MagentoCatalogSearchModelResourceModelFulltextCollection as ParentCollection;
/**
* Fulltext Collection
*
* This collection should be refactored to not have dependencies on MySQL-specific implementation.
*
* @api
* @since 100.0.2
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.TooManyFields)
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class Collection extends ParentCollection
{
/**
* @var string
*/
private $queryText;
/**
* @var string
*/
private $searchRequestName;
/**
* @var MagentoSearchApiSearchInterface
*/
private $search;
/**
* @var MagentoFrameworkApiSearchSearchCriteriaBuilder
*/
private $searchCriteriaBuilder;
/**
* @var MagentoFrameworkApiSearchSearchResultInterface
*/
private $searchResult;
/**
* @var SearchResultFactory
*/
private $searchResultFactory;
/**
* @var MagentoFrameworkApiFilterBuilder
*/
private $filterBuilder;
/**
* @var SearchCriteriaResolverFactory
*/
private $searchCriteriaResolverFactory;
/**
* @var SearchResultApplierFactory
*/
private $searchResultApplierFactory;
/**
* @var TotalRecordsResolverFactory
*/
private $totalRecordsResolverFactory;
/**
* @var array
*/
private $searchOrders;
/**
* @var DefaultFilterStrategyApplyCheckerInterface
*/
private $defaultFilterStrategyApplyChecker;
/**
* @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 mixed $catalogSearchData
* @param mixed $requestBuilder
* @param mixed $searchEngine
* @param mixed $temporaryStorageFactory
* @param MagentoFrameworkDBAdapterAdapterInterface|null $connection
* @param string $searchRequestName
* @param SearchResultFactory|null $searchResultFactory
* @param ProductLimitationFactory|null $productLimitationFactory
* @param MetadataPool|null $metadataPool
* @param MagentoSearchApiSearchInterface|null $search
* @param MagentoFrameworkApiSearchSearchCriteriaBuilder|null $searchCriteriaBuilder
* @param MagentoFrameworkApiFilterBuilder|null $filterBuilder
* @param SearchCriteriaResolverFactory|null $searchCriteriaResolverFactory
* @param SearchResultApplierFactory|null $searchResultApplierFactory
* @param TotalRecordsResolverFactory|null $totalRecordsResolverFactory
* @param DefaultFilterStrategyApplyCheckerInterface|null $defaultFilterStrategyApplyChecker
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
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,
$catalogSearchData = null,
$requestBuilder = null,
$searchEngine = null,
$temporaryStorageFactory = null,
MagentoFrameworkDBAdapterAdapterInterface $connection = null,
$searchRequestName = 'catalog_view_container',
SearchResultFactory $searchResultFactory = null,
ProductLimitationFactory $productLimitationFactory = null,
MetadataPool $metadataPool = null,
MagentoSearchApiSearchInterface $search = null,
MagentoFrameworkApiSearchSearchCriteriaBuilder $searchCriteriaBuilder = null,
MagentoFrameworkApiFilterBuilder $filterBuilder = null,
SearchCriteriaResolverFactory $searchCriteriaResolverFactory = null,
SearchResultApplierFactory $searchResultApplierFactory = null,
TotalRecordsResolverFactory $totalRecordsResolverFactory = null,
DefaultFilterStrategyApplyCheckerInterface $defaultFilterStrategyApplyChecker = null
) {
$this->searchResultFactory = $searchResultFactory
?? ObjectManager::getInstance()->get(SearchResultFactory::class);
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,
$productLimitationFactory,
$metadataPool,
$search,
$searchCriteriaBuilder,
$filterBuilder,
$searchCriteriaResolverFactory,
$searchResultApplierFactory,
$totalRecordsResolverFactory,
$defaultFilterStrategyApplyChecker
);
$this->searchRequestName = $searchRequestName;
$this->search = $search ?: ObjectManager::getInstance()->get(MagentoSearchApiSearchInterface::class);
$this->searchCriteriaBuilder = $searchCriteriaBuilder ?: ObjectManager::getInstance()
->get(MagentoFrameworkApiSearchSearchCriteriaBuilder::class);
$this->filterBuilder = $filterBuilder ?: ObjectManager::getInstance()
->get(MagentoFrameworkApiFilterBuilder::class);
$this->searchCriteriaResolverFactory = $searchCriteriaResolverFactory ?: ObjectManager::getInstance()
->get(SearchCriteriaResolverFactory::class);
$this->searchResultApplierFactory = $searchResultApplierFactory ?: ObjectManager::getInstance()
->get(SearchResultApplierFactory::class);
$this->totalRecordsResolverFactory = $totalRecordsResolverFactory ?: ObjectManager::getInstance()
->get(TotalRecordsResolverFactory::class);
$this->defaultFilterStrategyApplyChecker = $defaultFilterStrategyApplyChecker ?: ObjectManager::getInstance()
->get(DefaultFilterStrategyApplyChecker::class);
}
/**
* Get search.
*
* @deprecated 100.1.0
* @return MagentoSearchApiSearchInterface
*/
private function getSearch()
{
if ($this->search === null) {
$this->search = ObjectManager::getInstance()->get(MagentoSearchApiSearchInterface::class);
}
return $this->search;
}
/**
* Test search.
*
* @deprecated 100.1.0
* @param MagentoSearchApiSearchInterface $object
* @return void
* @since 100.1.0
*/
public function setSearch(MagentoSearchApiSearchInterface $object)
{
$this->search = $object;
}
/**
* Set search criteria builder.
*
* @deprecated 100.1.0
* @return MagentoFrameworkApiSearchSearchCriteriaBuilder
*/
private function getSearchCriteriaBuilder()
{
if ($this->searchCriteriaBuilder === null) {
$this->searchCriteriaBuilder = ObjectManager::getInstance()
->get(MagentoFrameworkApiSearchSearchCriteriaBuilder::class);
}
return $this->searchCriteriaBuilder;
}
/**
* Set search criteria builder.
*
* @deprecated 100.1.0
* @param MagentoFrameworkApiSearchSearchCriteriaBuilder $object
* @return void
* @since 100.1.0
*/
public function setSearchCriteriaBuilder(MagentoFrameworkApiSearchSearchCriteriaBuilder $object)
{
$this->searchCriteriaBuilder = $object;
}
/**
* Get filter builder.
*
* @deprecated 100.1.0
* @return MagentoFrameworkApiFilterBuilder
*/
private function getFilterBuilder()
{
if ($this->filterBuilder === null) {
$this->filterBuilder = ObjectManager::getInstance()->get(MagentoFrameworkApiFilterBuilder::class);
}
return $this->filterBuilder;
}
/**
* Set filter builder.
*
* @deprecated 100.1.0
* @param MagentoFrameworkApiFilterBuilder $object
* @return void
* @since 100.1.0
*/
public function setFilterBuilder(MagentoFrameworkApiFilterBuilder $object)
{
$this->filterBuilder = $object;
}
/**
* Apply attribute filter to facet collection
*
* @param string $field
* @param mixed|null $condition
* @return $this
*/
public function addFieldToFilter($field, $condition = null)
{
if ($this->searchResult !== null) {
throw new RuntimeException('Illegal state');
}
$this->getSearchCriteriaBuilder();
$this->getFilterBuilder();
if (!is_array($condition) || !in_array(key($condition), ['from', 'to'], true)) {
$this->filterBuilder->setField($field);
$this->filterBuilder->setValue($condition);
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
} else {
if (!empty($condition['from'])) {
$this->filterBuilder->setField("{$field}.from");
$this->filterBuilder->setValue($condition['from']);
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
}
if (!empty($condition['to'])) {
$this->filterBuilder->setField("{$field}.to");
$this->filterBuilder->setValue($condition['to']);
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
}
}
return $this;
}
/**
* @inheritDoc
* @since 101.0.4
*/
public function clear()
{
$this->searchResult = null;
$this->setFlag('has_category_filter', false);
return parent::clear();
}
/**
* @inheritDoc
* @since 101.0.4
*/
protected function _reset()
{
$this->searchResult = null;
$this->setFlag('has_category_filter', false);
return parent::_reset();
}
/**
* @inheritdoc
* @since 101.0.4
*/
public function _loadEntities($printQuery = false, $logQuery = false)
{
$this->getEntity();
$this->printLogQuery($printQuery, $logQuery);
/**
* Prepare select query
* @var string $query
*/
$query = $this->getSelect();
try {
$rows = $this->_fetchAll($query);
} catch (Exception $e) {
$this->printLogQuery(false, true, $query);
throw $e;
}
$position = 0;
foreach ($rows as $value) {
if ($this->getFlag('has_category_filter')) {
$value['cat_index_position'] = $position++;
}
$object = $this->getNewEmptyItem()->setData($value);
$this->addItem($object);
if (isset($this->_itemsById[$object->getId()])) {
$this->_itemsById[$object->getId()][] = $object;
} else {
$this->_itemsById[$object->getId()] = [$object];
}
}
if ($this->getFlag('has_category_filter')) {
$this->setFlag('has_category_filter', false);
}
return $this;
}
/**
* Add search query filter
*
* @param string $query
* @return $this
*/
public function addSearchFilter($query)
{
$this->queryText = trim($this->queryText . ' ' . $query);
return $this;
}
/**
* @inheritdoc
*/
public function setOrder($attribute, $dir = Select::SQL_DESC)
{
$this->setSearchOrder($attribute, $dir);
if ($this->defaultFilterStrategyApplyChecker->isApplicable()) {
parent::setOrder($attribute, $dir);
}
return $this;
}
/**
* Add attribute to sort order.
*
* @param string $attribute
* @param string $dir
* @return $this
* @since 101.0.2
*/
public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
{
if ($this->defaultFilterStrategyApplyChecker->isApplicable()) {
parent::addAttributeToSort($attribute, $dir);
} else {
$this->setOrder($attribute, $dir);
}
return $this;
}
/**
* @inheritdoc
*/
protected function _renderFiltersBefore()
{
if ($this->isLoaded()) {
return;
}
if ($this->searchRequestName !== 'quick_search_container'
|| ($this->queryText && strlen(trim($this->queryText)))
) {
$this->prepareSearchTermFilter();
$this->preparePriceAggregation();
/* Custom Code for SKU start */
$this->filterBuilder->setField('show_category');
$this->filterBuilder->setValue('1');
$this->filterBuilder->setConditionType('eq');
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
/* Custom Code for SKU over */
$searchCriteria = $this->getSearchCriteriaResolver()->resolve();
try {
$this->searchResult =  $this->getSearch()->search($searchCriteria);
$this->_totalRecords = $this->getTotalRecordsResolver($this->searchResult)->resolve();
} catch (EmptyRequestDataException $e) {
$this->searchResult = $this->createEmptyResult();
} catch (NonExistingRequestNameException $e) {
$this->_logger->error($e->getMessage());
throw new LocalizedException(__('An error occurred. For details, see the error log.'));
}
} else {
$this->searchResult = $this->createEmptyResult();
}
$this->getSearchResultApplier($this->searchResult)->apply();
parent::_renderFiltersBefore();
// $debugBackTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
// foreach ($debugBackTrace as $item) {
// echo @$item['class'] . @$item['type'] . @$item['function'] . "n";
// }
}
/**
* Create empty search result
*
* @return SearchResultInterface
*/
private function createEmptyResult()
{
return $this->searchResultFactory->create()->setItems([]);
}
/**
* Set sort order for search query.
*
* @param string $field
* @param string $direction
* @return void
*/
private function setSearchOrder($field, $direction)
{
$field = (string)$this->_getMappedField($field);
$direction = strtoupper($direction) == self::SORT_ORDER_ASC ? self::SORT_ORDER_ASC : self::SORT_ORDER_DESC;
$this->searchOrders[$field] = $direction;
}
/**
* Get total records resolver.
*
* @param SearchResultInterface $searchResult
* @return TotalRecordsResolverInterface
*/
private function getTotalRecordsResolver(SearchResultInterface $searchResult): TotalRecordsResolverInterface
{
return $this->totalRecordsResolverFactory->create(
[
'searchResult' => $searchResult,
]
);
}
/**
* Get search criteria resolver.
*
* @return SearchCriteriaResolverInterface
*/
private function getSearchCriteriaResolver(): SearchCriteriaResolverInterface
{
return $this->searchCriteriaResolverFactory->create(
[
'builder' => $this->getSearchCriteriaBuilder(),
'collection' => $this,
'searchRequestName' => $this->searchRequestName,
'currentPage' => (int)$this->_curPage,
'size' => $this->getPageSize(),
'orders' => $this->searchOrders,
]
);
}
/**
* Get search result applier.
*
* @param SearchResultInterface $searchResult
* @return SearchResultApplierInterface
*/
private function getSearchResultApplier(SearchResultInterface $searchResult): SearchResultApplierInterface
{
return $this->searchResultApplierFactory->create(
[
'collection' => $this,
'searchResult' => $searchResult,
/** This variable sets by serOrder method, but doesn't have a getter method. */
'orders' => $this->_orders,
'size' => $this->getPageSize(),
'currentPage' => (int)$this->_curPage,
]
);
}
/**
* @inheritdoc
* @since 100.2.3
*/
protected function _beforeLoad()
{
/*
* This order is required to force search results be the same
* for the same requests and products with the same relevance
* NOTE: this does not replace existing orders but ADDs one more
*/
$this->setOrder('entity_id');
return parent::_beforeLoad();
}
/**
* Render filters.
*
* @return $this
*/
protected function _renderFilters()
{
$this->_filters = [];
return parent::_renderFilters();
}
/**
* Stub method for compatibility with other search engines
*
* @return $this
*/
public function setGeneralDefaultQuery()
{
return $this;
}
/**
* 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(__("The bucket doesn't exist."));
}
}
return $result;
}
/**
* Specify category filter for product collection
*
* @param MagentoCatalogModelCategory $category
* @return $this
*/
public function addCategoryFilter(MagentoCatalogModelCategory $category)
{
$this->addFieldToFilter('category_ids', $category->getId());
/**
* This changes need in backward compatible reasons for support dynamic improved algorithm
* for price aggregation process.
*/
if ($this->defaultFilterStrategyApplyChecker->isApplicable()) {
parent::addCategoryFilter($category);
} else {
$this->setFlag('has_category_filter', true);
$this->_productLimitationPrice();
}
return $this;
}
/**
* Set product visibility filter for enabled products
*
* @param array $visibility
* @return $this
*/
public function setVisibility($visibility)
{
$this->addFieldToFilter('visibility', $visibility);
/**
* This changes need in backward compatible reasons for support dynamic improved algorithm
* for price aggregation process.
*/
if ($this->defaultFilterStrategyApplyChecker->isApplicable()) {
parent::setVisibility($visibility);
}
return $this;
}
/**
* Prepare search term filter for text query.
*
* @return void
*/
private function prepareSearchTermFilter(): void
{
if ($this->queryText) {
$this->filterBuilder->setField('search_term');
$this->filterBuilder->setValue($this->queryText);
$this->searchCriteriaBuilder->addFilter($this->filterBuilder->create());
}
}
/**
* Prepare price aggregation algorithm.
*
* @return void
*/
private function preparePriceAggregation(): void
{
$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());
}
}
}

Can anyone please suggest me how can I acheive this that layered navigation show show_category with yes/no, But on the products show only that which have the attribute set to show_category with Yes.

For example I set 14 products to show_category attribute yes and its shown correctly in pagination too.

enter image description here

But Its show only products to show_category attribute yes in product filter but need to show both show_category attribute yes or no.

enter image description here