Skip to content

Commit a4cf5e6

Browse files
authored
Merge pull request #9288 from adobe-commerce-tier-4/PR-10-04-24
[Support Tier-4 horytsky] 10-04-2024 Regular delivery of bugfixes and improvements
2 parents 581b7ef + c8d9f7f commit a4cf5e6

File tree

41 files changed

+1629
-820
lines changed

Some content is hidden

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

41 files changed

+1629
-820
lines changed

app/code/Magento/Analytics/Model/ExportDataHandler.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function __construct(
9090
public function prepareExportData()
9191
{
9292
try {
93-
$tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::TMP);
93+
$tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP);
9494
$this->prepareDirectory($tmpDirectory, $this->getTmpFilesDirRelativePath());
9595
$this->reportWriter->write($tmpDirectory, $this->getTmpFilesDirRelativePath());
9696

@@ -122,7 +122,17 @@ public function prepareExportData()
122122
*/
123123
private function getTmpFilesDirRelativePath()
124124
{
125-
return $this->subdirectoryPath . 'tmp/';
125+
return $this->subdirectoryPath . 'tmp/' . $this->getInstanceIdentifier() . '/';
126+
}
127+
128+
/**
129+
* Return unique identifier for an instance.
130+
*
131+
* @return string
132+
*/
133+
private function getInstanceIdentifier()
134+
{
135+
return hash('sha256', BP);
126136
}
127137

128138
/**

app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,23 @@ protected function setUp(): void
112112
);
113113
}
114114

115+
/**
116+
* Return unique identifier for an instance.
117+
*
118+
* @return string
119+
*/
120+
private function getInstanceIdentifier()
121+
{
122+
return hash('sha256', BP);
123+
}
124+
115125
/**
116126
* @param bool $isArchiveSourceDirectory
117127
* @dataProvider prepareExportDataDataProvider
118128
*/
119129
public function testPrepareExportData($isArchiveSourceDirectory)
120130
{
121-
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/';
131+
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/' . $this->getInstanceIdentifier() . '/';
122132
$archiveRelativePath = $this->subdirectoryPath . $this->archiveName;
123133

124134
$archiveSource = $isArchiveSourceDirectory ? (__DIR__) : '/tmp/' . $tmpFilesDirectoryPath;
@@ -127,7 +137,7 @@ public function testPrepareExportData($isArchiveSourceDirectory)
127137
$this->filesystemMock
128138
->expects($this->once())
129139
->method('getDirectoryWrite')
130-
->with(DirectoryList::TMP)
140+
->with(DirectoryList::SYS_TMP)
131141
->willReturn($this->directoryMock);
132142
$this->directoryMock
133143
->expects($this->exactly(4))
@@ -210,13 +220,13 @@ public static function prepareExportDataDataProvider()
210220
public function testPrepareExportDataWithLocalizedException()
211221
{
212222
$this->expectException('Magento\Framework\Exception\LocalizedException');
213-
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/';
223+
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/' . $this->getInstanceIdentifier() . '/';
214224
$archivePath = $this->subdirectoryPath . $this->archiveName;
215225

216226
$this->filesystemMock
217227
->expects($this->once())
218228
->method('getDirectoryWrite')
219-
->with(DirectoryList::TMP)
229+
->with(DirectoryList::SYS_TMP)
220230
->willReturn($this->directoryMock);
221231
$this->reportWriterMock
222232
->expects($this->once())

app/code/Magento/CatalogGraphQl/DataProvider/Product/SearchCriteriaBuilder.php

Lines changed: 54 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -8,103 +8,50 @@
88
namespace Magento\CatalogGraphQl\DataProvider\Product;
99

1010
use Magento\Catalog\Api\Data\EavAttributeInterface;
11-
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
1212
use Magento\Catalog\Model\Product\Visibility;
13-
use Magento\Eav\Model\Config;
13+
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchCriteriaResolverFactory;
1414
use Magento\Framework\Api\FilterBuilder;
1515
use Magento\Framework\Api\Search\FilterGroupBuilder;
1616
use Magento\Framework\Api\Search\SearchCriteriaInterface;
1717
use Magento\Framework\Api\SortOrder;
1818
use Magento\Framework\Api\SortOrderBuilder;
1919
use Magento\Framework\App\Config\ScopeConfigInterface;
20-
use Magento\Framework\App\ObjectManager;
2120
use Magento\Framework\Exception\LocalizedException;
22-
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\Builder;
21+
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\ArgumentApplierPool;
2322
use Magento\Framework\Search\Request\Config as SearchConfig;
2423

2524
/**
2625
* Build search criteria
2726
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2827
*/
29-
3028
class SearchCriteriaBuilder
3129
{
3230
/**
33-
* @var ScopeConfigInterface
34-
*/
35-
private $scopeConfig;
36-
37-
/**
38-
* @var FilterBuilder
39-
*/
40-
private $filterBuilder;
41-
42-
/**
43-
* @var FilterGroupBuilder
44-
*/
45-
private $filterGroupBuilder;
46-
47-
/**
48-
* @var Builder
49-
*/
50-
private $builder;
51-
52-
/**
53-
* @var Visibility
54-
*/
55-
private $visibility;
56-
57-
/**
58-
* @var SortOrderBuilder
59-
*/
60-
private $sortOrderBuilder;
61-
62-
/**
63-
* @var Config
64-
*/
65-
private Config $eavConfig;
66-
67-
/**
68-
* @var SearchConfig
69-
*/
70-
private SearchConfig $searchConfig;
71-
72-
/**
73-
* @var RequestDataBuilder|mixed
74-
*/
75-
private RequestDataBuilder $localData;
76-
77-
/**
78-
* @param Builder $builder
7931
* @param ScopeConfigInterface $scopeConfig
8032
* @param FilterBuilder $filterBuilder
8133
* @param FilterGroupBuilder $filterGroupBuilder
8234
* @param Visibility $visibility
83-
* @param SortOrderBuilder|null $sortOrderBuilder
84-
* @param Config|null $eavConfig
85-
* @param SearchConfig|null $searchConfig
86-
* @param RequestDataBuilder|null $localData
35+
* @param SortOrderBuilder $sortOrderBuilder
36+
* @param ProductAttributeRepositoryInterface $productAttributeRepository
37+
* @param SearchConfig $searchConfig
38+
* @param RequestDataBuilder $localData
39+
* @param SearchCriteriaResolverFactory $criteriaResolverFactory
40+
* @param ArgumentApplierPool $argumentApplierPool
41+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
8742
*/
8843
public function __construct(
89-
Builder $builder,
90-
ScopeConfigInterface $scopeConfig,
91-
FilterBuilder $filterBuilder,
92-
FilterGroupBuilder $filterGroupBuilder,
93-
Visibility $visibility,
94-
SortOrderBuilder $sortOrderBuilder = null,
95-
Config $eavConfig = null,
96-
SearchConfig $searchConfig = null,
97-
RequestDataBuilder $localData = null,
44+
private readonly ScopeConfigInterface $scopeConfig,
45+
private readonly FilterBuilder $filterBuilder,
46+
private readonly FilterGroupBuilder $filterGroupBuilder,
47+
private readonly Visibility $visibility,
48+
private readonly SortOrderBuilder $sortOrderBuilder,
49+
private readonly ProductAttributeRepositoryInterface $productAttributeRepository,
50+
private readonly SearchConfig $searchConfig,
51+
private readonly RequestDataBuilder $localData,
52+
private readonly SearchCriteriaResolverFactory $criteriaResolverFactory,
53+
private readonly ArgumentApplierPool $argumentApplierPool,
9854
) {
99-
$this->scopeConfig = $scopeConfig;
100-
$this->filterBuilder = $filterBuilder;
101-
$this->filterGroupBuilder = $filterGroupBuilder;
102-
$this->builder = $builder;
103-
$this->visibility = $visibility;
104-
$this->sortOrderBuilder = $sortOrderBuilder ?? ObjectManager::getInstance()->get(SortOrderBuilder::class);
105-
$this->eavConfig = $eavConfig ?? ObjectManager::getInstance()->get(Config::class);
106-
$this->searchConfig = $searchConfig ?? ObjectManager::getInstance()->get(SearchConfig::class);
107-
$this->localData = $localData ?? ObjectManager::getInstance()->get(RequestDataBuilder::class);
10855
}
10956

11057
/**
@@ -117,45 +64,42 @@ public function __construct(
11764
*/
11865
public function build(array $args, bool $includeAggregation): SearchCriteriaInterface
11966
{
120-
$partialMatchFilters = [];
67+
$isSearch = isset($args['search']);
68+
$requestName = $includeAggregation ? 'graphql_product_search_with_aggregation' : 'graphql_product_search';
69+
12170
if (isset($args['filter'])) {
12271
$partialMatchFilters = $this->getPartialMatchFilters($args);
72+
if (count($partialMatchFilters)) {
73+
$this->updateMatchTypeRequestConfig($requestName, $partialMatchFilters);
74+
}
12375
$args = $this->removeMatchTypeFromArguments($args);
12476
}
125-
$searchCriteria = $this->builder->build('products', $args);
126-
$isSearch = isset($args['search']);
127-
$this->updateRangeFilters($searchCriteria);
128-
if ($includeAggregation) {
129-
$attributeData = $this->eavConfig->getAttribute(Product::ENTITY, 'price');
130-
$priceOptions = $attributeData->getData();
13177

132-
if ($priceOptions['is_filterable'] != 0) {
133-
$this->preparePriceAggregation($searchCriteria);
78+
$searchCriteria = $this->criteriaResolverFactory->create(
79+
[
80+
'searchRequestName' => $requestName,
81+
'currentPage' => $args['currentPage'],
82+
'size' => $args['pageSize'],
83+
'orders' => null,
84+
]
85+
)->resolve();
86+
foreach ($args as $argumentName => $argument) {
87+
if ($this->argumentApplierPool->hasApplier($argumentName)) {
88+
$argumentApplier = $this->argumentApplierPool->getApplier($argumentName);
89+
$argumentApplier->applyArgument($searchCriteria, 'products', $argumentName, $argument);
13490
}
135-
$requestName = 'graphql_product_search_with_aggregation';
136-
} else {
137-
$requestName = 'graphql_product_search';
138-
}
139-
$searchCriteria->setRequestName($requestName);
140-
141-
if (count($partialMatchFilters)) {
142-
$this->updateMatchTypeRequestConfig($requestName, $partialMatchFilters);
14391
}
144-
92+
$this->updateRangeFilters($searchCriteria);
93+
$this->preparePriceAggregation($searchCriteria, $includeAggregation);
14594
if ($isSearch) {
14695
$this->addFilter($searchCriteria, 'search_term', $args['search']);
14796
}
148-
14997
if (!$searchCriteria->getSortOrders()) {
15098
$this->addDefaultSortOrder($searchCriteria, $args, $isSearch);
15199
}
152-
153100
$this->addEntityIdSort($searchCriteria);
154101
$this->addVisibilityFilter($searchCriteria, $isSearch, !empty($args['filter']['category_id']));
155102

156-
$searchCriteria->setCurrentPage($args['currentPage']);
157-
$searchCriteria->setPageSize($args['pageSize']);
158-
159103
return $searchCriteria;
160104
}
161105

@@ -164,7 +108,6 @@ public function build(array $args, bool $includeAggregation): SearchCriteriaInte
164108
*
165109
* @param string $requestName
166110
* @param array $partialMatchFilters
167-
*
168111
* @return void
169112
*/
170113
private function updateMatchTypeRequestConfig(string $requestName, array $partialMatchFilters): void
@@ -184,7 +127,6 @@ private function updateMatchTypeRequestConfig(string $requestName, array $partia
184127
* Check if and what type of match_type value was requested
185128
*
186129
* @param array $args
187-
*
188130
* @return array
189131
*/
190132
private function getPartialMatchFilters(array $args): array
@@ -202,7 +144,6 @@ private function getPartialMatchFilters(array $args): array
202144
* Remove the match_type to avoid search criteria containing it
203145
*
204146
* @param array $args
205-
*
206147
* @return array
207148
*/
208149
private function removeMatchTypeFromArguments(array $args): array
@@ -254,7 +195,7 @@ private function addEntityIdSort(SearchCriteriaInterface $searchCriteria): void
254195
}
255196

256197
$sortOrderArray[] = $this->sortOrderBuilder
257-
->setField('_id')
198+
->setField('entity_id')
258199
->setDirection($sortDir)
259200
->create();
260201
$searchCriteria->setSortOrders($sortOrderArray);
@@ -264,10 +205,21 @@ private function addEntityIdSort(SearchCriteriaInterface $searchCriteria): void
264205
* Prepare price aggregation algorithm
265206
*
266207
* @param SearchCriteriaInterface $searchCriteria
208+
* @param bool $includeAggregation
267209
* @return void
268210
*/
269-
private function preparePriceAggregation(SearchCriteriaInterface $searchCriteria): void
211+
private function preparePriceAggregation(SearchCriteriaInterface $searchCriteria, bool $includeAggregation): void
270212
{
213+
if (!$includeAggregation) {
214+
return;
215+
}
216+
217+
$attributeData = $this->productAttributeRepository->get('price');
218+
$priceOptions = $attributeData->getData();
219+
if ((int) $priceOptions['is_filterable'] === 0) {
220+
return;
221+
}
222+
271223
$priceRangeCalculation = $this->scopeConfig->getValue(
272224
\Magento\Catalog\Model\Layer\Filter\Dynamic\AlgorithmFactory::XML_PATH_RANGE_CALCULATION,
273225
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
@@ -319,7 +271,7 @@ private function addDefaultSortOrder(SearchCriteriaInterface $searchCriteria, ar
319271
->setDirection(SortOrder::SORT_DESC)
320272
->create();
321273
} else {
322-
$categoryIdFilter = isset($args['filter']['category_id']) ? $args['filter']['category_id'] : false;
274+
$categoryIdFilter = $args['filter']['category_id'] ?? false;
323275
if ($categoryIdFilter) {
324276
if (!is_array($categoryIdFilter[array_key_first($categoryIdFilter)])
325277
|| count($categoryIdFilter[array_key_first($categoryIdFilter)]) <= 1

0 commit comments

Comments
 (0)