Skip to content

Commit 0e0c57f

Browse files
committed
ACP2E-748: Layered navigation filters don't work when "show out of stock" is enabled
1 parent 17acaf5 commit 0e0c57f

File tree

1 file changed

+5
-173
lines changed

1 file changed

+5
-173
lines changed

app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php

Lines changed: 5 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,12 @@
66

77
namespace Magento\Elasticsearch\Model\ResourceModel\Fulltext\Collection;
88

9-
use Magento\Catalog\Api\Data\ProductInterface;
10-
use Magento\CatalogInventory\Model\StockStatusApplierInterface;
11-
use Magento\CatalogInventory\Model\ResourceModel\StockStatusFilterInterface;
129
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchResultApplierInterface;
1310
use Magento\Framework\Api\Search\SearchResultInterface;
14-
use Magento\Framework\App\Config\ScopeConfigInterface;
15-
use Magento\Framework\App\ObjectManager;
1611
use Magento\Framework\Data\Collection;
17-
use Magento\Framework\EntityManager\MetadataPool;
1812

1913
/**
2014
* Resolve specific attributes for search criteria.
21-
*
22-
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2315
*/
2416
class SearchResultApplier implements SearchResultApplierInterface
2517
{
@@ -43,56 +35,22 @@ class SearchResultApplier implements SearchResultApplierInterface
4335
*/
4436
private $currentPage;
4537

46-
/**
47-
* @var ScopeConfigInterface
48-
*/
49-
private $scopeConfig;
50-
51-
/**
52-
* @var MetadataPool
53-
*/
54-
private $metadataPool;
55-
56-
/**
57-
* @var StockStatusFilterInterface
58-
*/
59-
private $stockStatusFilter;
60-
61-
/**
62-
* @var StockStatusApplierInterface
63-
*/
64-
private $stockStatusApplier;
65-
6638
/**
6739
* @param Collection $collection
6840
* @param SearchResultInterface $searchResult
6941
* @param int $size
7042
* @param int $currentPage
71-
* @param ScopeConfigInterface|null $scopeConfig
72-
* @param MetadataPool|null $metadataPool
73-
* @param StockStatusFilterInterface|null $stockStatusFilter
74-
* @param StockStatusApplierInterface|null $stockStatusApplier
7543
*/
7644
public function __construct(
7745
Collection $collection,
7846
SearchResultInterface $searchResult,
7947
int $size,
80-
int $currentPage,
81-
?ScopeConfigInterface $scopeConfig = null,
82-
?MetadataPool $metadataPool = null,
83-
?StockStatusFilterInterface $stockStatusFilter = null,
84-
?StockStatusApplierInterface $stockStatusApplier = null
48+
int $currentPage
8549
) {
8650
$this->collection = $collection;
8751
$this->searchResult = $searchResult;
8852
$this->size = $size;
8953
$this->currentPage = $currentPage;
90-
$this->scopeConfig = $scopeConfig ?? ObjectManager::getInstance()->get(ScopeConfigInterface::class);
91-
$this->metadataPool = $metadataPool ?? ObjectManager::getInstance()->get(MetadataPool::class);
92-
$this->stockStatusFilter = $stockStatusFilter
93-
?? ObjectManager::getInstance()->get(StockStatusFilterInterface::class);
94-
$this->stockStatusApplier = $stockStatusApplier
95-
?? ObjectManager::getInstance()->get(StockStatusApplierInterface::class);
9654
}
9755

9856
/**
@@ -105,13 +63,10 @@ public function apply()
10563
return;
10664
}
10765

108-
$ids = $this->getProductIdsBySaleability();
109-
110-
if (count($ids) == 0) {
111-
$items = $this->sliceItems($this->searchResult->getItems(), $this->size, $this->currentPage);
112-
foreach ($items as $item) {
113-
$ids[] = (int)$item->getId();
114-
}
66+
$items = $this->sliceItems($this->searchResult->getItems(), $this->size, $this->currentPage);
67+
$ids = [];
68+
foreach ($items as $item) {
69+
$ids[] = (int)$item->getId();
11570
}
11671
$orderList = implode(',', $ids);
11772
$this->collection->getSelect()
@@ -160,127 +115,4 @@ private function getOffset(int $pageNumber, int $pageSize): int
160115
{
161116
return ($pageNumber - 1) * $pageSize;
162117
}
163-
/**
164-
* Fetch filtered product ids sorted by the saleability and other applied sort orders
165-
*
166-
* @return array
167-
*/
168-
private function getProductIdsBySaleability(): array
169-
{
170-
$ids = [];
171-
172-
if (!$this->hasShowOutOfStockStatus()) {
173-
return $ids;
174-
}
175-
176-
if ($this->collection->getFlag('has_stock_status_filter')
177-
|| $this->collection->getFlag('has_category_filter')) {
178-
$categoryId = null;
179-
$searchCriteria = $this->searchResult->getSearchCriteria();
180-
foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
181-
foreach ($filterGroup->getFilters() as $filter) {
182-
if ($filter->getField() === 'category_ids') {
183-
$categoryId = $filter->getValue();
184-
break 2;
185-
}
186-
}
187-
}
188-
189-
if ($categoryId) {
190-
$resultSet = $this->categoryProductByCustomSortOrder($categoryId);
191-
foreach ($resultSet as $item) {
192-
$ids[] = (int)$item['entity_id'];
193-
}
194-
}
195-
}
196-
197-
return $ids;
198-
}
199-
200-
/**
201-
* Fetch product resultset by custom sort orders
202-
*
203-
* @param int $categoryId
204-
* @return array
205-
* @throws \Magento\Framework\Exception\LocalizedException
206-
* @throws \Exception
207-
*/
208-
private function categoryProductByCustomSortOrder(int $categoryId): array
209-
{
210-
$storeId = $this->collection->getStoreId();
211-
$searchCriteria = $this->searchResult->getSearchCriteria();
212-
$sortOrders = $searchCriteria->getSortOrders() ?? [];
213-
$sortOrders = array_merge(['is_salable' => \Magento\Framework\DB\Select::SQL_DESC], $sortOrders);
214-
215-
$connection = $this->collection->getConnection();
216-
$query = clone $connection->select()
217-
->reset(\Magento\Framework\DB\Select::ORDER)
218-
->reset(\Magento\Framework\DB\Select::LIMIT_COUNT)
219-
->reset(\Magento\Framework\DB\Select::LIMIT_OFFSET)
220-
->reset(\Magento\Framework\DB\Select::COLUMNS);
221-
$query->from(
222-
['e' => $this->collection->getTable('catalog_product_entity')],
223-
['e.entity_id']
224-
);
225-
$this->stockStatusApplier->setSearchResultApplier(true);
226-
$query = $this->stockStatusFilter->execute($query, 'e', 'stockItem');
227-
$query->join(
228-
['cat_index' => $this->collection->getTable('catalog_category_product_index_store' . $storeId)],
229-
'cat_index.product_id = e.entity_id'
230-
. ' AND cat_index.category_id = ' . $categoryId
231-
. ' AND cat_index.store_id = ' . $storeId,
232-
['cat_index.position']
233-
);
234-
foreach ($sortOrders as $field => $dir) {
235-
if ($field === 'name') {
236-
$entityTypeId = $this->collection->getEntity()->getTypeId();
237-
$entityMetadata = $this->metadataPool->getMetadata(ProductInterface::class);
238-
$linkField = $entityMetadata->getLinkField();
239-
$query->joinLeft(
240-
['product_var' => $this->collection->getTable('catalog_product_entity_varchar')],
241-
"product_var.{$linkField} = e.{$linkField} AND product_var.attribute_id =
242-
(SELECT attribute_id FROM eav_attribute WHERE entity_type_id={$entityTypeId}
243-
AND attribute_code='name')",
244-
['product_var.value AS name']
245-
);
246-
} elseif ($field === 'price') {
247-
$query->joinLeft(
248-
['price_index' => $this->collection->getTable('catalog_product_index_price')],
249-
'price_index.entity_id = e.entity_id'
250-
. ' AND price_index.customer_group_id = 0'
251-
. ' AND price_index.website_id = (Select website_id FROM store WHERE store_id = '
252-
. $storeId . ')',
253-
['price_index.max_price AS price']
254-
);
255-
}
256-
$columnFilters = [];
257-
$columnsParts = $query->getPart('columns');
258-
foreach ($columnsParts as $columns) {
259-
$columnFilters[] = $columns[2] ?? $columns[1];
260-
}
261-
if (in_array($field, $columnFilters, true)) {
262-
$query->order(new \Zend_Db_Expr("{$field} {$dir}"));
263-
}
264-
}
265-
266-
$query->limit(
267-
$searchCriteria->getPageSize(),
268-
$searchCriteria->getCurrentPage() * $searchCriteria->getPageSize()
269-
);
270-
271-
return $connection->fetchAssoc($query) ?? [];
272-
}
273-
274-
/**
275-
* Returns if display out of stock status set or not in catalog inventory
276-
*
277-
* @return bool
278-
*/
279-
private function hasShowOutOfStockStatus(): bool
280-
{
281-
return (bool) $this->scopeConfig->getValue(
282-
\Magento\CatalogInventory\Model\Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
283-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
284-
);
285-
}
286118
}

0 commit comments

Comments
 (0)