[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-members/classes/ -> class-bp-members-admin.php (source)

   1  <?php
   2  /**
   3   * BuddyPress Members Admin
   4   *
   5   * @package BuddyPress
   6   * @subpackage MembersAdmin
   7   * @since 2.0.0
   8   */
   9  
  10  // Exit if accessed directly.
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  if ( !class_exists( 'BP_Members_Admin' ) ) :
  14  
  15  /**
  16   * Load Members admin area.
  17   *
  18   * @since 2.0.0
  19   */
  20  class BP_Members_Admin {
  21  
  22      /** Directory *************************************************************/
  23  
  24      /**
  25       * Path to the BP Members Admin directory.
  26       *
  27       * @var string $admin_dir
  28       */
  29      public $admin_dir = '';
  30  
  31      /** URLs ******************************************************************/
  32  
  33      /**
  34       * URL to the BP Members Admin directory.
  35       *
  36       * @var string $admin_url
  37       */
  38      public $admin_url = '';
  39  
  40      /**
  41       * URL to the BP Members Admin CSS directory.
  42       *
  43       * @var string $css_url
  44       */
  45      public $css_url = '';
  46  
  47      /**
  48       * URL to the BP Members Admin JS directory.
  49       *
  50       * @var string
  51       */
  52      public $js_url = '';
  53  
  54      /** Other *****************************************************************/
  55  
  56      /**
  57       * Screen id for edit user's profile page.
  58       *
  59       * @var string
  60       */
  61      public $user_page = '';
  62  
  63      /**
  64       * Setup BP Members Admin.
  65       *
  66       * @since 2.0.0
  67       *
  68       * @return BP_Members_Admin
  69       */
  70  	public static function register_members_admin() {
  71          if ( ! is_admin() ) {
  72              return;
  73          }
  74  
  75          $bp = buddypress();
  76  
  77          if ( empty( $bp->members->admin ) ) {
  78              $bp->members->admin = new self;
  79          }
  80  
  81          return $bp->members->admin;
  82      }
  83  
  84      /**
  85       * Constructor method.
  86       *
  87       * @since 2.0.0
  88       */
  89  	public function __construct() {
  90          $this->setup_globals();
  91          $this->setup_actions();
  92      }
  93  
  94      /**
  95       * Set admin-related globals.
  96       *
  97       * @since 2.0.0
  98       */
  99  	private function setup_globals() {
 100          $bp = buddypress();
 101  
 102          // Paths and URLs
 103          $this->admin_dir = trailingslashit( $bp->plugin_dir  . 'bp-members/admin' ); // Admin path.
 104          $this->admin_url = trailingslashit( $bp->plugin_url  . 'bp-members/admin' ); // Admin URL.
 105          $this->css_url   = trailingslashit( $this->admin_url . 'css' ); // Admin CSS URL.
 106          $this->js_url    = trailingslashit( $this->admin_url . 'js'  ); // Admin CSS URL.
 107  
 108          // Capability depends on config.
 109          $this->capability = bp_core_do_network_admin() ? 'manage_network_users' : 'edit_users';
 110  
 111          // The Edit Profile Screen id.
 112          $this->user_page = '';
 113  
 114          // The Show Profile Screen id.
 115          $this->user_profile = is_network_admin() ? 'users' : 'profile';
 116  
 117          // The current user id.
 118          $this->current_user_id = get_current_user_id();
 119  
 120          // The user id being edited.
 121          $this->user_id = 0;
 122  
 123          // Is a member editing their own profile.
 124          $this->is_self_profile = false;
 125  
 126          // The screen ids to load specific css for.
 127          $this->screen_id = array();
 128  
 129          // The stats metabox default position.
 130          $this->stats_metabox = new StdClass();
 131  
 132          // BuddyPress edit user's profile args.
 133          $this->edit_profile_args = array( 'page' => 'bp-profile-edit' );
 134          $this->edit_profile_url  = '';
 135          $this->edit_url          = '';
 136  
 137          // Data specific to signups.
 138          $this->users_page   = '';
 139          $this->signups_page = '';
 140          $this->users_url    = bp_get_admin_url( 'users.php' );
 141          $this->users_screen = bp_core_do_network_admin() ? 'users-network' : 'users';
 142  
 143          // Specific config: BuddyPress is not network activated.
 144          $this->subsite_activated = (bool) is_multisite() && ! bp_is_network_activated();
 145  
 146          // When BuddyPress is not network activated, only Super Admin can moderate signups.
 147          if ( ! empty( $this->subsite_activated ) ) {
 148              $this->capability = 'manage_network_users';
 149          }
 150      }
 151  
 152      /**
 153       * Set admin-related actions and filters.
 154       *
 155       * @since 2.0.0
 156       */
 157  	private function setup_actions() {
 158  
 159          /** Extended Profile *************************************************
 160           */
 161  
 162          // Enqueue all admin JS and CSS.
 163          add_action( 'bp_admin_enqueue_scripts', array( $this, 'enqueue_scripts'   )        );
 164  
 165          // Add some page specific output to the <head>.
 166          add_action( 'bp_admin_head',            array( $this, 'admin_head'        ), 999   );
 167  
 168          // Add menu item to all users menu.
 169          add_action( 'admin_menu',               array( $this, 'admin_menus'       ), 5     );
 170          add_action( 'network_admin_menu',       array( $this, 'admin_menus'       ), 5     );
 171          add_action( 'user_admin_menu',          array( $this, 'user_profile_menu' ), 5     );
 172  
 173          // Create the Profile Navigation (Profile/Extended Profile).
 174          add_action( 'edit_user_profile',        array( $this, 'profile_nav'       ), 99, 1 );
 175          add_action( 'show_user_profile',        array( $this, 'profile_nav'       ), 99, 1 );
 176  
 177          // Editing users of a specific site.
 178          add_action( "admin_head-site-users.php", array( $this, 'profile_admin_head' ) );
 179  
 180          // Add a row action to users listing.
 181          if ( bp_core_do_network_admin() ) {
 182              add_filter( 'ms_user_row_actions',        array( $this, 'row_actions'                    ), 10, 2 );
 183              add_action( 'admin_init',                 array( $this, 'add_edit_profile_url_filter'    )        );
 184              add_action( 'wp_after_admin_bar_render',  array( $this, 'remove_edit_profile_url_filter' )        );
 185          }
 186  
 187          // Add user row actions for single site.
 188          add_filter( 'user_row_actions', array( $this, 'row_actions' ), 10, 2 );
 189  
 190          // Process changes to member type.
 191          add_action( 'bp_members_admin_load', array( $this, 'process_member_type_update' ) );
 192  
 193          /** Signups **********************************************************
 194           */
 195  
 196          if ( is_admin() ) {
 197  
 198              // Filter non multisite user query to remove sign-up users.
 199              if ( ! is_multisite() ) {
 200                  add_action( 'pre_user_query', array( $this, 'remove_signups_from_user_query' ), 10, 1 );
 201              }
 202  
 203              // Reorganise the views navigation in users.php and signups page.
 204              if ( current_user_can( $this->capability ) ) {
 205                  $user_screen = $this->users_screen;
 206  
 207                  /**
 208                   * Users screen on multiblog is users, but signups
 209                   * need to be managed in the network for this case
 210                   */
 211                  if ( bp_is_network_activated() && bp_is_multiblog_mode() && false === strpos( $user_screen, '-network' ) ) {
 212                      $user_screen .= '-network';
 213                  }
 214  
 215                  add_filter( "views_{$user_screen}", array( $this, 'signup_filter_view'    ), 10, 1 );
 216                  add_filter( 'set-screen-option',    array( $this, 'signup_screen_options' ), 10, 3 );
 217              }
 218  
 219              // Registration is turned on.
 220              add_action( 'update_site_option_registration',  array( $this, 'multisite_registration_on' ),   10, 2 );
 221              add_action( 'update_option_users_can_register', array( $this, 'single_site_registration_on' ), 10, 2 );
 222          }
 223  
 224          /** Users List - Members Types ***************************************
 225           */
 226  
 227          if ( is_admin() && bp_get_member_types() ) {
 228  
 229              // Add "Change type" <select> to WP admin users list table and process bulk members type changes.
 230              add_action( 'restrict_manage_users', array( $this, 'users_table_output_type_change_select' ) );
 231              add_action( 'load-users.php',        array( $this, 'users_table_process_bulk_type_change'  ) );
 232  
 233              // Add the member type column to the WP admin users list table.
 234              add_filter( 'manage_users_columns',       array( $this, 'users_table_add_type_column'    )        );
 235              add_filter( 'manage_users_custom_column', array( $this, 'users_table_populate_type_cell' ), 10, 3 );
 236  
 237              // Filter WP admin users list table to include users of the specified type.
 238              add_filter( 'pre_get_users', array( $this, 'users_table_filter_by_type' ) );
 239          }
 240      }
 241  
 242      /**
 243       * Create registration pages when multisite user registration is turned on.
 244       *
 245       * @since 2.7.0
 246       *
 247       * @param string $option_name Current option name; value is always 'registration'.
 248       * @param string $value
 249       */
 250  	public function multisite_registration_on( $option_name, $value ) {
 251          if ( 'user' === $value || 'all' === $value ) {
 252              bp_core_add_page_mappings( array(
 253                  'register' => 1,
 254                  'activate' => 1
 255              ) );
 256          }
 257      }
 258  
 259      /**
 260       * Create registration pages when single site registration is turned on.
 261       *
 262       * @since 2.7.0
 263       *
 264       * @param string $old_value
 265       * @param string $value
 266       */
 267  	public function single_site_registration_on( $old_value, $value ) {
 268          // Single site.
 269          if ( ! is_multisite() && ! empty( $value ) ) {
 270              bp_core_add_page_mappings( array(
 271                  'register' => 1,
 272                  'activate' => 1
 273              ) );
 274          }
 275      }
 276  
 277      /**
 278       * Get the user ID.
 279       *
 280       * Look for $_GET['user_id']. If anything else, force the user ID to the
 281       * current user's ID so they aren't left without a user to edit.
 282       *
 283       * @since 2.1.0
 284       *
 285       * @return int
 286       */
 287  	private function get_user_id() {
 288          if ( ! empty( $this->user_id ) ) {
 289              return $this->user_id;
 290          }
 291  
 292          $this->user_id = (int) get_current_user_id();
 293  
 294          // We'll need a user ID when not on self profile.
 295          if ( ! empty( $_GET['user_id'] ) ) {
 296              $this->user_id = (int) $_GET['user_id'];
 297          }
 298  
 299          return $this->user_id;
 300      }
 301  
 302      /**
 303       * Can the current user edit the one displayed.
 304       *
 305       * Self profile editing / or bp_moderate check.
 306       * This might be replaced by more granular capabilities
 307       * in the future.
 308       *
 309       * @since 2.1.0
 310       *
 311       * @param int $user_id ID of the user being checked for edit ability.
 312       *
 313       * @return bool
 314       */
 315  	private function member_can_edit( $user_id = 0 ) {
 316          $retval = false;
 317  
 318          // Bail if no user ID was passed.
 319          if ( empty( $user_id ) ) {
 320              return $retval;
 321          }
 322  
 323          // Member can edit if they are viewing their own profile.
 324          if ( $this->current_user_id === $user_id ) {
 325              $retval = true;
 326  
 327          // Trust the 'bp_moderate' capability.
 328          } else {
 329              $retval = bp_current_user_can( 'bp_moderate' );
 330          }
 331  
 332          return $retval;
 333      }
 334  
 335      /**
 336       * Get admin notice when saving a user or member profile.
 337       *
 338       * @since 2.1.0
 339       *
 340       * @return array
 341       */
 342  	private function get_user_notice() {
 343  
 344          // Setup empty notice for return value.
 345          $notice = array();
 346  
 347          // Updates.
 348          if ( ! empty( $_REQUEST['updated'] ) ) {
 349              switch ( $_REQUEST['updated'] ) {
 350              case 'avatar':
 351                  $notice = array(
 352                      'class'   => 'updated',
 353                      'message' => __( 'Profile photo was deleted.', 'buddypress' )
 354                  );
 355                  break;
 356              case 'ham' :
 357                  $notice = array(
 358                      'class'   => 'updated',
 359                      'message' => __( 'User removed as spammer.', 'buddypress' )
 360                  );
 361                  break;
 362              case 'spam' :
 363                  $notice = array(
 364                      'class'   => 'updated',
 365                      'message' => __( 'User marked as spammer. Spam users are visible only to site admins.', 'buddypress' )
 366                  );
 367                  break;
 368              case 1 :
 369                  $notice = array(
 370                      'class'   => 'updated',
 371                      'message' => __( 'Profile updated.', 'buddypress' )
 372                  );
 373                  break;
 374              }
 375          }
 376  
 377          // Errors.
 378          if ( ! empty( $_REQUEST['error'] ) ) {
 379              switch ( $_REQUEST['error'] ) {
 380              case 'avatar':
 381                  $notice = array(
 382                      'class'   => 'error',
 383                      'message' => __( 'There was a problem deleting that profile photo. Please try again.', 'buddypress' )
 384                  );
 385                  break;
 386              case 'ham' :
 387                  $notice = array(
 388                      'class'   => 'error',
 389                      'message' => __( 'User could not be removed as spammer.', 'buddypress' )
 390                  );
 391                  break;
 392              case 'spam' :
 393                  $notice = array(
 394                      'class'   => 'error',
 395                      'message' => __( 'User could not be marked as spammer.', 'buddypress' )
 396                  );
 397                  break;
 398              case 1 :
 399                  $notice = array(
 400                      'class'   => 'error',
 401                      'message' => __( 'An error occurred while trying to update the profile.', 'buddypress' )
 402                  );
 403                  break;
 404              case 2:
 405                  $notice = array(
 406                      'class'   => 'error',
 407                      'message' => __( 'Your changes have not been saved. Please fill in all required fields, and save your changes again.', 'buddypress' )
 408                  );
 409                  break;
 410              case 3:
 411                  $notice = array(
 412                      'class'   => 'error',
 413                      'message' => __( 'There was a problem updating some of your profile information. Please try again.', 'buddypress' )
 414                  );
 415                  break;
 416              }
 417          }
 418  
 419          return $notice;
 420      }
 421  
 422      /**
 423       * Create the /user/ admin Profile submenus for all members.
 424       *
 425       * @since 2.1.0
 426       *
 427       */
 428  	public function user_profile_menu() {
 429  
 430          // Setup the hooks array.
 431          $hooks = array();
 432  
 433          // Add the faux "Edit Profile" submenu page.
 434          $hooks['user'] = $this->user_page = add_submenu_page(
 435              'profile.php',
 436              __( 'Edit Profile',  'buddypress' ),
 437              __( 'Edit Profile',  'buddypress' ),
 438              'exist',
 439              'bp-profile-edit',
 440              array( $this, 'user_admin' )
 441          );
 442  
 443          // Setup the screen ID's.
 444          $this->screen_id = array(
 445              $this->user_page    . '-user',
 446              $this->user_profile . '-user'
 447          );
 448  
 449          // Loop through new hooks and add method actions.
 450          foreach ( $hooks as $key => $hook ) {
 451              add_action( "load-{$hook}", array( $this, $key . '_admin_load' ) );
 452          }
 453  
 454          // Add the profile_admin_head method to proper admin_head actions.
 455          add_action( "admin_head-{$this->user_page}", array( $this, 'profile_admin_head' ) );
 456          add_action( "admin_head-profile.php",        array( $this, 'profile_admin_head' ) );
 457      }
 458  
 459      /**
 460       * Create the All Users / Profile > Edit Profile and All Users Signups submenus.
 461       *
 462       * @since 2.0.0
 463       *
 464       */
 465  	public function admin_menus() {
 466  
 467          // Setup the hooks array.
 468          $hooks = array();
 469  
 470          // Manage user's profile.
 471          $hooks['user'] = $this->user_page = add_submenu_page(
 472              $this->user_profile . '.php',
 473              __( 'Edit Profile',  'buddypress' ),
 474              __( 'Edit Profile',  'buddypress' ),
 475              'read',
 476              'bp-profile-edit',
 477              array( $this, 'user_admin' )
 478          );
 479  
 480          // Only show sign-ups where they belong.
 481          if ( ( ! bp_is_network_activated() && ! is_network_admin() ) || ( is_network_admin() && bp_is_network_activated() ) ) {
 482  
 483              // Manage signups.
 484              $hooks['signups'] = $this->signups_page = add_users_page(
 485                  __( 'Manage Signups',  'buddypress' ),
 486                  __( 'Manage Signups',  'buddypress' ),
 487                  $this->capability,
 488                  'bp-signups',
 489                  array( $this, 'signups_admin' )
 490              );
 491          }
 492  
 493          $edit_page         = 'user-edit';
 494          $profile_page      = 'profile';
 495          $this->users_page  = 'users';
 496  
 497          // Self profile check is needed for this pages.
 498          $page_head = array(
 499              $edit_page        . '.php',
 500              $profile_page     . '.php',
 501              $this->user_page,
 502              $this->users_page . '.php',
 503          );
 504  
 505          // Append '-network' to each array item if in network admin.
 506          if ( is_network_admin() ) {
 507              $edit_page          .= '-network';
 508              $profile_page       .= '-network';
 509              $this->user_page    .= '-network';
 510              $this->users_page   .= '-network';
 511              $this->signups_page .= '-network';
 512          }
 513  
 514          // Setup the screen ID's.
 515          $this->screen_id = array(
 516              $edit_page,
 517              $this->user_page,
 518              $profile_page
 519          );
 520  
 521          // Loop through new hooks and add method actions.
 522          foreach ( $hooks as $key => $hook ) {
 523              add_action( "load-{$hook}", array( $this, $key . '_admin_load' ) );
 524          }
 525  
 526          // Add the profile_admin_head method to proper admin_head actions.
 527          foreach ( $page_head as $head ) {
 528              add_action( "admin_head-{$head}", array( $this, 'profile_admin_head' ) );
 529          }
 530      }
 531  
 532      /**
 533       * Highlight the Users menu if on Edit Profile and check if on the user's admin profile.
 534       *
 535       * @since 2.1.0
 536       */
 537  	public function profile_admin_head() {
 538          global $submenu_file, $parent_file;
 539  
 540          // Is the user editing their own profile?
 541          if ( is_user_admin() || ( defined( 'IS_PROFILE_PAGE' ) && IS_PROFILE_PAGE ) ) {
 542              $this->is_self_profile = true;
 543  
 544          // Is the user attempting to edit their own profile.
 545          } elseif ( isset( $_GET['user_id' ] ) || ( isset( $_GET['page'] ) && ( 'bp-profile-edit' === $_GET['page'] ) ) ) {
 546              $this->is_self_profile = (bool) ( $this->get_user_id() === $this->current_user_id );
 547          }
 548  
 549          // Force the parent file to users.php to open the correct top level menu
 550          // but only if not editing a site via the network site editing page.
 551          if ( 'sites.php' !== $parent_file ) {
 552              $parent_file  = 'users.php';
 553              $submenu_file = 'users.php';
 554          }
 555  
 556          // Editing your own profile, so recheck some vars.
 557          if ( true === $this->is_self_profile ) {
 558  
 559              // Use profile.php as the edit page.
 560              $edit_page = 'profile.php';
 561  
 562              // Set profile.php as the parent & sub files to correct the menu nav.
 563              if ( is_blog_admin() || is_user_admin() ) {
 564                  $parent_file  = 'profile.php';
 565                  $submenu_file = 'profile.php';
 566              }
 567  
 568          // Not editing yourself, so use user-edit.php.
 569          } else {
 570              $edit_page = 'user-edit.php';
 571          }
 572  
 573          if ( is_user_admin() ) {
 574              $this->edit_profile_url = add_query_arg( $this->edit_profile_args, user_admin_url( 'profile.php' ) );
 575              $this->edit_url         = user_admin_url( 'profile.php' );
 576  
 577          } elseif ( is_blog_admin() ) {
 578              $this->edit_profile_url = add_query_arg( $this->edit_profile_args, admin_url( 'users.php' ) );
 579              $this->edit_url         = admin_url( $edit_page );
 580  
 581          } elseif ( is_network_admin() ) {
 582              $this->edit_profile_url = add_query_arg( $this->edit_profile_args, network_admin_url( 'users.php' ) );
 583              $this->edit_url         = network_admin_url( $edit_page );
 584          }
 585      }
 586  
 587      /**
 588       * Remove the Edit Profile page.
 589       *
 590       * We add these pages in order to integrate with WP's Users panel, but
 591       * we want them to show up as a row action of the WP panel, not as separate
 592       * subnav items under the Users menu.
 593       *
 594       * @since 2.0.0
 595       */
 596  	public function admin_head() {
 597          remove_submenu_page( 'users.php',   'bp-profile-edit' );
 598          remove_submenu_page( 'profile.php', 'bp-profile-edit' );
 599      }
 600  
 601      /** Community Profile *****************************************************/
 602  
 603      /**
 604       * Add some specific styling to the Edit User and Edit User's Profile page.
 605       *
 606       * @since 2.0.0
 607       */
 608  	public function enqueue_scripts() {
 609          if ( ! in_array( get_current_screen()->id, $this->screen_id ) ) {
 610              return;
 611          }
 612  
 613          $min = bp_core_get_minified_asset_suffix();
 614          $css = $this->css_url . "admin{$min}.css";
 615  
 616          /**
 617           * Filters the CSS URL to enqueue in the Members admin area.
 618           *
 619           * @since 2.0.0
 620           *
 621           * @param string $css URL to the CSS admin file to load.
 622           */
 623          $css = apply_filters( 'bp_members_admin_css', $css );
 624  
 625          wp_enqueue_style( 'bp-members-css', $css, array(), bp_get_version() );
 626  
 627          wp_style_add_data( 'bp-members-css', 'rtl', 'replace' );
 628          if ( $min ) {
 629              wp_style_add_data( 'bp-members-css', 'suffix', $min );
 630          }
 631  
 632          // Only load JavaScript for BuddyPress profile.
 633          if ( get_current_screen()->id == $this->user_page ) {
 634              $js = $this->js_url . "admin{$min}.js";
 635  
 636              /**
 637               * Filters the JS URL to enqueue in the Members admin area.
 638               *
 639               * @since 2.0.0
 640               *
 641               * @param string $js URL to the JavaScript admin file to load.
 642               */
 643              $js = apply_filters( 'bp_members_admin_js', $js );
 644              wp_enqueue_script( 'bp-members-js', $js, array( 'jquery' ), bp_get_version(), true );
 645  
 646              if ( ! bp_core_get_root_option( 'bp-disable-avatar-uploads' ) && buddypress()->avatar->show_avatars ) {
 647                  /**
 648                   * Get Thickbox.
 649                   *
 650                   * We cannot simply use add_thickbox() here as WordPress is not playing
 651                   * nice with Thickbox width/height see https://core.trac.wordpress.org/ticket/17249
 652                   * Using media-upload might be interesting in the future for the send to editor stuff
 653                   * and we make sure the tb_window is wide enough
 654                   */
 655                  wp_enqueue_style ( 'thickbox' );
 656                  wp_enqueue_script( 'media-upload' );
 657  
 658                  // Get Avatar Uploader.
 659                  bp_attachments_enqueue_scripts( 'BP_Attachment_Avatar' );
 660              }
 661          }
 662  
 663          /**
 664           * Fires after all of the members JavaScript and CSS are enqueued.
 665           *
 666           * @since 2.0.0
 667           *
 668           * @param string $id        ID of the current screen.
 669           * @param array  $screen_id Array of allowed screens to add scripts and styles to.
 670           */
 671          do_action( 'bp_members_admin_enqueue_scripts', get_current_screen()->id, $this->screen_id );
 672      }
 673  
 674      /**
 675       * Create the Profile navigation in Edit User & Edit Profile pages.
 676       *
 677       * @since 2.0.0
 678       *
 679       * @param object|null $user   User to create profile navigation for.
 680       * @param string      $active Which profile to highlight.
 681       * @return string|null
 682       */
 683  	public function profile_nav( $user = null, $active = 'WordPress' ) {
 684  
 685          // Bail if no user ID exists here.
 686          if ( empty( $user->ID ) ) {
 687              return;
 688          }
 689  
 690          // Add the user ID to query arguments when not editing yourself.
 691          if ( false === $this->is_self_profile ) {
 692              $query_args = array( 'user_id' => $user->ID );
 693          } else {
 694              $query_args = array();
 695          }
 696  
 697          // Conditionally add a referer if it exists in the existing request.
 698          if ( ! empty( $_REQUEST['wp_http_referer'] ) ) {
 699              $wp_http_referer = wp_unslash( $_REQUEST['wp_http_referer'] );
 700              $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
 701              $query_args['wp_http_referer'] = urlencode( $wp_http_referer );
 702          }
 703  
 704          // Setup the two distinct "edit" URL's.
 705          $community_url = add_query_arg( $query_args, $this->edit_profile_url );
 706          $wordpress_url = add_query_arg( $query_args, $this->edit_url         );
 707  
 708          $bp_active = false;
 709          $wp_active = ' nav-tab-active';
 710          if ( 'BuddyPress' === $active ) {
 711              $bp_active = ' nav-tab-active';
 712              $wp_active = false;
 713          } ?>
 714  
 715          <h2 id="profile-nav" class="nav-tab-wrapper">
 716              <?php
 717              /**
 718               * In configs where BuddyPress is not network activated, as regular
 719               * admins do not have the capacity to edit other users, we must add
 720               * this check.
 721               */
 722              if ( current_user_can( 'edit_user', $user->ID ) ) : ?>
 723  
 724                  <a class="nav-tab<?php echo esc_attr( $wp_active ); ?>" href="<?php echo esc_url( $wordpress_url );?>"><?php _e( 'Profile', 'buddypress' ); ?></a>
 725  
 726              <?php endif; ?>
 727  
 728              <a class="nav-tab<?php echo esc_attr( $bp_active ); ?>" href="<?php echo esc_url( $community_url );?>"><?php _e( 'Extended Profile', 'buddypress' ); ?></a>
 729          </h2>
 730  
 731          <?php
 732      }
 733  
 734      /**
 735       * Set up the user's profile admin page.
 736       *
 737       * Loaded before the page is rendered, this function does all initial
 738       * setup, including: processing form requests, registering contextual
 739       * help, and setting up screen options.
 740       *
 741       * @since 2.0.0
 742       * @since 6.0.0 The `delete_avatar` action is now managed into this method.
 743       */
 744  	public function user_admin_load() {
 745  
 746          // Get the user ID.
 747          $user_id = $this->get_user_id();
 748  
 749          // Can current user edit this profile?
 750          if ( ! $this->member_can_edit( $user_id ) ) {
 751              wp_die( __( 'You cannot edit the requested user.', 'buddypress' ) );
 752          }
 753  
 754          // Build redirection URL.
 755          $redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'spam', 'ham', 'delete_avatar' ), $_SERVER['REQUEST_URI'] );
 756          $doaction    = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : false;
 757  
 758          if ( ! empty( $_REQUEST['user_status'] ) ) {
 759              $spam = (bool) ( 'spam' === $_REQUEST['user_status'] );
 760  
 761              if ( $spam !== bp_is_user_spammer( $user_id ) ) {
 762                  $doaction = $_REQUEST['user_status'];
 763              }
 764          }
 765  
 766          /**
 767           * Fires at the start of the signups admin load.
 768           *
 769           * @since 2.0.0
 770           *
 771           * @param string $doaction Current bulk action being processed.
 772           * @param array  $_REQUEST Current $_REQUEST global.
 773           */
 774          do_action_ref_array( 'bp_members_admin_load', array( $doaction, $_REQUEST ) );
 775  
 776          /**
 777           * Filters the allowed actions for use in the user admin page.
 778           *
 779           * @since 2.0.0
 780           *
 781           * @param array $value Array of allowed actions to use.
 782           */
 783          $allowed_actions = apply_filters( 'bp_members_admin_allowed_actions', array( 'update', 'delete_avatar', 'spam', 'ham' ) );
 784  
 785          // Prepare the display of the Community Profile screen.
 786          if ( ! in_array( $doaction, $allowed_actions ) ) {
 787              add_screen_option( 'layout_columns', array( 'default' => 2, 'max' => 2, ) );
 788  
 789              get_current_screen()->add_help_tab( array(
 790                  'id'      => 'bp-profile-edit-overview',
 791                  'title'   => __( 'Overview', 'buddypress' ),
 792                  'content' =>
 793                  '<p>' . __( 'This is the admin view of a user&#39;s profile.', 'buddypress' ) . '</p>' .
 794                  '<p>' . __( 'In the main column, you can edit the fields of the user&#39;s extended profile.', 'buddypress' ) . '</p>' .
 795                  '<p>' . __( 'In the right-hand column, you can update the user&#39;s status, delete the user&#39;s avatar, and view recent statistics.', 'buddypress' ) . '</p>'
 796              ) );
 797  
 798              // Help panel - sidebar links.
 799              get_current_screen()->set_help_sidebar(
 800                  '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
 801                  '<p>' . __( '<a href="https://codex.buddypress.org/administrator-guide/extended-profiles/">Managing Profiles</a>', 'buddypress' ) . '</p>' .
 802                  '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
 803              );
 804  
 805              // Register metaboxes for the edit screen.
 806              add_meta_box(
 807                  'submitdiv',
 808                  _x( 'Status', 'members user-admin edit screen', 'buddypress' ),
 809                  array( $this, 'user_admin_status_metabox' ),
 810                  get_current_screen()->id,
 811                  'side',
 812                  'core'
 813              );
 814  
 815              // In case xprofile is not active.
 816              $this->stats_metabox->context  = 'normal';
 817              $this->stats_metabox->priority = 'core';
 818  
 819              /**
 820               * Fires before loading the profile fields if component is active.
 821               *
 822               * Plugins should not use this hook, please use 'bp_members_admin_user_metaboxes' instead.
 823               *
 824               * @since 2.0.0
 825               *
 826               * @param int    $user_id       Current user ID for the screen.
 827               * @param string $id            Current screen ID.
 828               * @param object $stats_metabox Object holding position data for use with the stats metabox.
 829               */
 830              do_action_ref_array( 'bp_members_admin_xprofile_metabox', array( $user_id, get_current_screen()->id, $this->stats_metabox ) );
 831  
 832              // If xProfile is inactive, difficult to know what's profile we're on.
 833              if ( 'normal' === $this->stats_metabox->context ) {
 834                  $display_name = bp_core_get_user_displayname( $user_id );
 835              } else {
 836                  $display_name = __( 'Member', 'buddypress' );
 837              }
 838  
 839              // Set the screen id.
 840              $screen_id = get_current_screen()->id;
 841  
 842              // User Stat metabox.
 843              add_meta_box(
 844                  'bp_members_admin_user_stats',
 845                  sprintf(
 846                      /* translators: %s: member name */
 847                      _x( "%s's Stats", 'members user-admin edit screen', 'buddypress' ),
 848                      $display_name
 849                  ),
 850                  array( $this, 'user_admin_stats_metabox' ),
 851                  $screen_id,
 852                  sanitize_key( $this->stats_metabox->context ),
 853                  sanitize_key( $this->stats_metabox->priority )
 854              );
 855  
 856              if ( buddypress()->avatar->show_avatars ) {
 857                  // Avatar Metabox.
 858                  add_meta_box(
 859                      'bp_members_user_admin_avatar',
 860                      _x( 'Profile Photo', 'members user-admin edit screen', 'buddypress' ),
 861                      array( $this, 'user_admin_avatar_metabox' ),
 862                      $screen_id,
 863                      'side',
 864                      'low'
 865                  );
 866              }
 867  
 868              // Member Type metabox. Only added if member types have been registered.
 869              $member_types = bp_get_member_types();
 870              if ( ! empty( $member_types ) ) {
 871                  add_meta_box(
 872                      'bp_members_admin_member_type',
 873                      _x( 'Member Type', 'members user-admin edit screen', 'buddypress' ),
 874                      array( $this, 'user_admin_member_type_metabox' ),
 875                      $screen_id,
 876                      'side',
 877                      'core'
 878                  );
 879              }
 880  
 881              /**
 882               * Fires at the end of the Community Profile screen.
 883               *
 884               * Plugins can restrict metabox to "bp_moderate" admins by checking if
 885               * the first argument ($this->is_self_profile) is false in their callback.
 886               * They can also restrict their metabox to self profile editing
 887               * by setting it to true.
 888               *
 889               * @since 2.0.0
 890               *
 891               * @param bool $is_self_profile Whether or not it is the current user's profile.
 892               * @param int  $user_id         Current user ID.
 893               */
 894              do_action( 'bp_members_admin_user_metaboxes', $this->is_self_profile, $user_id );
 895  
 896              // Enqueue JavaScript files.
 897              wp_enqueue_script( 'postbox'   );
 898              wp_enqueue_script( 'dashboard' );
 899  
 900          // Spam or Ham user.
 901          } elseif ( in_array( $doaction, array( 'spam', 'ham' ) ) && empty( $this->is_self_profile ) ) {
 902  
 903              check_admin_referer( 'edit-bp-profile_' . $user_id );
 904  
 905              if ( bp_core_process_spammer_status( $user_id, $doaction ) ) {
 906                  $redirect_to = add_query_arg( 'updated', $doaction, $redirect_to );
 907              } else {
 908                  $redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
 909              }
 910  
 911              bp_core_redirect( $redirect_to );
 912  
 913          // Eventually delete avatar.
 914          } elseif ( 'delete_avatar' === $doaction ) {
 915  
 916              // Check the nonce.
 917              check_admin_referer( 'delete_avatar' );
 918  
 919              $redirect_to = remove_query_arg( '_wpnonce', $redirect_to );
 920  
 921              if ( bp_core_delete_existing_avatar( array( 'item_id' => $user_id ) ) ) {
 922                  $redirect_to = add_query_arg( 'updated', 'avatar', $redirect_to );
 923              } else {
 924                  $redirect_to = add_query_arg( 'error', 'avatar', $redirect_to );
 925              }
 926  
 927              bp_core_redirect( $redirect_to );
 928  
 929          // Update other stuff once above ones are done.
 930          } else {
 931              $this->redirect = $redirect_to;
 932  
 933              /**
 934               * Fires at end of user profile admin load if doaction does not match any available actions.
 935               *
 936               * @since 2.0.0
 937               *
 938               * @param string $doaction Current bulk action being processed.
 939               * @param int    $user_id  Current user ID.
 940               * @param array  $_REQUEST Current $_REQUEST global.
 941               * @param string $redirect Determined redirect url to send user to.
 942               */
 943              do_action_ref_array( 'bp_members_admin_update_user', array( $doaction, $user_id, $_REQUEST, $this->redirect ) );
 944  
 945              bp_core_redirect( $this->redirect );
 946          }
 947      }
 948  
 949      /**
 950       * Display the user's profile.
 951       *
 952       * @since 2.0.0
 953       */
 954  	public function user_admin() {
 955  
 956          if ( ! bp_current_user_can( 'bp_moderate' ) && empty( $this->is_self_profile ) ) {
 957              die( '-1' );
 958          }
 959  
 960          // Get the user ID.
 961          $user_id = $this->get_user_id();
 962          $user    = get_user_to_edit( $user_id );
 963  
 964          // Construct title.
 965          if ( true === $this->is_self_profile ) {
 966              $title = __( 'Profile',   'buddypress' );
 967          } else {
 968              $title = __( 'Edit User', 'buddypress' );
 969          }
 970  
 971          // Construct URL for form.
 972          $request_url     = remove_query_arg( array( 'action', 'error', 'updated', 'spam', 'ham' ), $_SERVER['REQUEST_URI'] );
 973          $form_action_url = add_query_arg( 'action', 'update', $request_url );
 974          $wp_http_referer = false;
 975          if ( ! empty( $_REQUEST['wp_http_referer'] ) ) {
 976              $wp_http_referer = wp_unslash( $_REQUEST['wp_http_referer'] );
 977              $wp_http_referer = remove_query_arg( array( 'action', 'updated' ), $wp_http_referer );
 978              $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
 979          }
 980  
 981          // Prepare notice for admin.
 982          $notice = $this->get_user_notice();
 983  
 984          if ( ! empty( $notice ) ) : ?>
 985  
 986              <div <?php if ( 'updated' === $notice['class'] ) : ?>id="message" <?php endif; ?>class="<?php echo esc_attr( $notice['class'] ); ?>  notice is-dismissible">
 987  
 988                  <p><?php echo esc_html( $notice['message'] ); ?></p>
 989  
 990                  <?php if ( !empty( $wp_http_referer ) && ( 'updated' === $notice['class'] ) ) : ?>
 991  
 992                      <p><a href="<?php echo esc_url( $wp_http_referer ); ?>"><?php esc_html_e( '&larr; Back to Users', 'buddypress' ); ?></a></p>
 993  
 994                  <?php endif; ?>
 995  
 996              </div>
 997  
 998          <?php endif; ?>
 999  
1000          <div class="wrap" id="community-profile-page">
1001              <?php if ( version_compare( $GLOBALS['wp_version'], '4.8', '>=' ) ) : ?>
1002  
1003                  <h1 class="wp-heading-inline"><?php echo esc_html( $title ); ?></h1>
1004  
1005                  <?php if ( empty( $this->is_self_profile ) ) : ?>
1006  
1007                      <?php if ( current_user_can( 'create_users' ) ) : ?>
1008  
1009                          <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a>
1010  
1011                      <?php elseif ( is_multisite() && current_user_can( 'promote_users' ) ) : ?>
1012  
1013                          <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a>
1014  
1015                      <?php endif; ?>
1016  
1017                  <?php endif; ?>
1018  
1019                  <hr class="wp-header-end">
1020  
1021              <?php else : ?>
1022  
1023                  <h1><?php echo esc_html( $title ); ?>
1024  
1025                      <?php if ( empty( $this->is_self_profile ) ) : ?>
1026  
1027                          <?php if ( current_user_can( 'create_users' ) ) : ?>
1028  
1029                              <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a>
1030  
1031                          <?php elseif ( is_multisite() && current_user_can( 'promote_users' ) ) : ?>
1032  
1033                              <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a>
1034  
1035                          <?php endif; ?>
1036  
1037                      <?php endif; ?>
1038                  </h1>
1039  
1040              <?php endif; ?>
1041  
1042              <?php if ( ! empty( $user ) ) :
1043  
1044                  $this->profile_nav( $user, 'BuddyPress' ); ?>
1045  
1046                  <form action="<?php echo esc_url( $form_action_url ); ?>" id="your-profile" method="post">
1047                      <div id="poststuff">
1048  
1049                          <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
1050  
1051                              <div id="postbox-container-1" class="postbox-container">
1052                                  <?php do_meta_boxes( get_current_screen()->id, 'side', $user ); ?>
1053                              </div>
1054  
1055                              <div id="postbox-container-2" class="postbox-container">
1056                                  <?php do_meta_boxes( get_current_screen()->id, 'normal',   $user ); ?>
1057                                  <?php do_meta_boxes( get_current_screen()->id, 'advanced', $user ); ?>
1058                              </div>
1059                          </div><!-- #post-body -->
1060  
1061                      </div><!-- #poststuff -->
1062  
1063                      <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
1064                      <?php wp_nonce_field( 'meta-box-order',  'meta-box-order-nonce', false ); ?>
1065                      <?php wp_nonce_field( 'edit-bp-profile_' . $user->ID ); ?>
1066  
1067                  </form>
1068  
1069              <?php else : ?>
1070  
1071                  <p><?php
1072                      printf(
1073                          '%1$s <a href="%2$s">%3$s</a>',
1074                          __( 'No user found with this ID.', 'buddypress' ),
1075                          esc_url( bp_get_admin_url( 'users.php' ) ),
1076                          __( 'Go back and try again.', 'buddypress' )
1077                      );
1078                  ?></p>
1079  
1080              <?php endif; ?>
1081  
1082          </div><!-- .wrap -->
1083          <?php
1084      }
1085  
1086      /**
1087       * Render the Status metabox for user's profile screen.
1088       *
1089       * Actions are:
1090       * - Update profile fields if xProfile component is active
1091       * - Spam/Unspam user
1092       *
1093       * @since 2.0.0
1094       *
1095       * @param WP_User|null $user The WP_User object to be edited.
1096       */
1097  	public function user_admin_status_metabox( $user = null ) {
1098  
1099          // Bail if no user id or if the user has not activated their account yet.
1100          if ( empty( $user->ID ) ) {
1101              return;
1102          }
1103  
1104          // Bail if user has not been activated yet (how did you get here?).
1105          if ( isset( $user->user_status ) && ( 2 == $user->user_status ) ) : ?>
1106  
1107              <p class="not-activated"><?php esc_html_e( 'User account has not yet been activated', 'buddypress' ); ?></p><br/>
1108  
1109              <?php return;
1110  
1111          endif; ?>
1112  
1113          <div class="submitbox" id="submitcomment">
1114              <div id="minor-publishing">
1115                  <div id="misc-publishing-actions">
1116                      <?php
1117  
1118                      // Get the spam status once here to compare against below.
1119                      $is_spammer = bp_is_user_spammer( $user->ID );
1120  
1121                      /**
1122                       * In configs where BuddyPress is not network activated,
1123                       * regular admins cannot mark a user as a spammer on front
1124                       * end. This prevent them to do it in the back end.
1125                       *
1126                       * Also prevent admins from marking themselves or other
1127                       * admins as spammers.
1128                       */
1129                      if ( ( empty( $this->is_self_profile ) && ( ! in_array( $user->user_login, get_super_admins() ) ) && empty( $this->subsite_activated ) ) || ( ! empty( $this->subsite_activated ) && current_user_can( 'manage_network_users' ) ) ) : ?>
1130  
1131                          <div class="misc-pub-section" id="comment-status-radio">
1132                              <label class="approved"><input type="radio" name="user_status" value="ham" <?php checked( $is_spammer, false ); ?>><?php esc_html_e( 'Active', 'buddypress' ); ?></label><br />
1133                              <label class="spam"><input type="radio" name="user_status" value="spam" <?php checked( $is_spammer, true ); ?>><?php esc_html_e( 'Spammer', 'buddypress' ); ?></label>
1134                          </div>
1135  
1136                      <?php endif ;?>
1137  
1138                      <div class="misc-pub-section curtime misc-pub-section-last">
1139                          <?php
1140  
1141                          // Translators: Publish box date format, see http://php.net/date.
1142                          $datef = __( 'M j, Y @ G:i', 'buddypress' );
1143                          $date  = date_i18n( $datef, strtotime( $user->user_registered ) );
1144                          ?>
1145                          <span id="timestamp">
1146                              <?php
1147                              /* translators: %s: registration date */
1148                              printf( __( 'Registered on: %s', 'buddypress' ), '<strong>' . $date . '</strong>' );
1149                              ?>
1150                          </span>
1151                      </div>
1152                  </div> <!-- #misc-publishing-actions -->
1153  
1154                  <div class="clear"></div>
1155              </div><!-- #minor-publishing -->
1156  
1157              <div id="major-publishing-actions">
1158  
1159                  <div id="publishing-action">
1160                      <a class="button bp-view-profile" href="<?php echo esc_url( bp_core_get_user_domain( $user->ID ) ); ?>" target="_blank"><?php esc_html_e( 'View Profile', 'buddypress' ); ?></a>
1161                      <?php submit_button( esc_html__( 'Update Profile', 'buddypress' ), 'primary', 'save', false ); ?>
1162                  </div>
1163                  <div class="clear"></div>
1164              </div><!-- #major-publishing-actions -->
1165  
1166          </div><!-- #submitcomment -->
1167  
1168          <?php
1169      }
1170  
1171      /**
1172       * Render the fallback metabox in case a user has been marked as a spammer.
1173       *
1174       * @since 2.0.0
1175       *
1176       * @param WP_User|null $user The WP_User object to be edited.
1177       */
1178  	public function user_admin_spammer_metabox( $user = null ) {
1179      ?>
1180          <p>
1181              <?php
1182              /* translators: %s: member name */
1183              printf( __( '%s has been marked as a spammer. All BuddyPress data associated with the user has been removed', 'buddypress' ), esc_html( bp_core_get_user_displayname( $user->ID ) ) );
1184              ?>
1185          </p>
1186      <?php
1187      }
1188  
1189      /**
1190       * Render the Stats metabox to moderate inappropriate images.
1191       *
1192       * @since 2.0.0
1193       *
1194       * @param WP_User|null $user The WP_User object to be edited.
1195       */
1196  	public function user_admin_stats_metabox( $user = null ) {
1197  
1198          // Bail if no user ID.
1199          if ( empty( $user->ID ) ) {
1200              return;
1201          }
1202  
1203          // If account is not activated last activity is the time user registered.
1204          if ( isset( $user->user_status ) && 2 == $user->user_status ) {
1205              $last_active = $user->user_registered;
1206  
1207          // Account is activated, getting user's last activity.
1208          } else {
1209              $last_active = bp_get_user_last_activity( $user->ID );
1210          }
1211  
1212          $datef = __( 'M j, Y @ G:i', 'buddypress' );
1213          $date  = date_i18n( $datef, strtotime( $last_active ) ); ?>
1214  
1215          <ul>
1216              <li class="bp-members-profile-stats">
1217                  <?php
1218                  /* translators: %s: date */
1219                  printf( __( 'Last active: %1$s', 'buddypress' ), '<strong>' . $date . '</strong>' );
1220                  ?>
1221              </li>
1222  
1223              <?php
1224              // Loading other stats only if user has activated their account.
1225              if ( empty( $user->user_status ) ) {
1226  
1227                  /**
1228                   * Fires in the user stats metabox if the user has activated their account.
1229                   *
1230                   * @since 2.0.0
1231                   *
1232                   * @param array  $value Array holding the user ID.
1233                   * @param object $user  Current displayed user object.
1234                   */
1235                  do_action( 'bp_members_admin_user_stats', array( 'user_id' => $user->ID ), $user );
1236              }
1237              ?>
1238          </ul>
1239  
1240          <?php
1241      }
1242  
1243      /**
1244       * Render the Avatar metabox to moderate inappropriate images.
1245       *
1246       * @since 6.0.0
1247       *
1248       * @param WP_User|null $user The WP_User object for the user being edited.
1249       */
1250  	public function user_admin_avatar_metabox( $user = null ) {
1251  
1252          if ( empty( $user->ID ) ) {
1253              return;
1254          } ?>
1255  
1256          <div class="avatar">
1257  
1258              <?php echo bp_core_fetch_avatar( array(
1259                  'item_id' => $user->ID,
1260                  'object'  => 'user',
1261                  'type'    => 'full',
1262                  'title'   => $user->display_name
1263              ) ); ?>
1264  
1265              <?php if ( bp_get_user_has_avatar( $user->ID ) ) :
1266  
1267                  $query_args = array(
1268                      'user_id' => $user->ID,
1269                      'action'  => 'delete_avatar'
1270                  );
1271  
1272                  if ( ! empty( $_REQUEST['wp_http_referer'] ) ) {
1273                      $wp_http_referer = wp_unslash( $_REQUEST['wp_http_referer'] );
1274                      $wp_http_referer = remove_query_arg( array( 'action', 'updated' ), $wp_http_referer );
1275                      $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
1276                      $query_args['wp_http_referer'] = urlencode( $wp_http_referer );
1277                  }
1278  
1279                  $community_url = add_query_arg( $query_args, $this->edit_profile_url );
1280                  $delete_link   = wp_nonce_url( $community_url, 'delete_avatar' ); ?>
1281  
1282                  <a href="<?php echo esc_url( $delete_link ); ?>" class="bp-members-avatar-user-admin"><?php esc_html_e( 'Delete Profile Photo', 'buddypress' ); ?></a>
1283  
1284              <?php endif;
1285  
1286              // Load the Avatar UI templates if user avatar uploads are enabled.
1287              if ( ! bp_core_get_root_option( 'bp-disable-avatar-uploads' ) ) : ?>
1288                  <a href="#TB_inline?width=800px&height=400px&inlineId=bp-members-avatar-editor" class="thickbox bp-members-avatar-user-edit"><?php esc_html_e( 'Edit Profile Photo', 'buddypress' ); ?></a>
1289                  <div id="bp-members-avatar-editor" style="display:none;">
1290                      <?php bp_attachments_get_template_part( 'avatars/index' ); ?>
1291                  </div>
1292              <?php endif; ?>
1293  
1294          </div>
1295          <?php
1296      }
1297  
1298      /**
1299       * Render the Member Type metabox.
1300       *
1301       * @since 2.2.0
1302       *
1303       * @param WP_User|null $user The WP_User object to be edited.
1304       */
1305  	public function user_admin_member_type_metabox( $user = null ) {
1306  
1307          // Bail if no user ID.
1308          if ( empty( $user->ID ) ) {
1309              return;
1310          }
1311  
1312          $types = bp_get_member_types( array(), 'objects' );
1313          $current_type = bp_get_member_type( $user->ID );
1314          ?>
1315  
1316          <label for="bp-members-profile-member-type" class="screen-reader-text"><?php
1317              /* translators: accessibility text */
1318              esc_html_e( 'Select member type', 'buddypress' );
1319          ?></label>
1320          <select name="bp-members-profile-member-type" id="bp-members-profile-member-type">
1321              <option value="" <?php selected( '', $current_type ); ?>><?php
1322                  /* translators: no option picked in select box */
1323                  esc_attr_e( '----', 'buddypress' );
1324              ?></option>
1325              <?php foreach ( $types as $type ) : ?>
1326                  <option value="<?php echo esc_attr( $type->name ) ?>" <?php selected( $type->name, $current_type ) ?>><?php echo esc_html( $type->labels['singular_name'] ) ?></option>
1327              <?php endforeach; ?>
1328          </select>
1329  
1330          <?php
1331  
1332          wp_nonce_field( 'bp-member-type-change-' . $user->ID, 'bp-member-type-nonce' );
1333      }
1334  
1335      /**
1336       * Process changes from the Member Type metabox.
1337       *
1338       * @since 2.2.0
1339       */
1340  	public function process_member_type_update() {
1341          if ( ! isset( $_POST['bp-member-type-nonce'] ) || ! isset( $_POST['bp-members-profile-member-type'] ) ) {
1342              return;
1343          }
1344  
1345          $user_id = $this->get_user_id();
1346  
1347          check_admin_referer( 'bp-member-type-change-' . $user_id, 'bp-member-type-nonce' );
1348  
1349          // Permission check.
1350          if ( ! bp_current_user_can( 'bp_moderate' ) && $user_id != bp_loggedin_user_id() ) {
1351              return;
1352          }
1353  
1354          // Member type string must either reference a valid member type, or be empty.
1355          $member_type = stripslashes( $_POST['bp-members-profile-member-type'] );
1356          if ( ! empty( $member_type ) && ! bp_get_member_type_object( $member_type ) ) {
1357              return;
1358          }
1359  
1360          /*
1361           * If an invalid member type is passed, someone's doing something
1362           * fishy with the POST request, so we can fail silently.
1363           */
1364          if ( bp_set_member_type( $user_id, $member_type ) ) {
1365              // @todo Success messages can't be posted because other stuff happens on the page load.
1366          }
1367      }
1368  
1369      /**
1370       * Add a link to Profile in Users listing row actions.
1371       *
1372       * @since 2.0.0
1373       *
1374       * @param array|string $actions WordPress row actions (edit, delete).
1375       * @param object|null  $user    The object for the user row.
1376       * @return null|string|array Merged actions.
1377       */
1378  	public function row_actions( $actions = '', $user = null ) {
1379  
1380          // Bail if no user ID.
1381          if ( empty( $user->ID ) ) {
1382              return;
1383          }
1384  
1385          // Setup args array.
1386          $args = array();
1387  
1388          // Add the user ID if it's not for the current user.
1389          if ( $user->ID !== $this->current_user_id ) {
1390              $args['user_id'] = $user->ID;
1391          }
1392  
1393          // Add the referer.
1394          $wp_http_referer = wp_unslash( $_SERVER['REQUEST_URI'] );
1395          $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
1396          $args['wp_http_referer'] = urlencode( $wp_http_referer );
1397  
1398          // Add the "Extended" link if the current user can edit this user.
1399          if ( current_user_can( 'edit_user', $user->ID ) || bp_current_user_can( 'bp_moderate' ) ) {
1400  
1401              // Add query args and setup the Extended link.
1402              $edit_profile      = add_query_arg( $args, $this->edit_profile_url );
1403              $edit_profile_link = sprintf( '<a href="%1$s">%2$s</a>',  esc_url( $edit_profile ), esc_html__( 'Extended', 'buddypress' ) );
1404  
1405              /**
1406               * Check the edit action is available
1407               * and preserve the order edit | profile | remove/delete.
1408               */
1409              if ( ! empty( $actions['edit'] ) ) {
1410                  $edit_action = $actions['edit'];
1411                  unset( $actions['edit'] );
1412  
1413                  $new_edit_actions = array(
1414                      'edit'         => $edit_action,
1415                      'edit-profile' => $edit_profile_link,
1416                  );
1417  
1418              // If not available simply add the edit profile action.
1419              } else {
1420                  $new_edit_actions = array( 'edit-profile' => $edit_profile_link );
1421              }
1422  
1423              $actions = array_merge( $new_edit_actions, $actions );
1424          }
1425  
1426          return $actions;
1427      }
1428  
1429      /**
1430       * Add a filter to edit profile url in WP Admin Bar.
1431       *
1432       * @since 2.1.0
1433       */
1434  	public function add_edit_profile_url_filter() {
1435          add_filter( 'bp_members_edit_profile_url', array( $this, 'filter_adminbar_profile_link' ), 10, 3 );
1436      }
1437  
1438      /**
1439       * Filter the profile url.
1440       *
1441       * @since 2.1.0
1442       *
1443       *
1444       * @param string $profile_link Profile Link for admin bar.
1445       * @param string $url          Profile URL.
1446       * @param int    $user_id      User ID.
1447       * @return string
1448       */
1449  	public function filter_adminbar_profile_link( $profile_link = '', $url = '', $user_id = 0 ) {
1450          if ( ! is_super_admin( $user_id ) && is_admin() ) {
1451              $profile_link = user_admin_url( 'profile.php' );
1452          }
1453          return $profile_link;
1454      }
1455  
1456      /**
1457       * Remove the filter to edit profile url in WP Admin Bar.
1458       *
1459       * @since 2.1.0
1460       */
1461  	public function remove_edit_profile_url_filter() {
1462          remove_filter( 'bp_members_edit_profile_url', array( $this, 'filter_adminbar_profile_link' ), 10 );
1463      }
1464  
1465      /** Signups Management ****************************************************/
1466  
1467      /**
1468       * Display the admin preferences about signups pagination.
1469       *
1470       * @since 2.0.0
1471       *
1472       * @param int    $value     Value for signup option.
1473       * @param string $option    Value for the option key.
1474       * @param int    $new_value Value for the saved option.
1475       * @return int The pagination preferences.
1476       */
1477  	public function signup_screen_options( $value = 0, $option = '', $new_value = 0 ) {
1478          if ( 'users_page_bp_signups_network_per_page' != $option && 'users_page_bp_signups_per_page' != $option ) {
1479              return $value;
1480          }
1481  
1482          // Per page.
1483          $new_value = (int) $new_value;
1484          if ( $new_value < 1 || $new_value > 999 ) {
1485              return $value;
1486          }
1487  
1488          return $new_value;
1489      }
1490  
1491      /**
1492       * Make sure no signups will show in users list.
1493       *
1494       * This is needed to handle signups that may have not been activated
1495       * before the 2.0.0 upgrade.
1496       *
1497       * @since 2.0.0
1498       *
1499       * @param WP_User_Query|null $query The users query.
1500       * @return WP_User_Query|null The users query without the signups.
1501       */
1502  	public function remove_signups_from_user_query( $query = null ) {
1503          global $wpdb;
1504  
1505          // Bail if this is an ajax request.
1506          if ( defined( 'DOING_AJAX' ) ) {
1507              return;
1508          }
1509  
1510          // Bail if updating BuddyPress.
1511          if ( bp_is_update() ) {
1512              return;
1513          }
1514  
1515          // Bail if there is no current admin screen.
1516          if ( ! function_exists( 'get_current_screen' ) || ! get_current_screen() ) {
1517              return;
1518          }
1519  
1520          // Get current screen.
1521          $current_screen = get_current_screen();
1522  
1523          // Bail if not on a users page.
1524          if ( ! isset( $current_screen->id ) || $this->users_page !== $current_screen->id ) {
1525              return;
1526          }
1527  
1528          // Bail if already querying by an existing role.
1529          if ( ! empty( $query->query_vars['role'] ) ) {
1530              return;
1531          }
1532  
1533          $query->query_where .= " AND {$wpdb->users}.user_status != 2";
1534      }
1535  
1536      /**
1537       * Filter the WP Users List Table views to include 'bp-signups'.
1538       *
1539       * @since 2.0.0
1540       *
1541       * @param array $views WP List Table views.
1542       * @return array The views with the signup view added.
1543       */
1544  	public function signup_filter_view( $views = array() ) {
1545          global $role;
1546  
1547          // Remove the 'current' class from All if we're on the signups view.
1548          if ( 'registered' === $role ) {
1549              $views['all'] = str_replace( 'class="current"', '', $views['all'] );
1550              $class        = 'current';
1551          } else {
1552              $class        = '';
1553          }
1554  
1555          $signups = BP_Signup::count_signups();
1556  
1557          if ( is_network_admin() ) {
1558              $base_url = network_admin_url( 'users.php' );
1559          } else {
1560              $base_url = bp_get_admin_url( 'users.php' );
1561          }
1562  
1563          $url = add_query_arg( 'page', 'bp-signups', $base_url );
1564  
1565          /* translators: %s: number of pending accounts */
1566          $text = sprintf( _x( 'Pending %s', 'signup users', 'buddypress' ), '<span class="count">(' . number_format_i18n( $signups ) . ')</span>' );
1567  
1568          $views['registered'] = sprintf( '<a href="%1$s" class="%2$s">%3$s</a>', esc_url( $url ), $class, $text );
1569  
1570          return $views;
1571      }
1572  
1573      /**
1574       * Load the Signup WP Users List table.
1575       *
1576       * @since 2.0.0
1577       *
1578       * @param string $class    The name of the class to use.
1579       * @param string $required The parent class.
1580       * @return WP_List_Table|null The List table.
1581       */
1582  	public static function get_list_table_class( $class = '', $required = '' ) {
1583          if ( empty( $class ) ) {
1584              return;
1585          }
1586  
1587          if ( ! empty( $required ) ) {
1588              require_once( ABSPATH . 'wp-admin/includes/class-wp-' . $required . '-list-table.php' );
1589          }
1590  
1591          return new $class();
1592      }
1593  
1594      /**
1595       * Set up the signups admin page.
1596       *
1597       * Loaded before the page is rendered, this function does all initial
1598       * setup, including: processing form requests, registering contextual
1599       * help, and setting up screen options.
1600       *
1601       * @since 2.0.0
1602       *
1603       * @global $bp_members_signup_list_table
1604       */
1605  	public function signups_admin_load() {
1606          global $bp_members_signup_list_table;
1607  
1608          // Build redirection URL.
1609          $redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'activated', 'notactivated', 'deleted', 'notdeleted', 'resent', 'notresent', 'do_delete', 'do_resend', 'do_activate', '_wpnonce', 'signup_ids' ), $_SERVER['REQUEST_URI'] );
1610          $doaction    = bp_admin_list_table_current_bulk_action();
1611  
1612          /**
1613           * Fires at the start of the signups admin load.
1614           *
1615           * @since 2.0.0
1616           *
1617           * @param string $doaction Current bulk action being processed.
1618           * @param array  $_REQUEST Current $_REQUEST global.
1619           */
1620          do_action( 'bp_signups_admin_load', $doaction, $_REQUEST );
1621  
1622          /**
1623           * Filters the allowed actions for use in the user signups admin page.
1624           *
1625           * @since 2.0.0
1626           *
1627           * @param array $value Array of allowed actions to use.
1628           */
1629          $allowed_actions = apply_filters( 'bp_signups_admin_allowed_actions', array( 'do_delete', 'do_activate', 'do_resend' ) );
1630  
1631          // Prepare the display of the Community Profile screen.
1632          if ( ! in_array( $doaction, $allowed_actions ) || ( -1 == $doaction ) ) {
1633  
1634              if ( is_network_admin() ) {
1635                  $bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_MS_List_Table', 'ms-users' );
1636              } else {
1637                  $bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_List_Table', 'users' );
1638              }
1639  
1640              // The per_page screen option.
1641              add_screen_option( 'per_page', array( 'label' => _x( 'Pending Accounts', 'Pending Accounts per page (screen options)', 'buddypress' ) ) );
1642  
1643              get_current_screen()->add_help_tab( array(
1644                  'id'      => 'bp-signups-overview',
1645                  'title'   => __( 'Overview', 'buddypress' ),
1646                  'content' =>
1647                  '<p>' . __( 'This is the administration screen for pending accounts on your site.', 'buddypress' ) . '</p>' .
1648                  '<p>' . __( 'From the screen options, you can customize the displayed columns and the pagination of this screen.', 'buddypress' ) . '</p>' .
1649                  '<p>' . __( 'You can reorder the list of your pending accounts by clicking on the Username, Email or Registered column headers.', 'buddypress' ) . '</p>' .
1650                  '<p>' . __( 'Using the search form, you can find pending accounts more easily. The Username and Email fields will be included in the search.', 'buddypress' ) . '</p>'
1651              ) );
1652  
1653              get_current_screen()->add_help_tab( array(
1654                  'id'      => 'bp-signups-actions',
1655                  'title'   => __( 'Actions', 'buddypress' ),
1656                  'content' =>
1657                  '<p>' . __( 'Hovering over a row in the pending accounts list will display action links that allow you to manage pending accounts. You can perform the following actions:', 'buddypress' ) . '</p>' .
1658                  '<ul><li>' . __( '"Email" takes you to the confirmation screen before being able to send the activation link to the desired pending account. You can only send the activation email once per day.', 'buddypress' ) . '</li>' .
1659                  '<li>' . __( '"Delete" allows you to delete a pending account from your site. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>' .
1660                  '<p>' . __( 'By clicking on a Username you will be able to activate a pending account from the confirmation screen.', 'buddypress' ) . '</p>' .
1661                  '<p>' . __( 'Bulk actions allow you to perform these 3 actions for the selected rows.', 'buddypress' ) . '</p>'
1662              ) );
1663  
1664              // Help panel - sidebar links.
1665              get_current_screen()->set_help_sidebar(
1666                  '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
1667                  '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
1668              );
1669  
1670              // Add accessible hidden headings and text for the Pending Users screen.
1671              get_current_screen()->set_screen_reader_content( array(
1672                  /* translators: accessibility text */
1673                  'heading_views'      => __( 'Filter users list', 'buddypress' ),
1674                  /* translators: accessibility text */
1675                  'heading_pagination' => __( 'Pending users list navigation', 'buddypress' ),
1676                  /* translators: accessibility text */
1677                  'heading_list'       => __( 'Pending users list', 'buddypress' ),
1678              ) );
1679  
1680          } else {
1681              if ( ! empty( $_REQUEST['signup_ids' ] ) ) {
1682                  $signups = wp_parse_id_list( $_REQUEST['signup_ids' ] );
1683              }
1684  
1685              // Handle resent activation links.
1686              if ( 'do_resend' == $doaction ) {
1687  
1688                  // Nonce check.
1689                  check_admin_referer( 'signups_resend' );
1690  
1691                  $resent = BP_Signup::resend( $signups );
1692  
1693                  if ( empty( $resent ) ) {
1694                      $redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
1695                  } else {
1696                      $query_arg = array( 'updated' => 'resent' );
1697  
1698                      if ( ! empty( $resent['resent'] ) ) {
1699                          $query_arg['resent'] = count( $resent['resent'] );
1700                      }
1701  
1702                      if ( ! empty( $resent['errors'] ) ) {
1703                          $query_arg['notsent'] = count( $resent['errors'] );
1704                          set_transient( '_bp_admin_signups_errors', $resent['errors'], 30 );
1705                      }
1706  
1707                      $redirect_to = add_query_arg( $query_arg, $redirect_to );
1708                  }
1709  
1710                  bp_core_redirect( $redirect_to );
1711  
1712              // Handle activated accounts.
1713              } elseif ( 'do_activate' == $doaction ) {
1714  
1715                  // Nonce check.
1716                  check_admin_referer( 'signups_activate' );
1717  
1718                  $activated = BP_Signup::activate( $signups );
1719  
1720                  if ( empty( $activated ) ) {
1721                      $redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
1722                  } else {
1723                      $query_arg = array( 'updated' => 'activated' );
1724  
1725                      if ( ! empty( $activated['activated'] ) ) {
1726                          $query_arg['activated'] = count( $activated['activated'] );
1727                      }
1728  
1729                      if ( ! empty( $activated['errors'] ) ) {
1730                          $query_arg['notactivated'] = count( $activated['errors'] );
1731                          set_transient( '_bp_admin_signups_errors', $activated['errors'], 30 );
1732                      }
1733  
1734                      $redirect_to = add_query_arg( $query_arg, $redirect_to );
1735                  }
1736  
1737                  bp_core_redirect( $redirect_to );
1738  
1739              // Handle sign-ups delete.
1740              } elseif ( 'do_delete' == $doaction ) {
1741  
1742                  // Nonce check.
1743                  check_admin_referer( 'signups_delete' );
1744  
1745                  $deleted = BP_Signup::delete( $signups );
1746  
1747                  if ( empty( $deleted ) ) {
1748                      $redirect_to = add_query_arg( 'error', $doaction, $redirect_to );
1749                  } else {
1750                      $query_arg = array( 'updated' => 'deleted' );
1751  
1752                      if ( ! empty( $deleted['deleted'] ) ) {
1753                          $query_arg['deleted'] = count( $deleted['deleted'] );
1754                      }
1755  
1756                      if ( ! empty( $deleted['errors'] ) ) {
1757                          $query_arg['notdeleted'] = count( $deleted['errors'] );
1758                          set_transient( '_bp_admin_signups_errors', $deleted['errors'], 30 );
1759                      }
1760  
1761                      $redirect_to = add_query_arg( $query_arg, $redirect_to );
1762                  }
1763  
1764                  bp_core_redirect( $redirect_to );
1765  
1766              // Plugins can update other stuff from here.
1767              } else {
1768                  $this->redirect = $redirect_to;
1769  
1770                  /**
1771                   * Fires at end of signups admin load if doaction does not match any actions.
1772                   *
1773                   * @since 2.0.0
1774                   *
1775                   * @param string $doaction Current bulk action being processed.
1776                   * @param array  $_REQUEST Current $_REQUEST global.
1777                   * @param string $redirect Determined redirect url to send user to.
1778                   */
1779                  do_action( 'bp_members_admin_update_signups', $doaction, $_REQUEST, $this->redirect );
1780  
1781                  bp_core_redirect( $this->redirect );
1782              }
1783          }
1784      }
1785  
1786      /**
1787       * Display any activation errors.
1788       *
1789       * @since 2.0.0
1790       */
1791  	public function signups_display_errors() {
1792  
1793          // Look for sign-up errors.
1794          $errors = get_transient( '_bp_admin_signups_errors' );
1795  
1796          // Bail if no activation errors.
1797          if ( empty( $errors ) ) {
1798              return;
1799          }
1800  
1801          // Loop through errors and display them.
1802          foreach ( $errors as $error ) : ?>
1803  
1804              <li><?php echo esc_html( $error[0] );?>: <?php echo esc_html( $error[1] );?></li>
1805  
1806          <?php endforeach;
1807  
1808          // Delete the redirect transient.
1809          delete_transient( '_bp_admin_signups_errors' );
1810      }
1811  
1812      /**
1813       * Get admin notice when viewing the sign-up page.
1814       *
1815       * @since 2.1.0
1816       *
1817       * @return array
1818       */
1819  	private function get_signup_notice() {
1820  
1821          // Setup empty notice for return value.
1822          $notice = array();
1823  
1824          // Updates.
1825          if ( ! empty( $_REQUEST['updated'] ) ) {
1826              switch ( $_REQUEST['updated'] ) {
1827                  case 'resent':
1828                      $notice = array(
1829                          'class'   => 'updated',
1830                          'message' => ''
1831                      );
1832  
1833                      if ( ! empty( $_REQUEST['resent'] ) ) {
1834                          $notice['message'] .= sprintf(
1835                              /* translators: %s: number of activation emails sent */
1836                              _nx( '%s activation email successfully sent! ', '%s activation emails successfully sent! ',
1837                               absint( $_REQUEST['resent'] ),
1838                               'signup resent',
1839                               'buddypress'
1840                              ),
1841                              number_format_i18n( absint( $_REQUEST['resent'] ) )
1842                          );
1843                      }
1844  
1845                      if ( ! empty( $_REQUEST['notsent'] ) ) {
1846                          $notice['message'] .= sprintf(
1847                              /* translators: %s: number of unsent activation emails */
1848                              _nx( '%s activation email was not sent.', '%s activation emails were not sent.',
1849                               absint( $_REQUEST['notsent'] ),
1850                               'signup notsent',
1851                               'buddypress'
1852                              ),
1853                              number_format_i18n( absint( $_REQUEST['notsent'] ) )
1854                          );
1855  
1856                          if ( empty( $_REQUEST['resent'] ) ) {
1857                              $notice['class'] = 'error';
1858                          }
1859                      }
1860  
1861                      break;
1862  
1863                  case 'activated':
1864                      $notice = array(
1865                          'class'   => 'updated',
1866                          'message' => ''
1867                      );
1868  
1869                      if ( ! empty( $_REQUEST['activated'] ) ) {
1870                          $notice['message'] .= sprintf(
1871                              /* translators: %s: number of activated accounts */
1872                              _nx( '%s account successfully activated! ', '%s accounts successfully activated! ',
1873                               absint( $_REQUEST['activated'] ),
1874                               'signup resent',
1875                               'buddypress'
1876                              ),
1877                              number_format_i18n( absint( $_REQUEST['activated'] ) )
1878                          );
1879                      }
1880  
1881                      if ( ! empty( $_REQUEST['notactivated'] ) ) {
1882                          $notice['message'] .= sprintf(
1883                              /* translators: %s: number of accounts not activated */
1884                              _nx( '%s account was not activated.', '%s accounts were not activated.',
1885                               absint( $_REQUEST['notactivated'] ),
1886                               'signup notsent',
1887                               'buddypress'
1888                              ),
1889                              number_format_i18n( absint( $_REQUEST['notactivated'] ) )
1890                          );
1891  
1892                          if ( empty( $_REQUEST['activated'] ) ) {
1893                              $notice['class'] = 'error';
1894                          }
1895                      }
1896  
1897                      break;
1898  
1899                  case 'deleted':
1900                      $notice = array(
1901                          'class'   => 'updated',
1902                          'message' => ''
1903                      );
1904  
1905                      if ( ! empty( $_REQUEST['deleted'] ) ) {
1906                          $notice['message'] .= sprintf(
1907                              /* translators: %s: number of deleted signups */
1908                              _nx( '%s sign-up successfully deleted!', '%s sign-ups successfully deleted!',
1909                               absint( $_REQUEST['deleted'] ),
1910                               'signup deleted',
1911                               'buddypress'
1912                              ),
1913                              number_format_i18n( absint( $_REQUEST['deleted'] ) )
1914                          );
1915                      }
1916  
1917                      if ( ! empty( $_REQUEST['notdeleted'] ) ) {
1918                          $notice['message'] .= sprintf(
1919                              /* translators: %s: number of deleted signups not deleted */
1920                              _nx( '%s sign-up was not deleted.', '%s sign-ups were not deleted.',
1921                               absint( $_REQUEST['notdeleted'] ),
1922                               'signup notdeleted',
1923                               'buddypress'
1924                              ),
1925                              number_format_i18n( absint( $_REQUEST['notdeleted'] ) )
1926                          );
1927  
1928                          if ( empty( $_REQUEST['deleted'] ) ) {
1929                              $notice['class'] = 'error';
1930                          }
1931                      }
1932  
1933                      break;
1934              }
1935          }
1936  
1937          // Errors.
1938          if ( ! empty( $_REQUEST['error'] ) ) {
1939              switch ( $_REQUEST['error'] ) {
1940                  case 'do_resend':
1941                      $notice = array(
1942                          'class'   => 'error',
1943                          'message' => esc_html__( 'There was a problem sending the activation emails. Please try again.', 'buddypress' ),
1944                      );
1945                      break;
1946  
1947                  case 'do_activate':
1948                      $notice = array(
1949                          'class'   => 'error',
1950                          'message' => esc_html__( 'There was a problem activating accounts. Please try again.', 'buddypress' ),
1951                      );
1952                      break;
1953  
1954                  case 'do_delete':
1955                      $notice = array(
1956                          'class'   => 'error',
1957                          'message' => esc_html__( 'There was a problem deleting sign-ups. Please try again.', 'buddypress' ),
1958                      );
1959                      break;
1960              }
1961          }
1962  
1963          return $notice;
1964      }
1965  
1966      /**
1967       * Signups admin page router.
1968       *
1969       * Depending on the context, display
1970       * - the list of signups,
1971       * - or the delete confirmation screen,
1972       * - or the activate confirmation screen,
1973       * - or the "resend" email confirmation screen.
1974       *
1975       * Also prepare the admin notices.
1976       *
1977       * @since 2.0.0
1978       */
1979  	public function signups_admin() {
1980          $doaction = bp_admin_list_table_current_bulk_action();
1981  
1982          // Prepare notices for admin.
1983          $notice = $this->get_signup_notice();
1984  
1985          // Display notices.
1986          if ( ! empty( $notice ) ) :
1987              if ( 'updated' === $notice['class'] ) : ?>
1988  
1989                  <div id="message" class="<?php echo esc_attr( $notice['class'] ); ?> notice is-dismissible">
1990  
1991              <?php else: ?>
1992  
1993                  <div class="<?php echo esc_attr( $notice['class'] ); ?> notice is-dismissible">
1994  
1995              <?php endif; ?>
1996  
1997                  <p><?php echo $notice['message']; ?></p>
1998  
1999                  <?php if ( ! empty( $_REQUEST['notactivated'] ) || ! empty( $_REQUEST['notdeleted'] ) || ! empty( $_REQUEST['notsent'] ) ) :?>
2000  
2001                      <ul><?php $this->signups_display_errors();?></ul>
2002  
2003                  <?php endif ;?>
2004  
2005              </div>
2006  
2007          <?php endif;
2008  
2009          // Show the proper screen.
2010          switch ( $doaction ) {
2011              case 'activate' :
2012              case 'delete' :
2013              case 'resend' :
2014                  $this->signups_admin_manage( $doaction );
2015                  break;
2016  
2017              default:
2018                  $this->signups_admin_index();
2019                  break;
2020  
2021          }
2022      }
2023  
2024      /**
2025       * This is the list of the Pending accounts (signups).
2026       *
2027       * @since 2.0.0
2028       *
2029       * @global $plugin_page
2030       * @global $bp_members_signup_list_table
2031       */
2032  	public function signups_admin_index() {
2033          global $plugin_page, $bp_members_signup_list_table;
2034  
2035          $usersearch = ! empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '';
2036  
2037          // Prepare the group items for display.
2038          $bp_members_signup_list_table->prepare_items();
2039  
2040          if ( is_network_admin() ) {
2041              $form_url = network_admin_url( 'users.php' );
2042          } else {
2043              $form_url = bp_get_admin_url( 'users.php' );
2044          }
2045  
2046          $form_url = add_query_arg(
2047              array(
2048                  'page' => 'bp-signups',
2049              ),
2050              $form_url
2051          );
2052  
2053          $search_form_url = remove_query_arg(
2054              array(
2055                  'action',
2056                  'deleted',
2057                  'notdeleted',
2058                  'error',
2059                  'updated',
2060                  'delete',
2061                  'activate',
2062                  'activated',
2063                  'notactivated',
2064                  'resend',
2065                  'resent',
2066                  'notresent',
2067                  'do_delete',
2068                  'do_activate',
2069                  'do_resend',
2070                  'action2',
2071                  '_wpnonce',
2072                  'signup_ids'
2073              ), $_SERVER['REQUEST_URI']
2074          );
2075  
2076          ?>
2077  
2078          <div class="wrap">
2079              <?php if ( version_compare( $GLOBALS['wp_version'], '4.8', '>=' ) ) : ?>
2080  
2081                  <h1 class="wp-heading-inline"><?php _e( 'Users', 'buddypress' ); ?></h1>
2082  
2083                  <?php if ( current_user_can( 'create_users' ) ) : ?>
2084  
2085                      <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a>
2086  
2087                  <?php elseif ( is_multisite() && current_user_can( 'promote_users' ) ) : ?>
2088  
2089                      <a href="user-new.php" class="page-title-action"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a>
2090  
2091                  <?php endif;
2092  
2093                  if ( $usersearch ) {
2094                      printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'buddypress' ) . '</span>', esc_html( $usersearch ) );
2095                  }
2096                  ?>
2097  
2098                  <hr class="wp-header-end">
2099  
2100              <?php else : ?>
2101  
2102                  <h1><?php _e( 'Users', 'buddypress' ); ?>
2103  
2104                      <?php if ( current_user_can( 'create_users' ) ) : ?>
2105  
2106                          <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add New', 'user', 'buddypress' ); ?></a>
2107  
2108                      <?php elseif ( is_multisite() && current_user_can( 'promote_users' ) ) : ?>
2109  
2110                          <a href="user-new.php" class="add-new-h2"><?php echo esc_html_x( 'Add Existing', 'user', 'buddypress' ); ?></a>
2111  
2112                      <?php endif;
2113  
2114                      if ( $usersearch ) {
2115                          printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'buddypress' ) . '</span>', esc_html( $usersearch ) );
2116                      }
2117  
2118                      ?>
2119                  </h1>
2120  
2121              <?php endif; ?>
2122  
2123              <?php // Display each signups on its own row. ?>
2124              <?php $bp_members_signup_list_table->views(); ?>
2125  
2126              <form id="bp-signups-search-form" action="<?php echo esc_url( $search_form_url ) ;?>">
2127                  <input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" />
2128                  <?php $bp_members_signup_list_table->search_box( __( 'Search Pending Users', 'buddypress' ), 'bp-signups' ); ?>
2129              </form>
2130  
2131              <form id="bp-signups-form" action="<?php echo esc_url( $form_url );?>" method="post">
2132                  <?php $bp_members_signup_list_table->display(); ?>
2133              </form>
2134          </div>
2135      <?php
2136      }
2137  
2138      /**
2139       * This is the confirmation screen for actions.
2140       *
2141       * @since 2.0.0
2142       *
2143       * @param string $action Delete, activate, or resend activation link.
2144       *
2145       * @return null|false
2146       */
2147  	public function signups_admin_manage( $action = '' ) {
2148          if ( ! current_user_can( $this->capability ) || empty( $action ) ) {
2149              die( '-1' );
2150          }
2151  
2152          // Get the user IDs from the URL.
2153          $ids = false;
2154          if ( ! empty( $_POST['allsignups'] ) ) {
2155              $ids = wp_parse_id_list( $_POST['allsignups'] );
2156          } elseif ( ! empty( $_GET['signup_id'] ) ) {
2157              $ids = absint( $_GET['signup_id'] );
2158          }
2159  
2160          if ( empty( $ids ) ) {
2161              return false;
2162          }
2163  
2164          // Query for signups, and filter out those IDs that don't
2165          // correspond to an actual signup.
2166          $signups_query = BP_Signup::get( array(
2167              'include' => $ids,
2168          ) );
2169  
2170          $signups    = $signups_query['signups'];
2171          $signup_ids = wp_list_pluck( $signups, 'signup_id' );
2172  
2173          // Set up strings.
2174          switch ( $action ) {
2175              case 'delete' :
2176                  $header_text = __( 'Delete Pending Accounts', 'buddypress' );
2177                  if ( 1 == count( $signup_ids ) ) {
2178                      $helper_text = __( 'You are about to delete the following account:', 'buddypress' );
2179                  } else {
2180                      $helper_text = __( 'You are about to delete the following accounts:', 'buddypress' );
2181                  }
2182                  break;
2183  
2184              case 'activate' :
2185                  $header_text = __( 'Activate Pending Accounts', 'buddypress' );
2186                  if ( 1 == count( $signup_ids ) ) {
2187                      $helper_text = __( 'You are about to activate the following account:', 'buddypress' );
2188                  } else {
2189                      $helper_text = __( 'You are about to activate the following accounts:', 'buddypress' );
2190                  }
2191                  break;
2192  
2193              case 'resend' :
2194                  $header_text = __( 'Resend Activation Emails', 'buddypress' );
2195                  if ( 1 == count( $signup_ids ) ) {
2196                      $helper_text = __( 'You are about to resend an activation email to the following account:', 'buddypress' );
2197                  } else {
2198                      $helper_text = __( 'You are about to resend an activation email to the following accounts:', 'buddypress' );
2199                  }
2200                  break;
2201          }
2202  
2203          // These arguments are added to all URLs.
2204          $url_args = array( 'page' => 'bp-signups' );
2205  
2206          // These arguments are only added when performing an action.
2207          $action_args = array(
2208              'action'     => 'do_' . $action,
2209              'signup_ids' => implode( ',', $signup_ids )
2210          );
2211  
2212          if ( is_network_admin() ) {
2213              $base_url = network_admin_url( 'users.php' );
2214          } else {
2215              $base_url = bp_get_admin_url( 'users.php' );
2216          }
2217  
2218          $cancel_url = add_query_arg( $url_args, $base_url );
2219          $action_url = wp_nonce_url(
2220              add_query_arg(
2221                  array_merge( $url_args, $action_args ),
2222                  $base_url
2223              ),
2224              'signups_' . $action
2225          );
2226  
2227          // Prefetch registration field data.
2228          $fdata = array();
2229          if ( 'activate' === $action && bp_is_active( 'xprofile' ) ) {
2230              $field_groups = bp_xprofile_get_groups( array(
2231                  'exclude_fields'    => 1,
2232                  'update_meta_cache' => false,
2233                  'fetch_fields'      => true,
2234              ) );
2235  
2236              foreach( $field_groups as $fg ) {
2237                  foreach( $fg->fields as $f ) {
2238                      $fdata[ $f->id ] = $f->name;
2239                  }
2240              }
2241          }
2242  
2243          ?>
2244  
2245          <div class="wrap">
2246              <h1><?php echo esc_html( $header_text ); ?></h1>
2247              <p><?php echo esc_html( $helper_text ); ?></p>
2248  
2249              <ol class="bp-signups-list">
2250              <?php foreach ( $signups as $signup ) :
2251                  $last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent );
2252                  $profile_field_ids = array();
2253  
2254                  // Get all xprofile field IDs except field 1.
2255                  if ( ! empty( $signup->meta['profile_field_ids'] ) ) {
2256                      $profile_field_ids = array_flip( explode( ',', $signup->meta['profile_field_ids'] ) );
2257                      unset( $profile_field_ids[1] );
2258                  } ?>
2259  
2260                  <li>
2261                      <strong><?php echo esc_html( $signup->user_login ) ?></strong>
2262  
2263                      <?php if ( 'activate' == $action ) : ?>
2264                          <table class="wp-list-table widefat fixed striped">
2265                              <tbody>
2266                                  <tr>
2267                                      <td class="column-fields"><?php esc_html_e( 'Display Name', 'buddypress' ); ?></td>
2268                                      <td><?php echo esc_html( $signup->user_name ); ?></td>
2269                                  </tr>
2270  
2271                                  <tr>
2272                                      <td class="column-fields"><?php esc_html_e( 'Email', 'buddypress' ); ?></td>
2273                                      <td><?php echo sanitize_email( $signup->user_email ); ?></td>
2274                                  </tr>
2275  
2276                                  <?php if ( bp_is_active( 'xprofile' ) && ! empty( $profile_field_ids ) ) : ?>
2277                                      <?php foreach ( $profile_field_ids as $pid => $noop ) :
2278                                          $field_value = isset( $signup->meta[ "field_{$pid}" ] ) ? $signup->meta[ "field_{$pid}" ] : ''; ?>
2279                                          <tr>
2280                                              <td class="column-fields"><?php echo esc_html( $fdata[ $pid ] ); ?></td>
2281                                              <td><?php echo $this->format_xprofile_field_for_display( $field_value ); ?></td>
2282                                          </tr>
2283  
2284                                      <?php endforeach;  ?>
2285  
2286                                  <?php endif; ?>
2287  
2288                                  <?php
2289                                  /**
2290                                   * Fires inside the table listing the activate action confirmation details.
2291                                   *
2292                                   * @since 6.0.0
2293                                   *
2294                                   * @param object $signup The Sign-up Object.
2295                                   */
2296                                  do_action( 'bp_activate_signup_confirmation_details', $signup );
2297                                  ?>
2298  
2299                              </tbody>
2300                          </table>
2301  
2302                          <?php
2303                          /**
2304                           * Fires outside the table listing the activate action confirmation details.
2305                           *
2306                           * @since 6.0.0
2307                           *
2308                           * @param object $signup The Sign-up Object.
2309                           */
2310                          do_action( 'bp_activate_signup_confirmation_after_details', $signup );
2311                          ?>
2312  
2313                      <?php endif; ?>
2314  
2315                      <?php if ( 'resend' == $action ) : ?>
2316  
2317                          <p class="description">
2318                              <?php
2319                              /* translators: %s: notification date */
2320                              printf( esc_html__( 'Last notified: %s', 'buddypress'), $last_notified );
2321                              ?>
2322  
2323                              <?php if ( ! empty( $signup->recently_sent ) ) : ?>
2324  
2325                                  <span class="attention wp-ui-text-notification"> <?php esc_html_e( '(less than 24 hours ago)', 'buddypress' ); ?></span>
2326  
2327                              <?php endif; ?>
2328                          </p>
2329  
2330                      <?php endif; ?>
2331  
2332                  </li>
2333  
2334              <?php endforeach; ?>
2335              </ol>
2336  
2337              <?php if ( 'delete' === $action ) : ?>
2338  
2339                  <p><strong><?php esc_html_e( 'This action cannot be undone.', 'buddypress' ) ?></strong></p>
2340  
2341              <?php endif ; ?>
2342  
2343              <a class="button-primary" href="<?php echo esc_url( $action_url ); ?>"><?php esc_html_e( 'Confirm', 'buddypress' ); ?></a>
2344              <a class="button" href="<?php echo esc_url( $cancel_url ); ?>"><?php esc_html_e( 'Cancel', 'buddypress' ) ?></a>
2345          </div>
2346  
2347          <?php
2348      }
2349  
2350      /** Users List Management ****************************************************/
2351  
2352      /**
2353       * Display a dropdown to bulk change the member type of selected user(s).
2354       *
2355       * @since 2.7.0
2356       *
2357       * @param string $which Where this dropdown is displayed - top or bottom.
2358       */
2359  	public function users_table_output_type_change_select( $which = 'top' ) {
2360  
2361          // Bail if current user cannot promote users.
2362          if ( ! bp_current_user_can( 'promote_users' ) ) {
2363              return;
2364          }
2365  
2366          // `$which` is only passed in WordPress 4.6+. Avoid duplicating controls in earlier versions.
2367          static $displayed = false;
2368          if ( version_compare( bp_get_major_wp_version(), '4.6', '<' ) && $displayed ) {
2369              return;
2370          }
2371          $displayed = true;
2372  
2373          $id_name = 'bottom' === $which ? 'bp_change_type2' : 'bp_change_type';
2374  
2375          $types = bp_get_member_types( array(), 'objects' ); ?>
2376  
2377          <label class="screen-reader-text" for="<?php echo $id_name; ?>"><?php _e( 'Change member type to&hellip;', 'buddypress' ) ?></label>
2378          <select name="<?php echo $id_name; ?>" id="<?php echo $id_name; ?>" style="display:inline-block;float:none;">
2379              <option value=""><?php _e( 'Change member type to&hellip;', 'buddypress' ) ?></option>
2380  
2381              <?php foreach( $types as $type ) : ?>
2382  
2383                  <option value="<?php echo esc_attr( $type->name ); ?>"><?php echo esc_html( $type->labels['singular_name'] ); ?></option>
2384  
2385              <?php endforeach; ?>
2386  
2387              <option value="remove_member_type"><?php _e( 'No Member Type', 'buddypress' ) ?></option>
2388  
2389          </select>
2390          <?php
2391          wp_nonce_field( 'bp-bulk-users-change-type-' . bp_loggedin_user_id(), 'bp-bulk-users-change-type-nonce' );
2392          submit_button( __( 'Change', 'buddypress' ), 'button', 'bp_change_member_type', false );
2393      }
2394  
2395      /**
2396       * Process bulk member type change submission from the WP admin users list table.
2397       *
2398       * @since 2.7.0
2399       */
2400  	public function users_table_process_bulk_type_change() {
2401          // Output the admin notice.
2402          $this->users_type_change_notice();
2403  
2404          // Bail if no users are specified or if this isn't a BuddyPress action.
2405          if ( empty( $_REQUEST['users'] )
2406              || ( empty( $_REQUEST['bp_change_type'] ) && empty( $_REQUEST['bp_change_type2'] ) )
2407              || empty( $_REQUEST['bp_change_member_type'] )
2408          ) {
2409              return;
2410          }
2411  
2412          // Bail if nonce check fails.
2413          check_admin_referer( 'bp-bulk-users-change-type-' . bp_loggedin_user_id(), 'bp-bulk-users-change-type-nonce' );
2414  
2415          // Bail if current user cannot promote users.
2416          if ( ! bp_current_user_can( 'promote_users' ) ) {
2417              return;
2418          }
2419  
2420          $new_type = '';
2421          if ( ! empty( $_REQUEST['bp_change_type2'] ) ) {
2422              $new_type = sanitize_text_field( $_REQUEST['bp_change_type2'] );
2423          } elseif ( ! empty( $_REQUEST['bp_change_type'] ) ) {
2424              $new_type = sanitize_text_field( $_REQUEST['bp_change_type'] );
2425          }
2426  
2427          // Check that the selected type actually exists.
2428          if ( 'remove_member_type' != $new_type && null === bp_get_member_type_object( $new_type ) ) {
2429              $error = true;
2430          } else {
2431              // Run through user ids.
2432              $error = false;
2433              foreach ( (array) $_REQUEST['users'] as $user_id ) {
2434                  $user_id = (int) $user_id;
2435  
2436                  // Get the old member type to check against.
2437                  $member_type = bp_get_member_type( $user_id );
2438  
2439                  if ( 'remove_member_type' === $new_type ) {
2440                      // Remove the current member type, if there's one to remove.
2441                      if ( $member_type ) {
2442                          $removed = bp_remove_member_type( $user_id, $member_type );
2443                          if ( false === $removed || is_wp_error( $removed ) ) {
2444                              $error = true;
2445                          }
2446                      }
2447                  } else {
2448                      // Set the new member type.
2449                      if ( $new_type !== $member_type ) {
2450                          $set = bp_set_member_type( $user_id, $new_type );
2451                          if ( false === $set || is_wp_error( $set ) ) {
2452                              $error = true;
2453                          }
2454                      }
2455                  }
2456              }
2457          }
2458  
2459          // If there were any errors, show the error message.
2460          if ( $error ) {
2461              $redirect = add_query_arg( array( 'updated' => 'member-type-change-error' ), wp_get_referer() );
2462          } else {
2463              $redirect = add_query_arg( array( 'updated' => 'member-type-change-success' ), wp_get_referer() );
2464          }
2465  
2466          wp_redirect( $redirect );
2467          exit();
2468      }
2469  
2470      /**
2471       * Display an admin notice upon member type bulk update.
2472       *
2473       * @since 2.7.0
2474       */
2475  	public function users_type_change_notice() {
2476          $updated = isset( $_REQUEST['updated'] ) ? $_REQUEST['updated'] : false;
2477  
2478          // Display feedback.
2479          if ( $updated && in_array( $updated, array( 'member-type-change-error', 'member-type-change-success' ), true ) ) {
2480  
2481              if ( 'member-type-change-error' === $updated ) {
2482                  $notice = __( 'There was an error while changing member type. Please try again.', 'buddypress' );
2483                  $type   = 'error';
2484              } else {
2485                  $notice = __( 'Member type was changed successfully.', 'buddypress' );
2486                  $type   = 'updated';
2487              }
2488  
2489              bp_core_add_admin_notice( $notice, $type );
2490          }
2491      }
2492  
2493      /**
2494       * Add member type column to the WordPress admin users list table.
2495       *
2496       * @since 2.7.0
2497       *
2498       * @param array $columns Users table columns.
2499       *
2500       * @return array $columns
2501       */
2502  	public function users_table_add_type_column( $columns = array() ) {
2503          $columns[ bp_get_member_type_tax_name() ] = _x( 'Member Type', 'Label for the WP users table member type column', 'buddypress' );
2504  
2505          return $columns;
2506      }
2507  
2508      /**
2509       * Return member's type for display in the WP admin users list table.
2510       *
2511       * @since 2.7.0
2512       *
2513       * @param string $retval
2514       * @param string $column_name
2515       * @param int $user_id
2516       *
2517       * @return string Member type as a link to filter all users.
2518       */
2519  	public function users_table_populate_type_cell( $retval = '', $column_name = '', $user_id = 0 ) {
2520          // Only looking for member type column.
2521          if ( bp_get_member_type_tax_name() !== $column_name ) {
2522              return $retval;
2523          }
2524  
2525          // Get the member type.
2526          $type = bp_get_member_type( $user_id );
2527  
2528          // Output the
2529          if ( $type_obj = bp_get_member_type_object( $type ) ) {
2530              $url = add_query_arg( array( 'bp-member-type' => urlencode( $type ) ) );
2531              $retval = '<a href="' . esc_url( $url ) . '">' . esc_html( $type_obj->labels['singular_name'] ) . '</a>';
2532          }
2533  
2534          return $retval;
2535      }
2536  
2537      /**
2538       * Filter WP Admin users list table to include users of the specified type.
2539       *
2540       * @param WP_Query $query
2541       *
2542       * @since 2.7.0
2543       */
2544  	public function users_table_filter_by_type( $query ) {
2545          global $pagenow;
2546  
2547          if ( is_admin() && 'users.php' === $pagenow && ! empty( $_REQUEST['bp-member-type'] ) ) {
2548              $type_slug = sanitize_text_field( $_REQUEST['bp-member-type'] );
2549  
2550              // Check that the type is registered.
2551              if ( null == bp_get_member_type_object( $type_slug ) ) {
2552                  return;
2553              }
2554  
2555              // Get the list of users that are assigned to this member type.
2556              $type = bp_get_term_by( 'slug', $type_slug, bp_get_member_type_tax_name() );
2557  
2558              if ( empty( $type->term_id ) ) {
2559                  return;
2560              }
2561  
2562              $user_ids = bp_get_objects_in_term( $type->term_id, bp_get_member_type_tax_name() );
2563  
2564              if ( $user_ids && ! is_wp_error( $user_ids ) ) {
2565                  $query->set( 'include', (array) $user_ids );
2566              }
2567          }
2568      }
2569  
2570      /**
2571       * Formats a signup's xprofile field data for display.
2572       *
2573       * Operates recursively on arrays, which are then imploded with commas.
2574       *
2575       * @since 2.8.0
2576       *
2577       * @param string|array $value Field value.
2578       * @return string
2579       */
2580  	protected function format_xprofile_field_for_display( $value ) {
2581          if ( is_array( $value ) ) {
2582              $value = array_map( array( $this, 'format_xprofile_field_for_display' ), $value );
2583              $value = implode( ', ', $value );
2584          } else {
2585              $value = stripslashes( $value );
2586              $value = esc_html( $value );
2587          }
2588  
2589          return $value;
2590      }
2591  }
2592  endif; // End class_exists check.


Generated: Thu Jul 16 01:01:32 2020 Cross-referenced by PHPXref 0.7.1