@@ -34,7 +34,8 @@ public function __construct(
34
34
{}
35
35
36
36
/**
37
- * @param int $storeId
37
+ * Return the configuration to be used for the store product index `attributesForFaceting`
38
+ * @param int $storeId - The store ID for the index to be configured
38
39
* @return string[]
39
40
* @throws LocalizedException
40
41
* @throws NoSuchEntityException
@@ -45,12 +46,13 @@ public function getAttributesForFaceting(int $storeId): array
45
46
function ($ facet ) {
46
47
return $ this ->decorateAttributeForFaceting ($ facet );
47
48
},
48
- $ this ->getRawFacets ($ storeId )
49
+ $ this ->addMerchandisingFacets ( $ storeId , $ this -> getRawFacets ($ storeId) )
49
50
);
50
51
}
51
52
52
53
/**
53
- * @param int $storeId
54
+ * Return the configuration to be used for the store product index `renderingContent`
55
+ * @param int $storeId - The store ID for the index to be configured
54
56
* @return array<string, array>|null
55
57
* @throws LocalizedException
56
58
* @throws NoSuchEntityException
@@ -73,6 +75,8 @@ public function getRenderingContent(int $storeId): ?array
73
75
}
74
76
75
77
/**
78
+ * For an array of facet data, return an array of attribute names only
79
+ *
76
80
* @param array<array<string, mixed>> $facets
77
81
* @return string[]
78
82
*/
@@ -87,8 +91,9 @@ function($facet) {
87
91
}
88
92
89
93
/**
94
+ * Format the facet data to be : renderingContent > facetOrdering > values
90
95
* @param string[] $attributes
91
- * @return array<string, array>
96
+ * @return array<string, array> - Array key is the attribute name and the value is an object containing a `sortRemainingBy` value
92
97
*/
93
98
protected function getRenderingContentValues (array $ attributes ): array
94
99
{
@@ -99,6 +104,7 @@ protected function getRenderingContentValues(array $attributes): array
99
104
}
100
105
101
106
/**
107
+ * Take raw facet (common) attributes and convert to include attributes specifically needed for `renderingContent`
102
108
* @param string[] $facets
103
109
* @return string[]
104
110
*/
@@ -107,7 +113,7 @@ protected function getRenderingContentAttributes(array $facets): array
107
113
return array_map (
108
114
function (string $ attribute ) {
109
115
if ($ attribute === self ::FACET_ATTRIBUTE_CATEGORIES ) {
110
- $ attribute = self :: FACET_ATTRIBUTE_CATEGORIES . ' .level0 ' ;
116
+ $ attribute = $ this -> getCategoryAttributeNameForRenderingContent () ;
111
117
}
112
118
return $ attribute ;
113
119
},
@@ -116,9 +122,23 @@ function(string $attribute) {
116
122
}
117
123
118
124
/**
125
+ * `renderingContent` cannot utilize the entire categories object but instead must reference a scalar value
126
+ * Obtaining the root level of the category data will enable it to become selectable in the Algolia Dashboard
127
+ * for "Facet Display" and "Order facets" within merchandising rules
128
+ *
129
+ * @return string
130
+ */
131
+ protected function getCategoryAttributeNameForRenderingContent (): string
132
+ {
133
+ return self ::FACET_ATTRIBUTE_CATEGORIES . '.level0 ' ;
134
+ }
135
+
136
+ /**
137
+ * Return an associative array for an attribute that mimics the minimum structure used by the Magento configuration
138
+ *
119
139
* @param string $attribute
120
140
* @param bool $searchable
121
- * @return array< string, string>
141
+ * @return array{attribute: string, searchable: string}
122
142
*/
123
143
protected function getRawFacet (string $ attribute , bool $ searchable = false ): array
124
144
{
@@ -129,7 +149,8 @@ protected function getRawFacet(string $attribute, bool $searchable = false): arr
129
149
}
130
150
131
151
/**
132
- * Generates common data to be used for both attributesForFaceting and renderingContent
152
+ * Generates common data to be used for both `attributesForFaceting` and `renderingContent`
153
+ *
133
154
* @return array<array<string, mixed>>
134
155
* @throws NoSuchEntityException
135
156
* @throws LocalizedException
@@ -155,26 +176,57 @@ function(string $attribute) {
155
176
}
156
177
}
157
178
158
- $ this ->facets [$ storeId ] = $ this ->addCategoryFacets ($ storeId , $ rawFacets );
179
+ $ this ->facets [$ storeId ] = $ this ->assertCategoryFacet ($ storeId , $ rawFacets );
180
+
159
181
return $ this ->facets [$ storeId ];
160
182
}
161
183
162
184
/**
185
+ * Does a given array of facets include a category facet?
186
+ *
187
+ * @param array<array<string, mixed>> $facets
188
+ * @return bool
189
+ */
190
+ protected function hasCategoryFacet (array $ facets ): bool
191
+ {
192
+ return !!array_filter ($ facets , function ($ facet ) {
193
+ return $ facet ['attribute ' ] === self ::FACET_ATTRIBUTE_CATEGORIES ;
194
+ });
195
+ }
196
+
197
+ /**
198
+ * Applies the category facet if not manually configured but necessary for category functionality
199
+ * (The presence of the category facet drives logic for `attributesForFaceting` and `renderingContent`)
200
+ *
163
201
* @param int $storeId
164
202
* @param array<array<string, mixed>> $facets
165
203
* @return array<array<string, mixed>>
166
204
*/
167
- protected function addCategoryFacets (int $ storeId , array $ facets ): array
205
+ protected function assertCategoryFacet (int $ storeId , array $ facets ): array
168
206
{
169
207
if ($ this ->configHelper ->replaceCategories ($ storeId )
170
- && !array_filter ($ facets , function ($ facet ) {
171
- return $ facet ['attribute ' ] === self ::FACET_ATTRIBUTE_CATEGORIES ;
172
- })
208
+ && !$ this ->hasCategoryFacet ($ facets )
173
209
) {
174
210
$ facets [] = $ this ->getRawFacet (self ::FACET_ATTRIBUTE_CATEGORIES );
175
211
}
176
212
177
- // Added for legacy merchandising features
213
+ return $ facets ;
214
+ }
215
+
216
+ /**
217
+ * Add merchandising facets as needed for `attributesForFaceting`
218
+ *
219
+ * @param int $storeId
220
+ * @param array<array<string, mixed>> $facets
221
+ * @return array|string[]
222
+ */
223
+ protected function addMerchandisingFacets (int $ storeId , array $ facets ): array
224
+ {
225
+ if ($ this ->hasCategoryFacet ($ facets )) {
226
+ $ facets [] = $ this ->getRawFacet ($ this ->getCategoryAttributeNameForRenderingContent ());
227
+ }
228
+
229
+ // Used for legacy merchandising features - always required!
178
230
$ facets [] = $ this ->getRawFacet (self ::FACET_ATTRIBUTES_CATEGORY_ID );
179
231
180
232
if ($ this ->configHelper ->isVisualMerchEnabled ($ storeId )) {
@@ -186,6 +238,8 @@ protected function addCategoryFacets(int $storeId, array $facets): array
186
238
}
187
239
188
240
/**
241
+ * Get an array of pricing attribute names based on currency and customer group configuration
242
+ *
189
243
* @param int $storeId
190
244
* @return string[]
191
245
* @throws NoSuchEntityException
@@ -204,6 +258,8 @@ protected function getPricingAttributes(int $storeId): array
204
258
}
205
259
206
260
/**
261
+ * Get an array of pricing attribute names based on customer group configuration
262
+ *
207
263
* @param int $storeId
208
264
* @param string $currencyCode
209
265
* @return string[]
@@ -229,6 +285,8 @@ protected function getGroupPricingAttributes(int $storeId, string $currencyCode)
229
285
230
286
231
287
/**
288
+ * Format the `attributesForFaceting` values based on modifiers defined at:
289
+ * https://www.algolia.com/doc/api-reference/api-parameters/attributesForFaceting/#modifiers
232
290
* @param array<string, string|int> $facet
233
291
* @return string
234
292
*/
0 commit comments