functions.php ➔ elgg_solr_reindex()   F
last analyzed

Complexity

Conditions 21
Paths > 20000

Size

Total Lines 206

Duplication

Lines 11
Ratio 5.34 %

Code Coverage

Tests 0
CRAP Score 462

Importance

Changes 0
Metric Value
cc 21
nc 33536
nop 0
dl 11
loc 206
ccs 0
cts 163
cp 0
crap 462
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
function elgg_solr_reindex() {
4
	set_time_limit(0);
5
6
	$is_elgg18 = elgg_solr_is_elgg18();
7
8
	$guid_getter = 'elgg_solr_get_entity_guids';
9
	if ($is_elgg18) {
10
		$guid_getter = 'elgg_solr_get_entity_guids_18';
11
	}
12
13
	$ia = elgg_set_ignore_access(true);
14
	$show_hidden = access_get_show_hidden_status();
15
	access_show_hidden_entities(true);
16
17
	// lock the function
18
	elgg_set_plugin_setting('reindex_running', 1, 'elgg_solr');
19
20 View Code Duplication
	if (!file_exists(elgg_get_config('dataroot') . 'elgg_solr')) {
21
		mkdir(elgg_get_config('dataroot') . 'elgg_solr');
22
	}
23
24
	$logtime = elgg_get_config('elgg_solr_restart_logtime');
25
	if (!$logtime) {
26
		$logtime = time();
27
	}
28
	$log = elgg_get_config('dataroot') . 'elgg_solr/' . $logtime . '.txt';
29
	elgg_set_plugin_setting('current_log', $logtime, 'elgg_solr');
30
31
	// initialize the csv
32
	$report = array(
33
		'percent' => '',
34
		'count' => 0, // report prior to indexing this entity
35
		'typecount' => 0,
36
		'fullcount' => 0,
37
		'type' => '',
38
		'querytime' => 0,
39
		'message' => 'Initializing Reindex',
40
		'date' => date('Y-M-j H:i:s'),
41
		'logtime' => $logtime
42
	);
43
	file_put_contents($log, json_encode($report) . "\n", FILE_APPEND);
44
45
46
	$debug = get_input('debug', false);
47
	if ($debug) {
48
		elgg_set_config('elgg_solr_debug', 1);
49
	}
50
51
	$registered_types = elgg_get_config('elgg_solr_reindex_options');
52
	if (!$registered_types) {
53
		$registered_types = get_registered_entity_types();
54
	}
55
56
	// build our options and cache them in case we need to restart it
57
	$cacheoptions = array(
58
		'types' => $registered_types
59
	);
60
61
	$options = array();
62
	$time = elgg_get_config('elgg_solr_time_options');
63
	if ($time && is_array($time)) {
64
		$options['wheres'] = array(
65
			"e.time_created >= {$time['starttime']}",
66
			"e.time_created <= {$time['endtime']}",
67
		);
68
69
		$cacheoptions['starttime'] = $time['starttime'];
70
		$cacheoptions['endtime'] = $time['endtime'];
71
	}
72
73
	elgg_set_config('elgg_solr_nocommit', true); // tell our indexer not to commit right away
74
75
	$fullcount = 0;
76
	foreach ($registered_types as $type => $subtypes) {
77
		$options['type'] = $type;
78
		$options['subtypes'] = ELGG_ENTITIES_ANY_VALUE;
79
		$options['limit'] = false;
80
81
		$restart_time = elgg_get_config('elgg_solr_restart_time');
82
		if ($restart_time) {
83
			elgg_set_config('elgg_solr_restart_time', false);
84
85
			$options['wheres'][1] = "e.time_created <= {$restart_time}";
86
		} elseif ($time['endtime']) {
87
			$options['wheres'][1] = "e.time_created <= {$time['endtime']}";
88
		}
89
90 View Code Duplication
		if ($subtypes) {
91
			if (!is_array($subtypes)) {
92
				$options['subtypes'] = array($subtypes);
93
			}
94
			else {
95
				$options['subtypes'] = $subtypes;
96
			}
97
		}
98
99
		// this iteration fixes a bug https://github.com/Elgg/Elgg/issues/7561
100
		// uses a custom getter which only fetches the guids in a single large-batch query
101
		// which is much more efficient than standard egef
102
		$batch_size = elgg_get_plugin_setting('reindex_batch_size', 'elgg_solr');
103
		$entities = new ElggBatch($guid_getter, $options, null, $batch_size);
104
		$final_count = $guid_getter(array_merge($options, array('count' => true)));
105
106
		elgg_set_config('elgg_solr_nocommit', true); // disable committing on each entity for performance
107
		$count = 0;
108
		$fetch_time_start = microtime(true);
109
		foreach ($entities as $e) {
110
			$count++;
111
			$fullcount++;
112
			$first_entity = (bool) (($count % $batch_size) == 1);
113
			$last_entity = (bool) (($count % $batch_size) == 0);
114
115
			if ($first_entity) {
116
				// this is the first entity in the new batch
117
				$fetch_time = microtime(true) - $fetch_time_start; // the query time in seconds
118
			}
119
120
			$entity = get_entity($e->guid);
121
			if ($entity) {
122
				elgg_solr_add_update_entity(null, null, $entity);
123
				elgg_set_config('elgg_solr_nocommit', true);
124
			}
125
126
			if (!($count % 200)) {
127
				$qtime = round($fetch_time, 4);
0 ignored issues
show
Bug introduced by
The variable $fetch_time 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...
128
				$percent = round($count / $final_count * 100);
129
				if ($entity) {
130
					$restart_time = $entity->time_created;
131
				}
132
				$report = array(
133
					'percent' => $percent,
134
					'count' => $count,
135
					'typecount' => $final_count,
136
					'fullcount' => $fullcount,
137
					'type' => $type,
138
					'querytime' => $qtime,
139
					'message' => '',
140
					'date' => date('Y-M-j H:i:s'),
141
					'cacheoptions' => $cacheoptions,
142
					'logtime' => $logtime,
143
					'restart_time' => $restart_time
144
				);
145
146
				file_put_contents($log, json_encode($report) . "\n", FILE_APPEND);
147
				elgg_set_config('elgg_solr_nocommit', false); // push a commit on this one
148
149
				// check for the termination signal
150
				if ($logtime == elgg_get_plugin_setting('stop_reindex', 'elgg_solr')) {
151
					$report = array(
152
						'percent' => $percent,
153
						'count' => $count,
154
						'typecount' => $final_count,
155
						'fullcount' => $fullcount,
156
						'type' => $type,
157
						'querytime' => $qtime,
158
						'message' => 'Reindex has been stopped',
159
						'date' => date('Y-M-j H:i:s'),
160
						'cacheoptions' => $cacheoptions,
161
						'logtime' => $logtime,
162
						'restart_time' => $restart_time
163
					);
164
					
165
					file_put_contents($log, json_encode($report) . "\n", FILE_APPEND);
166
					error_log('Stopping reindex due to termination signal');
167
					exit;
168
				}
169
			}
170
171
			if ($last_entity) {
172
				$fetch_time_start = microtime(true);
173
			}
174
		}
175
176
		// we've finished this type, unset from the cache options
177
		unset($cacheoptions['types'][$type]);
178
	}
179
180
	$report = array(
181
		'percent' => '',
182
		'count' => 0, // report prior to indexing this entity
183
		'typecount' => 0,
184
		'fullcount' => 0,
185
		'type' => '',
186
		'querytime' => 0,
187
		'message' => 'Reindex complete',
188
		'date' => date('Y-M-j H:i:s'),
189
		'logtime' => $logtime
190
	);
191
	file_put_contents($log, json_encode($report) . "\n", FILE_APPEND);
192
	elgg_set_plugin_setting('reindex_running', 0, 'elgg_solr');
193
194
	// commit the last of the entities
195
	$client = elgg_solr_get_client();
196
	$query = $client->createUpdate();
197
	$query->addCommit();
198
199
	try {
200
		$client->update($query);
201
	} catch (Exception $e) {
202
		error_log($e->getMessage());
203
		return false;
204
	}
205
206
	access_show_hidden_entities($show_hidden);
207
	elgg_set_ignore_access($ia);
208
}
209
210
function elgg_solr_comment_reindex() {
211
	set_time_limit(0);
212
213
	$ia = elgg_set_ignore_access(true);
214
	$show_hidden = access_get_show_hidden_status();
215
	access_show_hidden_entities(true);
216
217
	$debug = get_input('debug', false);
218
	if ($debug) {
219
		elgg_set_config('elgg_solr_debug', 1);
220
	}
221
222
	// lock the function
223
	elgg_set_plugin_setting('reindex_running', 1, 'elgg_solr');
224
225 View Code Duplication
	if (!file_exists(elgg_get_config('dataroot') . 'elgg_solr')) {
226
		mkdir(elgg_get_config('dataroot') . 'elgg_solr');
227
	}
228
229
	$time = time();
230
	$log = elgg_get_config('dataroot') . 'elgg_solr/' . $time . '.txt';
231
	elgg_set_plugin_setting('current_log', $time, 'elgg_solr');
232
233
	// initialize the csv
234
	$report = array(
235
		'percent' => '',
236
		'count' => 0, // report prior to indexing this entity
237
		'typecount' => 0,
238
		'fullcount' => 0,
239
		'type' => 'Comments',
240
		'querytime' => 0,
241
		'message' => 'Initializing Reindex',
242
		'date' => date('Y-M-j H:i:s')
243
	);
244
	file_put_contents($log, json_encode($report) . "\n", FILE_APPEND);
245
246
247
	elgg_set_config('elgg_solr_nocommit', true); // tell our indexer not to commit right away
248
249
	$count = 0;
250
251
	// index comments
252
	$options = array(
253
		'annotation_name' => 'generic_comment',
254
		'limit' => false
255
	);
256
257
	$time = elgg_get_config('elgg_solr_time_options');
258
	if ($time && is_array($time)) {
259
		$options['annotation_created_time_lower'] = $time['starttime'];
260
		$options['annotation_created_time_upper'] = $time['endtime'];
261
	}
262
263
	$batch_size = elgg_get_plugin_setting('reindex_batch_size', 'elgg_solr');
264
	$comments = new ElggBatch('elgg_get_annotations', $options, null, $batch_size);
265
266
	$final_count = elgg_get_annotations(array_merge($options, array('count' => true)));
267
	$fetch_time_start = microtime(true);
268
269
	foreach ($comments as $comment) {
270
		$count++;
271
		$first_entity = (bool) (($count % $batch_size) == 1);
272
		$last_entity = (bool) (($count % $batch_size) == 0);
273
274
		if ($first_entity) {
275
			// this is the first entity in the new batch
276
			$fetch_time = microtime(true) - $fetch_time_start; // the query time in seconds
277
		}
278
279
		if ($count % 10000) {
280
			elgg_set_config('elgg_solr_nocommit', false); // push a commit on this one
281
		}
282
283
		if ($comment) {
284
			elgg_solr_index_annotation($comment);
285
			elgg_set_config('elgg_solr_nocommit', true);
286
		}
287
288
		if (!($count % 200)) {
289
			$qtime = round($fetch_time, 4);
0 ignored issues
show
Bug introduced by
The variable $fetch_time 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...
290
			$percent = round($count / $final_count * 100);
291
			$report = array(
292
				'percent' => $percent,
293
				'count' => $count,
294
				'typecount' => $final_count,
295
				'fullcount' => $count,
296
				'type' => 'Comments',
297
				'querytime' => $qtime,
298
				'message' => '',
299
				'date' => date('Y-M-j H:i:s')
300
			);
301
302
			file_put_contents($log, json_encode($report) . "\n", FILE_APPEND);
303
		}
304
305
		if ($last_entity) {
306
			$fetch_time_start = microtime(true);
307
		}
308
	}
309
310
	if ($debug) {
311
		elgg_solr_debug_log($count . ' entities sent to Solr');
312
	}
313
314
	$report = array(
315
		'percent' => 100,
316
		'count' => $count,
317
		'typecount' => $final_count,
318
		'fullcount' => $count,
319
		'type' => 'Comments',
320
		'querytime' => 0,
321
		'message' => 'Comment Reindex has been completed',
322
		'date' => date('Y-M-j H:i:s')
323
	);
324
325
	file_put_contents($log, json_encode($report) . "\n", FILE_APPEND);
326
327
	elgg_set_ignore_access($ia);
328
	access_show_hidden_entities($show_hidden);
329
	elgg_set_plugin_setting('reindex_running', 0, 'elgg_solr');
330
}
331
332
function elgg_solr_get_indexable_count() {
333
	$registered_types = get_registered_entity_types();
334
335
	$ia = elgg_set_ignore_access(true);
336
337
	$count = 0;
338
	foreach ($registered_types as $type => $subtypes) {
339
		$options = array(
340
			'type' => $type,
341
			'count' => true
342
		);
343
344
		if ($subtypes) {
345
			$options['subtypes'] = $subtypes;
346
		}
347
348
		$count += elgg_get_entities($options);
349
	}
350
351
	// count comments
352
	$options = array(
353
		'annotation_name' => 'generic_comment',
354
		'count' => true
355
	);
356
	$count += elgg_get_annotations($options);
357
358
	elgg_set_ignore_access($ia);
359
360
	return $count;
361
}
362
363
function elgg_solr_get_indexed_count($query = '*:*', $fq = array()) {
364
	$select = array(
365
		'query' => $query,
366
		'start' => 0,
367
		'rows' => 1,
368
		'fields' => array('id'),
369
	);
370
371
	// create a client instance
372
	$client = elgg_solr_get_client();
373
374
	// get an update query instance
375
	$query = $client->createSelect($select);
376
377
	if (!empty($fq)) {
378
		foreach ($fq as $key => $value) {
379
			$query->createFilterQuery($key)->setQuery($value);
380
		}
381
	}
382
383
	try {
384
		$resultset = $client->select($query);
385
	} catch (Exception $e) {
386
		error_log($e->getMessage());
387
		return false;
388
	}
389
390
	return $resultset->getNumFound();
391
}
392
393
function elgg_solr_get_client() {
394
	elgg_load_library('Solarium');
395
396
	Solarium\Autoloader::register();
397
398
	$options = elgg_solr_get_adapter_options();
399
400
	$config = array('endpoint' => array(
401
			'localhost' => $options
402
	));
403
404
	// create a client instance
405
	return new Solarium\Client($config);
406
}
407
408
function elgg_solr_get_adapter_options() {
409
	return array(
410
		'host' => elgg_get_plugin_setting('host', 'elgg_solr'),
411
		'port' => elgg_get_plugin_setting('port', 'elgg_solr'),
412
		'path' => elgg_get_plugin_setting('solr_path', 'elgg_solr'),
413
		'core' => elgg_get_plugin_setting('solr_core', 'elgg_solr'),
414
	);
415
}
416
417
function elgg_solr_has_settings() {
418
	$host = elgg_get_plugin_setting('host', 'elgg_solr');
419
	$port = elgg_get_plugin_setting('port', 'elgg_solr');
420
	$path = elgg_get_plugin_setting('path', 'elgg_solr');
421
422
	if (empty($host) || empty($port) || empty($path)) {
423
		return false;
424
	}
425
426
	return true;
427
}
428
429
/**
430
 * get default filter queries based on search params
431
 * 
432
 * @param type $params
433
 * 
434
 * return array
435
 */
