Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

elgg_get_site_entity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
ccs 1
cts 1
cp 1
crap 1
1
<?php
2
/**
3
 * Procedural code for creating, loading, and modifying \ElggEntity objects.
4
 */
5
6
/**
7
 * Return the class name registered as a constructor for an entity of a given type and subtype
8
 *
9
 * @see elgg_set_entity_type()
10
 *
11
 * @param string $type    The type
12
 * @param string $subtype The subtype
13
 *
14
 * @return string
15
 */
16
function elgg_get_entity_class($type, $subtype) {
17 293
	return _elgg_services()->entityTable->getEntityClass($type, $subtype);
18
}
19
20
/**
21
 * Sets class constructor name for entities with given type and subtype
22
 *
23
 * By default entities are loaded as one of the 4 parent objects:
24
 *  - site: ElggSite
25
 *  - user: ElggUser
26
 *  - object: ElggObject
27
 *  - group: ElggGroup
28
 *
29
 * Entity classes for subtypes should extend the base class for entity type,
30
 * e.g. ElggBlog must extend ElggObject
31
 *
32
 * @param string $type    Entity type
33
 * @param string $subtype Entity subtype
34
 * @param string $class   Class name for the object
35
 *                        Can be empty to reset previously declared class name
36
 *
37
 * @return void
38
 */
39
function elgg_set_entity_class($type, $subtype, $class = "") {
40 4791
	_elgg_services()->entityTable->setEntityClass($type, $subtype, $class);
41 4791
}
42
43
44
/**
45
 * Returns a database row from the entities table.
46
 *
47
 * @tip Use get_entity() to return the fully loaded entity.
48
 *
49
 * @warning This will only return results if a) it exists, b) you have access to it.
50
 * see {@link _elgg_get_access_where_sql()}.
51
 *
52
 * @param int $guid The GUID of the object to extract
53
 *
54
 * @return \stdClass|false
55
 * @see entity_row_to_elggstar()
56
 * @access private
57
 */
58
function get_entity_as_row($guid) {
59
	return _elgg_services()->entityTable->getRow($guid);
60
}
61
62
/**
63
 * Create an Elgg* object from a given entity row.
64
 *
65
 * Handles loading all tables into the correct class.
66
 *
67
 * @param \stdClass $row The row of the entry in the entities table.
68
 *
69
 * @return \ElggEntity|false
70
 * @see get_entity_as_row()
71
 * @see get_entity()
72
 * @access private
73
 *
74
 * @throws ClassException|InstallationException
75
 */
76
function entity_row_to_elggstar($row) {
77 424
	return _elgg_services()->entityTable->rowToElggStar($row);
78
}
79
80
/**
81
 * Loads and returns an entity object from a guid.
82
 *
83
 * @param int $guid The GUID of the entity
84
 *
85
 * @return \ElggEntity The correct Elgg or custom object based upon entity type and subtype
86
 */
87
function get_entity($guid) {
88 648
	if ($guid == 1) {
89 13
		return _elgg_config()->site;
90
	}
91 642
	return _elgg_services()->entityTable->get($guid);
0 ignored issues
show
Bug Best Practice introduced by Evan Winslow
The expression return _elgg_services()->entityTable->get($guid) returns the type false which is incompatible with the documented return type ElggEntity.
Loading history...
92
}
93
94
/**
95
 * Does an entity exist?
96
 *
97
 * This function checks for the existence of an entity independent of access
98
 * permissions. It is useful for situations when a user cannot access an entity
99
 * and it must be determined whether entity has been deleted or the access level
100
 * has changed.
101
 *
102
 * @param int $guid The GUID of the entity
103
 *
104
 * @return bool
105
 * @since 1.8.0
106
 */
107
function elgg_entity_exists($guid) {
108
	return _elgg_services()->entityTable->exists($guid);
109
}
110
111
/**
112
 * Enable an entity.
113
 *
114
 * @param int  $guid      GUID of entity to enable
115
 * @param bool $recursive Recursively enable all entities disabled with the entity?
116
 *
117
 * @return bool
118
 * @since 1.9.0
119
 */
120
function elgg_enable_entity($guid, $recursive = true) {
121
	return _elgg_services()->entityTable->enable($guid, $recursive);
122
}
123
124
/**
125
 * Get the current site entity
126
 *
127
 * @return \ElggSite
128
 * @since 1.8.0
129
 */
