bp-groups-functions.php ➔ groups_create_group()   F
last analyzed

Complexity

Conditions 21
Paths 4112

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 123
Code Lines 62

Importance

Changes 0
Metric Value
cc 21
eloc 62
nc 4112
nop 1
dl 0
loc 123
rs 2
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
 * BuddyPress Groups Functions.
4
 *
5
 * Functions are where all the magic happens in BuddyPress. They will
6
 * handle the actual saving or manipulation of information. Usually they will
7
 * hand off to a database class for data access, then return
8
 * true or false on success or failure.
9
 *
10
 * @package BuddyPress
11
 * @subpackage GroupsFunctions
12
 * @since 1.5.0
13
 */
14
15
// Exit if accessed directly.
16
defined( 'ABSPATH' ) || exit;
17
18
/**
19
 * Check whether there is a Groups directory page in the $bp global.
20
 *
21
 * @since 1.5.0
22
 *
23
 * @return bool True if set, False if empty.
24
 */
25
function bp_groups_has_directory() {
26
	$bp = buddypress();
27
28
	return (bool) !empty( $bp->pages->groups->id );
29
}
30
31
/**
32
 * Fetch a single group object.
33
 *
34
 * When calling up a group object, you should always use this function instead
35
 * of instantiating BP_Groups_Group directly, so that you will inherit cache
36
 * support and pass through the groups_get_group filter.
37
 *
38
 * @since 1.2.0
39
 * @since 2.7.0 The function signature was changed to accept a group ID only,
40
 *              instead of an array containing the group ID.
41
 *
42
 * @param int $group_id ID of the group.
43
 * @return BP_Groups_Group $group The group object.
44
 */
45
function groups_get_group( $group_id ) {
46
	/*
47
	 * Backward compatibilty.
48
	 * Old-style arguments take the form of an array or a query string.
49
	 */
50
	if ( ! is_numeric( $group_id ) ) {
51
		$r = bp_parse_args( $group_id, array(
52
			'group_id'        => false,
53
			'load_users'      => false,
54
			'populate_extras' => false,
55
		), 'groups_get_group' );
56
57
		$group_id = $r['group_id'];
0 ignored issues
show
Coding Style introduced by Boone B Gorges
Consider using a different name than the parameter $group_id. This often makes code more readable.
Loading history...
58
	}
59
60
	$group = new BP_Groups_Group( $group_id );
61
62
	/**
63
	 * Filters a single group object.
64
	 *
65
	 * @since 1.2.0
66
	 *
67
	 * @param BP_Groups_Group $group Single group object.
68
	 */
69
	return apply_filters( 'groups_get_group', $group );
70
}
71
72
/** Group Creation, Editing & Deletion ****************************************/
73
74
/**
75
 * Create a group.
76
 *
77
 * @since 1.0.0
78
 *
79
 * @param array|string $args {
80
 *     An array of arguments.
81
 *     @type int|bool $group_id     Pass a group ID to update an existing item, or
82
 *                                  0 / false to create a new group. Default: 0.
83
 *     @type int      $creator_id   The user ID that creates the group.
84
 *     @type string   $name         The group name.
85
 *     @type string   $description  Optional. The group's description.
86
 *     @type string   $slug         The group slug.
87
 *     @type string   $status       The group's status. Accepts 'public', 'private' or
88
 *                                  'hidden'. Defaults to 'public'.
89
 *     @type int      $parent_id    The ID of the parent group. Default: 0.
90
 *     @type int      $enable_forum Optional. Whether the group has a forum enabled.
91
 *                                  If a bbPress forum is enabled for the group,
92
 *                                  set this to 1. Default: 0.
93
 *     @type string   $date_created The GMT time, in Y-m-d h:i:s format, when the group
94
 *                                  was created. Defaults to the current time.
95
 * }
96
 * @return int|bool The ID of the group on success. False on error.
97
 */
