Skip to content

Commit 378b3d4

Browse files
committed
Merge branch '2.4-develop' of https://github.com/magento-commerce/magento2ce into ACP2E-111
2 parents 5ec2029 + ceffb8b commit 378b3d4

File tree

96 files changed

+3278
-842
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+3278
-842
lines changed

app/code/Magento/AdvancedSearch/Model/ResourceModel/Index.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ public function __construct(
8080

8181
/**
8282
* Implementation of abstract construct
83+
*
8384
* @return void
8485
* @since 100.1.0
86+
* phpcs:disable Magento2.CodeAnalysis.EmptyBlock
8587
*/
8688
protected function _construct()
8789
{
@@ -118,7 +120,8 @@ protected function _getCatalogProductPriceData($productIds = null)
118120

119121
$result = [];
120122
foreach ($connection->fetchAll($catalogProductIndexPriceUnionSelect) as $row) {
121-
$result[$row['website_id']][$row['entity_id']][$row['customer_group_id']] = round($row['min_price'], 2);
123+
$result[$row['website_id']][$row['entity_id']][$row['customer_group_id']] =
124+
round((float) $row['min_price'], 2);
122125
}
123126

124127
return $result;

app/code/Magento/AdvancedSearch/Test/Unit/Model/ResourceModel/IndexTest.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ class IndexTest extends TestCase
6060
*/
6161
private $resourceConnectionMock;
6262

63+
/**
64+
* @inheritdoc
65+
*/
6366
protected function setUp(): void
6467
{
6568
$this->storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class);
@@ -98,6 +101,9 @@ protected function setUp(): void
98101
);
99102
}
100103

104+
/**
105+
* @return void
106+
*/
101107
public function testGetPriceIndexDataUsesFrontendPriceIndexerTable(): void
102108
{
103109
$storeId = 1;
@@ -117,4 +123,73 @@ public function testGetPriceIndexDataUsesFrontendPriceIndexerTable(): void
117123

118124
$this->assertEmpty($this->model->getPriceIndexData([1], $storeId));
119125
}
126+
127+
/**
128+
* @param array $testData
129+
* @dataProvider providerForTestPriceIndexData
130+
*
131+
* @return void
132+
*/
133+
public function testGetPriceIndexData(array $testData): void
134+
{
135+
$storeMock = $this->getMockForAbstractClass(StoreInterface::class);
136+
$storeMock->expects($this->any())->method('getId')->willReturn(1);
137+
$storeMock->method('getWebsiteId')->willReturn($testData['website_id']);
138+
$this->storeManagerMock->expects($this->once())
139+
->method('getStore')
140+
->with(1)->willReturn($storeMock);
141+
142+
$selectMock = $this->createMock(Select::class);
143+
$selectMock->expects($this->any())->method('union')->willReturnSelf();
144+
$this->adapterMock->expects($this->any())->method('select')->willReturn($selectMock);
145+
$this->adapterMock->expects($this->any())->method('fetchAll')->with($selectMock)->willReturn([$testData]);
146+
$expectedData = [
147+
$testData['entity_id'] => [
148+
$testData['customer_group_id'] => round((float) $testData['min_price'], 2)
149+
]
150+
];
151+
152+
$this->assertEquals($this->model->getPriceIndexData([1], 1), $expectedData);
153+
}
154+
155+
/**
156+
* @return array
157+
*/
158+
public function providerForTestPriceIndexData(): array
159+
{
160+
return [
161+
[
162+
[
163+
'website_id' => 1,
164+
'entity_id' => 1,
165+
'customer_group_id' => 1,
166+
'min_price' => '12.12'
167+
]
168+
],
169+
[
170+
[
171+
'website_id' => 1,
172+
'entity_id' => 2,
173+
'customer_group_id' => 2,
174+
'min_price' => null
175+
]
176+
],
177+
[
178+
[
179+
'website_id' => 1,
180+
'entity_id' => 3,
181+
'customer_group_id' => 3,
182+
'min_price' => 12.12
183+
]
184+
],
185+
[
186+
[
187+
'website_id' => 1,
188+
'entity_id' => 3,
189+
'customer_group_id' => 3,
190+
'min_price' => ''
191+
]
192+
]
193+
];
194+
}
120195
}

