hooks.php ➔ elgg_solr_object_search()   F
last analyzed

Complexity

Conditions 27
Paths > 20000

Size

Total Lines 187

Duplication

Lines 79
Ratio 42.25 %

Code Coverage

Tests 0
CRAP Score 756

Importance

Changes 0
Metric Value
cc 27
nc 37888
nop 4
dl 79
loc 187
ccs 0
cts 139
cp 0
crap 756
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search_results of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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);
0 ignored issues
show
Unused Code introduced by
The call to elgg_solr_get_client() has too many arguments starting with $select.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search_results of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search_results of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search_results of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $valid_tag_names of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $query_parts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search_results of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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) {
0 ignored issues
show
Bug introduced by
The variable $snippet does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
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