98
function groups_create_group( $args = '' ) {
99
100
	$args = bp_parse_args( $args, array(
0 ignored issues
show
Coding Style introduced by Paul Gibbs
Consider using a different name than the parameter $args. This often makes code more readable.
Loading history...
101
		'group_id'     => 0,
102
		'creator_id'   => 0,
103
		'name'         => '',
104
		'description'  => '',
105
		'slug'         => '',
106
		'status'       => null,
107
		'parent_id'    => null,
108
		'enable_forum' => null,
109
		'date_created' => null
110
	), 'groups_create_group' );
111
112
	extract( $args, EXTR_SKIP );
0 ignored issues
show
introduced by Boone B Gorges
extract() usage is highly discouraged, due to the complexity and unintended issues it might cause.
Loading history...
113
114
	// Pass an existing group ID.
115
	if ( ! empty( $group_id ) ) {
116
		$group = groups_get_group( $group_id );
0 ignored issues
show
Bug introduced by Boone B Gorges
It seems like $group_id can also be of type boolean; however, groups_get_group() does only seem to accept integer, 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...
117
		$name  = ! empty( $name ) ? $name : $group->name;
118
		$slug  = ! empty( $slug ) ? $slug : $group->slug;
119
		$creator_id  = ! empty( $creator_id ) ? $creator_id : $group->creator_id;
120
		$description = ! empty( $description ) ? $description : $group->description;
121
		$status = ! is_null( $status ) ? $status : $group->status;
122
		$parent_id = ! is_null( $parent_id ) ? $parent_id : $group->parent_id;
123
		$enable_forum = ! is_null( $enable_forum ) ? $enable_forum : $group->enable_forum;
124
		$date_created = ! is_null( $date_created ) ? $date_created : $group->date_created;
125
126
		// Groups need at least a name.
127
		if ( empty( $name ) ) {
128
			return false;
129
		}
130
131
	// Create a new group.
132
	} else {
133
		// Instantiate new group object.
134
		$group = new BP_Groups_Group;
135
136
		// Check for null values, reset to sensible defaults.
137
		$status = ! is_null( $status ) ? $status : 'public';
138
		$parent_id = ! is_null( $parent_id ) ? $parent_id : 0;
139
		$enable_forum = ! is_null( $enable_forum ) ? $enable_forum : 0;
140
		$date_created = ! is_null( $date_created ) ? $date_created : bp_core_current_time();
141
	}
142
143
	// Set creator ID.
144
	if ( $creator_id ) {
145
		$group->creator_id = (int) $creator_id;
146
	} elseif ( is_user_logged_in() ) {
147
		$group->creator_id = bp_loggedin_user_id();
148
	}
149
150
	if ( ! $group->creator_id ) {
151
		return false;
152
	}
153
154
	// Validate status.
155
	if ( ! groups_is_valid_status( $status ) ) {
156
		return false;
157
	}
158
159
	// Set group name.
160
	$group->name         = $name;
161
	$group->description  = $description;
162
	$group->slug         = $slug;
163
	$group->status       = $status;
164
	$group->parent_id    = $parent_id;
165
	$group->enable_forum = (int) $enable_forum;
166
	$group->date_created = $date_created;
167
168
	// Save group.
169
	if ( ! $group->save() ) {
170
		return false;
171
	}
172
173
	// If this is a new group, set up the creator as the first member and admin.
174
	if ( empty( $group_id ) ) {
175
		$member                = new BP_Groups_Member;
176
		$member->group_id      = $group->id;
177
		$member->user_id       = $group->creator_id;
178
		$member->is_admin      = 1;
179
		$member->user_title    = __( 'Group Admin', 'buddypress' );
180
		$member->is_confirmed  = 1;
181
		$member->date_modified = bp_core_current_time();
182
		$member->save();
183
184
		/**
185
		 * Fires after the creation of a new group and a group creator needs to be made.
186
		 *
187
		 * @since 1.5.0
188
		 *
189
		 * @param int              $id     ID of the newly created group.
190
		 * @param BP_Groups_Member $member Instance of the member who is assigned
191
		 *                                 as group creator.
192
		 * @param BP_Groups_Group  $group  Instance of the group being created.
193
		 */
194
		do_action( 'groups_create_group', $group->id, $member, $group );
195
196
	} else {
197
198
		/**
199
		 * Fires after the update of a group.
200
		 *
201
		 * @since 1.5.0
202
		 *
203
		 * @param int             $id    ID of the updated group.
204
		 * @param BP_Groups_Group $group Instance of the group being updated.
205
		 */
206
		do_action( 'groups_update_group', $group->id, $group );
207
	}
208
209
	/**
210
	 * Fires after the creation or update of a group.
211
	 *
212
	 * @since 1.0.0
213
	 *
214
	 * @param int             $id    ID of the newly created group.
215
	 * @param BP_Groups_Group $group Instance of the group being updated.
216
	 */
217
	do_action( 'groups_created_group', $group->id, $group );
218
219
	return $group->id;
220
}
221
222
/**
223
 * Edit the base details for a group.
224
 *
225
 * These are the settings that appear on the first page of the group's Admin
226
 * section (Name, Description, and "Notify members...").
227
 *
228
 * @since 1.0.0
229
 *
230
 * @param array $args {
231
 *     An array of optional arguments.
232
 *     @type int    $group_id       ID of the group.
233
 *     @type string $name           Name of the group.
234
 *     @type string $slug           Slug of the group.
235
 *     @type string $description    Description of the group.
236
 *     @type bool   $notify_members Whether to send an email notification to group
237
 *                                  members about changes in these details.
238
 * }
239
 * @return bool True on success, false on failure.
240
 */