436
function elgg_solr_get_default_fq($params) {
437
	$fq = array();
438
439
	// type/types
440 View Code Duplication
	if (isset($params['type']) && $params['type'] !== ELGG_ENTITIES_ANY_VALUE) {
441
		if ($params['type'] === ELGG_ENTITIES_NO_VALUE) {
442
			//$fq['type'] = '-type:[* TO *]';
443
			$fq['type'] = 'type:""';
444
		} else {
445
			$fq['type'] = 'type:' . $params['type'];
446
		}
447
	}
448
449 View Code Duplication
	if ($params['types'] && $params['types'] !== ELGG_ENTITIES_ANY_VALUE) {
450
		if (is_array($params['types'])) {
451
			$fq['type'] = 'type:(' . implode(' OR ', $params['types']) . ')';
452
		} else {
453
			if ($params['types'] === ELGG_ENTITIES_NO_VALUE) {
454
				//$fq['type'] = '-type:[* TO *]';
455
				$fq['type'] = 'type:""';
456
			} else {
457
				$fq['type'] = 'type:' . $params['types'];
458
			}
459
		}
460
	}
461
462
	//subtype
463 View Code Duplication
	if (isset($params['subtype']) && $params['subtype'] !== ELGG_ENTITIES_ANY_VALUE) {
464
		if ($params['subtype'] === ELGG_ENTITIES_NO_VALUE) {
465
			//$fq['subtype'] = '-subtype:[* TO *]';
466
			$fq['subtype'] = 'subtype:""';
467
		} else {
468
			$fq['subtype'] = 'subtype:' . $params['subtype'];
469
		}
470
	}
471
472 View Code Duplication
	if (isset($params['subtypes']) && $params['subtypes'] !== ELGG_ENTITIES_ANY_VALUE) {
473
		if (is_array($params['subtypes'])) {
474
			$fq['subtype'] = 'subtype:(' . implode(' OR ', $params['subtypes']) . ')';
475
		} else {
476
			if ($params['subtypes'] === ELGG_ENTITIES_NO_VALUE) {
477
				//$fq['subtype'] = '-subtype:[* TO *]';
478
				$fq['subtype'] = 'subtype:""';
479
			} else {
480
				$fq['subtype'] = 'subtype:' . $params['subtypes'];
481
			}
482
		}
483
	}
484
485
486
	//container
487
	if (isset($params['container_guid']) && $params['container_guid'] !== ELGG_ENTITIES_ANY_VALUE) {
488
		$fq['container'] = 'container_guid:' . $params['container_guid'];
489
	}
490
491 View Code Duplication
	if (isset($params['container_guids']) && $params['container_guids'] !== ELGG_ENTITIES_ANY_VALUE) {
492
		if (is_array($params['container_guids'])) {
493
			$fq['container'] = 'container_guid:(' . implode(' OR ', $params['container_guids']) . ')';
494
		} else {
495
			$fq['container'] = 'container_guid:' . $params['container_guid'];
496
		}
497
	}
498
499
	//owner
500
	if (isset($params['owner_guid']) && $params['owner_guid'] !== ELGG_ENTITIES_ANY_VALUE) {
501
		$fq['owner'] = 'owner_guid:' . $params['owner_guid'];
502
	}
503
504 View Code Duplication
	if (isset($params['owner_guids']) && $params['owner_guids'] !== ELGG_ENTITIES_ANY_VALUE) {
505
		if (is_array($params['owner_guids'])) {
506
			$fq['owner'] = 'owner_guid:(' . implode(' OR ', $params['owner_guids']) . ')';
507
		} else {
508
			$fq['owner'] = 'owner_guid:' . $params['owner_guid'];
509
		}
510
	}
511
512
	$access_query = elgg_solr_get_access_query();
513
	if ($access_query) {
514
		$fq['access'] = $access_query;
515
	}
516
517
	if (!access_get_show_hidden_status()) {
518
		$fq['enabled'] = 'enabled:"yes"';
519
	}
520
521
	return $fq;
522
}
523
524
/**
525
 * Register a function to define specific configuration of an entity in solr
526
 * 
527
 * @param type $type - the entity type
528
 * @param type $subtype - the entity subtype
529
 * @param type $function - the function to call for updating an entity in solr
530
 */
