Passed
Push — master ( 96b2fe...fab0a4 )
by Jeroen
29:16 queued 05:53
created

search_hooks.php ➔ search_groups_hook()   C

Complexity

Conditions 10
Paths 70

Size

Total Lines 65
Code Lines 37

Duplication

Lines 26
Ratio 40 %

Importance

Changes 0
Metric Value
cc 10
eloc 37
nc 70
nop 4
dl 26
loc 65
rs 6.2553
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
 * Elgg core search.
4
 *
5
 * @package Elgg
6
 * @subpackage Search
7
 */
8
9
/**
10
 * Get objects that match the search parameters.
11
 *
12
 * @param string $hook   Hook name
13
 * @param string $type   Hook type
14
 * @param array  $value  Empty array
15
 * @param array  $params Search parameters
16
 * @return array
17
 */
18
function search_objects_hook($hook, $type, $value, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
19
20
	$params['joins'] = (array) elgg_extract('joins', $params, []);
21
	$params['wheres'] = (array) elgg_extract('wheres', $params, []);
22
	
23
	$db_prefix = elgg_get_config('dbprefix');
24
25
	$join = "JOIN {$db_prefix}objects_entity oe ON e.guid = oe.guid";
26
	array_unshift($params['joins'], $join);
27
28
	$fields = ['title', 'description'];
29
	$where = search_get_where_sql('oe', $fields, $params);
30
	$params['wheres'][] = $where;
31
	
32
	$params['count'] = true;
33
	$count = elgg_get_entities($params);
34
	
35
	// no need to continue if nothing here.
36
	if (!$count) {
37
		return ['entities' => [], 'count' => $count];
38
	}
39
	
40
	$params['count'] = false;
41 View Code Duplication
	if (isset($params['sort']) || !isset($params['order_by'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
42
		$params['order_by'] = search_get_order_by_sql('e', 'oe', $params['sort'], $params['order']);
43
	}
44
	$params['preload_owners'] = true;
45
	$entities = elgg_get_entities($params);
46
47
	// add the volatile data for why these entities have been returned.
48 View Code Duplication
	foreach ($entities as $entity) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Bug introduced by
The expression $entities of type object<ElggBatch>|false|integer|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
49
		$title = search_get_highlighted_relevant_substrings($entity->getDisplayName(), $params['query']);
50
		$entity->setVolatileData('search_matched_title', $title);
51
52
		$desc = search_get_highlighted_relevant_substrings($entity->description, $params['query']);
53
		$entity->setVolatileData('search_matched_description', $desc);
54
	}
55
56
	return [
57
		'entities' => $entities,
58
		'count' => $count,
59
	];
60
}
61
62
/**
63
 * Get groups that match the search parameters.
64
 *
65
 * @param string $hook   Hook name
66
 * @param string $type   Hook type
67
 * @param array  $value  Empty array
68
 * @param array  $params Search parameters
69
 * @return array
70
 */
71
function search_groups_hook($hook, $type, $value, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
72
73
	$params['joins'] = (array) elgg_extract('joins', $params, []);
74
	$params['wheres'] = (array) elgg_extract('wheres', $params, []);
75
	
76
	$query = sanitise_string($params['query']);
0 ignored issues
show
Deprecated Code introduced by
The function sanitise_string() has been deprecated with message: Use query parameters where possible

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
77
78
	$query_parts = explode(' ', $query);
79
	$db_prefix = elgg_get_config('dbprefix');
80
81
	$params['joins'][] = "JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
82
	
83
	$fields = ['name', 'description'];
84
	$wheres = [];
85 View Code Duplication
	foreach ($fields as $field) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
		$sublikes = [];
87
		foreach ($query_parts as $query_part) {
88
			$query_part = sanitise_string($query_part);
0 ignored issues
show
Deprecated Code introduced by
The function sanitise_string() has been deprecated with message: Use query parameters where possible

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
89
			if (strlen($query_part) == 0) {
90
				continue;
91
			}
92
			$sublikes[] = "(md.value LIKE '%{$query_part}%')";
93
		}
94
		
95
		if (empty($sublikes)) {
96
			continue;
97
		}
98
		
99
		$wheres[] = "(md.name = '{$field}' AND (" . implode(' AND ', $sublikes) . "))";
100
	}
101
	
102
	if (!empty($wheres)) {
103
		$params['wheres'][] = implode(' OR ', $wheres);
104
	}
105
	
106
	
107
	$params['count'] = true;
108
	
109
	$count = elgg_get_entities($params);
110
	
111
	// no need to continue if nothing here.
112
	if (!$count) {
113
		return ['entities' => [], 'count' => $count];
114
	}
115
	
116
	$params['count'] = false;
117 View Code Duplication
	if (isset($params['sort']) || !isset($params['order_by'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
		$params['order_by'] = search_get_order_by_sql('e', '', $params['sort'], $params['order']);
119
	}
120
	$entities = elgg_get_entities($params);
121
122
	// add the volatile data for why these entities have been returned.
123 View Code Duplication
	foreach ($entities as $entity) {
1 ignored issue
show
Bug introduced by
The expression $entities of type object<ElggBatch>|false|integer|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
		$name = search_get_highlighted_relevant_substrings($entity->getDisplayName(), $query);
125
		$entity->setVolatileData('search_matched_title', $name);
126
127
		$description = search_get_highlighted_relevant_substrings($entity->description, $query);
128
		$entity->setVolatileData('search_matched_description', $description);
129
	}
130
131
	return [
132
		'entities' => $entities,
133
		'count' => $count,
134
	];
135
}
136
137
/**
138
 * Get users that match the search parameters.
139
 *
140
 * Searches on username, display name, and profile fields
141
 *
142
 * @param string $hook   Hook name
143
 * @param string $type   Hook type
144
 * @param array  $value  Empty array
145
 * @param array  $params Search parameters
146
 * @return array
147
 */
148
function search_users_hook($hook, $type, $value, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
149
150
	$params['joins'] = (array) elgg_extract('joins', $params, []);
151
	$params['wheres'] = (array) elgg_extract('wheres', $params, []);
152
	
153
	$db_prefix = elgg_get_config('dbprefix');
154
155
	$query = sanitise_string($params['query']);
0 ignored issues
show
Deprecated Code introduced by
The function sanitise_string() has been deprecated with message: Use query parameters where possible

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
156
157
	$join = "JOIN {$db_prefix}users_entity ue ON e.guid = ue.guid";
158
	array_unshift($params['joins'], $join);
159
		
160
	// username and display name
161
	$fields = ['username', 'name'];
162
	$where = search_get_where_sql('ue', $fields, $params);
163
164
	// profile fields
165
	$profile_fields = array_keys(elgg_get_config('profile_fields'));
166
	
167
	if (!empty($profile_fields)) {
168
		$params['joins'][] = "JOIN {$db_prefix}annotations an on e.guid = an.entity_guid";
169
		
170
		// get the where clauses for the annotation names
171
		// can't use egef_annotations() because the n_table join comes too late.
172
		$clauses = _elgg_entities_get_metastrings_options('annotation', [
173
			'annotation_names' => $profile_fields,
174
175
			// avoid notices
176
			'annotation_values' => null,
177
			'annotation_name_value_pairs' => null,
178
			'annotation_name_value_pairs_operator' => null,
179
			'annotation_case_sensitive' => null,
180
			'order_by_annotation' => null,
181
			'annotation_owner_guids' => null,
182
		]);
183
184
		$params['joins'] = array_merge($clauses['joins'], $params['joins']);
185
		$md_where = "(({$clauses['wheres'][0]}) AND an.value LIKE '%$query%')";
186
		
187
		$params['wheres'][] = "(($where) OR ($md_where))";
188
	} else {
189
		$params['wheres'][] = "$where";
190
	}
191
192
	$params['count'] = true;
193
	$count = elgg_get_entities($params);
194
195
	// no need to continue if nothing here.
196
	if (!$count) {
197
		return ['entities' => [], 'count' => $count];
198
	}
199
	
200
	$params['count'] = false;
201 View Code Duplication
	if (isset($params['sort']) || !isset($params['order_by'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
202
		$params['order_by'] = search_get_order_by_sql('e', 'ue', $params['sort'], $params['order']);
203
	}
204
	$entities = elgg_get_entities($params);
205
	/* @var ElggUser[] $entities */
206
207
	// add the volatile data for why these entities have been returned.
208
	foreach ($entities as $entity) {
0 ignored issues
show
Bug introduced by
The expression $entities of type object<ElggBatch>|false|integer|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
209
		$title = search_get_highlighted_relevant_substrings($entity->getDisplayName(), $query);
210
211
		// include the username if it matches but the display name doesn't.
212
		if (false !== strpos($entity->username, $query)) {
213
			$username = search_get_highlighted_relevant_substrings($entity->username, $query);
214
			$title .= " ($username)";
215
		}
216
217
		$entity->setVolatileData('search_matched_title', $title);
218
219
		if (!empty($profile_fields)) {
220
			$matched = '';
221
			foreach ($profile_fields as $shortname) {
222
				$annotations = $entity->getAnnotations([
223
					'annotation_names' => "profile:$shortname",
224
					'limit' => false,
225
				]);
226
				$values = array_map(function (ElggAnnotation $a) {
227
					return $a->value;
228
				}, $annotations);
229
				foreach ($values as $text) {
230
					if (stristr($text, $query)) {
231
						$matched .= elgg_echo("profile:{$shortname}") . ': '
232
								. search_get_highlighted_relevant_substrings($text, $query);
233
					}
234
				}
235
			}
236
	
237
			$entity->setVolatileData('search_matched_description', $matched);
238
		}
239
	}
240
241
	return [
242
		'entities' => $entities,
243
		'count' => $count,
244
	];
245
}
246
247
/**
248
 * Get entities with tags that match the search parameters.
249
 *
250
 * @param string $hook   Hook name
251
 * @param string $type   Hook type
252
 * @param array  $value  Empty array
253
 * @param array  $params Search parameters
254
 * @return array
255
 */
256
function search_tags_hook($hook, $type, $value, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
257
258
	$params['joins'] = (array) elgg_extract('joins', $params, []);
259
	$params['wheres'] = (array) elgg_extract('wheres', $params, []);
260
261
	$db_prefix = elgg_get_config('dbprefix');
262
263
	$valid_tag_names = elgg_get_registered_tag_metadata_names();
264
265
	// @todo will need to split this up to support searching multiple tags at once.
266
	$query = sanitise_string($params['query']);
0 ignored issues
show
Deprecated Code introduced by
The function sanitise_string() has been deprecated with message: Use query parameters where possible

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
267
268
	// if passed a tag metadata name, only search on that tag name.
269
	// tag_name isn't included in the params because it's specific to
270
	// tag searches.
271
	if ($tag_names = get_input('tag_names')) {
272
		if (is_array($tag_names)) {
273
			$search_tag_names = $tag_names;
274
		} else {
275
			$search_tag_names = [$tag_names];
276
		}
277
278
		// check these are valid to avoid arbitrary metadata searches.
279
		foreach ($search_tag_names as $i => $tag_name) {
280
			if (!in_array($tag_name, $valid_tag_names)) {
281
				unset($search_tag_names[$i]);
282
			}
283
		}
284
	} else {
285
		$search_tag_names = $valid_tag_names;
286
	}
287
288
	if (!$search_tag_names) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search_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...
289
		return ['entities' => [], 'count' => $count];
0 ignored issues
show
Bug introduced by
The variable $count seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
290
	}
291
292
	// don't use elgg_get_entities_from_metadata() here because of
293
	// performance issues.  since we don't care what matches at this point
294
	// use an IN clause to grab everything that matches at once and sort
295
	// out the matches later.
296
	$params['joins'][] = "JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
297
298
	$access = _elgg_get_access_where_sql([
299
		'table_alias' => 'md',
300
		'guid_column' => 'entity_guid',
301
	]);
302
	$sanitised_tags = [];
303
304
	foreach ($search_tag_names as $tag) {
305
		$sanitised_tags[] = '"' . sanitise_string($tag) . '"';
0 ignored issues
show
Deprecated Code introduced by
The function sanitise_string() has been deprecated with message: Use query parameters where possible

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
306
	}
307
308
	$tags_in = implode(',', $sanitised_tags);
309
310
	$params['wheres'][] = "(md.name IN ($tags_in) AND md.value = '$query' AND $access)";
311
312
	$params['count'] = true;
313
	$count = elgg_get_entities($params);
314
315
	// no need to continue if nothing here.
316
	if (!$count) {
317
		return ['entities' => [], 'count' => $count];
318
	}
319
	
320
	$params['count'] = false;
321 View Code Duplication
	if (isset($params['sort']) || !isset($params['order_by'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
322
		$params['order_by'] = search_get_order_by_sql('e', null, $params['sort'], $params['order']);
323
	}
324
	$entities = elgg_get_entities($params);
325
326
	// add the volatile data for why these entities have been returned.
327
	foreach ($entities as $entity) {
0 ignored issues
show
Bug introduced by
The expression $entities of type object<ElggBatch>|false|integer|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
328
		$matched_tags_strs = [];
329
330
		// get tags for each tag name requested to find which ones matched.
331
		foreach ($search_tag_names as $tag_name) {
332
			$tags = $entity->getTags($tag_name);
333
334
			// @todo make one long tag string and run this through the highlight
335
			// function.  This might be confusing as it could chop off
336
			// the tag labels.
337
			if (in_array(strtolower($query), array_map('strtolower', $tags))) {
338
				if (is_array($tags)) {
339
					$tag_name_str = elgg_echo("tag_names:$tag_name");
340
					$matched_tags_strs[] = "$tag_name_str: " . implode(', ', $tags);
341
				}
342
			}
343
		}
344
345
		$title_str = elgg_get_excerpt($entity->getDisplayName(), 300);
346
		$desc_str = elgg_get_excerpt($entity->description, 300);
347
		
348
		$tags_str = implode('. ', $matched_tags_strs);
349
		$tags_str = search_get_highlighted_relevant_substrings($tags_str, $params['query'], 30, 300, true);
350
351
		$entity->setVolatileData('search_matched_title', $title_str);
352
		$entity->setVolatileData('search_matched_description', $desc_str);
353
		$entity->setVolatileData('search_matched_extra', $tags_str);
354
	}
355
356
	return [
357
		'entities' => $entities,
358
		'count' => $count,
359
	];
360
}
361
362
/**
363
 * Register tags as a custom search type.
364
 *
365
 * @param string $hook   Hook name
366
 * @param string $type   Hook type
367
 * @param array  $value  Array of custom search types
368
 * @param array  $params Search parameters
369
 * @return array
370
 */
371
function search_custom_types_tags_hook($hook, $type, $value, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
372
	$value[] = 'tags';
373
	return $value;
374
}
375