241
function groups_edit_base_group_details( $args = array() ) {
242
243
	// Backward compatibility with old method of passing arguments.
244 View Code Duplication
	if ( ! is_array( $args ) || func_num_args() > 1 ) {
245
		_deprecated_argument( __METHOD__, '2.9.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
246
247
		$old_args_keys = array(
248
			0 => 'group_id',
249
			1 => 'name',
250
			2 => 'description',
251
			3 => 'notify_members',
252
		);
253
254
		$args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
0 ignored issues
show
Coding Style introduced by Boone B Gorges
Consider using a different name than the parameter $args. This often makes code more readable.
Loading history...
255
	}
256
257
	$r = bp_parse_args( $args, array(
258
		'group_id'       => bp_get_current_group_id(),
259
		'name'           => null,
260
		'slug'           => null,
261
		'description'    => null,
262
		'notify_members' => false,
263
	), 'groups_edit_base_group_details' );
264
265
	if ( ! $r['group_id'] ) {
266
		return false;
267
	}
268
269
	$group     = groups_get_group( $r['group_id'] );
270
	$old_group = clone $group;
271
272
	// Group name, slug and description can never be empty. Update only if provided.
273
	if ( $r['name'] ) {
274
		$group->name = $r['name'];
275
	}
276
	if ( $r['slug'] && $r['slug'] != $group->slug ) {
277
		$group->slug = groups_check_slug( $r['slug'] );
278
	}
279
	if ( $r['description'] ) {
280
		$group->description = $r['description'];
281
	}
282
283
	if ( ! $group->save() ) {
284
		return false;
285
	}
286
287
	// Maybe update the "previous_slug" groupmeta.
288
	if ( $group->slug != $old_group->slug ) {
289
		/*
290
		 * If the old slug exists in this group's past, delete that entry.
291
		 * Recent previous_slugs are preferred when selecting the current group
292
		 * from an old group slug, so we want the previous slug to be
293
		 * saved "now" in the groupmeta table and don't need the old record.
294
		 */
295
		groups_delete_groupmeta( $group->id, 'previous_slug', $old_group->slug );
296
		groups_add_groupmeta( $group->id, 'previous_slug', $old_group->slug );
297
	}
298
299
	if ( $r['notify_members'] ) {
300
		groups_notification_group_updated( $group->id, $old_group );
301
	}
302
303
	/**
304
	 * Fired after a group's details are updated.
305
	 *
306
	 * @since 2.2.0
307
	 *
308
	 * @param int             $value          ID of the group.
309
	 * @param BP_Groups_Group $old_group      Group object, before being modified.
310
	 * @param bool            $notify_members Whether to send an email notification to members about the change.
311
	 */
312
	do_action( 'groups_details_updated', $group->id, $old_group, $r['notify_members'] );
313
314
	return true;
315
}
316
317
/**
318
 * Edit the base details for a group.
319
 *
320
 * These are the settings that appear on the Settings page of the group's Admin
321
 * section (privacy settings, "enable forum", invitation status).
322
 *
323
 * @since 1.0.0
324
 *
325
 * @param int         $group_id      ID of the group.
326
 * @param bool        $enable_forum  Whether to enable a forum for the group.
327
 * @param string      $status        Group status. 'public', 'private', 'hidden'.
328
 * @param string|bool $invite_status Optional. Who is allowed to send invitations
329
 *                                   to the group. 'members', 'mods', or 'admins'.
330
 * @param int|bool    $parent_id     Parent group ID.
331
 * @return bool True on success, false on failure.
332
 */
333
function groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status = false, $parent_id = false ) {
334
335
	$group = groups_get_group( $group_id );
336
	$group->enable_forum = $enable_forum;
0 ignored issues
show
Documentation Bug introduced by John James Jacoby
The property $enable_forum was declared of type integer, but $enable_forum is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
337
338
	/**
339
	 * Before we potentially switch the group status, if it has been changed to public
340
	 * from private and there are outstanding membership requests, auto-accept those requests.
341
	 */
342
	if ( 'private' == $group->status && 'public' == $status )
343
		groups_accept_all_pending_membership_requests( $group->id );
344
345
	// Now update the status.
346
	$group->status = $status;
347
348
	// Update the parent ID if necessary.
349
	if ( false !== $parent_id ) {
350
		$group->parent_id = $parent_id;
0 ignored issues
show
Documentation Bug introduced by David Cavins
It seems like $parent_id can also be of type boolean. However, the property $parent_id is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
351
	}
352
353
	if ( !$group->save() )
354
		return false;
355
356
	// Set the invite status.
357
	if ( $invite_status )
358
		groups_update_groupmeta( $group->id, 'invite_status', $invite_status );
359
360
	groups_update_groupmeta( $group->id, 'last_activity', bp_core_current_time() );
361
362
	/**
363
	 * Fires after the update of a groups settings.
364
	 *
365
	 * @since 1.0.0
366
	 *
367
	 * @param int $id ID of the group that was updated.
368
	 */
369
	do_action( 'groups_settings_updated', $group->id );
370
371
	return true;
372
}
373
374
/**
375
 * Delete a group and all of its associated metadata.
376
 *
377
 * @since 1.0.0
378
 *
379
 * @param int $group_id ID of the group to delete.
380
 * @return bool True on success, false on failure.
381
 */
382
function groups_delete_group( $group_id ) {
383
384
	/**
385
	 * Fires before the deletion of a group.
386
	 *
387
	 * @since 1.5.0
388
	 *
389
	 * @param int $group_id ID of the group to be deleted.
390
	 */
391
	do_action( 'groups_before_delete_group', $group_id );
392
393
	// Get the group object.
394
	$group = groups_get_group( $group_id );
395
396
	// Bail if group cannot be deleted.
397
	if ( ! $group->delete() ) {
398
		return false;
399
	}
400
401
	// Remove all outstanding invites for this group.
402
	groups_delete_all_group_invites( $group_id );
403
404
	/**
405
	 * Fires after the deletion of a group.
406
	 *
407
	 * @since 1.0.0
408
	 *
409
	 * @param int $group_id ID of the group that was deleted.
410
	 */
411
	do_action( 'groups_delete_group', $group_id );
412
413
	return true;
414
}
415
416
/**
417
 * Check a group status (eg 'private') against the whitelist of registered statuses.
418
 *
419
 * @since 1.1.0
420
 *
421
 * @param string $status Status to check.
422
 * @return bool True if status is allowed, otherwise false.
423
 */