531 View Code Duplication
function elgg_solr_register_solr_entity_type($type, $subtype, $function) {
532
	$solr_entities = elgg_get_config('solr_entities');
533
534
	if (!is_array($solr_entities)) {
535
		$solr_entities = array();
536
	}
537
538
	$solr_entities[$type][$subtype] = $function;
539
540
	elgg_set_config('solr_entities', $solr_entities);
541
}
542
543
/**
544
 * 
545
 * 
546
 * @param type $type
547
 * @param type $subtype
548
 * @return boolean
549
 */
550
function elgg_solr_get_solr_function($type, $subtype) {
551
	if (elgg_get_config('elgg_solr_debug')) {
552
		$debug = true;
553
	}
554
555
	$solr_entities = elgg_get_config('solr_entities');
556
557
	if (isset($solr_entities[$type][$subtype]) && is_callable($solr_entities[$type][$subtype])) {
558
		return $solr_entities[$type][$subtype];
559
	}
560
561
	if (isset($solr_entities[$type]['default']) && is_callable($solr_entities[$type]['default'])) {
562
		return $solr_entities[$type]['default'];
563
	}
564
565
	if (isset($solr_entities['entity']['default']) && is_callable($solr_entities['entity']['default'])) {
566
		return $solr_entities['entity']['default'];
567
	}
568
569
	if ($debug) {
0 ignored issues
show
Bug introduced by
The variable $debug 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...
570
		elgg_solr_debug_log('Solr function not callable for type: ' . $type . ', subtype: ' . $subtype);
571
	}
572
573
	return false;
574
}
575
576
/**
577
 * Index a file entity
578
 * 
579
 * @param type $entity
580
 * @return boolean
581
 */
582
function elgg_solr_add_update_file($entity) {
583
584
	$client = elgg_solr_get_client();
585
	$commit = elgg_get_config('elgg_solr_nocommit') ? false : true;
586
587
	$extract = elgg_get_plugin_setting('extract_handler', 'elgg_solr');
588
	$extracting = false;
589
	if (file_exists($entity->getFilenameOnFilestore()) && $extract == 'yes') {
590
		$extracting = true;
591
	}
592
593
	if ($extracting) {
594
		// get an extract query instance and add settings
595
		$query = $client->createExtract();
596
		$query->setFile($entity->getFilenameOnFilestore());
597
		$query->addFieldMapping('content', 'attr_content');
598
		$query->setUprefix('attr_');
599
		$query->setOmitHeader(true);
600
	} else {
601
		$query = $client->createUpdate();
602
	}
603
	
604
	$subtype = $entity->getSubtype() ? $entity->getSubtype() : '';
605
606
	// add document
607
	$doc = $query->createDocument();
608
	$doc->id = $entity->guid;
609
	$doc->type = $entity->type;
610
	$doc->subtype = $subtype;
611
	$doc->owner_guid = $entity->owner_guid;
612
	$doc->container_guid = $entity->container_guid;
613
	$doc->access_id = $entity->access_id;
614
	$doc->title = gc_explode_translation(elgg_strip_tags($entity->title), get_current_language());
615
	$doc->description = gc_explode_translation(elgg_strip_tags($entity->description), get_current_language());
616
	$doc->time_created = $entity->time_created;
617
	$doc = elgg_solr_add_tags($doc, $entity);
618
	$doc->enabled = $entity->enabled;
619
620
	$params = array('entity' => $entity);
621
	$doc = elgg_trigger_plugin_hook('elgg_solr:index', $entity->type, $params, $doc);
622
	
623
	if (!$doc) {
624
		return true; // a plugin hook has stopped the indexing
625
	}
626
627
	if ($extracting) {
628
		$query->setDocument($doc);
629
		if ($commit) {
630
			$query->setCommit(true);
631
		}
632
		try {
633
			$client->extract($query);
634
		} catch (Exception $exc) {
635
			error_log($exc->getMessage());
636
		}
637
	} else {
638
		$query->addDocument($doc);
639
		if ($commit) {
640
			$query->addCommit();
641
		}
642
643
		try {
644
			$client->update($query);
645
		} catch (Exception $exc) {
646
			error_log($exc->getMessage());
647
		}
648
	}
649
650
	return true;
651
}
652
653
/**
654
 * Index a generic elgg object
655
 * 
656
 * @param type $entity
657
 * @return boolean
658
 */
