[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

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

   1  <?php
   2  /**
   3   * BuddyPress Groups component admin screen.
   4   *
   5   * Props to WordPress core for the Comments admin screen, and its contextual
   6   * help text, on which this implementation is heavily based.
   7   *
   8   * @package BuddyPress
   9   * @subpackage Groups
  10   * @since 1.7.0
  11   */
  12  
  13  // Exit if accessed directly.
  14  defined( 'ABSPATH' ) || exit;
  15  
  16  // Include WP's list table class.
  17  if ( ! class_exists( 'WP_List_Table' ) ) {
  18      require ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
  19  }
  20  
  21  // The per_page screen option. Has to be hooked in extremely early.
  22  if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-groups' == $_REQUEST['page'] ) {
  23      add_filter( 'set-screen-option', 'bp_groups_admin_screen_options', 10, 3 );
  24  }
  25  
  26  /**
  27   * Register the Groups component admin screen.
  28   *
  29   * @since 1.7.0
  30   */
  31  function bp_groups_add_admin_menu() {
  32  
  33      // Add our screen.
  34      $hook = add_menu_page(
  35          _x( 'Groups', 'Admin Groups page title', 'buddypress' ),
  36          _x( 'Groups', 'Admin Groups menu', 'buddypress' ),
  37          'bp_moderate',
  38          'bp-groups',
  39          'bp_groups_admin',
  40          'div'
  41      );
  42  
  43      // Hook into early actions to load custom CSS and our init handler.
  44      add_action( "load-$hook", 'bp_groups_admin_load' );
  45  }
  46  add_action( bp_core_admin_hook(), 'bp_groups_add_admin_menu' );
  47  
  48  /**
  49   * Redirects the user on the Goups network admin screen when BuddyPress is network activated.
  50   *
  51   * @since 7.0.0
  52   */
  53  function bp_group_site_admin_network_admin_redirect() {
  54      wp_safe_redirect( add_query_arg( 'page', 'bp-groups', network_admin_url( 'admin.php' ) ) );
  55      exit();
  56  }
  57  
  58  /**
  59   * Create Groups submenu to manage BuddyPress types.
  60   *
  61   * @since 7.0.0
  62   */
  63  function bp_groups_admin_types_menu() {
  64      if ( ! bp_is_root_blog() ) {
  65          return;
  66      }
  67  
  68      if ( bp_is_network_activated() && is_network_admin() ) {
  69          // Adds a 'bp-groups' submenu to go to the root blog Group types screen.
  70          $group_type_admin_url = add_query_arg( 'taxonomy', 'bp_group_type', get_admin_url( bp_get_root_blog_id(), 'edit-tags.php' ) );
  71          add_submenu_page(
  72              'bp-groups',
  73              __( 'Group Types', 'buddypress' ),
  74              __( 'Group Types', 'buddypress' ),
  75              'bp_moderate',
  76              esc_url( $group_type_admin_url )
  77          );
  78      } elseif ( ! is_network_admin() ) {
  79          if ( bp_is_network_activated() ) {
  80              // Adds a 'bp-groups' menu to the root blog menu.
  81              $redirect_hook = add_menu_page(
  82                  _x( 'Groups', 'Admin Groups page title', 'buddypress' ),
  83                  _x( 'Groups', 'Admin Groups menu', 'buddypress' ),
  84                  'bp_moderate',
  85                  'bp-groups',
  86                  '__return_empty_string',
  87                  'div'
  88              );
  89  
  90              add_action( "load-{$redirect_hook}", 'bp_group_site_admin_network_admin_redirect' );
  91          }
  92  
  93          // Add the submenu to manage Group Types.
  94          add_submenu_page(
  95              'bp-groups',
  96              __( 'Group Types', 'buddypress' ),
  97              __( 'Group Types', 'buddypress' ),
  98              'bp_moderate',
  99              basename( add_query_arg( 'taxonomy', 'bp_group_type', bp_get_admin_url( 'edit-tags.php' ) ) )
 100          );
 101      }
 102  }
 103  add_action( 'bp_admin_menu', 'bp_groups_admin_types_menu' );
 104  
 105  /**
 106   * Add groups component to custom menus array.
 107   *
 108   * This ensures that the Groups menu item appears in the proper order on the
 109   * main Dashboard menu.
 110   *
 111   * @since 1.7.0
 112   *
 113   * @param array $custom_menus Array of BP top-level menu items.
 114   * @return array Menu item array, with Groups added.
 115   */
 116  function bp_groups_admin_menu_order( $custom_menus = array() ) {
 117      array_push( $custom_menus, 'bp-groups' );
 118      return $custom_menus;
 119  }
 120  add_filter( 'bp_admin_menu_order', 'bp_groups_admin_menu_order' );
 121  
 122  /**
 123   * Set up the Groups admin page.
 124   *
 125   * Loaded before the page is rendered, this function does all initial setup,
 126   * including: processing form requests, registering contextual help, and
 127   * setting up screen options.
 128   *
 129   * @since 1.7.0
 130   *
 131   * @global BP_Groups_List_Table $bp_groups_list_table Groups screen list table.
 132   */
 133  function bp_groups_admin_load() {
 134      global $bp_groups_list_table;
 135  
 136      // Build redirection URL.
 137      $redirect_to = remove_query_arg( array( 'action', 'action2', 'gid', 'deleted', 'error', 'updated', 'success_new', 'error_new', 'success_modified', 'error_modified' ), $_SERVER['REQUEST_URI'] );
 138  
 139      $doaction   = bp_admin_list_table_current_bulk_action();
 140      $min        = bp_core_get_minified_asset_suffix();
 141  
 142      /**
 143       * Fires at top of groups admin page.
 144       *
 145       * @since 1.7.0
 146       *
 147       * @param string $doaction Current $_GET action being performed in admin screen.
 148       */
 149      do_action( 'bp_groups_admin_load', $doaction );
 150  
 151      // Edit screen.
 152      if ( 'do_delete' == $doaction && ! empty( $_GET['gid'] ) ) {
 153  
 154          check_admin_referer( 'bp-groups-delete' );
 155  
 156          $group_ids = wp_parse_id_list( $_GET['gid'] );
 157  
 158          $count = 0;
 159          foreach ( $group_ids as $group_id ) {
 160              if ( groups_delete_group( $group_id ) ) {
 161                  $count++;
 162              }
 163          }
 164  
 165          $redirect_to = add_query_arg( 'deleted', $count, $redirect_to );
 166  
 167          bp_core_redirect( $redirect_to );
 168  
 169      } elseif ( 'edit' == $doaction && ! empty( $_GET['gid'] ) ) {
 170          // Columns screen option.
 171          add_screen_option( 'layout_columns', array( 'default' => 2, 'max' => 2, ) );
 172  
 173          get_current_screen()->add_help_tab( array(
 174              'id'      => 'bp-group-edit-overview',
 175              'title'   => __( 'Overview', 'buddypress' ),
 176              'content' =>
 177                  '<p>' . __( 'This page is a convenient way to edit the details associated with one of your groups.', 'buddypress' ) . '</p>' .
 178                  '<p>' . __( 'The Name and Description box is fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of each box. Use the Screen Options tab to hide or unhide, or to choose a 1- or 2-column layout for this screen.', 'buddypress' ) . '</p>'
 179          ) );
 180  
 181          // Help panel - sidebar links.
 182          get_current_screen()->set_help_sidebar(
 183              '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
 184              '<p><a href="https://buddypress.org/support">' . __( 'Support Forums', 'buddypress' ) . '</a></p>'
 185          );
 186  
 187          // Register metaboxes for the edit screen.
 188          add_meta_box( 'submitdiv', _x( 'Save', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_status', get_current_screen()->id, 'side', 'high' );
 189          add_meta_box( 'bp_group_settings', _x( 'Settings', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_settings', get_current_screen()->id, 'side', 'core' );
 190          add_meta_box( 'bp_group_add_members', _x( 'Add New Members', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_add_new_members', get_current_screen()->id, 'normal', 'core' );
 191          add_meta_box( 'bp_group_members', _x( 'Manage Members', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_members', get_current_screen()->id, 'normal', 'core' );
 192  
 193          // Group Type metabox. Only added if group types have been registered.
 194          $group_types = bp_groups_get_group_types();
 195          if ( ! empty( $group_types ) ) {
 196              add_meta_box(
 197                  'bp_groups_admin_group_type',
 198                  _x( 'Group Type', 'groups admin edit screen', 'buddypress' ),
 199                  'bp_groups_admin_edit_metabox_group_type',
 200                  get_current_screen()->id,
 201                  'side',
 202                  'core'
 203              );
 204          }
 205  
 206          /**
 207           * Fires after the registration of all of the default group meta boxes.
 208           *
 209           * @since 1.7.0
 210           */
 211          do_action( 'bp_groups_admin_meta_boxes' );
 212  
 213          // Enqueue JavaScript files.
 214          wp_enqueue_script( 'postbox' );
 215          wp_enqueue_script( 'dashboard' );
 216  
 217      // Index screen.
 218      } else {
 219          // Create the Groups screen list table.
 220          $bp_groups_list_table = new BP_Groups_List_Table();
 221  
 222          // The per_page screen option.
 223          add_screen_option( 'per_page', array( 'label' => _x( 'Groups', 'Groups per page (screen options)', 'buddypress' )) );
 224  
 225          // Help panel - overview text.
 226          get_current_screen()->add_help_tab( array(
 227              'id'      => 'bp-groups-overview',
 228              'title'   => __( 'Overview', 'buddypress' ),
 229              'content' =>
 230                  '<p>' . __( 'You can manage groups much like you can manage comments and other content. This screen is customizable in the same ways as other management screens, and you can act on groups by using the on-hover action links or the Bulk Actions.', 'buddypress' ) . '</p>',
 231          ) );
 232  
 233          get_current_screen()->add_help_tab( array(
 234              'id'      => 'bp-groups-overview-actions',
 235              'title'   => __( 'Group Actions', 'buddypress' ),
 236              'content' =>
 237                  '<p>' . __( 'Clicking "Visit" will take you to the group&#8217;s public page. Use this link to see what the group looks like on the front end of your site.', 'buddypress' ) . '</p>' .
 238                  '<p>' . __( 'Clicking "Edit" will take you to a Dashboard panel where you can manage various details about the group, such as its name and description, its members, and other settings.', 'buddypress' ) . '</p>' .
 239                  '<p>' . __( 'If you click "Delete" under a specific group, or select a number of groups and then choose Delete from the Bulk Actions menu, you will be led to a page where you&#8217;ll be asked to confirm the permanent deletion of the group(s).', 'buddypress' ) . '</p>',
 240          ) );
 241  
 242          // Help panel - sidebar links.
 243          get_current_screen()->set_help_sidebar(
 244              '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
 245              '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
 246          );
 247  
 248          // Add accessible hidden heading and text for Groups screen pagination.
 249          get_current_screen()->set_screen_reader_content( array(
 250              /* translators: accessibility text */
 251              'heading_pagination' => __( 'Groups list navigation', 'buddypress' ),
 252          ) );
 253      }
 254  
 255      $bp = buddypress();
 256  
 257      // Enqueue CSS and JavaScript.
 258      wp_enqueue_script( 'bp_groups_admin_js', $bp->plugin_url . "bp-groups/admin/js/admin{$min}.js", array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), bp_get_version(), true );
 259      wp_localize_script( 'bp_groups_admin_js', 'BP_Group_Admin', array(
 260          'add_member_placeholder' => __( 'Start typing a username to add a new member.', 'buddypress' ),
 261          'warn_on_leave'          => __( 'If you leave this page, you will lose any unsaved changes you have made to the group.', 'buddypress' ),
 262      ) );
 263      wp_enqueue_style( 'bp_groups_admin_css', $bp->plugin_url . "bp-groups/admin/css/admin{$min}.css", array(), bp_get_version() );
 264  
 265      wp_style_add_data( 'bp_groups_admin_css', 'rtl', 'replace' );
 266      if ( $min ) {
 267          wp_style_add_data( 'bp_groups_admin_css', 'suffix', $min );
 268      }
 269  
 270  
 271      if ( $doaction && 'save' == $doaction ) {
 272          // Get group ID.
 273          $group_id = isset( $_REQUEST['gid'] ) ? (int) $_REQUEST['gid'] : '';
 274  
 275          $redirect_to = add_query_arg( array(
 276              'gid'    => (int) $group_id,
 277              'action' => 'edit'
 278          ), $redirect_to );
 279  
 280          // Check this is a valid form submission.
 281          check_admin_referer( 'edit-group_' . $group_id );
 282  
 283          // Get the group from the database.
 284          $group = groups_get_group( $group_id );
 285  
 286          // If the group doesn't exist, just redirect back to the index.
 287          if ( empty( $group->slug ) ) {
 288              wp_redirect( $redirect_to );
 289              exit;
 290          }
 291  
 292          // Check the form for the updated properties.
 293          // Store errors.
 294          $error = 0;
 295          $success_new = $error_new = $success_modified = $error_modified = array();
 296  
 297          // Name, description and slug must not be empty.
 298          if ( empty( $_POST['bp-groups-name'] ) ) {
 299              $error = $error - 1;
 300          }
 301          if ( empty( $_POST['bp-groups-description'] ) ) {
 302              $error = $error - 2;
 303          }
 304          if ( empty( $_POST['bp-groups-slug'] ) ) {
 305              $error = $error - 4;
 306          }
 307  
 308          /*
 309           * Group name, slug, and description are handled with
 310           * groups_edit_base_group_details().
 311           */
 312          if ( ! $error && ! groups_edit_base_group_details( array(
 313                  'group_id'       => $group_id,
 314                  'name'           => $_POST['bp-groups-name'],
 315                  'slug'           => $_POST['bp-groups-slug'],
 316                  'description'    => $_POST['bp-groups-description'],
 317                  'notify_members' => false,
 318              ) ) ) {
 319              $error = $group_id;
 320          }
 321  
 322          // Enable discussion forum.
 323          $enable_forum   = ( isset( $_POST['group-show-forum'] ) ) ? 1 : 0;
 324  
 325          /**
 326           * Filters the allowed status values for the group.
 327           *
 328           * @since 1.0.2
 329           *
 330           * @param array $value Array of allowed group statuses.
 331           */
 332          $allowed_status = apply_filters( 'groups_allowed_status', array( 'public', 'private', 'hidden' ) );
 333          $status         = ( in_array( $_POST['group-status'], (array) $allowed_status ) ) ? $_POST['group-status'] : 'public';
 334  
 335          /**
 336           * Filters the allowed invite status values for the group.
 337           *
 338           * @since 1.5.0
 339           *
 340           * @param array $value Array of allowed invite statuses.
 341           */
 342          $allowed_invite_status = apply_filters( 'groups_allowed_invite_status', array( 'members', 'mods', 'admins' ) );
 343          $invite_status           = in_array( $_POST['group-invite-status'], (array) $allowed_invite_status ) ? $_POST['group-invite-status'] : 'members';
 344  
 345          if ( !groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status ) ) {
 346              $error = $group_id;
 347          }
 348  
 349          // Process new members.
 350          $user_names = array();
 351  
 352          if ( ! empty( $_POST['bp-groups-new-members'] ) ) {
 353              $user_names = array_merge( $user_names, explode( ',', $_POST['bp-groups-new-members'] ) );
 354          }
 355  
 356          if ( ! empty( $user_names ) ) {
 357  
 358              foreach( array_values( $user_names ) as $user_name ) {
 359                  $un = trim( $user_name );
 360  
 361                  // Make sure the user exists before attempting
 362                  // to add to the group.
 363                  $user = get_user_by( 'slug', $un );
 364  
 365                  if ( empty( $user ) ) {
 366                      $error_new[] = $un;
 367                  } else {
 368                      if ( ! groups_join_group( $group_id, $user->ID ) ) {
 369                          $error_new[]   = $un;
 370                      } else {
 371                          $success_new[] = $un;
 372                      }
 373                  }
 374              }
 375          }
 376  
 377          // Process member role changes.
 378          if ( ! empty( $_POST['bp-groups-role'] ) && ! empty( $_POST['bp-groups-existing-role'] ) ) {
 379  
 380              // Before processing anything, make sure you're not
 381              // attempting to remove the all user admins.
 382              $admin_count = 0;
 383              foreach ( (array) $_POST['bp-groups-role'] as $new_role ) {
 384                  if ( 'admin' == $new_role ) {
 385                      $admin_count++;
 386                      break;
 387                  }
 388              }
 389  
 390              if ( ! $admin_count ) {
 391  
 392                  $redirect_to = add_query_arg( 'no_admins', 1, $redirect_to );
 393                  $error = $group_id;
 394  
 395              } else {
 396  
 397                  // Process only those users who have had their roles changed.
 398                  foreach ( (array) $_POST['bp-groups-role'] as $user_id => $new_role ) {
 399                      $user_id = (int) $user_id;
 400  
 401                      $existing_role = isset( $_POST['bp-groups-existing-role'][$user_id] ) ? $_POST['bp-groups-existing-role'][$user_id] : '';
 402  
 403                      if ( $existing_role != $new_role ) {
 404                          $result = false;
 405  
 406                          switch ( $new_role ) {
 407                              case 'mod' :
 408                                  // Admin to mod is a demotion. Demote to
 409                                  // member, then fall through.
 410                                  if ( 'admin' == $existing_role ) {
 411                                      groups_demote_member( $user_id, $group_id );
 412                                  }
 413  
 414                              case 'admin' :
 415                                  // If the user was banned, we must
 416                                  // unban first.
 417                                  if ( 'banned' == $existing_role ) {
 418                                      groups_unban_member( $user_id, $group_id );
 419                                  }
 420  
 421                                  // At this point, each existing_role
 422                                  // is a member, so promote.
 423                                  $result = groups_promote_member( $user_id, $group_id, $new_role );
 424  
 425                                  break;
 426  
 427                              case 'member' :
 428  
 429                                  if ( 'admin' == $existing_role || 'mod' == $existing_role ) {
 430                                      $result = groups_demote_member( $user_id, $group_id );
 431                                  } elseif ( 'banned' == $existing_role ) {
 432                                      $result = groups_unban_member( $user_id, $group_id );
 433                                  }
 434  
 435                                  break;
 436  
 437                              case 'banned' :
 438  
 439                                  $result = groups_ban_member( $user_id, $group_id );
 440  
 441                                  break;
 442  
 443                              case 'remove' :
 444  
 445                                  $result = groups_remove_member( $user_id, $group_id );
 446  
 447                                  break;
 448                          }
 449  
 450                          // Store the success or failure.
 451                          if ( $result ) {
 452                              $success_modified[] = $user_id;
 453                          } else {
 454                              $error_modified[]   = $user_id;
 455                          }
 456                      }
 457                  }
 458              }
 459          }
 460  
 461          /**
 462           * Fires before redirect so plugins can do something first on save action.
 463           *
 464           * @since 1.6.0
 465           *
 466           * @param int $group_id ID of the group being edited.
 467           */
 468          do_action( 'bp_group_admin_edit_after', $group_id );
 469  
 470          // Create the redirect URL.
 471          if ( $error ) {
 472              // This means there was an error updating group details.
 473              $redirect_to = add_query_arg( 'error', (int) $error, $redirect_to );
 474          } else {
 475              // Group details were update successfully.
 476              $redirect_to = add_query_arg( 'updated', 1, $redirect_to );
 477          }
 478  
 479          if ( !empty( $success_new ) ) {
 480              $success_new = implode( ',', array_filter( $success_new, 'urlencode' ) );
 481              $redirect_to = add_query_arg( 'success_new', $success_new, $redirect_to );
 482          }
 483  
 484          if ( !empty( $error_new ) ) {
 485              $error_new = implode( ',', array_filter( $error_new, 'urlencode' ) );
 486              $redirect_to = add_query_arg( 'error_new', $error_new, $redirect_to );
 487          }
 488  
 489          if ( !empty( $success_modified ) ) {
 490              $success_modified = implode( ',', array_filter( $success_modified, 'urlencode' ) );
 491              $redirect_to = add_query_arg( 'success_modified', $success_modified, $redirect_to );
 492          }
 493  
 494          if ( !empty( $error_modified ) ) {
 495              $error_modified = implode( ',', array_filter( $error_modified, 'urlencode' ) );
 496              $redirect_to = add_query_arg( 'error_modified', $error_modified, $redirect_to );
 497          }
 498  
 499          /**
 500           * Filters the URL to redirect to after successfully editing a group.
 501           *
 502           * @since 1.7.0
 503           *
 504           * @param string $redirect_to URL to redirect user to.
 505           */
 506          wp_redirect( apply_filters( 'bp_group_admin_edit_redirect', $redirect_to ) );
 507          exit;
 508  
 509  
 510      // If a referrer and a nonce is supplied, but no action, redirect back.
 511      } elseif ( ! empty( $_GET['_wp_http_referer'] ) ) {
 512          wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
 513          exit;
 514      }
 515  }
 516  
 517  /**
 518   * Handle save/update of screen options for the Groups component admin screen.
 519   *
 520   * @since 1.7.0
 521   *
 522   * @param string $value     Will always be false unless another plugin filters it first.
 523   * @param string $option    Screen option name.
 524   * @param string $new_value Screen option form value.
 525   * @return string|int Option value. False to abandon update.
 526   */
 527  function bp_groups_admin_screen_options( $value, $option, $new_value ) {
 528      if ( 'toplevel_page_bp_groups_per_page' != $option && 'toplevel_page_bp_groups_network_per_page' != $option )
 529          return $value;
 530  
 531      // Per page.
 532      $new_value = (int) $new_value;
 533      if ( $new_value < 1 || $new_value > 999 )
 534          return $value;
 535  
 536      return $new_value;
 537  }
 538  
 539  /**
 540   * Select the appropriate Groups admin screen, and output it.
 541   *
 542   * @since 1.7.0
 543   */
 544  function bp_groups_admin() {
 545      // Decide whether to load the index or edit screen.
 546      $doaction = bp_admin_list_table_current_bulk_action();
 547  
 548      // Display the single group edit screen.
 549      if ( 'edit' == $doaction && ! empty( $_GET['gid'] ) ) {
 550          bp_groups_admin_edit();
 551  
 552      // Display the group deletion confirmation screen.
 553      } elseif ( 'delete' == $doaction && ! empty( $_GET['gid'] ) ) {
 554          bp_groups_admin_delete();
 555  
 556      // Otherwise, display the groups index screen.
 557      } else {
 558          bp_groups_admin_index();
 559      }
 560  }
 561  
 562  /**
 563   * Display the single groups edit screen.
 564   *
 565   * @since 1.7.0
 566   */
 567  function bp_groups_admin_edit() {
 568  
 569      if ( ! bp_current_user_can( 'bp_moderate' ) )
 570          die( '-1' );
 571  
 572      $messages = array();
 573  
 574      // If the user has just made a change to a group, build status messages.
 575      if ( !empty( $_REQUEST['no_admins'] ) || ! empty( $_REQUEST['error'] ) || ! empty( $_REQUEST['updated'] ) || ! empty( $_REQUEST['error_new'] ) || ! empty( $_REQUEST['success_new'] ) || ! empty( $_REQUEST['error_modified'] ) || ! empty( $_REQUEST['success_modified'] ) ) {
 576          $no_admins        = ! empty( $_REQUEST['no_admins']        ) ? 1                                             : 0;
 577          $errors           = ! empty( $_REQUEST['error']            ) ? $_REQUEST['error']                            : '';
 578          $updated          = ! empty( $_REQUEST['updated']          ) ? $_REQUEST['updated']                          : '';
 579          $error_new        = ! empty( $_REQUEST['error_new']        ) ? explode( ',', $_REQUEST['error_new'] )        : array();
 580          $success_new      = ! empty( $_REQUEST['success_new']      ) ? explode( ',', $_REQUEST['success_new'] )      : array();
 581          $error_modified   = ! empty( $_REQUEST['error_modified']   ) ? explode( ',', $_REQUEST['error_modified'] )   : array();
 582          $success_modified = ! empty( $_REQUEST['success_modified'] ) ? explode( ',', $_REQUEST['success_modified'] ) : array();
 583  
 584          if ( ! empty( $no_admins ) ) {
 585              $messages[] = __( 'You cannot remove all administrators from a group.', 'buddypress' );
 586          }
 587  
 588          if ( ! empty( $errors ) ) {
 589              if ( $errors < 0 ) {
 590                  $messages[] = __( 'Group name, slug, and description are all required fields.', 'buddypress' );
 591              } else {
 592                  $messages[] = __( 'An error occurred when trying to update your group details.', 'buddypress' );
 593              }
 594  
 595          } elseif ( ! empty( $updated ) ) {
 596              $messages[] = __( 'The group has been updated successfully.', 'buddypress' );
 597          }
 598  
 599          if ( ! empty( $error_new ) ) {
 600              /* translators: %s: comma separated list of usernames */
 601              $messages[] = sprintf( __( 'The following users could not be added to the group: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $error_new ) ) . '</em>' );
 602          }
 603  
 604          if ( ! empty( $success_new ) ) {
 605              /* translators: %s: comma separated list of usernames */
 606              $messages[] = sprintf( __( 'The following users were successfully added to the group: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $success_new ) ) . '</em>' );
 607          }
 608  
 609          if ( ! empty( $error_modified ) ) {
 610              $error_modified = bp_groups_admin_get_usernames_from_ids( $error_modified );
 611              /* translators: %s: comma separated list of usernames */
 612              $messages[] = sprintf( __( 'An error occurred when trying to modify the following members: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $error_modified ) ) . '</em>' );
 613          }
 614  
 615          if ( ! empty( $success_modified ) ) {
 616              $success_modified = bp_groups_admin_get_usernames_from_ids( $success_modified );
 617              /* translators: %s: comma separated list of usernames */
 618              $messages[] = sprintf( __( 'The following members were successfully modified: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $success_modified ) ) . '</em>' );
 619          }
 620      }
 621  
 622      $is_error = ! empty( $no_admins ) || ! empty( $errors ) || ! empty( $error_new ) || ! empty( $error_modified );
 623  
 624      // Get the group from the database.
 625      $group = groups_get_group( (int) $_GET['gid'] );
 626  
 627      $group_name = isset( $group->name ) ? bp_get_group_name( $group ) : '';
 628  
 629      // Construct URL for form.
 630      $form_url = remove_query_arg( array( 'action', 'deleted', 'no_admins', 'error', 'error_new', 'success_new', 'error_modified', 'success_modified' ), $_SERVER['REQUEST_URI'] );
 631      $form_url = add_query_arg( 'action', 'save', $form_url );
 632  
 633      /**
 634       * Fires before the display of the edit form.
 635       *
 636       * Useful for plugins to modify the group before display.
 637       *
 638       * @since 1.7.0
 639       *
 640       * @param BP_Groups_Group $this Instance of the current group being edited. Passed by reference.
 641       */
 642      do_action_ref_array( 'bp_groups_admin_edit', array( &$group ) ); ?>
 643  
 644      <div class="wrap">
 645          <h1 class="wp-heading-inline"><?php _e( 'Edit Group', 'buddypress' ); ?></h1>
 646  
 647          <?php if ( is_user_logged_in() && bp_user_can_create_groups() ) : ?>
 648              <a class="page-title-action" href="<?php echo trailingslashit( bp_get_groups_directory_permalink() . 'create' ); ?>"><?php _e( 'Add New', 'buddypress' ); ?></a>
 649          <?php endif; ?>
 650  
 651          <hr class="wp-header-end">
 652  
 653          <?php // If the user has just made a change to an group, display the status messages. ?>
 654          <?php if ( !empty( $messages ) ) : ?>
 655              <div id="moderated" class="<?php echo ( $is_error ) ? 'error' : 'updated'; ?> notice is-dismissible"><p><?php echo implode( "</p><p>", $messages ); ?></p></div>
 656          <?php endif; ?>
 657  
 658          <?php if ( $group->id ) : ?>
 659  
 660              <form action="<?php echo esc_url( $form_url ); ?>" id="bp-groups-edit-form" method="post">
 661                  <div id="poststuff">
 662  
 663                      <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
 664                          <div id="post-body-content">
 665                              <div id="postdiv">
 666                                  <div id="bp_groups_name" class="postbox">
 667                                      <h2><?php _e( 'Name and Description', 'buddypress' ); ?></h2>
 668                                      <div class="inside">
 669                                          <label for="bp-groups-name" class="screen-reader-text"><?php
 670                                              /* translators: accessibility text */
 671                                              _e( 'Group Name', 'buddypress' );
 672                                          ?></label>
 673                                          <input type="text" name="bp-groups-name" id="bp-groups-name" value="<?php echo esc_attr( stripslashes( $group_name ) ) ?>" />
 674                                          <div id="bp-groups-permalink-box">
 675                                              <strong><?php esc_html_e( 'Permalink:', 'buddypress' ) ?></strong>
 676                                              <span id="bp-groups-permalink">
 677                                                  <?php bp_groups_directory_permalink(); ?> <input type="text" id="bp-groups-slug" name="bp-groups-slug" value="<?php bp_group_slug( $group ); ?>" autocomplete="off"> /
 678                                              </span>
 679                                              <a href="<?php echo bp_group_permalink( $group ) ?>" class="button button-small" id="bp-groups-visit-group"><?php esc_html_e( 'Visit Group', 'buddypress' ) ?></a>
 680                                          </div>
 681  
 682                                          <label for="bp-groups-description" class="screen-reader-text"><?php
 683                                              /* translators: accessibility text */
 684                                              _e( 'Group Description', 'buddypress' );
 685                                          ?></label>
 686                                          <?php wp_editor( stripslashes( $group->description ), 'bp-groups-description', array( 'media_buttons' => false, 'teeny' => true, 'textarea_rows' => 5, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
 687                                      </div>
 688                                  </div>
 689                              </div>
 690                          </div><!-- #post-body-content -->
 691  
 692                          <div id="postbox-container-1" class="postbox-container">
 693                              <?php do_meta_boxes( get_current_screen()->id, 'side', $group ); ?>
 694                          </div>
 695  
 696                          <div id="postbox-container-2" class="postbox-container">
 697                              <?php do_meta_boxes( get_current_screen()->id, 'normal', $group ); ?>
 698                              <?php do_meta_boxes( get_current_screen()->id, 'advanced', $group ); ?>
 699                          </div>
 700                      </div><!-- #post-body -->
 701  
 702                  </div><!-- #poststuff -->
 703                  <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
 704                  <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
 705                  <?php wp_nonce_field( 'edit-group_' . $group->id ); ?>
 706              </form>
 707  
 708          <?php else : ?>
 709  
 710              <p><?php
 711                  printf(
 712                      '%1$s <a href="%2$s">%3$s</a>',
 713                      __( 'No group found with this ID.', 'buddypress' ),
 714                      esc_url( bp_get_admin_url( 'admin.php?page=bp-groups' ) ),
 715                      __( 'Go back and try again.', 'buddypress' )
 716                  );
 717              ?></p>
 718  
 719          <?php endif; ?>
 720  
 721      </div><!-- .wrap -->
 722  
 723  <?php
 724  }
 725  
 726  /**
 727   * Display the Group delete confirmation screen.
 728   *
 729   * We include a separate confirmation because group deletion is truly
 730   * irreversible.
 731   *
 732   * @since 1.7.0
 733   */
 734  function bp_groups_admin_delete() {
 735  
 736      if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 737          die( '-1' );
 738      }
 739  
 740      $group_ids = isset( $_REQUEST['gid'] ) ? $_REQUEST['gid'] : 0;
 741      if ( ! is_array( $group_ids ) ) {
 742          $group_ids = explode( ',', $group_ids );
 743      }
 744      $group_ids = wp_parse_id_list( $group_ids );
 745      $groups    = groups_get_groups( array(
 746          'include'     => $group_ids,
 747          'show_hidden' => true,
 748          'per_page'    => null, // Return all results.
 749      ) );
 750  
 751      // Create a new list of group ids, based on those that actually exist.
 752      $gids = array();
 753      foreach ( $groups['groups'] as $group ) {
 754          $gids[] = $group->id;
 755      }
 756  
 757      $base_url  = remove_query_arg( array( 'action', 'action2', 'paged', 's', '_wpnonce', 'gid' ), $_SERVER['REQUEST_URI'] ); ?>
 758  
 759      <div class="wrap">
 760          <h1 class="wp-heading-inline"><?php _e( 'Delete Groups', 'buddypress' ) ?></h1>
 761          <hr class="wp-header-end">
 762  
 763          <p><?php _e( 'You are about to delete the following groups:', 'buddypress' ) ?></p>
 764  
 765          <ul class="bp-group-delete-list">
 766          <?php foreach ( $groups['groups'] as $group ) : ?>
 767              <li><?php echo esc_html( bp_get_group_name( $group ) ); ?></li>
 768          <?php endforeach; ?>
 769          </ul>
 770  
 771          <p><strong><?php _e( 'This action cannot be undone.', 'buddypress' ) ?></strong></p>
 772  
 773          <a class="button-primary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'do_delete', 'gid' => implode( ',', $gids ) ), $base_url ), 'bp-groups-delete' ) ); ?>"><?php _e( 'Delete Permanently', 'buddypress' ) ?></a>
 774          <a class="button" href="<?php echo esc_attr( $base_url ); ?>"><?php _e( 'Cancel', 'buddypress' ) ?></a>
 775      </div>
 776  
 777      <?php
 778  }
 779  
 780  /**
 781   * Display the Groups admin index screen.
 782   *
 783   * This screen contains a list of all BuddyPress groups.
 784   *
 785   * @since 1.7.0
 786   *
 787   * @global BP_Groups_List_Table $bp_groups_list_table Group screen list table.
 788   * @global string $plugin_page Currently viewed plugin page.
 789   */
 790  function bp_groups_admin_index() {
 791      global $bp_groups_list_table, $plugin_page;
 792  
 793      $messages = array();
 794  
 795      // If the user has just made a change to a group, build status messages.
 796      if ( ! empty( $_REQUEST['deleted'] ) ) {
 797          $deleted  = ! empty( $_REQUEST['deleted'] ) ? (int) $_REQUEST['deleted'] : 0;
 798  
 799          if ( $deleted > 0 ) {
 800              /* translators: %s: number of deleted groups */
 801              $messages[] = sprintf( _n( '%s group has been permanently deleted.', '%s groups have been permanently deleted.', $deleted, 'buddypress' ), number_format_i18n( $deleted ) );
 802          }
 803      }
 804  
 805      // Prepare the group items for display.
 806      $bp_groups_list_table->prepare_items();
 807  
 808      /**
 809       * Fires before the display of messages for the edit form.
 810       *
 811       * Useful for plugins to modify the messages before display.
 812       *
 813       * @since 1.7.0
 814       *
 815       * @param array $messages Array of messages to be displayed.
 816       */
 817      do_action( 'bp_groups_admin_index', $messages ); ?>
 818  
 819      <div class="wrap">
 820  
 821          <h1 class="wp-heading-inline"><?php _e( 'Groups', 'buddypress' ); ?></h1>
 822  
 823          <?php if ( is_user_logged_in() && bp_user_can_create_groups() ) : ?>
 824              <a class="page-title-action" href="<?php echo trailingslashit( bp_get_groups_directory_permalink() . 'create' ); ?>"><?php _e( 'Add New', 'buddypress' ); ?></a>
 825          <?php endif; ?>
 826  
 827          <?php if ( !empty( $_REQUEST['s'] ) ) : ?>
 828              <span class="subtitle"><?php printf( __( 'Search results for &#8220;%s&#8221;', 'buddypress' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) ); ?></span>
 829          <?php endif; ?>
 830  
 831          <hr class="wp-header-end">
 832  
 833          <?php // If the user has just made a change to an group, display the status messages. ?>
 834          <?php if ( !empty( $messages ) ) : ?>
 835              <div id="moderated" class="<?php echo ( ! empty( $_REQUEST['error'] ) ) ? 'error' : 'updated'; ?> notice is-dismissible"><p><?php echo implode( "<br/>\n", $messages ); ?></p></div>
 836          <?php endif; ?>
 837  
 838          <?php // Display each group on its own row. ?>
 839          <?php $bp_groups_list_table->views(); ?>
 840  
 841          <form id="bp-groups-form" action="" method="get">
 842              <?php $bp_groups_list_table->search_box( __( 'Search all Groups', 'buddypress' ), 'bp-groups' ); ?>
 843              <input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" />
 844              <?php $bp_groups_list_table->display(); ?>
 845          </form>
 846  
 847      </div>
 848  
 849  <?php
 850  }
 851  
 852  /**
 853   * Markup for the single group's Settings metabox.
 854   *
 855   * @since 1.7.0
 856   *
 857   * @param object $item Information about the current group.
 858   */
 859  function bp_groups_admin_edit_metabox_settings( $item ) {
 860  
 861      $invite_status = bp_group_get_invite_status( $item->id ); ?>
 862  
 863      <?php if ( bp_is_active( 'forums' ) ) : ?>
 864          <div class="bp-groups-settings-section" id="bp-groups-settings-section-forum">
 865              <label for="group-show-forum"><input type="checkbox" name="group-show-forum" id="group-show-forum" <?php checked( $item->enable_forum ) ?> /> <?php _e( 'Enable discussion forum', 'buddypress' ) ?></label>
 866          </div>
 867      <?php endif; ?>
 868  
 869      <div class="bp-groups-settings-section" id="bp-groups-settings-section-status">
 870          <fieldset>
 871              <legend><?php _e( 'Privacy', 'buddypress' ); ?></legend>
 872  
 873              <label for="bp-group-status-public"><input type="radio" name="group-status" id="bp-group-status-public" value="public" <?php checked( $item->status, 'public' ) ?> /><?php _e( 'Public', 'buddypress' ) ?></label>
 874              <label for="bp-group-status-private"><input type="radio" name="group-status" id="bp-group-status-private" value="private" <?php checked( $item->status, 'private' ) ?> /><?php _e( 'Private', 'buddypress' ) ?></label>
 875              <label for="bp-group-status-hidden"><input type="radio" name="group-status" id="bp-group-status-hidden" value="hidden" <?php checked( $item->status, 'hidden' ) ?> /><?php _e( 'Hidden', 'buddypress' ) ?></label>
 876          </fieldset>
 877      </div>
 878  
 879      <div class="bp-groups-settings-section" id="bp-groups-settings-section-invite-status">
 880          <fieldset>
 881              <legend><?php _e( 'Who can invite others to this group?', 'buddypress' ); ?></legend>
 882  
 883              <label for="bp-group-invite-status-members"><input type="radio" name="group-invite-status" id="bp-group-invite-status-members" value="members" <?php checked( $invite_status, 'members' ) ?> /><?php _e( 'All group members', 'buddypress' ) ?></label>
 884              <label for="bp-group-invite-status-mods"><input type="radio" name="group-invite-status" id="bp-group-invite-status-mods" value="mods" <?php checked( $invite_status, 'mods' ) ?> /><?php _e( 'Group admins and mods only', 'buddypress' ) ?></label>
 885              <label for="bp-group-invite-status-admins"><input type="radio" name="group-invite-status" id="bp-group-invite-status-admins" value="admins" <?php checked( $invite_status, 'admins' ) ?> /><?php _e( 'Group admins only', 'buddypress' ) ?></label>
 886          </fieldset>
 887      </div>
 888  
 889  <?php
 890  }
 891  
 892  /**
 893   * Output the markup for a single group's Add New Members metabox.
 894   *
 895   * @since 1.7.0
 896   *
 897   * @param BP_Groups_Group $item The BP_Groups_Group object for the current group.
 898   */
 899  function bp_groups_admin_edit_metabox_add_new_members( $item ) {
 900      if ( bp_is_large_install() ) {
 901          $class  = '';
 902          $notice = __( 'Enter a comma-separated list of user logins.', 'buddypress' );
 903      } else {
 904          $class  = 'bp-suggest-user';
 905          $notice = '';
 906      }
 907  
 908      ?>
 909  
 910      <label for="bp-groups-new-members" class="screen-reader-text"><?php
 911          /* translators: accessibility text */
 912          _e( 'Add new members', 'buddypress' );
 913      ?></label>
 914      <input name="bp-groups-new-members" type="text" id="bp-groups-new-members" class="<?php echo esc_attr( $class ); ?>" placeholder="" />
 915      <?php if ( $notice ) : ?>
 916          <p class="description"><?php echo esc_html( $notice ); ?></p>
 917      <?php endif; ?>
 918      <ul id="bp-groups-new-members-list"></ul>
 919      <?php
 920  }
 921  
 922  /**
 923   * Renders the Members metabox on single group pages.
 924   *
 925   * @since 1.7.0
 926   *
 927   * @param BP_Groups_Group $item The BP_Groups_Group object for the current group.
 928   */
 929  function bp_groups_admin_edit_metabox_members( $item ) {
 930      // Use the BP REST API if it supported.
 931      if ( bp_rest_api_is_available() && bp_groups_has_manage_group_members_templates() ) {
 932          wp_enqueue_script( 'bp-group-manage-members' );
 933          wp_localize_script(
 934              'bp-group-manage-members',
 935              'bpGroupManageMembersSettings',
 936              bp_groups_get_group_manage_members_script_data( $item->id )
 937          );
 938  
 939          bp_get_template_part( 'common/js-templates/group-members/index' );
 940  
 941          /**
 942           * Echo out the JavaScript variable.
 943           * This seems to be required by the autocompleter, leaving this here for now...
 944           */
 945          echo '<script type="text/javascript">var group_id = "' . esc_js( $item->id ) . '";</script>';
 946          return;
 947      }
 948  
 949      // Pull up a list of group members, so we can separate out the types
 950      // We'll also keep track of group members here to place them into a
 951      // JavaScript variable, which will help with group member autocomplete.
 952      $members = array(
 953          'admin'  => array(),
 954          'mod'    => array(),
 955          'member' => array(),
 956          'banned' => array(),
 957      );
 958  
 959      $pagination = array(
 960          'admin'  => array(),
 961          'mod'    => array(),
 962          'member' => array(),
 963          'banned' => array(),
 964      );
 965  
 966      foreach ( $members as $type => &$member_type_users ) {
 967          $page_qs_key       = $type . '_page';
 968          $current_type_page = isset( $_GET[ $page_qs_key ] ) ? absint( $_GET[ $page_qs_key ] ) : 1;
 969          $member_type_query = new BP_Group_Member_Query( array(
 970              'group_id'   => $item->id,
 971              'group_role' => array( $type ),
 972              'type'       => 'alphabetical',
 973              /**
 974               * Filters the admin members type per page value.
 975               *
 976               * @since 2.8.0
 977               *
 978               * @param int    $value Member types per page. Default 10.
 979               * @param string $type  Member type.
 980               */
 981              'per_page'   => apply_filters( 'bp_groups_admin_members_type_per_page', 10, $type ),
 982              'page'       => $current_type_page,
 983          ) );
 984  
 985          $member_type_users   = $member_type_query->results;
 986          $pagination[ $type ] = bp_groups_admin_create_pagination_links( $member_type_query, $type );
 987      }
 988  
 989      // Echo out the JavaScript variable.
 990      echo '<script type="text/javascript">var group_id = "' . esc_js( $item->id ) . '";</script>';
 991  
 992      // Loop through each member type.
 993      foreach ( $members as $member_type => $type_users ) : ?>
 994  
 995          <div class="bp-groups-member-type" id="bp-groups-member-type-<?php echo esc_attr( $member_type ) ?>">
 996  
 997              <h3><?php switch ( $member_type ) :
 998                      case 'admin'  : esc_html_e( 'Administrators', 'buddypress' ); break;
 999                      case 'mod'    : esc_html_e( 'Moderators',     'buddypress' ); break;
1000                      case 'member' : esc_html_e( 'Members',        'buddypress' ); break;
1001                      case 'banned' : esc_html_e( 'Banned Members', 'buddypress' ); break;
1002              endswitch; ?></h3>
1003  
1004              <div class="bp-group-admin-pagination table-top">
1005                  <?php echo $pagination[ $member_type ] ?>
1006              </div>
1007  
1008          <?php if ( !empty( $type_users ) ) : ?>
1009  
1010              <table class="widefat bp-group-members">
1011                  <thead>
1012                      <tr>
1013                          <th scope="col" class="uid-column"><?php _ex( 'ID', 'Group member user_id in group admin', 'buddypress' ); ?></th>
1014                          <th scope="col" class="uname-column"><?php _ex( 'Name', 'Group member name in group admin', 'buddypress' ); ?></th>
1015                          <th scope="col" class="urole-column"><?php _ex( 'Group Role', 'Group member role in group admin', 'buddypress' ); ?></th>
1016                      </tr>
1017                  </thead>
1018  
1019                  <tbody>
1020  
1021                  <?php foreach ( $type_users as $type_user ) : ?>
1022                      <tr>
1023                          <th scope="row" class="uid-column"><?php echo esc_html( $type_user->ID ); ?></th>
1024  
1025                          <td class="uname-column">
1026                              <a style="float: left;" href="<?php echo bp_core_get_user_domain( $type_user->ID ); ?>"><?php echo bp_core_fetch_avatar( array(
1027                                  'item_id' => $type_user->ID,
1028                                  'width'   => '32',
1029                                  'height'  => '32'
1030                              ) ); ?></a>
1031  
1032                              <span style="margin: 8px; float: left;"><?php echo bp_core_get_userlink( $type_user->ID ); ?></span>
1033                          </td>
1034  
1035                          <td class="urole-column">
1036                              <label for="bp-groups-role-<?php echo esc_attr( $type_user->ID ); ?>" class="screen-reader-text"><?php
1037                                  /* translators: accessibility text */
1038                                  _e( 'Select group role for member', 'buddypress' );
1039                              ?></label>
1040                              <select class="bp-groups-role" id="bp-groups-role-<?php echo esc_attr( $type_user->ID ); ?>" name="bp-groups-role[<?php echo esc_attr( $type_user->ID ); ?>]">
1041                                  <optgroup label="<?php esc_attr_e( 'Roles', 'buddypress' ); ?>">
1042                                      <option class="admin"  value="admin"  <?php selected( 'admin',  $member_type ); ?>><?php esc_html_e( 'Administrator', 'buddypress' ); ?></option>
1043                                      <option class="mod"    value="mod"    <?php selected( 'mod',    $member_type ); ?>><?php esc_html_e( 'Moderator',     'buddypress' ); ?></option>
1044                                      <option class="member" value="member" <?php selected( 'member', $member_type ); ?>><?php esc_html_e( 'Member',        'buddypress' ); ?></option>
1045                                      <?php if ( 'banned' === $member_type ) : ?>
1046                                      <option class="banned" value="banned" <?php selected( 'banned', $member_type ); ?>><?php esc_html_e( 'Banned',        'buddypress' ); ?></option>
1047                                      <?php endif; ?>
1048                                  </optgroup>
1049                                  <optgroup label="<?php esc_attr_e( 'Actions', 'buddypress' ); ?>">
1050                                      <option class="remove" value="remove"><?php esc_html_e( 'Remove', 'buddypress' ); ?></option>
1051                                      <?php if ( 'banned' !== $member_type ) : ?>
1052                                          <option class="banned" value="banned"><?php esc_html_e( 'Ban', 'buddypress' ); ?></option>
1053                                      <?php endif; ?>
1054                                  </optgroup>
1055                              </select>
1056  
1057                              <?php
1058                              /**
1059                               * Store the current role for this user,
1060                               * so we can easily detect changes.
1061                               *
1062                               * @todo remove this, and do database detection on save
1063                               */
1064                              ?>
1065                              <input type="hidden" name="bp-groups-existing-role[<?php echo esc_attr( $type_user->ID ); ?>]" value="<?php echo esc_attr( $member_type ); ?>" />
1066                          </td>
1067                      </tr>
1068  
1069                      <?php if ( has_filter( 'bp_groups_admin_manage_member_row' ) ) : ?>
1070                          <tr>
1071                              <td colspan="3">
1072                                  <?php
1073  
1074                                  /**
1075                                   * Fires after the listing of a single row for members in a group on the group edit screen.
1076                                   *
1077                                   * @since 1.8.0
1078                                   *
1079                                   * @param int             $ID   ID of the user being rendered.
1080                                   * @param BP_Groups_Group $item Object for the current group.
1081                                   */
1082                                  do_action( 'bp_groups_admin_manage_member_row', $type_user->ID, $item ); ?>
1083                              </td>
1084                          </tr>
1085                      <?php endif; ?>
1086  
1087                  <?php endforeach; ?>
1088  
1089                  </tbody>
1090              </table>
1091  
1092          <?php else : ?>
1093  
1094              <p class="bp-groups-no-members description"><?php esc_html_e( 'No members of this type', 'buddypress' ); ?></p>
1095  
1096          <?php endif; ?>
1097  
1098          </div><!-- .bp-groups-member-type -->
1099  
1100      <?php endforeach;
1101  }
1102  
1103  /**
1104   * Renders the Status metabox for the Groups admin edit screen.
1105   *
1106   * @since 1.7.0
1107   *
1108   * @param object $item Information about the currently displayed group.
1109   */
1110  function bp_groups_admin_edit_metabox_status( $item ) {
1111      $base_url = add_query_arg( array(
1112          'page' => 'bp-groups',
1113          'gid'  => $item->id
1114      ), bp_get_admin_url( 'admin.php' ) ); ?>
1115  
1116      <div id="submitcomment" class="submitbox">
1117          <div id="major-publishing-actions">
1118              <div id="delete-action">
1119                  <a class="submitdelete deletion" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'action', 'delete', $base_url ), 'bp-groups-delete' ) ); ?>"><?php _e( 'Delete Group', 'buddypress' ) ?></a>
1120              </div>
1121  
1122              <div id="publishing-action">
1123                  <?php submit_button( __( 'Save Changes', 'buddypress' ), 'primary', 'save', false ); ?>
1124              </div>
1125              <div class="clear"></div>
1126          </div><!-- #major-publishing-actions -->
1127      </div><!-- #submitcomment -->
1128  
1129  <?php
1130  }
1131  
1132  /**
1133   * Render the Group Type metabox.
1134   *
1135   * @since 2.6.0
1136   *
1137   * @param BP_Groups_Group|null $group The BP_Groups_Group object corresponding to the group being edited.
1138   */
1139  function bp_groups_admin_edit_metabox_group_type( BP_Groups_Group $group = null ) {
1140  
1141      // Bail if no group ID.
1142      if ( empty( $group->id ) ) {
1143          return;
1144      }
1145  
1146      $types         = bp_groups_get_group_types( array(), 'objects' );
1147      $current_types = (array) bp_groups_get_group_type( $group->id, false );
1148      $backend_only  = bp_groups_get_group_types( array( 'show_in_create_screen' => false ) );
1149      ?>
1150  
1151      <label for="bp-groups-group-type" class="screen-reader-text"><?php
1152          /* translators: accessibility text */
1153          esc_html_e( 'Select group type', 'buddypress' );
1154      ?></label>
1155  
1156      <ul class="categorychecklist form-no-clear">
1157          <?php foreach ( $types as $type ) : ?>
1158              <li>
1159                  <label class="selectit"><input value="<?php echo esc_attr( $type->name ) ?>" name="bp-groups-group-type[]" type="checkbox" <?php checked( true, in_array( $type->name, $current_types ) ); ?>>
1160                      <?php
1161                          echo esc_html( $type->labels['singular_name'] );
1162                          if ( in_array( $type->name, $backend_only ) ) {
1163                              printf( ' <span class="description">%s</span>', esc_html__( '(Not available on the front end)', 'buddypress' ) );
1164                          }
1165                      ?>
1166  
1167                  </label>
1168              </li>
1169  
1170          <?php endforeach; ?>
1171  
1172      </ul>
1173  
1174      <?php
1175  
1176      wp_nonce_field( 'bp-group-type-change-' . $group->id, 'bp-group-type-nonce' );
1177  }
1178  
1179  /**
1180   * Process changes from the Group Type metabox.
1181   *
1182   * @since 2.6.0
1183   *
1184   * @param int $group_id Group ID.
1185   */
1186  function bp_groups_process_group_type_update( $group_id ) {
1187      if ( ! isset( $_POST['bp-group-type-nonce'] ) ) {
1188          return;
1189      }
1190  
1191      check_admin_referer( 'bp-group-type-change-' . $group_id, 'bp-group-type-nonce' );
1192  
1193      // Permission check.
1194      if ( ! bp_current_user_can( 'bp_moderate' ) ) {
1195          return;
1196      }
1197  
1198      $group_types = ! empty( $_POST['bp-groups-group-type'] ) ? wp_unslash( $_POST['bp-groups-group-type'] ) : array();
1199  
1200      /*
1201       * If an invalid group type is passed, someone's doing something
1202       * fishy with the POST request, so we can fail silently.
1203       */
1204      if ( bp_groups_set_group_type( $group_id, $group_types ) ) {
1205          // @todo Success messages can't be posted because other stuff happens on the page load.
1206      }
1207  }
1208  add_action( 'bp_group_admin_edit_after', 'bp_groups_process_group_type_update' );
1209  
1210  /**
1211   * Create pagination links out of a BP_Group_Member_Query.
1212   *
1213   * This function is intended to create pagination links for use under the
1214   * Manage Members section of the Groups Admin Dashboard pages. It is a stopgap
1215   * measure until a more general pagination solution is in place for BuddyPress.
1216   * Plugin authors should not use this function, as it is likely to be
1217   * deprecated soon.
1218   *
1219   * @since 1.8.0
1220   *
1221   * @param BP_Group_Member_Query $query       A BP_Group_Member_Query object.
1222   * @param string                $member_type member|mod|admin|banned.
1223   * @return string Pagination links HTML.
1224   */
1225  function bp_groups_admin_create_pagination_links( BP_Group_Member_Query $query, $member_type ) {
1226      $pagination = '';
1227  
1228      if ( ! in_array( $member_type, array( 'admin', 'mod', 'member', 'banned' ) ) ) {
1229          return $pagination;
1230      }
1231  
1232      // The key used to paginate this member type in the $_GET global.
1233      $qs_key   = $member_type . '_page';
1234      $url_base = remove_query_arg( array( $qs_key, 'updated', 'success_modified' ), $_SERVER['REQUEST_URI'] );
1235  
1236      $page = isset( $_GET[ $qs_key ] ) ? absint( $_GET[ $qs_key ] ) : 1;
1237  
1238      /**
1239       * Filters the number of members per member type that is displayed in group editing admin area.
1240       *
1241       * @since 2.8.0
1242       *
1243       * @param string $member_type Member type, which is a group role (admin, mod etc).
1244       */
1245      $per_page = apply_filters( 'bp_groups_admin_members_type_per_page', 10, $member_type );
1246  
1247      // Don't show anything if there's no pagination.
1248      if ( 1 === $page && $query->total_users <= $per_page ) {
1249          return $pagination;
1250      }
1251  
1252      $current_page_start = ( ( $page - 1 ) * $per_page ) + 1;
1253      $current_page_end   = $page * $per_page > intval( $query->total_users ) ? $query->total_users : $page * $per_page;
1254  
1255      $pag_links = paginate_links( array(
1256          'base'      => add_query_arg( $qs_key, '%#%', $url_base ),
1257          'format'    => '',
1258          'prev_text' => __( '&laquo;', 'buddypress' ),
1259          'next_text' => __( '&raquo;', 'buddypress' ),
1260          'total'     => ceil( $query->total_users / $per_page ),
1261          'current'   => $page,
1262      ) );
1263  
1264      if ( 1 == $query->total_users ) {
1265          $viewing_text = __( 'Viewing 1 member', 'buddypress' );
1266      } else {
1267          $viewing_text = sprintf(
1268              /* translators: 1: group member from number. 2: group member to number. 3: total group members. */
1269              _nx( 'Viewing %1$s - %2$s of %3$s member', 'Viewing %1$s - %2$s of %3$s members', $query->total_users, 'Group members pagination in group admin', 'buddypress' ),
1270              bp_core_number_format( $current_page_start ),
1271              bp_core_number_format( $current_page_end ),
1272              bp_core_number_format( $query->total_users )
1273          );
1274      }
1275  
1276      $pagination .= '<span class="bp-group-admin-pagination-viewing">' . $viewing_text . '</span>';
1277      $pagination .= '<span class="bp-group-admin-pagination-links">' . $pag_links . '</span>';
1278  
1279      return $pagination;
1280  }
1281  
1282  /**
1283   * Get a set of usernames corresponding to a set of user IDs.
1284   *
1285   * @since 1.7.0
1286   *
1287   * @param array $user_ids Array of user IDs.
1288   * @return array Array of user_logins corresponding to $user_ids.
1289   */
1290  function bp_groups_admin_get_usernames_from_ids( $user_ids = array() ) {
1291  
1292      $usernames = array();
1293      $users     = new WP_User_Query( array( 'blog_id' => 0, 'include' => $user_ids ) );
1294  
1295      foreach ( (array) $users->results as $user ) {
1296          $usernames[] = $user->user_login;
1297      }
1298  
1299      return $usernames;
1300  }
1301  
1302  /**
1303   * AJAX handler for group member autocomplete requests.
1304   *
1305   * @since 1.7.0
1306   */
1307  function bp_groups_admin_autocomplete_handler() {
1308  
1309      // Bail if user user shouldn't be here, or is a large network.
1310      if ( ! bp_current_user_can( 'bp_moderate' ) || bp_is_large_install() ) {
1311          wp_die( -1 );
1312      }
1313  
1314      $term     = isset( $_GET['term'] )     ? sanitize_text_field( $_GET['term'] ) : '';
1315      $group_id = isset( $_GET['group_id'] ) ? absint( $_GET['group_id'] )          : 0;
1316  
1317      if ( ! $term || ! $group_id ) {
1318          wp_die( -1 );
1319      }
1320  
1321      $suggestions = bp_core_get_suggestions( array(
1322          'group_id' => -$group_id,  // A negative value will exclude this group's members from the suggestions.
1323          'limit'    => 10,
1324          'term'     => $term,
1325          'type'     => 'members',
1326      ) );
1327  
1328      $matches = array();
1329  
1330      if ( $suggestions && ! is_wp_error( $suggestions ) ) {
1331          foreach ( $suggestions as $user ) {
1332  
1333              $matches[] = array(
1334                  // Translators: 1: user_login, 2: user_email.
1335                  'label' => sprintf( __( '%1$s (%2$s)', 'buddypress' ), $user->name, $user->ID ),
1336                  'value' => $user->ID,
1337              );
1338          }
1339      }
1340  
1341      wp_die( json_encode( $matches ) );
1342  }
1343  add_action( 'wp_ajax_bp_group_admin_member_autocomplete', 'bp_groups_admin_autocomplete_handler' );
1344  
1345  /**
1346   * Process input from the Group Type bulk change select.
1347   *
1348   * @since 2.7.0
1349   *
1350   * @param string $doaction Current $_GET action being performed in admin screen.
1351   */
1352  function bp_groups_admin_process_group_type_bulk_changes( $doaction ) {
1353      // Bail if no groups are specified or if this isn't a relevant action.
1354      if ( empty( $_REQUEST['gid'] )
1355          || ( empty( $_REQUEST['bp_change_type'] ) && empty( $_REQUEST['bp_change_type2'] ) )
1356          || empty( $_REQUEST['bp_change_group_type'] )
1357      ) {
1358          return;
1359      }
1360  
1361      // Bail if nonce check fails.
1362      check_admin_referer( 'bp-bulk-groups-change-type-' . bp_loggedin_user_id(), 'bp-bulk-groups-change-type-nonce' );
1363  
1364      if ( ! bp_current_user_can( 'bp_moderate' )  ) {
1365          return;
1366      }
1367  
1368      $new_type = '';
1369      if ( ! empty( $_REQUEST['bp_change_type2'] ) ) {
1370          $new_type = sanitize_text_field( $_REQUEST['bp_change_type2'] );
1371      } elseif ( ! empty( $_REQUEST['bp_change_type'] ) ) {
1372          $new_type = sanitize_text_field( $_REQUEST['bp_change_type'] );
1373      }
1374  
1375      // Check that the selected type actually exists.
1376      if ( 'remove_group_type' !== $new_type && null === bp_groups_get_group_type_object( $new_type ) ) {
1377          $error = true;
1378      } else {
1379          // Run through group ids.
1380          $error = false;
1381          foreach ( (array) $_REQUEST['gid'] as $group_id ) {
1382              $group_id = (int) $group_id;
1383  
1384              // Get the old group type to check against.
1385              $current_types = bp_groups_get_group_type( $group_id, false );
1386  
1387              if ( $current_types && 'remove_group_type' === $new_type ) {
1388                  $group_types = array();
1389              } elseif ( ! $current_types || 1 !== count( $current_types ) || $new_type !== $current_types[0] ) {
1390                  $group_types = array( $new_type );
1391              }
1392  
1393              // Set the new group type.
1394              if ( isset( $group_types ) ) {
1395                  $set = bp_groups_set_group_type( $group_id, $group_types );
1396                  if ( false === $set || is_wp_error( $set ) ) {
1397                      $error = true;
1398                  }
1399                  unset( $group_types );
1400              }
1401          }
1402      }
1403  
1404      // If there were any errors, show the error message.
1405      if ( $error ) {
1406          $redirect = add_query_arg( array( 'updated' => 'group-type-change-error' ), wp_get_referer() );
1407      } else {
1408          $redirect = add_query_arg( array( 'updated' => 'group-type-change-success' ), wp_get_referer() );
1409      }
1410  
1411      wp_redirect( $redirect );
1412      exit();
1413  }
1414  add_action( 'bp_groups_admin_load', 'bp_groups_admin_process_group_type_bulk_changes' );
1415  
1416  /**
1417   * Display an admin notice upon group type bulk update.
1418   *
1419   * @since 2.7.0
1420   */
1421  function bp_groups_admin_groups_type_change_notice() {
1422      $updated = isset( $_REQUEST['updated'] ) ? $_REQUEST['updated'] : false;
1423  
1424      // Display feedback.
1425      if ( $updated && in_array( $updated, array( 'group-type-change-error', 'group-type-change-success' ), true ) ) {
1426  
1427          if ( 'group-type-change-error' === $updated ) {
1428              $notice = __( 'There was an error while changing group type. Please try again.', 'buddypress' );
1429              $type   = 'error';
1430          } else {
1431              $notice = __( 'Group type was changed successfully.', 'buddypress' );
1432              $type   = 'updated';
1433          }
1434  
1435          bp_core_add_admin_notice( $notice, $type );
1436      }
1437  }
1438  add_action( bp_core_admin_hook(), 'bp_groups_admin_groups_type_change_notice' );
1439  
1440  /**
1441   * Checks whether a group type already exists.
1442   *
1443   * @since 7.0.0
1444   *
1445   * @param  boolean $exists  True if the group type already exists. False otherwise.
1446   * @param  string  $type_id The group type identifier.
1447   * @return boolean          True if the group type already exists. False otherwise.
1448   */
1449  function bp_groups_type_admin_type_exists( $exists = false, $type_id = '' ) {
1450      if ( ! $type_id ) {
1451          return $exists;
1452      }
1453  
1454      return ! is_null( bp_groups_get_group_type_object( $type_id ) );
1455  }
1456  add_filter( bp_get_group_type_tax_name() . '_check_existing_type', 'bp_groups_type_admin_type_exists', 1, 2 );
1457  
1458  /**
1459   * Set the feedback messages for the Group Types Admin actions.
1460   *
1461   * @since 7.0.0
1462   *
1463   * @param array  $messages The feedback messages.
1464   * @return array           The feedback messages including the ones for the Group Types Admin actions.
1465   */
1466  function bp_groups_type_admin_updated_messages( $messages = array() ) {
1467      $type_taxonomy = bp_get_group_type_tax_name();
1468  
1469      $messages[ $type_taxonomy ] = array(
1470          0  => '',
1471          1  => __( 'Please define the Group Type ID field.', 'buddypress' ),
1472          2  => __( 'Group type successfully added.', 'buddypress' ),
1473          3  => __( 'Sorry, there was an error and the Group type wasn’t added.', 'buddypress' ),
1474          // The following one needs to be != 5.
1475          4  => __( 'Group type successfully updated.', 'buddypress' ),
1476          5  => __( 'Sorry, this Group type already exists.', 'buddypress' ),
1477          6  => __( 'Sorry, the Group type was not deleted: it does not exist.', 'buddypress' ),
1478          7  => __( 'Sorry, This Group type is registered using code, deactivate the plugin or remove the custom code before trying to delete it again.', 'buddypress' ),
1479          8  => __( 'Sorry, there was an error while trying to delete this Group type.', 'buddypress' ),
1480          9  => __( 'Group type successfully deleted.', 'buddypress' ),
1481          10 => __( 'Group type could not be updated due to missing required information.', 'buddypress' ),
1482      );
1483  
1484      return $messages;
1485  }
1486  add_filter( 'term_updated_messages', 'bp_groups_type_admin_updated_messages' );


Generated: Tue Dec 1 01:01:37 2020 Cross-referenced by PHPXref 0.7.1