424
function groups_is_valid_status( $status ) {
425
	$bp = buddypress();
426
427
	return in_array( $status, (array) $bp->groups->valid_status );
428
}
429
430
/**
431
 * Provide a unique, sanitized version of a group slug.
432
 *
433
 * @since 1.0.0
434
 *
435
 * @param string $slug Group slug to check.
436
 * @return string $slug A unique and sanitized slug.
437
 */
438
function groups_check_slug( $slug ) {
439
	$bp = buddypress();
440
441
	// First, make the proposed slug work in a URL.
442
	$slug = sanitize_title( $slug );
0 ignored issues
show
Coding Style introduced by David Cavins
Consider using a different name than the parameter $slug. This often makes code more readable.
Loading history...
443
444
	if ( 'wp' == substr( $slug, 0, 2 ) )
445
		$slug = substr( $slug, 2, strlen( $slug ) - 2 );
0 ignored issues
show
Coding Style introduced by John James Jacoby
Consider using a different name than the parameter $slug. This often makes code more readable.
Loading history...
446
447
	if ( in_array( $slug, (array) $bp->groups->forbidden_names ) )
448
		$slug = $slug . '-' . rand();
0 ignored issues
show
Coding Style introduced by John James Jacoby
Consider using a different name than the parameter $slug. This often makes code more readable.
Loading history...
449
450
	if ( BP_Groups_Group::check_slug( $slug ) ) {
0 ignored issues
show
Bug Best Practice introduced by John James Jacoby
The expression \BP_Groups_Group::check_slug($slug) of type string|null 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...
451
		do {
452
			$slug = $slug . '-' . rand();
0 ignored issues
show
Coding Style introduced by John James Jacoby
Consider using a different name than the parameter $slug. This often makes code more readable.
Loading history...
453
		}
454
		while ( BP_Groups_Group::check_slug( $slug ) );
0 ignored issues
show
Bug Best Practice introduced by John James Jacoby
The expression \BP_Groups_Group::check_slug($slug) of type string|null 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...
455
	}
456
457
	return $slug;
458
}
459
460
/**
461
 * Get a group slug by its ID.
462
 *
463
 * @since 1.0.0
464
 *
465
 * @param int $group_id The numeric ID of the group.
466
 * @return string The group's slug.
467
 */
468
function groups_get_slug( $group_id ) {
469
	$group = groups_get_group( $group_id );
470
	return !empty( $group->slug ) ? $group->slug : '';
471
}
472
473
/**
474
 * Get a group ID by its slug.
475
 *
476
 * @since 1.6.0
477
 *
478
 * @param string $group_slug The group's slug.
479
 * @return int|null The group ID on success; null on failure.
480
 */
481
function groups_get_id( $group_slug ) {
482
	return BP_Groups_Group::group_exists( $group_slug );
483
}
484
485
/**
486
 * Get a group ID by checking against old (not currently active) slugs.
487
 *
488
 * @since 2.9.0
489
 *
490
 * @param string $group_slug The group's slug.
491
 * @return int|null The group ID on success; null on failure.
0 ignored issues
show
Documentation introduced by David Cavins
Should the return type not be integer|null|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
492
 */
493
function groups_get_id_by_previous_slug( $group_slug ) {
494
	return BP_Groups_Group::get_id_by_previous_slug( $group_slug );
495
}
496
497
/** User Actions **************************************************************/
498
499
/**
500
 * Remove a user from a group.
501
 *
502
 * @since 1.0.0
503
 *
504
 * @param int $group_id ID of the group.
505
 * @param int $user_id  Optional. ID of the user. Defaults to the currently
506
 *                      logged-in user.
507
 * @return bool True on success, false on failure.
508
 */
509
function groups_leave_group( $group_id, $user_id = 0 ) {
510
511
	if ( empty( $user_id ) )
512
		$user_id = bp_loggedin_user_id();
0 ignored issues
show
Coding Style introduced by John James Jacoby
Consider using a different name than the parameter $user_id. This often makes code more readable.
Loading history...
513
514
	// Don't let single admins leave the group.
515
	if ( count( groups_get_group_admins( $group_id ) ) < 2 ) {
516
		if ( groups_is_user_admin( $user_id, $group_id ) ) {
517
			bp_core_add_message( __( 'As the only admin, you cannot leave the group.', 'buddypress' ), 'error' );
518
			return false;
519
		}
520
	}
521
522
	if ( ! BP_Groups_Member::delete( $user_id, $group_id ) ) {
523
		return false;
524
	}
525
526
	bp_core_add_message( __( 'You successfully left the group.', 'buddypress' ) );
527
528
	/**
529
	 * Fires after a user leaves a group.
530
	 *
531
	 * @since 1.0.0
532
	 *
533
	 * @param int $group_id ID of the group.
534
	 * @param int $user_id  ID of the user leaving the group.
535
	 */
536
	do_action( 'groups_leave_group', $group_id, $user_id );
537
538
	return true;
539
}
540
541
/**
542
 * Add a user to a group.
543
 *
544
 * @since 1.0.0
545
 *
546
 * @param int $group_id ID of the group.
547
 * @param int $user_id  Optional. ID of the user. Defaults to the currently
548
 *                      logged-in user.
549
 * @return bool True on success, false on failure.
550
 */
