Skip to content

Commit 7d0fc5a

Browse files
authored
Merge pull request #5551 from magento-tsg-csl3/2.3-develop-pr42
[TSG-CSL3] For 2.3 (pr42)
2 parents 3bfcbcf + bc3cee6 commit 7d0fc5a

File tree

5 files changed

+157
-15
lines changed

5 files changed

+157
-15
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1733,7 +1733,9 @@ public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
17331733
if ($attribute == 'price' && $storeId != 0) {
17341734
$this->addPriceData();
17351735
if ($this->_productLimitationFilters->isUsingPriceIndex()) {
1736-
$this->getSelect()->order("price_index.min_price {$dir}");
1736+
$this->getSelect()->order(
1737+
new \Zend_Db_Expr("price_index.min_price = 0, price_index.min_price {$dir}")
1738+
);
17371739
return $this;
17381740
}
17391741
}

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,22 @@ public function apply()
6969
foreach ($items as $item) {
7070
$ids[] = (int)$item->getId();
7171
}
72-
$this->collection->getSelect()->where('e.entity_id IN (?)', $ids);
73-
$orderList = join(',', $ids);
74-
$this->collection->getSelect()->reset(\Magento\Framework\DB\Select::ORDER);
75-
$this->collection->getSelect()->order(new \Zend_Db_Expr("FIELD(e.entity_id,$orderList)"));
72+
$this->collection->getSelect()
73+
->where('e.entity_id IN (?)', $ids)
74+
->reset(\Magento\Framework\DB\Select::ORDER);
75+
$sortOrder = $this->searchResult->getSearchCriteria()
76+
->getSortOrders();
77+
if (!empty($sortOrder['price']) && $this->collection->getLimitationFilters()->isUsingPriceIndex()) {
78+
$sortDirection = $sortOrder['price'];
79+
$this->collection->getSelect()
80+
->order(
81+
new \Zend_Db_Expr("price_index.min_price = 0, price_index.min_price {$sortDirection}")
82+
);
83+
} else {
84+
$orderList = join(',', $ids);
85+
$this->collection->getSelect()
86+
->order(new \Zend_Db_Expr("FIELD(e.entity_id,$orderList)"));
87+
}
7688
}
7789

7890
/**

dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListProduct/SortingTest.php

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,7 @@ public function testProductListSortOrder(string $sortBy, string $direction, arra
110110
*/
111111
public function testProductListSortOrderWithConfig(string $sortBy, string $direction, array $expectation): void
112112
{
113-
$this->objectManager->removeSharedInstance(Config::class);
114-
$this->scopeConfig->setValue(
115-
Config::XML_PATH_LIST_DEFAULT_SORT_BY,
116-
$sortBy,
117-
ScopeInterface::SCOPE_STORE,
118-
Store::DEFAULT_STORE_ID
119-
);
120-
$category = $this->updateCategorySortBy('Category 1', Store::DEFAULT_STORE_ID, null);
121-
$this->renderBlock($category, $direction);
122-
$this->assertBlockSorting($sortBy, $expectation);
113+
$this->assertProductListSortOrderWithConfig($sortBy, $direction, $expectation);
123114
}
124115

