8
8
namespace Magento \CatalogGraphQl \DataProvider \Product ;
9
9
10
10
use Magento \Catalog \Api \Data \EavAttributeInterface ;
11
- use Magento \Catalog \Model \ Product ;
11
+ use Magento \Catalog \Api \ ProductAttributeRepositoryInterface ;
12
12
use Magento \Catalog \Model \Product \Visibility ;
13
- use Magento \Eav \Model \Config ;
13
+ use Magento \CatalogSearch \Model \ResourceModel \ Fulltext \ Collection \ SearchCriteriaResolverFactory ;
14
14
use Magento \Framework \Api \FilterBuilder ;
15
15
use Magento \Framework \Api \Search \FilterGroupBuilder ;
16
16
use Magento \Framework \Api \Search \SearchCriteriaInterface ;
17
17
use Magento \Framework \Api \SortOrder ;
18
18
use Magento \Framework \Api \SortOrderBuilder ;
19
19
use Magento \Framework \App \Config \ScopeConfigInterface ;
20
- use Magento \Framework \App \ObjectManager ;
21
20
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 ;
23
22
use Magento \Framework \Search \Request \Config as SearchConfig ;
24
23
25
24
/**
26
25
* Build search criteria
27
26
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28
27
*/
29
-
30
28
class SearchCriteriaBuilder
31
29
{
32
30
/**
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
79
31
* @param ScopeConfigInterface $scopeConfig
80
32
* @param FilterBuilder $filterBuilder
81
33
* @param FilterGroupBuilder $filterGroupBuilder
82
34
* @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)
87
42
*/
88
43
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 ,
98
54
) {
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);
108
55
}
109
56
110
57
/**
@@ -117,45 +64,42 @@ public function __construct(
117
64
*/
118
65
public function build (array $ args , bool $ includeAggregation ): SearchCriteriaInterface
119
66
{
120
- $ partialMatchFilters = [];
67
+ $ isSearch = isset ($ args ['search ' ]);
68
+ $ requestName = $ includeAggregation ? 'graphql_product_search_with_aggregation ' : 'graphql_product_search ' ;
69
+
121
70
if (isset ($ args ['filter ' ])) {
122
71
$ partialMatchFilters = $ this ->getPartialMatchFilters ($ args );
72
+ if (count ($ partialMatchFilters )) {
73
+ $ this ->updateMatchTypeRequestConfig ($ requestName , $ partialMatchFilters );
74
+ }
123
75
$ args = $ this ->removeMatchTypeFromArguments ($ args );
124
76
}
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 ();
131
77
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 );
134
90
}
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 );
143
91
}
144
-
92
+ $ this ->updateRangeFilters ($ searchCriteria );
93
+ $ this ->preparePriceAggregation ($ searchCriteria , $ includeAggregation );
145
94
if ($ isSearch ) {
146
95
$ this ->addFilter ($ searchCriteria , 'search_term ' , $ args ['search ' ]);
147
96
}
148
-
149
97
if (!$ searchCriteria ->getSortOrders ()) {
150
98
$ this ->addDefaultSortOrder ($ searchCriteria , $ args , $ isSearch );
151
99
}
152
-
153
100
$ this ->addEntityIdSort ($ searchCriteria );
154
101
$ this ->addVisibilityFilter ($ searchCriteria , $ isSearch , !empty ($ args ['filter ' ]['category_id ' ]));
155
102
156
- $ searchCriteria ->setCurrentPage ($ args ['currentPage ' ]);
157
- $ searchCriteria ->setPageSize ($ args ['pageSize ' ]);
158
-
159
103
return $ searchCriteria ;
160
104
}
161
105
@@ -164,7 +108,6 @@ public function build(array $args, bool $includeAggregation): SearchCriteriaInte
164
108
*
165
109
* @param string $requestName
166
110
* @param array $partialMatchFilters
167
- *
168
111
* @return void
169
112
*/
170
113
private function updateMatchTypeRequestConfig (string $ requestName , array $ partialMatchFilters ): void
@@ -184,7 +127,6 @@ private function updateMatchTypeRequestConfig(string $requestName, array $partia
184
127
* Check if and what type of match_type value was requested
185
128
*
186
129
* @param array $args
187
- *
188
130
* @return array
189
131
*/
190
132
private function getPartialMatchFilters (array $ args ): array
@@ -202,7 +144,6 @@ private function getPartialMatchFilters(array $args): array
202
144
* Remove the match_type to avoid search criteria containing it
203
145
*
204
146
* @param array $args
205
- *
206
147
* @return array
207
148
*/
208
149
private function removeMatchTypeFromArguments (array $ args ): array
@@ -254,7 +195,7 @@ private function addEntityIdSort(SearchCriteriaInterface $searchCriteria): void
254
195
}
255
196
256
197
$ sortOrderArray [] = $ this ->sortOrderBuilder
257
- ->setField ('_id ' )
198
+ ->setField ('entity_id ' )
258
199
->setDirection ($ sortDir )
259
200
->create ();
260
201
$ searchCriteria ->setSortOrders ($ sortOrderArray );
@@ -264,10 +205,21 @@ private function addEntityIdSort(SearchCriteriaInterface $searchCriteria): void
264
205
* Prepare price aggregation algorithm
265
206
*
266
207
* @param SearchCriteriaInterface $searchCriteria
208
+ * @param bool $includeAggregation
267
209
* @return void
268
210
*/
269
- private function preparePriceAggregation (SearchCriteriaInterface $ searchCriteria ): void
211
+ private function preparePriceAggregation (SearchCriteriaInterface $ searchCriteria, bool $ includeAggregation ): void
270
212
{
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
+
271
223
$ priceRangeCalculation = $ this ->scopeConfig ->getValue (
272
224
\Magento \Catalog \Model \Layer \Filter \Dynamic \AlgorithmFactory::XML_PATH_RANGE_CALCULATION ,
273
225
\Magento \Store \Model \ScopeInterface::SCOPE_STORE
@@ -319,7 +271,7 @@ private function addDefaultSortOrder(SearchCriteriaInterface $searchCriteria, ar
319
271
->setDirection (SortOrder::SORT_DESC )
320
272
->create ();
321
273
} else {
322
- $ categoryIdFilter = isset ( $ args ['filter ' ]['category_id ' ]) ? $ args [ ' filter ' ][ ' category_id ' ] : false ;
274
+ $ categoryIdFilter = $ args ['filter ' ]['category_id ' ] ?? false ;
323
275
if ($ categoryIdFilter ) {
324
276
if (!is_array ($ categoryIdFilter [array_key_first ($ categoryIdFilter )])
325
277
|| count ($ categoryIdFilter [array_key_first ($ categoryIdFilter )]) <= 1
0 commit comments