659
function elgg_solr_add_update_object_default($entity) {
660
661
	if (!is_registered_entity_type($entity->type, $entity->getSubtype())) {
662
		return false;
663
	}
664
665
	$client = elgg_solr_get_client();
666
	$commit = elgg_get_config('elgg_solr_nocommit') ? false : true;
667
668
	$query = $client->createUpdate();
669
	
670
	$subtype = $entity->getSubtype() ? $entity->getSubtype() : '';
671
672
	// add document
673
	$doc = $query->createDocument();
674
	$doc->id = $entity->guid;
675
	$doc->type = $entity->type;
676
	$doc->subtype = $subtype;
677
	$doc->owner_guid = $entity->owner_guid;
678
	$doc->container_guid = $entity->container_guid;
679
	$doc->access_id = $entity->access_id;
680
	$doc->title = gc_explode_translation(elgg_strip_tags($entity->title), get_current_language());
681
	$doc->name = gc_explode_translation(elgg_strip_tags($entity->name), get_current_language());
682
	$doc->description = gc_explode_translation(elgg_strip_tags($entity->description), get_current_language());
683
	$doc->time_created = $entity->time_created;
684
	$doc = elgg_solr_add_tags($doc, $entity);
685
	$doc->enabled = $entity->enabled;
686
687
	$params = array('entity' => $entity);
688
	$doc = elgg_trigger_plugin_hook('elgg_solr:index', $entity->type, $params, $doc);
689
	
690
	if (!$doc) {
691
		return true; // a plugin has stopped the index
692
	}
693
694
	$query->addDocument($doc);
695
	if ($commit) {
696
		$query->addCommit($commit);
697
	}
698
699
	// this executes the query and returns the result
700
	try {
701
		$client->update($query);
702
	} catch (Exception $exc) {
703
		error_log($exc->getMessage());
704
	}
705
706
	return true;
707
}
708
709
function elgg_solr_add_update_user($entity) {
710
711
	if (!elgg_instanceof($entity, 'user')) {
712
		return false;
713
	}
714
715
	if (!is_registered_entity_type($entity->type, $entity->getSubtype())) {
716
		return false;
717
	}
718
719
	// lump public profile fields in with description
720
	$profile_fields = elgg_get_config('profile_fields');
721
	$desc = '';
722
	if (is_array($profile_fields) && sizeof($profile_fields) > 0) {
723
		$walled = elgg_get_config('walled_garden');
724
		foreach ($profile_fields as $shortname => $valtype) {
725
			$md = elgg_get_metadata(array(
726
				'guid' => $entity->guid,
727
				'metadata_names' => array($shortname)
728
			));
729
730
			foreach ($md as $m) {
731
				if ($m->access_id == ACCESS_PUBLIC || ($walled && $m->access_id == ACCESS_LOGGED_IN)) {
732
					$desc .= $m->value . ' ';
733
				}
734
			}
735
		}
736
	}
737
738
	$client = elgg_solr_get_client();
739
	$commit = elgg_get_config('elgg_solr_nocommit') ? false : true;
740
741
	$query = $client->createUpdate();
742
	$subtype = $entity->getSubtype() ? $entity->getSubtype() : '';
743
744
	// add document
745
	$doc = $query->createDocument();
746
	$doc->id = $entity->guid;
747
	$doc->type = $entity->type;
748
	$doc->subtype = $subtype;
749
	$doc->owner_guid = $entity->owner_guid;
750
	$doc->container_guid = $entity->container_guid;
751
	$doc->access_id = $entity->access_id;
752
	$doc->title = elgg_strip_tags($entity->title);
753
	$doc->name = elgg_strip_tags($entity->name);
754
	$doc->username = $entity->username;
755
	$doc->description = elgg_strip_tags($desc);
756
	$doc->time_created = $entity->time_created;
757
	$doc = elgg_solr_add_tags($doc, $entity);
758
	$doc->enabled = $entity->enabled;
759
	$doc->user_type = $entity->user_type;
760
761
	$params = array('entity' => $entity);
762
	$doc = elgg_trigger_plugin_hook('elgg_solr:index', $entity->type, $params, $doc);
763
	
764
	if (!$doc) {
765
		return true; // a plugin has stopped the index
766
	}
767
768
	$query->addDocument($doc, true);
769
	if ($commit) {
770
		$query->addCommit();
771
	}
772
773
	// this executes the query and returns the result
774
	try {
775
		$client->update($query);
776
	} catch (Exception $exc) {
777
		error_log($exc->getMessage());
778
	}
779
	return true;
780
}
781
782
function elgg_solr_debug_log($message) {
783
	error_log($message);
784
}
785
786
function elgg_solr_get_access_query() {
787
788
	if (elgg_is_admin_logged_in() || elgg_get_ignore_access()) {
789
		return false; // no access limit
790
	}
791
792
	static $return;
793
794
	if ($return) {
795
		return $return;
796
	}
797
798
	$access = get_access_array();
799
800
	// access filter query
801
	if ($access) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $access 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...
802
		$access_list = implode(' ', $access);
803
	}
804
805
	if (elgg_is_logged_in()) {
806
807
		// get friends
808
		// @TODO - is there a better way? Not sure if there's a limit on solr if
809
		// someone has a whole lot of friends...
810
		$friends = elgg_get_entities_from_relationship(array(
811
			'type' => 'user',
812
			'relationship' => 'friend',
813
			'relationship_guid' => elgg_get_logged_in_user_guid(),
814
			'inverse_relationship' => true,
815
			'limit' => false,
816
			'callback' => false // keep the query fast
817
		));
818
819
		$friend_guids = array();
820
		foreach ($friends as $friend) {
821
			$friend_guids[] = $friend->guid;
822
		}
823
824
		$friends_list = '';
825
		if ($friend_guids) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $friend_guids 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...
826
			$friends_list = elgg_solr_escape_special_chars(implode(' ', $friend_guids));
827
		}
828
	}
829
830
	//$query->createFilterQuery('access')->setQuery("owner_guid: {guid} OR access_id:({$access_list}) OR (access_id:" . ACCESS_FRIENDS . " AND owner_guid:({$friends}))");
831
	if (elgg_is_logged_in()) {
832
		$return = "owner_guid:" . elgg_get_logged_in_user_guid();
833
	} else {
834
		$return = '';
835
	}
836
837
	if ($access_list) {
838
		if ($return) {
839
			$return .= ' OR ';
840
		}
841
		$return .= "access_id:(" . elgg_solr_escape_special_chars($access_list) . ")";
0 ignored issues
show
Bug introduced by
The variable $access_list 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...
842
	}
843
844
	$fr_prefix = '';
845
	$fr_suffix = '';
846
	if ($return && $friends_list) {
0 ignored issues
show
Bug introduced by
The variable $friends_list 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...
847
		$return .= ' OR ';
848
		$fr_prefix = '(';
849
		$fr_suffix = ')';
850
	}
851
852
	if ($friends_list) {
853
		$return .= $fr_prefix . 'access_id:' . elgg_solr_escape_special_chars(ACCESS_FRIENDS) . ' AND owner_guid:(' . $friends_list . ')' . $fr_suffix;
854
	}
855
856
	return $return;
857
}
858
859
/**
860
 * by default there's nothing we need to do different with this
861
 * so it's just a wrapper for object add
862
 * 
863
 * @param type $entity
864
 */
865
function elgg_solr_add_update_group_default($entity) {
866
	elgg_solr_add_update_object_default($entity);
867
}
868
869
function elgg_solr_escape_special_chars($string) {
870
	// Lucene characters that need escaping with \ are + - && || ! ( ) { } [ ] ^ " ~ * ? : \
871
	$luceneReservedCharacters = preg_quote('+-&|!(){}[]^"~*?:\\');
872
	$query = preg_replace_callback('/([' . $luceneReservedCharacters . '])/', 'elgg_solr_escape_special_chars_callback', $string);
873
	return $query;
874
}
875
876
function elgg_solr_escape_special_chars_callback($matches) {
877
	return '\\' . $matches[0];
878
}
879
880
/**
881
 * 
882
 * @param type $time - timestamp of the start of the block
883
 * @param type $block - the block of time, hour/day/month/year/all
884
 * @param type $type
885
 * @param type $subtype
886
 * @return type
887
 */