130
function elgg_get_site_entity() {
131 237
	return _elgg_config()->site;
132
}
133
134
/**
135
 * Fetches/counts entities or performs a calculation on their properties
136
 *
137
 * Note that you can use singulars for most options, e.g. $options['type'] will be normalized to $options['types']
138
 *
139
 * ------------------------
140
 * TYPE SUBTYPE CONSTRAINTS
141
 * ------------------------
142
 *
143
 * Filter entities by their type and subtype
144
 *
145
 * @option string[] $types
146
 * @option string[] $subtypes
147
 * @option string[] $type_subtype_pairs
148
 *
149
 * <code>
150
 * $options['types'] = ['object'];
151
 * $options['subtypes'] = ['blog', 'file'];
152
 * $options['type_subtype_pairs'] = [
153
 *     'object' => ['blog', 'file'],
154
 *     'group' => [], // all group subtypes
155
 *     'user' => null, // all user subtypes
156
 * ];
157
 * </code>
158
 *
159
 * ----------------
160
 * GUID CONSTRAINTS
161
 * ----------------
162
 *
163
 * Filter entities by their guid, owner or container
164
 *
165
 * @option int[]|ElggEntity[] $guids
166
 * @option int[]|ElggEntity[] $owner_guids
167
 * @option int[]|ElggEntity[] $container_guids
168
 *
169
 * ----------------
170
 * TIME CONSTRAINTS
171
 * ----------------
172
 *
173
 * Filter entities that were created, updated or last acted on within certain bounds
174
 *
175
 * @option DateTime|string|int $created_after
176
 * @option DateTime|string|int $created_before
177
 * @option DateTime|string|int $updated_after
178
 * @option DateTime|string|int $updated_before
179
 * @option DateTime|string|int $last_action_after
180
 * @option DateTime|string|int $last_action_before
181
 *
182
 * <code>
183
 * $options['created_after'] = '-1 year';
184
 * $options['created_before'] = 'now';
185
 * </code>
186
 *
187
 * ------------------
188
 * ACCESS CONSTRAINTS
189
 * ------------------
190
 *
191
 * Filter entities by their access_id attribute. Note that this filter apply to entities that the user has access to.
192
 * You can ignore access system using {@link elgg_set_ignore_access()}
193
 *
194
 * @option int[] $access_id
195
 *
196
 * ----------------
197
 * LIMIT AND OFFSET
198
 * ----------------
199
 *
200
 * This options are used for paginating lists of entities
201
 *
202
 * @option int $limit
203
 * @option int $offset
204
 *
205
 * --------------------
206
 * METADATA CONSTRAINTS
207
 * --------------------
208
 *
209
 * Filter entities by their metadata and attributes
210
 *
211
 * The following options will be merged and applied as a metadata pair to @options['metadata_name_value_pairs']
212
 * Note metadata names can contain attributes names and will be resolved automatically during query building.
213
 * @option int[]                $metadata_ids
214
 * @option string[]             $metadata_names
215
 * @option mixed                $metadata_values
216
 * @option DateTime|string|int  $metadata_created_after
217
 * @option DateTime|string|int  $metadata_created_before
218
 * @option bool                 $metadata_case_sensitive
219
 *
220
 * Metadata name value pairs will be joined by the boolean specified in $metadata_name_value_pairs_operator
221
 * @option array                $metadata_name_value_pairs
222
 * @option string               $metadata_name_value_pairs_operator
223
 *
224
 * In addition to metadata name value pairs, you can specify search pair, which will be merged using OR boolean
225
 * and will filter entities regardless of metadata name value pairs and their operator
226
 *
227
 * @option array                $search_name_value_pairs
228
 *
229
 * <code>
230
 * // Search for entities with:
231
 * // status of draft or unsaved_draft
232
 * // AND index greater than 5
233
 * // AND (title/description containing the word hello OR tags containing the word world)
234
 * $options['metadata_name_value_pairs'] = [
235
 *    [
236
 *       'name' => 'status',
237
 *       'value' => ['draft', 'unsaved_draft'],
238
 *       'operand' => 'IN',
239
 *       'created_after' => '-1 day',
240
 *    ],
241
 *    [
242
 *        'name' => 'index',
243
 *        'value' => 5,
244
 *        'operand' => '>=',
245
 *        'type' => ELGG_VALUE_INTEGER,
246
 *    ]
247
 * ];
248
 * $options['search_name_value_pairs'] = [
249
 *    [
250
 *       'name' => ['title', 'description'],
251
 *       'value' => '%hello%',
252
 *       'operand' => 'LIKE',
253
 *       'case_sensitive' => false,
254
 *    ],
255
 *    [
256
 *       'name' => 'tags',
257
 *       'value' => '%world%',
258
 *       'operand' => 'LIKE',
259
 *       'case_sensitive' => false,
260
 *    ],
261
 * ];
262
 * </code>
263
 *
264
 * ----------------------
265
 * ANNOTATION CONSTRAINTS
266
 * ----------------------
267
 *
268
 * Filter entities by their annotations
269
 *
270
 * The following options will be merged and applied as an annotation pair to @options['annotation_name_value_pairs']
271
 * @option int[]                $annotation_ids
272
 * @option string[]             $annotation_names
273
 * @option mixed                $annotation_values
274
 * @option bool                 $annotation_case_sensitive
275
 * @option DateTime|string|int  $annotation_created_after
276
 * @option DateTime|string|int  $annotation_created_before
277
 * @option int[]|ElggEntity[]   $annotation_owner_guids
278
 * @option int[]|ElggEntity[]   $annotation_access_ids
279
 *
280
 * Annotation name value pairs will be joined by the boolean specified in $annotation_name_value_pairs_operator
281
 * @option array                $annotation_name_value_pairs
282
 * @option string               $annotation_name_value_pairs_operator
283
 **
284
 * <code>
285
 * $options['annotation_name_value_pairs'] = [
286
 *    [
287
 *       'name' => 'likes',
288
 *       'created_after' => '-1 day',
289
 *    ],
290
 *    [
291
 *        'name' => 'rating',
292
 *        'value' => 5,
293
 *        'operand' => '>=',
294
 *        'type' => ELGG_VALUE_INTEGER,
295
 *    ],
296
 *    [
297
 *        'name' => 'review',
298
 *        'value' => '%awesome%',
299
 *        'operand' => 'LIKE',
300
 *        'type' => ELGG_VALUE_STRING,
301
 *    ]
302
 * ];
303
 * </code>
304
 *
305
 * ------------------------
306
 * RELATIONSHIP CONSTRAINTS
307
 * ------------------------
308
 *
309
 * Filter entities by their relationships
310
 *
311
 * The following options will be merged and applied as a relationship pair to $options['relationship_name_value_pairs']
312
 * @option int[]                $relationship_ids
313
 * @option string[]             $relationship
314
 * @option int[]|ElggEntity[]   $relationship_guid
315
 * @option bool                 $inverse_relationship
316
 * @option DateTime|string|int  $relationship_created_after
317
 * @option DateTime|string|int  $relationship_created_before
318
 * @option string               $relationship_join_on Column name in the name main table
319
 *
320
 * @option array                $relationship_pairs
321
 *
322
 * <code>
323
 * // Get all entities that user with guid 25 has friended or been friended by
324
 * $options['relationship_pairs'] = [
325
 *    [
326
 *       'relationship' => 'friend',
327
 *       'relationship_guid' => 25,
328
 *       'inverse_relationship' => true,
329
 *    ],
330
 *    [
331
 *       'relationship' => 'friend',
332
 *       'relationship_guid' => 25,
333
 *       'inverse_relationship' => false,
334
 *    ],
335
 * ];
336
 * </code>
337
 *
338
 * ----------------------------
339
 * PRIVATE SETTINGS CONSTRAINTS
340
 * ----------------------------
341
 *
342
 * Filter entities by their private settings
343
 *
344
 * The following options will be merged and applied as a private_setting pair to
345
 * $options['private_setting_name_value_pairs']
346
 * @option int[]                $private_setting_ids
347
 * @option string[]             $private_setting_names
348
 * @option mixed                $private_setting_values
349
 * @option bool                 $private_setting_case_sensitive
350
 *
351
 * Private name value pairs will be joined by the boolean specified in $private_setting_name_value_pairs_operator
352
 * @option array                $private_setting_name_value_pairs
353
 * @option string               $private_setting_name_value_pairs_operator
354
 *
355
 * Setting names in all pairs can be namespaced using the prefix
356
 * @option string               $private_setting_name_prefix
357
 *
358
 * <code>
359
 * $options['private_setting_name_value_pairs'] = [
360
 *    [
361
 *       'name' => 'handler',
362
 *       'value' => ['admin', 'dashboard'],
363
 *       'operand' => 'IN',
364
 *    ],
365
 * ];
366
 * </code>
367
 *
368
 * -------
369
 * SORTING
370
 * -------
371
 *
372
 * You can specify sorting options using ONE of the following options
373
 *
374
 * Order by a calculation performed on annotation name value pairs
375
 * $option array annotation_sort_by_calculation e.g. avg, max, min, sum
376
 *
377
 * Order by value of a specific annotation
378
 * @option array $order_by_annotation
379
 *
380
 * Order by value of a speicifc metadata/attribute
381
 * @option array $order_by_metadata
382
 *
383
 * Order by arbitrary clauses
384
 * @option array $order_by
385
 *
386
 * <code>
387
 * $options['order_by_metadata'] = [
388
 *     'name' => 'priority',
389
 *     'direction' => 'DESC',
390
 *     'as' => 'integer',
391
 * ];
392
 * $options['order_by_annotation'] = [
393
 *     'name' => 'priority',
394
 *     'direction' => 'DESC',
395
 *     'as' => 'integer',
396
 * ];
397
 *
398
 * $sort_by = new \Elgg\Database\Clauses\EntitySortByClause();
399
 * $sort_by->property = 'private';
400
 * $sort_by->property_type = 'private_setting';
401
 * $sort_by->join_type = 'left';
402
 *
403
 * $fallback = new \Elgg\Database\Clauses\OrderByClause('e.time_created', 'desc');
404
 *
405
 * $options['order_by'] = [
406
 *     $sort_by,
407
 *     $fallback,
408
 * ];
409
 * </code>
410
 *
411
 * -----------------
412
 * COUNT/CALCULATION
413
 * -----------------
414
 *
415
 * Performs a calculation on a set of entities that match all of the criteria
416
 * If any of these are specific, the return of this function will be int or float
417
 *
418
 * Return total number of entities
419
 * @option bool $count
420
 *
421
 * Perform a calculation on a set of entity's annotations using a numeric sql function
422
 * If specified, the number of annotation name value pairs can not be more than 1, or they must be merged using OR
423
 * operator
424
 * @option string $annotation_calculation e.g. avg, max, min, sum
425
 *
426
 * Perform a calculation on a set of entity's metadat using a numeric sql function
427
 * If specified, the number of metadata name value pairs can not be more than 1, or they must be merged using OR
428
 * operator
429
 * @option string $metadata_calculation e.g. avg, max, min, sum
430
 *
431
 * ----------
432
 * SQL SELECT
433
 * ----------
434
 *
435
 * @option array $selects
436
 * <code>
437
 * $options['selects'] = [
438
 *    'e.last_action AS last_action',
439
 *    function(QueryBulder $qb, $main_alias) {
440
 *        $joined_alias = $qb->joinMetadataTable($main_alias, 'guid', 'status');
441
 *        return "$joined_alias.value AS status";
442
 *    }
443
 * ];
444
 * </code>
445
 *
446
 * --------
447
 * SQL JOIN
448
 * --------
449
 *
450
 * @option array $joins
451
 * <code>
452
 * $on = function(QueryBuilder $qb, $joined_alias, $main_alias) {
453
 *     return $qb->compare("$joined_alias.user_guid", '=', "$main_alias.guid");
454
 * };
455
 * $options['joins'] = [
456
 *     new JoinClause('access_collections_membership', 'acm', $on);
457
 * ];
458
 * </code>
459
 *
460
 * ----------
461
 * SQL GROUPS
462
 * ----------
463
 *
464
 * @option array $group_by
465
 * @option array $having
466
 *
467
 * <code>
468
 * $options['group_by'] = [
469
 *      function(QueryBuilder $qb, $main_alias) {
470
 *          return "$main_alias.guid";
471
 *      }
472
 * ];
473
 * $options['having'] = [
474
 *      function(QueryBuilder $qb, $main_alias) {
475
 *          return $qb->compare("$main_alias.guid", '>=', 50, ELGG_VALUE_INTEGER);
476
 *      }
477
 * ];
478
 * </code>
479
 *
480
 * ---------
481
 * SQL WHERE
482
 * ---------
483
 *
484
 * @option array $where
485
 * <code>
486
 * $options['wheres'] = [
487
 *      function(QueryBuilder $qb, $main_alias) {
488
 *          return $qb->merge([
489
 *              $qb->compare("$main_alias.guid", '>=', 50, ELGG_VALUE_INTEGER),
490
 *              $qb->compare("$main_alias.guid", '<=', 250, ELGG_VALUE_INTEGER),
491
 *          ], 'OR');
492
 *      }
493
 * ];
494
 * </code>
495
 *
496
 * --------------
497
 * RESULT OPTIONS
498
 * --------------
499
 *
500
 * @option bool $distinct           If set to false, Elgg will drop the DISTINCT clause from
501
 *                                  the MySQL query, which will improve performance in some situations.
502
 *                                  Avoid setting this option without a full understanding of the underlying
503
 *                                  SQL query Elgg creates.
504
 *                                  Default: true
505
 * @option callable|false $callback A callback function to pass each row through
506
 *                                  Default: entity_row_to_elggstar
507
 * @option bool $preload_owners     If set to true, this function will preload
508
 *                                  all the owners of the returned entities resulting in better
509
 *                                  performance when displaying entities owned by several users
510
 *                                  Default: false
511
 * @option bool $preload_containers If set to true, this function will preload
512
 *                                  all the containers of the returned entities resulting in better
513
 *                                  performance when displaying entities contained by several users/groups
514
 *                                  Default: false
515
 * @option bool $batch              If set to true, an Elgg\BatchResult object will be returned instead of an array.
516
 *                                  Default: false
517
 * @option bool $batch_inc_offset   If "batch" is used, this tells the batch to increment the offset
518
 *                                  on each fetch. This must be set to false if you delete the batched results.
519
 *                                  Default: true
520
 * @option int  $batch_size         If "batch" is used, this is the number of entities/rows to pull in before
521
 *                                  requesting more.
522
 *                                  Default: 25
523
 *
524
 *
525
 * @see    elgg_list_entities()
526
 * @see    \Elgg\Database\LegacyQueryOptionsAdapter
527
 *
528
 * @param array $options Options
529
 *
530
 * @return \ElggEntity[]|int|mixed If count, int. Otherwise an array or an Elgg\BatchResult. false on errors.
531
 *
532
 * @since 1.7.0
533
 */
