members->admin ) ) { $bp->members->admin = new self; } return $bp->members->admin; } /** * Constructor method. * * @since 2.0.0 */ public function __construct() { $this->setup_globals(); $this->setup_actions(); } /** * Set admin-related globals. * * @since 2.0.0 */ private function setup_globals() { $bp = buddypress(); // Paths and URLs $this->admin_dir = trailingslashit( $bp->plugin_dir . 'bp-members/admin' ); // Admin path. $this->admin_url = trailingslashit( $bp->plugin_url . 'bp-members/admin' ); // Admin URL. $this->css_url = trailingslashit( $this->admin_url . 'css' ); // Admin CSS URL. $this->js_url = trailingslashit( $this->admin_url . 'js' ); // Admin CSS URL. // Capability depends on config. $this->capability = bp_core_do_network_admin() ? 'manage_network_users' : 'edit_users'; // The Edit Profile Screen id. $this->user_page = ''; // The Show Profile Screen id. $this->user_profile = is_network_admin() ? 'users' : 'profile'; // The current user id. $this->current_user_id = get_current_user_id(); // The user id being edited. $this->user_id = 0; // Is a member editing their own profile. $this->is_self_profile = false; // The screen ids to load specific css for. $this->screen_id = array(); // The stats metabox default position. $this->stats_metabox = new StdClass(); // BuddyPress edit user's profile args. $this->edit_profile_args = array( 'page' => 'bp-profile-edit' ); $this->edit_profile_url = ''; $this->edit_url = ''; // Data specific to signups. $this->users_page = ''; $this->signups_page = ''; $this->users_url = bp_get_admin_url( 'users.php' ); $this->users_screen = bp_core_do_network_admin() ? 'users-network' : 'users'; $this->members_invites_page = ''; // Specific config: BuddyPress is not network activated. $this->subsite_activated = (bool) is_multisite() && ! bp_is_network_activated(); // When BuddyPress is not network activated, only Super Admin can moderate signups. if ( ! empty( $this->subsite_activated ) ) { $this->capability = 'manage_network_users'; } /* * For consistency with non-Multisite, we add a Tools menu in * the Network Admin as a home for our Tools panel. */ if ( is_multisite() && bp_core_do_network_admin() ) { $this->tools_parent = 'network-tools'; } else { $this->tools_parent = 'tools.php'; } } /** * Set admin-related actions and filters. * * @since 2.0.0 */ private function setup_actions() { /** Extended Profile ************************************************* */ // Enqueue all admin JS and CSS. add_action( 'bp_admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // Add some page specific output to the . add_action( 'bp_admin_head', array( $this, 'admin_head' ), 999 ); // Add menu item to all users menu. add_action( 'admin_menu', array( $this, 'admin_menus' ), 5 ); add_action( 'network_admin_menu', array( $this, 'admin_menus' ), 5 ); if ( bp_members_is_community_profile_enabled() ) { add_action( 'user_admin_menu', array( $this, 'user_profile_menu' ), 5 ); // Create the Profile Navigation (Profile/Extended Profile). add_action( 'edit_user_profile', array( $this, 'profile_nav' ), 99, 1 ); add_action( 'show_user_profile', array( $this, 'profile_nav' ), 99, 1 ); // Editing users of a specific site. add_action( "admin_head-site-users.php", array( $this, 'profile_admin_head' ) ); } // Add a row action to users listing. if ( bp_core_do_network_admin() ) { if ( bp_members_is_community_profile_enabled() ) { add_filter( 'ms_user_row_actions', array( $this, 'row_actions' ), 10, 2 ); } add_action( 'admin_init', array( $this, 'add_edit_profile_url_filter' ) ); add_action( 'wp_after_admin_bar_render', array( $this, 'remove_edit_profile_url_filter' ) ); } // Add user row actions for single site. if ( bp_members_is_community_profile_enabled() ) { add_filter( 'user_row_actions', array( $this, 'row_actions' ), 10, 2 ); } // Process changes to member type. add_action( 'bp_members_admin_load', array( $this, 'process_member_type_update' ) ); /** Signups ********************************************************** */ if ( is_admin() ) { // Filter non multisite user query to remove sign-up users. if ( ! is_multisite() ) { add_action( 'pre_user_query', array( $this, 'remove_signups_from_user_query' ), 10, 1 ); } // Reorganise the views navigation in users.php and signups page. if ( current_user_can( $this->capability ) ) { $user_screen = $this->users_screen; /** * Users screen on multiblog is users, but signups * need to be managed in the network for this case */ if ( bp_is_network_activated() && bp_is_multiblog_mode() && false === strpos( $user_screen, '-network' ) ) { $user_screen .= '-network'; } add_filter( "views_{$user_screen}", array( $this, 'signup_filter_view' ), 10, 1 ); add_filter( 'set-screen-option', array( $this, 'signup_screen_options' ), 10, 3 ); } // Registration is turned on. add_action( 'update_site_option_registration', array( $this, 'multisite_registration_on' ), 10, 2 ); add_action( 'update_option_users_can_register', array( $this, 'single_site_registration_on' ), 10, 2 ); // Member invitations are enabled. if ( bp_is_network_activated() ) { add_action( 'update_site_option_bp-enable-members-invitations', array( $this, 'multisite_registration_on' ), 10, 2 ); } else { add_action( 'update_option_bp-enable-members-invitations', array( $this, 'single_site_registration_on' ), 10, 2 ); } } /** Users List - Members Types *************************************** */ if ( is_admin() && bp_get_member_types() ) { // Add "Change type" >
user_registered ) ); ?> ' . $date . '' ); ?>

ID ) ) ); ?>

