3
3
namespace Wilr \SilverStripe \Algolia \Service ;
4
4
5
5
use Algolia \AlgoliaSearch \Exceptions \NotFoundException ;
6
+ use Exception ;
6
7
use LogicException ;
7
8
use Psr \Log \LoggerInterface ;
8
9
use SilverStripe \Core \Injector \Injector ;
@@ -39,7 +40,11 @@ class AlgoliaIndexer
39
40
* @config
40
41
*/
41
42
private static $ attributes_blacklisted = [
42
- 'ID ' , 'Title ' , 'ClassName ' , 'LastEdited ' , 'Created '
43
+ 'ID ' ,
44
+ 'Title ' ,
45
+ 'ClassName ' ,
46
+ 'LastEdited ' ,
47
+ 'Created '
43
48
];
44
49
45
50
/**
@@ -61,7 +66,14 @@ class AlgoliaIndexer
61
66
public function indexItem ($ item )
62
67
{
63
68
$ searchIndexes = $ this ->getService ()->initIndexes ($ item );
64
- $ fields = $ this ->exportAttributesFromObject ($ item );
69
+
70
+ try {
71
+ $ fields = $ this ->exportAttributesFromObject ($ item );
72
+ } catch (Exception $ e ) {
73
+ Injector::inst ()->get (LoggerInterface::class)->error ($ e );
74
+
75
+ return false ;
76
+ }
65
77
66
78
if (method_exists ($ fields , 'toArray ' )) {
67
79
$ fields = $ fields ->toArray ();
@@ -196,86 +208,94 @@ public function exportAttributesFromObject($item)
196
208
$ specs = $ item ->config ()->get ('algolia_index_fields ' );
197
209
198
210
if ($ specs ) {
199
- $ maxFieldSize = $ this ->config ()->get ('max_field_size_bytes ' );
211
+ $ attributes = $ this ->addSpecsToAttributes ($ item , $ attributes , $ specs );
212
+ }
200
213
201
- foreach ($ specs as $ attributeName ) {
202
- if (in_array ($ attributeName , $ this ->config ()->get ('attributes_blacklisted ' ))) {
203
- continue ;
204
- }
214
+ $ item ->invokeWithExtensions ('updateAlgoliaAttributes ' , $ attributes );
205
215
206
- // fetch the db object, or fallback to the getters but prefer
207
- // the db object
208
- try {
209
- $ dbField = $ item ->relObject ($ attributeName );
210
- } catch (LogicException $ e ) {
211
- $ dbField = $ item ->{$ attributeName };
212
- }
216
+ return $ attributes ;
217
+ }
213
218
214
- if (!$ dbField ) {
215
- continue ;
216
- }
217
219
218
- if (is_string ($ dbField ) || is_array ($ dbField )) {
219
- $ attributes ->push ($ attributeName , $ dbField );
220
- } elseif ($ dbField instanceof DBForeignKey) {
221
- $ attributes ->push ($ attributeName , $ dbField ->Value );
222
- } elseif ($ dbField ->exists () || $ dbField instanceof DBBoolean) {
223
- if ($ dbField instanceof RelationList || $ dbField instanceof DataObject) {
224
- // has-many, many-many, has-one
225
- $ this ->exportAttributesFromRelationship ($ item , $ attributeName , $ attributes );
226
- } else {
227
- // db-field, if it's a date then use the timestamp since we need it
228
- $ hasContent = true ;
229
-
230
- switch (get_class ($ dbField )) {
231
- case DBDate::class:
232
- case DBDatetime::class:
233
- $ value = $ dbField ->getTimestamp ();
234
- break ;
235
- case DBBoolean::class:
236
- $ value = $ dbField ->getValue ();
237
- break ;
238
- case DBHTMLText::class:
239
- $ fieldData = $ dbField ->Plain ();
240
- $ fieldLength = mb_strlen ($ fieldData , '8bit ' );
241
-
242
- if ($ fieldLength > $ maxFieldSize ) {
243
- $ maxIterations = 100 ;
244
- $ i = 0 ;
245
-
246
- while ($ hasContent && $ i < $ maxIterations ) {
247
- $ block = mb_strcut (
248
- $ fieldData ,
249
- $ i * $ maxFieldSize ,
250
- $ maxFieldSize - 1
251
- );
252
-
253
- if ($ block ) {
254
- $ attributes ->push ($ attributeName . '_Block ' . $ i , $ block );
255
- } else {
256
- $ hasContent = false ;
257
- }
258
-
259
- $ i ++;
220
+ public function addSpecsToAttributes ($ item , $ attributes , $ specs )
221
+ {
222
+ $ maxFieldSize = $ this ->config ()->get ('max_field_size_bytes ' );
223
+
224
+ foreach ($ specs as $ attributeName ) {
225
+ if (in_array ($ attributeName , $ this ->config ()->get ('attributes_blacklisted ' ))) {
226
+ continue ;
227
+ }
228
+
229
+ // fetch the db object, or fallback to the getters but prefer
230
+ // the db object
231
+ try {
232
+ $ dbField = $ item ->relObject ($ attributeName );
233
+ } catch (LogicException $ e ) {
234
+ $ dbField = $ item ->{$ attributeName };
235
+ }
236
+
237
+ if (!$ dbField ) {
238
+ continue ;
239
+ }
240
+
241
+ if (is_string ($ dbField ) || is_array ($ dbField )) {
242
+ $ attributes ->push ($ attributeName , $ dbField );
243
+ } elseif ($ dbField instanceof DBForeignKey) {
244
+ $ attributes ->push ($ attributeName , $ dbField ->Value );
245
+ } elseif ($ dbField ->exists () || $ dbField instanceof DBBoolean) {
246
+ if ($ dbField instanceof RelationList || $ dbField instanceof DataObject) {
247
+ // has-many, many-many, has-one
248
+ $ this ->exportAttributesFromRelationship ($ item , $ attributeName , $ attributes );
249
+ } else {
250
+ // db-field, if it's a date then use the timestamp since we need it
251
+ $ hasContent = true ;
252
+
253
+ switch (get_class ($ dbField )) {
254
+ case DBDate::class:
255
+ case DBDatetime::class:
256
+ $ value = $ dbField ->getTimestamp ();
257
+ break ;
258
+ case DBBoolean::class:
259
+ $ value = $ dbField ->getValue ();
260
+ break ;
261
+ case DBHTMLText::class:
262
+ $ fieldData = $ dbField ->Plain ();
263
+ $ fieldLength = mb_strlen ($ fieldData , '8bit ' );
264
+
265
+ if ($ fieldLength > $ maxFieldSize ) {
266
+ $ maxIterations = 100 ;
267
+ $ i = 0 ;
268
+
269
+ while ($ hasContent && $ i < $ maxIterations ) {
270
+ $ block = mb_strcut (
271
+ $ fieldData ,
272
+ $ i * $ maxFieldSize ,
273
+ $ maxFieldSize - 1
274
+ );
275
+
276
+ if ($ block ) {
277
+ $ attributes ->push ($ attributeName . '_Block ' . $ i , $ block );
278
+ } else {
279
+ $ hasContent = false ;
260
280
}
261
- } else {
262
- $ value = $ fieldData ;
281
+
282
+ $ i ++ ;
263
283
}
264
- break ;
265
- default :
266
- $ value = @$ dbField ->forTemplate ();
267
- }
268
-
269
- if ($ hasContent ) {
270
- $ attributes ->push ($ attributeName , $ value );
271
- }
284
+ } else {
285
+ $ value = $ fieldData ;
286
+ }
287
+ break ;
288
+ default :
289
+ $ value = @$ dbField ->forTemplate ();
290
+ }
291
+
292
+ if ($ hasContent ) {
293
+ $ attributes ->push ($ attributeName , $ value );
272
294
}
273
295
}
274
296
}
275
297
}
276
298
277
- $ item ->invokeWithExtensions ('updateAlgoliaAttributes ' , $ attributes );
278
-
279
299
return $ attributes ;
280
300
}
281
301
0 commit comments