1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Return default results for searches on objects. |
5
|
|
|
* |
6
|
|
|
* @param unknown_type $hook |
7
|
|
|
* @param unknown_type $type |
8
|
|
|
* @param unknown_type $value |
9
|
|
|
* @param unknown_type $params |
10
|
|
|
* @return unknown_type |
11
|
|
|
*/ |
12
|
|
|
function elgg_solr_file_search($hook, $type, $value, $params) { |
13
|
|
|
|
14
|
|
|
$select = array( |
15
|
|
|
'start' => $params['offset'], |
16
|
|
|
'rows' => $params['limit'] ? $params['limit'] : 10, |
17
|
|
|
'fields' => array('id','title','description', 'score'), |
18
|
|
|
); |
19
|
|
|
|
20
|
|
View Code Duplication |
if ($params['select'] && is_array($params['select'])) { |
21
|
|
|
$select = array_merge($select, $params['select']); |
22
|
|
|
} |
23
|
|
|
|
24
|
|
|
// create a client instance |
25
|
|
|
$client = elgg_solr_get_client(); |
26
|
|
|
|
27
|
|
|
// get an update query instance |
28
|
|
|
$query = $client->createSelect($select); |
29
|
|
|
|
30
|
|
|
$default_sorts = array( |
31
|
|
|
'score' => 'desc', |
32
|
|
|
'time_created' => 'desc' |
33
|
|
|
); |
34
|
|
|
|
35
|
|
|
$sorts = $params['sorts'] ? $params['sorts'] : $default_sorts; |
36
|
|
|
$query->addSorts($sorts); |
37
|
|
|
|
38
|
|
|
$title_boost = elgg_solr_get_title_boost(); |
39
|
|
|
$description_boost = elgg_solr_get_description_boost(); |
40
|
|
|
|
41
|
|
|
// get the dismax component and set a boost query |
42
|
|
|
$dismax = $query->getEDisMax(); |
43
|
|
|
$qf = "title^{$title_boost} description^{$description_boost} attr_content^{$description_boost}"; |
44
|
|
|
if ($params['qf']) { |
45
|
|
|
$qf = $params['qf']; |
46
|
|
|
} |
47
|
|
|
$dismax->setQueryFields($qf); |
48
|
|
|
$dismax->setQueryAlternative('*:*'); |
49
|
|
|
|
50
|
|
|
|
51
|
|
|
$boostQuery = elgg_solr_get_boost_query(); |
52
|
|
|
if ($boostQuery) { |
53
|
|
|
$dismax->setBoostQuery($boostQuery); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
// this query is now a dismax query |
57
|
|
|
$query->setQuery($params['query']); |
58
|
|
|
|
59
|
|
|
|
60
|
|
|
$params['fq']['type'] = 'type:object'; |
61
|
|
|
$params['fq']['subtype'] = 'subtype:file'; |
62
|
|
|
|
63
|
|
|
$default_fq = elgg_solr_get_default_fq($params); |
64
|
|
View Code Duplication |
if ($params['fq']) { |
65
|
|
|
$filter_queries = array_merge($default_fq, $params['fq']); |
66
|
|
|
} |
67
|
|
|
else { |
68
|
|
|
$filter_queries = $default_fq; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
if (!empty($filter_queries)) { |
72
|
|
|
foreach ($filter_queries as $key => $value) { |
73
|
|
|
$query->createFilterQuery($key)->setQuery($value); |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
// get highlighting component and apply settings |
78
|
|
|
$hl = $query->getHighlighting(); |
79
|
|
|
$hlfields = array('title', 'attr_content', 'description'); |
80
|
|
|
if ($params['hlfields']) { |
81
|
|
|
$hlfields = $params['hlfields']; |
82
|
|
|
} |
83
|
|
|
$hl->setFields($hlfields); |
84
|
|
|
$hl->setSimplePrefix('<span data-hl="elgg-solr">'); |
85
|
|
|
$hl->setSimplePostfix('</span>'); |
86
|
|
|
|
87
|
|
|
$fragsize = elgg_solr_get_fragsize(); |
88
|
|
|
if (isset($params['fragsize'])) { |
89
|
|
|
$fragsize = (int) $params['fragsize']; |
90
|
|
|
} |
91
|
|
|
$hl->setFragSize($fragsize); |
92
|
|
|
|
93
|
|
|
|
94
|
|
|
// this executes the query and returns the result |
95
|
|
|
try { |
96
|
|
|
$resultset = $client->select($query); |
97
|
|
|
} catch (Exception $e) { |
98
|
|
|
error_log($e->getMessage()); |
99
|
|
|
return null; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
// Get the highlighted snippet |
103
|
|
|
try { |
104
|
|
|
$highlighting = $resultset->getHighlighting(); |
105
|
|
|
} catch (Exception $e) { |
106
|
|
|
error_log($e->getMessage()); |
107
|
|
|
return null; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
// Count the total number of documents found by solr |
111
|
|
|
$count = $resultset->getNumFound(); |
112
|
|
|
$hl_prefix = elgg_solr_get_hl_prefix(); |
113
|
|
|
$hl_suffix = elgg_solr_get_hl_suffix(); |
114
|
|
|
|
115
|
|
|
$search_results = array(); |
116
|
|
|
|
117
|
|
|
$config = HTMLPurifier_Config::createDefault(); |
118
|
|
|
$purifier = new HTMLPurifier($config); |
119
|
|
|
|
120
|
|
|
foreach ($resultset as $document) { |
121
|
|
|
$search_results[$document->id] = array(); |
122
|
|
|
$snippet = ''; |
123
|
|
|
|
124
|
|
|
// highlighting results can be fetched by document id (the field defined as uniquekey in this schema) |
125
|
|
|
$highlightedDoc = $highlighting->getResult($document->id); |
126
|
|
|
|
127
|
|
|
if($highlightedDoc){ |
128
|
|
|
foreach($highlightedDoc as $field => $highlight) { |
129
|
|
|
$snippet = implode(' (...) ', $highlight); |
130
|
|
|
// get our highlight based on the wrapped tokens |
131
|
|
|
// note, this is to prevent partial html from breaking page layouts |
132
|
|
|
preg_match_all('/<span data-hl="elgg-solr">(.*?)<\/span>/', $snippet, $match); |
133
|
|
|
|
134
|
|
|
if ($match[1]) { |
135
|
|
|
$matches = array_unique($match[1]); |
136
|
|
|
foreach ($matches as $m) { |
137
|
|
|
$snippet = str_replace($m, $hl_prefix . $m . $hl_suffix, $snippet); |
138
|
|
|
} |
139
|
|
|
$snippet = $purifier->purify($snippet); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
$search_results[$document->id][$field] = $snippet; |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
$search_results[$document->id]['score'] = $document->score; |
146
|
|
|
|
147
|
|
|
// normalize description with attr_content |
148
|
|
|
$search_results[$document->id]['description'] = trim($search_results[$document->id]['description'] . ' ' . $search_results[$document->id]['attr_content']); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
// get the entities in a single query |
152
|
|
|
// resort them into the order returned by solr by looping through $search_results |
153
|
|
|
$entities = array(); |
154
|
|
|
$entities_unsorted = array(); |
155
|
|
View Code Duplication |
if ($search_results) { |
|
|
|
|
156
|
|
|
$entities_unsorted = elgg_get_entities(array( |
157
|
|
|
'guids' => array_keys($search_results), |
158
|
|
|
'limit' => false |
159
|
|
|
)); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
$show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); |
163
|
|
View Code Duplication |
foreach ($search_results as $guid => $matches) { |
164
|
|
|
foreach ($entities_unsorted as $e) { |
165
|
|
|
if ($e->guid == $guid) { |
166
|
|
|
|
167
|
|
|
$desc_suffix = ''; |
168
|
|
|
if ($show_score == 'yes' && elgg_is_admin_logged_in()) { |
169
|
|
|
$desc_suffix .= elgg_view('output/longtext', array( |
170
|
|
|
'value' => elgg_echo('elgg_solr:relevancy', array($matches['score'])), |
171
|
|
|
'class' => 'elgg-subtext' |
172
|
|
|
)); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
|
176
|
|
|
if ($matches['title']) { |
177
|
|
|
$e->setVolatileData('search_matched_title', $matches['title']); |
178
|
|
|
} |
179
|
|
|
else { |
180
|
|
|
$e->setVolatileData('search_matched_title', $e->title); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
if ($matches['description']) { |
184
|
|
|
$desc = $matches['description']; |
185
|
|
|
} |
186
|
|
|
else { |
187
|
|
|
$desc = elgg_get_excerpt($e->description, 100); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
|
191
|
|
|
unset($matches['title']); |
192
|
|
|
unset($matches['description']); |
193
|
|
|
unset($matches['score']); |
194
|
|
|
$desc .= implode('...', $matches); |
195
|
|
|
|
196
|
|
|
$e->setVolatileData('search_matched_description', $desc . $desc_suffix); |
197
|
|
|
|
198
|
|
|
$entities[] = $e; |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
return array( |
204
|
|
|
'entities' => $entities, |
205
|
|
|
'count' => $count, |
206
|
|
|
); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
|
210
|
|
|
|
211
|
|
|
|
212
|
|
|
function elgg_solr_object_search($hook, $type, $return, $params) { |
213
|
|
|
|
214
|
|
|
$select = array( |
215
|
|
|
'start' => $params['offset'], |
216
|
|
|
'rows' => $params['limit'] ? $params['limit'] : 10, |
217
|
|
|
'fields' => array('id','title','description','score') |
218
|
|
|
); |
219
|
|
|
|
220
|
|
View Code Duplication |
if ($params['select'] && is_array($params['select'])) { |
221
|
|
|
$select = array_merge($select, $params['select']); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
// create a client instance |
225
|
|
|
$client = elgg_solr_get_client($select); |
|
|
|
|
226
|
|
|
|
227
|
|
|
// get an update query instance |
228
|
|
|
$query = $client->createSelect($select); |
229
|
|
|
|
230
|
|
|
$title_boost = elgg_solr_get_title_boost(); |
231
|
|
|
$description_boost = elgg_solr_get_description_boost(); |
232
|
|
|
|
233
|
|
|
// get the dismax component and set a boost query |
234
|
|
|
$dismax = $query->getEDisMax(); |
235
|
|
|
$qf = "title^{$title_boost} description^{$description_boost}"; |
236
|
|
|
if ($params['qf']) { |
237
|
|
|
$qf = $params['qf']; |
238
|
|
|
} |
239
|
|
|
$dismax->setQueryFields($qf); |
240
|
|
|
$dismax->setQueryAlternative('*:*'); |
241
|
|
|
|
242
|
|
|
$boostQuery = elgg_solr_get_boost_query(); |
243
|
|
|
if ($boostQuery) { |
244
|
|
|
$dismax->setBoostQuery($boostQuery); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
// this query is now a dismax query |
248
|
|
|
$query->setQuery($params['query']); |
249
|
|
|
|
250
|
|
|
$default_sorts = array( |
251
|
|
|
'score' => 'desc', |
252
|
|
|
'time_created' => 'desc' |
253
|
|
|
); |
254
|
|
|
|
255
|
|
|
$sorts = $params['sorts'] ? $params['sorts'] : $default_sorts; |
256
|
|
|
$query->addSorts($sorts); |
257
|
|
|
|
258
|
|
|
// make sure we're only getting objectss |
259
|
|
|
$params['fq']['type'] = 'type:object'; |
260
|
|
|
|
261
|
|
|
$default_fq = elgg_solr_get_default_fq($params); |
262
|
|
View Code Duplication |
if ($params['fq']) { |
263
|
|
|
$filter_queries = array_merge($default_fq, $params['fq']); |
264
|
|
|
} |
265
|
|
|
else { |
266
|
|
|
$filter_queries = $default_fq; |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
if (!empty($filter_queries)) { |
270
|
|
|
foreach ($filter_queries as $key => $value) { |
271
|
|
|
$query->createFilterQuery($key)->setQuery($value); |
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
// get highlighting component and apply settings |
276
|
|
|
$hl = $query->getHighlighting(); |
277
|
|
|
$hlfields = array('title', 'description'); |
278
|
|
|
if ($params['hlfields']) { |
279
|
|
|
$hlfields = $params['hlfields']; |
280
|
|
|
} |
281
|
|
|
$hl->setFields($hlfields); |
282
|
|
|
$hl->setSimplePrefix('<span data-hl="elgg-solr">'); |
283
|
|
|
$hl->setSimplePostfix('</span>'); |
284
|
|
|
|
285
|
|
|
$fragsize = elgg_solr_get_fragsize(); |
286
|
|
|
if (isset($params['fragsize'])) { |
287
|
|
|
$fragsize = (int) $params['fragsize']; |
288
|
|
|
} |
289
|
|
|
$hl->setFragSize($fragsize); |
290
|
|
|
|
291
|
|
|
|
292
|
|
|
// this executes the query and returns the result |
293
|
|
|
try { |
294
|
|
|
$resultset = $client->select($query); |
295
|
|
|
} catch (Exception $e) { |
296
|
|
|
error_log($e->getMessage()); |
297
|
|
|
return null; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
// Get the highlighted snippet |
301
|
|
|
try { |
302
|
|
|
$highlighting = $resultset->getHighlighting(); |
303
|
|
|
} catch (Exception $e) { |
304
|
|
|
error_log($e->getMessage()); |
305
|
|
|
return null; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
// Count the total number of documents found by solr |
309
|
|
|
$count = $resultset->getNumFound(); |
310
|
|
|
$hl_prefix = elgg_solr_get_hl_prefix(); |
311
|
|
|
$hl_suffix = elgg_solr_get_hl_suffix(); |
312
|
|
|
|
313
|
|
|
$config = HTMLPurifier_Config::createDefault(); |
314
|
|
|
$purifier = new HTMLPurifier($config); |
315
|
|
|
|
316
|
|
|
$search_results = array(); |
317
|
|
View Code Duplication |
foreach ($resultset as $document) { |
318
|
|
|
$search_results[$document->id] = array(); |
319
|
|
|
$snippet = ''; |
320
|
|
|
|
321
|
|
|
// highlighting results can be fetched by document id (the field defined as uniquekey in this schema) |
322
|
|
|
$highlightedDoc = $highlighting->getResult($document->id); |
323
|
|
|
|
324
|
|
|
if($highlightedDoc){ |
325
|
|
|
foreach($highlightedDoc as $field => $highlight) { |
326
|
|
|
$snippet = implode(' (...) ', $highlight); |
327
|
|
|
// get our highlight based on the wrapped tokens |
328
|
|
|
// note, this is to prevent partial html from breaking page layouts |
329
|
|
|
preg_match_all('/<span data-hl="elgg-solr">(.*?)<\/span>/', $snippet, $match); |
330
|
|
|
|
331
|
|
|
if ($match[1]) { |
332
|
|
|
$matches = array_unique($match[1]); |
333
|
|
|
foreach ($matches as $m) { |
334
|
|
|
$snippet = str_replace($m, $hl_prefix . $m . $hl_suffix, $snippet); |
335
|
|
|
} |
336
|
|
|
$snippet = $purifier->purify($snippet); |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
$search_results[$document->id][$field] = $snippet; |
340
|
|
|
} |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
$search_results[$document->id]['score'] = $document->score; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
// get the entities |
347
|
|
|
$entities = array(); |
348
|
|
|
$entities_unsorted = array(); |
349
|
|
View Code Duplication |
if ($search_results) { |
|
|
|
|
350
|
|
|
$entities_unsorted = elgg_get_entities(array( |
351
|
|
|
'guids' => array_keys($search_results), |
352
|
|
|
'limit' => false |
353
|
|
|
)); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
$show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); |
357
|
|
View Code Duplication |
foreach ($search_results as $guid => $matches) { |
358
|
|
|
foreach ($entities_unsorted as $e) { |
359
|
|
|
|
360
|
|
|
$desc_suffix = ''; |
361
|
|
|
if ($show_score == 'yes' && elgg_is_admin_logged_in()) { |
362
|
|
|
$desc_suffix .= elgg_view('output/longtext', array( |
363
|
|
|
'value' => elgg_echo('elgg_solr:relevancy', array($matches['score'])), |
364
|
|
|
'class' => 'elgg-subtext' |
365
|
|
|
)); |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
if ($e->guid == $guid) { |
369
|
|
|
if ($matches['title']) { |
370
|
|
|
$e->setVolatileData('search_matched_title', $matches['title']); |
371
|
|
|
} |
372
|
|
|
else { |
373
|
|
|
$e->setVolatileData('search_matched_title', $e->title); |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
if ($matches['description']) { |
377
|
|
|
$desc = $matches['description']; |
378
|
|
|
} |
379
|
|
|
else { |
380
|
|
|
$desc = elgg_get_excerpt($e->description, 100); |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
unset($matches['title']); |
384
|
|
|
unset($matches['description']); |
385
|
|
|
unset($matches['score']); |
386
|
|
|
$desc .= implode('...', $matches); |
387
|
|
|
|
388
|
|
|
$e->setVolatileData('search_matched_description', $desc . $desc_suffix); |
389
|
|
|
$entities[] = $e; |
390
|
|
|
} |
391
|
|
|
} |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
return array( |
395
|
|
|
'entities' => $entities, |
396
|
|
|
'count' => $count, |
397
|
|
|
); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
|
401
|
|
|
|
402
|
|
|
function elgg_solr_user_search($hook, $type, $return, $params) { |
403
|
|
|
|
404
|
|
|
$select = array( |
405
|
|
|
'start' => $params['offset'], |
406
|
|
|
'rows' => $params['limit'] ? $params['limit'] : 10, |
407
|
|
|
'fields' => array('id','name','username', 'description', 'score') |
408
|
|
|
); |
409
|
|
|
|
410
|
|
|
if( $params['user_type'] ){ |
411
|
|
|
$select['fields'][] = 'user_type'; |
412
|
|
|
} |
413
|
|
|
|
414
|
|
View Code Duplication |
if ($params['select'] && is_array($params['select'])) { |
415
|
|
|
$select = array_merge($select, $params['select']); |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
// create a client instance |
419
|
|
|
$client = elgg_solr_get_client(); |
420
|
|
|
|
421
|
|
|
// get an update query instance |
422
|
|
|
$query = $client->createSelect($select); |
423
|
|
|
|
424
|
|
|
$default_sorts = array( |
425
|
|
|
'score' => 'desc', |
426
|
|
|
'time_created' => 'desc' |
427
|
|
|
); |
428
|
|
|
|
429
|
|
|
$sorts = $params['sorts'] ? $params['sorts'] : $default_sorts; |
430
|
|
|
$query->addSorts($sorts); |
431
|
|
|
|
432
|
|
|
$title_boost = elgg_solr_get_title_boost(); |
433
|
|
|
$description_boost = elgg_solr_get_description_boost(); |
434
|
|
|
|
435
|
|
|
// get the dismax component and set a boost query |
436
|
|
|
$dismax = $query->getEDisMax(); |
437
|
|
|
$qf = "name^{$title_boost} username^{$title_boost} description^{$description_boost}"; |
438
|
|
|
|
439
|
|
|
if( $params['user_type'] ){ |
440
|
|
|
$qf .= " user_type^{$title_boost}"; |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
if ($params['qf']) { |
444
|
|
|
$qf = $params['qf']; |
445
|
|
|
} |
446
|
|
|
$dismax->setQueryFields($qf); |
447
|
|
|
$dismax->setQueryAlternative('*:*'); |
448
|
|
|
|
449
|
|
|
// no time boost for users |
450
|
|
|
/* |
451
|
|
|
$boostQuery = elgg_solr_get_boost_query(); |
452
|
|
|
if ($boostQuery) { |
453
|
|
|
$dismax->setBoostQuery($boostQuery); |
454
|
|
|
} |
455
|
|
|
* |
456
|
|
|
*/ |
457
|
|
|
|
458
|
|
|
// this query is now a dismax query |
459
|
|
|
$query->setQuery($params['query']); |
460
|
|
|
|
461
|
|
|
// make sure we're only getting users |
462
|
|
|
$params['fq']['type'] = 'type:user'; |
463
|
|
|
|
464
|
|
|
if( $params['user_type'] ){ |
465
|
|
|
$params['fq']['user_type'] = 'user_type:"' . $params['user_type'] . '"'; |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
$default_fq = elgg_solr_get_default_fq($params); |
469
|
|
View Code Duplication |
if ($params['fq']) { |
470
|
|
|
$filter_queries = array_merge($default_fq, $params['fq']); |
471
|
|
|
} |
472
|
|
|
else { |
473
|
|
|
$filter_queries = $default_fq; |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
if (!empty($filter_queries)) { |
477
|
|
|
foreach ($filter_queries as $key => $value) { |
478
|
|
|
$query->createFilterQuery($key)->setQuery($value); |
479
|
|
|
} |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
// get highlighting component and apply settings |
483
|
|
|
$hl = $query->getHighlighting(); |
484
|
|
|
$hlfields = array('name', 'username', 'description'); |
485
|
|
|
if ($params['hlfields']) { |
486
|
|
|
$hlfields = $params['hlfields']; |
487
|
|
|
} |
488
|
|
|
$hl->setFields($hlfields); |
489
|
|
|
$hl->setSimplePrefix('<span data-hl="elgg-solr">'); |
490
|
|
|
$hl->setSimplePostfix('</span>'); |
491
|
|
|
|
492
|
|
|
$fragsize = elgg_solr_get_fragsize(); |
493
|
|
|
if (isset($params['fragsize'])) { |
494
|
|
|
$fragsize = (int) $params['fragsize']; |
495
|
|
|
} |
496
|
|
|
$hl->setFragSize($fragsize); |
497
|
|
|
|
498
|
|
|
// this executes the query and returns the result |
499
|
|
|
try { |
500
|
|
|
$resultset = $client->select($query); |
501
|
|
|
} catch (Exception $e) { |
502
|
|
|
error_log($e->getMessage()); |
503
|
|
|
return null; |
504
|
|
|
} |
505
|
|
|
|
506
|
|
|
// Get the highlighted snippet |
507
|
|
|
try { |
508
|
|
|
$highlighting = $resultset->getHighlighting(); |
509
|
|
|
} catch (Exception $e) { |
510
|
|
|
error_log($e->getMessage()); |
511
|
|
|
return null; |
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
// Count the total number of documents found by solr |
515
|
|
|
$count = $resultset->getNumFound(); |
516
|
|
|
$hl_prefix = elgg_solr_get_hl_prefix(); |
517
|
|
|
$hl_suffix = elgg_solr_get_hl_suffix(); |
518
|
|
|
|
519
|
|
|
$search_results = array(); |
520
|
|
|
|
521
|
|
|
$config = HTMLPurifier_Config::createDefault(); |
522
|
|
|
$purifier = new HTMLPurifier($config); |
523
|
|
|
|
524
|
|
View Code Duplication |
foreach ($resultset as $document) { |
525
|
|
|
$search_results[$document->id] = array(); |
526
|
|
|
$snippet = ''; |
527
|
|
|
|
528
|
|
|
// highlighting results can be fetched by document id (the field defined as uniquekey in this schema) |
529
|
|
|
$highlightedDoc = $highlighting->getResult($document->id); |
530
|
|
|
|
531
|
|
|
if($highlightedDoc){ |
532
|
|
|
foreach($highlightedDoc as $field => $highlight) { |
533
|
|
|
$snippet = implode(' (...) ', $highlight); |
534
|
|
|
// get our highlight based on the wrapped tokens |
535
|
|
|
// note, this is to prevent partial html from breaking page layouts |
536
|
|
|
preg_match_all('/<span data-hl="elgg-solr">(.*?)<\/span>/', $snippet, $match); |
537
|
|
|
|
538
|
|
|
if ($match[1]) { |
539
|
|
|
$matches = array_unique($match[1]); |
540
|
|
|
foreach ($matches as $m) { |
541
|
|
|
$snippet = str_replace($m, $hl_prefix . $m . $hl_suffix, $snippet); |
542
|
|
|
} |
543
|
|
|
$snippet = $purifier->purify($snippet); |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
$search_results[$document->id][$field] = $snippet; |
547
|
|
|
} |
548
|
|
|
} |
549
|
|
|
$search_results[$document->id]['score'] = $document->score; |
550
|
|
|
} |
551
|
|
|
|
552
|
|
|
// get the entities |
553
|
|
|
$entities = array(); |
554
|
|
|
$entities_unsorted = array(); |
555
|
|
View Code Duplication |
if ($search_results) { |
|
|
|
|
556
|
|
|
$entities_unsorted = elgg_get_entities(array( |
557
|
|
|
'guids' => array_keys($search_results), |
558
|
|
|
'limit' => false |
559
|
|
|
)); |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
$show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); |
563
|
|
|
foreach ($search_results as $guid => $matches) { |
564
|
|
|
foreach ($entities_unsorted as $e) { |
565
|
|
|
if ($e->guid == $guid) { |
566
|
|
|
|
567
|
|
|
$desc_suffix = ''; |
568
|
|
|
if ($show_score == 'yes' && elgg_is_admin_logged_in()) { |
569
|
|
|
$desc_suffix .= elgg_view('output/longtext', array( |
570
|
|
|
'value' => elgg_echo('elgg_solr:relevancy', array($matches['score'])), |
571
|
|
|
'class' => 'elgg-subtext' |
572
|
|
|
)); |
573
|
|
|
} |
574
|
|
|
|
575
|
|
|
if ($matches['name']) { |
576
|
|
|
$name = $matches['name']; |
577
|
|
View Code Duplication |
if ($matches['username']) { |
578
|
|
|
$name .= ' (@' . $matches['username'] . ')'; |
579
|
|
|
} |
580
|
|
|
else { |
581
|
|
|
$name .= ' (@' . $e->username . ')'; |
582
|
|
|
} |
583
|
|
|
$e->setVolatileData('search_matched_name', $name); |
584
|
|
|
$e->setVolatileData('search_matched_title', $name); |
585
|
|
|
} |
586
|
|
|
else { |
587
|
|
|
$name = $e->name; |
588
|
|
View Code Duplication |
if ($matches['username']) { |
589
|
|
|
$name .= ' (@' . $matches['username'] . ')'; |
590
|
|
|
} |
591
|
|
|
else { |
592
|
|
|
$name .= ' (@' . $e->username . ')'; |
593
|
|
|
} |
594
|
|
|
$e->setVolatileData('search_matched_name', $name); |
595
|
|
|
$e->setVolatileData('search_matched_title', $name); |
596
|
|
|
} |
597
|
|
|
|
598
|
|
|
// anything not already matched can be lumped in with the description |
599
|
|
|
unset($matches['name']); |
600
|
|
|
unset($matches['username']); |
601
|
|
|
unset($matches['score']); |
602
|
|
|
$desc_suffix .= implode('...', $matches); |
603
|
|
|
|
604
|
|
|
$desc_hl = search_get_highlighted_relevant_substrings($e->description, $params['query']); |
605
|
|
|
$e->setVolatileData('search_matched_description', $desc_hl . $desc_suffix); |
606
|
|
|
$entities[] = $e; |
607
|
|
|
} |
608
|
|
|
} |
609
|
|
|
} |
610
|
|
|
|
611
|
|
|
return array( |
612
|
|
|
'entities' => $entities, |
613
|
|
|
'count' => $count, |
614
|
|
|
); |
615
|
|
|
} |
616
|
|
|
|
617
|
|
|
|
618
|
|
|
|
619
|
|
|
function elgg_solr_group_search($hook, $type, $return, $params) { |
620
|
|
|
|
621
|
|
|
$select = array( |
622
|
|
|
'start' => $params['offset'], |
623
|
|
|
'rows' => $params['limit'] ? $params['limit'] : 10, |
624
|
|
|
'fields' => array('id','name','description', 'score') |
625
|
|
|
); |
626
|
|
|
|
627
|
|
View Code Duplication |
if ($params['select'] && is_array($params['select'])) { |
628
|
|
|
$select = array_merge($select, $params['select']); |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
// create a client instance |
632
|
|
|
$client = elgg_solr_get_client(); |
633
|
|
|
|
634
|
|
|
// get an update query instance |
635
|
|
|
$query = $client->createSelect($select); |
636
|
|
|
|
637
|
|
|
$default_sorts = array( |
638
|
|
|
'score' => 'desc', |
639
|
|
|
'time_created' => 'desc' |
640
|
|
|
); |
641
|
|
|
|
642
|
|
|
$sorts = $params['sorts'] ? $params['sorts'] : $default_sorts; |
643
|
|
|
$query->addSorts($sorts); |
644
|
|
|
|
645
|
|
|
$title_boost = elgg_solr_get_title_boost(); |
646
|
|
|
$description_boost = elgg_solr_get_description_boost(); |
647
|
|
|
|
648
|
|
|
// get the dismax component and set a boost query |
649
|
|
|
$dismax = $query->getEDisMax(); |
650
|
|
|
$qf = "name^{$title_boost} description^{$description_boost}"; |
651
|
|
|
if ($params['qf']) { |
652
|
|
|
$qf = $params['qf']; |
653
|
|
|
} |
654
|
|
|
$dismax->setQueryFields($qf); |
655
|
|
|
$dismax->setQueryAlternative('*:*'); |
656
|
|
|
|
657
|
|
|
$boostQuery = elgg_solr_get_boost_query(); |
658
|
|
|
if ($boostQuery) { |
659
|
|
|
$dismax->setBoostQuery($boostQuery); |
660
|
|
|
} |
661
|
|
|
|
662
|
|
|
// this query is now a dismax query |
663
|
|
|
$query->setQuery($params['query']); |
664
|
|
|
|
665
|
|
|
// make sure we're only getting groups |
666
|
|
|
$params['fq']['type'] = 'type:group'; |
667
|
|
|
|
668
|
|
|
$default_fq = elgg_solr_get_default_fq($params); |
669
|
|
View Code Duplication |
if ($params['fq']) { |
670
|
|
|
$filter_queries = array_merge($default_fq, $params['fq']); |
671
|
|
|
} |
672
|
|
|
else { |
673
|
|
|
$filter_queries = $default_fq; |
674
|
|
|
} |
675
|
|
|
|
676
|
|
|
if (!empty($filter_queries)) { |
677
|
|
|
foreach ($filter_queries as $key => $value) { |
678
|
|
|
$query->createFilterQuery($key)->setQuery($value); |
679
|
|
|
} |
680
|
|
|
} |
681
|
|
|
|
682
|
|
|
// get highlighting component and apply settings |
683
|
|
|
$hl = $query->getHighlighting(); |
684
|
|
|
$hlfields = array('name', 'description'); |
685
|
|
|
if ($params['hlfields']) { |
686
|
|
|
$hlfields = $params['hlfields']; |
687
|
|
|
} |
688
|
|
|
$hl->setFields($hlfields); |
689
|
|
|
$hl->setSimplePrefix('<span data-hl="elgg-solr">'); |
690
|
|
|
$hl->setSimplePostfix('</span>'); |
691
|
|
|
|
692
|
|
|
$fragsize = elgg_solr_get_fragsize(); |
693
|
|
|
if (isset($params['fragsize'])) { |
694
|
|
|
$fragsize = (int) $params['fragsize']; |
695
|
|
|
} |
696
|
|
|
$hl->setFragSize($fragsize); |
697
|
|
|
|
698
|
|
|
|
699
|
|
|
// this executes the query and returns the result |
700
|
|
|
try { |
701
|
|
|
$resultset = $client->select($query); |
702
|
|
|
} catch (Exception $e) { |
703
|
|
|
error_log($e->getMessage()); |
704
|
|
|
return null; |
705
|
|
|
} |
706
|
|
|
|
707
|
|
|
// Get the highlighted snippet |
708
|
|
|
try { |
709
|
|
|
$highlighting = $resultset->getHighlighting(); |
710
|
|
|
} catch (Exception $e) { |
711
|
|
|
error_log($e->getMessage()); |
712
|
|
|
return null; |
713
|
|
|
} |
714
|
|
|
|
715
|
|
|
// Count the total number of documents found by solr |
716
|
|
|
$count = $resultset->getNumFound(); |
717
|
|
|
$hl_prefix = elgg_solr_get_hl_prefix(); |
718
|
|
|
$hl_suffix = elgg_solr_get_hl_suffix(); |
719
|
|
|
|
720
|
|
|
$search_results = array(); |
721
|
|
|
|
722
|
|
|
$config = HTMLPurifier_Config::createDefault(); |
723
|
|
|
$purifier = new HTMLPurifier($config); |
724
|
|
|
|
725
|
|
View Code Duplication |
foreach ($resultset as $document) { |
726
|
|
|
$search_results[$document->id] = array(); |
727
|
|
|
$snippet = ''; |
728
|
|
|
|
729
|
|
|
// highlighting results can be fetched by document id (the field defined as uniquekey in this schema) |
730
|
|
|
$highlightedDoc = $highlighting->getResult($document->id); |
731
|
|
|
|
732
|
|
|
if($highlightedDoc){ |
733
|
|
|
foreach($highlightedDoc as $field => $highlight) { |
734
|
|
|
$snippet = implode(' (...) ', $highlight); |
735
|
|
|
// get our highlight based on the wrapped tokens |
736
|
|
|
// note, this is to prevent partial html from breaking page layouts |
737
|
|
|
preg_match_all('/<span data-hl="elgg-solr">(.*?)<\/span>/', $snippet, $match); |
738
|
|
|
|
739
|
|
|
if ($match[1]) { |
740
|
|
|
$matches = array_unique($match[1]); |
741
|
|
|
foreach ($matches as $m) { |
742
|
|
|
$snippet = str_replace($m, $hl_prefix . $m . $hl_suffix, $snippet); |
743
|
|
|
} |
744
|
|
|
$snippet = $purifier->purify($snippet); |
745
|
|
|
} |
746
|
|
|
|
747
|
|
|
$search_results[$document->id][$field] = $snippet; |
748
|
|
|
} |
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
$search_results[$document->id]['score'] = $document->score; |
752
|
|
|
} |
753
|
|
|
|
754
|
|
|
// get the entities |
755
|
|
|
$entities = array(); |
756
|
|
|
$entities_unsorted = array(); |
757
|
|
View Code Duplication |
if ($search_results) { |
|
|
|
|
758
|
|
|
$entities_unsorted = elgg_get_entities(array( |
759
|
|
|
'guids' => array_keys($search_results), |
760
|
|
|
'limit' => false |
761
|
|
|
)); |
762
|
|
|
} |
763
|
|
|
|
764
|
|
|
$show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); |
765
|
|
|
foreach ($search_results as $guid => $matches) { |
766
|
|
|
foreach ($entities_unsorted as $e) { |
767
|
|
|
|
768
|
|
|
$desc_suffix = ''; |
769
|
|
|
if ($show_score == 'yes' && elgg_is_admin_logged_in()) { |
770
|
|
|
$desc_suffix .= elgg_view('output/longtext', array( |
771
|
|
|
'value' => elgg_echo('elgg_solr:relevancy', array($matches['score'])), |
772
|
|
|
'class' => 'elgg-subtext' |
773
|
|
|
)); |
774
|
|
|
} |
775
|
|
|
|
776
|
|
|
if ($e->guid == $guid) { |
777
|
|
|
if ($matches['name']) { |
778
|
|
|
$name = $matches['name']; |
779
|
|
|
$e->setVolatileData('search_matched_name', $name); |
780
|
|
|
$e->setVolatileData('search_matched_title', $name); |
781
|
|
|
} |
782
|
|
|
else { |
783
|
|
|
$name = $e->name; |
784
|
|
|
$e->setVolatileData('search_matched_name', $name); |
785
|
|
|
$e->setVolatileData('search_matched_title', $name); |
786
|
|
|
} |
787
|
|
|
|
788
|
|
|
if ($matches['description']) { |
789
|
|
|
$desc = $matches['description']; |
790
|
|
|
} |
791
|
|
|
else { |
792
|
|
|
$desc = search_get_highlighted_relevant_substrings($e->description, $params['query']); |
793
|
|
|
} |
794
|
|
|
|
795
|
|
|
|
796
|
|
|
unset($matches['name']); |
797
|
|
|
unset($matches['description']); |
798
|
|
|
unset($matches['score']); |
799
|
|
|
$desc .= implode('...', $matches); |
800
|
|
|
|
801
|
|
|
$e->setVolatileData('search_matched_description', $desc . $desc_suffix); |
802
|
|
|
|
803
|
|
|
$entities[] = $e; |
804
|
|
|
} |
805
|
|
|
} |
806
|
|
|
} |
807
|
|
|
|
808
|
|
|
return array( |
809
|
|
|
'entities' => $entities, |
810
|
|
|
'count' => $count, |
811
|
|
|
); |
812
|
|
|
} |
813
|
|
|
|
814
|
|
|
|
815
|
|
|
function elgg_solr_user_settings_save($hook, $type, $return, $params) { |
816
|
|
|
$user_guid = (int) get_input('guid'); |
817
|
|
|
$user = get_user($user_guid); |
818
|
|
|
|
819
|
|
|
if (!$user) { |
820
|
|
|
return $return; |
821
|
|
|
} |
822
|
|
|
|
823
|
|
|
$guids = elgg_get_config('elgg_solr_sync'); |
824
|
|
|
if (!is_array($guids)) { |
825
|
|
|
$guids = array(); |
826
|
|
|
} |
827
|
|
|
$guids[$user->guid] = 1; // use key to keep it unique |
828
|
|
|
|
829
|
|
|
elgg_set_config('elgg_solr_sync', $guids); |
830
|
|
|
|
831
|
|
|
return $return; |
832
|
|
|
} |
833
|
|
|
|
834
|
|
|
|
835
|
|
|
|
836
|
|
|
function elgg_solr_tag_search($hook, $type, $return, $params) { |
837
|
|
|
|
838
|
|
|
$valid_tag_names = elgg_get_registered_tag_metadata_names(); |
839
|
|
|
|
840
|
|
|
if (!$valid_tag_names || !is_array($valid_tag_names)) { |
|
|
|
|
841
|
|
|
return array('entities' => array(), 'count' => 0); |
842
|
|
|
} |
843
|
|
|
|
844
|
|
|
// if passed a tag metadata name, only search on that tag name. |
845
|
|
|
// tag_name isn't included in the params because it's specific to |
846
|
|
|
// tag searches. |
847
|
|
View Code Duplication |
if ($tag_names = get_input('tag_names')) { |
848
|
|
|
if (is_array($tag_names)) { |
849
|
|
|
$search_tag_names = $tag_names; |
850
|
|
|
} else { |
851
|
|
|
$search_tag_names = array($tag_names); |
852
|
|
|
} |
853
|
|
|
|
854
|
|
|
// check these are valid to avoid arbitrary metadata searches. |
855
|
|
|
foreach ($search_tag_names as $i => $tag_name) { |
856
|
|
|
if (!in_array($tag_name, $valid_tag_names)) { |
857
|
|
|
unset($search_tag_names[$i]); |
858
|
|
|
} |
859
|
|
|
} |
860
|
|
|
} else { |
861
|
|
|
$search_tag_names = $valid_tag_names; |
862
|
|
|
} |
863
|
|
|
|
864
|
|
|
$query_parts = array(); |
865
|
|
|
foreach ($search_tag_names as $tagname) { |
866
|
|
|
// @note - these need to be treated as literal exact matches, so encapsulate in double-quotes |
867
|
|
|
$query_parts[] = 'tags:"' . elgg_solr_escape_special_chars($tagname . '%%' . $params['query']) . '"'; |
868
|
|
|
} |
869
|
|
|
|
870
|
|
|
if (!$query_parts) { |
|
|
|
|
871
|
|
|
return array('entities' => array(), 'count' => 0); |
872
|
|
|
} |
873
|
|
|
|
874
|
|
|
$q = implode(' OR ', $query_parts); |
875
|
|
|
|
876
|
|
|
$select = array( |
877
|
|
|
'query' => $q, |
878
|
|
|
'start' => $params['offset'], |
879
|
|
|
'rows' => $params['limit'], |
880
|
|
|
'fields' => array('id','title','description','score') |
881
|
|
|
); |
882
|
|
|
|
883
|
|
View Code Duplication |
if ($params['select'] && is_array($params['select'])) { |
884
|
|
|
$select = array_merge($select, $params['select']); |
885
|
|
|
} |
886
|
|
|
|
887
|
|
|
$client = elgg_solr_get_client(); |
888
|
|
|
// get an update query instance |
889
|
|
|
$query = $client->createSelect($select); |
890
|
|
|
|
891
|
|
|
$default_sorts = array( |
892
|
|
|
'score' => 'desc', |
893
|
|
|
'time_created' => 'desc' |
894
|
|
|
); |
895
|
|
|
|
896
|
|
|
$sorts = $params['sorts'] ? $params['sorts'] : $default_sorts; |
897
|
|
|
$query->addSorts($sorts); |
898
|
|
|
|
899
|
|
|
$default_fq = elgg_solr_get_default_fq($params); |
900
|
|
View Code Duplication |
if ($params['fq']) { |
901
|
|
|
$filter_queries = array_merge($default_fq, $params['fq']); |
902
|
|
|
} |
903
|
|
|
else { |
904
|
|
|
$filter_queries = $default_fq; |
905
|
|
|
} |
906
|
|
|
|
907
|
|
|
if (!empty($filter_queries)) { |
908
|
|
|
foreach ($filter_queries as $key => $value) { |
909
|
|
|
$query->createFilterQuery($key)->setQuery($value); |
910
|
|
|
} |
911
|
|
|
} |
912
|
|
|
|
913
|
|
|
// get highlighting component and apply settings |
914
|
|
|
$hl = $query->getHighlighting(); |
915
|
|
|
$hl->setFields(array('tags')); |
916
|
|
|
$hl->setSimplePrefix('<span data-hl="elgg-solr">'); |
917
|
|
|
$hl->setSimplePostfix('</span>'); |
918
|
|
|
|
919
|
|
|
// this executes the query and returns the result |
920
|
|
|
try { |
921
|
|
|
$resultset = $client->select($query); |
922
|
|
|
} catch (Exception $e) { |
923
|
|
|
error_log($e->getMessage()); |
924
|
|
|
return null; |
925
|
|
|
} |
926
|
|
|
|
927
|
|
|
// Get the highlighted snippet |
928
|
|
|
try { |
929
|
|
|
$highlighting = $resultset->getHighlighting(); |
930
|
|
|
} catch (Exception $e) { |
931
|
|
|
error_log($e->getMessage()); |
932
|
|
|
return null; |
933
|
|
|
} |
934
|
|
|
|
935
|
|
|
// Count the total number of documents found by solr |
936
|
|
|
$count = $resultset->getNumFound(); |
937
|
|
|
$hl_prefix = elgg_solr_get_hl_prefix(); |
938
|
|
|
$hl_suffix = elgg_solr_get_hl_suffix(); |
939
|
|
|
|
940
|
|
|
$search_results = array(); |
941
|
|
|
|
942
|
|
|
$config = HTMLPurifier_Config::createDefault(); |
943
|
|
|
$purifier = new HTMLPurifier($config); |
944
|
|
|
|
945
|
|
|
foreach ($resultset as $document) { |
946
|
|
|
$search_results[$document->id] = array(); |
947
|
|
|
$snippet = ''; |
948
|
|
|
|
949
|
|
|
// highlighting results can be fetched by document id (the field defined as uniquekey in this schema) |
950
|
|
|
$highlightedDoc = $highlighting->getResult($document->id); |
951
|
|
|
|
952
|
|
|
if($highlightedDoc){ |
953
|
|
|
foreach($highlightedDoc as $field => $highlight) { |
954
|
|
|
// a little hackery for matched tags |
955
|
|
|
$snippet = array(); |
956
|
|
|
foreach ($highlight as $key => $h) { |
957
|
|
|
$matched = $hl_prefix; |
958
|
|
|
$matched .= substr(strstr(elgg_strip_tags($h), '%%'), 2); |
959
|
|
|
$matched .= $hl_suffix; |
960
|
|
|
$snippet[] = $purifier->purify($matched); |
961
|
|
|
} |
962
|
|
|
|
963
|
|
|
$display = implode(', ', $snippet); |
964
|
|
|
$search_results[$document->id][$field] = $display; |
965
|
|
|
} |
966
|
|
|
} |
967
|
|
|
$search_results[$document->id]['score'] = $document->score; |
968
|
|
|
} |
969
|
|
|
|
970
|
|
|
// get the entities |
971
|
|
|
$entities = array(); |
972
|
|
|
$entities_unsorted = array(); |
973
|
|
View Code Duplication |
if ($search_results) { |
|
|
|
|
974
|
|
|
$entities_unsorted = elgg_get_entities(array( |
975
|
|
|
'guids' => array_keys($search_results), |
976
|
|
|
'limit' => false |
977
|
|
|
)); |
978
|
|
|
} |
979
|
|
|
|
980
|
|
|
$show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); |
981
|
|
|
foreach ($search_results as $guid => $matches) { |
982
|
|
|
foreach ($entities_unsorted as $e) { |
983
|
|
|
if ($e->guid == $guid) { |
984
|
|
|
|
985
|
|
|
$desc_suffix = ''; |
986
|
|
|
if ($show_score == 'yes' && elgg_is_admin_logged_in()) { |
987
|
|
|
$desc_suffix .= elgg_view('output/longtext', array( |
988
|
|
|
'value' => elgg_echo('elgg_solr:relevancy', array($matches['score'])), |
989
|
|
|
'class' => 'elgg-subtext' |
990
|
|
|
)); |
991
|
|
|
} |
992
|
|
|
|
993
|
|
|
$title = $e->title ? $e->title : $e->name; |
994
|
|
|
$description = $e->description; |
995
|
|
|
$e->setVolatileData('search_matched_title', $title); |
996
|
|
|
$e->setVolatileData('search_matched_description', elgg_get_excerpt($description) . $desc_suffix); |
997
|
|
|
|
998
|
|
|
$e->setVolatileData('search_matched_extra', $matches['tags']); |
999
|
|
|
$entities[] = $e; |
1000
|
|
|
} |
1001
|
|
|
} |
1002
|
|
|
} |
1003
|
|
|
|
1004
|
|
|
return array( |
1005
|
|
|
'entities' => $entities, |
1006
|
|
|
'count' => $count, |
1007
|
|
|
); |
1008
|
|
|
} |
1009
|
|
|
|
1010
|
|
|
|
1011
|
|
|
// optimize our index daily |
1012
|
|
|
function elgg_solr_daily_cron($hook, $type, $return, $params) { |
1013
|
|
|
$ia = elgg_set_ignore_access(true); |
1014
|
|
|
|
1015
|
|
|
$client = elgg_solr_get_client(); |
1016
|
|
|
$query = $client->createUpdate(); |
1017
|
|
|
$query->addOptimize(true, true, 5); |
1018
|
|
|
|
1019
|
|
|
try { |
1020
|
|
|
$client->update($query); |
1021
|
|
|
} |
1022
|
|
|
catch (Exception $exc) { |
1023
|
|
|
// fail silently |
1024
|
|
|
} |
1025
|
|
|
|
1026
|
|
|
|
1027
|
|
|
// try to catch any missed deletions |
1028
|
|
|
$options = array( |
1029
|
|
|
'guid' => elgg_get_site_entity()->guid, |
1030
|
|
|
'annotation_names' => array('elgg_solr_delete_cache'), |
1031
|
|
|
'limit' => false |
1032
|
|
|
); |
1033
|
|
|
|
1034
|
|
|
$annotations = new ElggBatch('elgg_get_annotations', $options, null, 25, false); |
1035
|
|
|
foreach ($annotations as $a) { |
1036
|
|
|
$client = elgg_solr_get_client(); |
1037
|
|
|
$query = $client->createUpdate(); |
1038
|
|
|
$query->addDeleteById($a->value); |
1039
|
|
|
$query->addCommit(); |
1040
|
|
|
|
1041
|
|
|
try { |
1042
|
|
|
$client->update($query); |
1043
|
|
|
} catch (Exception $exc) { |
1044
|
|
|
// well we tried... |
1045
|
|
|
} |
1046
|
|
|
|
1047
|
|
|
$a->delete(); |
1048
|
|
|
} |
1049
|
|
|
|
1050
|
|
|
elgg_set_ignore_access($ia); |
1051
|
|
|
} |
1052
|
|
|
|
1053
|
|
|
|
1054
|
|
|
/** |
1055
|
|
|
* NOTE - this is only used in Elgg 1.8 as comments are annotations |
1056
|
|
|
* |
1057
|
|
|
* @param type $hook |
1058
|
|
|
* @param type $type |
1059
|
|
|
* @param type $return |
1060
|
|
|
* @param type $params |
1061
|
|
|
* @return null |
1062
|
|
|
*/ |
1063
|
|
|
function elgg_solr_comment_search($hook, $type, $return, $params) { |
1064
|
|
|
|
1065
|
|
|
$entities = array(); |
1066
|
|
|
|
1067
|
|
|
$select = array( |
1068
|
|
|
'start' => $params['offset'], |
1069
|
|
|
'rows' => $params['limit'] ? $params['limit'] : 10, |
1070
|
|
|
'fields' => array('id', 'container_guid', 'description', 'owner_guid', 'time_created', 'score'), |
1071
|
|
|
); |
1072
|
|
|
|
1073
|
|
View Code Duplication |
if ($params['select'] && is_array($params['select'])) { |
1074
|
|
|
$select = array_merge($select, $params['select']); |
1075
|
|
|
} |
1076
|
|
|
|
1077
|
|
|
// create a client instance |
1078
|
|
|
$client = elgg_solr_get_client(); |
1079
|
|
|
|
1080
|
|
|
// get an update query instance |
1081
|
|
|
$query = $client->createSelect($select); |
1082
|
|
|
|
1083
|
|
|
$default_sort = array( |
1084
|
|
|
'score' => 'desc', |
1085
|
|
|
'time_created' => 'desc' |
1086
|
|
|
); |
1087
|
|
|
$sorts = $params['sorts'] ? $params['sorts'] : $default_sort; |
1088
|
|
|
|
1089
|
|
|
$query->addSorts($sorts); |
1090
|
|
|
|
1091
|
|
|
$description_boost = elgg_solr_get_description_boost(); |
1092
|
|
|
|
1093
|
|
|
// get the dismax component and set a boost query |
1094
|
|
|
$dismax = $query->getEDisMax(); |
1095
|
|
|
$qf = "description^{$description_boost}"; |
1096
|
|
|
if ($params['qf']) { |
1097
|
|
|
$qf = $params['qf']; |
1098
|
|
|
} |
1099
|
|
|
$dismax->setQueryFields($qf); |
1100
|
|
|
|
1101
|
|
|
$boostQuery = elgg_solr_get_boost_query(); |
1102
|
|
|
if ($boostQuery) { |
1103
|
|
|
$dismax->setBoostQuery($boostQuery); |
1104
|
|
|
} |
1105
|
|
|
|
1106
|
|
|
// this query is now a dismax query |
1107
|
|
|
$query->setQuery($params['query']); |
1108
|
|
|
|
1109
|
|
|
|
1110
|
|
|
// make sure we're only getting comments |
1111
|
|
|
$params['fq']['type'] = 'type:annotation'; |
1112
|
|
|
$params['fq']['subtype'] = 'subtype:generic_comment'; |
1113
|
|
|
|
1114
|
|
|
$default_fq = elgg_solr_get_default_fq($params); |
1115
|
|
View Code Duplication |
if ($params['fq']) { |
1116
|
|
|
$filter_queries = array_merge($default_fq, $params['fq']); |
1117
|
|
|
} |
1118
|
|
|
else { |
1119
|
|
|
$filter_queries = $default_fq; |
1120
|
|
|
} |
1121
|
|
|
|
1122
|
|
|
if (!empty($filter_queries)) { |
1123
|
|
|
foreach ($filter_queries as $key => $value) { |
1124
|
|
|
$query->createFilterQuery($key)->setQuery($value); |
1125
|
|
|
} |
1126
|
|
|
} |
1127
|
|
|
|
1128
|
|
|
// get highlighting component and apply settings |
1129
|
|
|
$hl = $query->getHighlighting(); |
1130
|
|
|
$hl->setFields(array('description')); |
1131
|
|
|
$hl->setSimplePrefix('<span data-hl="elgg-solr">'); |
1132
|
|
|
$hl->setSimplePostfix('</span>'); |
1133
|
|
|
|
1134
|
|
|
$fragsize = elgg_solr_get_fragsize(); |
1135
|
|
|
if (isset($params['fragsize'])) { |
1136
|
|
|
$fragsize = (int) $params['fragsize']; |
1137
|
|
|
} |
1138
|
|
|
$hl->setFragSize($fragsize); |
1139
|
|
|
|
1140
|
|
|
|
1141
|
|
|
// this executes the query and returns the result |
1142
|
|
|
try { |
1143
|
|
|
$resultset = $client->select($query); |
1144
|
|
|
} catch (Exception $e) { |
1145
|
|
|
error_log($e->getMessage()); |
1146
|
|
|
return null; |
1147
|
|
|
} |
1148
|
|
|
|
1149
|
|
|
// Get the highlighted snippet |
1150
|
|
|
try { |
1151
|
|
|
$highlighting = $resultset->getHighlighting(); |
1152
|
|
|
} catch (Exception $e) { |
1153
|
|
|
error_log($e->getMessage()); |
1154
|
|
|
return null; |
1155
|
|
|
} |
1156
|
|
|
|
1157
|
|
|
// Count the total number of documents found by solr |
1158
|
|
|
$count = $resultset->getNumFound(); |
1159
|
|
|
$hl_prefix = elgg_solr_get_hl_prefix(); |
1160
|
|
|
$hl_suffix = elgg_solr_get_hl_suffix(); |
1161
|
|
|
|
1162
|
|
|
$show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); |
1163
|
|
|
|
1164
|
|
|
$config = HTMLPurifier_Config::createDefault(); |
1165
|
|
|
$purifier = new HTMLPurifier($config); |
1166
|
|
|
|
1167
|
|
|
foreach ($resultset as $document) { |
1168
|
|
|
// comments entity_guid stored as container_guid in solr |
1169
|
|
|
$entity = get_entity($document->container_guid); |
1170
|
|
|
|
1171
|
|
|
if (!$entity) { |
1172
|
|
|
$entity = new ElggObject(); |
1173
|
|
|
$entity->setVolatileData('search_unavailable_entity', TRUE); |
1174
|
|
|
} |
1175
|
|
|
|
1176
|
|
|
// highlighting results can be fetched by document id (the field defined as uniquekey in this schema) |
1177
|
|
|
$highlightedDoc = $highlighting->getResult($document->id); |
1178
|
|
|
|
1179
|
|
|
if($highlightedDoc){ |
1180
|
|
|
foreach($highlightedDoc as $highlight) { |
1181
|
|
|
$snippet = implode(' (...) ', $highlight); |
1182
|
|
|
// get our highlight based on the wrapped tokens |
1183
|
|
|
// note, this is to prevent partial html from breaking page layouts |
1184
|
|
|
$match = array(); |
1185
|
|
|
preg_match('/<span data-hl="elgg-solr">(.*)<\/span>/', $snippet, $match); |
1186
|
|
|
|
1187
|
|
|
if ($match[1]) { |
1188
|
|
|
$snippet = str_replace($match[1], $hl_prefix . $match[1] . $hl_suffix, $snippet); |
1189
|
|
|
$snippet = $purifier->purify($snippet); |
1190
|
|
|
} |
1191
|
|
|
} |
1192
|
|
|
} |
1193
|
|
|
|
1194
|
|
|
if (!$snippet) { |
|
|
|
|
1195
|
|
|
$snippet = search_get_highlighted_relevant_substrings(elgg_get_excerpt($document->description), $params['query']); |
1196
|
|
|
} |
1197
|
|
|
|
1198
|
|
|
if ($show_score == 'yes' && elgg_is_admin_logged_in()) { |
1199
|
|
|
$snippet .= elgg_view('output/longtext', array( |
1200
|
|
|
'value' => elgg_echo('elgg_solr:relevancy', array($document->score)), |
1201
|
|
|
'class' => 'elgg-subtext' |
1202
|
|
|
)); |
1203
|
|
|
} |
1204
|
|
|
|
1205
|
|
|
$comments_data = $entity->getVolatileData('search_comments_data'); |
1206
|
|
|
if (!$comments_data) { |
1207
|
|
|
$comments_data = array(); |
1208
|
|
|
} |
1209
|
|
|
$comments_data[] = array( |
1210
|
|
|
'annotation_id' => substr(strstr(elgg_strip_tags($document->id), ':'), 1), |
1211
|
|
|
'text' => $snippet, |
1212
|
|
|
'owner_guid' => $document->owner_guid, |
1213
|
|
|
'time_created' => $document->time_created, |
1214
|
|
|
); |
1215
|
|
|
$entity->setVolatileData('search_comments_data', $comments_data); |
1216
|
|
|
|
1217
|
|
|
$entities[] = $entity; |
1218
|
|
|
} |
1219
|
|
|
|
1220
|
|
|
return array( |
1221
|
|
|
'entities' => $entities, |
1222
|
|
|
'count' => $count, |
1223
|
|
|
); |
1224
|
|
|
} |
1225
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.