[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-groups/ -> bp-groups-functions.php (source)

   1  <?php
   2  /**
   3   * BuddyPress Groups Functions.
   4   *
   5   * Functions are where all the magic happens in BuddyPress. They will
   6   * handle the actual saving or manipulation of information. Usually they will
   7   * hand off to a database class for data access, then return
   8   * true or false on success or failure.
   9   *
  10   * @package BuddyPress
  11   * @subpackage GroupsFunctions
  12   * @since 1.5.0
  13   */
  14  
  15  // Exit if accessed directly.
  16  defined( 'ABSPATH' ) || exit;
  17  
  18  /**
  19   * Check whether there is a Groups directory page in the $bp global.
  20   *
  21   * @since 1.5.0
  22   *
  23   * @return bool True if set, False if empty.
  24   */
  25  function bp_groups_has_directory() {
  26      $bp = buddypress();
  27  
  28      return (bool) !empty( $bp->pages->groups->id );
  29  }
  30  
  31  /**
  32   * Fetch a single group object.
  33   *
  34   * When calling up a group object, you should always use this function instead
  35   * of instantiating BP_Groups_Group directly, so that you will inherit cache
  36   * support and pass through the groups_get_group filter.
  37   *
  38   * @since 1.2.0
  39   * @since 2.7.0 The function signature was changed to accept a group ID only,
  40   *              instead of an array containing the group ID.
  41   *
  42   * @param int $group_id ID of the group.
  43   * @return BP_Groups_Group $group The group object.
  44   */
  45  function groups_get_group( $group_id ) {
  46      /*
  47       * Backward compatibilty.
  48       * Old-style arguments take the form of an array or a query string.
  49       */
  50      if ( ! is_numeric( $group_id ) ) {
  51          $r = bp_parse_args( $group_id, array(
  52              'group_id'        => false,
  53              'load_users'      => false,
  54              'populate_extras' => false,
  55          ), 'groups_get_group' );
  56  
  57          $group_id = $r['group_id'];
  58      }
  59  
  60      $group = new BP_Groups_Group( $group_id );
  61  
  62      /**
  63       * Filters a single group object.
  64       *
  65       * @since 1.2.0
  66       *
  67       * @param BP_Groups_Group $group Single group object.
  68       */
  69      return apply_filters( 'groups_get_group', $group );
  70  }
  71  
  72  /** Group Creation, Editing & Deletion ****************************************/
  73  
  74  /**
  75   * Create a group.
  76   *
  77   * @since 1.0.0
  78   *
  79   * @param array|string $args {
  80   *     An array of arguments.
  81   *     @type int|bool $group_id     Pass a group ID to update an existing item, or
  82   *                                  0 / false to create a new group. Default: 0.
  83   *     @type int      $creator_id   The user ID that creates the group.
  84   *     @type string   $name         The group name.
  85   *     @type string   $description  Optional. The group's description.
  86   *     @type string   $slug         The group slug.
  87   *     @type string   $status       The group's status. Accepts 'public', 'private' or
  88   *                                  'hidden'. Defaults to 'public'.
  89   *     @type int      $parent_id    The ID of the parent group. Default: 0.
  90   *     @type int      $enable_forum Optional. Whether the group has a forum enabled.
  91   *                                  If a bbPress forum is enabled for the group,
  92   *                                  set this to 1. Default: 0.
  93   *     @type string   $date_created The GMT time, in Y-m-d h:i:s format, when the group
  94   *                                  was created. Defaults to the current time.
  95   * }
  96   * @return int|bool The ID of the group on success. False on error.
  97   */
  98  function groups_create_group( $args = '' ) {
  99  
 100      $args = bp_parse_args( $args, array(
 101          'group_id'     => 0,
 102          'creator_id'   => 0,
 103          'name'         => '',
 104          'description'  => '',
 105          'slug'         => '',
 106          'status'       => null,
 107          'parent_id'    => null,
 108          'enable_forum' => null,
 109          'date_created' => null
 110      ), 'groups_create_group' );
 111  
 112      extract( $args, EXTR_SKIP );
 113  
 114      // Pass an existing group ID.
 115      if ( ! empty( $group_id ) ) {
 116          $group = groups_get_group( $group_id );
 117          $name  = ! empty( $name ) ? $name : $group->name;
 118          $slug  = ! empty( $slug ) ? $slug : $group->slug;
 119          $creator_id  = ! empty( $creator_id ) ? $creator_id : $group->creator_id;
 120          $description = ! empty( $description ) ? $description : $group->description;
 121          $status = ! is_null( $status ) ? $status : $group->status;
 122          $parent_id = ! is_null( $parent_id ) ? $parent_id : $group->parent_id;
 123          $enable_forum = ! is_null( $enable_forum ) ? $enable_forum : $group->enable_forum;
 124          $date_created = ! is_null( $date_created ) ? $date_created : $group->date_created;
 125  
 126          // Groups need at least a name.
 127          if ( empty( $name ) ) {
 128              return false;
 129          }
 130  
 131      // Create a new group.
 132      } else {
 133          // Instantiate new group object.
 134          $group = new BP_Groups_Group;
 135  
 136          // Check for null values, reset to sensible defaults.
 137          $status = ! is_null( $status ) ? $status : 'public';
 138          $parent_id = ! is_null( $parent_id ) ? $parent_id : 0;
 139          $enable_forum = ! is_null( $enable_forum ) ? $enable_forum : 0;
 140          $date_created = ! is_null( $date_created ) ? $date_created : bp_core_current_time();
 141      }
 142  
 143      // Set creator ID.
 144      if ( $creator_id ) {
 145          $group->creator_id = (int) $creator_id;
 146      } elseif ( is_user_logged_in() ) {
 147          $group->creator_id = bp_loggedin_user_id();
 148      }
 149  
 150      if ( ! $group->creator_id ) {
 151          return false;
 152      }
 153  
 154      // Validate status.
 155      if ( ! groups_is_valid_status( $status ) ) {
 156          return false;
 157      }
 158  
 159      // Set group name.
 160      $group->name         = $name;
 161      $group->description  = $description;
 162      $group->slug         = $slug;
 163      $group->status       = $status;
 164      $group->parent_id    = $parent_id;
 165      $group->enable_forum = (int) $enable_forum;
 166      $group->date_created = $date_created;
 167  
 168      // Save group.
 169      if ( ! $group->save() ) {
 170          return false;
 171      }
 172  
 173      // If this is a new group, set up the creator as the first member and admin.
 174      if ( empty( $group_id ) ) {
 175          $member                = new BP_Groups_Member;
 176          $member->group_id      = $group->id;
 177          $member->user_id       = $group->creator_id;
 178          $member->is_admin      = 1;
 179          $member->user_title    = __( 'Group Admin', 'buddypress' );
 180          $member->is_confirmed  = 1;
 181          $member->date_modified = bp_core_current_time();
 182          $member->save();
 183  
 184          /**
 185           * Fires after the creation of a new group and a group creator needs to be made.
 186           *
 187           * @since 1.5.0
 188           *
 189           * @param int              $id     ID of the newly created group.
 190           * @param BP_Groups_Member $member Instance of the member who is assigned
 191           *                                 as group creator.
 192           * @param BP_Groups_Group  $group  Instance of the group being created.
 193           */
 194          do_action( 'groups_create_group', $group->id, $member, $group );
 195  
 196      } else {
 197  
 198          /**
 199           * Fires after the update of a group.
 200           *
 201           * @since 1.5.0
 202           *
 203           * @param int             $id    ID of the updated group.
 204           * @param BP_Groups_Group $group Instance of the group being updated.
 205           */
 206          do_action( 'groups_update_group', $group->id, $group );
 207      }
 208  
 209      /**
 210       * Fires after the creation or update of a group.
 211       *
 212       * @since 1.0.0
 213       *
 214       * @param int             $id    ID of the newly created group.
 215       * @param BP_Groups_Group $group Instance of the group being updated.
 216       */
 217      do_action( 'groups_created_group', $group->id, $group );
 218  
 219      return $group->id;
 220  }
 221  
 222  /**
 223   * Edit the base details for a group.
 224   *
 225   * These are the settings that appear on the first page of the group's Admin
 226   * section (Name, Description, and "Notify members...").
 227   *
 228   * @since 1.0.0
 229   *
 230   * @param array $args {
 231   *     An array of optional arguments.
 232   *     @type int    $group_id       ID of the group.
 233   *     @type string $name           Name of the group.
 234   *     @type string $slug           Slug of the group.
 235   *     @type string $description    Description of the group.
 236   *     @type bool   $notify_members Whether to send an email notification to group
 237   *                                  members about changes in these details.
 238   * }
 239   * @return bool True on success, false on failure.
 240   */
 241  function groups_edit_base_group_details( $args = array() ) {
 242      $function_args = func_get_args();
 243  
 244      // Backward compatibility with old method of passing arguments.
 245      if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
 246          _deprecated_argument( __METHOD__, '2.9.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
 247  
 248          $old_args_keys = array(
 249              0 => 'group_id',
 250              1 => 'name',
 251              2 => 'description',
 252              3 => 'notify_members',
 253          );
 254  
 255          $args = bp_core_parse_args_array( $old_args_keys, $function_args );
 256      }
 257  
 258      $r = bp_parse_args( $args, array(
 259          'group_id'       => bp_get_current_group_id(),
 260          'name'           => null,
 261          'slug'           => null,
 262          'description'    => null,
 263          'notify_members' => false,
 264      ), 'groups_edit_base_group_details' );
 265  
 266      if ( ! $r['group_id'] ) {
 267          return false;
 268      }
 269  
 270      $group     = groups_get_group( $r['group_id'] );
 271      $old_group = clone $group;
 272  
 273      // Group name, slug and description can never be empty. Update only if provided.
 274      if ( $r['name'] ) {
 275          $group->name = $r['name'];
 276      }
 277      if ( $r['slug'] && $r['slug'] != $group->slug ) {
 278          $group->slug = groups_check_slug( $r['slug'] );
 279      }
 280      if ( $r['description'] ) {
 281          $group->description = $r['description'];
 282      }
 283  
 284      if ( ! $group->save() ) {
 285          return false;
 286      }
 287  
 288      // Maybe update the "previous_slug" groupmeta.
 289      if ( $group->slug != $old_group->slug ) {
 290          /*
 291           * If the old slug exists in this group's past, delete that entry.
 292           * Recent previous_slugs are preferred when selecting the current group
 293           * from an old group slug, so we want the previous slug to be
 294           * saved "now" in the groupmeta table and don't need the old record.
 295           */
 296          groups_delete_groupmeta( $group->id, 'previous_slug', $old_group->slug );
 297          groups_add_groupmeta( $group->id, 'previous_slug', $old_group->slug );
 298      }
 299  
 300      if ( $r['notify_members'] ) {
 301          groups_notification_group_updated( $group->id, $old_group );
 302      }
 303  
 304      /**
 305       * Fired after a group's details are updated.
 306       *
 307       * @since 2.2.0
 308       *
 309       * @param int             $value          ID of the group.
 310       * @param BP_Groups_Group $old_group      Group object, before being modified.
 311       * @param bool            $notify_members Whether to send an email notification to members about the change.
 312       */
 313      do_action( 'groups_details_updated', $group->id, $old_group, $r['notify_members'] );
 314  
 315      return true;
 316  }
 317  
 318  /**
 319   * Edit the base details for a group.
 320   *
 321   * These are the settings that appear on the Settings page of the group's Admin
 322   * section (privacy settings, "enable forum", invitation status).
 323   *
 324   * @since 1.0.0
 325   *
 326   * @param int         $group_id      ID of the group.
 327   * @param bool        $enable_forum  Whether to enable a forum for the group.
 328   * @param string      $status        Group status. 'public', 'private', 'hidden'.
 329   * @param string|bool $invite_status Optional. Who is allowed to send invitations
 330   *                                   to the group. 'members', 'mods', or 'admins'.
 331   * @param int|bool    $parent_id     Parent group ID.
 332   * @return bool True on success, false on failure.
 333   */
 334  function groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status = false, $parent_id = false ) {
 335  
 336      $group = groups_get_group( $group_id );
 337      $group->enable_forum = $enable_forum;
 338  
 339      /**
 340       * Before we potentially switch the group status, if it has been changed to public
 341       * from private and there are outstanding membership requests, auto-accept those requests.
 342       */
 343      if ( 'private' == $group->status && 'public' == $status )
 344          groups_accept_all_pending_membership_requests( $group->id );
 345  
 346      // Now update the status.
 347      $group->status = $status;
 348  
 349      // Update the parent ID if necessary.
 350      if ( false !== $parent_id ) {
 351          $group->parent_id = $parent_id;
 352      }
 353  
 354      if ( !$group->save() )
 355          return false;
 356  
 357      // Set the invite status.
 358      if ( $invite_status )
 359          groups_update_groupmeta( $group->id, 'invite_status', $invite_status );
 360  
 361      groups_update_groupmeta( $group->id, 'last_activity', bp_core_current_time() );
 362  
 363      /**
 364       * Fires after the update of a groups settings.
 365       *
 366       * @since 1.0.0
 367       *
 368       * @param int $id ID of the group that was updated.
 369       */
 370      do_action( 'groups_settings_updated', $group->id );
 371  
 372      return true;
 373  }
 374  
 375  /**
 376   * Delete a group and all of its associated metadata.
 377   *
 378   * @since 1.0.0
 379   *
 380   * @param int $group_id ID of the group to delete.
 381   * @return bool True on success, false on failure.
 382   */
 383  function groups_delete_group( $group_id ) {
 384  
 385      /**
 386       * Fires before the deletion of a group.
 387       *
 388       * @since 1.5.0
 389       *
 390       * @param int $group_id ID of the group to be deleted.
 391       */
 392      do_action( 'groups_before_delete_group', $group_id );
 393  
 394      // Get the group object.
 395      $group = groups_get_group( $group_id );
 396  
 397      // Bail if group cannot be deleted.
 398      if ( ! $group->delete() ) {
 399          return false;
 400      }
 401  
 402      // Remove all outstanding invites for this group.
 403      groups_delete_all_group_invites( $group_id );
 404  
 405      /**
 406       * Fires after the deletion of a group.
 407       *
 408       * @since 1.0.0
 409       *
 410       * @param int $group_id ID of the group that was deleted.
 411       */
 412      do_action( 'groups_delete_group', $group_id );
 413  
 414      return true;
 415  }
 416  
 417  /**
 418   * Check a group status (eg 'private') against the whitelist of registered statuses.
 419   *
 420   * @since 1.1.0
 421   *
 422   * @param string $status Status to check.
 423   * @return bool True if status is allowed, otherwise false.
 424   */
 425  function groups_is_valid_status( $status ) {
 426      $bp = buddypress();
 427  
 428      return in_array( $status, (array) $bp->groups->valid_status );
 429  }
 430  
 431  /**
 432   * Provide a unique, sanitized version of a group slug.
 433   *
 434   * @since 1.0.0
 435   *
 436   * @param string $slug Group slug to check.
 437   * @return string $slug A unique and sanitized slug.
 438   */
 439  function groups_check_slug( $slug ) {
 440      $bp = buddypress();
 441  
 442      // First, make the proposed slug work in a URL.
 443      $slug = sanitize_title( $slug );
 444  
 445      if ( 'wp' == substr( $slug, 0, 2 ) )
 446          $slug = substr( $slug, 2, strlen( $slug ) - 2 );
 447  
 448      if ( in_array( $slug, (array) $bp->groups->forbidden_names ) )
 449          $slug = $slug . '-' . rand();
 450  
 451      if ( BP_Groups_Group::check_slug( $slug ) ) {
 452          do {
 453              $slug = $slug . '-' . rand();
 454          }
 455          while ( BP_Groups_Group::check_slug( $slug ) );
 456      }
 457  
 458      return $slug;
 459  }
 460  
 461  /**
 462   * Get a group slug by its ID.
 463   *
 464   * @since 1.0.0
 465   *
 466   * @param int $group_id The numeric ID of the group.
 467   * @return string The group's slug.
 468   */
 469  function groups_get_slug( $group_id ) {
 470      $group = groups_get_group( $group_id );
 471      return !empty( $group->slug ) ? $group->slug : '';
 472  }
 473  
 474  /**
 475   * Get a group ID by its slug.
 476   *
 477   * @since 1.6.0
 478   *
 479   * @param string $group_slug The group's slug.
 480   * @return int|null The group ID on success; null on failure.
 481   */
 482  function groups_get_id( $group_slug ) {
 483      return BP_Groups_Group::group_exists( $group_slug );
 484  }
 485  
 486  /**
 487   * Get a group ID by checking against old (not currently active) slugs.
 488   *
 489   * @since 2.9.0
 490   *
 491   * @param string $group_slug The group's slug.
 492   * @return int|null The group ID on success; null on failure.
 493   */
 494  function groups_get_id_by_previous_slug( $group_slug ) {
 495      return BP_Groups_Group::get_id_by_previous_slug( $group_slug );
 496  }
 497  
 498  /** User Actions **************************************************************/
 499  
 500  /**
 501   * Remove a user from a group.
 502   *
 503   * @since 1.0.0
 504   *
 505   * @param int $group_id ID of the group.
 506   * @param int $user_id  Optional. ID of the user. Defaults to the currently
 507   *                      logged-in user.
 508   * @return bool True on success, false on failure.
 509   */
 510  function groups_leave_group( $group_id, $user_id = 0 ) {
 511  
 512      if ( empty( $user_id ) )
 513          $user_id = bp_loggedin_user_id();
 514  
 515      // Don't let single admins leave the group.
 516      if ( count( groups_get_group_admins( $group_id ) ) < 2 ) {
 517          if ( groups_is_user_admin( $user_id, $group_id ) ) {
 518              bp_core_add_message( __( 'As the only admin, you cannot leave the group.', 'buddypress' ), 'error' );
 519              return false;
 520          }
 521      }
 522  
 523      if ( ! BP_Groups_Member::delete( $user_id, $group_id ) ) {
 524          return false;
 525      }
 526  
 527      bp_core_add_message( __( 'You successfully left the group.', 'buddypress' ) );
 528  
 529      /**
 530       * Fires after a user leaves a group.
 531       *
 532       * @since 1.0.0
 533       *
 534       * @param int $group_id ID of the group.
 535       * @param int $user_id  ID of the user leaving the group.
 536       */
 537      do_action( 'groups_leave_group', $group_id, $user_id );
 538  
 539      return true;
 540  }
 541  
 542  /**
 543   * Add a user to a group.
 544   *
 545   * @since 1.0.0
 546   *
 547   * @param int $group_id ID of the group.
 548   * @param int $user_id  Optional. ID of the user. Defaults to the currently
 549   *                      logged-in user.
 550   * @return bool True on success, false on failure.
 551   */
 552  function groups_join_group( $group_id, $user_id = 0 ) {
 553  
 554      if ( empty( $user_id ) )
 555          $user_id = bp_loggedin_user_id();
 556  
 557      // Check if the user has an outstanding invite. If so, delete it.
 558      if ( groups_check_user_has_invite( $user_id, $group_id ) )
 559          groups_delete_invite( $user_id, $group_id );
 560  
 561      // Check if the user has an outstanding request. If so, delete it.
 562      if ( groups_check_for_membership_request( $user_id, $group_id ) )
 563          groups_delete_membership_request( null, $user_id, $group_id );
 564  
 565      // User is already a member, just return true.
 566      if ( groups_is_user_member( $user_id, $group_id ) )
 567          return true;
 568  
 569      $new_member                = new BP_Groups_Member;
 570      $new_member->group_id      = $group_id;
 571      $new_member->user_id       = $user_id;
 572      $new_member->inviter_id    = 0;
 573      $new_member->is_admin      = 0;
 574      $new_member->user_title    = '';
 575      $new_member->date_modified = bp_core_current_time();
 576      $new_member->is_confirmed  = 1;
 577  
 578      if ( !$new_member->save() )
 579          return false;
 580  
 581      $bp = buddypress();
 582  
 583      if ( !isset( $bp->groups->current_group ) || !$bp->groups->current_group || $group_id != $bp->groups->current_group->id )
 584          $group = groups_get_group( $group_id );
 585      else
 586          $group = $bp->groups->current_group;
 587  
 588      // Record this in activity streams.
 589      if ( bp_is_active( 'activity' ) ) {
 590          groups_record_activity( array(
 591              'type'    => 'joined_group',
 592              'item_id' => $group_id,
 593              'user_id' => $user_id,
 594          ) );
 595      }
 596  
 597      /**
 598       * Fires after a user joins a group.
 599       *
 600       * @since 1.0.0
 601       *
 602       * @param int $group_id ID of the group.
 603       * @param int $user_id  ID of the user joining the group.
 604       */
 605      do_action( 'groups_join_group', $group_id, $user_id );
 606  
 607      return true;
 608  }
 609  
 610  /**
 611   * Update the last_activity meta value for a given group.
 612   *
 613   * @since 1.0.0
 614   *
 615   * @param int $group_id Optional. The ID of the group whose last_activity is
 616   *                      being updated. Default: the current group's ID.
 617   * @return false|null False on failure.
 618   */
 619  function groups_update_last_activity( $group_id = 0 ) {
 620  
 621      if ( empty( $group_id ) ) {
 622          $group_id = buddypress()->groups->current_group->id;
 623      }
 624  
 625      if ( empty( $group_id ) ) {
 626          return false;
 627      }
 628  
 629      groups_update_groupmeta( $group_id, 'last_activity', bp_core_current_time() );
 630  }
 631  add_action( 'groups_join_group',           'groups_update_last_activity' );
 632  add_action( 'groups_leave_group',          'groups_update_last_activity' );
 633  add_action( 'groups_created_group',        'groups_update_last_activity' );
 634  
 635  /** General Group Functions ***************************************************/
 636  
 637  /**
 638   * Get a list of group administrators.
 639   *
 640   * @since 1.0.0
 641   *
 642   * @param int $group_id ID of the group.
 643   * @return array Info about group admins (user_id + date_modified).
 644   */
 645  function groups_get_group_admins( $group_id ) {
 646      return BP_Groups_Member::get_group_administrator_ids( $group_id );
 647  }
 648  
 649  /**
 650   * Get a list of group moderators.
 651   *
 652   * @since 1.0.0
 653   *
 654   * @param int $group_id ID of the group.
 655   * @return array Info about group admins (user_id + date_modified).
 656   */
 657  function groups_get_group_mods( $group_id ) {
 658      return BP_Groups_Member::get_group_moderator_ids( $group_id );
 659  }
 660  
 661  /**
 662   * Fetch the members of a group.
 663   *
 664   * Since BuddyPress 1.8, a procedural wrapper for BP_Group_Member_Query.
 665   * Previously called BP_Groups_Member::get_all_for_group().
 666   *
 667   * To use the legacy query, filter 'bp_use_legacy_group_member_query',
 668   * returning true.
 669   *
 670   * @since 1.0.0
 671   * @since 3.0.0 $group_id now supports multiple values. Only works if legacy query is not
 672   *              in use.
 673   *
 674   * @param array $args {
 675   *     An array of optional arguments.
 676   *     @type int|array|string $group_id            ID of the group to limit results to. Also accepts multiple values
 677   *                                                 either as an array or as a comma-delimited string.
 678   *     @type int              $page                Page of results to be queried. Default: 1.
 679   *     @type int              $per_page            Number of items to return per page of results. Default: 20.
 680   *     @type int              $max                 Optional. Max number of items to return.
 681   *     @type array            $exclude             Optional. Array of user IDs to exclude.
 682   *     @type bool|int         $exclude_admins_mods True (or 1) to exclude admins and mods from results. Default: 1.
 683   *     @type bool|int         $exclude_banned      True (or 1) to exclude banned users from results. Default: 1.
 684   *     @type array            $group_role          Optional. Array of group roles to include.
 685   *     @type string           $search_terms        Optional. Filter results by a search string.
 686   *     @type string           $type                Optional. Sort the order of results. 'last_joined', 'first_joined', or
 687   *                                                 any of the $type params available in {@link BP_User_Query}. Default:
 688   *                                                 'last_joined'.
 689   * }
 690   * @return false|array Multi-d array of 'members' list and 'count'.
 691   */
 692  function groups_get_group_members( $args = array() ) {
 693      $function_args = func_get_args();
 694  
 695      // Backward compatibility with old method of passing arguments.
 696      if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
 697          _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
 698  
 699          $old_args_keys = array(
 700              0 => 'group_id',
 701              1 => 'per_page',
 702              2 => 'page',
 703              3 => 'exclude_admins_mods',
 704              4 => 'exclude_banned',
 705              5 => 'exclude',
 706              6 => 'group_role',
 707          );
 708  
 709          $args = bp_core_parse_args_array( $old_args_keys, $function_args );
 710      }
 711  
 712      $r = bp_parse_args( $args, array(
 713          'group_id'            => bp_get_current_group_id(),
 714          'per_page'            => false,
 715          'page'                => false,
 716          'exclude_admins_mods' => true,
 717          'exclude_banned'      => true,
 718          'exclude'             => false,
 719          'group_role'          => array(),
 720          'search_terms'        => false,
 721          'type'                => 'last_joined',
 722      ), 'groups_get_group_members' );
 723  
 724      // For legacy users. Use of BP_Groups_Member::get_all_for_group() is deprecated.
 725      if ( apply_filters( 'bp_use_legacy_group_member_query', false, __FUNCTION__, $function_args ) ) {
 726          $retval = BP_Groups_Member::get_all_for_group( $r['group_id'], $r['per_page'], $r['page'], $r['exclude_admins_mods'], $r['exclude_banned'], $r['exclude'] );
 727      } else {
 728  
 729          // Both exclude_admins_mods and exclude_banned are legacy arguments.
 730          // Convert to group_role.
 731          if ( empty( $r['group_role'] ) ) {
 732              $r['group_role'] = array( 'member' );
 733  
 734              if ( ! $r['exclude_admins_mods'] ) {
 735                  $r['group_role'][] = 'mod';
 736                  $r['group_role'][] = 'admin';
 737              }
 738  
 739              if ( ! $r['exclude_banned'] ) {
 740                  $r['group_role'][] = 'banned';
 741              }
 742          }
 743  
 744          // Perform the group member query (extends BP_User_Query).
 745          $members = new BP_Group_Member_Query( array(
 746              'group_id'       => $r['group_id'],
 747              'per_page'       => $r['per_page'],
 748              'page'           => $r['page'],
 749              'group_role'     => $r['group_role'],
 750              'exclude'        => $r['exclude'],
 751              'search_terms'   => $r['search_terms'],
 752              'type'           => $r['type'],
 753          ) );
 754  
 755          // Structure the return value as expected by the template functions.
 756          $retval = array(
 757              'members' => array_values( $members->results ),
 758              'count'   => $members->total_users,
 759          );
 760      }
 761  
 762      return $retval;
 763  }
 764  
 765  /**
 766   * Get the member count for a group.
 767   *
 768   * @since 1.2.3
 769   *
 770   * @param int $group_id Group ID.
 771   * @return int Count of confirmed members for the group.
 772   */
 773  function groups_get_total_member_count( $group_id ) {
 774      return BP_Groups_Group::get_total_member_count( $group_id );
 775  }
 776  
 777  /** Group Fetching, Filtering & Searching  ************************************/
 778  
 779  /**
 780   * Get a collection of groups, based on the parameters passed.
 781   *
 782   * @since 1.2.0
 783   * @since 2.6.0 Added `$group_type`, `$group_type__in`, and `$group_type__not_in` parameters.
 784   * @since 2.7.0 Added `$update_admin_cache` and `$parent_id` parameters.
 785   *
 786   * @param array|string $args {
 787   *     Array of arguments. Supports all arguments of
 788   *     {@link BP_Groups_Group::get()}. Where the default values differ, they
 789   *     have been described here.
 790   *     @type int $per_page Default: 20.
 791   *     @type int $page Default: 1.
 792   * }
 793   * @return array See {@link BP_Groups_Group::get()}.
 794   */
 795  function groups_get_groups( $args = '' ) {
 796  
 797      $defaults = array(
 798          'type'               => false,          // Active, newest, alphabetical, random, popular.
 799          'order'              => 'DESC',         // 'ASC' or 'DESC'
 800          'orderby'            => 'date_created', // date_created, last_activity, total_member_count, name, random, meta_id.
 801          'user_id'            => false,          // Pass a user_id to limit to only groups that this user is a member of.
 802          'include'            => false,          // Only include these specific groups (group_ids).
 803          'exclude'            => false,          // Do not include these specific groups (group_ids).
 804          'parent_id'          => null,           // Get groups that are children of the specified group(s).
 805          'slug'               => array(),        // Find a group or groups by slug.
 806          'search_terms'       => false,          // Limit to groups that match these search terms.
 807          'search_columns'     => array(),        // Select which columns to search.
 808          'group_type'         => '',             // Array or comma-separated list of group types to limit results to.
 809          'group_type__in'     => '',             // Array or comma-separated list of group types to limit results to.
 810          'group_type__not_in' => '',             // Array or comma-separated list of group types that will be excluded from results.
 811          'meta_query'         => false,          // Filter by groupmeta. See WP_Meta_Query for syntax.
 812          'show_hidden'        => false,          // Show hidden groups to non-admins.
 813          'status'             => array(),        // Array or comma-separated list of group statuses to limit results to.
 814          'per_page'           => 20,             // The number of results to return per page.
 815          'page'               => 1,              // The page to return if limiting per page.
 816          'update_meta_cache'  => true,           // Pre-fetch groupmeta for queried groups.
 817          'update_admin_cache' => false,
 818          'fields'             => 'all',          // Return BP_Groups_Group objects or a list of ids.
 819      );
 820  
 821      $r = bp_parse_args( $args, $defaults, 'groups_get_groups' );
 822  
 823      $groups = BP_Groups_Group::get( array(
 824          'type'               => $r['type'],
 825          'user_id'            => $r['user_id'],
 826          'include'            => $r['include'],
 827          'exclude'            => $r['exclude'],
 828          'slug'               => $r['slug'],
 829          'parent_id'          => $r['parent_id'],
 830          'search_terms'       => $r['search_terms'],
 831          'search_columns'     => $r['search_columns'],
 832          'group_type'         => $r['group_type'],
 833          'group_type__in'     => $r['group_type__in'],
 834          'group_type__not_in' => $r['group_type__not_in'],
 835          'meta_query'         => $r['meta_query'],
 836          'show_hidden'        => $r['show_hidden'],
 837          'status'             => $r['status'],
 838          'per_page'           => $r['per_page'],
 839          'page'               => $r['page'],
 840          'update_meta_cache'  => $r['update_meta_cache'],
 841          'update_admin_cache' => $r['update_admin_cache'],
 842          'order'              => $r['order'],
 843          'orderby'            => $r['orderby'],
 844          'fields'             => $r['fields'],
 845      ) );
 846  
 847      /**
 848       * Filters the collection of groups based on parsed parameters.
 849       *
 850       * @since 1.2.0
 851       *
 852       * @param BP_Groups_Group $groups Object of found groups based on parameters.
 853       *                                Passed by reference.
 854       * @param array           $r      Array of parsed arguments used for group query.
 855       *                                Passed by reference.
 856       */
 857      return apply_filters_ref_array( 'groups_get_groups', array( &$groups, &$r ) );
 858  }
 859  
 860  /**
 861   * Get the total group count for the site.
 862   *
 863   * @since 1.2.0
 864   *
 865   * @return int
 866   */
 867  function groups_get_total_group_count() {
 868      $count = wp_cache_get( 'bp_total_group_count', 'bp' );
 869  
 870      if ( false === $count ) {
 871          $count = BP_Groups_Group::get_total_group_count();
 872          wp_cache_set( 'bp_total_group_count', $count, 'bp' );
 873      }
 874  
 875      return $count;
 876  }
 877  
 878  /**
 879   * Get the IDs of the groups of which a specified user is a member.
 880   *
 881   * @since 1.0.0
 882   *
 883   * @param int $user_id  ID of the user.
 884   * @param int $pag_num  Optional. Max number of results to return.
 885   *                      Default: false (no limit).
 886   * @param int $pag_page Optional. Page offset of results to return.
 887   *                      Default: false (no limit).
 888   * @return array {
 889   *     @type array $groups Array of groups returned by paginated query.
 890   *     @type int   $total Count of groups matching query.
 891   * }
 892   */
 893  function groups_get_user_groups( $user_id = 0, $pag_num = 0, $pag_page = 0 ) {
 894  
 895      if ( empty( $user_id ) )
 896          $user_id = bp_displayed_user_id();
 897  
 898      return BP_Groups_Member::get_group_ids( $user_id, $pag_num, $pag_page );
 899  }
 900  
 901  /**
 902   * Get a list of groups of which the specified user is a member.
 903   *
 904   * Get a list of the groups to which this member belongs,
 905   * filtered by group membership status and role.
 906   * Usage examples: Used with no arguments specified,
 907   *
 908   *    bp_get_user_groups( bp_loggedin_user_id() );
 909   *
 910   * returns an array of the groups in which the logged-in user
 911   * is an unpromoted member. To fetch an array of all groups that
 912   * the current user belongs to, in any membership role,
 913   * member, moderator or administrator, use
 914   *
 915   *    bp_get_user_groups( $user_id, array(
 916   *        'is_admin' => null,
 917   *        'is_mod' => null,
 918   *    ) );
 919   *
 920   * @since 2.6.0
 921   *
 922   * @param int $user_id ID of the user.
 923   * @param array $args {
 924   *     Array of optional args.
 925   *     @param bool|null   $is_confirmed Whether to return only confirmed memberships. Pass `null` to disable this
 926   *                                      filter. Default: true.
 927   *     @param bool|null   $is_banned    Whether to return only banned memberships. Pass `null` to disable this filter.
 928   *                                      Default: false.
 929   *     @param bool|null   $is_admin     Whether to return only admin memberships. Pass `null` to disable this filter.
 930   *                                      Default: false.
 931   *     @param bool|null   $is_mod       Whether to return only mod memberships. Pass `null` to disable this filter.
 932   *                                      Default: false.
 933   *     @param bool|null   $invite_sent  Whether to return only memberships with 'invite_sent'. Pass `null` to disable
 934   *                                      this filter. Default: false.
 935   *     @param string      $orderby      Field to order by. Accepts 'id' (membership ID), 'group_id', 'date_modified'.
 936   *                                      Default: 'group_id'.
 937   *     @param string      $order        Sort order. Accepts 'ASC' or 'DESC'. Default: 'ASC'.
 938   * }
 939   * @return array Array of matching group memberships, keyed by group ID.
 940   */
 941  function bp_get_user_groups( $user_id, $args = array() ) {
 942      $r = bp_parse_args( $args, array(
 943          'is_confirmed' => true,
 944          'is_banned'    => false,
 945          'is_admin'     => false,
 946          'is_mod'       => false,
 947          'invite_sent'  => null,
 948          'orderby'      => 'group_id',
 949          'order'        => 'ASC',
 950      ), 'get_user_groups' );
 951  
 952      $user_id = intval( $user_id );
 953  
 954      // Standard memberships
 955      $membership_ids = wp_cache_get( $user_id, 'bp_groups_memberships_for_user' );
 956      if ( false === $membership_ids ) {
 957          $membership_ids = BP_Groups_Member::get_membership_ids_for_user( $user_id );
 958          wp_cache_set( $user_id, $membership_ids, 'bp_groups_memberships_for_user' );
 959      }
 960  
 961      // Prime the membership cache.
 962      $uncached_membership_ids = bp_get_non_cached_ids( $membership_ids, 'bp_groups_memberships' );
 963      if ( ! empty( $uncached_membership_ids ) ) {
 964          $uncached_memberships = BP_Groups_Member::get_memberships_by_id( $uncached_membership_ids );
 965  
 966          foreach ( $uncached_memberships as $uncached_membership ) {
 967              wp_cache_set( $uncached_membership->id, $uncached_membership, 'bp_groups_memberships' );
 968          }
 969      }
 970  
 971      // Prime the invitations- and requests-as-memberships cache
 972      $invitation_ids = array();
 973      if ( true !== $r['is_confirmed'] || false !== $r['invite_sent'] ) {
 974          $invitation_ids = groups_get_invites( array(
 975              'user_id'     => $user_id,
 976              'invite_sent' => 'all',
 977              'type'        => 'all',
 978              'fields'      => 'ids'
 979          ) );
 980  
 981          // Prime the invitations cache.
 982          $uncached_invitation_ids = bp_get_non_cached_ids( $invitation_ids, 'bp_groups_invitations_as_memberships' );
 983          if ( $uncached_invitation_ids ) {
 984              $uncached_invitations = groups_get_invites( array(
 985                  'id'          => $uncached_invitation_ids,
 986                  'invite_sent' => 'all',
 987                  'type'        => 'all'
 988              ) );
 989              foreach ( $uncached_invitations as $uncached_invitation ) {
 990                  // Reshape the result as a membership db entry.
 991                  $invitation = new StdClass;
 992                  $invitation->id            = $uncached_invitation->id;
 993                  $invitation->group_id      = $uncached_invitation->item_id;
 994                  $invitation->user_id       = $uncached_invitation->user_id;
 995                  $invitation->inviter_id    = $uncached_invitation->inviter_id;
 996                  $invitation->is_admin      = false;
 997                  $invitation->is_mod        = false;
 998                  $invitation->user_title    = '';
 999                  $invitation->date_modified = $uncached_invitation->date_modified;
1000                  $invitation->comments      = $uncached_invitation->content;
1001                  $invitation->is_confirmed  = false;
1002                  $invitation->is_banned     = false;
1003                  $invitation->invite_sent   = $uncached_invitation->invite_sent;
1004                  wp_cache_set( $uncached_invitation->id, $invitation, 'bp_groups_invitations_as_memberships' );
1005              }
1006          }
1007      }
1008  
1009      // Assemble filter array for use in `wp_list_filter()`.
1010      $filters = wp_array_slice_assoc( $r, array( 'is_confirmed', 'is_banned', 'is_admin', 'is_mod', 'invite_sent' ) );
1011      foreach ( $filters as $filter_name => $filter_value ) {
1012          if ( is_null( $filter_value ) ) {
1013              unset( $filters[ $filter_name ] );
1014          }
1015      }
1016  
1017      // Populate group membership array from cache, and normalize.
1018      $groups    = array();
1019      $int_keys  = array( 'id', 'group_id', 'user_id', 'inviter_id' );
1020      $bool_keys = array( 'is_admin', 'is_mod', 'is_confirmed', 'is_banned', 'invite_sent' );
1021      foreach ( $membership_ids as $membership_id ) {
1022          $membership = wp_cache_get( $membership_id, 'bp_groups_memberships' );
1023  
1024          // Sanity check.
1025          if ( ! isset( $membership->group_id ) ) {
1026              continue;
1027          }
1028  
1029          // Integer values.
1030          foreach ( $int_keys as $index ) {
1031              $membership->{$index} = intval( $membership->{$index} );
1032          }
1033  
1034          // Boolean values.
1035          foreach ( $bool_keys as $index ) {
1036              $membership->{$index} = (bool) $membership->{$index};
1037          }
1038  
1039          foreach ( $filters as $filter_name => $filter_value ) {
1040              if ( ! isset( $membership->{$filter_name} ) || $filter_value != $membership->{$filter_name} ) {
1041                  continue 2;
1042              }
1043          }
1044  
1045          $group_id = (int) $membership->group_id;
1046  
1047          $groups[ $group_id ] = $membership;
1048      }
1049  
1050      // Populate group invitations array from cache, and normalize.
1051      foreach ( $invitation_ids as $invitation_id ) {
1052          $invitation = wp_cache_get( $invitation_id, 'bp_groups_invitations_as_memberships' );
1053  
1054          // Sanity check.
1055          if ( ! isset( $invitation->group_id ) ) {
1056              continue;
1057          }
1058  
1059          // Integer values.
1060          foreach ( $int_keys as $index ) {
1061              $invitation->{$index} = intval( $invitation->{$index} );
1062          }
1063  
1064          // Boolean values.
1065          foreach ( $bool_keys as $index ) {
1066              $invitation->{$index} = (bool) $invitation->{$index};
1067          }
1068  
1069          foreach ( $filters as $filter_name => $filter_value ) {
1070              if ( ! isset( $invitation->{$filter_name} ) || $filter_value != $invitation->{$filter_name} ) {
1071                  continue 2;
1072              }
1073          }
1074  
1075          $group_id = (int) $invitation->group_id;
1076  
1077          $groups[ $group_id ] = $invitation;
1078      }
1079  
1080      // By default, results are ordered by membership id.
1081      if ( 'group_id' === $r['orderby'] ) {
1082          ksort( $groups );
1083      } elseif ( in_array( $r['orderby'], array( 'id', 'date_modified' ) ) ) {
1084          $groups = bp_sort_by_key( $groups, $r['orderby'] );
1085      }
1086  
1087      // By default, results are ordered ASC.
1088      if ( 'DESC' === strtoupper( $r['order'] ) ) {
1089          // `true` to preserve keys.
1090          $groups = array_reverse( $groups, true );
1091      }
1092  
1093      return $groups;
1094  }
1095  
1096  /**
1097   * Get the count of groups of which the specified user is a member.
1098   *
1099   * @since 1.0.0
1100   *
1101   * @param int $user_id Optional. Default: ID of the displayed user.
1102   * @return int Group count.
1103   */
1104  function groups_total_groups_for_user( $user_id = 0 ) {
1105  
1106      if ( empty( $user_id ) )
1107          $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
1108  
1109      $count = wp_cache_get( 'bp_total_groups_for_user_' . $user_id, 'bp' );
1110  
1111      if ( false === $count ) {
1112          $count = BP_Groups_Member::total_group_count( $user_id );
1113          wp_cache_set( 'bp_total_groups_for_user_' . $user_id, $count, 'bp' );
1114      }
1115  
1116      return (int) $count;
1117  }
1118  
1119  /**
1120   * Get the BP_Groups_Group object corresponding to the current group.
1121   *
1122   * @since 1.5.0
1123   *
1124   * @return BP_Groups_Group The current group object.
1125   */
1126  function groups_get_current_group() {
1127      $bp = buddypress();
1128  
1129      $current_group = isset( $bp->groups->current_group )
1130          ? $bp->groups->current_group
1131          : false;
1132  
1133      /**
1134       * Filters the BP_Groups_Group object corresponding to the current group.
1135       *
1136       * @since 1.5.0
1137       *
1138       * @param BP_Groups_Group $current_group Current BP_Groups_Group object.
1139       */
1140      return apply_filters( 'groups_get_current_group', $current_group );
1141  }
1142  
1143  /** Group Avatars *************************************************************/
1144  
1145  /**
1146   * Generate the avatar upload directory path for a given group.
1147   *
1148   * @since 1.1.0
1149   *
1150   * @param int $group_id Optional. ID of the group. Default: ID of the current group.
1151   * @return string
1152   */
1153  function groups_avatar_upload_dir( $group_id = 0 ) {
1154  
1155      if ( empty( $group_id ) ) {
1156          $group_id = bp_get_current_group_id();
1157      }
1158  
1159      $directory = 'group-avatars';
1160      $path      = bp_core_avatar_upload_path() . '/' . $directory . '/' . $group_id;
1161      $newbdir   = $path;
1162      $newurl    = bp_core_avatar_url() . '/' . $directory . '/' . $group_id;
1163      $newburl   = $newurl;
1164      $newsubdir = '/' . $directory . '/' . $group_id;
1165  
1166      /**
1167       * Filters the avatar upload directory path for a given group.
1168       *
1169       * @since 1.1.0
1170       *
1171       * @param array $value Array of parts related to the groups avatar upload directory.
1172       */
1173      return apply_filters( 'groups_avatar_upload_dir', array(
1174          'path'    => $path,
1175          'url'     => $newurl,
1176          'subdir'  => $newsubdir,
1177          'basedir' => $newbdir,
1178          'baseurl' => $newburl,
1179          'error'   => false
1180      ) );
1181  }
1182  
1183  /** Group Member Status Checks ************************************************/
1184  
1185  /**
1186   * Get the Group roles.
1187   *
1188   * @since 5.0.0
1189   *
1190   * @return array The list of Group role objects.
1191   */
1192  function bp_groups_get_group_roles() {
1193      return array(
1194          'admin' => (object) array(
1195              'id'           => 'admin',
1196              'name'         => __( 'Administrator', 'buddypress' ),
1197              'is_admin'     => true,
1198              'is_banned'    => false,
1199              'is_confirmed' => true,
1200              'is_mod'       => false,
1201          ),
1202          'mod' => (object) array(
1203              'id'           => 'mod',
1204              'name'         => __( 'Moderator', 'buddypress' ),
1205              'is_admin'     => false,
1206              'is_banned'    => false,
1207              'is_confirmed' => true,
1208              'is_mod'       => true,
1209          ),
1210          'member' => (object) array(
1211              'id'           => 'member',
1212              'name'         => __( 'Member', 'buddypress' ),
1213              'is_admin'     => false,
1214              'is_banned'    => false,
1215              'is_confirmed' => true,
1216              'is_mod'       => false,
1217          ),
1218          'banned' => (object) array(
1219              'id'           => 'banned',
1220              'name'         => __( 'Banned', 'buddypress' ),
1221              'is_admin'     => false,
1222              'is_banned'    => true,
1223              'is_confirmed' => true,
1224              'is_mod'       => false,
1225          ),
1226      );
1227  }
1228  
1229  /**
1230   * Check whether a user is an admin of a given group.
1231   *
1232   * @since 1.0.0
1233   *
1234   * @param int $user_id ID of the user.
1235   * @param int $group_id ID of the group.
1236   * @return int|bool ID of the membership if the user is admin, otherwise false.
1237   */
1238  function groups_is_user_admin( $user_id, $group_id ) {
1239      $is_admin = false;
1240  
1241      $user_groups = bp_get_user_groups( $user_id, array(
1242          'is_admin' => true,
1243      ) );
1244  
1245      if ( isset( $user_groups[ $group_id ] ) ) {
1246          $is_admin = $user_groups[ $group_id ]->id;
1247      }
1248  
1249      return $is_admin;
1250  }
1251  
1252  /**
1253   * Check whether a user is a mod of a given group.
1254   *
1255   * @since 1.0.0
1256   *
1257   * @param int $user_id ID of the user.
1258   * @param int $group_id ID of the group.
1259   * @return int|bool ID of the membership if the user is mod, otherwise false.
1260   */
1261  function groups_is_user_mod( $user_id, $group_id ) {
1262      $is_mod = false;
1263  
1264      $user_groups = bp_get_user_groups( $user_id, array(
1265          'is_mod' => true,
1266      ) );
1267  
1268      if ( isset( $user_groups[ $group_id ] ) ) {
1269          $is_mod = $user_groups[ $group_id ]->id;
1270      }
1271  
1272      return $is_mod;
1273  }
1274  
1275  /**
1276   * Check whether a user is a member of a given group.
1277   *
1278   * @since 1.0.0
1279   *
1280   * @param int $user_id ID of the user.
1281   * @param int $group_id ID of the group.
1282   * @return int|bool ID of the membership if the user is member, otherwise false.
1283   */
1284  function groups_is_user_member( $user_id, $group_id ) {
1285      $is_member = false;
1286  
1287      $user_groups = bp_get_user_groups( $user_id, array(
1288          'is_admin' => null,
1289          'is_mod' => null,
1290      ) );
1291  
1292      if ( isset( $user_groups[ $group_id ] ) ) {
1293          $is_member = $user_groups[ $group_id ]->id;
1294      }
1295  
1296      return $is_member;
1297  }
1298  
1299  /**
1300   * Check whether a user is banned from a given group.
1301   *
1302   * @since 1.0.0
1303   *
1304   * @param int $user_id  ID of the user.
1305   * @param int $group_id ID of the group.
1306   * @return int|bool ID of the membership if the user is banned, otherwise false.
1307   */
1308  function groups_is_user_banned( $user_id, $group_id ) {
1309      $is_banned = false;
1310  
1311      $user_groups = bp_get_user_groups( $user_id, array(
1312          'is_confirmed' => null,
1313          'is_banned' => true,
1314      ) );
1315  
1316      if ( isset( $user_groups[ $group_id ] ) ) {
1317          $is_banned = $user_groups[ $group_id ]->id;
1318      }
1319  
1320      return $is_banned;
1321  }
1322  
1323  /**
1324   * Check whether a user has an outstanding invitation to a group.
1325   *
1326   * @since 2.6.0
1327   * @since 5.0.0 Added $type parameter.
1328   *
1329   * @param int    $user_id  ID of the user.
1330   * @param int    $group_id ID of the group.
1331   * @param string $type     If 'sent', results are limited to those invitations
1332   *                         that have actually been sent (non-draft).
1333   *                         Possible values: 'sent', 'draft', or 'all' Default: 'sent'.
1334   * @return int|bool ID of the membership if the user is invited, otherwise false.
1335   */
1336  function groups_is_user_invited( $user_id, $group_id, $type = 'sent' ) {
1337      return groups_check_has_invite_from_user( $user_id, $group_id, false, $type );
1338  }
1339  
1340  /**
1341   * Check whether a user has a pending membership request for a group.
1342   *
1343   * @since 2.6.0
1344   *
1345   * @param int $user_id ID of the user.
1346   * @param int $group_id ID of the group.
1347   * @return int|bool ID of the membership if the user is pending, otherwise false.
1348   */
1349  function groups_is_user_pending( $user_id, $group_id ) {
1350      if ( empty( $user_id ) || empty( $group_id ) ) {
1351          return false;
1352      }
1353  
1354      $args = array(
1355          'user_id'     => $user_id,
1356          'item_id'     => $group_id,
1357      );
1358      $invites_class = new BP_Groups_Invitation_Manager();
1359  
1360      return $invites_class->request_exists( $args );
1361  }
1362  
1363  /**
1364   * Is the specified user the creator of the group?
1365   *
1366   * @since 1.2.6
1367   *
1368   * @param int $user_id ID of the user.
1369   * @param int $group_id ID of the group.
1370   * @return int|null
1371   */
1372  function groups_is_user_creator( $user_id, $group_id ) {
1373      return BP_Groups_Member::check_is_creator( $user_id, $group_id );
1374  }
1375  
1376  /** Group Invitations *********************************************************/
1377  
1378  /**
1379   * Get group objects for groups that a user is currently invited to.
1380   *
1381   * @since 1.0.0
1382   *
1383   * @param int               $user_id ID of the invited user.
1384   * @param int|bool          $limit   Limit to restrict to.
1385   * @param int|bool          $page    Optional. Page offset of results to return.
1386   * @param string|array|bool $exclude Array of comma-separated list of group IDs
1387   *                                   to exclude from results.
1388   * @return array {
1389   *     @type array $groups Array of groups returned by paginated query.
1390   *     @type int   $total  Count of groups matching query.
1391   * }
1392   */
1393  function groups_get_invites_for_user( $user_id = 0, $limit = false, $page = false, $exclude = false ) {
1394      if ( empty( $user_id ) ) {
1395          $user_id = bp_loggedin_user_id();
1396      }
1397  
1398      $group_ids = groups_get_invited_to_group_ids( $user_id );
1399  
1400      // Remove excluded groups.
1401      if ( $exclude ) {
1402          $group_ids = array_diff( $group_ids, wp_parse_id_list( $exclude ) );
1403      }
1404  
1405      // Avoid passing an empty array.
1406      if ( ! $group_ids ) {
1407          $group_ids = array( 0 );
1408      }
1409  
1410      // Get a filtered list of groups.
1411      $args = array(
1412          'include'     => $group_ids,
1413          'show_hidden' => true,
1414          'per_page'    => $limit,
1415          'page'        => $page,
1416      );
1417      $groups = groups_get_groups( $args );
1418  
1419      return array( 'groups' => $groups['groups'], 'total' => groups_get_invite_count_for_user( $user_id ) );
1420  }
1421  
1422  /**
1423   * Get the total group invite count for a user.
1424   *
1425   * @since 2.0.0
1426   *
1427   * @param int $user_id The user ID.
1428   * @return int
1429   */
1430  function groups_get_invite_count_for_user( $user_id = 0 ) {
1431      if ( empty( $user_id ) ) {
1432          $user_id = bp_loggedin_user_id();
1433      }
1434  
1435      return count( groups_get_invited_to_group_ids( $user_id ) );
1436  }
1437  
1438  /**
1439   * Get an array of group IDs to which a user is invited.
1440   *
1441   * @since 5.0.0
1442   *
1443   * @param int $user_id The user ID.
1444   *
1445   * @return array Array of group IDs.
1446   */
1447   function groups_get_invited_to_group_ids( $user_id = 0 ) {
1448      if ( empty( $user_id ) ) {
1449          $user_id = bp_loggedin_user_id();
1450      }
1451  
1452      $group_ids = groups_get_invites( array(
1453          'user_id'     => $user_id,
1454          'invite_sent' => 'sent',
1455          'fields'      => 'item_ids'
1456      ) );
1457  
1458      return array_unique( $group_ids );
1459  }
1460  
1461  /**
1462   * Invite a user to a group.
1463   *
1464   * @since 1.0.0
1465   *
1466   * @param array|string $args {
1467   *     Array of arguments.
1468   *     @type int    $user_id       ID of the user being invited.
1469   *     @type int    $group_id      ID of the group to which the user is being invited.
1470   *     @type int    $inviter_id    Optional. ID of the inviting user. Default:
1471   *                                 ID of the logged-in user.
1472   *     @type string $date_modified Optional. Modified date for the invitation.
1473   *                                 Default: current date/time.
1474   *     @type string $content       Optional. Message to invitee.
1475   *     @type bool   $send_invite   Optional. Whether the invitation should be
1476   *                                 sent now. Default: false.
1477   * }
1478   * @return bool True on success, false on failure.
1479   */
1480  function groups_invite_user( $args = '' ) {
1481  
1482      $r = bp_parse_args( $args, array(
1483          'user_id'       => false,
1484          'group_id'      => false,
1485          'inviter_id'    => bp_loggedin_user_id(),
1486          'date_modified' => bp_core_current_time(),
1487          'content'       => '',
1488          'send_invite'   => 0
1489      ), 'groups_invite_user' );
1490  
1491      $inv_args = array(
1492          'user_id'       => $r['user_id'],
1493          'item_id'       => $r['group_id'],
1494          'inviter_id'    => $r['inviter_id'],
1495          'date_modified' => $r['date_modified'],
1496          'content'       => $r['content'],
1497          'send_invite'   => $r['send_invite']
1498      );
1499  
1500      // Create the unsent invitataion.
1501      $invites_class = new BP_Groups_Invitation_Manager();
1502      $created       = $invites_class->add_invitation( $inv_args );
1503  
1504      /**
1505       * Fires after the creation of a new group invite.
1506       *
1507       * @since 1.0.0
1508       *
1509       * @param array    $r       Array of parsed arguments for the group invite.
1510       * @param int|bool $created The ID of the invitation or false if it couldn't be created.
1511       */
1512      do_action( 'groups_invite_user', $r, $created );
1513  
1514      return $created;
1515  }
1516  
1517  /**
1518   * Uninvite a user from a group.
1519   *
1520   * @since 1.0.0
1521   *
1522   * @param int $user_id  ID of the user.
1523   * @param int $group_id ID of the group.
1524   * @param int $inviter_id ID of the inviter.
1525   * @return bool True on success, false on failure.
1526   */
1527  function groups_uninvite_user( $user_id, $group_id, $inviter_id = false ) {
1528      if ( empty( $user_id ) || empty( $group_id ) ) {
1529          return false;
1530      }
1531  
1532      $invites_class = new BP_Groups_Invitation_Manager();
1533      $success       = $invites_class->delete( array(
1534          'user_id'    => $user_id,
1535          'item_id'    => $group_id,
1536          'inviter_id' => $inviter_id,
1537      ) );
1538  
1539      if ( $success ) {
1540          /**
1541           * Fires after uninviting a user from a group.
1542           *
1543           * @since 1.0.0
1544           * @since 2.7.0 Added $inviter_id parameter
1545           *
1546           * @param int $group_id    ID of the group being uninvited from.
1547           * @param int $user_id     ID of the user being uninvited.
1548           * @param int $inviter_id  ID of the inviter.
1549           */
1550          do_action( 'groups_uninvite_user', $group_id, $user_id, $inviter_id );
1551      }
1552  
1553      return $success;
1554  }
1555  
1556  /**
1557   * Process the acceptance of a group invitation.
1558   *
1559   * Returns true if a user is already a member of the group.
1560   *
1561   * @since 1.0.0
1562   *
1563   * @param int $user_id  ID of the user.
1564   * @param int $group_id ID of the group.
1565   * @return bool True when the user is a member of the group, otherwise false.
1566   */
1567  function groups_accept_invite( $user_id, $group_id ) {
1568      $invites_class = new BP_Groups_Invitation_Manager();
1569      $args = array(
1570          'user_id'     => $user_id,
1571          'item_id'     => $group_id,
1572          'invite_sent' => 'sent',
1573      );
1574  
1575      return $invites_class->accept_invitation( $args );
1576  }
1577  
1578  /**
1579   * Reject a group invitation.
1580   *
1581   * @since 1.0.0
1582   * @since 5.0.0 The $inviter_id arg was added.
1583   *
1584   * @param int $user_id    ID of the user.
1585   * @param int $group_id   ID of the group.
1586   * @param int $inviter_id ID of the inviter.
1587   *
1588   * @return bool True on success, false on failure.
1589   */
1590  function groups_reject_invite( $user_id, $group_id, $inviter_id = false ) {
1591      if ( empty( $user_id ) || empty( $group_id ) ) {
1592          return false;
1593      }
1594  
1595      $invites_class = new BP_Groups_Invitation_Manager();
1596      $success       = $invites_class->delete( array(
1597          'user_id'    => $user_id,
1598          'item_id'    => $group_id,
1599          'inviter_id' => $inviter_id,
1600      ) );
1601  
1602      /**
1603       * Fires after a user rejects a group invitation.
1604       *
1605       * @since 1.0.0
1606       * @since 5.0.0 The $inviter_id arg was added.
1607       *
1608       * @param int $user_id    ID of the user rejecting the invite.
1609       * @param int $group_id   ID of the group being rejected.
1610       * @param int $inviter_id ID of the inviter.
1611       */
1612      do_action( 'groups_reject_invite', $user_id, $group_id, $inviter_id );
1613  
1614      return $success;
1615  }
1616  
1617  /**
1618   * Delete a group invitation.
1619   *
1620   * @since 1.0.0
1621   * @since 5.0.0 The $inviter_id arg was added.
1622   *
1623   * @param int $user_id  ID of the invited user.
1624   * @param int $group_id ID of the group.
1625   * @param int $inviter_id ID of the inviter.
1626   *
1627   * @return bool True on success, false on failure.
1628   */
1629  function groups_delete_invite( $user_id, $group_id, $inviter_id = false ) {
1630      if ( empty( $user_id ) || empty( $group_id ) ) {
1631          return false;
1632      }
1633  
1634      $invites_class = new BP_Groups_Invitation_Manager();
1635      $success       = $invites_class->delete( array(
1636          'user_id'    => $user_id,
1637          'item_id'    => $group_id,
1638          'inviter_id' => $inviter_id,
1639      ) );
1640  
1641      /**
1642       * Fires after the deletion of a group invitation.
1643       *
1644       * @since 1.9.0
1645       * @since 5.0.0 The $inviter_id arg was added.
1646       *
1647       * @param int $user_id  ID of the user whose invitation is being deleted.
1648       * @param int $group_id ID of the group whose invitation is being deleted.
1649       * @param int $inviter_id ID of the inviter.
1650       */
1651      do_action( 'groups_delete_invite', $user_id, $group_id, $inviter_id );
1652  
1653      return true;
1654  }
1655  
1656  /**
1657   * Send some or all pending invites by a single user to a specific group.
1658   *
1659   * @since 1.0.0
1660   * @since 5.0.0 Parameters changed to associative array.
1661   *
1662   * @param array $args {
1663   *     An array of optional arguments.
1664   *     @type int    $user_id       ID of the invited user.
1665   *     @type string $invitee_email Email address of the invited user, if not a member of the site.
1666   *     @type string $group_id      ID of the group or an array of group IDs.
1667   *     @type string $inviter_id    ID of the user extending the invitation.
1668   *     @type bool   $force_resend  Whether to resend the email & notification if one has already been sent.
1669   * }
1670   */
1671  function groups_send_invites( $args = array() ) {
1672      // Backward compatibility with old method of passing arguments.
1673      if ( ! is_array( $args ) || func_num_args() > 1 ) {
1674          _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__ ) );
1675  
1676          $old_args_keys = array(
1677              0 => 'inviter_id',
1678              1 => 'group_id',
1679          );
1680  
1681          $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
1682      }
1683  
1684      $r = bp_parse_args( $args, array(
1685          'user_id'       => false,
1686          'invitee_email' => '',
1687          'group_id'      => 0,
1688          'inviter_id'    => bp_loggedin_user_id(),
1689          'force_resend'  => false,
1690      ), 'groups_send_invitation' );
1691  
1692      /*
1693       * We will generally only want to fetch unsent invitations.
1694       * If force_resend is true, then we need to fetch both sent and draft invites.
1695       */
1696      if ( $r['force_resend'] ) {
1697          $args['invite_sent'] = 'all';
1698      } else {
1699          $args['invite_sent'] = 'draft';
1700      }
1701  
1702      $args = array(
1703          'user_id'       => $r['user_id'],
1704          'invitee_email' => $r['invitee_email'],
1705          'item_id'       => $r['group_id'],
1706          'inviter_id'    => $r['inviter_id'],
1707      );
1708      $invites = groups_get_invites( $args );
1709  
1710      $invited_users = array();
1711  
1712      $invites_class = new BP_Groups_Invitation_Manager();
1713      foreach ( $invites as $invite ) {
1714          $invited_users[] = $invite->user_id;
1715          $invites_class->send_invitation_by_id( $invite->id );
1716      }
1717  
1718      /**
1719       * Fires after the sending of invites for a group.
1720       *
1721       * @since 1.0.0
1722       * @since 2.5.0 Added $user_id to passed parameters.
1723       *
1724       * @param int   $group_id      ID of the group who's being invited to.
1725       * @param array $invited_users Array of users being invited to the group.
1726       * @param int   $user_id       ID of the inviting user.
1727       */
1728      do_action( 'groups_send_invites', $r['group_id'], $invited_users, $r['inviter_id'] );
1729  }
1730  
1731  /**
1732   * Get IDs of users with outstanding invites to a given group.
1733   *
1734   * @since 1.0.0
1735   * @since 2.9.0 Added $sent as a parameter.
1736   *
1737   * @param  int      $user_id  ID of the inviting user.
1738   * @param  int      $group_id ID of the group.
1739   * @param  int|null $sent     Query for a specific invite sent status. If 0, this will query for users
1740   *                            that haven't had an invite sent to them yet. If 1, this will query for
1741   *                            users that have had an invite sent to them. If null, no invite status will
1742   *                            queried. Default: null.
1743   * @return array    IDs of users who have been invited to the group by the user but have not
1744   *                  yet accepted.
1745   */
1746  function groups_get_invites_for_group( $user_id, $group_id, $sent = null ) {
1747      return BP_Groups_Group::get_invites( $user_id, $group_id, $sent );
1748  }
1749  
1750  /**
1751   * Get invitations to a given group filtered by arguments.
1752   *
1753   * @since 5.0.0
1754   *
1755   * @param int   $group_id ID of the group.
1756   * @param array $args     Invitation arguments.
1757   *                        See BP_Invitation::get() for list.
1758   *
1759   * @return array $invites     Matching BP_Invitation objects.
1760   */
1761  function groups_get_invites( $args = array() ) {
1762      $invites_class = new BP_Groups_Invitation_Manager();
1763      return $invites_class->get_invitations( $args );
1764  }
1765  
1766  /**
1767   * Check to see whether a user has already been invited to a group.
1768   *
1769   * By default, the function checks for invitations that have been sent.
1770   * Entering 'all' as the $type parameter will return unsent invitations as
1771   * well (useful to make sure AJAX requests are not duplicated).
1772   *
1773   * @since 1.0.0
1774   *
1775   * @param int    $user_id  ID of potential group member.
1776   * @param int    $group_id ID of potential group.
1777   * @param string $type     Optional. Use 'sent' to check for sent invites,
1778   *                         'all' to check for all. Default: 'sent'.
1779   * @return int|bool ID of the first found membership if found, otherwise false.
1780   */
1781  function groups_check_user_has_invite( $user_id, $group_id, $type = 'sent' ) {
1782      return groups_check_has_invite_from_user( $user_id, $group_id, false, $type );
1783  }
1784  
1785  /**
1786   * Check to see whether a user has already been invited to a group by a particular user.
1787   *
1788   * By default, the function checks for invitations that have been sent.
1789   * Entering 'all' as the $type parameter will return unsent invitations as
1790   * well (useful to make sure AJAX requests are not duplicated).
1791   *
1792   * @since 5.0.0
1793   *
1794   * @param int    $user_id    ID of potential group member.
1795   * @param int    $group_id   ID of potential group.
1796   * @param string $inviter_id Optional. Use 'sent' to check for sent invites,
1797   *                           'all' to check for all. Default: 'sent'.
1798   * @param string $type       Optional. Specify a user ID to limit to only invited from that user.
1799   *                           Default: 'false'.
1800   * @return int|bool ID of the first found membership if found, otherwise false.
1801   */
1802   function groups_check_has_invite_from_user( $user_id, $group_id, $inviter_id = false, $type = 'sent' ) {
1803      if ( empty( $user_id ) || empty( $group_id ) ) {
1804          return false;
1805      }
1806  
1807      $args = array(
1808          'user_id'     => $user_id,
1809          'item_id'     => $group_id,
1810          'invite_sent' => 'sent',
1811      );
1812      if ( $inviter_id ) {
1813          $args['inviter_id'] = $inviter_id;
1814      }
1815      if ( $type === 'draft' || $type === 'all' ) {
1816          $args['invite_sent'] = $type;
1817      }
1818  
1819      $invites_class = new BP_Groups_Invitation_Manager();
1820  
1821      return $invites_class->invitation_exists( $args );
1822  }
1823  
1824  /**
1825   * Delete all invitations to a given group.
1826   *
1827   * @since 1.0.0
1828   *
1829   * @param int $group_id ID of the group whose invitations are being deleted.
1830   * @return int|null Number of rows records deleted on success, null on failure.
1831   */
1832  function groups_delete_all_group_invites( $group_id ) {
1833      return BP_Groups_Group::delete_all_invites( $group_id );
1834  }
1835  
1836  /** Group Promotion & Banning *************************************************/
1837  
1838  /**
1839   * Promote a member to a new status within a group.
1840   *
1841   * @since 1.0.0
1842   *
1843   * @param int    $user_id  ID of the user.
1844   * @param int    $group_id ID of the group.
1845   * @param string $status   The new status. 'mod' or 'admin'.
1846   * @return bool True on success, false on failure.
1847   */
1848  function groups_promote_member( $user_id, $group_id, $status ) {
1849  
1850      if ( ! bp_is_item_admin() )
1851          return false;
1852  
1853      $member = new BP_Groups_Member( $user_id, $group_id );
1854  
1855      // Don't use this action. It's deprecated as of BuddyPress 1.6.
1856      do_action( 'groups_premote_member', $group_id, $user_id, $status );
1857  
1858      /**
1859       * Fires before the promotion of a user to a new status.
1860       *
1861       * @since 1.6.0
1862       *
1863       * @param int    $group_id ID of the group being promoted in.
1864       * @param int    $user_id  ID of the user being promoted.
1865       * @param string $status   New status being promoted to.
1866       */
1867      do_action( 'groups_promote_member', $group_id, $user_id, $status );
1868  
1869      return $member->promote( $status );
1870  }
1871  
1872  /**
1873   * Demote a user to 'member' status within a group.
1874   *
1875   * @since 1.0.0
1876   *
1877   * @param int $user_id  ID of the user.
1878   * @param int $group_id ID of the group.
1879   * @return bool True on success, false on failure.
1880   */
1881  function groups_demote_member( $user_id, $group_id ) {
1882  
1883      if ( ! bp_is_item_admin() )
1884          return false;
1885  
1886      $member = new BP_Groups_Member( $user_id, $group_id );
1887  
1888      /**
1889       * Fires before the demotion of a user to 'member'.
1890       *
1891       * @since 1.0.0
1892       *
1893       * @param int $group_id ID of the group being demoted in.
1894       * @param int $user_id  ID of the user being demoted.
1895       */
1896      do_action( 'groups_demote_member', $group_id, $user_id );
1897  
1898      return $member->demote();
1899  }
1900  
1901  /**
1902   * Ban a member from a group.
1903   *
1904   * @since 1.0.0
1905   *
1906   * @param int $user_id  ID of the user.
1907   * @param int $group_id ID of the group.
1908   * @return bool True on success, false on failure.
1909   */
1910  function groups_ban_member( $user_id, $group_id ) {
1911  
1912      if ( ! bp_is_item_admin() )
1913          return false;
1914  
1915      $member = new BP_Groups_Member( $user_id, $group_id );
1916  
1917      /**
1918       * Fires before the banning of a member from a group.
1919       *
1920       * @since 1.0.0
1921       *
1922       * @param int $group_id ID of the group being banned from.
1923       * @param int $user_id  ID of the user being banned.
1924       */
1925      do_action( 'groups_ban_member', $group_id, $user_id );
1926  
1927      return $member->ban();
1928  }
1929  
1930  /**
1931   * Unban a member from a group.
1932   *
1933   * @since 1.0.0
1934   *
1935   * @param int $user_id  ID of the user.
1936   * @param int $group_id ID of the group.
1937   * @return bool True on success, false on failure.
1938   */
1939  function groups_unban_member( $user_id, $group_id ) {
1940  
1941      if ( ! bp_is_item_admin() )
1942          return false;
1943  
1944      $member = new BP_Groups_Member( $user_id, $group_id );
1945  
1946      /**
1947       * Fires before the unbanning of a member from a group.
1948       *
1949       * @since 1.0.0
1950       *
1951       * @param int $group_id ID of the group being unbanned from.
1952       * @param int $user_id  ID of the user being unbanned.
1953       */
1954      do_action( 'groups_unban_member', $group_id, $user_id );
1955  
1956      return $member->unban();
1957  }
1958  
1959  /** Group Removal *************************************************************/
1960  
1961  /**
1962   * Remove a member from a group.
1963   *
1964   * @since 1.2.6
1965   *
1966   * @param int $user_id  ID of the user.
1967   * @param int $group_id ID of the group.
1968   * @return bool True on success, false on failure.
1969   */
1970  function groups_remove_member( $user_id, $group_id ) {
1971  
1972      if ( ! bp_is_item_admin() ) {
1973          return false;
1974      }
1975  
1976      $member = new BP_Groups_Member( $user_id, $group_id );
1977  
1978      /**
1979       * Fires before the removal of a member from a group.
1980       *
1981       * @since 1.2.6
1982       *
1983       * @param int $group_id ID of the group being removed from.
1984       * @param int $user_id  ID of the user being removed.
1985       */
1986      do_action( 'groups_remove_member', $group_id, $user_id );
1987  
1988      return $member->remove();
1989  }
1990  
1991  /** Group Membership **********************************************************/
1992  
1993  /**
1994   * Create a group membership request.
1995   *
1996   * @since 1.0.0
1997   *
1998   * @param array|string $args {
1999   *     Array of arguments.
2000   *     @type int    $user_id       ID of the user being invited.
2001   *     @type int    $group_id      ID of the group to which the user is being invited.
2002   *     @type string $content       Optional. Message to invitee.
2003   *     @type string $date_modified Optional. Modified date for the invitation.
2004   *                                 Default: current date/time.
2005   * }
2006   * @return bool True on success, false on failure.
2007   */
2008  function groups_send_membership_request( $args = array() ) {
2009      // Backward compatibility with old method of passing arguments.
2010      if ( ! is_array( $args ) || func_num_args() > 1 ) {
2011          _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__ ) );
2012  
2013          $old_args_keys = array(
2014              0 => 'user_id',
2015              1 => 'group_id',
2016          );
2017  
2018          $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
2019      }
2020  
2021      $r = bp_parse_args( $args, array(
2022          'user_id'       => false,
2023          'group_id'      => false,
2024          'content'       => '',
2025          'date_modified' => bp_core_current_time(),
2026      ), 'groups_send_membership_request' );
2027  
2028      $inv_args = array(
2029          'user_id'       => $r['user_id'],
2030          'item_id'       => $r['group_id'],
2031          'content'       => $r['content'],
2032          'date_modified' => $r['date_modified'],
2033      );
2034  
2035      $invites_class = new BP_Groups_Invitation_Manager();
2036      $request_id = $invites_class->add_request( $inv_args );
2037  
2038      // If a new request was created, send the emails.
2039      if ( $request_id && is_int( $request_id ) ) {
2040          $invites_class->send_request_notification_by_id( $request_id );
2041          $admins = groups_get_group_admins( $r['group_id'] );
2042  
2043          /**
2044           * Fires after the creation of a new membership request.
2045           *
2046           * @since 1.0.0
2047           *
2048           * @param int   $requesting_user_id  ID of the user requesting membership.
2049           * @param array $admins              Array of group admins.
2050           * @param int   $group_id            ID of the group being requested to.
2051           * @param int   $request_id          ID of the request.
2052           */
2053          do_action( 'groups_membership_requested', $r['user_id'], $admins, $r['group_id'], $request_id );
2054  
2055          return $request_id;
2056      }
2057  
2058      return false;
2059  }
2060  
2061  /**
2062   * Accept a pending group membership request.
2063   *
2064   * @since 1.0.0
2065   * @since 5.0.0 Deprecated $membership_id argument.
2066   *
2067   * @param int $membership_id Deprecated 5.0.0.
2068   * @param int $user_id       Required. ID of the user who requested membership.
2069   *                           Provide this value along with $group_id to override
2070   *                           $membership_id.
2071   * @param int $group_id      Required. ID of the group to which membership is being
2072   *                           requested. Provide this value along with $user_id to
2073   *                           override $membership_id.
2074   * @return bool True on success, false on failure.
2075   */
2076  function groups_accept_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
2077  
2078      if ( ! empty( $membership_id ) ) {
2079          _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__ ) );
2080      }
2081  
2082      if ( ! $user_id || ! $group_id ) {
2083          return false;
2084      }
2085  
2086      $invites_class = new BP_Groups_Invitation_Manager();
2087      $args = array(
2088          'user_id' => $user_id,
2089          'item_id' => $group_id,
2090      );
2091  
2092      return $invites_class->accept_request( $args );
2093  }
2094  
2095  /**
2096   * Reject a pending group membership request.
2097   *
2098   * @since 1.0.0
2099   *
2100   * @param int $membership_id Deprecated 5.0.0.
2101   * @param int $user_id       Optional. ID of the user who requested membership.
2102   *                           Provide this value along with $group_id to override
2103   *                           $membership_id.
2104   * @param int $group_id      Optional. ID of the group to which membership is being
2105   *                           requested. Provide this value along with $user_id to
2106   *                           override $membership_id.
2107   * @return bool True on success, false on failure.
2108   */
2109  function groups_reject_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
2110  
2111      if ( ! empty( $membership_id ) ){
2112          _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__ ) );
2113      }
2114  
2115      if ( ! groups_delete_membership_request( false, $user_id, $group_id ) ) {
2116          return false;
2117      }
2118  
2119      /**
2120       * Fires after a group membership request has been rejected.
2121       *
2122       * @since 1.0.0
2123       *
2124       * @param int  $user_id  ID of the user who rejected membership.
2125       * @param int  $group_id ID of the group that was rejected membership to.
2126       * @param bool $value    If membership was accepted.
2127       */
2128      do_action( 'groups_membership_rejected', $user_id, $group_id, false );
2129  
2130      return true;
2131  }
2132  
2133  /**
2134   * Delete a pending group membership request.
2135   *
2136   * @since 1.2.0
2137   *
2138   * @param int $membership_id Deprecated 5.0.0.
2139   * @param int $user_id       Optional. ID of the user who requested membership.
2140   *                           Provide this value along with $group_id to override
2141   *                           $membership_id.
2142   * @param int $group_id      Optional. ID of the group to which membership is being
2143   *                           requested. Provide this value along with $user_id to
2144   *                           override $membership_id.
2145   * @return false|BP_Groups_Member True on success, false on failure.
2146   */
2147  function groups_delete_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
2148      if ( ! empty( $membership_id ) ){
2149          _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__ ) );
2150      }
2151  
2152      if ( empty( $user_id ) || empty( $group_id ) ) {
2153          return false;
2154      }
2155  
2156      $invites_class = new BP_Groups_Invitation_Manager();
2157      $success       = $invites_class->delete_requests( array(
2158          'user_id' => $user_id,
2159          'item_id' => $group_id
2160      ) );
2161  
2162      return $success;
2163  }
2164  
2165  /**
2166   * Get group membership requests filtered by arguments.
2167   *
2168   * @since 5.0.0
2169   *
2170   * @param int   $group_id ID of the group.
2171   * @param array $args     Invitation arguments.
2172   *                        See BP_Invitation::get() for list.
2173   *
2174   * @return array $requests Matching BP_Invitation objects.
2175   */
2176  function groups_get_requests( $args = array() ) {
2177      $invites_class = new BP_Groups_Invitation_Manager();
2178      return $invites_class->get_requests( $args );
2179  }
2180  
2181  /**
2182   * Check whether a user has an outstanding membership request for a given group.
2183   *
2184   * @since 1.0.0
2185   *
2186   * @param int $user_id  ID of the user.
2187   * @param int $group_id ID of the group.
2188   * @return int|bool ID of the request if found, otherwise false.
2189   */
2190  function groups_check_for_membership_request( $user_id, $group_id ) {
2191      if ( empty( $user_id ) || empty( $group_id ) ) {
2192          return false;
2193      }
2194  
2195      $args = array(
2196          'user_id' => $user_id,
2197          'item_id' => $group_id,
2198      );
2199      $invites_class = new BP_Groups_Invitation_Manager();
2200  
2201      return $invites_class->request_exists( $args );
2202  }
2203  
2204   /**
2205    * Get an array of group IDs to which a user has requested membership.
2206    *
2207    * @since 5.0.0
2208    *
2209    * @param int $user_id The user ID.
2210    *
2211    * @return array Array of group IDs.
2212    */
2213   function groups_get_membership_requested_group_ids( $user_id = 0 ) {
2214      if ( ! $user_id ) {
2215          $user_id = bp_loggedin_user_id();
2216      }
2217  
2218      $group_ids     = groups_get_requests( array(
2219          'user_id' => $user_id,
2220          'fields'  => 'item_ids'
2221      ) );
2222  
2223      return $group_ids;
2224  }
2225  
2226   /**
2227    * Get an array of group IDs to which a user has requested membership.
2228    *
2229    * @since 5.0.0
2230    *
2231    * @param int $user_id The user ID.
2232    *
2233    * @return array Array of group IDs.
2234    */
2235   function groups_get_membership_requested_user_ids( $group_id = 0 ) {
2236      if ( ! $group_id ) {
2237          $group_id = bp_get_current_group_id();
2238      }
2239  
2240      $requests = groups_get_requests( array(
2241          'item_id' => $group_id,
2242          'fields'  => 'user_ids'
2243      ) );
2244  
2245      return $requests;
2246  }
2247  
2248  /**
2249   * Accept all pending membership requests to a group.
2250   *
2251   * @since 1.0.2
2252   *
2253   * @param int $group_id ID of the group.
2254   * @return bool True on success, false on failure.
2255   */
2256  function groups_accept_all_pending_membership_requests( $group_id = 0 ) {
2257      if ( ! $group_id ) {
2258          $group_id = bp_get_current_group_id();
2259      }
2260  
2261      $user_ids = groups_get_membership_requested_user_ids( $group_id );
2262  
2263      if ( ! $user_ids ) {
2264          return false;
2265      }
2266  
2267      foreach ( (array) $user_ids as $user_id ) {
2268          groups_accept_membership_request( false, $user_id, $group_id );
2269      }
2270  
2271      /**
2272       * Fires after the acceptance of all pending membership requests to a group.
2273       *
2274       * @since 1.0.2
2275       *
2276       * @param int $group_id ID of the group whose pending memberships were accepted.
2277       */
2278      do_action( 'groups_accept_all_pending_membership_requests', $group_id );
2279  
2280      return true;
2281  }
2282  
2283  /** Group Meta ****************************************************************/
2284  
2285  /**
2286   * Delete metadata for a group.
2287   *
2288   * @since 1.0.0
2289   *
2290   * @param int         $group_id   ID of the group.
2291   * @param string|bool $meta_key   The key of the row to delete.
2292   * @param string|bool $meta_value Optional. Metadata value. If specified, only delete
2293   *                                metadata entries with this value.
2294   * @param bool        $delete_all Optional. If true, delete matching metadata entries
2295   *                                for all groups. Otherwise, only delete matching
2296   *                                metadata entries for the specified group.
2297   *                                Default: false.
2298   * @return bool True on success, false on failure.
2299   */
2300  function groups_delete_groupmeta( $group_id, $meta_key = false, $meta_value = false, $delete_all = false ) {
2301      global $wpdb;
2302  
2303      // Legacy - if no meta_key is passed, delete all for the item.
2304      if ( empty( $meta_key ) ) {
2305          $table_name = buddypress()->groups->table_name_groupmeta;
2306          $sql        = "SELECT meta_key FROM {$table_name} WHERE group_id = %d";
2307          $query      = $wpdb->prepare( $sql, $group_id );
2308          $keys       = $wpdb->get_col( $query );
2309  
2310          // With no meta_key, ignore $delete_all.
2311          $delete_all = false;
2312      } else {
2313          $keys = array( $meta_key );
2314      }
2315  
2316      add_filter( 'query', 'bp_filter_metaid_column_name' );
2317  
2318      $retval = true;
2319      foreach ( $keys as $key ) {
2320          $retval = delete_metadata( 'group', $group_id, $key, $meta_value, $delete_all );
2321      }
2322  
2323      remove_filter( 'query', 'bp_filter_metaid_column_name' );
2324  
2325      return $retval;
2326  }
2327  
2328  /**
2329   * Get a piece of group metadata.
2330   *
2331   * @since 1.0.0
2332   *
2333   * @param int    $group_id ID of the group.
2334   * @param string $meta_key Metadata key.
2335   * @param bool   $single   Optional. If true, return only the first value of the
2336   *                         specified meta_key. This parameter has no effect if
2337   *                         meta_key is empty.
2338   * @return mixed Metadata value.
2339   */
2340  function groups_get_groupmeta( $group_id, $meta_key = '', $single = true ) {
2341      add_filter( 'query', 'bp_filter_metaid_column_name' );
2342      $retval = get_metadata( 'group', $group_id, $meta_key, $single );
2343      remove_filter( 'query', 'bp_filter_metaid_column_name' );
2344  
2345      return $retval;
2346  }
2347  
2348  /**
2349   * Update a piece of group metadata.
2350   *
2351   * @since 1.0.0
2352   *
2353   * @param int    $group_id   ID of the group.
2354   * @param string $meta_key   Metadata key.
2355   * @param mixed  $meta_value Value to store.
2356   * @param mixed  $prev_value Optional. If specified, only update existing
2357   *                           metadata entries with the specified value.
2358   *                           Otherwise, update all entries.
2359   * @return bool|int $retval Returns false on failure. On successful update of existing
2360   *                          metadata, returns true. On successful creation of new metadata,
2361   *                          returns the integer ID of the new metadata row.
2362   */
2363  function groups_update_groupmeta( $group_id, $meta_key, $meta_value, $prev_value = '' ) {
2364      add_filter( 'query', 'bp_filter_metaid_column_name' );
2365      $retval = update_metadata( 'group', $group_id, $meta_key, $meta_value, $prev_value );
2366      remove_filter( 'query', 'bp_filter_metaid_column_name' );
2367  
2368      return $retval;
2369  }
2370  
2371  /**
2372   * Add a piece of group metadata.
2373   *
2374   * @since 2.0.0
2375   *
2376   * @param int    $group_id   ID of the group.
2377   * @param string $meta_key   Metadata key.
2378   * @param mixed  $meta_value Metadata value.
2379   * @param bool   $unique     Optional. Whether to enforce a single metadata value
2380   *                           for the given key. If true, and the object already
2381   *                           has a value for the key, no change will be made.
2382   *                           Default: false.
2383   * @return int|bool The meta ID on successful update, false on failure.
2384   */
2385  function groups_add_groupmeta( $group_id, $meta_key, $meta_value, $unique = false ) {
2386      add_filter( 'query', 'bp_filter_metaid_column_name' );
2387      $retval = add_metadata( 'group', $group_id, $meta_key, $meta_value, $unique );
2388      remove_filter( 'query', 'bp_filter_metaid_column_name' );
2389  
2390      return $retval;
2391  }
2392  
2393  /** Group Cleanup Functions ***************************************************/
2394  
2395  /**
2396   * Delete all group membership information for the specified user.
2397   *
2398   * @since 1.0.0
2399   *
2400   * @param int $user_id ID of the user.
2401   */
2402  function groups_remove_data_for_user( $user_id ) {
2403      BP_Groups_Member::delete_all_for_user( $user_id );
2404  
2405      /**
2406       * Fires after the deletion of all data for a user.
2407       *
2408       * @since 1.1.0
2409       *
2410       * @param int $user_id ID of the user whose data is being deleted.
2411       */
2412      do_action( 'groups_remove_data_for_user', $user_id );
2413  }
2414  add_action( 'wpmu_delete_user',  'groups_remove_data_for_user' );
2415  add_action( 'delete_user',       'groups_remove_data_for_user' );
2416  add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
2417  
2418  /**
2419   * Update orphaned child groups when the parent is deleted.
2420   *
2421   * @since 2.7.0
2422   *
2423   * @param BP_Groups_Group $group Instance of the group item being deleted.
2424   */
2425  function bp_groups_update_orphaned_groups_on_group_delete( $group ) {
2426      // Get child groups and set the parent to the deleted parent's parent.
2427      $grandparent_group_id = $group->parent_id;
2428      $child_args = array(
2429          'parent_id'         => $group->id,
2430          'show_hidden'       => true,
2431          'per_page'          => false,
2432          'update_meta_cache' => false,
2433      );
2434      $children = groups_get_groups( $child_args );
2435      $children = $children['groups'];
2436  
2437      foreach ( $children as $cgroup ) {
2438          $cgroup->parent_id = $grandparent_group_id;
2439          $cgroup->save();
2440      }
2441  }
2442  add_action( 'bp_groups_delete_group', 'bp_groups_update_orphaned_groups_on_group_delete', 10, 2 );
2443  
2444  /** Group Types ***************************************************************/
2445  
2446  /**
2447   * Fire the 'bp_groups_register_group_types' action.
2448   *
2449   * @since 2.6.0
2450   */
2451  function bp_groups_register_group_types() {
2452      /**
2453       * Fires when it's appropriate to register group types.
2454       *
2455       * @since 2.6.0
2456       */
2457      do_action( 'bp_groups_register_group_types' );
2458  }
2459  add_action( 'bp_register_taxonomies', 'bp_groups_register_group_types' );
2460  
2461  /**
2462   * Register a group type.
2463   *
2464   * @since 2.6.0
2465   * @since 2.7.0 Introduce $has_directory, $show_in_create_screen, $show_in_list, and
2466   *              $description, $create_screen_checked as $args parameters.
2467   *
2468   * @param string $group_type Unique string identifier for the group type.
2469   * @param array  $args {
2470   *     Array of arguments describing the group type.
2471   *
2472   *     @type string|bool $has_directory         Set the slug to be used for custom group directory page. eg.
2473   *                                              example.com/groups/type/MY_SLUG. Default: false.
2474   *     @type bool        $show_in_create_screen Whether this group type is allowed to be selected on the group creation
2475   *                                              page. Default: false.
2476   *     @type bool|null   $show_in_list          Whether this group type should be shown in lists rendered by
2477   *                                              bp_group_type_list(). Default: null. If $show_in_create_screen is true,
2478   *                                              this will default to true, unless this is set explicitly to false.
2479   *     @type string      $description           A short descriptive summary of what the group type is. Currently shown
2480   *                                              on a group's "Manage > Settings" page when selecting group types.
2481   *     @type bool        $create_screen_checked If $show_in_create_screen is true, whether we should have our group type
2482   *                                              checkbox checked by default. Handy if you want to imply that the group
2483   *                                              type should be enforced, but decision lies with the group creator.
2484   *                                              Default: false.
2485   *     @type array       $labels {
2486   *         Array of labels to use in various parts of the interface.
2487   *
2488   *         @type string $name          Default name. Should typically be plural.
2489   *         @type string $singular_name Singular name.
2490   *     }
2491   * }
2492   * @return object|WP_Error Group type object on success, WP_Error object on failure.
2493   */
2494  function bp_groups_register_group_type( $group_type, $args = array() ) {
2495      $bp = buddypress();
2496  
2497      if ( isset( $bp->groups->types[ $group_type ] ) ) {
2498          return new WP_Error( 'bp_group_type_exists', __( 'Group type already exists.', 'buddypress' ), $group_type );
2499      }
2500  
2501      $r = bp_parse_args( $args, array(
2502          'has_directory'         => false,
2503          'show_in_create_screen' => false,
2504          'show_in_list'          => null,
2505          'description'           => '',
2506          'create_screen_checked' => false,
2507          'labels'                => array(),
2508      ), 'register_group_type' );
2509  
2510      $group_type = sanitize_key( $group_type );
2511  
2512      /**
2513       * Filters the list of illegal group type names.
2514       *
2515       * - 'any' is a special pseudo-type, representing items unassociated with any group type.
2516       * - 'null' is a special pseudo-type, representing users without any type.
2517       * - '_none' is used internally to denote an item that should not apply to any group types.
2518       *
2519       * @since 2.6.0
2520       *
2521       * @param array $illegal_names Array of illegal names.
2522       */
2523      $illegal_names = apply_filters( 'bp_group_type_illegal_names', array( 'any', 'null', '_none' ) );
2524      if ( in_array( $group_type, $illegal_names, true ) ) {
2525          return new WP_Error( 'bp_group_type_illegal_name', __( 'You may not register a group type with this name.', 'buddypress' ), $group_type );
2526      }
2527  
2528      // Store the group type name as data in the object (not just as the array key).
2529      $r['name'] = $group_type;
2530  
2531      // Make sure the relevant labels have been filled in.
2532      $default_name = isset( $r['labels']['name'] ) ? $r['labels']['name'] : ucfirst( $r['name'] );
2533      $r['labels'] = array_merge( array(
2534          'name'          => $default_name,
2535          'singular_name' => $default_name,
2536      ), $r['labels'] );
2537  
2538      // Directory slug.
2539      if ( ! empty( $r['has_directory'] ) ) {
2540          // A string value is intepreted as the directory slug.
2541          if ( is_string( $r['has_directory'] ) ) {
2542              $directory_slug = $r['has_directory'];
2543  
2544          // Otherwise fall back on group type.
2545          } else {
2546              $directory_slug = $group_type;
2547          }
2548  
2549          // Sanitize for use in URLs.
2550          $r['directory_slug'] = sanitize_title( $directory_slug );
2551          $r['has_directory']  = true;
2552      } else {
2553          $r['directory_slug'] = '';
2554          $r['has_directory']  = false;
2555      }
2556  
2557      // Type lists.
2558      if ( true === $r['show_in_create_screen'] && is_null( $r['show_in_list'] ) ) {
2559          $r['show_in_list'] = true;
2560      } else {
2561          $r['show_in_list'] = (bool) $r['show_in_list'];
2562      }
2563  
2564      $bp->groups->types[ $group_type ] = $type = (object) $r;
2565  
2566      /**
2567       * Fires after a group type is registered.
2568       *
2569       * @since 2.6.0
2570       *
2571       * @param string $group_type Group type identifier.
2572       * @param object $type       Group type object.
2573       */
2574      do_action( 'bp_groups_register_group_type', $group_type, $type );
2575  
2576      return $type;
2577  }
2578  
2579  /**
2580   * Get a list of all registered group type objects.
2581   *
2582   * @since 2.6.0
2583   *
2584   * @see bp_groups_register_group_type() for accepted arguments.
2585   *
2586   * @param array|string $args     Optional. An array of key => value arguments to match against
2587   *                               the group type objects. Default empty array.
2588   * @param string       $output   Optional. The type of output to return. Accepts 'names'
2589   *                               or 'objects'. Default 'names'.
2590   * @param string       $operator Optional. The logical operation to perform. 'or' means only one
2591   *                               element from the array needs to match; 'and' means all elements
2592   *                               must match. Accepts 'or' or 'and'. Default 'and'.
2593   * @return array       $types    A list of groups type names or objects.
2594   */
2595  function bp_groups_get_group_types( $args = array(), $output = 'names', $operator = 'and' ) {
2596      $types = buddypress()->groups->types;
2597  
2598      $types = wp_filter_object_list( $types, $args, $operator );
2599  
2600      /**
2601       * Filters the array of group type objects.
2602       *
2603       * This filter is run before the $output filter has been applied, so that
2604       * filtering functions have access to the entire group type objects.
2605       *
2606       * @since 2.6.0
2607       *
2608       * @param array  $types     group type objects, keyed by name.
2609       * @param array  $args      Array of key=>value arguments for filtering.
2610       * @param string $operator  'or' to match any of $args, 'and' to require all.
2611       */
2612      $types = apply_filters( 'bp_groups_get_group_types', $types, $args, $operator );
2613  
2614      if ( 'names' === $output ) {
2615          $types = wp_list_pluck( $types, 'name' );
2616      }
2617  
2618      return $types;
2619  }
2620  
2621  /**
2622   * Retrieve a group type object by name.
2623   *
2624   * @since 2.6.0
2625   *
2626   * @param string $group_type The name of the group type.
2627   * @return object A group type object.
2628   */
2629  function bp_groups_get_group_type_object( $group_type ) {
2630      $types = bp_groups_get_group_types( array(), 'objects' );
2631  
2632      if ( empty( $types[ $group_type ] ) ) {
2633          return null;
2634      }
2635  
2636      return $types[ $group_type ];
2637  }
2638  
2639  /**
2640   * Set type for a group.
2641   *
2642   * @since 2.6.0
2643   * @since 2.7.0 $group_type parameter also accepts an array of group types now.
2644   *
2645   * @param int          $group_id   ID of the group.
2646   * @param string|array $group_type Group type or array of group types to set.
2647   * @param bool         $append     Optional. True to append this to existing types for group,
2648   *                                 false to replace. Default: false.
2649   * @return false|array $retval See bp_set_object_terms().
2650   */
2651  function bp_groups_set_group_type( $group_id, $group_type, $append = false ) {
2652      // Pass an empty group type to remove group's type.
2653      if ( ! empty( $group_type ) && is_string( $group_type ) && ! bp_groups_get_group_type_object( $group_type ) ) {
2654          return false;
2655      }
2656  
2657      // Cast as array.
2658      $group_type = (array) $group_type;
2659  
2660      // Validate group types.
2661      foreach ( $group_type as $type ) {
2662          // Remove any invalid group types.
2663          if ( is_null( bp_groups_get_group_type_object( $type ) ) ) {
2664              unset( $group_type[ $type ] );
2665          }
2666      }
2667  
2668      $retval = bp_set_object_terms( $group_id, $group_type, 'bp_group_type', $append );
2669  
2670      // Bust the cache if the type has been updated.
2671      if ( ! is_wp_error( $retval ) ) {
2672          wp_cache_delete( $group_id, 'bp_groups_group_type' );
2673  
2674          /**
2675           * Fires just after a group type has been changed.
2676           *
2677           * @since 2.6.0
2678           *
2679           * @param int          $group_id   ID of the group whose group type has been updated.
2680           * @param string|array $group_type Group type or array of group types.
2681           * @param bool         $append     Whether the type is being appended to existing types.
2682           */
2683          do_action( 'bp_groups_set_group_type', $group_id, $group_type, $append );
2684      }
2685  
2686      return $retval;
2687  }
2688  
2689  /**
2690   * Get type for a group.
2691   *
2692   * @since 2.6.0
2693   *
2694   * @param int  $group_id ID of the group.
2695   * @param bool $single   Optional. Whether to return a single type string. If multiple types are found
2696   *                       for the group, the oldest one will be returned. Default: true.
2697   * @return string|array|bool On success, returns a single group type (if `$single` is true) or an array of group
2698   *                           types (if `$single` is false). Returns false on failure.
2699   */
2700  function bp_groups_get_group_type( $group_id, $single = true ) {
2701      $types = wp_cache_get( $group_id, 'bp_groups_group_type' );
2702  
2703      if ( false === $types ) {
2704          $raw_types = bp_get_object_terms( $group_id, 'bp_group_type' );
2705  
2706          if ( ! is_wp_error( $raw_types ) ) {
2707              $types = array();
2708  
2709              // Only include currently registered group types.
2710              foreach ( $raw_types as $gtype ) {
2711                  if ( bp_groups_get_group_type_object( $gtype->name ) ) {
2712                      $types[] = $gtype->name;
2713                  }
2714              }
2715  
2716              wp_cache_set( $group_id, $types, 'bp_groups_group_type' );
2717          }
2718      }
2719  
2720      $type = false;
2721      if ( ! empty( $types ) ) {
2722          if ( $single ) {
2723              $type = end( $types );
2724          } else {
2725              $type = $types;
2726          }
2727      }
2728  
2729      /**
2730       * Filters a groups's group type(s).
2731       *
2732       * @since 2.6.0
2733       *
2734       * @param string|array $type     Group type.
2735       * @param int          $group_id ID of the group.
2736       * @param bool         $single   Whether to return a single type string, or an array.
2737       */
2738      return apply_filters( 'bp_groups_get_group_type', $type, $group_id, $single );
2739  }
2740  
2741  /**
2742   * Remove type for a group.
2743   *
2744   * @since 2.6.0
2745   *
2746   * @param int            $group_id   ID of the user.
2747   * @param string         $group_type Group type.
2748   * @return bool|WP_Error $deleted    True on success. False or WP_Error on failure.
2749   */
2750  function bp_groups_remove_group_type( $group_id, $group_type ) {
2751      if ( empty( $group_type ) || ! bp_groups_get_group_type_object( $group_type ) ) {
2752          return false;
2753      }
2754  
2755      $deleted = bp_remove_object_terms( $group_id, $group_type, 'bp_group_type' );
2756  
2757      // Bust the case, if the type has been removed.
2758      if ( ! is_wp_error( $deleted ) ) {
2759          wp_cache_delete( $group_id, 'bp_groups_group_type' );
2760  
2761          /**
2762           * Fires just after a group's group type has been removed.
2763           *
2764           * @since 2.6.0
2765           *
2766           * @param int    $group      ID of the group whose group type has been removed.
2767           * @param string $group_type Group type.
2768           */
2769          do_action( 'bp_groups_remove_group_type', $group_id, $group_type );
2770      }
2771  
2772      return $deleted;
2773  }
2774  
2775  /**
2776   * Check whether the given group has a certain group type.
2777   *
2778   * @since 2.6.0
2779   *
2780   * @param  int    $group_id   ID of the group.
2781   * @param  string $group_type Group type.
2782   * @return bool   Whether the group has the give group type.
2783   */
2784  function bp_groups_has_group_type( $group_id, $group_type ) {
2785      if ( empty( $group_type ) || ! bp_groups_get_group_type_object( $group_type ) ) {
2786          return false;
2787      }
2788  
2789      // Get all group's group types.
2790      $types = bp_groups_get_group_type( $group_id, false );
2791  
2792      if ( ! is_array( $types ) ) {
2793          return false;
2794      }
2795  
2796      return in_array( $group_type, $types );
2797  }
2798  
2799  /**
2800   * Get the "current" group type, if one is provided, in group directories.
2801   *
2802   * @since 2.7.0
2803   *
2804   * @return string
2805   */
2806  function bp_get_current_group_directory_type() {
2807  
2808      /**
2809       * Filters the "current" group type, if one is provided, in group directories.
2810       *
2811       * @since 2.7.0
2812       *
2813       * @param string $value "Current" group type.
2814       */
2815      return apply_filters( 'bp_get_current_group_directory_type', buddypress()->groups->current_directory_type );
2816  }
2817  
2818  /**
2819   * Delete a group's type when the group is deleted.
2820   *
2821   * @since 2.6.0
2822   *
2823   * @param  int   $group_id ID of the group.
2824   * @return array|null $value    See {@see bp_groups_set_group_type()}.
2825   */
2826  function bp_remove_group_type_on_group_delete( $group_id = 0 ) {
2827      bp_groups_set_group_type( $group_id, '' );
2828  }
2829  add_action( 'groups_delete_group', 'bp_remove_group_type_on_group_delete' );
2830  
2831  /**
2832   * Finds and exports group membership data associated with an email address.
2833   *
2834   * @since 4.0.0
2835   *
2836   * @param string $email_address  The user's email address.
2837   * @param int    $page           Batch number.
2838   * @return array An array of personal data.
2839   */
2840  function bp_groups_memberships_personal_data_exporter( $email_address, $page ) {
2841      $number = 20;
2842  
2843      $email_address = trim( $email_address );
2844  
2845      $data_to_export = array();
2846  
2847      $user = get_user_by( 'email', $email_address );
2848  
2849      if ( ! $user ) {
2850          return array(
2851              'data' => array(),
2852              'done' => true,
2853          );
2854      }
2855  
2856      $memberships = BP_Groups_Member::get_user_memberships( $user->ID, array(
2857          'type'     => 'membership',
2858          'page'     => $page,
2859          'per_page' => $number,
2860      ) );
2861  
2862      foreach ( $memberships as $membership ) {
2863          $group = groups_get_group( $membership->group_id );
2864  
2865          $item_data = array(
2866              array(
2867                  'name'  => __( 'Group Name', 'buddypress' ),
2868                  'value' => bp_get_group_name( $group ),
2869              ),
2870              array(
2871                  'name'  => __( 'Group URL', 'buddypress' ),
2872                  'value' => bp_get_group_permalink( $group ),
2873              ),
2874          );
2875  
2876          if ( $membership->inviter_id ) {
2877              $item_data[] = array(
2878                  'name'  => __( 'Invited By', 'buddypress' ),
2879                  'value' => bp_core_get_userlink( $membership->inviter_id ),
2880              );
2881          }
2882  
2883          if ( $group->creator_id === $user->ID ) {
2884              $group_role = __( 'Creator', 'buddypress' );
2885          } elseif ( $membership->is_admin ) {
2886              $group_role = __( 'Admin', 'buddypress' );
2887          } elseif ( $membership->is_mod ) {
2888              $group_role = __( 'Moderator', 'buddypress' );
2889          } else {
2890              $group_role = __( 'Member', 'buddypress' );
2891          }
2892  
2893          $item_data[] = array(
2894              'name'  => __( 'Group Role', 'buddypress' ),
2895              'value' => $group_role,
2896          );
2897  
2898          $item_data[] = array(
2899              'name'  => __( 'Date Joined', 'buddypress' ),
2900              'value' => $membership->date_modified,
2901          );
2902  
2903          $data_to_export[] = array(
2904              'group_id'    => 'bp_groups_memberships',
2905              'group_label' => __( 'Group Memberships', 'buddypress' ),
2906              'item_id'     => "bp-group-membership-{$group->id}",
2907              'data'        => $item_data,
2908          );
2909      }
2910  
2911      // Tell core if we have more items to process.
2912      $done = count( $memberships ) < $number;
2913  
2914      return array(
2915          'data' => $data_to_export,
2916          'done' => $done,
2917      );
2918  }
2919  
2920  /**
2921   * Finds and exports data on pending group membership requests associated with an email address.
2922   *
2923   * @since 4.0.0
2924   *
2925   * @param string $email_address  The user's email address.
2926   * @param int    $page           Batch number.
2927   * @return array An array of personal data.
2928   */
2929  function bp_groups_pending_requests_personal_data_exporter( $email_address, $page ) {
2930      $number = 20;
2931  
2932      $email_address = trim( $email_address );
2933  
2934      $data_to_export = array();
2935  
2936      $user = get_user_by( 'email', $email_address );
2937  
2938      if ( ! $user ) {
2939          return array(
2940              'data' => array(),
2941              'done' => true,
2942          );
2943      }
2944  
2945      $requests = groups_get_requests( array(
2946          'user_id'  => $user->ID,
2947          'page'     => $page,
2948          'per_page' => $number,
2949      ) );
2950  
2951      foreach ( $requests as $request ) {
2952          $group = groups_get_group( $request->item_id );
2953  
2954          $item_data = array(
2955              array(
2956                  'name'  => __( 'Group Name', 'buddypress' ),
2957                  'value' => bp_get_group_name( $group ),
2958              ),
2959              array(
2960                  'name'  => __( 'Group URL', 'buddypress' ),
2961                  'value' => bp_get_group_permalink( $group ),
2962              ),
2963              array(
2964                  'name'  => __( 'Date Sent', 'buddypress' ),
2965                  'value' => $request->date_modified,
2966              ),
2967          );
2968  
2969          $data_to_export[] = array(
2970              'group_id'    => 'bp_groups_pending_requests',
2971              'group_label' => __( 'Pending Group Membership Requests', 'buddypress' ),
2972              'item_id'     => "bp-group-pending-request-{$group->id}",
2973              'data'        => $item_data,
2974          );
2975      }
2976  
2977      // Tell core if we have more items to process.
2978      $done = count( $requests ) < $number;
2979  
2980      return array(
2981          'data' => $data_to_export,
2982          'done' => $done,
2983      );
2984  }
2985  
2986  /**
2987   * Finds and exports data on pending group invitations sent by a user associated with an email address.
2988   *
2989   * @since 4.0.0
2990   *
2991   * @param string $email_address  The user's email address.
2992   * @param int    $page           Batch number.
2993   * @return array An array of personal data.
2994   */
2995  function bp_groups_pending_sent_invitations_personal_data_exporter( $email_address, $page ) {
2996      $number = 20;
2997  
2998      $email_address = trim( $email_address );
2999  
3000      $data_to_export = array();
3001  
3002      $user = get_user_by( 'email', $email_address );
3003  
3004      if ( ! $user ) {
3005          return array(
3006              'data' => array(),
3007              'done' => true,
3008          );
3009      }
3010  
3011      $invitations = groups_get_invites( array(
3012          'inviter_id'  => $user->ID,
3013          'page'        => $page,
3014          'per_page'    => $number,
3015      ) );
3016  
3017      foreach ( $invitations as $invitation ) {
3018          $group = groups_get_group( $invitation->item_id );
3019  
3020          $item_data = array(
3021              array(
3022                  'name'  => __( 'Group Name', 'buddypress' ),
3023                  'value' => bp_get_group_name( $group ),
3024              ),
3025              array(
3026                  'name'  => __( 'Group URL', 'buddypress' ),
3027                  'value' => bp_get_group_permalink( $group ),
3028              ),
3029              array(
3030                  'name'  => __( 'Sent To', 'buddypress' ),
3031                  'value' => bp_core_get_userlink( $invitation->user_id ),
3032              ),
3033              array(
3034                  'name'  => __( 'Date Sent', 'buddypress' ),
3035                  'value' => $invitation->date_modified,
3036              ),
3037          );
3038  
3039          $data_to_export[] = array(
3040              'group_id'    => 'bp_groups_pending_sent_invitations',
3041              'group_label' => __( 'Pending Group Invitations (Sent)', 'buddypress' ),
3042              'item_id'     => "bp-group-pending-sent-invitation-{$group->id}",
3043              'data'        => $item_data,
3044          );
3045      }
3046  
3047      // Tell core if we have more items to process.
3048      $done = count( $invitations ) < $number;
3049  
3050      return array(
3051          'data' => $data_to_export,
3052          'done' => $done,
3053      );
3054  }
3055  
3056  /**
3057   * Finds and exports data on pending group invitations received by a user associated with an email address.
3058   *
3059   * @since 4.0.0
3060   *
3061   * @param string $email_address  The user's email address.
3062   * @param int    $page           Batch number.
3063   * @return array An array of personal data.
3064   */
3065  function bp_groups_pending_received_invitations_personal_data_exporter( $email_address, $page ) {
3066      $number = 20;
3067  
3068      $email_address = trim( $email_address );
3069  
3070      $data_to_export = array();
3071  
3072      $user = get_user_by( 'email', $email_address );
3073  
3074      if ( ! $user ) {
3075          return array(
3076              'data' => array(),
3077              'done' => true,
3078          );
3079      }
3080  
3081      $invitations = groups_get_invites( array(
3082          'user_id'  => $user->ID,
3083          'page'     => $page,
3084          'per_page' => $number,
3085      ) );
3086  
3087      foreach ( $invitations as $invitation ) {
3088          $group = groups_get_group( $invitation->item_id );
3089  
3090          $item_data = array(
3091              array(
3092                  'name'  => __( 'Group Name', 'buddypress' ),
3093                  'value' => bp_get_group_name( $group ),
3094              ),
3095              array(
3096                  'name'  => __( 'Group URL', 'buddypress' ),
3097                  'value' => bp_get_group_permalink( $group ),
3098              ),
3099              array(
3100                  'name'  => __( 'Invited By', 'buddypress' ),
3101                  'value' => bp_core_get_userlink( $invitation->inviter_id ),
3102              ),
3103              array(
3104                  'name'  => __( 'Date Sent', 'buddypress' ),
3105                  'value' => $invitation->date_modified,
3106              ),
3107          );
3108  
3109          $data_to_export[] = array(
3110              'group_id'    => 'bp_groups_pending_received_invitations',
3111              'group_label' => __( 'Pending Group Invitations (Received)', 'buddypress' ),
3112              'item_id'     => "bp-group-pending-received-invitation-{$group->id}",
3113              'data'        => $item_data,
3114          );
3115      }
3116  
3117      // Tell core if we have more items to process.
3118      $done = count( $invitations ) < $number;
3119  
3120      return array(
3121          'data' => $data_to_export,
3122          'done' => $done,
3123      );
3124  }
3125  
3126  /**
3127   * Migrate invitations and requests from pre-5.0 group_members table to invitations table.
3128   *
3129   * @since 5.0.0
3130   */
3131  function bp_groups_migrate_invitations() {
3132      global $wpdb;
3133      $bp = buddypress();
3134  
3135      $records = $wpdb->get_results( "SELECT id, group_id, user_id, inviter_id, date_modified, comments, invite_sent FROM {$bp->groups->table_name_members} WHERE is_confirmed = 0 AND is_banned = 0" );
3136      if ( empty( $records ) ) {
3137          return;
3138      }
3139  
3140      $processed = array();
3141      $values = array();
3142      foreach ( $records as $record ) {
3143          $values[] = $wpdb->prepare(
3144              "(%d, %d, %s, %s, %d, %d, %s, %s, %s, %d, %d)",
3145              (int) $record->user_id,
3146              (int) $record->inviter_id,
3147              '',
3148              'bp_groups_invitation_manager',
3149              (int) $record->group_id,
3150              0,
3151              ( 0 === (int) $record->inviter_id ) ? 'request' : 'invite',
3152              $record->comments,
3153              $record->date_modified,
3154              (int) $record->invite_sent,
3155              0
3156          );
3157          $processed[] = (int) $record->id;
3158      }
3159  
3160      $table_name = BP_Invitation_Manager::get_table_name();
3161      $query = "INSERT INTO {$table_name} (user_id, inviter_id, invitee_email, class, item_id, secondary_item_id, type, content, date_modified, invite_sent, accepted) VALUES ";
3162      $query .= implode(', ', $values );
3163      $query .= ';';
3164      $wpdb->query( $query );
3165  
3166      $ids_to_delete = implode( ',', $processed );
3167      if ( $ids_to_delete ) {
3168          $wpdb->query( "DELETE FROM {$bp->groups->table_name_members} WHERE ID IN ($ids_to_delete)" );
3169      }
3170  }


Generated: Sun Nov 17 01:01:36 2019 Cross-referenced by PHPXref 0.7.1