app/code/Magento/Bundle/Model/Product/SelectionProductsDisabledRequired.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function __construct(
8282
* @param int $bundleId
8383
* @param int|null $websiteId
8484
* @return array
85+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
8586
*/
8687
public function getChildProductIds(int $bundleId, ?int $websiteId = null): array
8788
{
@@ -128,10 +129,12 @@ public function getChildProductIds(int $bundleId, ?int $websiteId = null): array
128129
private function getProducts(array $selectionProductIds, int $websiteId): array
129130
{
130131
$productIds = [];
131-
$defaultStoreId = $this->storeManager->getWebsite($websiteId)->getDefaultStore()->getId();
132+
$defaultStore = $this->storeManager->getWebsite($websiteId)->getDefaultStore();
133+
$defaultStoreId = $defaultStore ? $defaultStore->getId() : null;
132134
foreach ($selectionProductIds as $optionProductIds) {
133-
$productIds = array_merge($productIds, $optionProductIds);
135+
$productIds[] = $optionProductIds;
134136
}
137+
$productIds = array_merge([], ...$productIds);
135138
$productCollection = $this->productCollectionFactory->create();
136139
$productCollection->joinAttribute(
137140
ProductInterface::STATUS,

app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use Magento\Store\Model\StoreManagerInterface;
1313

1414
/**
15-
* Class Save
15+
* Category save controller
1616
*
1717
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1818
*/
@@ -144,10 +144,10 @@ public function execute()
144144
$categoryPostData = $this->stringToBoolConverting($categoryPostData);
145145
$categoryPostData = $this->imagePreprocessing($categoryPostData);
146146
$categoryPostData = $this->dateTimePreprocessing($category, $categoryPostData);
147-
$storeId = isset($categoryPostData['store_id']) ? $categoryPostData['store_id'] : null;
147+
$storeId = $categoryPostData['store_id'] ?? null;
148148
$store = $this->storeManager->getStore($storeId);
149149
$this->storeManager->setCurrentStore($store->getCode());
150-
$parentId = isset($categoryPostData['parent']) ? $categoryPostData['parent'] : null;
150+
$parentId = $categoryPostData['parent'] ?? null;
151151
if ($categoryPostData) {
152152
$category->addData($categoryPostData);
153153
if ($parentId) {
@@ -168,7 +168,7 @@ public function execute()
168168
if (isset($categoryPostData['use_config']) && !empty($categoryPostData['use_config'])) {
169169
foreach ($categoryPostData['use_config'] as $attributeCode => $attributeValue) {
170170
if ($attributeValue) {
171-
$useConfig[] = $attributeCode;
171+
$useConfig[] = $attributeValue;
172172
$category->setData($attributeCode, null);
173173
}
174174
}
@@ -220,7 +220,11 @@ public function execute()
220220
__('The "%1" attribute is required. Enter and try again.', $attribute)
221221
);
222222
} else {
223-
$this->messageManager->addErrorMessage(__('Something went wrong while saving the category.'));
223+
$this->messageManager->addErrorMessage(
224+
__(
225+
'Something went wrong while saving the category.'
226+
)
227+
);
224228
$this->logger->critical('Something went wrong while saving the category.');
225229
$this->_getSession()->setCategoryData($categoryPostData);
226230
}

app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ public function getCacheKeyInfo()
196196
$cacheKeys['display_minimal_price'] = $this->getDisplayMinimalPrice();
197197
$cacheKeys['is_product_list'] = $this->isProductList();
198198
$cacheKeys['customer_group_id'] = $this->getSaleableItem()->getCustomerGroupId();
199+
$cacheKeys['zone'] = $this->getZone();
199200
return $cacheKeys;
200201
}
201202

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
namespace Magento\CatalogGraphQl\Model;
9+
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\Framework\Stdlib\StringUtils as StdlibString;
12+
use Magento\GraphQl\Model\Query\ContextInterface;
13+
use Magento\Search\Model\Query;
14+
use Magento\Search\Model\QueryFactory;
15+
16+
/**
17+
* Prepares search query based on search text.
18+
*/
19+
class QueryProcessor
20+
{
21+
/**
22+
* @var QueryFactory
23+
*/
24+
private $queryFactory;
25+
26+
/**
27+
* @var StdlibString
28+
*/
29+
private $string;
30+
31+
/**
32+
* @param QueryFactory $queryFactory
33+
* @param StdlibString $string
34+
*/
35+
public function __construct(
36+
QueryFactory $queryFactory,
37+
StdlibString $string
38+
) {
39+
$this->queryFactory = $queryFactory;
40+
$this->string = $string;
41+
}
42+
43+
/**
44+
* Prepare Query object based on search text
45+
*
46+
* @param ContextInterface $context
47+
* @param string $queryText
48+
* @throws NoSuchEntityException
49+
* @return Query
50+
*/
51+
public function prepare(ContextInterface $context, string $queryText) : Query
52+
{
53+
$query = $this->queryFactory->create();
54+
$maxQueryLength = (int) $query->getMaxQueryLength();
55+
if ($maxQueryLength && $this->string->strlen($queryText) > $maxQueryLength) {
56+
$queryText = $this->string->substr($queryText, 0, $maxQueryLength);
57+
}
58+
$query->setQueryText($queryText);
59+
$store = $context->getExtensionAttributes()->getStore();
60+
$query->setStoreId($store->getId());
61+
return $query;
62+
}
63+
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public function resolve(
7070
$data = [
7171
'total_count' => $searchResult->getTotalCount(),
7272
'items' => $searchResult->getProductsSearchResult(),
73+
'suggestions' => $searchResult->getSuggestions(),
7374
'page_info' => [
7475
'page_size' => $searchResult->getPageSize(),
7576
'current_page' => $searchResult->getCurrentPage(),

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ class Search implements ProductQueryInterface
6363
*/
6464
private $searchCriteriaBuilder;
6565

66+
/**
67+
* @var Suggestions
68+
*/
69+
private $suggestions;
70+
6671
/**
6772
* @var QueryPopularity
6873
*/
@@ -76,6 +81,7 @@ class Search implements ProductQueryInterface
7681
* @param ProductSearch $productsProvider
7782
* @param SearchCriteriaBuilder $searchCriteriaBuilder
7883
* @param ArgumentsProcessorInterface|null $argsSelection
84+
* @param Suggestions|null $suggestions
7985
* @param QueryPopularity|null $queryPopularity
8086
*/
8187
public function __construct(
@@ -86,6 +92,7 @@ public function __construct(
8692
ProductSearch $productsProvider,
8793
SearchCriteriaBuilder $searchCriteriaBuilder,
8894
ArgumentsProcessorInterface $argsSelection = null,
95+
Suggestions $suggestions = null,
8996
QueryPopularity $queryPopularity = null
9097
) {
9198
$this->search = $search;
@@ -94,7 +101,10 @@ public function __construct(
94101
$this->fieldSelection = $fieldSelection;
95102
$this->productsProvider = $productsProvider;
96103
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
97-
$this->argsSelection = $argsSelection ?: ObjectManager::getInstance()->get(ArgumentsProcessorInterface::class);
104+
$this->argsSelection = $argsSelection ?: ObjectManager::getInstance()
105+
->get(ArgumentsProcessorInterface::class);
106+
$this->suggestions = $suggestions ?: ObjectManager::getInstance()
107+
->get(Suggestions::class);
98108
$this->queryPopularity = $queryPopularity ?: ObjectManager::getInstance()->get(QueryPopularity::class);
99109
}
100110

@@ -146,14 +156,21 @@ public function getResult(
146156
$productArray[$product->getId()]['model'] = $product;
147157
}
148158

159+
$suggestions = [];
160+
$totalCount = (int) $searchResults->getTotalCount();
161+
if ($totalCount === 0 && !empty($args['search'])) {
162+
$suggestions = $this->suggestions->execute($context, $args['search']);
163+
}
164+
149165
return $this->searchResultFactory->create(
150166
[
151-
'totalCount' => $searchResults->getTotalCount(),
167+
'totalCount' => $totalCount,
152168
'productsSearchResult' => $productArray,
153169
'searchAggregation' => $itemsResults->getAggregations(),
154170
'pageSize' => $realPageSize,
155171
'currentPage' => $realCurrentPage,
156172
'totalPages' => $totalPages,
173+
'suggestions' => $suggestions,
157174
]
158175
);
159176
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
namespace Magento\CatalogGraphQl\Model\Resolver\Products\Query;
9+
10+
use Magento\AdvancedSearch\Model\SuggestedQueries;
11+
use Magento\GraphQl\Model\Query\ContextInterface;
12+
use Magento\CatalogGraphQl\Model\QueryProcessor;
13+
14+
/**
15+
* Search suggestions implementations for GraphQL
16+
*/
17+
class Suggestions
18+
{
19+
/**
20+
* @var QueryProcessor
21+
*/
22+
private $queryProcessor;
23+
24+
/**
25+
* @var SuggestedQueries
26+
*/
27+
private $suggestedQueries;
28+
29+
/**
30+
* @param QueryProcessor $queryProcessor
31+
* @param SuggestedQueries $suggestedQueries
32+
*/
33+
public function __construct(
34+
QueryProcessor $queryProcessor,
35+
SuggestedQueries $suggestedQueries
36+
) {
37+
$this->queryProcessor = $queryProcessor;
38+
$this->suggestedQueries = $suggestedQueries;
39+
}
40+
41+
/**
42+
* Return search suggestions for the provided query text
43+
*
44+
* @param ContextInterface $context
45+
* @param string $queryText
46+
* @return array
47+
*/
48+
public function execute(ContextInterface $context, string $queryText) : array
49+
{
50+
$result = [];
51+
$query = $this->queryProcessor->prepare($context, $queryText);
52+
$suggestionItems = $this->suggestedQueries->getItems($query);
53+
foreach ($suggestionItems as $suggestion) {
54+
$result[] = ['search' => $suggestion->getQueryText()];
55+
}
56+
return $result;
57+
}
58+
}

0 commit comments

Comments
 (0)