Ticket #6210: 6210.03072019.diff
File 6210.03072019.diff, 173.2 KB (added by , 6 years ago) |
---|
-
src/bp-core/admin/bp-core-admin-schema.php
diff --git src/bp-core/admin/bp-core-admin-schema.php src/bp-core/admin/bp-core-admin-schema.php index 02a410ba9..f4d5b9e4c 100644
function bp_core_install_emails() { 535 535 */ 536 536 do_action( 'bp_core_install_emails' ); 537 537 } 538 539 /** 540 * Install database tables for the Invitations API 541 * 542 * @since 5.0.0 543 * 544 * @uses bp_core_set_charset() 545 * @uses bp_core_get_table_prefix() 546 * @uses dbDelta() 547 */ 548 function bp_core_install_invitations() { 549 $sql = array(); 550 $charset_collate = $GLOBALS['wpdb']->get_charset_collate(); 551 $bp_prefix = bp_core_get_table_prefix(); 552 $sql[] = "CREATE TABLE {$bp_prefix}bp_invitations ( 553 id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, 554 user_id bigint(20) NOT NULL, 555 inviter_id bigint(20) NOT NULL, 556 invitee_email varchar(100) DEFAULT NULL, 557 component_name varchar(75) NOT NULL, 558 component_action varchar(75) NOT NULL, 559 item_id bigint(20) NOT NULL, 560 secondary_item_id bigint(20) DEFAULT NULL, 561 type varchar(12) NOT NULL DEFAULT 'invite', 562 content longtext DEFAULT '', 563 date_modified datetime NOT NULL, 564 invite_sent tinyint(1) NOT NULL DEFAULT '0', 565 accepted tinyint(1) NOT NULL DEFAULT '0', 566 KEY user_id (user_id), 567 KEY inviter_id (inviter_id), 568 KEY invitee_email (invitee_email), 569 KEY component_name (component_name), 570 KEY component_action (component_action), 571 KEY item_id (item_id), 572 KEY secondary_item_id (secondary_item_id), 573 KEY type (type), 574 KEY invite_sent (invite_sent), 575 KEY accepted (accepted) 576 ) {$charset_collate};"; 577 dbDelta( $sql ); 578 579 // @TODO: Migrate invitations here 580 581 /** 582 * Fires after BuddyPress adds the invitations table. 583 * 584 * @since 5.0.0 585 */ 586 do_action( 'bp_core_install_invitations' ); 587 } -
src/bp-core/bp-core-functions.php
diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php index f3c8be614..dfeb65368 100644
function bp_email_get_schema() { 3479 3479 /* translators: do not remove {} brackets or translate its contents. */ 3480 3480 'post_title' => __( '[{{{site.name}}}] You have an invitation to the group: "{{group.name}}"', 'buddypress' ), 3481 3481 /* translators: do not remove {} brackets or translate its contents. */ 3482 'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: "{{group.name}}".\n <a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ),3482 'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: "{{group.name}}".\n{{invite.message}}\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ), 3483 3483 /* translators: do not remove {} brackets or translate its contents. */ 3484 3484 'post_excerpt' => __( "{{inviter.name}} has invited you to join the group: \"{{group.name}}\".\n\nTo accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the group, visit: {{{group.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ), 3485 3485 ), … … function bp_email_get_schema() { 3495 3495 /* translators: do not remove {} brackets or translate its contents. */ 3496 3496 'post_title' => __( '[{{{site.name}}}] Membership request for group: {{group.name}}', 'buddypress' ), 3497 3497 /* translators: do not remove {} brackets or translate its contents. */ 3498 'post_content' => __( "<a href=\"{{{profile.url}}}\">{{requesting-user.name}}</a> wants to join the group "{{group.name}}". As you are an administrator of this group, you must either accept or reject the membership request.\n\n<a href=\"{{{group-requests.url}}}\">Go here to manage this</a> and all other pending requests.", 'buddypress' ),3498 'post_content' => __( "<a href=\"{{{profile.url}}}\">{{requesting-user.name}}</a> wants to join the group "{{group.name}}".\n {{request.message}}\n As you are an administrator of this group, you must either accept or reject the membership request.\n\n<a href=\"{{{group-requests.url}}}\">Go here to manage this</a> and all other pending requests.", 'buddypress' ), 3499 3499 /* translators: do not remove {} brackets or translate its contents. */ 3500 3500 'post_excerpt' => __( "{{requesting-user.name}} wants to join the group \"{{group.name}}\". As you are the administrator of this group, you must either accept or reject the membership request.\n\nTo manage this and all other pending requests, visit: {{{group-requests.url}}}\n\nTo view {{requesting-user.name}}'s profile, visit: {{{profile.url}}}", 'buddypress' ), 3501 3501 ), -
new file src/bp-core/bp-core-invitations-cache.php
diff --git src/bp-core/bp-core-invitations-cache.php src/bp-core/bp-core-invitations-cache.php new file mode 100644 index 000000000..7cf867398
- + 1 <?php 2 /** 3 * BuddyPress Invitation Caching Functions. 4 * 5 * Caching functions handle the clearing of cached objects and pages on specific 6 * actions throughout BuddyPress. 7 * 8 * @package BuddyPress 9 * @subpackage InvitationsCache 10 * @since 5.0.0 11 */ 12 13 /** 14 * Resets all incremented bp_invitations caches. 15 * 16 * @since 5.0.0 17 */ 18 function bp_invitations_reset_cache_incrementor() { 19 bp_core_reset_incrementor( 'bp_invitations' ); 20 } 21 add_action( 'bp_invitation_after_save', 'bp_invitations_reset_cache_incrementor' ); 22 add_action( 'bp_invitation_after_delete', 'bp_invitations_reset_cache_incrementor' ); -
src/bp-core/bp-core-update.php
diff --git src/bp-core/bp-core-update.php src/bp-core/bp-core-update.php index b006ff4d5..4a4b1e20a 100644
function bp_version_updater() { 211 211 bp_update_option( 'bp-active-components', $default_components ); 212 212 bp_core_add_page_mappings( $default_components, 'delete' ); 213 213 bp_core_install_emails(); 214 bp_core_install_invitations(); 214 215 215 216 // Upgrades. 216 217 } else { … … function bp_version_updater() { 268 269 if ( $raw_db_version < 11105 ) { 269 270 bp_update_to_2_7(); 270 271 } 272 273 // Version 5.0.0. 274 if ( $raw_db_version < 11300 ) { 275 bp_update_to_5_0(); 276 } 271 277 } 272 278 273 279 /* All done! *************************************************************/ … … function bp_update_to_2_7() { 542 548 bp_add_option( '_bp_ignore_deprecated_code', false ); 543 549 } 544 550 551 /** 552 * 5.0.0 update routine. 553 * 554 * - Create the invitations table. 555 * - Migrate requests and invitations to the new table. 556 * 557 * @since 2.7.0 558 */ 559 function bp_update_to_5_0() { 560 bp_core_install_invitations(); 561 //@TODO: Migration function. 562 } 563 545 564 /** 546 565 * Updates the component field for new_members type. 547 566 * -
new file src/bp-core/classes/class-bp-invitations-invitation.php
diff --git src/bp-core/classes/class-bp-invitations-invitation.php src/bp-core/classes/class-bp-invitations-invitation.php new file mode 100644 index 000000000..4b31771fb
- + 1 <?php 2 3 /** 4 * BuddyPress Invitations Class 5 * 6 * @package BuddyPress 7 * @subpackage Invitations 8 * 9 * @since 5.0.0 10 */ 11 12 // Exit if accessed directly. 13 defined( 'ABSPATH' ) || exit; 14 15 /** 16 * BuddyPress Invitations. 17 * 18 * Use this class to create, access, edit, or delete BuddyPress Invitations. 19 * 20 * @since 5.0.0 21 */ 22 class BP_Invitations_Invitation { 23 24 /** 25 * The invitation ID. 26 * 27 * @since 5.0.0 28 * @access public 29 * @var int 30 */ 31 public $id; 32 33 /** 34 * The ID of the invited user. 35 * 36 * @since 5.0.0 37 * @access public 38 * @var int 39 */ 40 public $user_id; 41 42 /** 43 * The ID of the user who created the invitation. 44 * 45 * @since 5.0.0 46 * @access public 47 * @var int 48 */ 49 public $inviter_id; 50 51 /** 52 * The email address of the invited user. 53 * Used when extending an invitation to someone who does not belong to the site. 54 * 55 * @since 5.0.0 56 * @access public 57 * @var string 58 */ 59 public $invitee_email; 60 61 /** 62 * The name of the related component. 63 * 64 * @since 5.0.0 65 * @access public 66 * @var string 67 */ 68 public $component_name; 69 70 /** 71 * The name of the related component action. 72 * 73 * @since 5.0.0 74 * @access public 75 * @var string 76 */ 77 public $component_action; 78 79 /** 80 * The ID associated with the invitation and component. 81 * Example: the group ID if a group invitation 82 * 83 * @since 5.0.0 84 * @access public 85 * @var int 86 */ 87 public $item_id; 88 89 /** 90 * The secondary ID associated with the invitation and component. 91 * Example: a taxonomy term ID if invited to a site's category-specific RSS feed 92 * 93 * @since 5.0.0 94 * @access public 95 * @var int 96 */ 97 public $secondary_item_id = null; 98 99 100 /** 101 * Invite or request. 102 * 103 * @since 5.0.0 104 * @access public 105 * @var string 106 */ 107 public $type; 108 109 /** 110 * Extra information provided by the requester or inviter. 111 * 112 * @since 5.0.0 113 * @access public 114 * @var string 115 */ 116 public $content; 117 118 /** 119 * The date the invitation was last modified. 120 * 121 * @since 5.0.0 122 * @access public 123 * @var string 124 */ 125 public $date_modified; 126 127 /** 128 * Has the invitation been sent, or is it a draft invite? 129 * 130 * @since 5.0.0 131 * @access public 132 * @var bool 133 */ 134 public $invite_sent; 135 136 /** 137 * Has the invitation been accepted by the invitee? 138 * 139 * @since 5.0.0 140 * @access public 141 * @var bool 142 */ 143 public $accepted; 144 145 146 /** Public Methods ****************************************************/ 147 148 /** 149 * Constructor method. 150 * 151 * @since 5.0.0 152 * 153 * @param int $id Optional. Provide an ID to access an existing 154 * invitation item. 155 */ 156 public function __construct( $id = 0 ) { 157 if ( ! empty( $id ) ) { 158 $this->id = (int) $id; 159 $this->populate(); 160 } 161 } 162 163 /** 164 * Update or insert invitation details into the database. 165 * 166 * @since 5.0.0 167 * 168 * @global wpdb $wpdb WordPress database object. 169 * 170 * @return bool True on success, false on failure. 171 */ 172 public function save() { 173 174 // Return value 175 $retval = false; 176 177 // Default data and format 178 $data = array( 179 'user_id' => $this->user_id, 180 'inviter_id' => $this->inviter_id, 181 'invitee_email' => $this->invitee_email, 182 'component_name' => $this->component_name, 183 'component_action' => $this->component_action, 184 'item_id' => $this->item_id, 185 'secondary_item_id' => $this->secondary_item_id, 186 'type' => $this->type, 187 'content' => $this->content, 188 'date_modified' => $this->date_modified, 189 'invite_sent' => $this->invite_sent, 190 'accepted' => $this->accepted, 191 ); 192 $data_format = array( '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%s', '%s', '%s', '%d', '%d' ); 193 194 /** 195 * Fires before an invitation is saved. 196 * 197 * @since 5.0.0 198 * 199 * @param BP_Invitations_Invitation object $this Characteristics of the invitation to be saved. 200 */ 201 do_action_ref_array( 'bp_invitation_before_save', array( &$this ) ); 202 203 // Update 204 if ( ! empty( $this->id ) ) { 205 $result = self::_update( $data, array( 'ID' => $this->id ), $data_format, array( '%d' ) ); 206 // Insert 207 } else { 208 $result = self::_insert( $data, $data_format ); 209 } 210 211 // Set the invitation ID if successful 212 if ( ! empty( $result ) && ! is_wp_error( $result ) ) { 213 global $wpdb; 214 215 $this->id = $wpdb->insert_id; 216 $retval = $wpdb->insert_id; 217 } 218 219 /** 220 * Fires after an invitation is saved. 221 * 222 * @since 5.0.0 223 * 224 * @param BP_Invitations_Invitation object $this Characteristics of the invitation just saved. 225 */ 226 do_action_ref_array( 'bp_invitation_after_save', array( &$this ) ); 227 228 // Return the result 229 return $retval; 230 } 231 232 /** 233 * Fetch data for an existing invitation from the database. 234 * 235 * @since 5.0.0 236 * 237 * @global BuddyPress $bp The one true BuddyPress instance. 238 * @global wpdb $wpdb WordPress database object. 239 */ 240 public function populate() { 241 global $wpdb; 242 $invites_table_name = BP_Invitations::get_table_name(); 243 244 // Check cache for invitation data. 245 $invitation = wp_cache_get( $this->id, 'bp_invitations' ); 246 247 // Cache missed, so query the DB. 248 if ( false === $invitation ) { 249 $invitation = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$invites_table_name} WHERE id = %d", $this->id ) ); 250 wp_cache_set( $this->id, $invitation,'bp_invitations' ); 251 } 252 253 // No invitation found so set the ID and bail. 254 if ( empty( $invitation ) || is_wp_error( $invitation ) ) { 255 $this->id = 0; 256 return; 257 } 258 259 $this->user_id = (int) $invitation->user_id; 260 $this->inviter_id = (int) $invitation->inviter_id; 261 $this->invitee_email = $invitation->invitee_email; 262 $this->component_name = $invitation->component_name; 263 $this->component_action = $invitation->component_action; 264 $this->item_id = (int) $invitation->item_id; 265 $this->secondary_item_id = (int) $invitation->secondary_item_id; 266 $this->type = $invitation->type; 267 $this->content = $invitation->content; 268 $this->date_modified = $invitation->date_modified; 269 $this->invite_sent = (int) $invitation->invite_sent; 270 $this->accepted = (int) $invitation->accepted; 271 272 } 273 274 /** Protected Static Methods ******************************************/ 275 276 /** 277 * Create an invitation entry. 278 * 279 * @since 5.0.0 280 * 281 * @param array $data { 282 * Array of invitation data, passed to {@link wpdb::insert()}. 283 * @type int $user_id ID of the invited user. 284 * @type int $inviter_id ID of the user who created the invitation. 285 * @type string $invitee_email Email address of the invited user. 286 * @type string $component_name Name of the related component. 287 * @type string $component_action Name of the related component action. 288 * @type int item_id ID associated with the invitation and component. 289 * @type int secondary_item_id secondary ID associated with the 290 * invitation and component. 291 * @type string content Extra information provided by the requester 292 * or inviter. 293 * @type string date_modified Date the invitation was last modified. 294 * @type int invite_sent Has the invitation been sent, or is it a 295 * draft invite? 296 * } 297 * @param array $data_format See {@link wpdb::insert()}. 298 * @return int|false The number of rows inserted, or false on error. 299 */ 300 protected static function _insert( $data = array(), $data_format = array() ) { 301 global $wpdb; 302 return $wpdb->insert( BP_Invitations::get_table_name(), $data, $data_format ); 303 } 304 305 /** 306 * Update invitations. 307 * 308 * @since 5.0.0 309 * 310 * @see wpdb::update() for further description of paramater formats. 311 * 312 * @param array $data Array of invitation data to update, passed to 313 * {@link wpdb::update()}. Accepts any property of a 314 * BP_Invitations_Invitation object. 315 * @param array $where The WHERE params as passed to wpdb::update(). 316 * Typically consists of array( 'ID' => $id ) to specify the ID 317 * of the item being updated. See {@link wpdb::update()}. 318 * @param array $data_format See {@link wpdb::insert()}. 319 * @param array $where_format See {@link wpdb::insert()}. 320 * @return int|false The number of rows updated, or false on error. 321 */ 322 protected static function _update( $data = array(), $where = array(), $data_format = array(), $where_format = array() ) { 323 global $wpdb; 324 return $wpdb->update( BP_Invitations::get_table_name(), $data, $where, $data_format, $where_format ); 325 } 326 327 /** 328 * Delete invitations. 329 * 330 * @since 5.0.0 331 * 332 * @see wpdb::update() for further description of paramater formats. 333 * 334 * @param array $where Array of WHERE clauses to filter by, passed to 335 * {@link wpdb::delete()}. Accepts any property of a 336 * BP_Invitations_Invitation object. 337 * @param array $where_format See {@link wpdb::insert()}. 338 * @return int|false The number of rows updated, or false on error. 339 */ 340 protected static function _delete( $where = array(), $where_format = array() ) { 341 global $wpdb; 342 return $wpdb->delete( BP_Invitations::get_table_name(), $where, $where_format ); 343 } 344 345 /** 346 * Assemble the WHERE clause of a get() SQL statement. 347 * 348 * Used by BP_Invitations_Invitation::get() to create its WHERE 349 * clause. 350 * 351 * @since 5.0.0 352 * 353 * @param array $args See {@link BP_Invitations_Invitation::get()} 354 * for more details. 355 * @return string WHERE clause. 356 */ 357 protected static function get_where_sql( $args = array() ) { 358 global $wpdb; 359 360 $where_conditions = array(); 361 $where = ''; 362 363 // id 364 if ( ! empty( $args['id'] ) ) { 365 $id_in = implode( ',', wp_parse_id_list( $args['id'] ) ); 366 $where_conditions['id'] = "id IN ({$id_in})"; 367 } 368 369 // user_id 370 if ( ! empty( $args['user_id'] ) ) { 371 $user_id_in = implode( ',', wp_parse_id_list( $args['user_id'] ) ); 372 $where_conditions['user_id'] = "user_id IN ({$user_id_in})"; 373 } 374 375 // inviter_id. 0 can be meaningful, in the case of requests. 376 if ( ! empty( $args['inviter_id'] ) || 0 === $args['inviter_id'] ) { 377 $inviter_id_in = implode( ',', wp_parse_id_list( $args['inviter_id'] ) ); 378 $where_conditions['inviter_id'] = "inviter_id IN ({$inviter_id_in})"; 379 } 380 381 // invitee_email 382 if ( ! empty( $args['invitee_email'] ) ) { 383 if ( ! is_array( $args['invitee_email'] ) ) { 384 $invitee_emails = explode( ',', $args['invitee_email'] ); 385 } else { 386 $invitee_emails = $args['invitee_email']; 387 } 388 389 $email_clean = array(); 390 foreach ( $invitee_emails as $email ) { 391 $email_clean[] = $wpdb->prepare( '%s', $email ); 392 } 393 394 $invitee_email_in = implode( ',', $email_clean ); 395 $where_conditions['invitee_email'] = "invitee_email IN ({$invitee_email_in})"; 396 } 397 398 // component_name 399 if ( ! empty( $args['component_name'] ) ) { 400 if ( ! is_array( $args['component_name'] ) ) { 401 $component_names = explode( ',', $args['component_name'] ); 402 } else { 403 $component_names = $args['component_name']; 404 } 405 406 $cn_clean = array(); 407 foreach ( $component_names as $cn ) { 408 $cn_clean[] = $wpdb->prepare( '%s', $cn ); 409 } 410 411 $cn_in = implode( ',', $cn_clean ); 412 $where_conditions['component_name'] = "component_name IN ({$cn_in})"; 413 } 414 415 // component_action 416 if ( ! empty( $args['component_action'] ) ) { 417 if ( ! is_array( $args['component_action'] ) ) { 418 $component_actions = explode( ',', $args['component_action'] ); 419 } else { 420 $component_actions = $args['component_action']; 421 } 422 423 $ca_clean = array(); 424 foreach ( $component_actions as $ca ) { 425 $ca_clean[] = $wpdb->prepare( '%s', $ca ); 426 } 427 428 $ca_in = implode( ',', $ca_clean ); 429 $where_conditions['component_action'] = "component_action IN ({$ca_in})"; 430 } 431 432 // item_id 433 if ( ! empty( $args['item_id'] ) ) { 434 $item_id_in = implode( ',', wp_parse_id_list( $args['item_id'] ) ); 435 $where_conditions['item_id'] = "item_id IN ({$item_id_in})"; 436 } 437 438 // secondary_item_id 439 if ( ! empty( $args['secondary_item_id'] ) ) { 440 $secondary_item_id_in = implode( ',', wp_parse_id_list( $args['secondary_item_id'] ) ); 441 $where_conditions['secondary_item_id'] = "secondary_item_id IN ({$secondary_item_id_in})"; 442 } 443 444 // type 445 if ( ! empty( $args['type'] ) && 'all' !== $args['type'] ) { 446 if ( 'invite' == $args['type'] || 'request' == $args['type'] ) { 447 $type_clean = $wpdb->prepare( '%s', $args['type'] ); 448 $where_conditions['type'] = "type = {$type_clean}"; 449 } 450 } 451 452 // invite_sent 453 // Only create a where statement if something less than "all" has been 454 // specifically requested. 455 if ( ! empty( $args['invite_sent'] ) && 'all' !== $args['invite_sent'] ) { 456 if ( $args['invite_sent'] == 'draft' ) { 457 $where_conditions['invite_sent'] = "invite_sent = 0"; 458 } else if ( $args['invite_sent'] == 'sent' ) { 459 $where_conditions['invite_sent'] = "invite_sent = 1"; 460 } 461 } 462 463 // accepted 464 if ( ! empty( $args['accepted'] ) && 'all' !== $args['accepted'] ) { 465 if ( $args['accepted'] == 'pending' ) { 466 $where_conditions['accepted'] = "accepted = 0"; 467 } else if ( $args['accepted'] == 'accepted' ) { 468 $where_conditions['accepted'] = "accepted = 1"; 469 } 470 } 471 472 // search_terms 473 if ( ! empty( $args['search_terms'] ) ) { 474 $search_terms_like = '%' . bp_esc_like( $args['search_terms'] ) . '%'; 475 $where_conditions['search_terms'] = $wpdb->prepare( "( component_name LIKE %s OR component_action LIKE %s )", $search_terms_like, $search_terms_like ); 476 } 477 478 // Custom WHERE 479 if ( ! empty( $where_conditions ) ) { 480 $where = 'WHERE ' . implode( ' AND ', $where_conditions ); 481 } 482 483 return $where; 484 } 485 486 /** 487 * Assemble the ORDER BY clause of a get() SQL statement. 488 * 489 * Used by BP_Invitations_Invitation::get() to create its ORDER BY 490 * clause. 491 * 492 * @since 5.0.0 493 * 494 * @param array $args See {@link BP_Invitations_Invitation::get()} 495 * for more details. 496 * @return string ORDER BY clause. 497 */ 498 protected static function get_order_by_sql( $args = array() ) { 499 500 // Setup local variable 501 $conditions = array(); 502 $retval = ''; 503 504 // Order by 505 if ( ! empty( $args['order_by'] ) ) { 506 $order_by = implode( ', ', (array) $args['order_by'] ); 507 $conditions['order_by'] = "{$order_by}"; 508 } 509 510 // Sort order direction 511 if ( ! empty( $args['sort_order'] ) ) { 512 $sort_order = bp_esc_sql_order( $args['sort_order'] ); 513 $conditions['sort_order'] = "{$sort_order}"; 514 } 515 516 // Custom ORDER BY 517 if ( ! empty( $conditions ) ) { 518 $retval = 'ORDER BY ' . implode( ' ', $conditions ); 519 } 520 521 return $retval; 522 } 523 524 /** 525 * Assemble the LIMIT clause of a get() SQL statement. 526 * 527 * Used by BP_Invitations_Invitation::get() to create its LIMIT clause. 528 * 529 * @since 5.0.0 530 * 531 * @param array $args See {@link BP_Invitations_Invitation::get()} 532 * for more details. 533 * @return string LIMIT clause. 534 */ 535 protected static function get_paged_sql( $args = array() ) { 536 global $wpdb; 537 538 // Setup local variable 539 $retval = ''; 540 541 // Custom LIMIT 542 if ( ! empty( $args['page'] ) && ! empty( $args['per_page'] ) ) { 543 $page = absint( $args['page'] ); 544 $per_page = absint( $args['per_page'] ); 545 $offset = $per_page * ( $page - 1 ); 546 $retval = $wpdb->prepare( "LIMIT %d, %d", $offset, $per_page ); 547 } 548 549 return $retval; 550 } 551 552 /** 553 * Assemble query clauses, based on arguments, to pass to $wpdb methods. 554 * 555 * The insert(), update(), and delete() methods of {@link wpdb} expect 556 * arguments of the following forms: 557 * 558 * - associative arrays whose key/value pairs are column => value, to 559 * be used in WHERE, SET, or VALUES clauses 560 * - arrays of "formats", which tell $wpdb->prepare() which type of 561 * value to expect when sanitizing (eg, array( '%s', '%d' )) 562 * 563 * This utility method can be used to assemble both kinds of params, 564 * out of a single set of associative array arguments, such as: 565 * 566 * $args = array( 567 * 'user_id' => 4, 568 * 'component_name' => 'groups', 569 * ); 570 * 571 * This will be converted to: 572 * 573 * array( 574 * 'data' => array( 575 * 'user_id' => 4, 576 * 'component_name' => 'groups', 577 * ), 578 * 'format' => array( 579 * '%d', 580 * '%s', 581 * ), 582 * ) 583 * 584 * which can easily be passed as arguments to the $wpdb methods. 585 * 586 * @since 5.0.0 587 * 588 * @param $args Associative array of filter arguments. 589 * See {@BP_Invitations_Invitation::get()} for a breakdown. 590 * @return array Associative array of 'data' and 'format' args. 591 */ 592 protected static function get_query_clauses( $args = array() ) { 593 $where_clauses = array( 594 'data' => array(), 595 'format' => array(), 596 ); 597 598 // id 599 if ( ! empty( $args['id'] ) ) { 600 $where_clauses['data']['id'] = absint( $args['id'] ); 601 $where_clauses['format'][] = '%d'; 602 } 603 604 // user_id 605 if ( ! empty( $args['user_id'] ) ) { 606 $where_clauses['data']['user_id'] = absint( $args['user_id'] ); 607 $where_clauses['format'][] = '%d'; 608 } 609 610 // inviter_id 611 if ( ! empty( $args['inviter_id'] ) ) { 612 $where_clauses['data']['inviter_id'] = absint( $args['inviter_id'] ); 613 $where_clauses['format'][] = '%d'; 614 } 615 616 // invitee_email 617 if ( ! empty( $args['invitee_email'] ) ) { 618 $where_clauses['data']['invitee_email'] = $args['invitee_email']; 619 $where_clauses['format'][] = '%s'; 620 } 621 622 // component_name 623 if ( ! empty( $args['component_name'] ) ) { 624 $where_clauses['data']['component_name'] = $args['component_name']; 625 $where_clauses['format'][] = '%s'; 626 } 627 628 // component_action 629 if ( ! empty( $args['component_action'] ) ) { 630 $where_clauses['data']['component_action'] = $args['component_action']; 631 $where_clauses['format'][] = '%s'; 632 } 633 634 // item_id 635 if ( ! empty( $args['item_id'] ) ) { 636 $where_clauses['data']['item_id'] = absint( $args['item_id'] ); 637 $where_clauses['format'][] = '%d'; 638 } 639 640 // secondary_item_id 641 if ( ! empty( $args['secondary_item_id'] ) ) { 642 $where_clauses['data']['secondary_item_id'] = absint( $args['secondary_item_id'] ); 643 $where_clauses['format'][] = '%d'; 644 } 645 646 // type 647 if ( ! empty( $args['type'] ) && 'all' !== $args['type'] ) { 648 if ( 'invite' == $args['type'] || 'request' == $args['type'] ) { 649 $where_clauses['data']['type'] = $args['type']; 650 $where_clauses['format'][] = '%s'; 651 } 652 } 653 654 // invite_sent 655 // Only create a where statement if something less than "all" has been 656 // specifically requested. 657 if ( isset( $args['invite_sent'] ) && 'all' !== $args['invite_sent'] ) { 658 if ( $args['invite_sent'] == 'draft' ) { 659 $where_clauses['data']['invite_sent'] = 0; 660 $where_clauses['format'][] = '%d'; 661 } else if ( $args['invite_sent'] == 'sent' ) { 662 $where_clauses['data']['invite_sent'] = 1; 663 $where_clauses['format'][] = '%d'; 664 } 665 } 666 667 // accepted 668 if ( ! empty( $args['accepted'] ) && 'all' !== $args['accepted'] ) { 669 if ( $args['accepted'] == 'pending' ) { 670 $where_clauses['data']['accepted'] = 0; 671 $where_clauses['format'][] = '%d'; 672 } else if ( $args['accepted'] == 'accepted' ) { 673 $where_clauses['data']['accepted'] = 1; 674 $where_clauses['format'][] = '%d'; 675 } 676 } 677 678 return $where_clauses; 679 } 680 681 /** Public Static Methods *********************************************/ 682 683 /** 684 * Get invitations, based on provided filter parameters. 685 * 686 * @since 5.0.0 687 * 688 * @param array $args { 689 * Associative array of arguments. All arguments but $page and 690 * $per_page can be treated as filter values for get_where_sql() 691 * and get_query_clauses(). All items are optional. 692 * @type int|array $id ID of invitation being updated. 693 * Can be an array of IDs. 694 * @type int|array $user_id ID of user being queried. Can be an 695 * Can be an array of IDs. 696 * @type int|array $inviter_id ID of user who created the 697 * invitation. Can be an array of IDs. 698 * @type string|array $invitee_email Email address of invited users 699 * being queried. Can be an array of 700 * addresses. 701 * @type string|array $component_name Name of the component to filter by. 702 * Can be an array of component names. 703 * @type string|array $component_action Name of the action to filter by. 704 * Can be an array of actions. 705 * @type int|array $item_id ID of associated item. 706 * Can be an array of multiple item IDs. 707 * @type int|array $secondary_item_id ID of secondary associated item. 708 * Can be an array of multiple IDs. 709 * @type string|array $type Type of item. An "invite" is sent 710 * from one user to another. 711 * A "request" is submitted by a 712 * user and no inviter is required. 713 * 'all' returns all. Default: 'all'. 714 * @type string $invite_sent Limit to draft, sent or all 715 * 'draft' limits to unsent invites, 716 * 'sent' returns only sent invites, 717 * 'all' returns all. Default: 'all'. 718 * @type bool $accepted Limit to accepted or 719 * not-yet-accepted invitations. 720 * 'accepted' returns accepted invites, 721 * 'pending' returns pending invites, 722 * 'all' returns all. Default: 'pending' 723 * @type string $search_terms Term to match against component_name 724 * or component_action fields. 725 * @type string $order_by Database column to order by. 726 * @type string $sort_order Either 'ASC' or 'DESC'. 727 * @type string $order_by Field to order results by. 728 * @type string $sort_order ASC or DESC. 729 * @type int $page Number of the current page of results. 730 * Default: false (no pagination, 731 * all items). 732 * @type int $per_page Number of items to show per page. 733 * Default: false (no pagination, 734 * all items). 735 * @type string $fields Which fields to return. Specify 'item_ids' to fetch a list of Item_IDs. 736 * Specify 'ids' to fetch a list of Invitation IDs. 737 * Default: 'all' (return BP_Invitations_Invitation objects). 738 * } 739 * 740 * @return array BP_Invitations_Invitation objects | IDs of found invit. 741 */ 742 public static function get( $args = array() ) { 743 global $wpdb; 744 $invites_table_name = BP_Invitations::get_table_name(); 745 746 // Parse the arguments 747 $r = bp_parse_args( $args, array( 748 'id' => false, 749 'user_id' => false, 750 'inviter_id' => false, 751 'invitee_email' => false, 752 'component_name' => false, 753 'component_action' => false, 754 'item_id' => false, 755 'secondary_item_id' => false, 756 'type' => 'all', 757 'invite_sent' => 'all', 758 'accepted' => 'pending', 759 'search_terms' => '', 760 'order_by' => false, 761 'sort_order' => false, 762 'page' => false, 763 'per_page' => false, 764 'fields' => 'all', 765 ), 'bp_invitations_invitation_get' ); 766 767 $sql = array( 768 'select' => "SELECT", 769 'fields' => '', 770 'from' => "FROM {$invites_table_name} i", 771 'where' => '', 772 'orderby' => '', 773 'pagination' => '', 774 ); 775 776 if ( 'item_ids' === $r['fields'] ) { 777 $sql['fields'] = "DISTINCT i.item_id"; 778 } else if ( 'user_ids' === $r['fields'] ) { 779 $sql['fields'] = "DISTINCT i.user_id"; 780 } else { 781 $sql['fields'] = 'DISTINCT i.id'; 782 } 783 784 // WHERE 785 $sql['where'] = self::get_where_sql( array( 786 'id' => $r['id'], 787 'user_id' => $r['user_id'], 788 'inviter_id' => $r['inviter_id'], 789 'invitee_email' => $r['invitee_email'], 790 'component_name' => $r['component_name'], 791 'component_action' => $r['component_action'], 792 'item_id' => $r['item_id'], 793 'secondary_item_id' => $r['secondary_item_id'], 794 'type' => $r['type'], 795 'invite_sent' => $r['invite_sent'], 796 'accepted' => $r['accepted'], 797 'search_terms' => $r['search_terms'], 798 ) ); 799 800 // ORDER BY 801 $sql['orderby'] = self::get_order_by_sql( array( 802 'order_by' => $r['order_by'], 803 'sort_order' => $r['sort_order'] 804 ) ); 805 806 // LIMIT %d, %d 807 $sql['pagination'] = self::get_paged_sql( array( 808 'page' => $r['page'], 809 'per_page' => $r['per_page'], 810 ) ); 811 812 $paged_invites_sql = "{$sql['select']} {$sql['fields']} {$sql['from']} {$sql['where']} {$sql['orderby']} {$sql['pagination']}"; 813 814 /** 815 * Filters the pagination SQL statement. 816 * 817 * @since 5.0.0 818 * 819 * @param string $value Concatenated SQL statement. 820 * @param array $sql Array of SQL parts before concatenation. 821 * @param array $r Array of parsed arguments for the get method. 822 */ 823 $paged_invites_sql = apply_filters( 'bp_invitations_get_paged_invitations_sql', $paged_invites_sql, $sql, $r ); 824 825 $cached = bp_core_get_incremented_cache( $paged_invites_sql, 'bp_invitations' ); 826 if ( false === $cached ) { 827 $paged_invite_ids = $wpdb->get_col( $paged_invites_sql ); 828 bp_core_set_incremented_cache( $paged_invites_sql, 'bp_invitations', $paged_invite_ids ); 829 } else { 830 $paged_invite_ids = $cached; 831 } 832 833 // Special return format cases. 834 if ( 'ids' === $r['fields'] || 'item_ids' === $r['fields'] || 'user_ids' === $r['fields'] ) { 835 // We only want the field that was found. 836 return array_map( 'intval', $paged_invite_ids ); 837 } 838 839 $uncached_ids = bp_get_non_cached_ids( $paged_invite_ids, 'bp_invitations' ); 840 if ( $uncached_ids ) { 841 $ids_sql = implode( ',', array_map( 'intval', $uncached_ids ) ); 842 $data_objects = $wpdb->get_results( "SELECT i.* FROM {$invites_table_name} i WHERE i.id IN ({$ids_sql})" ); 843 foreach ( $data_objects as $data_object ) { 844 wp_cache_set( $data_object->id, $data_object, 'bp_invitations' ); 845 } 846 } 847 848 $paged_invites = array(); 849 foreach ( $paged_invite_ids as $paged_invite_id ) { 850 $paged_invites[] = new BP_Invitations_Invitation( $paged_invite_id ); 851 } 852 853 return $paged_invites; 854 } 855 856 /** 857 * Get a count of total invitations matching a set of arguments. 858 * 859 * @since 5.0.0 860 * 861 * @see BP_Invitations_Invitation::get() for a description of 862 * arguments. 863 * 864 * @param array $args See {@link BP_Invitations_Invitation::get()}. 865 * @return int Count of located items. 866 */ 867 public static function get_total_count( $args ) { 868 global $wpdb; 869 $invites_table_name = BP_Invitations::get_table_name(); 870 871 // Build the query 872 $select_sql = "SELECT COUNT(*)"; 873 $from_sql = "FROM {$invites_table_name}"; 874 $where_sql = self::get_where_sql( $args ); 875 $sql = "{$select_sql} {$from_sql} {$where_sql}"; 876 877 // Return the queried results 878 return $wpdb->get_var( $sql ); 879 } 880 881 /** 882 * Update invitations. 883 * 884 * @since 5.0.0 885 * 886 * @see BP_Invitations_Invitation::get() for a description of 887 * accepted update/where arguments. 888 * 889 * @param array $update_args Associative array of fields to update, 890 * and the values to update them to. Of the format 891 * array( 'user_id' => 4, 'component_name' => 'groups', ) 892 * @param array $where_args Associative array of columns/values, to 893 * determine which rows should be updated. Of the format 894 * array( 'item_id' => 7, 'component_action' => 'members', ) 895 * @return int|bool Number of rows updated on success, false on failure. 896 */ 897 public static function update( $update_args = array(), $where_args = array() ) { 898 $update = self::get_query_clauses( $update_args ); 899 $where = self::get_query_clauses( $where_args ); 900 901 /** 902 * Fires before an invitation is updated. 903 * 904 * @since 5.0.0 905 * 906 * @param array $where_args Array of fields to update. 907 * @param array $update_args Array of new values. 908 */ 909 do_action( 'bp_invitation_before_update', $where_args, $update_args ); 910 911 $retval = self::_update( $update['data'], $where['data'], $update['format'], $where['format'] ); 912 913 return $retval; 914 } 915 916 /** 917 * Delete invitations. 918 * 919 * @since 5.0.0 920 * 921 * @see BP_Invitations_Invitation::get() for a description of 922 * accepted where arguments. 923 * 924 * @param array $args Associative array of columns/values, to determine 925 * which rows should be deleted. Of the format 926 * array( 'item_id' => 7, 'component_action' => 'members', ) 927 * @return int|bool Number of rows deleted on success, false on failure. 928 */ 929 public static function delete( $args = array() ) { 930 $where = self::get_query_clauses( $args ); 931 932 /** 933 * Fires before an invitation is deleted. 934 * 935 * @since 5.0.0 936 * 937 * @param array $args Characteristics of the invitations to be deleted. 938 */ 939 do_action( 'bp_invitation_before_delete', $args ); 940 941 $retval = self::_delete( $where['data'], $where['format'] ); 942 943 /** 944 * Fires after an invitation is deleted. 945 * 946 * @since 5.0.0 947 * 948 * @param array $args Characteristics of the invitations just deleted. 949 */ 950 do_action( 'bp_invitation_after_delete', $args ); 951 952 return $retval; 953 } 954 955 /** Convenience methods ***********************************************/ 956 957 /** 958 * Delete a single invitation by ID. 959 * 960 * @since 5.0.0 961 * 962 * @see BP_Invitations_Invitation::delete() for explanation of 963 * return value. 964 * 965 * @param int $id ID of the invitation item to be deleted. 966 * @return bool True on success, false on failure. 967 */ 968 public static function delete_by_id( $id ) { 969 return self::delete( array( 970 'id' => $id, 971 ) ); 972 } 973 974 /** Sent status ***********************************************************/ 975 976 /** 977 * Mark specific invitations as sent by invitation ID. 978 * 979 * @since 5.0.0 980 * 981 * @param int $id The ID of the invitation to mark as sent. 982 */ 983 public static function mark_sent( $id = 0 ) { 984 985 if ( ! $id ) { 986 return false; 987 } 988 989 // Values to be updated 990 $update_args = array( 991 'invite_sent' => 'sent', 992 ); 993 994 // WHERE clauses 995 $where_args = array( 996 'id' => $id, 997 ); 998 999 return self::update( $update_args, $where_args ); 1000 } 1001 1002 /** 1003 * Mark invitations as sent that are found by user_id, inviter_id, item id, and optional 1004 * secondary item id, and component name and action. 1005 * 1006 * @since 5.0.0 1007 * 1008 * @param array $args See BP_Invitations_Invitation::update(). 1009 */ 1010 public static function mark_sent_by_data( $args ) { 1011 1012 // Values to be updated 1013 $update_args = array( 1014 'invite_sent' => 'sent', 1015 ); 1016 1017 return self::update( $update_args, $args ); 1018 } 1019 1020 /** Accepted status ***********************************************************/ 1021 1022 /** 1023 * Mark specific invitations as accepted by invitation ID. 1024 * 1025 * @since 5.0.0 1026 * 1027 * @param int $id The ID of the invitation to mark as sent. 1028 */ 1029 public static function mark_accepted( $id = 0 ) { 1030 1031 if ( ! $id ) { 1032 return false; 1033 } 1034 1035 // Values to be updated 1036 $update_args = array( 1037 'accepted' => 'accepted', 1038 ); 1039 1040 // WHERE clauses 1041 $where_args = array( 1042 'id' => $id, 1043 ); 1044 1045 return self::update( $update_args, $where_args ); 1046 } 1047 1048 /** 1049 * Mark invitations as accepted that are found by user_id, inviter_id, 1050 * item id, and optional secondary item id, and component name and action. 1051 * 1052 * @since 5.0.0 1053 * 1054 * @param array $args See BP_Invitations_Invitation::update(). 1055 */ 1056 public static function mark_accepted_by_data( $args ) { 1057 1058 // Values to be updated 1059 $update_args = array( 1060 'accepted' => 'accepted', 1061 ); 1062 1063 return self::update( $update_args, $args ); 1064 } 1065 1066 } -
new file src/bp-core/classes/class-bp-invitations.php
diff --git src/bp-core/classes/class-bp-invitations.php src/bp-core/classes/class-bp-invitations.php new file mode 100644 index 000000000..6abeb33c7
- + 1 <?php 2 /** 3 * Core invitations class. 4 * 5 * @package BuddyPress 6 * @subpackage Core 7 * @since 5.0.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * BP Invitations class. 15 * 16 * Extend it to manage your component's invitations. 17 * 18 * @since 5.0.0 19 */ 20 class BP_Invitations { 21 22 /** 23 * The name of the related component. 24 * 25 * @since 5.0.0 26 * @access public 27 * @var string 28 */ 29 protected $component_name; 30 31 /** 32 * Construct parameters. 33 * 34 * @since 5.0.0 35 * 36 * @param array|string $args { 37 38 * } 39 */ 40 public function __construct( $args = array() ) { 41 // Component name is required. 42 if ( empty( $args['component_name'] ) ) { 43 return false; 44 } 45 46 $this->component_name = sanitize_key( $args['component_name'] ); 47 } 48 49 /** 50 * Get the invitations table name. 51 * 52 * @since 5.0.0 53 * @access public 54 * @return string 55 */ 56 public static function get_table_name() { 57 return buddypress()->table_prefix . 'bp_invitations'; 58 } 59 60 /** Create ********************************************************************/ 61 62 /** 63 * Add an invitation to a specific user, from a specific user, related to a 64 * specific component. 65 * 66 * @since 5.0.0 67 * 68 * @param array $args { 69 * Array of arguments describing the invitation. All are optional. 70 * @type int $user_id ID of the invited user. 71 * @type int $inviter_id ID of the user who created the invitation. 72 * @type string $invitee_email Email address of the invited user. 73 * @type string $component_name Name of the related component. 74 * @type string $component_action Name of the related component action. 75 * @type int $item_id ID associated with the invitation and component. 76 * @type int $secondary_item_id secondary ID associated with the 77 * invitation and component. 78 * @type string $type @TODO. 79 * @type string $content Extra information provided by the requester 80 * or inviter. 81 * @type string $date_modified Date the invitation was last modified. 82 * @type int $send_invite Should the invitation also be sent, or is it a 83 * draft invite? 84 * } 85 * @return int|bool ID of the newly created invitation on success, false 86 * on failure. 87 */ 88 public function add_invitation( $args = array() ) { 89 90 $r = bp_parse_args( $args, array( 91 'user_id' => 0, 92 'invitee_email' => '', 93 'inviter_id' => 0, 94 'component_action' => '', 95 'item_id' => 0, 96 'secondary_item_id' => 0, 97 'type' => 'invite', 98 'content' => '', 99 'date_modified' => bp_core_current_time(), 100 'send_invite' => 0, 101 'accepted' => 0 102 ), 'add_invitation' ); 103 104 // Invitations must have an invitee and inviter. 105 if ( ! ( ( $r['user_id'] || $r['invitee_email'] ) && $r['inviter_id'] ) ) { 106 return false; 107 } 108 109 /** 110 * Is this user allowed to extend invitations from this component/item? 111 * 112 * @since 5.0.0 113 * 114 * @param array $r Describes the invitation to be added. 115 */ 116 if ( ! $this->allow_invitation( $r ) ) { 117 return false; 118 } 119 120 // Avoid creating duplicate invitations. 121 $invite_id = $this->invitation_exists( array( 122 'user_id' => $r['user_id'], 123 'invitee_email' => $r['invitee_email'], 124 'inviter_id' => $r['inviter_id'], 125 'component_action' => $r['component_action'], 126 'item_id' => $r['item_id'], 127 'secondary_item_id' => $r['secondary_item_id'], 128 ) ); 129 130 if ( ! $invite_id ) { 131 // Set up the new invitation as a draft. 132 $invitation = new BP_Invitations_Invitation; 133 $invitation->user_id = $r['user_id']; 134 $invitation->inviter_id = $r['inviter_id']; 135 $invitation->invitee_email = $r['invitee_email']; 136 $invitation->component_name = $this->component_name; 137 $invitation->component_action = $r['component_action']; 138 $invitation->item_id = $r['item_id']; 139 $invitation->secondary_item_id = $r['secondary_item_id']; 140 $invitation->type = $r['type']; 141 $invitation->content = $r['content']; 142 $invitation->date_modified = $r['date_modified']; 143 $invitation->invite_sent = 0; 144 $invitation->accepted = 0; 145 146 $invite_id = $invitation->save(); 147 } 148 149 // "Send" the invite if necessary. 150 if ( $invite_id && $r['send_invite'] ) { 151 $sent = $this->send_invitation_by_id( $invite_id ); 152 if ( ! $sent ) { 153 return false; 154 } 155 } 156 157 return $invite_id; 158 } 159 160 /** 161 * Send an invitation notification. 162 * 163 * @since 5.0.0 164 * @access public 165 * 166 * @param int $invitation_id ID of invitation to send. 167 * 168 * @return int|bool The number of rows updated, or false on error. 169 */ 170 public function send_invitation_by_id( $invitation_id = 0 ) { 171 $updated = false; 172 173 $invitation = new BP_Invitations_Invitation( $invitation_id ); 174 175 if ( ! $invitation->id ) { 176 return false; 177 } 178 179 /** 180 * Fires before an invitation is sent. 181 * 182 * @since 5.0.0 183 * 184 * @param BP_Invitations_Invitation object $invitation Invitation about to be sent. 185 */ 186 do_action( 'bp_invitations_send_invitation_by_id_before_send', $invitation ); 187 188 /* 189 * Before sending an invitation, check for outstanding requests to the same item. 190 * A sent invitation + a request = acceptance. 191 */ 192 $request_args = array( 193 'user_id' => $invitation->user_id, 194 'invitee_email' => $invitation->invitee_email, 195 'component_action' => $invitation->component_action, 196 'item_id' => $invitation->item_id, 197 'secondary_item_id' => $invitation->secondary_item_id, 198 ); 199 $request = $this->request_exists( $request_args ); 200 201 if ( ! empty( $request ) ) { 202 // Accept the request. 203 return $this->accept_request( $request_args ); 204 } 205 206 // Perform the send action. 207 $this->run_send_action( $invitation ); 208 209 $updated = BP_Invitations_Invitation::mark_sent( $invitation->id ); 210 211 return $updated; 212 } 213 214 /** 215 * Add a request to an item for a specific user, related to a 216 * specific component. 217 * 218 * @since 5.0.0 219 * 220 * @param array $args { 221 * Array of arguments describing the invitation. All are optional. 222 * @type int $user_id ID of the invited user. 223 * @type int $inviter_id ID of the user who created the invitation. 224 * @type string $component_name Name of the related component. 225 * @type string $component_action Name of the related component action. 226 * @type int $item_id ID associated with the invitation and component. 227 * @type int $secondary_item_id secondary ID associated with the 228 * invitation and component. 229 * @type string $type @TODO. 230 * @type string $content Extra information provided by the requester 231 * or inviter. 232 * @type string $date_modified Date the invitation was last modified. 233 * @type int $invite_sent Has the invitation been sent, or is it a 234 * draft invite? 235 * } 236 * @return int|bool ID of the newly created invitation on success, false 237 * on failure. 238 */ 239 public function add_request( $args = array() ) { 240 241 $r = bp_parse_args( $args, array( 242 'user_id' => 0, 243 'inviter_id' => 0, 244 'invitee_email' => '', 245 'component_action' => '', 246 'item_id' => 0, 247 'secondary_item_id' => 0, 248 'type' => 'request', 249 'content' => '', 250 'date_modified' => bp_core_current_time(), 251 'invite_sent' => 0, 252 'accepted' => 0 253 ), 'add_request' ); 254 255 // If there is no invitee, bail. 256 if ( ! ( $r['user_id'] || $r['invitee_email'] ) ) { 257 return false; 258 } 259 260 /** 261 * Is this user allowed to make a request to this component/item? 262 * 263 * @since 5.0.0 264 * 265 * @param array $r Describes the invitation to be added. 266 */ 267 if ( ! $this->allow_request( $r ) ) { 268 return false; 269 } 270 271 /* 272 * Avoid creating duplicate requests. 273 */ 274 $base_args = array( 275 'user_id' => $r['user_id'], 276 'invitee_email' => $r['invitee_email'], 277 'component_action' => $r['component_action'], 278 'item_id' => $r['item_id'], 279 'secondary_item_id' => $r['secondary_item_id'], 280 ); 281 if ( $this->request_exists( $base_args ) ) { 282 return false; 283 } 284 285 /* 286 * Check for outstanding invitations to the same item. 287 * A request + a sent invite = acceptance. 288 */ 289 $invite_args = array_merge( $base_args, array( 'invite_sent' => 'sent' ) ); 290 $invite = $this->invitation_exists( $invite_args ); 291 292 if ( $invite ) { 293 // Accept the invite. 294 return $this->accept_invitation( $base_args ); 295 } else { 296 // Set up the new request. 297 $request = new BP_Invitations_Invitation; 298 $request->user_id = $r['user_id']; 299 $request->inviter_id = $r['inviter_id']; 300 $request->invitee_email = $r['invitee_email']; 301 $request->component_name = $this->component_name; 302 $request->component_action = $r['component_action']; 303 $request->item_id = $r['item_id']; 304 $request->secondary_item_id = $r['secondary_item_id']; 305 $request->type = $r['type']; 306 $request->content = $r['content']; 307 $request->date_modified = $r['date_modified']; 308 $request->invite_sent = $r['invite_sent']; 309 $request->accepted = $r['accepted']; 310 311 // Save the new invitation. 312 return $request->save(); 313 } 314 } 315 316 /** 317 * Send a request notification. 318 * 319 * @since 5.0.0 320 * @access public 321 * 322 * @param int $request_id ID of request to send. 323 * 324 * @return int|bool The number of rows updated, or false on error. 325 */ 326 public function send_request_notification_by_id( $request_id = 0 ) { 327 $updated = false; 328 329 $request = new BP_Invitations_Invitation( $request_id ); 330 331 if ( ! $request->id ) { 332 return false; 333 } 334 335 // Different uses may need different actions on sending. Plugins can hook in here to perform their own tasks. 336 do_action( 'bp_invitations_send_request_notification_by_id_before_send', $request_id, $request ); 337 338 /* 339 * Before sending notifications, check for outstanding invitations to the same item. 340 * A sent invitation + a request = acceptance. 341 */ 342 $args = array( 343 'user_id' => $request->user_id, 344 'invitee_email' => $request->invitee_email, 345 'component_action' => $request->component_action, 346 'item_id' => $request->item_id, 347 'secondary_item_id' => $request->secondary_item_id, 348 'invite_sent' => 'sent' 349 ); 350 $invites = $this->invitation_exists( $args ); 351 352 if ( ! empty( $invites ) ) { 353 // Accept the request. 354 return $this->accept_invitation( $args ); 355 } 356 357 // Perform the send action. 358 $this->run_send_action( $request ); 359 360 $updated = BP_Invitations_Invitation::mark_sent( $request->id ); 361 362 return $updated; 363 } 364 365 /** Retrieve ******************************************************************/ 366 367 /** 368 * Get a specific invitation by its ID. 369 * 370 * @since 5.0.0 371 * 372 * @param int $id ID of the invitation. 373 * @return BP_Invitations_Invitation object 374 */ 375 public function get_by_id( $id = 0 ) { 376 return new BP_Invitations_Invitation( $id ); 377 } 378 379 /** 380 * Get invitations, based on provided filter parameters. 381 * 382 * @since 5.0.0 383 * 384 * @see BP_Invitations_Invitation::get() for a description of accepted parameters. 385 * 386 * @return array Located invitations. 387 */ 388 public function get_invitations( $args = array() ) { 389 // Default to returning invitations, not requests. 390 if ( empty( $args['type'] ) ) { 391 $args['type'] = 'invite'; 392 } 393 // Use this class's component_name property value. 394 $args['component_name'] = $this->component_name; 395 396 return BP_Invitations_Invitation::get( $args ); 397 } 398 399 /** 400 * Get requests, based on provided filter parameters. 401 * 402 * @since 5.0.0 403 * 404 * @see BP_Invitations_Invitation::get() for a description of accepted parameters. 405 * 406 * @return array Located invitations. 407 */ 408 public function get_requests( $args = array() ) { 409 // Set request-specific parameters. 410 $args['type'] = 'request'; 411 $args['inviter_id'] = false; 412 $args['invite_sent'] = 'all'; 413 414 // Use this class's component_name property value. 415 $args['component_name'] = $this->component_name; 416 417 return BP_Invitations_Invitation::get( $args ); 418 } 419 420 /** 421 * Check whether an invitation exists matching the passed arguments. 422 * 423 * @since 5.0.0 424 * 425 * @see BP_Invitations_Invitation::get() for a description of accepted parameters. 426 * 427 * @return bool|int ID of first found invitation or false if none found. 428 */ 429 public function invitation_exists( $args = array() ) { 430 $is_invited = false; 431 432 $args['fields'] = 'ids'; 433 $invites = $this->get_invitations( $args ); 434 if ( $invites ) { 435 $is_invited = current( $invites ); 436 } 437 return $is_invited; 438 } 439 440 /** 441 * Check whether a request exists matching the passed arguments. 442 * 443 * @since 5.0.0 444 * 445 * @see BP_Invitations_Invitation::get() for a description of accepted parameters. 446 * 447 * @return bool|int ID of existing request or false if none found. 448 */ 449 public function request_exists( $args = array() ) { 450 $has_request = false; 451 452 $args['fields'] = 'ids'; 453 $requests = $this->get_requests( $args ); 454 if ( $requests ) { 455 $has_request = current( $requests ); 456 } 457 return $has_request; 458 } 459 460 /** Update ********************************************************************/ 461 462 /** 463 * Accept invitation, based on provided filter parameters. 464 * 465 * @since 5.0.0 466 * 467 * @see BP_Invitations_Invitation::get() for a description of 468 * accepted update/where arguments. 469 * 470 * @param array $update_args Associative array of fields to update, 471 * and the values to update them to. Of the format 472 * array( 'user_id' => 4, 'component_name' => 'groups', ) 473 * 474 * @return int|bool Number of rows updated on success, false on failure. 475 */ 476 public function accept_invitation( $args = array() ) { 477 478 /* 479 * Some basic info is required to accept an invitation, 480 * because we'll need to mark all similar invitations and requests. 481 * The following, except the optional 'secondary_item_id', are required. 482 */ 483 $r = bp_parse_args( $args, array( 484 'user_id' => 0, 485 'invitee_email' => '', 486 'component_action' => '', 487 'item_id' => null, 488 'secondary_item_id' => null, 489 'invite_sent' => 'sent', 490 ), 'accept_invitation' ); 491 $r['component_name'] = $this->component_name; 492 493 if ( ! ( ( $r['user_id'] || $r['invitee_email'] ) && $r['component_name'] && $r['item_id'] ) ) { 494 return false; 495 } 496 497 $success = $this->run_acceptance_action( 'invite', $r ); 498 if ( $success ) { 499 // Mark invitations & requests to this item for this user. 500 $this->mark_accepted( $r ); 501 502 // Allow plugins an opportunity to act on the change. 503 do_action( 'bp_invitations_accepted_invite', $r ); 504 } 505 return $success; 506 } 507 508 /** 509 * Accept invitation, based on provided filter parameters. 510 * 511 * @since 5.0.0 512 * 513 * @see BP_Invitations_Invitation::get() for a description of 514 * accepted update/where arguments. 515 * 516 * @param array $update_args Associative array of fields to update, 517 * and the values to update them to. Of the format 518 * array( 'user_id' => 4, 'component_name' => 'groups', ) 519 * 520 * @return bool Number of rows updated on success, false on failure. 521 */ 522 public function accept_request( $args = array() ) { 523 /* 524 * Some basic info is required to accept an invitation, 525 * because we'll need to accept all similar invitations and requests. 526 * The following, except the optional 'secondary_item_id', are required. 527 */ 528 $r = bp_parse_args( $args, array( 529 'user_id' => 0, 530 'component_action' => '', 531 'item_id' => null, 532 'secondary_item_id' => null, 533 ), 'accept_request' ); 534 $r['component_name'] = $this->component_name; 535 536 if ( ! ( $r['user_id'] && $r['component_name'] && $r['item_id'] ) ) { 537 return false; 538 } 539 540 $success = $this->run_acceptance_action( 'request', $r ); 541 if ( $success ) { 542 // Update/Delete all related invitations & requests to this item for this user. 543 $this->mark_accepted( $r ); 544 545 // Allow plugins an opportunity to act on the change. 546 do_action( 'bp_invitations_accepted_request', $r ); 547 } 548 return $success; 549 } 550 551 /** 552 * Update invitation, based on provided filter parameters. 553 * 554 * @since 5.0.0 555 * 556 * @see BP_Invitations_Invitation::get() for a description of 557 * accepted update/where arguments. 558 * 559 * @param array $update_args Associative array of fields to update, 560 * and the values to update them to. Of the format 561 * array( 'user_id' => 4, 'component_name' => 'groups', ) 562 * @param array $where_args Associative array of columns/values, to 563 * determine which invitations should be updated. Formatted as 564 * array( 'item_id' => 7, 'component_action' => 'members', ) 565 * @return int|bool Number of rows updated on success, false on failure. 566 */ 567 public function update_invitation( $update_args = array(), $where_args = array() ) { 568 $update_args['component_name'] = $this->component_name; 569 return BP_Invitations_Invitation::update( $update_args, $where_args ); 570 } 571 572 573 /** 574 * This is where custom actions are added (in child classes) 575 * to run when an invitation or request needs to be "sent." 576 * 577 * @since 5.0.0 578 * 579 * @param BP_Invitations_Invitation $invitation The invitation to send. 580 * @return bool True on success, false on failure. 581 */ 582 public function run_send_action( BP_Invitations_Invitation $invitation ) { 583 return true; 584 } 585 586 /** 587 * Mark invitations as sent that are found by user_id, inviter_id, 588 * invitee_email, component name and action, optional item id, 589 * optional secondary item id. 590 * 591 * @since 5.0.0 592 * 593 * @param array $args { 594 * Associative array of arguments. All arguments but $page and 595 * $per_page can be treated as filter values for get_where_sql() 596 * and get_query_clauses(). All items are optional. 597 * @type int|array $user_id ID of user being queried. Can be an 598 * array of user IDs. 599 * @type int|array $inviter_id ID of user who created the 600 * invitation. Can be an array of user IDs. 601 * Special cases 602 * @type string|array $invitee_email Email address of invited users 603 * being queried. Can be an array of addresses. 604 * @type string|array $component_name Name of the component to 605 * filter by. Can be an array of component names. 606 * @type string|array $component_action Name of the action to 607 * filter by. Can be an array of actions. 608 * @type int|array $item_id ID of associated item. Can be an array 609 * of multiple item IDs. 610 * @type int|array $secondary_item_id ID of secondary associated 611 * item. Can be an array of multiple IDs. 612 * } 613 */ 614 public function mark_sent( $args ) { 615 $args['component_name'] = $this->component_name; 616 return BP_Invitations_Invitation::mark_sent_by_data( $args ); 617 } 618 619 /** 620 * This is where custom actions are added (in child classes) 621 * to run when an invitation or request is accepted. 622 * 623 * @since 5.0.0 624 * 625 * @param int $id The ID of the invitation to mark as sent. 626 * @return bool True on success, false on failure. 627 */ 628 public function run_acceptance_action( $type = 'invite', $r ) { 629 return true; 630 } 631 632 /** 633 * Mark invitation as accepted by invitation ID. 634 * 635 * @since 5.0.0 636 * 637 * @param int $id The ID of the invitation to mark as sent. 638 * @return bool True on success, false on failure. 639 */ 640 public function mark_accepted_by_id( $id ) { 641 return BP_Invitations_Invitation::mark_accepted( $id ); 642 } 643 644 /** 645 * Mark invitations as sent that are found by user_id, inviter_id, 646 * invitee_email, component name and action, optional item id, 647 * optional secondary item id. 648 * 649 * @since 5.0.0 650 * 651 * @see BP_Invitations_Invitation::mark_accepted_by_data() 652 * for a description of arguments. 653 */ 654 public function mark_accepted( $args ) { 655 $args['component_name'] = $this->component_name; 656 return BP_Invitations_Invitation::mark_accepted_by_data( $args ); 657 } 658 659 /** Delete ********************************************************************/ 660 661 /** 662 * Delete an invitation or invitations by query data. 663 * 664 * @since 5.0.0 665 * 666 * @see BP_Invitations_Invitation::delete for a description of arguments. 667 * @return int|false Number of rows deleted on success, false on failure. 668 */ 669 public function delete( $args ) { 670 if ( empty( $args['type'] ) ) { 671 $args['type'] = 'invite'; 672 } 673 $args['component_name'] = $this->component_name; 674 return BP_Invitations_Invitation::delete( $args ); 675 } 676 677 /** 678 * Delete a request or requests by query data. 679 * 680 * @since 5.0.0 681 * 682 * @see BP_Invitations_Invitation::delete for a description of arguments. 683 * 684 * @return int|false Number of rows deleted on success, false on failure. 685 */ 686 public function delete_requests( $args ) { 687 $args['type'] = 'request'; 688 return $this->delete( $args ); 689 } 690 691 /** 692 * Delete all invitations by component. 693 * 694 * Used when clearing out invitations for an entire component. Possibly used 695 * when deactivating a component that created invitations. 696 * 697 * @since 5.0.0 698 * 699 * @param string $component_action Optional. Name of the associated action. 700 * @return int|false Number of rows deleted on success, false on failure. 701 */ 702 public function delete_all( $component_action = false ) { 703 return BP_Invitations_Invitation::delete( array( 704 'component_name' => $this->component_name, 705 'component_action' => $component_action, 706 ) ); 707 } 708 709 /** 710 * This is where custom actions are added (in child classes) 711 * to determine whether an invitation should be allowed. 712 * 713 * @since 5.0.0 714 * 715 * @param array $args The parameters describing the invitation. 716 * @return bool True if allowed, false to end process. 717 */ 718 public function allow_invitation( $args ) { 719 return true; 720 } 721 722 /** 723 * This is where custom actions are added (in child classes) 724 * to determine whether a request should be allowed. 725 * 726 * @since 5.0.0 727 * 728 * @param array $args The parameters describing the request. 729 * @return bool True if allowed, false to end process. 730 */ 731 public function allow_request( $args ) { 732 return true; 733 } 734 735 } -
src/bp-groups/actions/leave-group.php
diff --git src/bp-groups/actions/leave-group.php src/bp-groups/actions/leave-group.php index 860e9fc1d..ed87abccf 100644
function groups_action_leave_group() { 58 58 /** This filter is documented in bp-groups/bp-groups-actions.php */ 59 59 bp_core_load_template( apply_filters( 'groups_template_group_home', 'groups/single/home' ) ); 60 60 } 61 add_action( 'bp_actions', 'groups_action_leave_group' ); 62 No newline at end of file 61 add_action( 'bp_actions', 'groups_action_leave_group' ); 62 63 /** 64 * Clean up requests/invites when a member leaves a group. 65 * 66 * @since 5.0.0 67 */ 68 function groups_action_clean_up_invites_requests( $user_id, $group_id ) { 69 $invites_class = new BP_Groups_Invitations(); 70 // Remove invitations/requests where the deleted user is the receiver. 71 $invites_class->delete( array( 72 'user_id' => $user_id, 73 'item_id' => $group_id, 74 'type' => 'all' 75 ) ); 76 // Remove invitations where the deleted user is the sender. 77 $invites_class->delete( array( 78 'inviter_id' => $user_id, 79 'item_id' => $group_id, 80 ) ); 81 } 82 add_action( 'bp_groups_member_after_delete', 'groups_action_clean_up_invites_requests', 10, 2 ); -
src/bp-groups/bp-groups-functions.php
diff --git src/bp-groups/bp-groups-functions.php src/bp-groups/bp-groups-functions.php index 43240122a..7daa03211 100644
function bp_get_user_groups( $user_id, $args = array() ) { 949 949 950 950 $user_id = intval( $user_id ); 951 951 952 // @TODO-6210: This is tied to the groups membership table. How to include invites/requests from a separate table? 952 953 $membership_ids = wp_cache_get( $user_id, 'bp_groups_memberships_for_user' ); 953 954 if ( false === $membership_ids ) { 954 955 $membership_ids = BP_Groups_Member::get_membership_ids_for_user( $user_id ); … … function groups_is_user_banned( $user_id, $group_id ) { 1209 1210 * Check whether a user has an outstanding invitation to a group. 1210 1211 * 1211 1212 * @since 2.6.0 1213 * @since 5.0.0 Added $type parameter. 1212 1214 * 1213 * @param int $user_id ID of the user. 1214 * @param int $group_id ID of the group. 1215 * @param int $user_id ID of the user. 1216 * @param int $group_id ID of the group. 1217 * @param string $type If 'sent', results are limited to those invitations 1218 * that have actually been sent (non-draft). 1219 * Possible values: 'sent', 'draft', or 'all' Default: 'sent'. 1215 1220 * @return int|bool ID of the membership if the user is invited, otherwise false. 1216 1221 */ 1217 function groups_is_user_invited( $user_id, $group_id ) { 1218 $is_invited = false; 1219 1220 $user_groups = bp_get_user_groups( $user_id, array( 1221 'invite_sent' => true, 1222 'is_confirmed' => false, 1223 ) ); 1224 1225 if ( isset( $user_groups[ $group_id ] ) ) { 1226 $is_invited = $user_groups[ $group_id ]->id; 1227 } 1228 1229 return $is_invited; 1222 function groups_is_user_invited( $user_id, $group_id, $type = 'sent' ) { 1223 return groups_check_has_invite_from_user( $user_id, $group_id, false, $type ); 1230 1224 } 1231 1225 1232 1226 /** … … function groups_is_user_invited( $user_id, $group_id ) { 1239 1233 * @return int|bool ID of the membership if the user is pending, otherwise false. 1240 1234 */ 1241 1235 function groups_is_user_pending( $user_id, $group_id ) { 1242 $is_pending = false; 1243 1244 $user_groups = bp_get_user_groups( $user_id, array( 1245 'invite_sent' => false, 1246 'is_confirmed' => false, 1247 ) ); 1248 1249 if ( isset( $user_groups[ $group_id ] ) ) { 1250 $is_pending = $user_groups[ $group_id ]->id; 1236 if ( empty( $user_id ) || empty( $group_id ) ) { 1237 return false; 1251 1238 } 1252 1239 1253 return $is_pending; 1240 $args = array( 1241 'user_id' => $user_id, 1242 'item_id' => $group_id, 1243 ); 1244 $invites_class = new BP_Groups_Invitations(); 1245 1246 return $invites_class->request_exists( $args ); 1254 1247 } 1255 1248 1256 1249 /** … … function groups_post_update( $args = '' ) { 1362 1355 /** Group Invitations *********************************************************/ 1363 1356 1364 1357 /** 1365 * Get IDs of users with outstanding invites to a given group from a specified user.1358 * Get group objects for groups that a user is currently invited to. 1366 1359 * 1367 1360 * @since 1.0.0 1368 1361 * 1369 * @param int $user_id ID of the invit inguser.1362 * @param int $user_id ID of the invited user. 1370 1363 * @param int|bool $limit Limit to restrict to. 1371 1364 * @param int|bool $page Optional. Page offset of results to return. 1372 1365 * @param string|array|bool $exclude Array of comma-separated list of group IDs 1373 1366 * to exclude from results. 1374 * @return array $value IDs of users who have been invited to the group by the 1375 * user but have not yet accepted. 1367 * @return array { 1368 * @type array $groups Array of groups returned by paginated query. 1369 * @type int $total Count of groups matching query. 1370 * } 1376 1371 */ 1377 1372 function groups_get_invites_for_user( $user_id = 0, $limit = false, $page = false, $exclude = false ) { 1378 1379 if ( empty( $user_id ) ) 1373 if ( empty( $user_id ) ) { 1380 1374 $user_id = bp_loggedin_user_id(); 1375 } 1376 1377 $group_ids = groups_get_invited_to_group_ids( $user_id ); 1378 1379 // Remove excluded groups. 1380 if ( $exclude ) { 1381 $group_ids = array_diff( $group_ids, wp_parse_id_list( $exclude ) ); 1382 } 1381 1383 1382 return BP_Groups_Member::get_invites( $user_id, $limit, $page, $exclude ); 1384 // Avoid passing an empty array. 1385 if ( ! $group_ids ) { 1386 $group_ids = array( 0 ); 1387 } 1388 1389 // Get a filtered list of groups. 1390 $args = array( 1391 'include' => $group_ids, 1392 'show_hidden' => true, 1393 'per_page' => $limit, 1394 'page' => $page, 1395 ); 1396 $groups = groups_get_groups( $args ); 1397 1398 return array( 'groups' => $groups['groups'], 'total' => groups_get_invite_count_for_user( $user_id ) ); 1383 1399 } 1384 1400 1385 1401 /** … … function groups_get_invite_count_for_user( $user_id = 0 ) { 1395 1411 $user_id = bp_loggedin_user_id(); 1396 1412 } 1397 1413 1398 return BP_Groups_Member::get_invite_count_for_user( $user_id ); 1414 return count( groups_get_invited_to_group_ids( $user_id ) ); 1415 } 1416 1417 /** 1418 * Get an array of group IDs to which a user is invited. 1419 * 1420 * @since 5.0.0 1421 * 1422 * @param int $user_id The user ID. 1423 * 1424 * @return array Array of group IDs. 1425 */ 1426 function groups_get_invited_to_group_ids( $user_id = 0 ) { 1427 if ( empty( $user_id ) ) { 1428 $user_id = bp_loggedin_user_id(); 1429 } 1430 1431 $group_ids = groups_get_invites( array( 1432 'user_id' => $user_id, 1433 'invite_sent' => 'sent', 1434 'fields' => 'item_ids' 1435 ) ); 1436 1437 return array_unique( $group_ids ); 1399 1438 } 1400 1439 1401 1440 /** … … function groups_get_invite_count_for_user( $user_id = 0 ) { 1411 1450 * ID of the logged-in user. 1412 1451 * @type string $date_modified Optional. Modified date for the invitation. 1413 1452 * Default: current date/time. 1414 * @type bool $is_confirmed Optional. Whether the invitation should be 1415 * marked confirmed. Default: false. 1453 * @type string $content Optional. Message to invitee. 1454 * @type bool $send_invite Optional. Whether the invitation should be 1455 * sent now. Default: false. 1416 1456 * } 1417 1457 * @return bool True on success, false on failure. 1418 1458 */ 1419 1459 function groups_invite_user( $args = '' ) { 1420 1460 1421 $ args= bp_parse_args( $args, array(1461 $r = bp_parse_args( $args, array( 1422 1462 'user_id' => false, 1423 1463 'group_id' => false, 1424 1464 'inviter_id' => bp_loggedin_user_id(), 1425 1465 'date_modified' => bp_core_current_time(), 1426 'is_confirmed' => 0 1466 'content' => '', 1467 'send_invite' => 0 1427 1468 ), 'groups_invite_user' ); 1428 extract( $args, EXTR_SKIP );1429 1469 1430 if ( ! $user_id || ! $group_id || ! $inviter_id ) { 1431 return false; 1432 } 1433 1434 // If the user has already requested membership, accept the request. 1435 if ( $membership_id = groups_check_for_membership_request( $user_id, $group_id ) ) { 1436 groups_accept_membership_request( $membership_id, $user_id, $group_id ); 1437 1438 // Otherwise, create a new invitation. 1439 } elseif ( ! groups_is_user_member( $user_id, $group_id ) && ! groups_check_user_has_invite( $user_id, $group_id, 'all' ) ) { 1440 $invite = new BP_Groups_Member; 1441 $invite->group_id = $group_id; 1442 $invite->user_id = $user_id; 1443 $invite->date_modified = $date_modified; 1444 $invite->inviter_id = $inviter_id; 1445 $invite->is_confirmed = $is_confirmed; 1470 $inv_args = array( 1471 'user_id' => $r['user_id'], 1472 'item_id' => $r['group_id'], 1473 'inviter_id' => $r['inviter_id'], 1474 'date_modified' => $r['date_modified'], 1475 'content' => $r['content'], 1476 'send_invite' => $r['send_invite'] 1477 ); 1446 1478 1447 if ( !$invite->save() ) 1448 return false; 1479 // Create the unsent invitataion. 1480 $invites_class = new BP_Groups_Invitations(); 1481 $created = $invites_class->add_invitation( $inv_args ); 1449 1482 1450 1451 1452 1453 1454 1455 * @param array $argsArray of parsed arguments for the group invite.1456 */1457 do_action( 'groups_invite_user', $args );1458 }1483 /** 1484 * Fires after the creation of a new group invite. 1485 * 1486 * @since 1.0.0 1487 * 1488 * @param array $r Array of parsed arguments for the group invite. 1489 * @param int|bool $created The ID of the invitation or false if it couldn't be created. 1490 */ 1491 do_action( 'groups_invite_user', $r, $created ); 1459 1492 1460 return true;1493 return $created; 1461 1494 } 1462 1495 1463 1496 /** … … function groups_invite_user( $args = '' ) { 1469 1502 * 1470 1503 * @param int $user_id ID of the user. 1471 1504 * @param int $group_id ID of the group. 1505 * @param int $inviter_id ID of the inviter. 1472 1506 * @return bool True on success, false on failure. 1473 1507 */ 1474 function groups_uninvite_user( $user_id, $group_id ) { 1475 1476 if ( ! BP_Groups_Member::delete_invite( $user_id, $group_id ) ) 1508 function groups_uninvite_user( $user_id, $group_id, $inviter_id = false ) { 1509 if ( empty( $user_id ) || empty( $group_id ) ) { 1477 1510 return false; 1511 } 1478 1512 1479 /** 1480 * Fires after uninviting a user from a group. 1481 * 1482 * @since 1.0.0 1483 * 1484 * @param int $group_id ID of the group being uninvited from. 1485 * @param int $user_id ID of the user being uninvited. 1486 */ 1487 do_action( 'groups_uninvite_user', $group_id, $user_id ); 1513 $invites_class = new BP_Groups_Invitations(); 1514 $success = $invites_class->delete( array( 1515 'user_id' => $user_id, 1516 'item_id' => $group_id, 1517 'inviter_id' => $inviter_id, 1518 ) ); 1488 1519 1489 return true; 1520 if ( $success ) { 1521 /** 1522 * Fires after uninviting a user from a group. 1523 * 1524 * @since 1.0.0 1525 * @since 2.7.0 Added $inviter_id parameter 1526 * 1527 * @param int $group_id ID of the group being uninvited from. 1528 * @param int $user_id ID of the user being uninvited. 1529 * @param int $inviter_id ID of the inviter. 1530 */ 1531 do_action( 'groups_uninvite_user', $group_id, $user_id, $inviter_id ); 1532 } 1533 1534 return $success; 1490 1535 } 1491 1536 1492 1537 /** … … function groups_uninvite_user( $user_id, $group_id ) { 1501 1546 * @return bool True when the user is a member of the group, otherwise false. 1502 1547 */ 1503 1548 function groups_accept_invite( $user_id, $group_id ) { 1549 $invites_class = new BP_Groups_Invitations(); 1550 $args = array( 1551 'user_id' => $user_id, 1552 'item_id' => $group_id, 1553 'invite_sent' => 'sent', 1554 ); 1555 // Get an inviter_id from the invitation. 1556 $invites = groups_get_invites( $args ); 1557 $inviter_id = 0; 1558 if ( $invites ) { 1559 $inviter_id = current( $invites )->inviter_id; 1560 } 1504 1561 1505 // If the user is already a member (because BP at one point allowed two invitations to 1506 // slip through), delete all existing invitations/requests and return true. 1507 if ( groups_is_user_member( $user_id, $group_id ) ) { 1508 if ( groups_check_user_has_invite( $user_id, $group_id ) ) { 1509 groups_delete_invite( $user_id, $group_id ); 1510 } 1511 1512 if ( groups_check_for_membership_request( $user_id, $group_id ) ) { 1513 groups_delete_membership_request( null, $user_id, $group_id ); 1514 } 1515 1516 return true; 1517 } 1518 1519 $member = new BP_Groups_Member( $user_id, $group_id ); 1520 1521 // Save the inviter ID so that we can pass it to the action below. 1522 $inviter_id = $member->inviter_id; 1523 1524 $member->accept_invite(); 1525 1526 if ( !$member->save() ) { 1527 return false; 1528 } 1529 1530 // Remove request to join. 1531 if ( $member->check_for_membership_request( $user_id, $group_id ) ) { 1532 $member->delete_request( $user_id, $group_id ); 1533 } 1534 1535 // Modify group meta. 1536 groups_update_groupmeta( $group_id, 'last_activity', bp_core_current_time() ); 1562 $invites_class->accept_invitation( $args ); 1537 1563 1538 1564 /** 1539 1565 * Fires after a user has accepted a group invite. … … function groups_accept_invite( $user_id, $group_id ) { 1554 1580 * Reject a group invitation. 1555 1581 * 1556 1582 * @since 1.0.0 1583 * @since 5.0.0 The $inviter_id arg was added. 1584 * 1585 * @param int $user_id ID of the user. 1586 * @param int $group_id ID of the group. 1587 * @param int $inviter_id ID of the inviter. 1557 1588 * 1558 * @param int $user_id ID of the user.1559 * @param int $group_id ID of the group.1560 1589 * @return bool True on success, false on failure. 1561 1590 */ 1562 function groups_reject_invite( $user_id, $group_id ) {1563 if ( ! BP_Groups_Member::delete_invite( $user_id, $group_id ) )1591 function groups_reject_invite( $user_id, $group_id, $inviter_id = false ) { 1592 if ( empty( $user_id ) || empty( $group_id ) ) { 1564 1593 return false; 1594 } 1595 1596 $invites_class = new BP_Groups_Invitations(); 1597 $success = $invites_class->delete( array( 1598 'user_id' => $user_id, 1599 'item_id' => $group_id, 1600 'inviter_id' => $inviter_id, 1601 ) ); 1565 1602 1566 1603 /** 1567 1604 * Fires after a user rejects a group invitation. 1568 1605 * 1569 1606 * @since 1.0.0 1607 * @since 5.0.0 The $inviter_id arg was added. 1570 1608 * 1571 1609 * @param int $user_id ID of the user rejecting the invite. 1572 1610 * @param int $group_id ID of the group being rejected. 1611 * @param int $inviter_id ID of the inviter. 1573 1612 */ 1574 do_action( 'groups_reject_invite', $user_id, $group_id );1613 do_action( 'groups_reject_invite', $user_id, $group_id, $inviter_id ); 1575 1614 1576 return true;1615 return $success; 1577 1616 } 1578 1617 1579 1618 /** 1580 1619 * Delete a group invitation. 1581 1620 * 1582 1621 * @since 1.0.0 1622 * @since 5.0.0 The $inviter_id arg was added. 1583 1623 * 1584 1624 * @param int $user_id ID of the invited user. 1585 1625 * @param int $group_id ID of the group. 1626 * @param int $inviter_id ID of the inviter. 1627 * 1586 1628 * @return bool True on success, false on failure. 1587 1629 */ 1588 function groups_delete_invite( $user_id, $group_id ) {1589 if ( ! BP_Groups_Member::delete_invite( $user_id, $group_id ) )1630 function groups_delete_invite( $user_id, $group_id, $inviter_id = false ) { 1631 if ( empty( $user_id ) || empty( $group_id ) ) { 1590 1632 return false; 1633 } 1634 1635 $invites_class = new BP_Groups_Invitations(); 1636 $success = $invites_class->delete( array( 1637 'user_id' => $user_id, 1638 'item_id' => $group_id, 1639 'inviter_id' => $inviter_id, 1640 ) ); 1591 1641 1592 1642 /** 1593 1643 * Fires after the deletion of a group invitation. 1594 1644 * 1595 1645 * @since 1.9.0 1646 * @since 5.0.0 The $inviter_id arg was added. 1596 1647 * 1597 1648 * @param int $user_id ID of the user whose invitation is being deleted. 1598 1649 * @param int $group_id ID of the group whose invitation is being deleted. 1650 * @param int $inviter_id ID of the inviter. 1599 1651 */ 1600 do_action( 'groups_delete_invite', $user_id, $group_id );1652 do_action( 'groups_delete_invite', $user_id, $group_id, $inviter_id ); 1601 1653 1602 1654 return true; 1603 1655 } 1604 1656 1605 1657 /** 1606 * Send all pending invites by a single user to a specific group.1658 * Send some or all pending invites by a single user to a specific group. 1607 1659 * 1608 1660 * @since 1.0.0 1661 * @since 5.0.0 Parameters changed to associative array. 1609 1662 * 1610 * @param int $user_id ID of the inviting user. 1611 * @param int $group_id ID of the group. 1663 * @param array $args { 1664 * An array of optional arguments. 1665 * @type int $user_id ID of the invited user. 1666 * @type string $invitee_email Email address of the invited user, if not a member of the site. 1667 * @type string $group_id ID of the group or an array of group IDs. 1668 * @type string $inviter_id ID of the user extending the invitation. 1669 * @type bool $force_resend Whether to resend the email & notification if one has already been sent. 1670 * } 1612 1671 */ 1613 function groups_send_invites( $user_id, $group_id ) { 1672 function groups_send_invites( $args = array() ) { 1673 // Backward compatibility with old method of passing arguments. 1674 if ( ! is_array( $args ) || func_num_args() > 1 ) { 1675 _deprecated_argument( __METHOD__, '5.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__ ) ); 1614 1676 1615 if ( empty( $user_id ) ) 1616 $user_id = bp_loggedin_user_id(); 1677 $old_args_keys = array( 1678 0 => 'inviter_id', 1679 1 => 'group_id', 1680 ); 1617 1681 1618 // Send friend invites. 1619 $invited_users = groups_get_invites_for_group( $user_id, $group_id ); 1620 $group = groups_get_group( $group_id ); 1682 $args = bp_core_parse_args_array( $old_args_keys, func_get_args() ); 1683 } 1621 1684 1622 for ( $i = 0, $count = count( $invited_users ); $i < $count; ++$i ) { 1623 $member = new BP_Groups_Member( $invited_users[$i], $group_id ); 1685 $r = bp_parse_args( $args, array( 1686 'user_id' => false, 1687 'invitee_email' => '', 1688 'group_id' => 0, 1689 'inviter_id' => bp_loggedin_user_id(), 1690 'force_resend' => false, 1691 ), 'groups_send_invitation' ); 1624 1692 1625 // Skip if we've already sent an invite to this user. 1626 if ( $member->invite_sent ) { 1627 continue; 1628 } 1693 /* 1694 * We will generally only want to fetch unsent invitations. 1695 * If force_resend is true, then we need to fetch both sent and draft invites. 1696 */ 1697 if ( $r['force_resend'] ) { 1698 $args['invite_sent'] = 'all'; 1699 } else { 1700 $args['invite_sent'] = 'draft'; 1701 } 1629 1702 1630 // Send the actual invite. 1631 groups_notification_group_invites( $group, $member, $user_id ); 1703 $args = array( 1704 'user_id' => $r['user_id'], 1705 'invitee_email' => $r['invitee_email'], 1706 'item_id' => $r['group_id'], 1707 'inviter_id' => $r['inviter_id'], 1708 ); 1709 $invites = groups_get_invites( $args ); 1632 1710 1633 $member->invite_sent = 1; 1634 $member->save(); 1711 $invited_users = array(); 1712 1713 $invites_class = new BP_Groups_Invitations(); 1714 foreach ( $invites as $invite ) { 1715 $invited_users[] = $invite->user_id; 1716 $invites_class->send_invitation_by_id( $invite->id ); 1635 1717 } 1636 1718 1637 1719 /** … … function groups_send_invites( $user_id, $group_id ) { 1644 1726 * @param array $invited_users Array of users being invited to the group. 1645 1727 * @param int $user_id ID of the inviting user. 1646 1728 */ 1647 do_action( 'groups_send_invites', $ group_id, $invited_users, $user_id);1729 do_action( 'groups_send_invites', $r['group_id'], $invited_users, $r['inviter_id'] ); 1648 1730 } 1649 1731 1650 1732 /** 1651 * Get IDs of users with outstanding invites to a given group from a specified user.1733 * Get IDs of users with outstanding invites to a given group. 1652 1734 * 1653 1735 * @since 1.0.0 1654 1736 * @since 2.9.0 Added $sent as a parameter. … … function groups_get_invites_for_group( $user_id, $group_id, $sent = null ) { 1666 1748 return BP_Groups_Group::get_invites( $user_id, $group_id, $sent ); 1667 1749 } 1668 1750 1751 /** 1752 * Get invitations to a given group filtered by arguments. 1753 * 1754 * @since 5.0.0 1755 * 1756 * @param int $group_id ID of the group. 1757 * @param array $args Invitation arguments. 1758 * See BP_Invitations_Invitation::get() for list. 1759 * 1760 * @return array $invites Matching BP_Invitations_Invitation objects. 1761 */ 1762 function groups_get_invites( $args = array() ) { 1763 $invites_class = new BP_Groups_Invitations(); 1764 return $invites_class->get_invitations( $args ); 1765 } 1766 1669 1767 /** 1670 1768 * Check to see whether a user has already been invited to a group. 1671 1769 * … … function groups_get_invites_for_group( $user_id, $group_id, $sent = null ) { 1679 1777 * @param int $group_id ID of potential group. 1680 1778 * @param string $type Optional. Use 'sent' to check for sent invites, 1681 1779 * 'all' to check for all. Default: 'sent'. 1682 * @return int|bool ID of the membership if found, otherwise false.1780 * @return int|bool ID of the first found membership if found, otherwise false. 1683 1781 */ 1684 1782 function groups_check_user_has_invite( $user_id, $group_id, $type = 'sent' ) { 1685 $invite = false; 1783 return groups_check_has_invite_from_user( $user_id, $group_id, false, $type ); 1784 } 1785 1786 /** 1787 * Check to see whether a user has already been invited to a group by a particular user. 1788 * 1789 * By default, the function checks for invitations that have been sent. 1790 * Entering 'all' as the $type parameter will return unsent invitations as 1791 * well (useful to make sure AJAX requests are not duplicated). 1792 * 1793 * @since 5.0.0 1794 * 1795 * @param int $user_id ID of potential group member. 1796 * @param int $group_id ID of potential group. 1797 * @param string $inviter_id Optional. Use 'sent' to check for sent invites, 1798 * 'all' to check for all. Default: 'sent'. 1799 * @param string $type Optional. Specify a user ID to limit to only invited from that user. 1800 * Default: 'false'. 1801 * @return int|bool ID of the first found membership if found, otherwise false. 1802 */ 1803 function groups_check_has_invite_from_user( $user_id, $group_id, $inviter_id = false, $type = 'sent' ) { 1804 if ( empty( $user_id ) || empty( $group_id ) ) { 1805 return false; 1806 } 1686 1807 1687 1808 $args = array( 1688 'is_confirmed' => false, 1689 'is_banned' => null, 1690 'is_admin' => null, 1691 'is_mod' => null, 1809 'user_id' => $user_id, 1810 'item_id' => $group_id, 1811 'invite_sent' => 'sent', 1692 1812 ); 1693 1694 if ( 'sent' === $type ) { 1695 $args['invite_sent'] = true; 1813 if ( $inviter_id ) { 1814 $args['inviter_id'] = $inviter_id; 1696 1815 } 1697 1698 $user_groups = bp_get_user_groups( $user_id, $args ); 1699 1700 if ( isset( $user_groups[ $group_id ] ) && 0 !== $user_groups[ $group_id ]->inviter_id ) { 1701 $invite = $user_groups[ $group_id ]->id; 1816 if ( $type === 'draft' || $type === 'all' ) { 1817 $args['invite_sent'] = $type; 1702 1818 } 1703 1819 1704 return $invite; 1820 $invites_class = new BP_Groups_Invitations(); 1821 1822 return $invites_class->invitation_exists( $args ); 1705 1823 } 1706 1824 1707 1825 /** … … function groups_remove_member( $user_id, $group_id ) { 1878 1996 * 1879 1997 * @since 1.0.0 1880 1998 * 1881 * @param int $requesting_user_id ID of the user requesting membership. 1882 * @param int $group_id ID of the group. 1999 * @param array|string $args { 2000 * Array of arguments. 2001 * @type int $user_id ID of the user being invited. 2002 * @type int $group_id ID of the group to which the user is being invited. 2003 * @type string $content Optional. Message to invitee. 2004 * @type string $date_modified Optional. Modified date for the invitation. 2005 * Default: current date/time. 2006 * } 1883 2007 * @return bool True on success, false on failure. 1884 2008 */ 1885 function groups_send_membership_request( $requesting_user_id, $group_id ) { 1886 1887 // Prevent duplicate requests. 1888 if ( groups_check_for_membership_request( $requesting_user_id, $group_id ) ) 1889 return false; 2009 function groups_send_membership_request( $args = array() ) { 2010 // Backward compatibility with old method of passing arguments. 2011 if ( ! is_array( $args ) || func_num_args() > 1 ) { 2012 _deprecated_argument( __METHOD__, '5.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__ ) ); 1890 2013 1891 // Check if the user is already a member or is banned. 1892 if ( groups_is_user_member( $requesting_user_id, $group_id ) || groups_is_user_banned( $requesting_user_id, $group_id ) ) 1893 return false; 2014 $old_args_keys = array( 2015 0 => 'user_id', 2016 1 => 'group_id', 2017 ); 1894 2018 1895 // Check if the user is already invited - if so, simply accept invite. 1896 if ( groups_check_user_has_invite( $requesting_user_id, $group_id ) ) { 1897 groups_accept_invite( $requesting_user_id, $group_id ); 1898 return true; 2019 $args = bp_core_parse_args_array( $old_args_keys, func_get_args() ); 1899 2020 } 1900 2021 1901 $requesting_user = new BP_Groups_Member; 1902 $requesting_user->group_id = $group_id; 1903 $requesting_user->user_id = $requesting_user_id; 1904 $requesting_user->inviter_id = 0; 1905 $requesting_user->is_admin = 0; 1906 $requesting_user->user_title = ''; 1907 $requesting_user->date_modified = bp_core_current_time(); 1908 $requesting_user->is_confirmed = 0; 1909 $requesting_user->comments = isset( $_POST['group-request-membership-comments'] ) ? $_POST['group-request-membership-comments'] : ''; 2022 $r = bp_parse_args( $args, array( 2023 'user_id' => false, 2024 'group_id' => false, 2025 'content' => '', 2026 'date_modified' => bp_core_current_time(), 2027 ), 'groups_invite_user' ); 1910 2028 1911 if ( $requesting_user->save() ) { 1912 $admins = groups_get_group_admins( $group_id ); 2029 $inv_args = array( 2030 'user_id' => $r['user_id'], 2031 'item_id' => $r['group_id'], 2032 'content' => $r['content'], 2033 'date_modified' => $r['date_modified'], 2034 ); 2035 2036 $invites_class = new BP_Groups_Invitations(); 2037 $request_id = $invites_class->add_request( $inv_args ); 1913 2038 1914 // Saved okay, now send the email notification. 1915 for ( $i = 0, $count = count( $admins ); $i < $count; ++$i ) 1916 groups_notification_new_membership_request( $requesting_user_id, $admins[$i]->user_id, $group_id, $requesting_user->id ); 2039 // If a new request was created, send the emails. 2040 if ( $request_id && is_int( $request_id ) ) { 2041 $invites_class->send_request_notification_by_id( $request_id ); 2042 $admins = groups_get_group_admins( $r['group_id'] ); 1917 2043 1918 2044 /** 1919 2045 * Fires after the creation of a new membership request. … … function groups_send_membership_request( $requesting_user_id, $group_id ) { 1923 2049 * @param int $requesting_user_id ID of the user requesting membership. 1924 2050 * @param array $admins Array of group admins. 1925 2051 * @param int $group_id ID of the group being requested to. 1926 * @param int $request ing_user->id ID of the membership.2052 * @param int $request_id ID of the request. 1927 2053 */ 1928 do_action( 'groups_membership_requested', $r equesting_user_id, $admins, $group_id, $requesting_user->id );2054 do_action( 'groups_membership_requested', $r['user_id'], $admins, $r['group_id'], $request_id ); 1929 2055 1930 return true;2056 return $request_id; 1931 2057 } 1932 2058 1933 2059 return false; … … function groups_send_membership_request( $requesting_user_id, $group_id ) { 1937 2063 * Accept a pending group membership request. 1938 2064 * 1939 2065 * @since 1.0.0 2066 * @since 5.0.0 Deprecated $membership_id argument. 1940 2067 * 1941 * @param int $membership_id ID of the membership object.1942 * @param int $user_id Optional. ID of the user who requested membership.2068 * @param int $membership_id Deprecated 5.0.0. 2069 * @param int $user_id Required. ID of the user who requested membership. 1943 2070 * Provide this value along with $group_id to override 1944 2071 * $membership_id. 1945 * @param int $group_id Optional. ID of the group to which membership is being2072 * @param int $group_id Required. ID of the group to which membership is being 1946 2073 * requested. Provide this value along with $user_id to 1947 2074 * override $membership_id. 1948 2075 * @return bool True on success, false on failure. 1949 2076 */ 1950 2077 function groups_accept_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) { 1951 2078 1952 if ( !empty( $user_id ) && !empty( $group_id ) ) { 1953 $membership = new BP_Groups_Member( $user_id, $group_id ); 1954 } else { 1955 $membership = new BP_Groups_Member( false, false, $membership_id ); 2079 if ( ! empty( $membership_id ) ) { 2080 _deprecated_argument( __METHOD__, '5.0.0', sprintf( __( 'Argument `membership_id` passed to %1$s is deprecated. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) ); 1956 2081 } 1957 2082 1958 $membership->accept_request(); 1959 1960 if ( !$membership->save() ) { 2083 if ( ! $user_id || ! $group_id ) { 1961 2084 return false; 1962 2085 } 1963 2086 1964 // Check if the user has an outstanding invite, if so delete it. 1965 if ( groups_check_user_has_invite( $membership->user_id, $membership->group_id ) ) { 1966 groups_delete_invite( $membership->user_id, $membership->group_id ); 1967 } 2087 $invites_class = new BP_Groups_Invitations(); 2088 $args = array( 2089 'user_id' => $user_id, 2090 'item_id' => $group_id, 2091 ); 2092 $invites_class->accept_request( $args ); 1968 2093 1969 2094 /** 1970 2095 * Fires after a group membership request has been accepted. … … function groups_accept_membership_request( $membership_id, $user_id = 0, $group_ 1975 2100 * @param int $group_id ID of the group that was accepted membership to. 1976 2101 * @param bool $value If membership was accepted. 1977 2102 */ 1978 do_action( 'groups_membership_accepted', $ membership->user_id, $membership->group_id, true );2103 do_action( 'groups_membership_accepted', $user_id, $group_id, true ); 1979 2104 1980 2105 return true; 1981 2106 } … … function groups_accept_membership_request( $membership_id, $user_id = 0, $group_ 1985 2110 * 1986 2111 * @since 1.0.0 1987 2112 * 1988 * @param int $membership_id ID of the membership object.2113 * @param int $membership_id Deprecated 5.0.0. 1989 2114 * @param int $user_id Optional. ID of the user who requested membership. 1990 2115 * Provide this value along with $group_id to override 1991 2116 * $membership_id. … … function groups_accept_membership_request( $membership_id, $user_id = 0, $group_ 1995 2120 * @return bool True on success, false on failure. 1996 2121 */ 1997 2122 function groups_reject_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) { 1998 if ( !$membership = groups_delete_membership_request( $membership_id, $user_id, $group_id ) ) { 2123 2124 if ( ! empty( $membership_id ) ){ 2125 _deprecated_argument( __METHOD__, '5.0.0', sprintf( __( 'Argument `membership_id` passed to %1$s is deprecated. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) ); 2126 } 2127 2128 if ( ! groups_delete_membership_request( false, $user_id, $group_id ) ) { 1999 2129 return false; 2000 2130 } 2001 2131 … … function groups_reject_membership_request( $membership_id, $user_id = 0, $group_ 2008 2138 * @param int $group_id ID of the group that was rejected membership to. 2009 2139 * @param bool $value If membership was accepted. 2010 2140 */ 2011 do_action( 'groups_membership_rejected', $ membership->user_id, $membership->group_id, false );2141 do_action( 'groups_membership_rejected', $user_id, $group_id, false ); 2012 2142 2013 2143 return true; 2014 2144 } … … function groups_reject_membership_request( $membership_id, $user_id = 0, $group_ 2018 2148 * 2019 2149 * @since 1.2.0 2020 2150 * 2021 * @param int $membership_id ID of the membership object.2151 * @param int $membership_id Deprecated 5.0.0. 2022 2152 * @param int $user_id Optional. ID of the user who requested membership. 2023 2153 * Provide this value along with $group_id to override 2024 2154 * $membership_id. … … function groups_reject_membership_request( $membership_id, $user_id = 0, $group_ 2028 2158 * @return false|BP_Groups_Member True on success, false on failure. 2029 2159 */ 2030 2160 function groups_delete_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) { 2031 if ( !empty( $user_id ) && !empty( $group_id ) ) 2032 $membership = new BP_Groups_Member( $user_id, $group_id ); 2033 else 2034 $membership = new BP_Groups_Member( false, false, $membership_id ); 2161 if ( ! empty( $membership_id ) ){ 2162 _deprecated_argument( __METHOD__, '5.0.0', sprintf( __( 'Argument `membership_id` passed to %1$s is deprecated. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) ); 2163 } 2035 2164 2036 if ( ! BP_Groups_Member::delete_request( $membership->user_id, $membership->group_id ) )2165 if ( empty( $user_id ) || empty( $group_id ) ) { 2037 2166 return false; 2167 } 2168 2169 $invites_class = new BP_Groups_Invitations(); 2170 $success = $invites_class->delete_requests( array( 2171 'user_id' => $user_id, 2172 'item_id' => $group_id 2173 ) ); 2038 2174 2039 return $membership; 2175 return $success; 2176 } 2177 2178 /** 2179 * Get group membership requests filtered by arguments. 2180 * 2181 * @since 5.0.0 2182 * 2183 * @param int $group_id ID of the group. 2184 * @param array $args Invitation arguments. 2185 * See BP_Invitations_Invitation::get() for list. 2186 * 2187 * @return array $requests Matching BP_Invitations_Invitation objects. 2188 */ 2189 function groups_get_requests( $args = array() ) { 2190 $invites_class = new BP_Groups_Invitations(); 2191 return $invites_class->get_requests( $args ); 2040 2192 } 2041 2193 2042 2194 /** … … function groups_delete_membership_request( $membership_id, $user_id = 0, $group_ 2046 2198 * 2047 2199 * @param int $user_id ID of the user. 2048 2200 * @param int $group_id ID of the group. 2049 * @return int|bool ID of the membershipif found, otherwise false.2201 * @return int|bool ID of the request if found, otherwise false. 2050 2202 */ 2051 2203 function groups_check_for_membership_request( $user_id, $group_id ) { 2052 $request = false; 2204 if ( empty( $user_id ) || empty( $group_id ) ) { 2205 return false; 2206 } 2053 2207 2054 $user_groups = bp_get_user_groups( $user_id, array( 2055 'is_confirmed' => false, 2056 'is_banned' => false, 2057 'is_admin' => null, 2058 'is_mod' => null 2208 $args = array( 2209 'user_id' => $user_id, 2210 'item_id' => $group_id, 2211 ); 2212 $invites_class = new BP_Groups_Invitations(); 2213 2214 return $invites_class->request_exists( $args ); 2215 } 2216 2217 /** 2218 * Get an array of group IDs to which a user has requested membership. 2219 * 2220 * @since 5.0.0 2221 * 2222 * @param int $user_id The user ID. 2223 * 2224 * @return array Array of group IDs. 2225 */ 2226 function groups_get_membership_requested_group_ids( $user_id = 0 ) { 2227 if ( ! $user_id ) { 2228 $user_id = bp_loggedin_user_id(); 2229 } 2230 2231 $group_ids = groups_get_requests( array( 2232 'user_id' => $user_id, 2233 'fields' => 'item_ids' 2059 2234 ) ); 2060 2235 2061 if ( isset( $user_groups[ $group_id ] ) && 0 === $user_groups[ $group_id ]->inviter_id ) { 2062 $request = $user_groups[ $group_id ]->id; 2063 } 2236 return $group_ids; 2237 } 2238 2239 /** 2240 * Get an array of group IDs to which a user has requested membership. 2241 * 2242 * @since 5.0.0 2243 * 2244 * @param int $user_id The user ID. 2245 * 2246 * @return array Array of group IDs. 2247 */ 2248 function groups_get_membership_requested_user_ids( $group_id = 0 ) { 2249 if ( ! $group_id ) { 2250 $group_id = bp_get_current_group_id(); 2251 } 2252 2253 $requests = groups_get_requests( array( 2254 'item_id' => $group_id, 2255 'fields' => 'user_ids' 2256 ) ); 2064 2257 2065 return $request; 2258 //@TODO-6210: What about those who make a request by email only (not yet site members)? 2259 return $requests; 2066 2260 } 2067 2261 2068 2262 /** … … function groups_check_for_membership_request( $user_id, $group_id ) { 2073 2267 * @param int $group_id ID of the group. 2074 2268 * @return bool True on success, false on failure. 2075 2269 */ 2076 function groups_accept_all_pending_membership_requests( $group_id ) { 2077 $user_ids = BP_Groups_Member::get_all_membership_request_user_ids( $group_id ); 2270 function groups_accept_all_pending_membership_requests( $group_id = 0 ) { 2271 if ( ! $group_id ) { 2272 $group_id = bp_get_current_group_id(); 2273 } 2078 2274 2079 if ( !$user_ids ) 2275 $user_ids = groups_get_membership_requested_user_ids( $group_id ); 2276 2277 if ( ! $user_ids ) { 2080 2278 return false; 2279 } 2081 2280 2082 foreach ( (array) $user_ids as $user_id ) 2281 foreach ( (array) $user_ids as $user_id ) { 2083 2282 groups_accept_membership_request( false, $user_id, $group_id ); 2283 } 2084 2284 2085 2285 /** 2086 2286 * Fires after the acceptance of all pending membership requests to a group. … … function bp_groups_pending_requests_personal_data_exporter( $email_address, $pag 2756 2956 ); 2757 2957 } 2758 2958 2759 $requests = BP_Groups_Member::get_user_memberships( $user->ID,array(2760 ' type' => 'pending_request',2959 $requests = groups_get_requests( array( 2960 'user_id' => $user->ID, 2761 2961 'page' => $page, 2762 2962 'per_page' => $number, 2763 2963 ) ); 2764 2964 2765 2965 foreach ( $requests as $request ) { 2766 $group = groups_get_group( $request-> group_id );2966 $group = groups_get_group( $request->item_id ); 2767 2967 2768 2968 $item_data = array( 2769 2969 array( … … function bp_groups_pending_sent_invitations_personal_data_exporter( $email_addre 2822 3022 ); 2823 3023 } 2824 3024 2825 $invitations = BP_Groups_Member::get_user_memberships( $user->ID,array(2826 ' type' => 'pending_sent_invitation',2827 'page' => $page,2828 'per_page' => $number,3025 $invitations = groups_get_invites( array( 3026 'inviter_id' => $user->ID, 3027 'page' => $page, 3028 'per_page' => $number, 2829 3029 ) ); 2830 3030 2831 3031 foreach ( $invitations as $invitation ) { 2832 $group = groups_get_group( $invitation-> group_id );3032 $group = groups_get_group( $invitation->item_id ); 2833 3033 2834 3034 $item_data = array( 2835 3035 array( … … function bp_groups_pending_received_invitations_personal_data_exporter( $email_a 2892 3092 ); 2893 3093 } 2894 3094 2895 $invitations = BP_Groups_Member::get_user_memberships( $user->ID,array(2896 ' type' => 'pending_received_invitation',3095 $invitations = groups_get_invites( array( 3096 'user_id' => $user->ID, 2897 3097 'page' => $page, 2898 3098 'per_page' => $number, 2899 3099 ) ); 2900 3100 2901 3101 foreach ( $invitations as $invitation ) { 2902 $group = groups_get_group( $invitation-> group_id );3102 $group = groups_get_group( $invitation->item_id ); 2903 3103 2904 3104 $item_data = array( 2905 3105 array( -
src/bp-groups/bp-groups-notifications.php
diff --git src/bp-groups/bp-groups-notifications.php src/bp-groups/bp-groups-notifications.php index b94850fb5..481c70770 100644
function groups_notification_new_membership_request( $requesting_user_id = 0, $a 143 143 'notification_type' => 'groups-membership-request', 144 144 ); 145 145 146 $request_message = ''; 147 $requests = groups_get_requests( $args = array( 148 'user_id' => $requesting_user_id, 149 'item_id' => $group_id, 150 ) ); 151 if ( $requests ) { 152 $request_message = current( $requests )->content; 153 } 154 146 155 $group = groups_get_group( $group_id ); 147 156 $args = array( 148 157 'tokens' => array( … … function groups_notification_new_membership_request( $requesting_user_id = 0, $a 151 160 'group.name' => $group->name, 152 161 'group.id' => $group_id, 153 162 'group-requests.url' => esc_url( bp_get_group_permalink( $group ) . 'admin/membership-requests' ), 154 'membership.id' => $membership_id,155 163 'profile.url' => esc_url( bp_core_get_user_domain( $requesting_user_id ) ), 156 164 'requesting-user.id' => $requesting_user_id, 157 165 'requesting-user.name' => bp_core_get_user_displayname( $requesting_user_id ), 166 'request.message' => $request_message, 158 167 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ), 159 168 ), 160 169 ); … … add_action( 'groups_promoted_member', 'groups_notification_promoted_member', 10, 289 298 * 290 299 * @since 1.0.0 291 300 * 292 * @param BP_Groups_Group $group Group object.293 * @param BP_Groups_Member $member Member object.294 * @param int $inviter_user_id ID of the user who sent the invite.301 * @param BP_Groups_Group $group Group object. 302 * @param BP_Groups_Member|int $member Member object or invited_user_id. 303 * @param int $inviter_user_id ID of the user who sent the invite. 295 304 */ 296 305 function groups_notification_group_invites( &$group, &$member, $inviter_user_id ) { 297 306 298 // Bail if member has already been invited.299 if ( ! empty( $member->invite_sent ) ) {300 return;301 }302 303 307 // @todo $inviter_ud may be used for caching, test without it 304 308 $inviter_ud = bp_core_get_core_userdata( $inviter_user_id ); 305 $invited_user_id = $member->user_id; 309 310 if ( $member instanceof BP_Groups_Member ) { 311 $invited_user_id = $member->user_id; 312 } else if ( is_int( $member ) ) { 313 $invited_user_id = $member; 314 } 306 315 307 316 // Trigger a BuddyPress Notification. 308 317 if ( bp_is_active( 'notifications' ) ) { … … function groups_notification_group_invites( &$group, &$member, $inviter_user_id 326 335 'notification_type' => 'groups-invitation', 327 336 ); 328 337 338 $invite_message = ''; 339 $invitations = groups_get_invites( $args = array( 340 'user_id' => $invited_user_id, 341 'item_id' => $group->id, 342 'inviter_id' => $inviter_user_id, 343 ) ); 344 if ( $invitations ) { 345 $invite_message = current( $invitations )->content; 346 } 347 329 348 $args = array( 330 349 'tokens' => array( 331 'group' => $group, 332 'group.url' => bp_get_group_permalink( $group ), 333 'group.name' => $group->name, 334 'inviter.name' => bp_core_get_userlink( $inviter_user_id, true, false, true ), 335 'inviter.url' => bp_core_get_user_domain( $inviter_user_id ), 336 'inviter.id' => $inviter_user_id, 337 'invites.url' => esc_url( $invited_link . '/invites/' ), 338 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ), 350 'group' => $group, 351 'group.url' => bp_get_group_permalink( $group ), 352 'group.name' => $group->name, 353 'inviter.name' => bp_core_get_userlink( $inviter_user_id, true, false, true ), 354 'inviter.url' => bp_core_get_user_domain( $inviter_user_id ), 355 'inviter.id' => $inviter_user_id, 356 'invites.url' => esc_url( $invited_link . '/invites/' ), 357 'invite.message' => $invite_message, 358 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ), 339 359 ), 340 360 ); 361 341 362 bp_send_email( 'groups-invitation', (int) $invited_user_id, $args ); 342 363 } 343 364 -
src/bp-groups/bp-groups-template.php
diff --git src/bp-groups/bp-groups-template.php src/bp-groups/bp-groups-template.php index c5c5a0465..710830c33 100644
function bp_group_request_reject_link() { 5437 5437 * 5438 5438 * @param string $value URL to use to reject a membership request. 5439 5439 */ 5440 return apply_filters( 'bp_get_group_request_reject_link', wp_nonce_url( trailingslashit( bp_get_group_permalink( groups_get_current_group() ) . 'admin/membership-requests/reject/' . $requests_template->request-> membership_id ), 'groups_reject_membership_request' ) );5440 return apply_filters( 'bp_get_group_request_reject_link', wp_nonce_url( trailingslashit( bp_get_group_permalink( groups_get_current_group() ) . 'admin/membership-requests/reject/' . $requests_template->request->user_id ), 'groups_reject_membership_request' ) ); 5441 5441 } 5442 5442 5443 5443 /** … … function bp_group_request_accept_link() { 5461 5461 * 5462 5462 * @param string $value URL to use to accept a membership request. 5463 5463 */ 5464 return apply_filters( 'bp_get_group_request_accept_link', wp_nonce_url( trailingslashit( bp_get_group_permalink( groups_get_current_group() ) . 'admin/membership-requests/accept/' . $requests_template->request-> membership_id ), 'groups_accept_membership_request' ) );5464 return apply_filters( 'bp_get_group_request_accept_link', wp_nonce_url( trailingslashit( bp_get_group_permalink( groups_get_current_group() ) . 'admin/membership-requests/accept/' . $requests_template->request->user_id ), 'groups_accept_membership_request' ) ); 5465 5465 } 5466 5466 5467 5467 /** -
src/bp-groups/classes/class-bp-group-member-query.php
diff --git src/bp-groups/classes/class-bp-group-member-query.php src/bp-groups/classes/class-bp-group-member-query.php index d872810e3..859075921 100644
class BP_Group_Member_Query extends BP_User_Query { 231 231 $sql['orderby'] = "ORDER BY date_modified"; 232 232 $sql['order'] = 'first_joined' === $this->query_vars['type'] ? 'ASC' : 'DESC'; 233 233 234 $this->group_member_ids = $wpdb->get_col( "{$sql['select']} {$sql['where']} {$sql['orderby']} {$sql['order']}" ); 234 $group_member_ids = $wpdb->get_col( "{$sql['select']} {$sql['where']} {$sql['orderby']} {$sql['order']}" ); 235 236 $invited_member_ids = array(); 237 238 // If appropriate, fetch invitations and add them to the results. 239 if ( ! $is_confirmed || ! is_null( $this->query_vars['invite_sent'] ) || ! is_null( $this->query_vars['inviter_id'] ) ) { 240 $invite_args = array( 241 'item_id' => $this->query_vars['group_id'], 242 'fields' => 'user_ids', 243 'type' => 'all', 244 ); 245 246 if ( ! is_null( $this->query_vars['invite_sent'] ) ) { 247 $invite_args['invite_sent'] = ! empty( $this->query_vars['invite_sent'] ) ? 'sent' : 'draft'; 248 } 249 250 // If inviter_id. 251 if ( ! is_null( $this->query_vars['inviter_id'] ) ) { 252 $inviter_id = $this->query_vars['inviter_id']; 253 254 // Empty: inviter_id = 0. (pass false, 0, or empty array). 255 if ( empty( $inviter_id ) ) { 256 $invite_args['type'] = 'request'; 257 258 /* 259 * The string 'any' matches any non-zero value (inviter_id != 0). 260 * These are invitations, not requests. 261 */ 262 } elseif ( 'any' === $inviter_id ) { 263 $invite_args['type'] = 'invite'; 264 265 // Assume that a list of inviter IDs has been passed. 266 } else { 267 $invite_args['type'] = 'invite'; 268 // Parse and sanitize. 269 $inviter_ids = wp_parse_id_list( $inviter_id ); 270 if ( ! empty( $inviter_ids ) ) { 271 $invite_args['inviter_id'] = $inviter_ids; 272 } 273 } 274 } 275 276 /* 277 * If first_joined is the "type" of query, sort the oldest 278 * requests and invitations to the top. 279 */ 280 if ( 'first_joined' === $this->query_vars['type'] ) { 281 $invite_args['order_by'] = 'date_modified'; 282 $invite_args['sort_order'] = 'ASC'; 283 } 284 285 $invited_member_ids = groups_get_invites( $invite_args ); 286 } 287 288 $this->group_member_ids = array_merge( $group_member_ids, $invited_member_ids ); 235 289 236 290 /** 237 291 * Filters the member IDs for the current group member query. … … class BP_Group_Member_Query extends BP_User_Query { 330 384 } 331 385 } 332 386 387 // Add accurate invitation info from the invitations table. 388 $invites = groups_get_invites( array( 389 'user_id' => $user_ids_sql, 390 'item_id' => $this->query_vars['group_id'], 391 'type' => 'all', 392 ) ); 393 foreach ( $invites as $invite ) { 394 if ( isset( $this->results[ $invite->user_id ] ) ) { 395 $this->results[ $invite->user_id ]->comments = $invite->content; 396 $this->results[ $invite->user_id ]->is_confirmed = 0; 397 $this->results[ $invite->user_id ]->invitation_id = $invite->id; 398 $this->results[ $invite->user_id ]->invite_sent = (int) $invite->invite_sent; 399 $this->results[ $invite->user_id ]->inviter_id = $invite->inviter_id; 400 401 // Backfill properties that are not being set above. 402 if ( ! isset( $this->results[ $invite->user_id ]->user_id ) ) { 403 $this->results[ $invite->user_id ]->user_id = $invite->user_id; 404 } 405 if ( ! isset( $this->results[ $invite->user_id ]->is_admin ) ) { 406 $this->results[ $invite->user_id ]->is_admin = 0; 407 } 408 if ( ! isset( $this->results[ $invite->user_id ]->is_mod ) ) { 409 $this->results[ $invite->user_id ]->is_mod = 0; 410 } 411 if ( ! isset( $this->results[ $invite->user_id ]->is_banned ) ) { 412 $this->results[ $invite->user_id ]->is_banned = 0; 413 } 414 if ( ! isset( $this->results[ $invite->user_id ]->date_modified ) ) { 415 $this->results[ $invite->user_id ]->date_modified = $invite->date_modified; 416 } 417 if ( ! isset( $this->results[ $invite->user_id ]->user_title ) ) { 418 $this->results[ $invite->user_id ]->user_title = ''; 419 } 420 if ( ! isset( $this->results[ $invite->user_id ]->membership_id ) ) { 421 $this->results[ $invite->user_id ]->membership_id = 0; 422 } 423 } 424 } 425 333 426 // Don't filter other BP_User_Query objects on the same page. 334 427 remove_action( 'bp_user_query_populate_extras', array( $this, 'populate_group_member_extras' ), 10 ); 335 428 } -
src/bp-groups/classes/class-bp-groups-group.php
diff --git src/bp-groups/classes/class-bp-groups-group.php src/bp-groups/classes/class-bp-groups-group.php index 5c40c011b..218bd9b83 100644
class BP_Groups_Group { 771 771 * yet accepted. 772 772 */ 773 773 public static function get_invites( $user_id, $group_id, $sent = null ) { 774 global $wpdb; 775 776 $bp = buddypress(); 777 $sql = $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE group_id = %d and is_confirmed = 0 AND inviter_id = %d", $group_id, $user_id ); 778 779 // Query for a specific invite sent status. 780 if ( ! is_null( $sent ) ) { 781 $sql .= $wpdb->prepare( ' AND invite_sent = %d', $sent ); 774 if ( 0 === $sent ) { 775 $sent_arg = 'draft'; 776 } else if ( 1 === $sent ) { 777 $sent_arg = 'sent'; 778 } else { 779 $sent_arg = 'all'; 782 780 } 783 781 784 return $wpdb->get_col( $sql ); 782 return groups_get_invites( array( 783 'item_id' => $group_id, 784 'inviter_id' => $user_id, 785 'invite_sent' => $sent_arg, 786 'fields' => 'user_ids', 787 ) ); 785 788 } 786 789 787 790 /** … … class BP_Groups_Group { 959 962 * } 960 963 */ 961 964 public static function get_membership_requests( $group_id, $limit = null, $page = null ) { 962 global $wpdb; 963 964 if ( !empty( $limit ) && !empty( $page ) ) { 965 $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) ); 965 $args = array( 966 'item_id' => $group_id 967 ); 968 if ( $limit ) { 969 $args['per_page'] = $limit; 966 970 } 971 if ( $page ) { 972 $args['page'] = $page; 973 } 967 974 968 $bp = buddypress(); 969 970 $paged_requests = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 0 AND inviter_id = 0{$pag_sql}", $group_id ) ); 971 $total_requests = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 0 AND inviter_id = 0", $group_id ) ); 975 $requests = groups_get_requests( $args ); 976 $total = count( groups_get_membership_requested_user_ids( $group_id ) ); 972 977 973 return array( 'requests' => $ paged_requests, 'total' => $total_requests);978 return array( 'requests' => $requests, 'total' => $total ); 974 979 } 975 980 976 981 /** … … class BP_Groups_Group { 1635 1640 * failure. 1636 1641 */ 1637 1642 public static function delete_all_invites( $group_id ) { 1638 global $wpdb; 1643 if ( empty( $group_id ) ) { 1644 return false; 1645 } 1639 1646 1640 $ bp = buddypress();1647 $invites_class = new BP_Groups_Invitations(); 1641 1648 1642 return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE group_id = %d AND invite_sent = 1", $group_id ) ); 1649 return $invites_class->delete( array( 1650 'item_id' => $group_id, 1651 ) ); 1643 1652 } 1644 1653 1645 1654 /** -
new file src/bp-groups/classes/class-bp-groups-invitations.php
diff --git src/bp-groups/classes/class-bp-groups-invitations.php src/bp-groups/classes/class-bp-groups-invitations.php new file mode 100644 index 000000000..235feb2d3
- + 1 <?php 2 /** 3 * Group invitations class. 4 * 5 * @package BuddyPress 6 * @subpackage Core 7 * @since 5.0.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * Group invitations class. 15 * 16 * An extension of the core Invitations class that adapts the 17 * core logic to accommodate group invitation behavior. 18 * 19 * @since 5.0.0 20 */ 21 class BP_Groups_Invitations extends BP_Invitations { 22 /** 23 * The name of the related component. 24 * 25 * @since 5.0.0 26 * @access public 27 * @var string 28 */ 29 protected $component_name; 30 31 /** 32 * Construct parameters. 33 * 34 * @since 3.1.0 35 * 36 * @param array|string $args { 37 38 * } 39 */ 40 public function __construct( $args = '' ) { 41 $this->component_name = buddypress()->groups->id; 42 parent::__construct( array( 43 'component_name' => $this->component_name, 44 ) ); 45 } 46 47 /** 48 * This is where custom actions are added to run when notifications of an 49 * invitation or request need to be generated & sent. 50 * 51 * @since 2.7.0 52 * 53 * @param int $id The ID of the invitation to mark as sent. 54 * @return bool True on success, false on failure. 55 */ 56 public function run_send_action( BP_Invitations_Invitation $invitation ) { 57 // Notify group admins of the pending request 58 if ( 'request' === $invitation->type ) { 59 $admins = groups_get_group_admins( $invitation->item_id ); 60 61 foreach ( $admins as $admin ) { 62 groups_notification_new_membership_request( $invitation->user_id, $admin->user_id, $invitation->item_id, $invitation->id ); 63 } 64 return true; 65 66 // Notify the invitee of the invitation. 67 } else { 68 $group = groups_get_group( $invitation->item_id ); 69 groups_notification_group_invites( $group, $invitation->user_id, $invitation->inviter_id ); 70 return true; 71 } 72 } 73 74 /** 75 * This is where custom actions are added to run when an invitation 76 * or request is accepted. 77 * 78 * @since 2.7.0 79 * 80 * @param int $id The ID of the invitation to mark as sent. 81 * @return bool True on success, false on failure. 82 */ 83 public function run_acceptance_action( $type = 'invite', $r ) { 84 // If the user is already a member (because BP at one point allowed two invitations to 85 // slip through), return early. 86 if ( groups_is_user_member( $r['user_id'], $r['item_id'] ) ) { 87 return true; 88 } 89 90 // Create the new membership 91 $member = new BP_Groups_Member( $r['user_id'], $r['item_id'] ); 92 93 if ( 'request' === $type ) { 94 $member->accept_request(); 95 } else { 96 $member->accept_invite(); 97 } 98 99 if ( ! $member->save() ) { 100 return false; 101 } 102 103 // Modify group meta. 104 groups_update_groupmeta( $r['item_id'], 'last_activity', bp_core_current_time() ); 105 106 return true; 107 } 108 109 /** 110 * With group invitations, we don't need to keep the old record, so we delete rather than 111 * mark invitations as "accepted." 112 * 113 * @since 2.7.0 114 * 115 * @see BP_Invitations_Invitation::mark_accepted_by_data() 116 * for a description of arguments. 117 */ 118 public function mark_accepted( $args ) { 119 // Delete all existing invitations/requests to this group for this user. 120 $this->delete( array( 121 'user_id' => $args['user_id'], 122 'item_id' => $args['item_id'], 123 'type' => 'all' 124 ) ); 125 } 126 127 /** 128 * Should this invitation be created? 129 * 130 * @since 5.0.0 131 */ 132 public function allow_invitation( $args ) { 133 // Does the inviter have this capability? 134 if ( ! bp_user_can( $args['inviter_id'], 'groups_send_invitation', array( 'group_id' => $args['item_id'] ) ) ) { 135 return false; 136 } 137 138 // Is the invited user eligible to receive an invitation? 139 if ( ! bp_user_can( $args['user_id'], 'groups_receive_invitation', array( 'group_id' => $args['item_id'] ) ) ) { 140 return false; 141 } 142 143 // Prevent duplicated invitations. 144 if ( groups_check_has_invite_from_user( $args['user_id'], $args['item_id'], $args['inviter_id'], 'all' ) ) { 145 return false; 146 } 147 148 return true; 149 } 150 151 /** 152 * Should this request be created? 153 * 154 * @since 5.0.0 155 */ 156 public function allow_request( $args ) { 157 // Does the requester have this capability? (Also checks for duplicates.) 158 if ( ! bp_user_can( $args['user_id'], 'groups_request_membership', array( 'group_id' => $args['item_id'] ) ) ) { 159 return false; 160 } 161 162 return true; 163 } 164 } -
src/bp-groups/classes/class-bp-groups-member.php
diff --git src/bp-groups/classes/class-bp-groups-member.php src/bp-groups/classes/class-bp-groups-member.php index 66f833022..dc54b9466 100644
class BP_Groups_Member { 767 767 } 768 768 769 769 /** 770 * Get a user's outstanding group invitations.770 * Get group objects for groups that a user is currently invited to. 771 771 * 772 772 * @since 1.6.0 773 773 * … … class BP_Groups_Member { 784 784 * } 785 785 */ 786 786 public static function get_invites( $user_id, $limit = false, $page = false, $exclude = false ) { 787 global $wpdb; 788 789 $pag_sql = ( !empty( $limit ) && !empty( $page ) ) ? $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) ) : ''; 790 791 if ( !empty( $exclude ) ) { 792 $exclude = implode( ',', wp_parse_id_list( $exclude ) ); 793 $exclude_sql = " AND g.id NOT IN ({$exclude})"; 794 } else { 795 $exclude_sql = ''; 796 } 797 798 $bp = buddypress(); 799 800 $paged_groups = $wpdb->get_results( $wpdb->prepare( "SELECT g.*, gm1.meta_value as total_member_count, gm2.meta_value as last_activity FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2, {$bp->groups->table_name_members} m, {$bp->groups->table_name} g WHERE g.id = m.group_id AND g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count' AND m.is_confirmed = 0 AND m.inviter_id != 0 AND m.invite_sent = 1 AND m.user_id = %d {$exclude_sql} ORDER BY m.date_modified ASC {$pag_sql}", $user_id ) ); 801 802 return array( 'groups' => $paged_groups, 'total' => self::get_invite_count_for_user( $user_id ) ); 787 return groups_get_invites_for_user( $user_id, $limit, $page, $exclude ); 803 788 } 804 789 805 790 /** … … class BP_Groups_Member { 811 796 * @return int 812 797 */ 813 798 public static function get_invite_count_for_user( $user_id = 0 ) { 814 global $wpdb; 815 816 $bp = buddypress(); 817 818 $count = wp_cache_get( $user_id, 'bp_group_invite_count' ); 819 820 if ( false === $count ) { 821 $count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT m.group_id) FROM {$bp->groups->table_name_members} m, {$bp->groups->table_name} g WHERE m.group_id = g.id AND m.is_confirmed = 0 AND m.inviter_id != 0 AND m.invite_sent = 1 AND m.user_id = %d", $user_id ) ); 822 wp_cache_set( $user_id, $count, 'bp_group_invite_count' ); 823 } 824 825 return $count; 799 return groups_get_invite_count_for_user( $user_id ); 826 800 } 827 801 828 802 /** … … class BP_Groups_Member { 859 833 'where' => '', 860 834 'limits' => '', 861 835 ); 862 836 //@TODO 6210. 863 837 switch ( $r['type'] ) { 864 case 'pending_request' :865 $sql['where'] = $wpdb->prepare( "user_id = %d AND is_confirmed = 0 AND inviter_id = 0", $user_id );866 break;867 868 case 'pending_received_invitation' :869 $sql['where'] = $wpdb->prepare( "user_id = %d AND is_confirmed = 0 AND inviter_id != 0", $user_id );870 break;871 872 case 'pending_sent_invitation' :873 $sql['where'] = $wpdb->prepare( "inviter_id = %d AND is_confirmed = 0", $user_id );874 break;875 876 838 case 'membership' : 877 839 default : 878 840 $sql['where'] = $wpdb->prepare( "user_id = %d AND is_confirmed = 1", $user_id ); … … class BP_Groups_Member { 912 874 * @return int|null The ID of the invitation if found; null if not found. 913 875 */ 914 876 public static function check_has_invite( $user_id, $group_id, $type = 'sent' ) { 915 global $wpdb; 916 917 if ( empty( $user_id ) ) 918 return false; 919 920 $bp = buddypress(); 921 $sql = "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_confirmed = 0 AND inviter_id != 0"; 922 923 if ( 'sent' == $type ) 924 $sql .= " AND invite_sent = 1"; 925 926 $query = $wpdb->get_var( $wpdb->prepare( $sql, $user_id, $group_id ) ); 927 928 return is_numeric( $query ) ? (int) $query : $query; 877 return groups_is_user_invited( $user_id, $group_id, $type ); 929 878 } 930 879 931 880 /** … … class BP_Groups_Member { 937 886 * 938 887 * @param int $user_id ID of the user. 939 888 * @param int $group_id ID of the group. 889 * @param int $inviter_id ID of the inviter. Specify if you want to delete 890 * a specific invite. Leave false if you want to 891 * delete all invites to this group. 940 892 * @return int Number of records deleted. 941 893 */ 942 public static function delete_invite( $user_id, $group_id ) { 943 global $wpdb; 944 945 if ( empty( $user_id ) ) { 946 return false; 947 } 948 894 public static function delete_invite( $user_id, $group_id, $inviter_id = false ) { 949 895 /** 950 896 * Fires before a group invitation is deleted. 951 897 * 952 898 * @since 2.6.0 899 * @since 5.0.0 Added $inviter_id 953 900 * 954 901 * @param int $user_id ID of the user. 955 902 * @param int $group_id ID of the group. 903 * @param int $inviter_id ID of the inviter. 956 904 */ 957 do_action( 'bp_groups_member_before_delete_invite', $user_id, $group_id ); 958 959 $table_name = buddypress()->groups->table_name_members; 960 961 $sql = "DELETE FROM {$table_name} 962 WHERE user_id = %d 963 AND group_id = %d 964 AND is_confirmed = 0 965 AND inviter_id != 0"; 966 967 $prepared = $wpdb->prepare( $sql, $user_id, $group_id ); 905 do_action( 'bp_groups_member_before_delete_invite', $user_id, $group_id, $inviter_id ); 968 906 969 return $wpdb->query( $prepared );907 return groups_delete_invite( $user_id, $group_id, $inviter_id ); 970 908 } 971 909 972 910 /** … … class BP_Groups_Member { 979 917 * @return int Number of records deleted. 980 918 */ 981 919 public static function delete_request( $user_id, $group_id ) { 982 global $wpdb; 983 984 if ( empty( $user_id ) ) 985 return false; 986 987 $bp = buddypress(); 988 989 return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_confirmed = 0 AND inviter_id = 0 AND invite_sent = 0", $user_id, $group_id ) ); 920 return groups_delete_membership_request( false, $user_id, $group_id ); 990 921 } 991 922 992 923 /** … … class BP_Groups_Member { 1104 1035 * @return int Database ID of the membership if found; int 0 on failure. 1105 1036 */ 1106 1037 public static function check_for_membership_request( $user_id, $group_id ) { 1107 global $wpdb; 1108 1109 if ( empty( $user_id ) ) 1110 return false; 1111 1112 $bp = buddypress(); 1113 1114 return $wpdb->query( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d AND is_confirmed = 0 AND is_banned = 0 AND inviter_id = 0", $user_id, $group_id ) ); 1038 return groups_is_user_pending( $user_id, $group_id ); 1115 1039 } 1116 1040 1117 1041 /** … … class BP_Groups_Member { 1292 1216 * @return array IDs of users with outstanding membership requests. 1293 1217 */ 1294 1218 public static function get_all_membership_request_user_ids( $group_id ) { 1295 global $wpdb; 1296 1297 $bp = buddypress(); 1298 1299 return array_map( 'intval', $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 0 AND inviter_id = 0", $group_id ) ) ); 1219 return groups_get_membership_requested_user_ids( $group_id ); 1300 1220 } 1301 1221 1302 1222 /** -
src/bp-groups/screens/single/admin/membership-requests.php
diff --git src/bp-groups/screens/single/admin/membership-requests.php src/bp-groups/screens/single/admin/membership-requests.php index ca12c2cc0..cace86eb0 100644
function groups_screen_group_admin_requests() { 24 24 } 25 25 26 26 $request_action = (string) bp_action_variable( 1 ); 27 $membership_id = (int) bp_action_variable( 2 ); 27 $user_id = (int) bp_action_variable( 2 ); 28 $group_id = bp_get_current_group_id(); 28 29 29 if ( ! empty( $request_action ) && !empty( $membership_id) ) {30 if ( 'accept' == $request_action && is_numeric( $ membership_id) ) {30 if ( ! empty( $request_action ) && ! empty( $user ) ) { 31 if ( 'accept' == $request_action && is_numeric( $user_id) ) { 31 32 32 33 // Check the nonce first. 33 if ( ! check_admin_referer( 'groups_accept_membership_request' ) )34 if ( ! check_admin_referer( 'groups_accept_membership_request' ) ) { 34 35 return false; 36 } 35 37 36 38 // Accept the membership request. 37 if ( ! groups_accept_membership_request( $membership_id ) )39 if ( ! groups_accept_membership_request( false, $user_id, $group_id ) ) { 38 40 bp_core_add_message( __( 'There was an error accepting the membership request. Please try again.', 'buddypress' ), 'error' ); 39 else41 } else { 40 42 bp_core_add_message( __( 'Group membership request accepted', 'buddypress' ) ); 43 } 41 44 42 } elseif ( 'reject' == $request_action && is_numeric( $ membership_id ) ) {45 } elseif ( 'reject' == $request_action && is_numeric( $user_id ) ) { 43 46 /* Check the nonce first. */ 44 if ( ! check_admin_referer( 'groups_reject_membership_request' ) )47 if ( ! check_admin_referer( 'groups_reject_membership_request' ) ) { 45 48 return false; 49 } 46 50 47 51 // Reject the membership request. 48 if ( ! groups_reject_membership_request( $membership_id ) )52 if ( ! groups_reject_membership_request( false, $user_id, $group_id ) ) { 49 53 bp_core_add_message( __( 'There was an error rejecting the membership request. Please try again.', 'buddypress' ), 'error' ); 50 else54 } else { 51 55 bp_core_add_message( __( 'Group membership request rejected', 'buddypress' ) ); 56 } 52 57 } 53 58 59 // Was the member added to the group? 60 $membership_id = groups_is_user_member( $user_id, $group_id ); 61 54 62 /** 55 63 * Fires before the redirect if a group membership request has been handled. 56 64 * … … function groups_screen_group_admin_requests() { 58 66 * 59 67 * @param int $id ID of the group that was edited. 60 68 * @param string $request_action Membership request action being performed. 61 * @param int $membership_id The key of the action_variables array that you want. 69 * @param int $membership_id The membership ID of the new user; false if rejected. 70 * @param int $user_id The ID of the requesting user. 71 * @param int $group_id The ID of the requested group. 62 72 */ 63 do_action( 'groups_group_request_managed', $bp->groups->current_group->id, $request_action, $membership_id );73 do_action( 'groups_group_request_managed', $bp->groups->current_group->id, $request_action, $membership_id, $user_id, $group_id ); 64 74 bp_core_redirect( bp_get_group_permalink( groups_get_current_group() ) . 'admin/membership-requests/' ); 65 75 } 66 76 … … function groups_screen_group_admin_requests() { 82 92 */ 83 93 bp_core_load_template( apply_filters( 'groups_template_group_admin_requests', 'groups/single/home' ) ); 84 94 } 85 add_action( 'bp_screens', 'groups_screen_group_admin_requests' ); 86 No newline at end of file 95 add_action( 'bp_screens', 'groups_screen_group_admin_requests' ); -
src/class-buddypress.php
diff --git src/class-buddypress.php src/class-buddypress.php index 21bfd2224..0cfbaff4d 100644
class BuddyPress { 487 487 require( $this->plugin_dir . 'bp-core/bp-core-moderation.php' ); 488 488 require( $this->plugin_dir . 'bp-core/bp-core-loader.php' ); 489 489 require( $this->plugin_dir . 'bp-core/bp-core-customizer-email.php' ); 490 require( $this->plugin_dir . 'bp-core/bp-core-invitations-cache.php' ); 490 491 491 492 // Maybe load deprecated functionality (this double negative is proof positive!) 492 493 if ( ! bp_get_option( '_bp_ignore_deprecated_code', ! $this->load_deprecated ) ) { … … class BuddyPress { 568 569 'BP_Walker_Category_Checklist' => 'core', 569 570 'BP_Walker_Nav_Menu_Checklist' => 'core', 570 571 'BP_Walker_Nav_Menu' => 'core', 572 'BP_Invitations' => 'core', 573 'BP_Invitations_Invitation' => 'core', 571 574 572 575 'BP_Core_Friends_Widget' => 'friends', 573 576 -
new file tests/phpunit/testcases/core/invitations.php
diff --git tests/phpunit/testcases/core/invitations.php tests/phpunit/testcases/core/invitations.php new file mode 100644 index 000000000..d41d32856
- + 1 <?php 2 /** 3 * @group core 4 * @group invitations 5 */ 6 class BP_Tests_Invitations extends BP_UnitTestCase { 7 public function test_bp_invitations_add_invitation_vanilla() { 8 $old_current_user = get_current_user_id(); 9 10 $u1 = $this->factory->user->create(); 11 $u2 = $this->factory->user->create(); 12 $u3 = $this->factory->user->create(); 13 $this->set_current_user( $u1 ); 14 15 $invites_class = new BP_Invitations( array( 'component_name' => 'cakes' ) ); 16 17 // Create a couple of invitations. 18 $invite_args = array( 19 'user_id' => $u3, 20 'inviter_id' => $u1, 21 'component_action' => 'cupcakes', 22 'item_id' => 1, 23 'send_invite' => 'sent', 24 ); 25 $i1 = $invites_class->add_invitation( $invite_args ); 26 $invite_args['inviter_id'] = $u2; 27 $i2 = $invites_class->add_invitation( $invite_args ); 28 29 $get_invites = array( 30 'user_id' => $u3, 31 'fields' => 'ids', 32 ); 33 $invites = $invites_class->get_invitations( $get_invites ); 34 $this->assertEqualSets( array( $i1, $i2 ), $invites ); 35 36 $this->set_current_user( $old_current_user ); 37 } 38 39 public function test_bp_invitations_add_invitation_avoid_duplicates() { 40 $old_current_user = get_current_user_id(); 41 42 $u1 = $this->factory->user->create(); 43 $u2 = $this->factory->user->create(); 44 $this->set_current_user( $u1 ); 45 46 $invites_class = new BP_Invitations( array( 'component_name' => 'blogs' ) ); 47 48 // Create an invitation. 49 $invite_args = array( 50 'user_id' => $u2, 51 'inviter_id' => $u1, 52 'component_action' => 'blog_invite', 53 'item_id' => 1, 54 'send_invite' => 'sent', 55 ); 56 $i1 = $invites_class->add_invitation( $invite_args ); 57 // Attempt to create a duplicate. 58 $this->assertFalse( $invites_class->add_invitation( $invite_args ) ); 59 60 $this->set_current_user( $old_current_user ); 61 } 62 63 public function test_bp_invitations_add_invitation_invite_plus_request_should_accept() { 64 $old_current_user = get_current_user_id(); 65 66 $u1 = $this->factory->user->create(); 67 $u2 = $this->factory->user->create(); 68 $u3 = $this->factory->user->create(); 69 $this->set_current_user( $u1 ); 70 71 $invites_class = new BP_Invitations( array( 'component_name' => 'cakes' ) ); 72 73 // Create an invitation. 74 $invite_args = array( 75 'user_id' => $u3, 76 'inviter_id' => $u1, 77 'component_action' => 'cupcakes', 78 'item_id' => 1, 79 'send_invite' => 'sent', 80 ); 81 $i1 = $invites_class->add_invitation( $invite_args ); 82 83 // Create a request. 84 $request_args = array( 85 'user_id' => $u3, 86 'component_action' => 'cupcakes', 87 'item_id' => 1, 88 ); 89 $r1 = $invites_class->add_request( $request_args ); 90 91 $get_invites = array( 92 'user_id' => $u3, 93 'component_action' => 'cupcakes', 94 'accepted' => 'accepted' 95 ); 96 $invites = $invites_class->get_invitations( $get_invites ); 97 $this->assertEqualSets( array( $i1 ), wp_list_pluck( $invites, 'id' ) ); 98 99 $this->set_current_user( $old_current_user ); 100 } 101 102 public function test_bp_invitations_add_invitation_unsent_invite_plus_request_should_not_accept() { 103 $old_current_user = get_current_user_id(); 104 105 $u1 = $this->factory->user->create(); 106 $u2 = $this->factory->user->create(); 107 $u3 = $this->factory->user->create(); 108 $this->set_current_user( $u1 ); 109 110 $invites_class = new BP_Invitations( array( 'component_name' => 'cakes' ) ); 111 112 // Create an invitation. 113 $invite_args = array( 114 'user_id' => $u3, 115 'inviter_id' => $u1, 116 'component_action' => 'cupcakes', 117 'item_id' => 1, 118 'send_invite' => 0, 119 ); 120 $i1 = $invites_class->add_invitation( $invite_args ); 121 122 // Create a request. 123 $request_args = array( 124 'user_id' => $u3, 125 'component_action' => 'cupcakes', 126 'item_id' => 1, 127 ); 128 $r1 = $invites_class->add_request( $request_args ); 129 130 $get_invites = array( 131 'user_id' => $u3, 132 'component_action' => 'cupcakes', 133 'accepted' => 'accepted' 134 ); 135 $invites = $invites_class->get_invitations( $get_invites ); 136 $this->assertEqualSets( array(), wp_list_pluck( $invites, 'id' ) ); 137 138 $this->set_current_user( $old_current_user ); 139 } 140 141 public function test_bp_invitations_add_invitation_unsent_invite_plus_request_then_send_invite_should_accept() { 142 $old_current_user = get_current_user_id(); 143 144 $u1 = $this->factory->user->create(); 145 $u2 = $this->factory->user->create(); 146 $u3 = $this->factory->user->create(); 147 $this->set_current_user( $u1 ); 148 149 $invites_class = new BP_Invitations( array( 'component_name' => 'cakes' ) ); 150 151 // Create an invitation. 152 $invite_args = array( 153 'user_id' => $u3, 154 'inviter_id' => $u1, 155 'component_action' => 'cupcakes', 156 'item_id' => 1, 157 'send_invite' => 0, 158 ); 159 $i1 = $invites_class->add_invitation( $invite_args ); 160 161 // Create a request. 162 $request_args = array( 163 'user_id' => $u3, 164 'component_action' => 'cupcakes', 165 'item_id' => 1, 166 ); 167 $r1 = $invites_class->add_request( $request_args ); 168 169 $invites_class->send_invitation_by_id( $i1 ); 170 171 // Check that both the request and invitation are marked 'accepted'. 172 $get_invites = array( 173 'user_id' => $u3, 174 'component_action' => 'cupcakes', 175 'type' => 'all', 176 'accepted' => 'accepted', 177 'fields' => 'ids' 178 ); 179 $invites = $invites_class->get_invitations( $get_invites ); 180 $this->assertEqualSets( array( $i1, $r1 ), $invites ); 181 182 $this->set_current_user( $old_current_user ); 183 } 184 185 public function test_bp_invitations_add_request_vanilla() { 186 $old_current_user = get_current_user_id(); 187 188 $u1 = $this->factory->user->create(); 189 $this->set_current_user( $u1 ); 190 191 $invites_class = new BP_Invitations( array( 'component_name' => 'cakes' ) ); 192 193 // Create a couple of requests. 194 $request_args = array( 195 'user_id' => $u1, 196 'component_action' => 'cupcakes', 197 'item_id' => 7, 198 ); 199 $r1 = $invites_class->add_request( $request_args ); 200 $request_args['item_id'] = 4; 201 $r2 = $invites_class->add_request( $request_args ); 202 203 $get_requests = array( 204 'user_id' => $u1, 205 'component_action' => 'cupcakes', 206 'fields' => 'ids' 207 ); 208 $requests = $invites_class->get_requests( $get_requests ); 209 $this->assertEqualSets( array( $r1, $r2 ), $requests ); 210 211 $this->set_current_user( $old_current_user ); 212 } 213 214 public function test_bp_invitations_add_request_avoid_duplicates() { 215 $old_current_user = get_current_user_id(); 216 217 $invites_class = new BP_Invitations( array( 'component_name' => 'cakes' ) ); 218 219 $u1 = $this->factory->user->create(); 220 $this->set_current_user( $u1 ); 221 222 // Create a couple of requests. 223 $request_args = array( 224 'user_id' => $u1, 225 'component_action' => 'cupcakes', 226 'item_id' => 7, 227 ); 228 $r1 = $invites_class->add_request( $request_args ); 229 // Attempt to create a duplicate. 230 $this->assertFalse( $invites_class->add_request( $request_args ) ); 231 232 $this->set_current_user( $old_current_user ); 233 } 234 235 public function test_bp_invitations_add_request_request_plus_sent_invite_should_accept() { 236 $old_current_user = get_current_user_id(); 237 238 $u1 = $this->factory->user->create(); 239 $u2 = $this->factory->user->create(); 240 $this->set_current_user( $u1 ); 241 242 $invites_class = new BP_Invitations( array( 'component_name' => 'cakes' ) ); 243 244 // Create a request. 245 $request_args = array( 246 'user_id' => $u2, 247 'component_action' => 'cupcakes', 248 'item_id' => 1, 249 ); 250 $r1 = $invites_class->add_request( $request_args ); 251 252 // Create an invitation. 253 $invite_args = array( 254 'user_id' => $u2, 255 'inviter_id' => $u1, 256 'component_action' => 'cupcakes', 257 'item_id' => 1, 258 'send_invite' => 1, 259 ); 260 $i1 = $invites_class->add_invitation( $invite_args ); 261 262 // Check that both the request and invitation are marked 'accepted'. 263 $get_invites = array( 264 'user_id' => $u2, 265 'type' => 'all', 266 'component_action' => 'cupcakes', 267 'accepted' => 'accepted', 268 'fields' => 'ids' 269 ); 270 $invites = $invites_class->get_invitations( $get_invites ); 271 $this->assertEqualSets( array( $r1, $i1 ), $invites ); 272 273 $this->set_current_user( $old_current_user ); 274 } 275 276 } -
tests/phpunit/testcases/groups/class-bp-groups-group.php
diff --git tests/phpunit/testcases/groups/class-bp-groups-group.php tests/phpunit/testcases/groups/class-bp-groups-group.php index a76d4e72c..f03a4c801 100644
class BP_Tests_BP_Groups_Group_TestCases extends BP_UnitTestCase { 1372 1372 */ 1373 1373 public function test_get_group_extras_invited() { 1374 1374 $u = self::factory()->user->create(); 1375 $g = self::factory()->group->create(); 1375 $u2 = self::factory()->user->create(); 1376 $g = self::factory()->group->create( array( 'creator_id' => $u2, 'status' => 'private' ) ); 1376 1377 1377 $invite = new BP_Groups_Member;1378 $invite->group_id = $g;1379 $invite->user_id = $u;1380 $invite->date_modified = bp_core_current_time();1381 $invite->invite_sent = true;1382 $invite->is_confirmed = false;1383 $invite->save();1378 // Outstanding invitations should be left intact. 1379 groups_invite_user( array( 1380 'user_id' => $u, 1381 'group_id' => $g, 1382 'inviter_id' => $u2, 1383 'send_invite' => 1, 1384 ) ); 1384 1385 1385 1386 $paged_groups = array(); 1386 1387 $paged_groups[] = new stdClass; … … class BP_Tests_BP_Groups_Group_TestCases extends BP_UnitTestCase { 1411 1412 */ 1412 1413 public function test_get_group_extras_pending() { 1413 1414 $u = self::factory()->user->create(); 1414 $g = self::factory()->group->create( );1415 $g = self::factory()->group->create( array( 'status' => 'private' ) ); 1415 1416 1416 $invite = new BP_Groups_Member; 1417 $invite->group_id = $g; 1418 $invite->user_id = $u; 1419 $invite->date_modified = bp_core_current_time(); 1420 $invite->invite_sent = false; 1421 $invite->is_confirmed = false; 1422 $invite->save(); 1417 // Create membership request 1418 groups_send_membership_request( array( 1419 'user_id' => $u, 1420 'group_id' => $g, 1421 ) ); 1423 1422 1424 1423 $paged_groups = array(); 1425 1424 $paged_groups[] = new stdClass; -
tests/phpunit/testcases/groups/class-bp-groups-member.php
diff --git tests/phpunit/testcases/groups/class-bp-groups-member.php tests/phpunit/testcases/groups/class-bp-groups-member.php index b052f81fe..480c2ae0f 100644
class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 20 20 array_map( 'groups_delete_group', self::$group_ids ); 21 21 } 22 22 23 public static function invite_user_to_group( $user_id, $group_id, $inviter_id ) {24 $invite = new BP_Groups_Member;25 $invite->group_id = $group_id;26 $invite->user_id = $user_id;27 $invite->date_modified = bp_core_current_time();28 $invite->inviter_id = $inviter_id;29 $invite->is_confirmed = 0;30 $invite->invite_sent = 1;31 32 $invite->save();33 return $invite->id;34 }35 36 public static function create_group_membership_request( $user_id, $group_id ) {37 $request = new BP_Groups_Member;38 $request->group_id = $group_id;39 $request->user_id = $user_id;40 $request->date_modified = bp_core_current_time();41 $request->inviter_id = 0;42 $request->is_confirmed = 0;43 44 $request->save();45 return $request->id;46 }47 48 23 public function test_get_recently_joined_with_filter() { 49 24 $g1 = self::factory()->group->create( array( 50 25 'name' => 'Tab', … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 133 108 } 134 109 135 110 public function test_get_invites_with_exclude() { 111 $u1 = self::factory()->user->create(); 112 $u2 = self::factory()->user->create(); 136 113 $g1 = self::factory()->group->create( array( 137 'name' => 'RC Cola', 114 'status' => 'private', 115 'creator_id' => $u1 138 116 ) ); 139 117 $g2 = self::factory()->group->create( array( 140 'name' => 'Pepsi', 118 'status' => 'private', 119 'creator_id' => $u1 141 120 ) ); 142 121 143 $u1 = self::factory()->user->create(); 144 $u2 = self::factory()->user->create(); 145 self::add_user_to_group( $u1, $g1 ); 146 self::add_user_to_group( $u1, $g2 ); 147 self::invite_user_to_group( $u2, $g1, $u1 ); 148 self::invite_user_to_group( $u2, $g2, $u1 ); 122 groups_invite_user( array( 123 'user_id' => $u2, 124 'group_id' => $g1, 125 'inviter_id' => $u1, 126 'send_invite' => 1, 127 ) ); 128 groups_invite_user( array( 129 'user_id' => $u2, 130 'group_id' => $g2, 131 'inviter_id' => $u1, 132 'send_invite' => 1, 133 ) ); 149 134 150 135 $groups = BP_Groups_Member::get_invites( $u2, false, false, array( 'awesome', $g1 ) ); 151 136 … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 282 267 ) ); 283 268 284 269 // Membership requests should be removed. 285 self::create_group_membership_request( $u1, $g ); 270 groups_send_membership_request( array( 271 'user_id' => $u1, 272 'group_id' => $g 273 ) ); 274 286 275 groups_reject_membership_request( null, $u1, $g ); 287 276 $u1_has_request = groups_check_for_membership_request( $u1, $g ); 288 277 $this->assertEquals( 0, $u1_has_request ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 325 314 ) ); 326 315 327 316 // Outstanding invitations should be left intact. 328 self::invite_user_to_group( $u2, $g, $u1 ); 317 groups_invite_user( array( 318 'user_id' => $u2, 319 'group_id' => $g, 320 'inviter_id' => $u1, 321 'send_invite' => 1, 322 ) ); 329 323 groups_reject_membership_request( null, $u2, $g ); 330 324 $u2_has_invite = groups_check_user_has_invite( $u2, $g ); 331 325 $this->assertTrue( is_numeric( $u2_has_invite ) && $u2_has_invite > 0 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 343 337 ) ); 344 338 345 339 // Membership requests should be removed. 346 self::create_group_membership_request( $u1, $g ); 340 groups_send_membership_request( array( 341 'user_id' => $u1, 342 'group_id' => $g 343 ) ); 347 344 groups_delete_membership_request( null, $u1, $g ); 348 345 $u1_has_request = groups_check_for_membership_request( $u1, $g ); 349 346 $this->assertEquals( 0, $u1_has_request ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 386 383 ) ); 387 384 388 385 // Outstanding invitations should be left intact. 389 self::invite_user_to_group( $u2, $g, $u1 ); 386 groups_invite_user( array( 387 'user_id' => $u2, 388 'group_id' => $g, 389 'inviter_id' => $u1, 390 'send_invite' => 1, 391 ) ); 392 390 393 groups_delete_membership_request( null, $u2, $g ); 391 394 $u2_has_invite = groups_check_user_has_invite( $u2, $g ); 392 395 $this->assertTrue( is_numeric( $u2_has_invite ) && $u2_has_invite > 0 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 410 413 ) ); 411 414 412 415 // The invitation should be removed. 413 self::invite_user_to_group( $u2, $g, $u1 ); 416 groups_invite_user( array( 417 'user_id' => $u2, 418 'group_id' => $g, 419 'inviter_id' => $u1, 420 'send_invite' => 1, 421 ) ); 422 414 423 groups_reject_invite( $u2, $g ); 415 424 $u2_has_invite = groups_check_user_has_invite( $u2, $g, 'all' ); 416 425 $this->assertEquals( 0, $u2_has_invite ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 450 459 ) ); 451 460 452 461 // Membership requests should be left intact. 453 self::create_group_membership_request( $u1, $g ); 462 groups_send_membership_request( array( 463 'user_id' => $u1, 464 'group_id' => $g 465 ) ); 454 466 groups_reject_invite( $u1, $g ); 455 467 $u1_has_request = groups_check_for_membership_request( $u1, $g ); 456 468 $this->assertTrue( is_numeric( $u1_has_request ) && $u1_has_request > 0 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 474 486 ) ); 475 487 476 488 // The invitation should be removed. 477 self::invite_user_to_group( $u2, $g, $u1 ); 489 groups_invite_user( array( 490 'user_id' => $u2, 491 'group_id' => $g, 492 'inviter_id' => $u1, 493 'send_invite' => 1, 494 ) ); 495 478 496 groups_delete_invite( $u2, $g ); 479 497 $u2_has_invite = groups_check_user_has_invite( $u2, $g, 'all' ); 480 498 $this->assertEquals( 0, $u2_has_invite ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 547 565 ) ); 548 566 549 567 // Membership requests should be left intact. 550 self::create_group_membership_request( $u1, $g ); 568 groups_send_membership_request( array( 569 'user_id' => $u1, 570 'group_id' => $g 571 ) ); 551 572 groups_delete_invite( $u1, $g ); 552 573 $u1_has_request = groups_check_for_membership_request( $u1, $g ); 553 574 $this->assertTrue( is_numeric( $u1_has_request ) && $u1_has_request > 0 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 571 592 ) ); 572 593 573 594 // The invitation should be removed. 574 self::invite_user_to_group( $u2, $g, $u1 ); 595 groups_invite_user( array( 596 'user_id' => $u2, 597 'group_id' => $g, 598 'inviter_id' => $u1, 599 'send_invite' => 1, 600 ) ); 575 601 groups_uninvite_user( $u2, $g ); 576 602 $u2_has_invite = groups_check_user_has_invite( $u2, $g, 'all' ); 577 603 $this->assertEquals( 0, $u2_has_invite ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 612 638 ) ); 613 639 614 640 // Membership requests should be left intact. 615 self::create_group_membership_request( $u1, $g ); 641 groups_send_membership_request( array( 642 'user_id' => $u1, 643 'group_id' => $g 644 ) ); 616 645 groups_uninvite_user( $u1, $g ); 617 646 $u1_has_request = groups_check_for_membership_request( $u1, $g ); 618 647 $this->assertTrue( is_numeric( $u1_has_request ) && $u1_has_request > 0 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 672 701 $m1 = new BP_Groups_Member( $u1, $g ); 673 702 $m1->promote( 'admin' ); 674 703 675 self::invite_user_to_group( $u2, $g, $u1 ); 676 704 groups_invite_user( array( 705 'user_id' => $u2, 706 'group_id' => $g, 707 'inviter_id' => $u1, 708 'send_invite' => 1, 709 ) ); 677 710 groups_join_group( $g, $u2 ); 678 711 // Upon joining the group, outstanding invitations should be cleaned up. 679 712 $this->assertEquals( null, groups_check_user_has_invite( $u2, $g, 'any' ) ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 686 719 public function test_groups_join_group_cleanup_requests() { 687 720 $u1 = self::factory()->user->create(); 688 721 $g = self::factory()->group->create(); 689 self::create_group_membership_request( $u1, $g ); 722 723 groups_send_membership_request( array( 724 'user_id' => $u1, 725 'group_id' => $g 726 ) ); 690 727 691 728 groups_join_group( $g, $u1 ); 692 729 // Upon joining the group, outstanding requests should be cleaned up. … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 825 862 public function test_groups_get_invites_for_user() { 826 863 $u1 = self::factory()->user->create(); 827 864 $u2 = self::factory()->user->create(); 828 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) ); 829 $g2 = self::factory()->group->create( array( 'creator_id' => $u1 ) ); 830 $g3 = self::factory()->group->create( array( 'creator_id' => $u1 ) ); 831 832 self::invite_user_to_group( $u2, $g1, $u1 ); 833 self::invite_user_to_group( $u2, $g2, $u1 ); 834 self::invite_user_to_group( $u2, $g3, $u1 ); 865 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 866 $g2 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 867 $g3 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 835 868 869 groups_invite_user( array( 870 'user_id' => $u2, 871 'group_id' => $g1, 872 'inviter_id' => $u1, 873 'send_invite' => 1, 874 ) ); 875 groups_invite_user( array( 876 'user_id' => $u2, 877 'group_id' => $g2, 878 'inviter_id' => $u1, 879 'send_invite' => 1, 880 ) ); 881 groups_invite_user( array( 882 'user_id' => $u2, 883 'group_id' => $g3, 884 'inviter_id' => $u1, 885 'send_invite' => 1, 886 ) ); 836 887 $groups = groups_get_invites_for_user( $u2 ); 837 888 838 889 $this->assertEqualSets( array( $g1, $g2, $g3 ), wp_list_pluck( $groups['groups'], 'id' ) ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 848 899 849 900 $u1 = self::factory()->user->create(); 850 901 $u2 = self::factory()->user->create(); 851 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );852 $g2 = self::factory()->group->create( array( 'creator_id' => $u1 ) );853 $g3 = self::factory()->group->create( array( 'creator_id' => $u1 ) );902 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 903 $g2 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 904 $g3 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 854 905 855 self::invite_user_to_group( $u2, $g1, $u1 ); 856 self::invite_user_to_group( $u2, $g2, $u1 ); 857 self::invite_user_to_group( $u2, $g3, $u1 ); 906 groups_invite_user( array( 907 'user_id' => $u2, 908 'group_id' => $g1, 909 'inviter_id' => $u1, 910 'send_invite' => 1, 911 ) ); 912 groups_invite_user( array( 913 'user_id' => $u2, 914 'group_id' => $g2, 915 'inviter_id' => $u1, 916 'send_invite' => 1, 917 ) ); 918 groups_invite_user( array( 919 'user_id' => $u2, 920 'group_id' => $g3, 921 'inviter_id' => $u1, 922 'send_invite' => 1, 923 ) ); 858 924 859 925 $this->set_current_user( $u2 ); 860 926 $groups = groups_get_invites_for_user(); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 871 937 public function test_groups_get_invites_for_user_with_exclude() { 872 938 $u1 = self::factory()->user->create(); 873 939 $u2 = self::factory()->user->create(); 874 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );875 $g2 = self::factory()->group->create( array( 'creator_id' => $u1 ) );876 $g3 = self::factory()->group->create( array( 'creator_id' => $u1 ) );940 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 941 $g2 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 942 $g3 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 877 943 878 self::invite_user_to_group( $u2, $g1, $u1 ); 879 self::invite_user_to_group( $u2, $g2, $u1 ); 880 self::invite_user_to_group( $u2, $g3, $u1 ); 944 groups_invite_user( array( 945 'user_id' => $u2, 946 'group_id' => $g1, 947 'inviter_id' => $u1, 948 'send_invite' => 1, 949 ) ); 950 groups_invite_user( array( 951 'user_id' => $u2, 952 'group_id' => $g2, 953 'inviter_id' => $u1, 954 'send_invite' => 1, 955 ) ); 956 groups_invite_user( array( 957 'user_id' => $u2, 958 'group_id' => $g3, 959 'inviter_id' => $u1, 960 'send_invite' => 1, 961 ) ); 881 962 882 963 $groups = groups_get_invites_for_user( $u2, false, false, array( $g2 ) ); 883 964 $this->assertEqualSets( array( $g1, $g3 ), wp_list_pluck( $groups['groups'], 'id' ) ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 891 972 public function test_groups_get_invite_count_for_user() { 892 973 $u1 = self::factory()->user->create(); 893 974 $u2 = self::factory()->user->create(); 894 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );895 $g2 = self::factory()->group->create( array( 'creator_id' => $u1 ) );896 $g3 = self::factory()->group->create( array( 'creator_id' => $u1 ) );975 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 976 $g2 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 977 $g3 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 897 978 898 self::invite_user_to_group( $u2, $g1, $u1 ); 899 self::invite_user_to_group( $u2, $g2, $u1 ); 900 self::invite_user_to_group( $u2, $g3, $u1 ); 979 groups_invite_user( array( 980 'user_id' => $u2, 981 'group_id' => $g1, 982 'inviter_id' => $u1, 983 'send_invite' => 1, 984 ) ); 985 groups_invite_user( array( 986 'user_id' => $u2, 987 'group_id' => $g2, 988 'inviter_id' => $u1, 989 'send_invite' => 1, 990 ) ); 991 groups_invite_user( array( 992 'user_id' => $u2, 993 'group_id' => $g3, 994 'inviter_id' => $u1, 995 'send_invite' => 1, 996 ) ); 901 997 902 998 $this->assertEquals( 3, groups_get_invite_count_for_user( $u2 ) ); 903 999 } … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 910 1006 public function test_groups_get_invite_count_for_user_ignore_drafts() { 911 1007 $u1 = self::factory()->user->create(); 912 1008 $u2 = self::factory()->user->create(); 913 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1009 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 914 1010 915 1011 // Create draft invitation. 916 1012 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 933 1029 public function test_groups_invite_user() { 934 1030 $u1 = self::factory()->user->create(); 935 1031 $u2 = self::factory()->user->create(); 936 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1032 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 937 1033 938 1034 // Create draft invitation 939 1035 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 957 1053 public function test_groups_send_invites() { 958 1054 $u1 = self::factory()->user->create(); 959 1055 $u2 = self::factory()->user->create(); 960 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1056 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 961 1057 962 1058 // Create draft invitation 963 1059 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 969 1065 ) ); 970 1066 971 1067 // Send the invitation 972 groups_send_invites( $u1, $g1 ); 1068 groups_send_invites( array( 1069 'group_id' => $g1, 1070 'inviter_id' => $u1, 1071 ) ); 973 1072 974 1073 // Check that the invitation has been sent. 975 1074 $sent = groups_check_user_has_invite( $u2, $g1, $type = 'sent' ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 977 1076 } 978 1077 979 1078 /** 980 * @group groups_ accept_invite1079 * @group groups_send_invites 981 1080 * @group group_invitations 982 1081 * @group group_membership 1082 * @expectedDeprecated groups_send_invites 983 1083 */ 984 public function test_groups_ accept_invite() {1084 public function test_groups_send_invites_deprecated_args() { 985 1085 $u1 = self::factory()->user->create(); 986 1086 $u2 = self::factory()->user->create(); 987 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1087 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 988 1088 989 1089 // Create draft invitation 990 1090 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 998 1098 // Send the invitation 999 1099 groups_send_invites( $u1, $g1 ); 1000 1100 1101 // Check that the invitation has been sent. 1102 $sent = groups_check_user_has_invite( $u2, $g1, $type = 'sent' ); 1103 $this->assertTrue( is_numeric( $sent ) && $sent > 0 ); 1104 } 1105 1106 /** 1107 * @group groups_accept_invite 1108 * @group group_invitations 1109 * @group group_membership 1110 */ 1111 public function test_groups_accept_invite() { 1112 $u1 = self::factory()->user->create(); 1113 $u2 = self::factory()->user->create(); 1114 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1115 1116 // Create draft invitation 1117 groups_invite_user( array( 1118 'user_id' => $u2, 1119 'group_id' => $g1, 1120 'inviter_id' => $u1, 1121 'date_modified' => bp_core_current_time(), 1122 'is_confirmed' => 0, 1123 'send_invite' => 1 1124 ) ); 1125 1001 1126 // Accept the invitation 1002 1127 groups_accept_invite( $u2, $g1 ); 1003 1128 … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1017 1142 public function test_groups_accept_invite_removes_membership_requests() { 1018 1143 $u1 = self::factory()->user->create(); 1019 1144 $u2 = self::factory()->user->create(); 1020 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1145 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1021 1146 1022 1147 // Create draft invitation 1023 1148 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1029 1154 ) ); 1030 1155 1031 1156 // Create membership request 1032 groups_send_membership_request( $u2, $g1 ); 1157 $request_id = groups_send_membership_request( array( 1158 'user_id' => $u2, 1159 'group_id' => $g1, 1160 ) ); 1161 1033 1162 $request = groups_check_for_membership_request( $u2, $g1 ); 1163 1034 1164 $this->assertTrue( is_numeric( $request ) && $request > 0 ); 1035 1165 1036 1166 // Send the invitation 1037 groups_send_invites( $u1, $g1 ); 1167 groups_send_invites( array( 1168 'group_id' => $g1, 1169 'inviter_id' => $u1, 1170 ) ); 1038 1171 1039 1172 // Accept the invitation 1040 1173 groups_accept_invite( $u2, $g1 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1052 1185 public function test_groups_sent_invite_plus_request_equals_member() { 1053 1186 $u1 = self::factory()->user->create(); 1054 1187 $u2 = self::factory()->user->create(); 1055 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1188 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1056 1189 1057 1190 // Create draft invitation 1058 1191 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1060 1193 'group_id' => $g1, 1061 1194 'inviter_id' => $u1, 1062 1195 'date_modified' => bp_core_current_time(), 1063 'is_confirmed' => 0 1196 'is_confirmed' => 0, 1197 'send_invite' => 1 1064 1198 ) ); 1065 1199 1066 // Send the invitation1067 groups_send_invites( $u1, $g1 );1068 1069 1200 // Create membership request 1070 groups_send_membership_request( $u2, $g1 ); 1201 groups_send_membership_request( array( 1202 'user_id' => $u2, 1203 'group_id' => $g1 1204 ) ); 1071 1205 1072 1206 // User should now be a group member 1073 1207 $member = groups_is_user_member( $u2, $g1 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1083 1217 $u1 = self::factory()->user->create(); 1084 1218 $u2 = self::factory()->user->create(); 1085 1219 $u3 = self::factory()->user->create(); 1086 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1220 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1087 1221 1088 self::invite_user_to_group( $u2, $g1, $u1 ); 1089 self::invite_user_to_group( $u3, $g1, $u1 ); 1222 groups_invite_user( array( 1223 'user_id' => $u2, 1224 'group_id' => $g1, 1225 'inviter_id' => $u1, 1226 'send_invite' => 1, 1227 ) ); 1228 groups_invite_user( array( 1229 'user_id' => $u3, 1230 'group_id' => $g1, 1231 'inviter_id' => $u1, 1232 'send_invite' => 1, 1233 ) ); 1090 1234 1091 1235 groups_delete_all_group_invites( $g1 ); 1092 1236 1093 1237 // Get group invitations of any type, from any user in the group. 1094 $invitees = new BP_Group_Member_Query( array( 1238 1239 $invitees = groups_get_invites( array( 1095 1240 'group_id' => $g1, 1096 'is_confirmed' => 0, 1097 'invite_sent' => null, 1098 'inviter_id' => 'any', 1241 'invite_sent' => 'all', 1099 1242 ) ); 1100 1243 1101 $this->assertTrue( empty( $invitees ->results) );1244 $this->assertTrue( empty( $invitees ) ); 1102 1245 } 1103 1246 1104 1247 /** … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1129 1272 */ 1130 1273 public function test_groups_send_invites_fail_on_empty_user_id() { 1131 1274 $u1 = self::factory()->user->create(); 1132 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1275 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1133 1276 1134 1277 // Create draft invitation with empty inviter_id 1135 1278 $invite_created = groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1151 1294 public function test_groups_send_invites_fail_on_empty_inviter_id() { 1152 1295 $u1 = self::factory()->user->create(); 1153 1296 $u2 = self::factory()->user->create(); 1154 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1297 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1155 1298 1156 1299 // Create draft invitation with empty inviter_id 1157 1300 $invite_created = groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1174 1317 public function test_groups_get_invites_for_group_with_sent_parameter() { 1175 1318 $u1 = self::factory()->user->create(); 1176 1319 $u2 = self::factory()->user->create(); 1177 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1320 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1178 1321 1179 1322 // Create draft invitation 1180 1323 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1182 1325 'group_id' => $g1, 1183 1326 'inviter_id' => $u1, 1184 1327 'date_modified' => bp_core_current_time(), 1185 'is_confirmed' => 0 1328 'is_confirmed' => 0, 1329 'send_invite' => 1 1186 1330 ) ); 1187 1331 1188 // Send the invitation; this will set the 'invite_sent' value to 1.1189 groups_send_invites( $u1, $g1 );1190 1191 1332 // Default groups_get_invites_for_group() call 1192 1333 $i = groups_get_invites_for_group( $u1, $g1 ); 1193 1334 $this->assertEqualSets( array( $u2 ), $i ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1208 1349 */ 1209 1350 public function test_groups_send_membership_request() { 1210 1351 $u1 = self::factory()->user->create(); 1211 $g1 = self::factory()->group->create(); 1352 $g1 = self::factory()->group->create( array( 'status' => 'private' ) ); 1353 1354 // Create membership request 1355 groups_send_membership_request( array( 1356 'user_id' => $u1, 1357 'group_id' => $g1 1358 ) ); 1359 1360 $request = groups_check_for_membership_request( $u1, $g1 ); 1361 $this->assertTrue( is_numeric( $request ) && $request > 0 ); 1362 } 1363 1364 /** 1365 * @group groups_send_membership_request 1366 * @group group_membership_requests 1367 * @group group_membership 1368 * @expectedDeprecated groups_send_membership_request 1369 */ 1370 public function test_groups_send_membership_request_deprecated_args() { 1371 $u1 = self::factory()->user->create(); 1372 $g1 = self::factory()->group->create( array( 'status' => 'private' ) ); 1212 1373 1213 1374 // Create membership request 1214 1375 groups_send_membership_request( $u1, $g1 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1224 1385 */ 1225 1386 public function test_groups_accept_membership_request_by_membership_id() { 1226 1387 $u1 = self::factory()->user->create(); 1227 $g1 = self::factory()->group->create( );1388 $g1 = self::factory()->group->create( array( 'status' => 'private' ) ); 1228 1389 1229 1390 // Create membership request 1230 groups_send_membership_request( $u1, $g1 ); 1391 groups_send_membership_request( array( 1392 'user_id' => $u1, 1393 'group_id' => $g1 1394 ) ); 1231 1395 1232 1396 // Get group invitations of any type, from any user in the group. 1233 1397 $member = new BP_Groups_Member( $u1, $g1 ); 1234 1398 1235 groups_accept_membership_request( $member->id);1399 groups_accept_membership_request( false, $u1, $g1 ); 1236 1400 1237 1401 // User should now be a group member. 1238 1402 $member = groups_is_user_member( $u1, $g1 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1247 1411 */ 1248 1412 public function test_groups_accept_membership_request_by_user_id_group_id() { 1249 1413 $u1 = self::factory()->user->create(); 1250 $g1 = self::factory()->group->create( );1414 $g1 = self::factory()->group->create( array( 'status' => 'private' ) ); 1251 1415 1252 1416 // Create membership request 1253 groups_send_membership_request( $u1, $g1 ); 1417 groups_send_membership_request( array( 1418 'user_id' => $u1, 1419 'group_id' => $g1 1420 ) ); 1254 1421 1255 1422 groups_accept_membership_request( null, $u1, $g1 ); 1256 1423 … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1268 1435 public function test_groups_membership_request_plus_invite_equals_member() { 1269 1436 $u1 = self::factory()->user->create(); 1270 1437 $u2 = self::factory()->user->create(); 1271 $g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );1438 $g1 = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 1272 1439 1273 1440 // Create membership request 1274 groups_send_membership_request( $u2, $g1 ); 1441 groups_send_membership_request( array( 1442 'user_id' => $u2, 1443 'group_id' => $g1 1444 ) ); 1275 1445 1276 1446 // Create draft invitation 1277 1447 groups_invite_user( array( … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1279 1449 'group_id' => $g1, 1280 1450 'inviter_id' => $u1, 1281 1451 'date_modified' => bp_core_current_time(), 1282 'is_confirmed' => 0 1452 'is_confirmed' => 0, 1453 'send_invite' => 1 1283 1454 ) ); 1284 1455 1285 // Send the invitation1286 groups_send_invites( $u1, $g1 );1287 1288 1456 // User should now be a group member 1289 1457 $member = groups_is_user_member( $u2, $g1 ); 1290 1458 $this->assertTrue( is_numeric( $member ) && $member > 0 ); … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1299 1467 $u1 = self::factory()->user->create(); 1300 1468 $u2 = self::factory()->user->create(); 1301 1469 $u3 = self::factory()->user->create(); 1302 $g1 = self::factory()->group->create( );1470 $g1 = self::factory()->group->create( array( 'status' => 'private' ) ); 1303 1471 1304 1472 // Create membership request 1305 groups_send_membership_request( $u1, $g1 ); 1306 groups_send_membership_request( $u2, $g1 ); 1307 groups_send_membership_request( $u3, $g1 ); 1473 groups_send_membership_request( array( 1474 'user_id' => $u1, 1475 'group_id' => $g1 1476 ) ); 1477 groups_send_membership_request( array( 1478 'user_id' => $u2, 1479 'group_id' => $g1 1480 ) ); 1481 groups_send_membership_request( array( 1482 'user_id' => $u3, 1483 'group_id' => $g1 1484 ) ); 1308 1485 1309 1486 groups_accept_all_pending_membership_requests( $g1 ); 1310 1487 … … class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase { 1402 1579 $this->assertSame( self::$group_ids[0], $memberships[0]->group_id ); 1403 1580 } 1404 1581 1405 /**1406 * @ticket BP78591407 */1408 public function test_get_user_memberships_type_pending_request() {1409 groups_join_group( self::$group_ids[0], self::$user_ids[0] );1410 groups_send_membership_request( self::$user_ids[0], self::$group_ids[1] );1411 1412 $memberships = BP_Groups_Member::get_user_memberships( self::$user_ids[0], array(1413 'type' => 'pending_request',1414 ) );1415 1416 $this->assertCount( 1, $memberships );1417 $this->assertSame( self::$group_ids[1], $memberships[0]->group_id );1418 }1419 1420 /**1421 * @ticket BP78591422 */1423 public function test_get_user_memberships_type_pending_received_invitation() {1424 groups_join_group( self::$group_ids[0], self::$user_ids[0] );1425 groups_invite_user( array(1426 'user_id' => self::$user_ids[0],1427 'group_id' => self::$group_ids[1],1428 'inviter_id' => self::$user_ids[1],1429 ) );1430 1431 $memberships = BP_Groups_Member::get_user_memberships( self::$user_ids[0], array(1432 'type' => 'pending_received_invitation',1433 ) );1434 1435 $this->assertCount( 1, $memberships );1436 $this->assertSame( self::$group_ids[1], $memberships[0]->group_id );1437 }1438 1439 /**1440 * @ticket BP78591441 */1442 public function test_get_user_memberships_type_pending_sent_invitation() {1443 groups_join_group( self::$group_ids[0], self::$user_ids[0] );1444 groups_invite_user( array(1445 'user_id' => self::$user_ids[1],1446 'group_id' => self::$group_ids[1],1447 'inviter_id' => self::$user_ids[0],1448 ) );1449 1450 $memberships = BP_Groups_Member::get_user_memberships( self::$user_ids[0], array(1451 'type' => 'pending_sent_invitation',1452 ) );1453 1454 $this->assertCount( 1, $memberships );1455 $this->assertSame( self::$group_ids[1], $memberships[0]->group_id );1456 }1457 1458 1582 /** 1459 1583 * @ticket BP7476 1460 1584 */ -
tests/phpunit/testcases/groups/functions.php
diff --git tests/phpunit/testcases/groups/functions.php tests/phpunit/testcases/groups/functions.php index c4a24592a..ee04ef6a0 100644
class BP_Tests_Groups_Functions extends BP_UnitTestCase { 12 12 self::$user_ids = $factory->user->create_many( 3 ); 13 13 self::$group_ids = $factory->group->create_many( 2, array( 14 14 'creator_id' => self::$user_ids[2], 15 'status' => 'private' 15 16 ) ); 16 17 } 17 18 … … class BP_Tests_Groups_Functions extends BP_UnitTestCase { 138 139 $this->set_current_user( $u2 ); 139 140 140 141 $g = self::factory()->group->create(); 141 groups_send_membership_request( $u1, $g ); 142 groups_send_membership_request( array( 143 'user_id' => $u1, 144 'group_id' => $g, 145 ) ); 142 146 143 147 groups_accept_membership_request( 0, $u1, $g ); 144 148 … … class BP_Tests_Groups_Functions extends BP_UnitTestCase { 262 266 $u2 = self::factory()->user->create(); 263 267 $g = self::factory()->group->create( array( 'creator_id' => $u1 ) ); 264 268 265 groups_send_membership_request( $u2, $g ); 269 groups_send_membership_request( array( 270 'user_id' => $u2, 271 'group_id' => $g, 272 ) ); 266 273 groups_accept_membership_request( 0, $u2, $g ); 267 274 268 275 $this->assertEquals( 2, groups_get_groupmeta( $g, 'total_member_count' ) ); … … Bar!'; 632 639 public function test_get_invite_count_for_user() { 633 640 $u1 = self::factory()->user->create(); 634 641 $u2 = self::factory()->user->create(); 635 $g = self::factory()->group->create( array( 'creator_id' => $u1 ) );642 $g = self::factory()->group->create( array( 'creator_id' => $u1, 'status' => 'private' ) ); 636 643 637 644 // create invitation 638 645 groups_invite_user( array( 639 646 'user_id' => $u2, 640 647 'group_id' => $g, 641 648 'inviter_id' => $u1, 649 'send_invite' => 1 642 650 ) ); 643 651 644 // send the invite645 // this function is imperative to set the 'invite_sent' flag in the DB646 // why is this separated from groups_invite_user()?647 // @see groups_screen_group_invite()648 groups_send_invites( $u1, $g );649 650 652 // assert invite count 651 653 $this->assertEquals( 1, groups_get_invite_count_for_user( $u2 ) ); 652 654 … … Bar!'; 890 892 * @ticket BP7698 891 893 */ 892 894 public function test_bp_groups_pending_requests_personal_data_exporter() { 893 groups_send_membership_request( self::$user_ids[0], self::$group_ids[0] ); 895 groups_send_membership_request( array( 896 'user_id' => self::$user_ids[0], 897 'group_id' => self::$group_ids[0], 898 ) ); 894 899 895 900 $test_user = new WP_User( self::$user_ids[0] ); 896 901 -
tests/phpunit/testcases/groups/functions/bpGetUserGroups.php
diff --git tests/phpunit/testcases/groups/functions/bpGetUserGroups.php tests/phpunit/testcases/groups/functions/bpGetUserGroups.php index acf28c6b1..ccdb888ba 100644
class BP_Tests_Groups_Functions_BpGetUserGroups extends BP_UnitTestCase { 541 541 $server_name = isset( $_SERVER['SERVER_NAME'] ) ? $_SERVER['SERVER_NAME'] : null; 542 542 $_SERVER['SERVER_NAME'] = ''; 543 543 544 groups_send_membership_request( self::$user, self::$groups[2] ); 544 groups_send_membership_request( array( 545 'user_id' => self::$user, 546 'group_id' => self::$groups[2], 547 ) ); 545 548 546 549 // Populate cache. 547 550 $g1 = bp_get_user_groups( self::$user ); 548 551 549 552 $m = new BP_Groups_Member( self::$user, self::$groups[2] ); 550 553 551 groups_accept_membership_request( $m->id, self::$user, self::$groups[2] );554 groups_accept_membership_request( false, self::$user, self::$groups[2] ); 552 555 553 556 // For `wp_mail()`. 554 557 if ( is_null( $server_name ) ) { -
tests/phpunit/testcases/groups/functions/groupsIsUser.php
diff --git tests/phpunit/testcases/groups/functions/groupsIsUser.php tests/phpunit/testcases/groups/functions/groupsIsUser.php index f7d6dd356..ef35382c9 100644
class BP_Tests_Groups_Functions_GroupsIsUser extends BP_UnitTestCase { 21 21 ) ); 22 22 self::$groups = $f->group->create_many( 3, array( 23 23 'creator_id' => self::$admin_user, 24 'status' => 'private' 24 25 ) ); 25 26 26 27 $now = time(); … … class BP_Tests_Groups_Functions_GroupsIsUser extends BP_UnitTestCase { 173 174 $i = groups_invite_user( array( 174 175 'user_id' => self::$user, 175 176 'group_id' => self::$groups[1], 176 'inviter_id' => 123, 177 'inviter_id' => self::$admin_user, 178 'send_invite' => 1, 177 179 ) ); 178 180 179 // Send invite.180 $m = new BP_Groups_Member( self::$user, self::$groups[1] );181 $m->invite_sent = 1;182 $m->save();183 184 181 $this->assertNotEmpty( groups_is_user_invited( self::$user, self::$groups[1] ) ); 185 182 } 186 183 187 public function test_groups_is_user_pending_should_return_false_for_ pending_member() {184 public function test_groups_is_user_pending_should_return_false_for_invited_member() { 188 185 groups_invite_user( array( 189 186 'user_id' => self::$user, 190 187 'group_id' => self::$groups[1], 191 ' inviter_id' => 123,188 'send_invite' => 1 192 189 ) ); 193 190 194 // Send invite.195 $m = new BP_Groups_Member( self::$user, self::$groups[1] );196 $m->invite_sent = 1;197 $m->save();198 199 191 $this->assertEquals( false, groups_is_user_pending( self::$user, self::$groups[1] ) ); 200 192 } 201 193 … … class BP_Tests_Groups_Functions_GroupsIsUser extends BP_UnitTestCase { 204 196 } 205 197 206 198 public function test_groups_is_user_pending_should_return_true_for_pending_member() { 207 208 $m = new BP_Groups_Member; 209 $m->group_id = self::$groups[1]; 210 $m->user_id = self::$user; 211 $m->inviter_id = 0; 212 $m->is_admin = 0; 213 $m->user_title = ''; 214 $m->date_modified = bp_core_current_time(); 215 $m->is_confirmed = 0; 216 $m->comments = 'request'; 217 $m->save(); 199 groups_send_membership_request( array( 200 'user_id' => self::$user, 201 'group_id' => self::$groups[1], 202 ) ); 218 203 219 204 $this->assertNotEmpty( groups_is_user_pending( self::$user, self::$groups[1] ) ); 220 205 } -
tests/phpunit/testcases/groups/template/bpGroupStatusMessage.php
diff --git tests/phpunit/testcases/groups/template/bpGroupStatusMessage.php tests/phpunit/testcases/groups/template/bpGroupStatusMessage.php index b6d5e1173..bcc1ff3eb 100644
class BP_Tests_Groups_Template_BpGroupStatusMessage extends BP_UnitTestCase { 98 98 99 99 $this->set_current_user( $u ); 100 100 101 groups_send_membership_request( $u, $g ); 101 groups_send_membership_request( array( 102 'user_id' => $u, 103 'group_id' => $g 104 ) ); 102 105 103 106 if ( bp_has_groups( array( 'include' => array( $g ) ) ) ) { 104 107 while ( bp_groups() ) { … … class BP_Tests_Groups_Template_BpGroupStatusMessage extends BP_UnitTestCase { 141 144 $GLOBALS['groups_template'] = new stdClass; 142 145 $GLOBALS['groups_template']->group = groups_get_group( $groups[0] ); 143 146 144 groups_send_membership_request( $u, $groups[1] ); 147 groups_send_membership_request( array( 148 'user_id' => $u, 149 'group_id' => $groups[1] 150 ) ); 145 151 146 152 $group1 = groups_get_group( array( 147 153 'group_id' => $groups[1], -
tests/phpunit/testcases/groups/user_can.php
diff --git tests/phpunit/testcases/groups/user_can.php tests/phpunit/testcases/groups/user_can.php index 01b4bd254..fee0706f4 100644
class BP_Tests_Groups_User_Can_Filter extends BP_UnitTestCase { 108 108 'status' => 'private' 109 109 ) ); 110 110 $u1 = $this->factory->user->create(); 111 groups_send_membership_request( $u1, $g1 ); 111 groups_send_membership_request( array( 112 'user_id' => $u1, 113 'group_id' => $g1 114 ) ); 112 115 113 116 $this->assertFalse( bp_user_can( $u1, 'groups_request_membership', array( 'group_id' => $g1 ) ) ); 114 117 }