551
function groups_join_group( $group_id, $user_id = 0 ) {
552
553
	if ( empty( $user_id ) )
554
		$user_id = bp_loggedin_user_id();
0 ignored issues
show
Coding Style introduced by John James Jacoby
Consider using a different name than the parameter $user_id. This often makes code more readable.
Loading history...
555
556
	// Check if the user has an outstanding invite. If so, delete it.
557
	if ( groups_check_user_has_invite( $user_id, $group_id ) )
558
		groups_delete_invite( $user_id, $group_id );
559
560
	// Check if the user has an outstanding request. If so, delete it.
561
	if ( groups_check_for_membership_request( $user_id, $group_id ) )
562
		groups_delete_membership_request( null, $user_id, $group_id );
563
564
	// User is already a member, just return true.
565
	if ( groups_is_user_member( $user_id, $group_id ) )
566
		return true;
567
568
	$new_member                = new BP_Groups_Member;
569
	$new_member->group_id      = $group_id;
570
	$new_member->user_id       = $user_id;
571
	$new_member->inviter_id    = 0;
572
	$new_member->is_admin      = 0;
573
	$new_member->user_title    = '';
0 ignored issues
show
Documentation Bug introduced by John James Jacoby
The property $user_title was declared of type integer, but '' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
574
	$new_member->date_modified = bp_core_current_time();
575
	$new_member->is_confirmed  = 1;
576
577
	if ( !$new_member->save() )
578
		return false;
579
580
	$bp = buddypress();
581
582
	if ( !isset( $bp->groups->current_group ) || !$bp->groups->current_group || $group_id != $bp->groups->current_group->id )
583
		$group = groups_get_group( $group_id );
584
	else
585
		$group = $bp->groups->current_group;
586
587
	// Record this in activity streams.
588
	if ( bp_is_active( 'activity' ) ) {
589
		groups_record_activity( array(
590
			'type'    => 'joined_group',
591
			'item_id' => $group_id,
592
			'user_id' => $user_id,
593
		) );
594
	}
595
596
	/**
597
	 * Fires after a user joins a group.
598
	 *
599
	 * @since 1.0.0
600
	 *
601
	 * @param int $group_id ID of the group.
602
	 * @param int $user_id  ID of the user joining the group.
603
	 */
604
	do_action( 'groups_join_group', $group_id, $user_id );
605
606
	return true;
607
}
608
609
/**
610
 * Update the last_activity meta value for a given group.
611
 *
612
 * @since 1.0.0
613
 *
614
 * @param int $group_id Optional. The ID of the group whose last_activity is
615
 *                      being updated. Default: the current group's ID.
616
 * @return false|null False on failure.
617
 */
618
function groups_update_last_activity( $group_id = 0 ) {
619
620
	if ( empty( $group_id ) ) {
621
		$group_id = buddypress()->groups->current_group->id;
0 ignored issues
show
Coding Style introduced by John James Jacoby
Consider using a different name than the parameter $group_id. This often makes code more readable.
Loading history...
622
	}
623
624
	if ( empty( $group_id ) ) {
625
		return false;
626
	}
627
628
	groups_update_groupmeta( $group_id, 'last_activity', bp_core_current_time() );
629
}
630
add_action( 'groups_join_group',           'groups_update_last_activity' );
631
add_action( 'groups_leave_group',          'groups_update_last_activity' );
632
add_action( 'groups_created_group',        'groups_update_last_activity' );
633
634
/** General Group Functions ***************************************************/
635
636
/**
637
 * Get a list of group administrators.
638
 *
639
 * @since 1.0.0
640
 *
641
 * @param int $group_id ID of the group.
642
 * @return array Info about group admins (user_id + date_modified).
643
 */
644
function groups_get_group_admins( $group_id ) {
645
	return BP_Groups_Member::get_group_administrator_ids( $group_id );
646
}
647
648
/**
649
 * Get a list of group moderators.
650
 *
651
 * @since 1.0.0
652
 *
653
 * @param int $group_id ID of the group.
654
 * @return array Info about group admins (user_id + date_modified).
655
 */