888
function elgg_solr_get_stats($time, $block, $type, $subtype) {
889
	$options = array(
890
		'type' => $type
891
	);
892
893
	$fq = array();
894
895
	if ($subtype) {
896
		$options['subtype'] = $subtype;
897
		$fq['subtype'] = "subtype:{$subtype}";
898
	} else {
899
		$options['subtype'] = ELGG_ENTITIES_NO_VALUE;
900
	}
901
902
	$stats = array();
903
	switch ($block) {
904
		case 'minute':
905
			for ($i = 0; $i < 60; $i++) {
906
				$starttime = mktime(date('G', $time), date('i', $time), $i, date('m', $time), date('j', $time), date('Y', $time));
907
				$endtime = mktime(date('G', $time), date('i', $time), $i + 1, date('m', $time), date('j', $time), date('Y', $time));
908
909
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
910
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
911
				$system = elgg_solr_get_system_count($options, $starttime, $endtime);
912
913
				$stats[date('s', $starttime)] = array(
914
					'count' => $system,
915
					'indexed' => $indexed,
916
					'starttime' => $starttime,
917
					'endtime' => $endtime,
918
					'block' => false
919
				);
920
			}
921
			break;
922
		case 'hour':
923
			for ($i = 0; $i < 60; $i++) {
924
				$starttime = mktime(date('G', $time), $i, 0, date('m', $time), date('j', $time), date('Y', $time));
925
				$endtime = mktime(date('G', $time), $i + 1, 0, date('m', $time), date('j', $time), date('Y', $time)) - 1;
926
927
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
928
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
929
				$system = elgg_solr_get_system_count($options, $starttime, $endtime);
930
931
				$stats[date('i', $starttime)] = array(
932
					'count' => $system,
933
					'indexed' => $indexed,
934
					'starttime' => $starttime,
935
					'endtime' => $endtime,
936
					'block' => false
937
				);
938
			}
939
			break;
940 View Code Duplication
		case 'day':
941
			for ($i = 0; $i < 24; $i++) {
942
				$starttime = mktime($i, 0, 0, date('m', $time), date('j', $time), date('Y', $time));
943
				$endtime = mktime($i + 1, 0, 0, date('m', $time), date('j', $time), date('Y', $time)) - 1;
944
945
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
946
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
947
				$system = elgg_solr_get_system_count($options, $starttime, $endtime);
948
949
				$stats[date('H', $starttime)] = array(
950
					'count' => $system,
951
					'indexed' => $indexed,
952
					'starttime' => $starttime,
953
					'endtime' => $endtime,
954
					'block' => 'hour'
955
				);
956
			}
957
			break;
958 View Code Duplication
		case 'month':
959
			for ($i = 1; $i < date('t', $time) + 1; $i++) {
960
				$starttime = mktime(0, 0, 0, date('m', $time), $i, date('Y', $time));
961
				$endtime = mktime(0, 0, 0, date('m', $time), $i + 1, date('Y', $time)) - 1;
962
963
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
964
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
965
				$system = elgg_solr_get_system_count($options, $starttime, $endtime);
966
967
				$stats[date('d', $starttime)] = array(
968
					'count' => $system,
969
					'indexed' => $indexed,
970
					'starttime' => $starttime,
971
					'endtime' => $endtime,
972
					'block' => 'day'
973
				);
974
			}
975
			break;
976
		case 'year':
977
			for ($i = 1; $i < 13; $i++) {
978
				$starttime = mktime(0, 0, 0, $i, 1, date('Y', $time));
979
				$endtime = mktime(0, 0, 0, $i + 1, 1, date('Y', $time)) - 1;
980
981
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
982
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
983
				$system = elgg_solr_get_system_count($options, $starttime, $endtime);
984
985
				$stats[date('F', $starttime)] = array(
986
					'count' => $system,
987
					'indexed' => $indexed,
988
					'starttime' => $starttime,
989
					'endtime' => $endtime,
990
					'block' => 'month'
991
				);
992
			}
993
			break;
994
995
		case 'all':
996
		default:
997
			$startyear = date('Y', elgg_get_site_entity()->time_created);
998
			$currentyear = date('Y');
999
1000
			for ($i = $currentyear; $i > $startyear - 1; $i--) {
1001
				$starttime = mktime(0, 0, 0, 1, 1, $i);
1002
				$endtime = mktime(0, 0, 0, 1, 1, $i + 1) - 1;
1003
1004
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
1005
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
1006
				$system = elgg_solr_get_system_count($options, $starttime, $endtime);
1007
1008
				$stats[$i] = array(
1009
					'count' => $system,
1010
					'indexed' => $indexed,
1011
					'starttime' => $starttime,
1012
					'endtime' => $endtime,
1013
					'block' => 'year'
1014
				);
1015
			}
1016
1017
			break;
1018
	}
1019
1020
	return $stats;
1021
}
1022
1023
function elgg_solr_get_system_count($options, $starttime, $endtime) {
1024
	$options['wheres'] = array(
1025
		"e.time_created >= {$starttime}",
1026
		"e.time_created <= {$endtime}"
1027
	);
1028
1029
	$options['count'] = true;
1030
1031
	$access = access_get_show_hidden_status();
1032
	access_show_hidden_entities(true);
1033
	$count = elgg_get_entities($options);
1034
	access_show_hidden_entities($access);
1035
1036
	return $count;
1037
}
1038
1039
function elgg_solr_get_display_datetime($time, $block) {
1040
1041
	switch ($block) {
1042
		case 'year':
1043
			$format = 'Y';
1044
			break;
1045
		case 'month':
1046
			$format = 'F Y';
1047
			break;
1048
		case 'day':
1049
			$format = 'F j, Y';
1050
			break;
1051
		case 'hour':
1052
			$format = 'F j, Y H:00';
1053
			break;
1054
		case 'minute':
1055
			$format = 'F j, Y H:i';
1056
			break;
1057
		case 'all':
1058
		default:
1059
			return elgg_echo('elgg_solr:time:all');
1060
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1061
	}
1062
1063
	return date($format, $time);
1064
}
1065
1066
/**
1067
 * Returns an array of tags for indexing
1068
 * 
1069
 * @param type $entity
1070
 * @return string
1071
 */
1072
function elgg_solr_get_tags_array($entity) {
1073
	$valid_tag_names = elgg_get_registered_tag_metadata_names();
1074
1075
	$t = array();
1076
	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...
1077
		foreach ($valid_tag_names as $tagname) {
1078
			$tags = $entity->$tagname;
1079
			if ($tags && !is_array($tags)) {
1080
				$tags = array($tags);
1081
			}
1082
1083
			if ($tags && is_array($tags)) {
1084
				foreach ($tags as $tag) {
1085
					$t[] = $tagname . '%%' . $tag;
1086
				}
1087
			}
1088
		}
1089
	}
1090
1091
	return $t;
1092
}
1093
1094
1095
function elgg_solr_add_tags($doc, $entity) {
1096
	if (!elgg_instanceof($entity)) {
1097
		return $doc;
1098
	}
1099
	
1100
	// store tags the old way - lumped together in $doc->tags as $name . '%%' . $value'
1101
	$doc->tags = elgg_solr_get_tags_array($entity);
1102
	
1103
	// also store them separately with magick fields
1104
	// store in different field types for different search types
1105
	$valid_tag_names = elgg_get_registered_tag_metadata_names();
1106
1107
	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...
1108
		foreach ($valid_tag_names as $tagname) {
1109
			$tags = $entity->$tagname;
1110
			if ($tags && !is_array($tags)) {
1111
				$tags = array($tags);
1112
			}
1113
1114
			$name = 'tag_' . $tagname . '_ss'; // multivalued string
1115
			$doc->$name = $tags;
1116
		}
1117
	}
1118
	
1119
	return $doc;