534
function elgg_get_entities(array $options = []) {
535 1159
	return \Elgg\Database\Entities::find($options);
536
}
537
538
/**
539
 * Returns a string of rendered entities.
540
 *
541
 * Displays list of entities with formatting specified by the entity view.
542
 *
543
 * @tip Pagination is handled automatically.
544
 *
545
 * @note Internal: This also provides the views for elgg_view_annotation().
546
 *
547
 * @note Internal: If the initial COUNT query returns 0, the $getter will not be called again.
548
 *
549
 * @param array    $options Any options from $getter options plus:
550
 *                   item_view => STR Optional. Alternative view used to render list items
551
 *                   full_view => BOOL Display full view of entities (default: false)
552
 *                   list_type => STR 'list', 'gallery', or 'table'
553
 *                   columns => ARR instances of Elgg\Views\TableColumn if list_type is "table"
554
 *                   list_type_toggle => BOOL Display gallery / list switch
555
 *                   pagination => BOOL Display pagination links
556
 *                   no_results => STR|Closure Message to display when there are no entities
557
 *
558
 * @param callable $getter  The entity getter function to use to fetch the entities.
559
 * @param callable $viewer  The function to use to view the entity list.
560
 *
561
 * @return string
562
 * @since 1.7
563
 * @see elgg_get_entities()
564
 * @see elgg_view_entity_list()
565
 */