656
function groups_get_group_mods( $group_id ) {
657
	return BP_Groups_Member::get_group_moderator_ids( $group_id );
658
}
659
660
/**
661
 * Fetch the members of a group.
662
 *
663
 * Since BuddyPress 1.8, a procedural wrapper for BP_Group_Member_Query.
664
 * Previously called BP_Groups_Member::get_all_for_group().
665
 *
666
 * To use the legacy query, filter 'bp_use_legacy_group_member_query',
667
 * returning true.
668
 *
669
 * @since 1.0.0
670
 * @since 3.0.0 $group_id now supports multiple values. Only works if legacy query is not
671
 *              in use.
672
 *
673
 * @param array $args {
674
 *     An array of optional arguments.
675
 *     @type int|array|string $group_id            ID of the group to limit results to. Also accepts multiple values
676
 *                                                 either as an array or as a comma-delimited string.
677
 *     @type int              $page                Page of results to be queried. Default: 1.
678
 *     @type int              $per_page            Number of items to return per page of results. Default: 20.
679
 *     @type int              $max                 Optional. Max number of items to return.
680
 *     @type array            $exclude             Optional. Array of user IDs to exclude.
681
 *     @type bool|int         $exclude_admins_mods True (or 1) to exclude admins and mods from results. Default: 1.
682
 *     @type bool|int         $exclude_banned      True (or 1) to exclude banned users from results. Default: 1.
683
 *     @type array            $group_role          Optional. Array of group roles to include.
684
 *     @type string           $search_terms        Optional. Filter results by a search string.
685
 *     @type string           $type                Optional. Sort the order of results. 'last_joined', 'first_joined', or
686
 *                                                 any of the $type params available in {@link BP_User_Query}. Default:
687
 *                                                 'last_joined'.
688
 * }
689
 * @return false|array Multi-d array of 'members' list and 'count'.
690
 */
691
function groups_get_group_members( $args = array() ) {
692
693
	// Backward compatibility with old method of passing arguments.
694
	if ( ! is_array( $args ) || func_num_args() > 1 ) {
695
		_deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
696
697
		$old_args_keys = array(
698
			0 => 'group_id',
699
			1 => 'per_page',
700
			2 => 'page',
701
			3 => 'exclude_admins_mods',
702
			4 => 'exclude_banned',
703
			5 => 'exclude',
704
			6 => 'group_role',
705
		);
706
707
		$args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
0 ignored issues
show
Coding Style introduced by Boone B Gorges
Consider using a different name than the parameter $args. This often makes code more readable.
Loading history...
708
	}
709
710
	$r = bp_parse_args( $args, array(
711
		'group_id'            => bp_get_current_group_id(),
712
		'per_page'            => false,
713
		'page'                => false,
714
		'exclude_admins_mods' => true,
715
		'exclude_banned'      => true,
716
		'exclude'             => false,
717
		'group_role'          => array(),
718
		'search_terms'        => false,
719
		'type'                => 'last_joined',
720
	), 'groups_get_group_members' );
721
722
	// For legacy users. Use of BP_Groups_Member::get_all_for_group() is deprecated.
723
	if ( apply_filters( 'bp_use_legacy_group_member_query', false, __FUNCTION__, func_get_args() ) ) {
724
		$retval = BP_Groups_Member::get_all_for_group( $r['group_id'], $r['per_page'], $r['page'], $r['exclude_admins_mods'], $r['exclude_banned'], $r['exclude'] );
725
	} else {
726
727
		// Both exclude_admins_mods and exclude_banned are legacy arguments.
728
		// Convert to group_role.
729
		if ( empty( $r['group_role'] ) ) {
730
			$r['group_role'] = array( 'member' );
731
732
			if ( ! $r['exclude_admins_mods'] ) {
733
				$r['group_role'][] = 'mod';
734
				$r['group_role'][] = 'admin';
735
			}
736
737
			if ( ! $r['exclude_banned'] ) {
738
				$r['group_role'][] = 'banned';
739
			}
740
		}
741
742
		// Perform the group member query (extends BP_User_Query).
743
		$members = new BP_Group_Member_Query( array(
744
			'group_id'       => $r['group_id'],
745
			'per_page'       => $r['per_page'],
746
			'page'           => $r['page'],
747
			'group_role'     => $r['group_role'],
748
			'exclude'        => $r['exclude'],
749
			'search_terms'   => $r['search_terms'],
750
			'type'           => $r['type'],
751
		) );
752
753
		// Structure the return value as expected by the template functions.
754
		$retval = array(
755
			'members' => array_values( $members->results ),
756
			'count'   => $members->total_users,
757
		);
758
	}
759
760
	return $retval;
761
}
762
763
/**
764
 * Get the member count for a group.
765
 *
766
 * @since 1.2.3
767
 *
768
 * @param int $group_id Group ID.
769
 * @return int Count of confirmed members for the group.
770
 */
771
function groups_get_total_member_count( $group_id ) {
772
	return BP_Groups_Group::get_total_member_count( $group_id );
773
}
774
775
/** Group Fetching, Filtering & Searching  ************************************/
776
777
/**
778
 * Get a collection of groups, based on the parameters passed.
779
 *
780
 * @since 1.2.0
781
 * @since 2.6.0 Added `$group_type`, `$group_type__in`, and `$group_type__not_in` parameters.
782
 * @since 2.7.0 Added `$update_admin_cache` and `$parent_id` parameters.
783
 *
784
 * @param array|string $args {
785
 *     Array of arguments. Supports all arguments of
786
 *     {@link BP_Groups_Group::get()}. Where the default values differ, they
787
 *     have been described here.
788
 *     @type int $per_page Default: 20.
789
 *     @type int $page Default: 1.
790
 * }
791
 * @return array See {@link BP_Groups_Group::get()}.
792
 */