1120
}
1121
1122 View Code Duplication
function elgg_solr_get_title_boost() {
1123
	static $title_boost;
1124
1125
	if ($title_boost) {
1126
		return $title_boost;
1127
	}
1128
1129
	$title_boost = elgg_get_plugin_setting('title_boost', 'elgg_solr');
1130
	if (!is_numeric($title_boost)) {
1131
		$title_boost = 1.5;
1132
	}
1133
1134
	return $title_boost;
1135
}
1136
1137 View Code Duplication
function elgg_solr_get_description_boost() {
1138
	static $description_boost;
1139
1140
	if ($description_boost) {
1141
		return $description_boost;
1142
	}
1143
1144
	$description_boost = elgg_get_plugin_setting('description_boost', 'elgg_solr');
1145
	if (!is_numeric($description_boost)) {
1146
		$description_boost = 1.5;
1147
	}
1148
1149
	return $description_boost;
1150
}
1151
1152
function elgg_solr_get_boost_query() {
1153
	static $boostquery;
1154
1155
	if ($boostquery || $boostquery === false) {
1156
		return $boostquery;
1157
	}
1158
1159
	$use_boostquery = elgg_get_plugin_setting('use_time_boost', 'elgg_solr');
1160
	if ($use_boostquery != 'yes') {
1161
		$boostquery = false;
1162
		return $boostquery;
1163
	}
1164
1165
	$num = elgg_get_plugin_setting('time_boost_num', 'elgg_solr');
1166
	$interval = elgg_get_plugin_setting('time_boost_interval', 'elgg_solr');
1167
	$time_boost = elgg_get_plugin_setting('time_boost', 'elgg_solr');
1168
	$starttime = strtotime("-{$num} {$interval}");
1169
	$now = time();
1170
1171
	if (!is_numeric($num) || !is_numeric($starttime) || !is_numeric($time_boost)) {
1172
		$boostquery = false;
1173
		return $boostquery;
1174
	}
1175
1176
	$boostquery = "time_created:[{$starttime} TO {$now}]^{$time_boost}";
1177
	return $boostquery;
1178
}
1179
1180
function elgg_solr_get_hl_prefix() {
1181
	static $hl_prefix;
1182
1183
	if ($hl_prefix) {
1184
		return $hl_prefix;
1185
	}
1186
1187
	$hl_prefix = elgg_get_plugin_setting('hl_prefix', 'elgg_solr');
1188
1189
	return $hl_prefix;
1190
}
1191
1192
function elgg_solr_get_hl_suffix() {
1193
	static $hl_suffix;
1194
1195
	if ($hl_suffix) {
1196
		return $hl_suffix;
1197
	}
1198
1199
	$hl_suffix = elgg_get_plugin_setting('hl_suffix', 'elgg_solr');
1200
1201
	return $hl_suffix;
1202
}
1203
1204 View Code Duplication
function elgg_solr_defer_index_update($guid) {
1205
	$guids = elgg_get_config('elgg_solr_sync');
1206
	if (!is_array($guids)) {
1207
		$guids = array();
1208
	}
1209
	$guids[$guid] = 1; // use key to keep it unique
1210
1211
	elgg_set_config('elgg_solr_sync', $guids);
1212
}
1213
1214 View Code Duplication
function elgg_solr_defer_index_delete($guid) {
1215
	$delete_guids = elgg_get_config('elgg_solr_delete');
1216
	if (!is_array($delete_guids)) {
1217
		$delete_guids = array();
1218
	}
1219
1220
	$delete_guids[$guid] = 1;
1221
1222
	elgg_set_config('elgg_solr_delete', $delete_guids);
1223
}
1224
1225 View Code Duplication
function elgg_solr_defer_annotation_delete($id) {
1226
	$delete_ids = elgg_get_config('elgg_solr_annotation_delete');
1227
	if (!is_array($delete_ids)) {
1228
		$delete_ids = array();
1229
	}
1230
1231
	$delete_ids[$id] = 1;
1232
1233
	elgg_set_config('elgg_solr_annotation_delete', $delete_ids);
1234
}
1235
1236
1237
// 1.8 only
1238
// copy of elgg_get_entities
1239
// but only returns guids for performance
1240
// ignores access
1241
function elgg_solr_get_entity_guids_18($options) {
1242
	global $CONFIG;
1243
1244
	$defaults = array(
1245
		'types' => ELGG_ENTITIES_ANY_VALUE,
1246
		'subtypes' => ELGG_ENTITIES_ANY_VALUE,
1247
		'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE,
1248
		'guids' => ELGG_ENTITIES_ANY_VALUE,
1249
		'owner_guids' => ELGG_ENTITIES_ANY_VALUE,
1250
		'container_guids' => ELGG_ENTITIES_ANY_VALUE,
1251
		'site_guids' => $CONFIG->site_guid,
1252
		'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE,
1253
		'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE,
1254
		'created_time_lower' => ELGG_ENTITIES_ANY_VALUE,
1255
		'created_time_upper' => ELGG_ENTITIES_ANY_VALUE,
1256
		'reverse_order_by' => false,
1257
		'order_by' => 'e.guid desc',
1258
		'group_by' => ELGG_ENTITIES_ANY_VALUE,
1259
		'limit' => 10,
1260
		'offset' => 0,
1261
		'count' => FALSE,
1262
		'selects' => array(),
1263
		'wheres' => array(),
1264
		'joins' => array(),
1265
		'callback' => false,
1266
		'__ElggBatch' => null,
1267
	);
1268
1269
	$options = array_merge($defaults, $options);
1270
1271
	// can't use helper function with type_subtype_pair because
1272
	// it's already an array...just need to merge it
1273 View Code Duplication
	if (isset($options['type_subtype_pair'])) {
1274
		if (isset($options['type_subtype_pairs'])) {
1275
			$options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], $options['type_subtype_pair']);
1276
		} else {
1277
			$options['type_subtype_pairs'] = $options['type_subtype_pair'];
1278
		}
1279
	}
1280
1281
	$singulars = array('type', 'subtype', 'guid', 'owner_guid', 'container_guid', 'site_guid');
1282
	$options = elgg_normalise_plural_options_array($options, $singulars);
1283
1284
	// evaluate where clauses
1285
	if (!is_array($options['wheres'])) {
1286
		$options['wheres'] = array($options['wheres']);
1287
	}
1288
1289
	$wheres = $options['wheres'];
1290
1291
	$wheres[] = elgg_get_entity_type_subtype_where_sql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
1292
1293
	$wheres[] = elgg_get_guid_based_where_sql('e.guid', $options['guids']);
1294
	$wheres[] = elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']);
1295
	$wheres[] = elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']);
1296
	$wheres[] = elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']);
1297
1298
	$wheres[] = elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']);
1299
1300
	// see if any functions failed
1301
	// remove empty strings on successful functions
1302 View Code Duplication
	foreach ($wheres as $i => $where) {
1303
		if ($where === FALSE) {
1304
			return FALSE;
1305
		} elseif (empty($where)) {
1306
			unset($wheres[$i]);
1307
		}
1308
	}
1309
1310
	// remove identical where clauses
1311
	$wheres = array_unique($wheres);
1312
1313
	// evaluate join clauses
1314
	if (!is_array($options['joins'])) {
1315
		$options['joins'] = array($options['joins']);
1316
	}
1317
1318
	// remove identical join clauses
1319
	$joins = array_unique($options['joins']);
1320
1321 View Code Duplication
	foreach ($joins as $i => $join) {
1322
		if ($join === FALSE) {
1323
			return FALSE;
1324
		} elseif (empty($join)) {
1325
			unset($joins[$i]);
1326
		}
1327
	}
1328
1329
	// evalutate selects
1330 View Code Duplication
	if ($options['selects']) {
1331
		$selects = '';
1332
		foreach ($options['selects'] as $select) {
1333
			$selects .= ", $select";
1334
		}
1335
	} else {
1336
		$selects = '';
1337
	}
1338
1339 View Code Duplication
	if (!$options['count']) {
1340
		$distinct = '';
1341
		if ($options['require_distinct']) {
1342
			$distinct = ' DISTINCT';
1343
		}
1344
		$query = "SELECT{$distinct} e.guid FROM {$CONFIG->dbprefix}entities e ";
1345
	} else {
1346
		$query = "SELECT count(DISTINCT e.guid) as total FROM {$CONFIG->dbprefix}entities e ";
1347
	}
1348
1349
	// add joins
1350
	foreach ($joins as $j) {
1351
		$query .= " $j ";
1352
	}
1353
1354
	// add wheres
1355
	$query .= ' WHERE ';
1356
1357
	foreach ($wheres as $w) {
1358
		$query .= " $w AND ";
1359
	}
1360
1361
	// Add access controls
1362
	$query .= get_access_sql_suffix('e');
1363
1364
	// reverse order by
1365
	if ($options['reverse_order_by']) {
1366
		$options['order_by'] = elgg_sql_reverse_order_by_clause($options['order_by']);
1367
	}