125116
/**
@@ -322,4 +313,89 @@ private function updateCategorySortBy(
322313

323314
return $category;
324315
}
316+
317+
/**
318+
* Test product list ordered by price with out-of-stock configurable product options with elasticsearch engine
319+
*
320+
* @magentoDataFixture Magento/Catalog/_files/products_with_not_empty_layered_navigation_attribute.php
321+
* @magentoDataFixture Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child.php
322+
* @magentoConfigFixture current_store cataloginventory/options/show_out_of_stock 1
323+
* @magentoConfigFixture default/catalog/search/engine elasticsearch7
324+
* @dataProvider productListWithOutOfStockSortOrderDataProvider
325+
* @param string $sortBy
326+
* @param string $direction
327+
* @param array $expected
328+
* @return void
329+
*/
330+
public function testProductListOutOfStockSortOrderWithElasticsearch(
331+
string $sortBy,
332+
string $direction,
333+
array $expected
334+
): void {
335+
$this->assertProductListSortOrderWithConfig($sortBy, $direction, $expected);
336+
}
337+
338+
/**
339+
* Test product list ordered by price with out-of-stock configurable product options with mysql search engine
340+
*
341+
* @magentoDataFixture Magento/Catalog/_files/products_with_not_empty_layered_navigation_attribute.php
342+
* @magentoDataFixture Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child.php
343+
* @magentoConfigFixture current_store cataloginventory/options/show_out_of_stock 1
344+
* @magentoConfigFixture default/catalog/search/engine mysql
345+
* @dataProvider productListWithOutOfStockSortOrderDataProvider
346+
* @param string $sortBy
347+
* @param string $direction
348+
* @param array $expected
349+
* @return void
350+
*/
351+
public function testProductListOutOfStockSortOrderWithMysql(
352+
string $sortBy,
353+
string $direction,
354+
array $expected
355+
): void {
356+
$this->assertProductListSortOrderWithConfig($sortBy, $direction, $expected);
357+
}
358+
359+
/**
360+
* Product list with out-of-stock sort order data provider
361+
*
362+
* @return array
363+
*/
364+
public function productListWithOutOfStockSortOrderDataProvider(): array
365+
{
366+
return [
367+
'default_order_price_asc' => [
368+
'sort' => 'price',
369+
'direction' => Collection::SORT_ORDER_ASC,
370+
'expectation' => ['simple1', 'simple2', 'simple3', 'configurable'],
371+
],
372+
'default_order_price_desc' => [
373+
'sort' => 'price',
374+
'direction' => Collection::SORT_ORDER_DESC,
375+
'expectation' => ['simple3', 'simple2', 'simple1', 'configurable'],
376+
],
377+
];
378+
}
379+
380+
/**
381+
* Assert product list order
382+
*
383+
* @param string $sortBy
384+
* @param string $direction
385+
* @param array $expected
386+
* @return void
387+
*/
388+
private function assertProductListSortOrderWithConfig(string $sortBy, string $direction, array $expected): void
389+
{
390+
$this->objectManager->removeSharedInstance(Config::class);
391+
$this->scopeConfig->setValue(
392+
Config::XML_PATH_LIST_DEFAULT_SORT_BY,
393+
$sortBy,
394+
ScopeInterface::SCOPE_STORE,
395+
Store::DEFAULT_STORE_ID
396+
);
397+
$category = $this->updateCategorySortBy('Category 1', Store::DEFAULT_STORE_ID, null);
398+
$this->renderBlock($category, $direction);
399+
$this->assertBlockSorting($sortBy, $expected);
400+
}
325401
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Catalog\Api\CategoryLinkManagementInterface;
9+
use Magento\Catalog\Api\ProductRepositoryInterface;
10+
use Magento\Catalog\Helper\DefaultCategory;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
13+
require __DIR__ . '/product_configurable.php';
14+
15+
$objectManager = Bootstrap::getObjectManager();
16+
17+
/** @var ProductRepositoryInterface $productRepository */
18+
$productRepository = $objectManager->create(ProductRepositoryInterface::class);
19+
20+
$product = $productRepository->get('simple_1010');
21+
$product->setStockData(
22+
[
23+
'qty' => 0,
24+
]
25+
);
26+
$productRepository->save($product);
27+
28+
$product = $productRepository->get('simple_1020');
29+
$product->setStockData(
30+
[
31+
'qty' => 0,
32+
]
33+
);
34+
$productRepository->save($product);
35+
36+
/** @var CategoryLinkManagementInterface $categoryLinkManagement */
37+
$categoryLinkManagement = $objectManager->create(CategoryLinkManagementInterface::class);
38+
/** @var DefaultCategory $categoryHelper */
39+
$categoryHelper = $objectManager->get(DefaultCategory::class);
40+
41+
foreach (['simple_1010', 'simple_1020', 'configurable'] as $sku) {
42+
$categoryLinkManagement->assignProductToCategories($sku, [$categoryHelper->getId(), 333]);
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
require __DIR__ . '/../../../Catalog/_files/category_rollback.php';
9+
require __DIR__ . '/product_configurable_rollback.php';

0 commit comments

Comments
 (0)