793
function groups_get_groups( $args = '' ) {
794
795
	$defaults = array(
796
		'type'               => false,          // Active, newest, alphabetical, random, popular.
797
		'order'              => 'DESC',         // 'ASC' or 'DESC'
798
		'orderby'            => 'date_created', // date_created, last_activity, total_member_count, name, random, meta_id.
799
		'user_id'            => false,          // Pass a user_id to limit to only groups that this user is a member of.
800
		'include'            => false,          // Only include these specific groups (group_ids).
801
		'exclude'            => false,          // Do not include these specific groups (group_ids).
802
		'parent_id'          => null,           // Get groups that are children of the specified group(s).
803
		'slug'               => array(),        // Find a group or groups by slug.
804
		'search_terms'       => false,          // Limit to groups that match these search terms.
805
		'search_columns'     => array(),        // Select which columns to search.
806
		'group_type'         => '',             // Array or comma-separated list of group types to limit results to.
807
		'group_type__in'     => '',             // Array or comma-separated list of group types to limit results to.
808
		'group_type__not_in' => '',             // Array or comma-separated list of group types that will be excluded from results.
809
		'meta_query'         => false,          // Filter by groupmeta. See WP_Meta_Query for syntax.
810
		'show_hidden'        => false,          // Show hidden groups to non-admins.
811
		'status'             => array(),        // Array or comma-separated list of group statuses to limit results to.
812
		'per_page'           => 20,             // The number of results to return per page.
813
		'page'               => 1,              // The page to return if limiting per page.
814
		'update_meta_cache'  => true,           // Pre-fetch groupmeta for queried groups.
815
		'update_admin_cache' => false,
816
		'fields'             => 'all',          // Return BP_Groups_Group objects or a list of ids.
817
	);
818
819
	$r = bp_parse_args( $args, $defaults, 'groups_get_groups' );
820
821
	$groups = BP_Groups_Group::get( array(
822
		'type'               => $r['type'],
823
		'user_id'            => $r['user_id'],
824
		'include'            => $r['include'],
825
		'exclude'            => $r['exclude'],
826
		'slug'               => $r['slug'],
827
		'parent_id'          => $r['parent_id'],
828
		'search_terms'       => $r['search_terms'],
829
		'search_columns'     => $r['search_columns'],
830
		'group_type'         => $r['group_type'],
831
		'group_type__in'     => $r['group_type__in'],
832
		'group_type__not_in' => $r['group_type__not_in'],
833
		'meta_query'         => $r['meta_query'],
834
		'show_hidden'        => $r['show_hidden'],
835
		'status'             => $r['status'],
836
		'per_page'           => $r['per_page'],
837
		'page'               => $r['page'],
838
		'update_meta_cache'  => $r['update_meta_cache'],
839
		'update_admin_cache' => $r['update_admin_cache'],
840
		'order'              => $r['order'],
841
		'orderby'            => $r['orderby'],
842
		'fields'             => $r['fields'],
843
	) );
844
845
	/**
846
	 * Filters the collection of groups based on parsed parameters.
847
	 *
848
	 * @since 1.2.0
849
	 *
850
	 * @param BP_Groups_Group $groups Object of found groups based on parameters.
851
	 *                                Passed by reference.
852
	 * @param array           $r      Array of parsed arguments used for group query.
853
	 *                                Passed by reference.
854
	 */
855
	return apply_filters_ref_array( 'groups_get_groups', array( &$groups, &$r ) );
856
}
857
858
/**
859
 * Get the total group count for the site.
860
 *
861
 * @since 1.2.0
862
 *
863
 * @return int
864
 */
865
function groups_get_total_group_count() {
866
	$count = wp_cache_get( 'bp_total_group_count', 'bp' );
867
868
	if ( false === $count ) {
869
		$count = BP_Groups_Group::get_total_group_count();
870
		wp_cache_set( 'bp_total_group_count', $count, 'bp' );
871
	}
872
873
	return $count;
874
}
875
876
/**
877
 * Get the IDs of the groups of which a specified user is a member.
878
 *
879
 * @since 1.0.0
880
 *
881
 * @param int $user_id  ID of the user.
882
 * @param int $pag_num  Optional. Max number of results to return.
883
 *                      Default: false (no limit).
884
 * @param int $pag_page Optional. Page offset of results to return.
885
 *                      Default: false (no limit).
886
 * @return array {
887
 *     @type array $groups Array of groups returned by paginated query.
888
 *     @type int   $total Count of groups matching query.
889
 * }
890
 */