1368
1369
	if (!$options['count']) {
1370
		if ($options['group_by']) {
1371
			$query .= " GROUP BY {$options['group_by']}";
1372
		}
1373
1374
		if ($options['order_by']) {
1375
			$query .= " ORDER BY {$options['order_by']}";
1376
		}
1377
1378 View Code Duplication
		if ($options['limit']) {
1379
			$limit = sanitise_int($options['limit'], false);
1380
			$offset = sanitise_int($options['offset'], false);
1381
			$query .= " LIMIT $offset, $limit";
1382
		}
1383
1384
		$dt = get_data($query);
1385
1386
		return $dt;
1387
	} else {
1388
		$total = get_data_row($query);
1389
		return (int) $total->total;
1390
	}
1391
}
1392
1393
function elgg_solr_get_entity_guids(array $options = array()) {
1394
	global $CONFIG;
1395
1396
	$defaults = array(
1397
		'types' => ELGG_ENTITIES_ANY_VALUE,
1398
		'subtypes' => ELGG_ENTITIES_ANY_VALUE,
1399
		'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE,
1400
		'guids' => ELGG_ENTITIES_ANY_VALUE,
1401
		'owner_guids' => ELGG_ENTITIES_ANY_VALUE,
1402
		'container_guids' => ELGG_ENTITIES_ANY_VALUE,
1403
		'site_guids' => $CONFIG->site_guid,
1404
		'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE,
1405
		'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE,
1406
		'created_time_lower' => ELGG_ENTITIES_ANY_VALUE,
1407
		'created_time_upper' => ELGG_ENTITIES_ANY_VALUE,
1408
		'reverse_order_by' => false,
1409
		'order_by' => 'e.time_created desc',
1410
		'group_by' => ELGG_ENTITIES_ANY_VALUE,
1411
		'limit' => 10,
1412
		'offset' => 0,
1413
		'count' => false,
1414
		'selects' => array(),
1415
		'wheres' => array(),
1416
		'joins' => array(),
1417
		'callback' => false,
1418
		'__ElggBatch' => null,
1419
	);
1420
1421
	$options = array_merge($defaults, $options);
1422
1423
	// can't use helper function with type_subtype_pair because
1424
	// it's already an array...just need to merge it
1425 View Code Duplication
	if (isset($options['type_subtype_pair'])) {
1426
		if (isset($options['type_subtype_pairs'])) {
1427
			$options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], $options['type_subtype_pair']);
1428
		} else {
1429
			$options['type_subtype_pairs'] = $options['type_subtype_pair'];
1430
		}
1431
	}
1432
1433
	$singulars = array('type', 'subtype', 'guid', 'owner_guid', 'container_guid', 'site_guid');
1434
	$options = _elgg_normalize_plural_options_array($options, $singulars);
1435
1436
	// evaluate where clauses
1437
	if (!is_array($options['wheres'])) {
1438
		$options['wheres'] = array($options['wheres']);
1439
	}
1440
1441
	$wheres = $options['wheres'];
1442
1443
	$wheres[] = _elgg_get_entity_type_subtype_where_sql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
1444
1445
	$wheres[] = _elgg_get_guid_based_where_sql('e.guid', $options['guids']);
1446
	$wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']);
1447
	$wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']);
1448
	$wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']);
1449
1450
	$wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']);
1451
1452
	// see if any functions failed
1453
	// remove empty strings on successful functions
1454 View Code Duplication
	foreach ($wheres as $i => $where) {
1455
		if ($where === false) {
1456
			return false;
1457
		} elseif (empty($where)) {
1458
			unset($wheres[$i]);
1459
		}
1460
	}
1461
1462
	// remove identical where clauses
1463
	$wheres = array_unique($wheres);
1464
1465
	// evaluate join clauses
1466
	if (!is_array($options['joins'])) {
1467
		$options['joins'] = array($options['joins']);
1468
	}
1469
1470
	// remove identical join clauses
1471
	$joins = array_unique($options['joins']);
1472
1473 View Code Duplication
	foreach ($joins as $i => $join) {
1474
		if ($join === false) {
1475
			return false;
1476
		} elseif (empty($join)) {
1477
			unset($joins[$i]);
1478
		}
1479
	}
1480
1481
	// evalutate selects
1482 View Code Duplication
	if ($options['selects']) {
1483
		$selects = '';
1484
		foreach ($options['selects'] as $select) {
1485
			$selects .= ", $select";
1486
		}
1487
	} else {
1488
		$selects = '';
1489
	}
1490
1491 View Code Duplication
	if (!$options['count']) {
1492
		$distinct = '';
1493
		if ($options['require_distinct']) {
1494
			$distinct = ' DISTINCT';
1495
		}
1496
		$query = "SELECT{$distinct} e.guid{$selects} FROM {$CONFIG->dbprefix}entities e ";
1497
	} else {
1498
		$query = "SELECT count(DISTINCT e.guid) as total FROM {$CONFIG->dbprefix}entities e ";
1499
	}
1500
1501
	// add joins
1502
	foreach ($joins as $j) {
1503
		$query .= " $j ";
1504
	}
1505
1506
	// add wheres
1507
	$query .= ' WHERE ';
1508
1509
	foreach ($wheres as $w) {
1510
		$query .= " $w AND ";
1511
	}
1512
1513
	// Add access controls
1514
	$query .= _elgg_get_access_where_sql();
1515
1516
	// reverse order by
1517
	if ($options['reverse_order_by']) {
1518
		$options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']);
0 ignored issues
show
Documentation introduced by
$options['order_by'] is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1519
	}
1520
1521
	if (!$options['count']) {
1522
		if ($options['group_by']) {
1523
			$query .= " GROUP BY {$options['group_by']}";
1524
		}
1525
1526
		if ($options['order_by']) {
1527
			$query .= " ORDER BY {$options['order_by']}";
1528
		}
1529
1530 View Code Duplication
		if ($options['limit']) {
1531
			$limit = sanitise_int($options['limit'], false);
0 ignored issues
show
Documentation introduced by
$options['limit'] is of type array|string, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1532
			$offset = sanitise_int($options['offset'], false);
0 ignored issues
show
Documentation introduced by
$options['offset'] is of type array|string, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1533
			$query .= " LIMIT $offset, $limit";
1534
		}
1535
1536
		if ($options['callback'] === 'entity_row_to_elggstar') {
1537
			$dt = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']);
1538
		} else {
1539
			$dt = get_data($query, $options['callback']);
0 ignored issues
show
Bug introduced by
It seems like $options['callback'] can also be of type array; however, get_data() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1540
		}
1541
1542
		if ($dt) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $dt 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...
1543
			// populate entity and metadata caches
1544
			$guids = array();
1545 View Code Duplication
			foreach ($dt as $item) {
1546
				// A custom callback could result in items that aren't ElggEntity's, so check for them
1547
				if ($item instanceof ElggEntity) {
1548
					_elgg_cache_entity($item);
1549
					// plugins usually have only settings
1550
					if (!$item instanceof ElggPlugin) {
1551
						$guids[] = $item->guid;
1552
					}
1553
				}
1554
			}
1555
			// @todo Without this, recursive delete fails. See #4568
1556
			reset($dt);
1557
1558
			if ($guids) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $guids 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...
1559
				_elgg_get_metadata_cache()->populateFromEntities($guids);
1560
			}
1561
		}
1562
		return $dt;
1563
	} else {
1564
		$total = get_data_row($query);
1565
		return (int) $total->total;
1566
	}