566
function elgg_list_entities(array $options = [], $getter = 'elgg_get_entities', $viewer = 'elgg_view_entity_list') {
567
568 4
	elgg_register_rss_link();
569
570 4
	$offset_key = isset($options['offset_key']) ? $options['offset_key'] : 'offset';
571
572
	$defaults = [
573 4
		'offset' => (int) max(get_input($offset_key, 0), 0),
574 4
		'limit' => (int) max(get_input('limit', _elgg_config()->default_limit), 0),
575
		'full_view' => false,
576
		'list_type_toggle' => false,
577
		'pagination' => true,
578 4
		'no_results' => '',
579
	];
580
581 4
	$options = array_merge($defaults, $options);
582
583 4
	$entities = [];
584
	
585 4
	if (!$options['pagination']) {
586 3
		$options['count'] = false;
587 3
		$entities = call_user_func($getter, $options);
588 3
		unset($options['count']);
589
	} else {
590 1
		$options['count'] = true;
591 1
		$count = call_user_func($getter, $options);
592
	
593 1
		if ($count > 0) {
594
			$options['count'] = false;
595
			$entities = call_user_func($getter, $options);
596
		}
597
598 1
		$options['count'] = $count;
599
	}
600
	
601 4
	return call_user_func($viewer, $entities, $options);
602
}
603
604
/**
605
 * Returns a list of months in which entities were updated or created.
606
 *
607
 * @tip Use this to generate a list of archives by month for when entities were added or updated.
608
 *
609
 * @todo document how to pass in array for $subtype
610
 *
611
 * @warning Months are returned in the form YYYYMM.
612
 *
613
 * @param string $type           The type of entity
614
 * @param string $subtype        The subtype of entity
615
 * @param int    $container_guid The container GUID that the entities belong to
616
 * @param int    $ignored        Ignored parameter
617
 * @param string $order_by       Order_by SQL order by clause
618
 *
619
 * @return array|false Either an array months as YYYYMM, or false on failure
620
 */