891
function groups_get_user_groups( $user_id = 0, $pag_num = 0, $pag_page = 0 ) {
892
893
	if ( empty( $user_id ) )
894
		$user_id = bp_displayed_user_id();
0 ignored issues
show
Coding Style introduced by John James Jacoby
Consider using a different name than the parameter $user_id. This often makes code more readable.
Loading history...
895
896
	return BP_Groups_Member::get_group_ids( $user_id, $pag_num, $pag_page );
897
}
898
899
/**
900
 * Get a list of groups of which the specified user is a member.
901
 *
902
 * Get a list of the groups to which this member belongs,
903
 * filtered by group membership status and role.
904
 * Usage examples: Used with no arguments specified,
905
 *
906
 *    bp_get_user_groups( bp_loggedin_user_id() );
907
 *
908
 * returns an array of the groups in which the logged-in user
909
 * is an unpromoted member. To fetch an array of all groups that
910
 * the current user belongs to, in any membership role,
911
 * member, moderator or administrator, use
912
 *
913
 *    bp_get_user_groups( $user_id, array(
914
 *        'is_admin' => null,
915
 *        'is_mod' => null,
916
 *    ) );
917
 *
918
 * @since 2.6.0
919
 *
920
 * @param int $user_id ID of the user.
921
 * @param array $args {
922
 *     Array of optional args.
923
 *     @param bool|null   $is_confirmed Whether to return only confirmed memberships. Pass `null` to disable this
0 ignored issues
show
Bug introduced by Boone B Gorges
There is no parameter named $is_confirmed. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
924
 *                                      filter. Default: true.
925
 *     @param bool|null   $is_banned    Whether to return only banned memberships. Pass `null` to disable this filter.
0 ignored issues
show
Bug introduced by Boone B Gorges
There is no parameter named $is_banned. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
926
 *                                      Default: false.
927
 *     @param bool|null   $is_admin     Whether to return only admin memberships. Pass `null` to disable this filter.
0 ignored issues
show
Bug introduced by Boone B Gorges
There is no parameter named $is_admin. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
928
 *                                      Default: false.
929
 *     @param bool|null   $is_mod       Whether to return only mod memberships. Pass `null` to disable this filter.
0 ignored issues
show
Bug introduced by Boone B Gorges
There is no parameter named $is_mod. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
930
 *                                      Default: false.
931
 *     @param bool|null   $invite_sent  Whether to return only memberships with 'invite_sent'. Pass `null` to disable
0 ignored issues
show
Bug introduced by Boone B Gorges
There is no parameter named $invite_sent. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
932
 *                                      this filter. Default: false.
933
 *     @param string      $orderby      Field to order by. Accepts 'id' (membership ID), 'group_id', 'date_modified'.
0 ignored issues
show
Bug introduced by Boone B Gorges
There is no parameter named $orderby. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
934
 *                                      Default: 'group_id'.
935
 *     @param string      $order        Sort order. Accepts 'ASC' or 'DESC'. Default: 'ASC'.
0 ignored issues
show
Bug introduced by Boone B Gorges
There is no parameter named $order. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
936
 * }
937
 * @return array Array of matching group memberships, keyed by group ID.
938
 */
939
function bp_get_user_groups( $user_id, $args = array() ) {
940
	$r = bp_parse_args( $args, array(
941
		'is_confirmed' => true,
942
		'is_banned'    => false,
943
		'is_admin'     => false,
944
		'is_mod'       => false,
945
		'invite_sent'  => null,
946
		'orderby'      => 'group_id',
947
		'order'        => 'ASC',
948
	), 'get_user_groups' );
949
950
	$user_id = intval( $user_id );
0 ignored issues
show
Coding Style introduced by Boone B Gorges
Consider using a different name than the parameter $user_id. This often makes code more readable.
Loading history...
951
952
	$membership_ids = wp_cache_get( $user_id, 'bp_groups_memberships_for_user' );
953
	if ( false === $membership_ids ) {
954
		$membership_ids = BP_Groups_Member::get_membership_ids_for_user( $user_id );
955
		wp_cache_set( $user_id, $membership_ids, 'bp_groups_memberships_for_user' );
956
	}
957
958
	// Prime the membership cache.
959
	$uncached_membership_ids = bp_get_non_cached_ids( $membership_ids, 'bp_groups_memberships' );
960
	if ( ! empty( $uncached_membership_ids ) ) {
961
		$uncached_memberships = BP_Groups_Member::get_memberships_by_id( $uncached_membership_ids );
962
963
		foreach ( $uncached_memberships as $uncached_membership ) {
964
			wp_cache_set( $uncached_membership->id, $uncached_membership, 'bp_groups_memberships' );
965
		}
966
	}
967
968
	// Assemble filter array for use in `wp_list_filter()`.
969
	$filters = wp_array_slice_assoc( $r, array( 'is_confirmed', 'is_banned', 'is_admin', 'is_mod', 'invite_sent' ) );
970
	foreach ( $filters as $filter_name => $filter_value ) {
971
		if ( is_null( $filter_value ) ) {
972
			unset( $filters[ $filter_name ] );
973
		}
974
	}
975
976
	// Populate group membership array from cache, and normalize.
977
	$groups    = array();
978
	$int_keys  = array( 'id', 'group_id', 'user_id', 'inviter_id' );
979
	$bool_keys = array( 'is_admin', 'is_mod', 'is_confirmed', 'is_banned', 'invite_sent' );
980
	foreach ( $membership_ids as $membership_id ) {
981
		$membership = wp_cache_get( $membership_id, 'bp_groups_memberships' );
982
983
		// Sanity check.
984
		if ( ! isset( $membership->group_id ) ) {
985
			continue;
986