1567
}
1568
1569
function elgg_solr_index_annotation($annotation) {
1570
	$client = elgg_solr_get_client();
1571
	$commit = elgg_get_config('elgg_solr_nocommit') ? false : true;
1572
1573
	$query = $client->createUpdate();
1574
1575
	// add document
1576
	$doc = $query->createDocument();
1577
	$doc->id = 'annotation:' . $annotation->id;
1578
	$doc->type = 'annotation';
1579
	$doc->subtype = $annotation->name;
1580
	$doc->owner_guid = $annotation->owner_guid;
1581
	$doc->container_guid = $annotation->entity_guid;
1582
	$doc->access_id = $annotation->access_id;
1583
	$doc->description = elgg_strip_tags($annotation->value);
1584
	$doc->time_created = $annotation->time_created;
1585
	$doc->enabled = $annotation->enabled;
1586
1587
	$doc = elgg_trigger_plugin_hook('elgg_solr:index', 'annotation', array('annotation' => $annotation), $doc);
1588
	
1589
	if (!$doc) {
1590
		return true; // a plugin has stopped the index
1591
	}
1592
1593
	$query->addDocument($doc);
1594
	if ($commit) {
1595
		$query->addCommit($commit);
1596
	}
1597
1598
	// this executes the query and returns the result
1599
	try {
1600
		$client->update($query);
1601
	} catch (Exception $exc) {
1602
		error_log($exc->getMessage());
1603
	}
1604
}
1605
1606
/**
1607
 * Note - only needed for 1.8
1608
 * 
1609
 * @param type $time
1610
 * @param type $block
1611
 * @return type
1612
 */
1613
function elgg_solr_get_comment_stats($time, $block) {
1614
	$type = 'annotation';
1615
	$fq = array(
1616
		'subtype' => "subtype:generic_comment"
1617
	);
1618
	$stats = array();
1619
	switch ($block) {
1620
		case 'hour':
1621
			// I don't think we need minute resolution right now...
1622
			break;
1623
		case 'day':
1624
			for ($i = 0; $i < 24; $i++) {
1625
				$starttime = mktime($i, 0, 0, date('m', $time), date('j', $time), date('Y', $time));
1626
				$endtime = mktime($i + 1, 0, 0, date('m', $time), date('j', $time), date('Y', $time)) - 1;
1627
1628
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
1629
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
1630
				$system = elgg_get_annotations(array(
1631
					'annotation_name' => 'generic_comment',
1632
					'annotation_created_time_lower' => $starttime,
1633
					'annotation_created_time_upper' => $endtime,
1634
					'count' => true
1635
				));
1636
1637
				$stats[date('H', $starttime)] = array(
1638
					'count' => $system,
1639
					'indexed' => $indexed,
1640
					'starttime' => $starttime,
1641
					'endtime' => $endtime,
1642
					'block' => false
1643
				);
1644
			}
1645
			break;
1646
		case 'month':
1647
			for ($i = 1; $i < date('t', $time) + 1; $i++) {
1648
				$starttime = mktime(0, 0, 0, date('m', $time), $i, date('Y', $time));
1649
				$endtime = mktime(0, 0, 0, date('m', $time), $i + 1, date('Y', $time)) - 1;
1650
1651
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
1652
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
1653
				$system = elgg_get_annotations(array(
1654
					'annotation_name' => 'generic_comment',
1655
					'annotation_created_time_lower' => $starttime,
1656
					'annotation_created_time_upper' => $endtime,
1657
					'count' => true
1658
				));
1659
1660
				$stats[date('d', $starttime)] = array(
1661
					'count' => $system,
1662
					'indexed' => $indexed,
1663
					'starttime' => $starttime,
1664
					'endtime' => $endtime,
1665
					'block' => 'day'
1666
				);
1667
			}
1668
			break;
1669
		case 'year':
1670
			for ($i = 1; $i < 13; $i++) {
1671
				$starttime = mktime(0, 0, 0, $i, 1, date('Y', $time));
1672
				$endtime = mktime(0, 0, 0, $i + 1, 1, date('Y', $time)) - 1;
1673
1674
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
1675
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
1676
				$system = elgg_get_annotations(array(
1677
					'annotation_name' => 'generic_comment',
1678
					'annotation_created_time_lower' => $starttime,
1679
					'annotation_created_time_upper' => $endtime,
1680
					'count' => true
1681
				));
1682
1683
				$stats[date('F', $starttime)] = array(
1684
					'count' => $system,
1685
					'indexed' => $indexed,
1686
					'starttime' => $starttime,
1687
					'endtime' => $endtime,
1688
					'block' => 'month'
1689
				);
1690
			}
1691
			break;
1692
1693
		case 'all':
1694
		default:
1695
			$startyear = date('Y', elgg_get_site_entity()->time_created);
1696
			$currentyear = date('Y');
1697
1698
			for ($i = $currentyear; $i > $startyear - 1; $i--) {
1699
				$starttime = mktime(0, 0, 0, 1, 1, $i);
1700
				$endtime = mktime(0, 0, 0, 1, 1, $i + 1) - 1;
1701
1702
				$fq['time_created'] = "time_created:[{$starttime} TO {$endtime}]";
1703
				$indexed = elgg_solr_get_indexed_count("type:{$type}", $fq);
1704
				$system = elgg_get_annotations(array(
1705
					'annotation_name' => 'generic_comment',
1706
					'annotation_created_time_lower' => $starttime,
1707
					'annotation_created_time_upper' => $endtime,
1708
					'count' => true
1709
				));
1710
1711
				$stats[$i] = array(
1712
					'count' => $system,
1713
					'indexed' => $indexed,
1714
					'starttime' => $starttime,
1715
					'endtime' => $endtime,
1716
					'block' => 'year'
1717
				);
1718
			}
1719
1720
			break;
1721
	}
1722
1723
	return $stats;
1724
}
1725
1726 View Code Duplication
function elgg_solr_get_log_line($filename) {
1727
	$line = false;
1728
	$f = false;
1729
	if (file_exists($filename)) {
1730
		$f = @fopen($filename, 'r');
1731
	}
1732
1733
	if ($f === false) {
1734
		return false;
1735
	} else {
1736
		$cursor = -1;
1737
1738
		fseek($f, $cursor, SEEK_END);
1739
		$char = fgetc($f);
1740
1741
		/**
1742
		 * Trim trailing newline chars of the file
1743
		 */
1744
		while ($char === "\n" || $char === "\r") {
1745
			fseek($f, $cursor--, SEEK_END);
1746
			$char = fgetc($f);
1747
		}
1748
1749
		/**
1750
		 * Read until the start of file or first newline char
1751
		 */
1752
		while ($char !== false && $char !== "\n" && $char !== "\r") {
1753
			/**
1754
			 * Prepend the new char
1755
			 */
1756
			$line = $char . $line;
1757
			fseek($f, $cursor--, SEEK_END);
1758
			$char = fgetc($f);
1759
		}
1760
	}
1761
1762
	return $line;
1763
}
1764
1765
1766
function elgg_solr_get_cores() {
1767
	$options = elgg_solr_get_adapter_options();
1768
	
1769
	if (!$options['host'] || !$options['port'] || !$options['path']) {
1770
		return array();
1771
	}
1772
	
1773
	$cores = array();
1774
1775
    $url = "http://{$options['host']}:{$options['port']}{$options['path']}admin/cores?action=STATUS&wt=json";
1776
1777
    // Initialize cURL
1778
    $ch = curl_init();
1779
1780
    curl_setopt($ch, CURLOPT_URL, $url);
1781
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
1782
    curl_setopt($ch, CURLOPT_POST, 1);
1783
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1784
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
1785
1786
    $response = curl_exec($ch);
1787
1788
    $status = json_decode($response);
1789
1790
	if (is_object($status)) {
1791
		$array = json_decode(json_encode($status), true);
1792
		
1793
		foreach ($array['status'] as $name => $params) {
1794
			$cores[] = $name;
1795
		}
1796
	}
1797
	
1798
	return $cores;
1799
}
1800
1801
1802
function elgg_solr_is_elgg18() {
1803
	$version_getter = 'get_version';
1804
	if (is_callable('elgg_get_version')) {
1805
		$version_getter = 'elgg_get_version';
1806
	}
1807
	
1808
	$is_elgg18 = (strpos($version_getter(true), '1.8') === 0);
1809
	
1810
	return $is_elgg18;
1811
}
1812
1813
1814
function elgg_solr_get_fragsize() {
1815
	static $fragsize;
1816
	if ($fragsize) {
1817
		return (int) $fragsize;
1818
	}
1819
	
1820
	$setting = elgg_get_plugin_setting('fragsize', 'elgg_solr');
1821
	if (is_numeric($setting)) {
1822
		$fragsize = (int) $setting;
1823
	}
1824
	else {
1825
		$fragsize = 100;
1826
	}
1827
	
1828
	return $fragsize;
1829
}