* @copyright Copyright (c) 2009 - 2018, Justin Tadlock * @link https://themehybrid.com/plugins/members * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html */ namespace Members\Admin; /** * Manager users screen class. * * @since 2.0.0 * @access public */ final class Manage_Users { /** * Holds the instances of this class. * * @since 2.0.0 * @access private * @var object */ private static $instance = null; /** * Custom admin notices. * * @since 2.0.0 * @access public * @var array */ public $notices = array(); /** * Constructore method. * * @since 2.0.0 * @access private * @return void */ private function __construct() {} /** * Sets up needed actions/filters. * * @since 2.0.0 * @access private * @return void */ private function setup_actions() { // If multiple roles per user is not enabled, bail. if ( ! members_multiple_user_roles_enabled() ) return; // Add our primary actions to the load hook. add_action( 'load-users.php', array( $this, 'load' ) ); add_action( 'load-users.php', array( $this, 'role_bulk_add' ) ); add_action( 'load-users.php', array( $this, 'role_bulk_remove' ) ); } /** * Adds actions/filters on load. * * @since 2.0.0 * @access public * @return void */ public function load() { // Add custom bulk fields. add_action( 'restrict_manage_users', array( $this, 'bulk_fields' ), 5 ); // Custom manage users columns. add_filter( 'manage_users_columns', array( $this, 'manage_users_columns' ) ); // Handle scripts and styles. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) ); add_action( 'admin_footer', array( $this, 'print_scripts' ), 25 ); add_action( 'admin_head', array( $this, 'print_styles' ) ); // If there was an update, add notices if they're from our plugin. if ( isset( $_GET['update'] ) ) { $action = sanitize_key( $_GET['update'] ); // If a role was added. if ( 'members-role-added' === $action ) { $this->notices['role_added'] = array( 'message' => esc_html__( 'Role added to selected users.', 'members' ), 'type' => 'success' ); // If a role was removed. } elseif ( 'members-role-removed' === $action ) { $this->notices['role_removed'] = array( 'message' => esc_html__( 'Role removed from selected users.', 'members' ), 'type' => 'success' ); } elseif ( 'members-error-remove-admin' === $action ) { $this->notices['error_remove_admin'] = array( 'message' => esc_html__( 'The current user’s role must have user editing capabilities.', 'members' ), 'type' => 'error' ); $this->notices['role_removed'] = array( 'message' => esc_html__( 'Role removed from other selected users.', 'members' ), 'type' => 'success' ); } // If we have notices, hook them in. if ( $this->notices ) add_action( 'admin_notices', array( $this, 'notices' ) ); } } /** * Adds a single role to users in bulk. * * @since 2.0.0 * @access public * @return void */ public function role_bulk_add() { // Bail if we ain't got users. if ( empty( $_REQUEST['users'] ) ) return; // Figure out if we have a role selected. if ( ! empty( $_REQUEST['members-add-role-top'] ) && ! empty( $_REQUEST['members-add-role-submit-top'] ) ) $role = members_sanitize_role( $_REQUEST['members-add-role-top'] ); elseif ( ! empty( $_REQUEST['members-add-role-bottom'] ) && ! empty( $_REQUEST['members-add-role-submit-bottom'] ) ) $role = members_sanitize_role( $_REQUEST['members-add-role-bottom'] ); // Get only editable roles. $editable_roles = members_get_editable_roles(); // If we don't have a role or the role is not editable, bail. if ( empty( $role ) || ! in_array( $role, $editable_roles ) ) return; // Validate our nonce. check_admin_referer( 'members-bulk-users', 'members-bulk-users-nonce' ); // If the current user cannot promote users, bail. if ( ! current_user_can( 'promote_users' ) ) return; // Loop through the users and add the role if possible. foreach ( (array) $_REQUEST['users'] as $user_id ) { $user_id = absint( $user_id ); // If the user doesn't already belong to the blog, bail. if ( is_multisite() && ! is_user_member_of_blog( $user_id ) ) { wp_die( sprintf( '
%s
', esc_html__( 'Whoah, partner!', 'members' ), esc_html__( 'One of the selected users is not a member of this site.', 'members' ) ), 403 ); } // Check that the current user can promote this specific user. if ( ! current_user_can( 'promote_user', $user_id ) ) continue; // Get the user object. $user = new \WP_User( $user_id ); // If the user doesn't have the role, add it. if ( ! in_array( $role, $user->roles ) ) $user->add_role( $role ); } // Redirect to the users screen. wp_redirect( add_query_arg( 'update', 'members-role-added', 'users.php' ) ); } /** * Removes a single role from users in bulk. * * @since 2.0.0 * @access public * @return void */ public function role_bulk_remove() { // Bail if we ain't got users. if ( empty( $_REQUEST['users'] ) ) return; // Figure out if we have a role selected. if ( ! empty( $_REQUEST['members-remove-role-top'] ) && ! empty( $_REQUEST['members-remove-role-submit-top'] ) ) $role = members_sanitize_role( $_REQUEST['members-remove-role-top'] ); elseif ( ! empty( $_REQUEST['members-remove-role-bottom'] ) && ! empty( $_REQUEST['members-remove-role-submit-bottom'] ) ) $role = members_sanitize_role( $_REQUEST['members-remove-role-bottom'] ); // Get only editable roles. $editable_roles = members_get_editable_roles(); // If we don't have a role or the role is not editable, bail. if ( empty( $role ) || ! in_array( $role, $editable_roles ) ) return; // Validate our nonce. check_admin_referer( 'members-bulk-users', 'members-bulk-users-nonce' ); // If the current user cannot promote users, bail. if ( ! current_user_can( 'promote_users' ) ) return; // Get the current user. $current_user = wp_get_current_user(); $m_role = members_get_role( $role ); $update = 'members-role-removed'; // Loop through the users and remove the role if possible. foreach ( (array) $_REQUEST['users'] as $user_id ) { $user_id = absint( $user_id ); // If the user doesn't already belong to the blog, bail. if ( is_multisite() && ! is_user_member_of_blog( $user_id ) ) { wp_die( sprintf( '%s
', esc_html__( 'Whoah, partner!', 'members' ), esc_html__( 'One of the selected users is not a member of this site.', 'members' ) ), 403 ); } // Check that the current user can promote this specific user. if ( ! current_user_can( 'promote_user', $user_id ) ) continue; $is_current_user = $user_id == $current_user->ID; $role_can_promote = in_array( 'promote_users', $m_role->granted_caps ); $can_manage_network = is_multisite() && current_user_can( 'manage_network_users' ); // If the removed role has the `promote_users` cap and user is removing it from themselves. if ( $is_current_user && $role_can_promote && ! $can_manage_network ) { $can_remove = false; // Loop through the current user's roles. foreach ( $current_user->roles as $_r ) { // If the current user has another role that can promote users, it's // safe to remove the role. Else, the current user needs to keep // the role. if ( $role !== $_r && in_array( 'promote_users', members_get_role( $_r )->granted_caps ) ) { $can_remove = true; break; } } if ( ! $can_remove ) { $update = 'members-error-remove-admin'; continue; } } // Get the user object. $user = new \WP_User( $user_id ); // If the user has the role, remove it. if ( in_array( $role, $user->roles ) ) $user->remove_role( $role ); } // Redirect to the users screen. wp_redirect( add_query_arg( 'update', $update, 'users.php' ) ); } /** * Print admin notices. * * @since 2.0.0 * @access public * @param string $which * @return void */ public function notices() { if ( $this->notices ) : ?> notices as $notice ) : ?>