621
function get_entity_dates($type = '', $subtype = '', $container_guid = 0, $ignored = 0, $order_by = 'time_created') {
1 ignored issue
show
Unused Code introduced by Ismayil Khayredinov
The parameter $ignored is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

621
function get_entity_dates($type = '', $subtype = '', $container_guid = 0, /** @scrutinizer ignore-unused */ $ignored = 0, $order_by = 'time_created') {

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

Loading history...
622
	return _elgg_services()->entityTable->getDates($type, $subtype, $container_guid, $order_by);
623
}
624
625
/**
626
 * Registers an entity type and subtype as a public-facing entity that should
627
 * be shown in search and by {@link elgg_list_registered_entities()}.
628
 *
629
 * @warning Entities that aren't registered here will not show up in search.
630
 *
631
 * @tip Add a language string item:type:subtype to make sure the items are display properly.
632
 *
633
 * @param string $type    The type of entity (object, site, user, group)
634
 * @param string $subtype The subtype to register (may be blank)
635
 *
636
 * @return bool Depending on success
637
 * @see get_registered_entity_types()
638
 */
639
function elgg_register_entity_type($type, $subtype = null) {
640 59
	$type = strtolower($type);
641 59
	if (!in_array($type, \Elgg\Config::getEntityTypes())) {
642
		return false;
643
	}
644
645 59
	$entities = _elgg_config()->registered_entities;
646 59
	if (!$entities) {
647 40
		$entities = [];
648
	}
649
650 59
	if (!isset($entities[$type])) {
651 40
		$entities[$type] = [];
652
	}
653
654 59
	if ($subtype) {
0 ignored issues
show
Bug Best Practice introduced by Brett Profitt
The expression $subtype of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
655 59
		$entities[$type][] = $subtype;
656
	}
657
658 59
	_elgg_config()->registered_entities = $entities;
659
660 59
	return true;
661
}
662
663
/**
664
 * Unregisters an entity type and subtype as a public-facing type.
665
 *
666
 * @warning With a blank subtype, it unregisters that entity type including
667
 * all subtypes. This must be called after all subtypes have been registered.
668
 *
669
 * @param string $type    The type of entity (object, site, user, group)
670
 * @param string $subtype The subtype to register (may be blank)
671
 *
672
 * @return bool Depending on success
673
 * @see elgg_register_entity_type()
674
 */
675
function elgg_unregister_entity_type($type, $subtype = null) {
676
	$type = strtolower($type);
677
	if (!in_array($type, \Elgg\Config::getEntityTypes())) {
678
		return false;
679
	}
680
681
	$entities = _elgg_config()->registered_entities;
682
	if (!$entities) {
683
		return false;
684
	}
685
686
	if (!isset($entities[$type])) {
687
		return false;
688
	}
689
690
	if ($subtype) {
0 ignored issues
show
Bug Best Practice introduced by Cash Costello
The expression $subtype of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
691
		if (in_array($subtype, $entities[$type])) {
692
			$key = array_search($subtype, $entities[$type]);
693
			unset($entities[$type][$key]);
694
		} else {
695
			return false;
696
		}
697
	} else {
698
		unset($entities[$type]);
699
	}
700
701
	_elgg_config()->registered_entities = $entities;
702
	return true;
703
}
704
705
/**
706
 * Returns registered entity types and subtypes
707
 *
708
 * @param string $type The type of entity (object, site, user, group) or blank for all
709
 *
710
 * @return array|false Depending on whether entities have been registered
711
 * @see elgg_register_entity_type()
712
 */
713
function get_registered_entity_types($type = null) {
714 3
	$registered_entities = _elgg_config()->registered_entities;
715 3
	if (!$registered_entities) {
716 1
		return false;
717
	}
718
719 2
	if ($type) {
0 ignored issues
show
Bug Best Practice introduced by Brett Profitt
The expression $type of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
720
		$type = strtolower($type);
721
	}
722
723 2
	if (!empty($type) && !isset($registered_entities[$type])) {
724
		return false;
725
	}
726
727 2
	if (empty($type)) {
728 2
		return $registered_entities;
729
	}
730
731
	return $registered_entities[$type];
732
}
733
734
/**
735
 * Returns if the entity type and subtype have been registered with {@link elgg_register_entity_type()}.
736
 *
737
 * @param string $type    The type of entity (object, site, user, group)
738
 * @param string $subtype The subtype (may be blank)
739
 *
740
 * @return bool Depending on whether or not the type has been registered
741
 */
742
function is_registered_entity_type($type, $subtype = null) {
743
	$registered_entities = _elgg_config()->registered_entities;
744
	if (!$registered_entities) {
745
		return true;
746
	}
747
748
	$type = strtolower($type);
749
750
	// @todo registering a subtype implicitly registers the type.
751
	// see #2684
752
	if (!isset($registered_entities[$type])) {
753
		return false;
754
	}
755
756
	if ($subtype && !in_array($subtype, $registered_entities[$type])) {
0 ignored issues
show
Bug Best Practice introduced by Steve Clay
The expression $subtype of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
757
		return false;
758
	}
759
	return true;
760
}
761
762
/**
763
 * Returns a viewable list of entities based on the registered types.
764
 *
765
 * @see elgg_view_entity_list()
766
 *
767
 * @param array $options Any elgg_get_entity() options plus:
768
 *
769
 * 	full_view => BOOL Display full view entities
770
 *
771
 * 	list_type_toggle => BOOL Display gallery / list switch
772
 *
773
 * 	allowed_types => true|ARRAY True to show all types or an array of valid types.
774
 *
775
 * 	pagination => BOOL Display pagination links
776
 *
777
 * @return string A viewable list of entities
778
 * @since 1.7.0
779
 */
780
function elgg_list_registered_entities(array $options = []) {
781
	elgg_register_rss_link();
782
783
	$defaults = [
784
		'full_view' => false,
785
		'allowed_types' => true,
786
		'list_type_toggle' => false,
787
		'pagination' => true,
788
		'offset' => 0,
789
		'types' => [],
790
		'type_subtype_pairs' => [],
791
	];
792
793
	$options = array_merge($defaults, $options);
794
795
	$types = get_registered_entity_types();
796
797
	foreach ($types as $type => $subtype_array) {
1 ignored issue
show
Bug introduced by Brett Profitt
The expression $types of type false is not traversable.
Loading history...
798
		if (in_array($type, $options['allowed_types']) || $options['allowed_types'] === true) {
799
			// you must explicitly register types to show up in here and in search for objects
800
			if ($type == 'object') {
801
				if (is_array($subtype_array) && count($subtype_array)) {
802
					$options['type_subtype_pairs'][$type] = $subtype_array;
803
				}
804
			} else {
805
				if (is_array($subtype_array) && count($subtype_array)) {
806
					$options['type_subtype_pairs'][$type] = $subtype_array;
807
				} else {
808
					$options['type_subtype_pairs'][$type] = ELGG_ENTITIES_ANY_VALUE;
809
				}
810
			}
811
		}
812
	}
813
814
	if (!empty($options['type_subtype_pairs'])) {
815
		$count = elgg_get_entities(array_merge(['count' => true], $options));
816
		if ($count > 0) {
817
			$entities = elgg_get_entities($options);
818
		} else {
819
			$entities = [];
820
		}
821
	} else {
822
		$count = 0;
823
		$entities = [];
824
	}
825
826
	$options['count'] = $count;
827
	return elgg_view_entity_list($entities, $options);
0 ignored issues
show
Bug introduced by Cash Costello
It seems like $entities can also be of type integer and false; however, parameter $entities of elgg_view_entity_list() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

827
	return elgg_view_entity_list(/** @scrutinizer ignore-type */ $entities, $options);
Loading history...
828
}
829
830
/**
831
 * Checks if $entity is an \ElggEntity and optionally for type and subtype.
832
 *
833
 * @tip Use this function in actions and views to check that you are dealing
834
 * with the correct type of entity.
835
 *
836
 * @param mixed  $entity  Entity
837
 * @param string $type    Entity type
838
 * @param string $subtype Entity subtype
839
 *
840
 * @return bool
841
 * @since 1.8.0
842
 */
843
function elgg_instanceof($entity, $type = null, $subtype = null) {
844 227
	$return = ($entity instanceof \ElggEntity);
845
846 227
	if ($type) {
0 ignored issues
show
Bug Best Practice introduced by Brett Profitt
The expression $type of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
847
		/* @var \ElggEntity $entity */
848 227
		$return = $return && ($entity->getType() == $type);
849
	}
850
851 227
	if ($subtype) {
0 ignored issues
show
Bug Best Practice introduced by Brett Profitt
The expression $subtype of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
852 7
		$return = $return && ($entity->getSubtype() == $subtype);
853
	}
854
855 227
	return $return;
856
}
857
858
/**
859
 * Checks options for the existing of site_guid or site_guids contents and reports a warning if found
860
 *
861
 * @param array $options array of options to check
862
 *
863
 * @return void
864
 */
865
function _elgg_check_unsupported_site_guid(array $options = []) {
866 1301
	$site_guid = elgg_extract('site_guid', $options, elgg_extract('site_guids', $options));
867 1301
	if ($site_guid === null) {
868 1301
		return;
869
	}
870
	
871
	$backtrace = debug_backtrace();
872
	// never show this call.
873
	array_shift($backtrace);
874
875
	if (!empty($backtrace[0]['class'])) {
876
		$warning = "Passing site_guid or site_guids to the method {$backtrace[0]['class']}::{$backtrace[0]['file']} is not supported.";
877
		$warning .= "Please update your usage of the method.";
878
	} else {
879
		$warning = "Passing site_guid or site_guids to the function {$backtrace[0]['function']} in {$backtrace[0]['file']} is not supported.";
880
		$warning .= "Please update your usage of the function.";
881
	}
882
883
	_elgg_services()->logger->warn($warning);
884
}
885
886
/**
887
 * Runs unit tests for the entity objects.
888
 *
889
 * @param string $hook  'unit_test'
890
 * @param string $type  'system'
891
 * @param array  $value Array of tests
892
 *
893
 * @return array
894
 * @access private
895
 * @codeCoverageIgnore
896
 */
897
function _elgg_entities_test($hook, $type, $value) {
2 ignored issues
show
Unused Code introduced by Cash Costello
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

897
function _elgg_entities_test($hook, /** @scrutinizer ignore-unused */ $type, $value) {

This check looks for 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 Cash Costello
The parameter $hook is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

897
function _elgg_entities_test(/** @scrutinizer ignore-unused */ $hook, $type, $value) {

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

Loading history...
898
	$value[] = ElggEntityUnitTest::class;
0 ignored issues
show
Bug introduced by Ismayil Khayredinov
The type ElggEntityUnitTest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
899
	$value[] = ElggCoreGetEntitiesFromAnnotationsTest::class;
900
	$value[] = ElggCoreGetEntitiesFromMetadataTest::class;
901
	$value[] = ElggCoreGetEntitiesFromPrivateSettingsTest::class;
902
	$value[] = ElggCoreGetEntitiesFromRelationshipTest::class;
903
	$value[] = ElggEntityPreloaderIntegrationTest::class;
904
	$value[] = ElggCoreObjectTest::class;
905
	return $value;
906
}
907
908
/**
909
 * Entities init function; establishes the default entity page handler
910
 *
911
 * @return void
912
 * @elgg_event_handler init system
913
 * @access private
914
 */
915
function _elgg_entities_init() {
916 31
	elgg_register_plugin_hook_handler('unit_test', 'system', '_elgg_entities_test');
917 31
}
918
919
/**
920
 * @see \Elgg\Application::loadCore Do not do work here. Just register for events.
921
 */
922
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
1 ignored issue
show
Unused Code introduced by Steve Clay
The parameter $hooks is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

922
return function(\Elgg\EventsService $events, /** @scrutinizer ignore-unused */ \Elgg\HooksRegistrationService $hooks) {

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

Loading history...
923 18
	$events->registerHandler('init', 'system', '_elgg_entities_init');
924
};
925