ID ) ) { return; } // If account is not activated last activity is the time user registered. if ( isset( $user->user_status ) && 2 == $user->user_status ) { $last_active = $user->user_registered; // Account is activated, getting user's last activity. } else { $last_active = bp_get_user_last_activity( $user->ID ); } $datef = __( 'M j, Y @ G:i', 'buddypress' ); $date = date_i18n( $datef, strtotime( $last_active ) ); ?> ID ) ) { return; } ?>
$user->ID, 'object' => 'user', 'type' => 'full', 'title' => $user->display_name ) ); ?> ID ) ) : $query_args = array( 'user_id' => $user->ID, 'action' => 'delete_avatar' ); if ( ! empty( $_REQUEST['wp_http_referer'] ) ) { $wp_http_referer = wp_unslash( $_REQUEST['wp_http_referer'] ); $wp_http_referer = remove_query_arg( array( 'action', 'updated' ), $wp_http_referer ); $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) ); $query_args['wp_http_referer'] = urlencode( $wp_http_referer ); } $community_url = add_query_arg( $query_args, $this->edit_profile_url ); $delete_link = wp_nonce_url( $community_url, 'delete_avatar' ); ?>
ID ) ) { return; } $types = bp_get_member_types( array(), 'objects' ); $current_type = (array) bp_get_member_type( $user->ID, false ); $types_count = count( array_filter( $current_type ) ); ?> ID, 'bp-member-type-nonce' ); } /** * Process changes from the Member Type metabox. * * @since 2.2.0 */ public function process_member_type_update() { if ( ! isset( $_POST['bp-member-type-nonce'] ) || ! isset( $_POST['bp-members-profile-member-types-count'] ) ) { return; } $user_id = $this->get_user_id(); check_admin_referer( 'bp-member-type-change-' . $user_id, 'bp-member-type-nonce' ); // Permission check. if ( ! bp_current_user_can( 'edit_users' ) && ! bp_current_user_can( 'bp_moderate' ) && $user_id != bp_loggedin_user_id() ) { return; } if ( isset( $_POST['bp-members-profile-member-type'] ) ) { // Member type [string] must either reference a valid member type, or be empty. $member_type = wp_parse_slug_list( wp_unslash( $_POST['bp-members-profile-member-type'] ) ); $member_type = array_filter( $member_type ); } elseif ( 0 !== intval( $_POST['bp-members-profile-member-types-count'] ) ) { $member_type = false; } // Nothing to do there. if ( ! isset( $member_type ) ) { return; } /* * If an invalid member type is passed, someone's doing something * fishy with the POST request, so we can fail silently. */ if ( bp_set_member_type( $user_id, $member_type ) ) { // @todo Success messages can't be posted because other stuff happens on the page load. } } /** * Add a link to Profile in Users listing row actions. * * @since 2.0.0 * * @param array|string $actions WordPress row actions (edit, delete). * @param object|null $user The object for the user row. * @return null|string|array Merged actions. */ public function row_actions( $actions = '', $user = null ) { // Bail if no user ID. if ( empty( $user->ID ) ) { return; } // Setup args array. $args = array(); // Add the user ID if it's not for the current user. if ( $user->ID !== $this->current_user_id ) { $args['user_id'] = $user->ID; } // Add the referer. $wp_http_referer = wp_unslash( $_SERVER['REQUEST_URI'] ); $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) ); $args['wp_http_referer'] = urlencode( $wp_http_referer ); // Add the "Extended" link if the current user can edit this user. if ( current_user_can( 'edit_user', $user->ID ) || bp_current_user_can( 'bp_moderate' ) ) { // Add query args and setup the Extended link. $edit_profile = add_query_arg( $args, $this->edit_profile_url ); $edit_profile_link = sprintf( '%2$s', esc_url( $edit_profile ), esc_html__( 'Extended', 'buddypress' ) ); /** * Check the edit action is available * and preserve the order edit | profile | remove/delete. */ if ( ! empty( $actions['edit'] ) ) { $edit_action = $actions['edit']; unset( $actions['edit'] ); $new_edit_actions = array( 'edit' => $edit_action, 'edit-profile' => $edit_profile_link, ); // If not available simply add the edit profile action. } else { $new_edit_actions = array( 'edit-profile' => $edit_profile_link ); } $actions = array_merge( $new_edit_actions, $actions ); } return $actions; } /** * Add a filter to edit profile url in WP Admin Bar. * * @since 2.1.0 */ public function add_edit_profile_url_filter() { add_filter( 'bp_members_edit_profile_url', array( $this, 'filter_adminbar_profile_link' ), 10, 3 ); } /** * Filter the profile url. * * @since 2.1.0 * * * @param string $profile_link Profile Link for admin bar. * @param string $url Profile URL. * @param int $user_id User ID. * @return string */ public function filter_adminbar_profile_link( $profile_link = '', $url = '', $user_id = 0 ) { if ( ! is_super_admin( $user_id ) && is_admin() ) { $profile_link = user_admin_url( 'profile.php' ); } return $profile_link; } /** * Remove the filter to edit profile url in WP Admin Bar. * * @since 2.1.0 */ public function remove_edit_profile_url_filter() { remove_filter( 'bp_members_edit_profile_url', array( $this, 'filter_adminbar_profile_link' ), 10 ); } /** Signups Management ****************************************************/ /** * Display the admin preferences about signups pagination. * * @since 2.0.0 * * @param int $value Value for signup option. * @param string $option Value for the option key. * @param int $new_value Value for the saved option. * @return int The pagination preferences. */ public function signup_screen_options( $value = 0, $option = '', $new_value = 0 ) { if ( 'users_page_bp_signups_network_per_page' != $option && 'users_page_bp_signups_per_page' != $option ) { return $value; } // Per page. $new_value = (int) $new_value; if ( $new_value < 1 || $new_value > 999 ) { return $value; } return $new_value; } /** * Make sure no signups will show in users list. * * This is needed to handle signups that may have not been activated * before the 2.0.0 upgrade. * * @since 2.0.0 * * @param WP_User_Query|null $query The users query. * @return WP_User_Query|null The users query without the signups. */ public function remove_signups_from_user_query( $query = null ) { global $wpdb; // Bail if this is an ajax request. if ( defined( 'DOING_AJAX' ) ) { return; } // Bail if updating BuddyPress. if ( bp_is_update() ) { return; } // Bail if there is no current admin screen. if ( ! function_exists( 'get_current_screen' ) || ! get_current_screen() ) { return; } // Get current screen. $current_screen = get_current_screen(); // Bail if not on a users page. if ( ! isset( $current_screen->id ) || $this->users_page !== $current_screen->id ) { return; } // Bail if already querying by an existing role. if ( ! empty( $query->query_vars['role'] ) ) { return; } $query->query_where .= " AND {$wpdb->users}.user_status != 2"; } /** * Filter the WP Users List Table views to include 'bp-signups'. * * @since 2.0.0 * * @param array $views WP List Table views. * @return array The views with the signup view added. */ public function signup_filter_view( $views = array() ) { global $role; // Remove the 'current' class from All if we're on the signups view. if ( 'registered' === $role ) { $views['all'] = str_replace( 'class="current"', '', $views['all'] ); $class = 'current'; } else { $class = ''; } $signups = BP_Signup::count_signups(); if ( is_network_admin() ) { $base_url = network_admin_url( 'users.php' ); } else { $base_url = bp_get_admin_url( 'users.php' ); } $url = add_query_arg( 'page', 'bp-signups', $base_url ); /* translators: %s: number of pending accounts */ $text = sprintf( _x( 'Pending %s', 'signup users', 'buddypress' ), '(' . number_format_i18n( $signups ) . ')' ); $views['registered'] = sprintf( '%3$s', esc_url( $url ), $class, $text ); return $views; } /** * Load the Signup WP Users List table. * * @since 2.0.0 * * @param string $class The name of the class to use. * @param string $required The parent class. * @return WP_List_Table|null The List table. */ public static function get_list_table_class( $class = '', $required = '' ) { if ( empty( $class ) ) { return; } if ( ! empty( $required ) ) { require_once( ABSPATH . 'wp-admin/includes/class-wp-' . $required . '-list-table.php' ); } return new $class(); } /** * Set up the signups admin page. * * Loaded before the page is rendered, this function does all initial * setup, including: processing form requests, registering contextual * help, and setting up screen options. * * @since 2.0.0 * * @global $bp_members_signup_list_table */ public function signups_admin_load() { global $bp_members_signup_list_table; // Build redirection URL. $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'] ); $doaction = bp_admin_list_table_current_bulk_action(); /** * Fires at the start of the signups admin load. * * @since 2.0.0 * * @param string $doaction Current bulk action being processed. * @param array $_REQUEST Current $_REQUEST global. */ do_action( 'bp_signups_admin_load', $doaction, $_REQUEST ); /** * Filters the allowed actions for use in the user signups admin page. * * @since 2.0.0 * * @param array $value Array of allowed actions to use. */ $allowed_actions = apply_filters( 'bp_signups_admin_allowed_actions', array( 'do_delete', 'do_activate', 'do_resend' ) ); // Prepare the display of the Signups screen. if ( ! in_array( $doaction, $allowed_actions ) || ( -1 == $doaction ) ) { if ( is_network_admin() ) { $bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_MS_List_Table', 'ms-users' ); } else { $bp_members_signup_list_table = self::get_list_table_class( 'BP_Members_List_Table', 'users' ); } // The per_page screen option. add_screen_option( 'per_page', array( 'label' => _x( 'Pending Accounts', 'Pending Accounts per page (screen options)', 'buddypress' ) ) ); get_current_screen()->add_help_tab( array( 'id' => 'bp-signups-overview', 'title' => __( 'Overview', 'buddypress' ), 'content' => '

' . __( 'This is the administration screen for pending accounts on your site.', 'buddypress' ) . '

' . '

' . __( 'From the screen options, you can customize the displayed columns and the pagination of this screen.', 'buddypress' ) . '

' . '

' . __( 'You can reorder the list of your pending accounts by clicking on the Username, Email or Registered column headers.', 'buddypress' ) . '

' . '

' . __( 'Using the search form, you can find pending accounts more easily. The Username and Email fields will be included in the search.', 'buddypress' ) . '

' ) ); $signup_help_content = '

' . esc_html__( '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' ) . '

'; if ( bp_get_membership_requests_required() ) { $signup_help_content .= ''; } else { $signup_help_content .= ''; } $signup_help_content .= '

' . esc_html__( 'By clicking on a Username you will be able to activate a pending account from the confirmation screen.', 'buddypress' ) . '

' . '

' . __( 'Bulk actions allow you to perform these 3 actions for the selected rows.', 'buddypress' ) . '

'; get_current_screen()->add_help_tab( array( 'id' => 'bp-signups-actions', 'title' => __( 'Actions', 'buddypress' ), 'content' => $signup_help_content ) ); // Help panel - sidebar links. get_current_screen()->set_help_sidebar( '

' . esc_html__( 'For more information:', 'buddypress' ) . '

' . '

' . __( 'Support Forums', 'buddypress' ) . '

' ); // Add accessible hidden headings and text for the Pending Users screen. get_current_screen()->set_screen_reader_content( array( /* translators: accessibility text */ 'heading_views' => __( 'Filter users list', 'buddypress' ), /* translators: accessibility text */ 'heading_pagination' => __( 'Pending users list navigation', 'buddypress' ), /* translators: accessibility text */ 'heading_list' => __( 'Pending users list', 'buddypress' ), ) ); // Use thickbox to display the extended profile information. if ( bp_is_active( 'xprofile' ) || bp_members_site_requests_enabled() ) { wp_enqueue_style( 'thickbox' ); wp_enqueue_script( 'bp-signup-preview', $this->js_url . 'signup-preview' . bp_core_get_minified_asset_suffix() . '.js', array( 'bp-thickbox', 'jquery' ), bp_get_version(), true ); wp_localize_script( 'bp-signup-preview', 'bpSignupPreview', array( 'modalLabel' => __( 'Profile info preview', 'buddypress' ), ) ); } } else { if ( ! empty( $_REQUEST['signup_ids' ] ) ) { $signups = wp_parse_id_list( $_REQUEST['signup_ids' ] ); } // Handle resent activation links. if ( 'do_resend' == $doaction ) { // Nonce check. check_admin_referer( 'signups_resend' ); $resent = BP_Signup::resend( $signups ); if ( empty( $resent ) ) { $redirect_to = add_query_arg( 'error', $doaction, $redirect_to ); } else { $query_arg = array( 'updated' => 'resent' ); if ( ! empty( $resent['resent'] ) ) { $query_arg['resent'] = count( $resent['resent'] ); } if ( ! empty( $resent['errors'] ) ) { $query_arg['notsent'] = count( $resent['errors'] ); set_transient( '_bp_admin_signups_errors', $resent['errors'], 30 ); } $redirect_to = add_query_arg( $query_arg, $redirect_to ); } bp_core_redirect( $redirect_to ); // Handle activated accounts. } elseif ( 'do_activate' == $doaction ) { // Nonce check. check_admin_referer( 'signups_activate' ); $activated = BP_Signup::activate( $signups ); if ( empty( $activated ) ) { $redirect_to = add_query_arg( 'error', $doaction, $redirect_to ); } else { $query_arg = array( 'updated' => 'activated' ); if ( ! empty( $activated['activated'] ) ) { $query_arg['activated'] = count( $activated['activated'] ); } if ( ! empty( $activated['errors'] ) ) { $query_arg['notactivated'] = count( $activated['errors'] ); set_transient( '_bp_admin_signups_errors', $activated['errors'], 30 ); } $redirect_to = add_query_arg( $query_arg, $redirect_to ); } bp_core_redirect( $redirect_to ); // Handle sign-ups delete. } elseif ( 'do_delete' == $doaction ) { // Nonce check. check_admin_referer( 'signups_delete' ); $deleted = BP_Signup::delete( $signups ); if ( empty( $deleted ) ) { $redirect_to = add_query_arg( 'error', $doaction, $redirect_to ); } else { $query_arg = array( 'updated' => 'deleted' ); if ( ! empty( $deleted['deleted'] ) ) { $query_arg['deleted'] = count( $deleted['deleted'] ); } if ( ! empty( $deleted['errors'] ) ) { $query_arg['notdeleted'] = count( $deleted['errors'] ); set_transient( '_bp_admin_signups_errors', $deleted['errors'], 30 ); } $redirect_to = add_query_arg( $query_arg, $redirect_to ); } bp_core_redirect( $redirect_to ); // Plugins can update other stuff from here. } else { $this->redirect = $redirect_to; /** * Fires at end of signups admin load if doaction does not match any actions. * * @since 2.0.0 * * @param string $doaction Current bulk action being processed. * @param array $_REQUEST Current $_REQUEST global. * @param string $redirect Determined redirect url to send user to. */ do_action( 'bp_members_admin_update_signups', $doaction, $_REQUEST, $this->redirect ); bp_core_redirect( $this->redirect ); } } } /** * Display any activation errors. * * @since 2.0.0 */ public function signups_display_errors() { // Look for sign-up errors. $errors = get_transient( '_bp_admin_signups_errors' ); // Bail if no activation errors. if ( empty( $errors ) ) { return; } // Loop through errors and display them. foreach ( $errors as $error ) : ?>
  • :
  • 'updated', 'message' => '' ); if ( ! empty( $_REQUEST['resent'] ) ) { $notice['message'] .= sprintf( /* translators: %s: number of activation emails sent */ _nx( '%s activation email successfully sent! ', '%s activation emails successfully sent! ', absint( $_REQUEST['resent'] ), 'signup resent', 'buddypress' ), number_format_i18n( absint( $_REQUEST['resent'] ) ) ); } if ( ! empty( $_REQUEST['notsent'] ) ) { $notice['message'] .= sprintf( /* translators: %s: number of unsent activation emails */ _nx( '%s activation email was not sent.', '%s activation emails were not sent.', absint( $_REQUEST['notsent'] ), 'signup notsent', 'buddypress' ), number_format_i18n( absint( $_REQUEST['notsent'] ) ) ); if ( empty( $_REQUEST['resent'] ) ) { $notice['class'] = 'error'; } } break; case 'activated': $notice = array( 'class' => 'updated', 'message' => '' ); if ( ! empty( $_REQUEST['activated'] ) ) { $notice['message'] .= sprintf( /* translators: %s: number of activated accounts */ _nx( '%s account successfully activated! ', '%s accounts successfully activated! ', absint( $_REQUEST['activated'] ), 'signup resent', 'buddypress' ), number_format_i18n( absint( $_REQUEST['activated'] ) ) ); } if ( ! empty( $_REQUEST['notactivated'] ) ) { $notice['message'] .= sprintf( /* translators: %s: number of accounts not activated */ _nx( '%s account was not activated.', '%s accounts were not activated.', absint( $_REQUEST['notactivated'] ), 'signup notsent', 'buddypress' ), number_format_i18n( absint( $_REQUEST['notactivated'] ) ) ); if ( empty( $_REQUEST['activated'] ) ) { $notice['class'] = 'error'; } } break; case 'deleted': $notice = array( 'class' => 'updated', 'message' => '' ); if ( ! empty( $_REQUEST['deleted'] ) ) { $notice['message'] .= sprintf( /* translators: %s: number of deleted signups */ _nx( '%s sign-up successfully deleted!', '%s sign-ups successfully deleted!', absint( $_REQUEST['deleted'] ), 'signup deleted', 'buddypress' ), number_format_i18n( absint( $_REQUEST['deleted'] ) ) ); } if ( ! empty( $_REQUEST['notdeleted'] ) ) { $notdeleted = absint( $_REQUEST['notdeleted'] ); $notice['message'] .= sprintf( _nx( /* translators: %s: number of deleted signups not deleted */ '%s sign-up was not deleted.', '%s sign-ups were not deleted.', $notdeleted, 'signup notdeleted', 'buddypress' ), number_format_i18n( $notdeleted ) ); if ( empty( $_REQUEST['deleted'] ) ) { $notice['class'] = 'error'; } } break; } } // Errors. if ( ! empty( $_REQUEST['error'] ) ) { switch ( $_REQUEST['error'] ) { case 'do_resend': $notice = array( 'class' => 'error', 'message' => esc_html__( 'There was a problem sending the activation emails. Please try again.', 'buddypress' ), ); break; case 'do_activate': $notice = array( 'class' => 'error', 'message' => esc_html__( 'There was a problem activating accounts. Please try again.', 'buddypress' ), ); break; case 'do_delete': $notice = array( 'class' => 'error', 'message' => esc_html__( 'There was a problem deleting sign-ups. Please try again.', 'buddypress' ), ); break; } } return $notice; } /** * Signups admin page router. * * Depending on the context, display * - the list of signups, * - or the delete confirmation screen, * - or the activate confirmation screen, * - or the "resend" email confirmation screen. * * Also prepare the admin notices. * * @since 2.0.0 */ public function signups_admin() { $doaction = bp_admin_list_table_current_bulk_action(); // Prepare notices for admin. $notice = $this->get_signup_notice(); // Display notices. if ( ! empty( $notice ) ) : if ( 'updated' === $notice['class'] ) : ?>

    signups_admin_manage( $doaction ); break; default: $this->signups_admin_index(); break; } } /** * This is the list of the Pending accounts (signups). * * @since 2.0.0 * * @global $plugin_page * @global $bp_members_signup_list_table */ public function signups_admin_index() { global $plugin_page, $bp_members_signup_list_table; $usersearch = ! empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : ''; // Prepare the group items for display. $bp_members_signup_list_table->prepare_items(); if ( is_network_admin() ) { $form_url = network_admin_url( 'users.php' ); } else { $form_url = bp_get_admin_url( 'users.php' ); } $form_url = add_query_arg( array( 'page' => 'bp-signups', ), $form_url ); $search_form_url = remove_query_arg( array( 'action', 'deleted', 'notdeleted', 'error', 'updated', 'delete', 'activate', 'activated', 'notactivated', 'resend', 'resent', 'notresent', 'do_delete', 'do_activate', 'do_resend', 'action2', '_wpnonce', 'signup_ids' ), $_SERVER['REQUEST_URI'] ); ?>

    ' . __( 'Search results for “%s”', 'buddypress' ) . '', esc_html( $usersearch ) ); } ?>
    views(); ?>
    search_box( __( 'Search Pending Users', 'buddypress' ), 'bp-signups' ); ?>
    display(); ?>
    capability ) || empty( $action ) ) { die( '-1' ); } // Get the user IDs from the URL. $ids = false; if ( ! empty( $_POST['allsignups'] ) ) { $ids = wp_parse_id_list( $_POST['allsignups'] ); } elseif ( ! empty( $_GET['signup_id'] ) ) { $ids = absint( $_GET['signup_id'] ); } if ( empty( $ids ) ) { return false; } // Query for signups, and filter out those IDs that don't // correspond to an actual signup. $signups_query = BP_Signup::get( array( 'include' => $ids, ) ); $signups = $signups_query['signups']; $signup_ids = wp_list_pluck( $signups, 'id' ); // Set up strings. switch ( $action ) { case 'delete' : $header_text = __( 'Delete Pending Accounts', 'buddypress' ); if ( 1 == count( $signup_ids ) ) { $helper_text = __( 'You are about to delete the following account:', 'buddypress' ); } else { $helper_text = __( 'You are about to delete the following accounts:', 'buddypress' ); } break; case 'activate' : $header_text = __( 'Activate Pending Accounts', 'buddypress' ); if ( 1 == count( $signup_ids ) ) { $helper_text = __( 'You are about to activate the following account:', 'buddypress' ); } else { $helper_text = __( 'You are about to activate the following accounts:', 'buddypress' ); } break; case 'resend' : if ( bp_get_membership_requests_required() ) { $header_text = __( 'Approve Membership Requests', 'buddypress' ); if ( 1 === count( $signup_ids ) ) { $helper_text = __( 'You are about to send an approval email to the following user:', 'buddypress' ); } else { $helper_text = __( 'You are about to send approval emails to the following users:', 'buddypress' ); } } else { $header_text = __( 'Resend Activation Emails', 'buddypress' ); if ( 1 === count( $signup_ids ) ) { $helper_text = __( 'You are about to resend an activation email to the following account:', 'buddypress' ); } else { $helper_text = __( 'You are about to resend an activation email to the following accounts:', 'buddypress' ); } } break; } // These arguments are added to all URLs. $url_args = array( 'page' => 'bp-signups' ); // These arguments are only added when performing an action. $action_args = array( 'action' => 'do_' . $action, 'signup_ids' => implode( ',', $signup_ids ) ); if ( is_network_admin() ) { $base_url = network_admin_url( 'users.php' ); } else { $base_url = bp_get_admin_url( 'users.php' ); } $cancel_url = add_query_arg( $url_args, $base_url ); $action_url = wp_nonce_url( add_query_arg( array_merge( $url_args, $action_args ), $base_url ), 'signups_' . $action ); // Prefetch registration field data. $fdata = array(); if ( bp_is_active( 'xprofile' ) && ( 'activate' == $action || ( 'resend' == $action && bp_get_membership_requests_required() ) ) ) { $field_groups = bp_xprofile_get_groups( array( 'exclude_fields' => 1, 'update_meta_cache' => false, 'fetch_fields' => true, ) ); foreach( $field_groups as $fg ) { foreach( $fg->fields as $f ) { $fdata[ $f->id ] = $f->name; } } } ?>


      count_sent > 0 ) { $last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent ); } else { $last_notified = __( 'Not yet notified', 'buddypress' ); } $profile_field_ids = array(); // Get all xprofile field IDs except field 1. if ( ! empty( $signup->meta['profile_field_ids'] ) ) { $profile_field_ids = array_flip( explode( ',', $signup->meta['profile_field_ids'] ) ); unset( $profile_field_ids[1] ); } ?>
    1. user_login ) ?> $noop ) : $field_value = isset( $signup->meta[ "field_{$pid}" ] ) ? $signup->meta[ "field_{$pid}" ] : ''; ?>
      user_name ); ?>
      user_email ); ?>

      recently_sent ) ) : ?>

    users_type_change_notice(); // Bail if no users are specified or if this isn't a BuddyPress action. if ( empty( $_REQUEST['users'] ) || ( empty( $_REQUEST['bp_change_type'] ) && empty( $_REQUEST['bp_change_type2'] ) ) || empty( $_REQUEST['bp_change_member_type'] ) ) { return; } // Bail if nonce check fails. check_admin_referer( 'bp-bulk-users-change-type-' . bp_loggedin_user_id(), 'bp-bulk-users-change-type-nonce' ); // Bail if current user cannot promote users. if ( ! bp_current_user_can( 'promote_users' ) ) { return; } $new_type = ''; if ( ! empty( $_REQUEST['bp_change_type2'] ) ) { $new_type = sanitize_text_field( $_REQUEST['bp_change_type2'] ); } elseif ( ! empty( $_REQUEST['bp_change_type'] ) ) { $new_type = sanitize_text_field( $_REQUEST['bp_change_type'] ); } // Check that the selected type actually exists. if ( 'remove_member_type' != $new_type && null === bp_get_member_type_object( $new_type ) ) { $error = true; } else { // Run through user ids. $error = false; foreach ( (array) $_REQUEST['users'] as $user_id ) { $user_id = (int) $user_id; // Get the old member types to check against. $current_types = bp_get_member_type( $user_id, false ); if ( $current_types && 'remove_member_type' === $new_type ) { $member_types = array(); } elseif ( ! $current_types || 1 !== count( $current_types ) || $new_type !== $current_types[0] ) { // Set the new member type. $member_types = array( $new_type ); } if ( isset( $member_types ) ) { $set = bp_set_member_type( $user_id, $member_types ); if ( false === $set || is_wp_error( $set ) ) { $error = true; } unset( $member_types ); } } } // If there were any errors, show the error message. if ( $error ) { $redirect = add_query_arg( array( 'updated' => 'member-type-change-error' ), wp_get_referer() ); } else { $redirect = add_query_arg( array( 'updated' => 'member-type-change-success' ), wp_get_referer() ); } wp_redirect( $redirect ); exit(); } /** * Display an admin notice upon member type bulk update. * * @since 2.7.0 */ public function users_type_change_notice() { $updated = isset( $_REQUEST['updated'] ) ? $_REQUEST['updated'] : false; // Display feedback. if ( $updated && in_array( $updated, array( 'member-type-change-error', 'member-type-change-success' ), true ) ) { if ( 'member-type-change-error' === $updated ) { $notice = __( 'There was an error while changing member type. Please try again.', 'buddypress' ); $type = 'error'; } else { $notice = __( 'Member type was changed successfully.', 'buddypress' ); $type = 'updated'; } bp_core_add_admin_notice( $notice, $type ); } } /** * Add member type column to the WordPress admin users list table. * * @since 2.7.0 * * @param array $columns Users table columns. * * @return array $columns */ public function users_table_add_type_column( $columns = array() ) { $columns[ bp_get_member_type_tax_name() ] = _x( 'Member Type', 'Label for the WP users table member type column', 'buddypress' ); return $columns; } /** * Return member's type for display in the WP admin users list table. * * @since 2.7.0 * * @param string $retval * @param string $column_name * @param int $user_id * * @return string Member type as a link to filter all users. */ public function users_table_populate_type_cell( $retval = '', $column_name = '', $user_id = 0 ) { // Only looking for member type column. if ( bp_get_member_type_tax_name() !== $column_name ) { return $retval; } // Get the member type. $member_type = bp_get_member_type( $user_id, false ); // Build the Output. if ( $member_type ) { $member_types = array_filter( array_map( 'bp_get_member_type_object', $member_type ) ); if ( ! $member_types ) { return $retval; } $type_links = array(); foreach ( $member_types as $type ) { $url = add_query_arg( array( 'bp-member-type' => urlencode( $type->name ) ) ); $type_links[] = sprintf( '%2$s', esc_url( $url ), esc_html( $type->labels['singular_name'] ) ); } $retval = implode( ', ', $type_links ); } return $retval; } /** * Filter WP Admin users list table to include users of the specified type. * * @param WP_Query $query * * @since 2.7.0 */ public function users_table_filter_by_type( $query ) { global $pagenow; if ( is_admin() && 'users.php' === $pagenow && ! empty( $_REQUEST['bp-member-type'] ) ) { $type_slug = sanitize_text_field( $_REQUEST['bp-member-type'] ); // Check that the type is registered. if ( null == bp_get_member_type_object( $type_slug ) ) { return; } // Get the list of users that are assigned to this member type. $type = bp_get_term_by( 'slug', $type_slug, bp_get_member_type_tax_name() ); if ( empty( $type->term_id ) ) { return; } $user_ids = bp_get_objects_in_term( $type->term_id, bp_get_member_type_tax_name() ); if ( $user_ids && ! is_wp_error( $user_ids ) ) { $query->set( 'include', (array) $user_ids ); } } } /** * Formats a signup's xprofile field data for display. * * Operates recursively on arrays, which are then imploded with commas. * * @since 2.8.0 * @deprecated 10.0.0 * * @param string|array $value Field value. * @return string */ protected function format_xprofile_field_for_display( $value ) { _deprecated_function( __METHOD__, '10.0.0', 'bp_members_admin_format_xprofile_field_for_display' ); return bp_members_admin_format_xprofile_field_for_display( $value ); } /** * Set up the signups admin page. * * Loaded before the page is rendered, this function does all initial * setup, including: processing form requests, registering contextual * help, and setting up screen options. * * @since 8.0.0 * * @global $bp_members_invitations_list_table */ public function members_invitations_admin_load() { global $bp_members_invitations_list_table; // Build redirection URL. $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'] ); $doaction = bp_admin_list_table_current_bulk_action(); /** * Fires at the start of the member invitations admin load. * * @since 8.0.0 * * @param string $doaction Current bulk action being processed. * @param array $_REQUEST Current $_REQUEST global. */ do_action( 'bp_members_invitations_admin_load', $doaction, $_REQUEST ); /** * Filters the allowed actions for use in the user signups admin page. * * @since 8.0.0 * * @param array $value Array of allowed actions to use. */ $allowed_actions = apply_filters( 'bp_members_invitations_admin_allowed_actions', array( 'do_delete', 'do_resend' ) ); // Prepare the display of the bulk invitation action screen. if ( ! in_array( $doaction, $allowed_actions ) ) { $bp_members_invitations_list_table = self::get_list_table_class( 'BP_Members_Invitations_List_Table', 'users' ); // The per_page screen option. add_screen_option( 'per_page', array( 'label' => _x( 'Members Invitations', 'Members Invitations per page (screen options)', 'buddypress' ) ) ); get_current_screen()->add_help_tab( array( 'id' => 'bp-members-invitations-overview', 'title' => __( 'Overview', 'buddypress' ), 'content' => '

    ' . __( 'This is the administration screen for member invitations on your site.', 'buddypress' ) . '

    ' . '

    ' . __( 'From the screen options, you can customize the displayed columns and the pagination of this screen.', 'buddypress' ) . '

    ' . '

    ' . __( 'You can reorder the list of invitations by clicking on the Invitee, Inviter, Date Modified, Email Sent, or Accepted column headers.', 'buddypress' ) . '

    ' . '

    ' . __( 'Using the search form, you can find specific invitations more easily. The Invitee Email field will be included in the search.', 'buddypress' ) . '

    ' ) ); get_current_screen()->add_help_tab( array( 'id' => 'bp-members-invitations-actions', 'title' => __( 'Actions', 'buddypress' ), 'content' => '

    ' . __( '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' ) . '

    ' . '' . '

    ' . __( 'Bulk actions allow you to perform these actions for the selected rows.', 'buddypress' ) . '

    ' ) ); // Help panel - sidebar links. get_current_screen()->set_help_sidebar( '

    ' . __( 'For more information:', 'buddypress' ) . '

    ' . '

    ' . __( 'Support Forums', 'buddypress' ) . '

    ' ); // Add accessible hidden headings and text for the Pending Users screen. get_current_screen()->set_screen_reader_content( array( /* translators: accessibility text */ 'heading_views' => __( 'Filter invitations list', 'buddypress' ), /* translators: accessibility text */ 'heading_pagination' => __( 'Invitation list navigation', 'buddypress' ), /* translators: accessibility text */ 'heading_list' => __( 'Invitations list', 'buddypress' ), ) ); } else { if ( empty( $_REQUEST['invite_ids' ] ) ) { return; } $invite_ids = wp_parse_id_list( $_REQUEST['invite_ids' ] ); // Handle resent invitations. if ( 'do_resend' == $doaction ) { // Nonce check. check_admin_referer( 'invitations_resend' ); $success = 0; foreach ( $invite_ids as $invite_id ) { if ( bp_members_invitation_resend_by_id( $invite_id ) ) { $success++; } } $query_arg = array( 'updated' => 'resent' ); if ( ! empty( $success ) ) { $query_arg['resent'] = $success; } $not_sent = count( $invite_ids ) - $success; if ( $not_sent > 0 ) { $query_arg['notsent'] = $not_sent; } $redirect_to = add_query_arg( $query_arg, $redirect_to ); bp_core_redirect( $redirect_to ); // Handle invitation deletion. } elseif ( 'do_delete' == $doaction ) { // Nonce check. check_admin_referer( 'invitations_delete' ); $success = 0; foreach ( $invite_ids as $invite_id ) { if ( bp_members_invitations_delete_by_id( $invite_id ) ) { $success++; } } $query_arg = array( 'updated' => 'deleted' ); if ( ! empty( $success ) ) { $query_arg['deleted'] = $success; } $notdeleted = count( $invite_ids ) - $success; if ( $notdeleted > 0 ) { $query_arg['notdeleted'] = $notdeleted; } $redirect_to = add_query_arg( $query_arg, $redirect_to ); bp_core_redirect( $redirect_to ); // Plugins can update other stuff from here. } else { $this->redirect = $redirect_to; /** * Fires at end of member invitations admin load * if doaction does not match any actions. * * @since 8.0.0 * * @param string $doaction Current bulk action being processed. * @param array $_REQUEST Current $_REQUEST global. * @param string $redirect Determined redirect url to send user to. */ do_action( 'bp_members_admin_update_invitations', $doaction, $_REQUEST, $this->redirect ); bp_core_redirect( $this->redirect ); } } } /** * Get admin notice when viewing the invitations management page. * * @since 8.0.0 * * @return array */ private function get_members_invitations_notice() { // Setup empty notice for return value. $notice = array(); // Updates. if ( ! empty( $_REQUEST['updated'] ) ) { switch ( $_REQUEST['updated'] ) { case 'resent': $notice = array( 'class' => 'updated', 'message' => '' ); if ( ! empty( $_REQUEST['resent'] ) ) { $resent = absint( $_REQUEST['resent'] ); $notice['message'] .= sprintf( _nx( /* translators: %s: number of invitation emails sent */ '%s invtitation email successfully sent! ', '%s invitation emails successfully sent! ', $resent, 'members invitation resent', 'buddypress' ), number_format_i18n( $resent ) ); } if ( ! empty( $_REQUEST['notsent'] ) ) { $notsent = absint( $_REQUEST['notsent'] ); $notice['message'] .= sprintf( _nx( /* translators: %s: number of unsent invitation emails */ '%s invitation email was not sent.', '%s invitation emails were not sent.', $notsent, 'members invitation notsent', 'buddypress' ), number_format_i18n( $notsent ) ); if ( empty( $_REQUEST['resent'] ) ) { $notice['class'] = 'error'; } } break; case 'deleted': $notice = array( 'class' => 'updated', 'message' => '' ); if ( ! empty( $_REQUEST['deleted'] ) ) { $deleted = absint( $_REQUEST['deleted'] ); $notice['message'] .= sprintf( _nx( /* translators: %s: number of deleted invitations */ '%s invitation successfully deleted!', '%s invitations successfully deleted!', $deleted, 'members invitation deleted', 'buddypress' ), number_format_i18n( $deleted ) ); } if ( ! empty( $_REQUEST['notdeleted'] ) ) { $notdeleted = absint( $_REQUEST['notdeleted'] ); $notice['message'] .= sprintf( _nx( /* translators: %s: number of invitations that failed to be deleted */ '%s invitation was not deleted.', '%s invitations were not deleted.', $notdeleted, 'members invitation notdeleted', 'buddypress' ), number_format_i18n( $notdeleted ) ); if ( empty( $_REQUEST['deleted'] ) ) { $notice['class'] = 'error'; } } break; } } // Errors. if ( ! empty( $_REQUEST['error'] ) ) { switch ( $_REQUEST['error'] ) { case 'do_resend': $notice = array( 'class' => 'error', 'message' => esc_html__( 'There was a problem sending the invitation emails. Please try again.', 'buddypress' ), ); break; case 'do_delete': $notice = array( 'class' => 'error', 'message' => esc_html__( 'There was a problem deleting invitations. Please try again.', 'buddypress' ), ); break; } } return $notice; } /** * Member invitations admin page router. * * Depending on the context, display * - the list of invitations, * - or the delete confirmation screen, * - or the "resend" email confirmation screen. * * Also prepare the admin notices. * * @since 8.0.0 */ public function invitations_admin() { $doaction = bp_admin_list_table_current_bulk_action(); // Prepare notices for admin. $notice = $this->get_members_invitations_notice(); // Display notices. if ( ! empty( $notice ) ) : if ( 'updated' === $notice['class'] ) : ?>

    invitations_admin_manage( $doaction ); break; default: $this->invitations_admin_index(); break; } } /** * This is the list of invitations. * * @since 8.0.0 * * @global $plugin_page * @global $bp_members_invitations_list_table */ public function invitations_admin_index() { global $plugin_page, $bp_members_invitations_list_table; $usersearch = ! empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : ''; // Prepare the group items for display. $bp_members_invitations_list_table->prepare_items(); if ( is_network_admin() ) { $form_url = network_admin_url( 'admin.php' ); } else { $form_url = bp_get_admin_url( 'tools.php' ); } $form_url = add_query_arg( array( 'page' => 'bp-members-invitations', ), $form_url ); $search_form_url = remove_query_arg( array( 'action', 'deleted', 'notdeleted', 'error', 'updated', 'delete', 'activate', 'activated', 'notactivated', 'resend', 'resent', 'notresent', 'do_delete', 'do_activate', 'do_resend', 'action2', '_wpnonce', 'invite_ids' ), $_SERVER['REQUEST_URI'] ); bp_core_admin_tabbed_screen_header( __( 'BuddyPress tools', 'buddypress' ), __( 'Manage Invitations', 'buddypress' ), 'tools' ); ?>
    ' . __( 'Search results for “%s”', 'buddypress' ) . '', esc_html( $usersearch ) ); } ?> views(); ?>
    search_box( __( 'Search Invitations', 'buddypress' ), 'bp-members-invitations' ); ?>
    display(); ?>
    capability ) || empty( $action ) ) { die( '-1' ); } // Get the IDs from the URL. $ids = false; if ( ! empty( $_POST['invite_ids'] ) ) { $ids = wp_parse_id_list( $_POST['invite_ids'] ); } elseif ( ! empty( $_GET['invite_id'] ) ) { $ids = absint( $_GET['invite_id'] ); } if ( empty( $ids ) ) { return false; } // Check invite IDs and set up strings. switch ( $action ) { case 'delete' : // Query for matching invites, and filter out bad IDs. $args = array( 'id' => $ids, 'invite_sent' => 'all', 'accepted' => 'all', ); $invites = bp_members_invitations_get_invites( $args ); $invite_ids = wp_list_pluck( $invites, 'id' ); $header_text = __( 'Delete Invitations', 'buddypress' ); if ( 0 === count( $invite_ids ) ) { $helper_text = __( 'No invites were found, nothing to delete!', 'buddypress' ); } else { $helper_text = _n( 'You are about to delete the following invitation:', 'You are about to delete the following invitations:', count( $invite_ids ), 'buddypress' ); } break; case 'resend' : /** * Query for matching invites, and filter out bad IDs * or those that have already been accepted. */ $args = array( 'id' => $ids, 'invite_sent' => 'all', 'accepted' => 'pending', ); $invites = bp_members_invitations_get_invites( $args ); $invite_ids = wp_list_pluck( $invites, 'id' ); $header_text = __( 'Resend Invitation Emails', 'buddypress' ); if ( 0 === count( $invite_ids ) ) { $helper_text = __( 'No pending invites were found, nothing to resend!', 'buddypress' ); } else { $helper_text = _n( 'You are about to resend an invitation email to the following address:', 'You are about to resend invitation emails to the following addresses:', count( $invite_ids ), 'buddypress' ); } break; } // These arguments are added to all URLs. $url_args = array( 'page' => 'bp-members-invitations' ); // These arguments are only added when performing an action. $action_args = array( 'action' => 'do_' . $action, 'invite_ids' => implode( ',', $invite_ids ) ); if ( is_network_admin() ) { $base_url = network_admin_url( 'admin.php' ); } else { $base_url = bp_get_admin_url( 'tools.php' ); } $cancel_url = add_query_arg( $url_args, $base_url ); $action_url = wp_nonce_url( add_query_arg( array_merge( $url_args, $action_args ), $base_url ), 'invitations_' . $action ); bp_core_admin_tabbed_screen_header( __( 'BuddyPress tools', 'buddypress' ), __( 'Manage Invitations', 'buddypress' ), 'tools' ); ?>

      invite_sent ) { $last_notified = mysql2date( 'Y/m/d g:i:s a', $invite->date_modified ); } else { $last_notified = __( 'Not yet notified', 'buddypress'); } ?>
    1. invitee_email ) ?>

    >