/** * Adds the meta box. * * @since 1.0.0 * @access public * @param string $screen_id * @param string $role * @return void */ public function add_meta_boxes($screen_id, $role = '') { // If role isn't editable, bail. if ($role && !members_is_role_editable($role)) { return; } // Add the meta box. add_meta_box('newcapdiv', esc_html__('Custom Capability', 'members'), array($this, 'meta_box'), $screen_id, 'side', 'core'); }
/** * Outputs the role level meta box. * * @since 1.0.0 * @access public * @param object $role * @return void */ public function meta_box($role) { // If the role isn't editable, the field should be read-only. $is_editable = $role ? members_is_role_editable($role->name) : true; $readonly = $is_editable ? '' : ' disabled="disabled" readonly="readonly"'; // Get the role level. $role_level = mrl_get_role_level($role); // If there is no role level, check if cloning or error. if (!$role_level) { // If there was a posted level (error). if (isset($_POST['mrl-role-level']) && mrl_is_valid_level($_POST['mrl-role-level'])) { $role_level = $_POST['mrl-role-level']; } else { if (isset($_GET['page']) && 'role-new' === $_GET['page'] && !empty($_GET['clone'])) { $role_level = mrl_get_role_level(members_sanitize_role($_GET['clone'])); } } } // If still no level, set it to `level_0`. $role_level = $role_level ? $role_level : 'level_0'; wp_nonce_field('role_level', 'mrl_role_level_nonce'); ?> <p> <select class="widefat" name="mrl-role-level"<?php echo $readonly; ?> > <?php foreach (mrl_get_role_levels() as $level => $label) { ?> <option value="<?php echo esc_attr($level); ?> " <?php selected($level, $role_level); ?> ><?php echo esc_html($label); ?> </option> <?php } ?> </select> </p> <?php }
/** * Handles the row actions. * * @since 1.0.0 * @access protected * @param string $role * @param string $column_name * @param string $primary * @return array */ protected function handle_row_actions($role, $column_name, $primary) { $actions = array(); // Only add row actions on the primary column (title/role name). if ($primary === $column_name) { // If the role can be edited. if (members_is_role_editable($role)) { // If the current user can edit the role, add an edit link. if (current_user_can('edit_roles')) { $actions['edit'] = sprintf('<a href="%s">%s</a>', esc_url(members_get_edit_role_url($role)), esc_html__('Edit', 'members')); } // If the current user can delete the role, add a delete link. if (is_multisite() && is_super_admin() && $role !== $this->default_role || current_user_can('delete_roles') && $role !== $this->default_role && !current_user_can($role)) { $actions['delete'] = sprintf('<a class="members-delete-role-link" href="%s">%s</a>', esc_url(members_get_delete_role_url($role)), esc_html__('Delete', 'members')); } // If the role cannot be edited. } else { // Add the view role link. $actions['view'] = sprintf('<a href="%s">%s</a>', esc_url(members_get_edit_role_url($role)), esc_html__('View', 'members')); } // If the current user can create roles, add the clone role link. if (current_user_can('create_roles')) { $actions['clone'] = sprintf('<a href="%s">%s</a>', esc_url(members_get_clone_role_url($role)), esc_html__('Clone', 'members')); } // If this is the default role and the current user can manage options, add a default role change link. if (current_user_can('manage_options') && $role === $this->default_role) { $actions['default_role'] = sprintf('<a href="%s">%s</a>', esc_url(admin_url('options-general.php#default_role')), esc_html__('Change Default', 'members')); } // If the currrent user can view users, add a users link. if (current_user_can('list_users')) { $actions['users'] = sprintf('<a href="%s">%s</a>', members_get_role_users_url($role), esc_html__('Users', 'members')); } // Allow devs to filter the row actions. $actions = apply_filters('members_roles_row_actions', $actions, $role); } return $this->row_actions($actions); }
/** * Outputs the meta box HTML. * * @since 1.0.0 * @access public * @param object $role * @return void */ public function meta_box($role) { // Set up some defaults for new roles. $is_editable = true; $user_count = 0; $grant_count = 0; $deny_count = 0; // If we're editing a role, overwrite the defaults. if ($role) { $is_editable = members_is_role_editable($role->name); $user_count = members_get_role_user_count($role->name); $grant_count = members_get_role_granted_cap_count($role->name); $deny_count = members_get_role_denied_cap_count($role->name); } ?> <div class="submitbox" id="submitpost"> <div id="misc-publishing-actions"> <div class="misc-pub-section misc-pub-section-users"> <i class="dashicons dashicons-admin-users"></i> <?php esc_html_e('Users:', 'members'); ?> <strong class="user-count"><?php echo number_format_i18n($user_count); ?> </strong> </div> <div class="misc-pub-section misc-pub-section-granted"> <i class="dashicons dashicons-yes"></i> <?php esc_html_e('Granted:', 'members'); ?> <strong class="granted-count"><?php echo number_format_i18n($grant_count); ?> </strong> </div> <div class="misc-pub-section misc-pub-section-denied"> <i class="dashicons dashicons-no"></i> <?php esc_html_e('Denied:', 'members'); ?> <strong class="denied-count"><?php echo number_format_i18n($deny_count); ?> </strong> </div> </div><!-- #misc-publishing-actions --> <div id="major-publishing-actions"> <div id="delete-action"> <?php if ($is_editable && $role) { ?> <a class="submitdelete deletion members-delete-role-link" href="<?php echo esc_url(members_get_delete_role_url($role->name)); ?> "><?php echo esc_html_x('Delete', 'delete role', 'members'); ?> </a> <?php } ?> </div> <div id="publishing-action"> <?php if ($is_editable) { ?> <?php submit_button($role ? esc_attr__('Update', 'members') : esc_attr__('Add Role', 'members'), 'primary', 'publish', false, array('id' => 'publish')); ?> <?php } ?> </div><!-- #publishing-action --> <div class="clear"></div> </div><!-- #major-publishing-actions --> </div><!-- .submitbox --> <?php }
/** * Runs on the `load-{$page}` hook. This is the handler for form submissions. * * @since 1.0.0 * @access public * @return void */ public function load() { // If the current user can't edit roles, don't proceed. if (!current_user_can('edit_roles')) { wp_die(esc_html__('Whoah, partner!', 'members')); } // Get the current role object to edit. $this->role = get_role(members_sanitize_role($_GET['role'])); // If we don't have a real role, die. if (is_null($this->role)) { wp_die(esc_html__('The requested role to edit does not exist.', 'members')); } $this->members_role = members_get_role($this->role->name); // Get all the capabilities. $this->capabilities = members_get_capabilities(); // Add all caps from the cap groups. foreach (members_get_cap_groups() as $group) { $this->capabilities = array_merge($this->capabilities, $group->caps); } // Make sure we have a unique array of caps. $this->capabilities = array_unique($this->capabilities); // Is the role editable? $this->is_editable = members_is_role_editable($this->role->name); // Check if the form has been submitted. if ($this->is_editable && isset($_POST['members_edit_role_nonce'])) { // Verify the nonce. check_admin_referer('edit_role', 'members_edit_role_nonce'); // Get the granted and denied caps. $grant_caps = !empty($_POST['grant-caps']) ? array_unique($_POST['grant-caps']) : array(); $deny_caps = !empty($_POST['deny-caps']) ? array_unique($_POST['deny-caps']) : array(); // Get the new (custom) granted and denied caps. $grant_new_caps = !empty($_POST['grant-new-caps']) ? array_unique($_POST['grant-new-caps']) : array(); $deny_new_caps = !empty($_POST['deny-new-caps']) ? array_unique($_POST['deny-new-caps']) : array(); // Get the all and custom cap group objects. $all_group = members_get_cap_group('all'); $custom_group = members_get_cap_group('custom'); // New caps to push to cap groups on update. $push_caps = array(); // Set the $role_updated variable to true. $this->role_updated = true; // Loop through all available capabilities. foreach ($this->capabilities as $cap) { // Get the posted capability. $grant_this_cap = in_array($cap, $grant_caps); $deny_this_cap = in_array($cap, $deny_caps); // Does the role have the cap? $is_granted_cap = $this->role->has_cap($cap); $is_denied_cap = isset($this->role->capabilities[$cap]) && false === $this->role->capabilities[$cap]; if ($grant_this_cap && !$is_granted_cap) { $this->role->add_cap($cap); } else { if ($deny_this_cap && !$is_denied_cap) { $this->role->add_cap($cap, false); } else { if (!$grant_this_cap && $is_granted_cap) { $this->role->remove_cap($cap); } else { if (!$deny_this_cap && $is_denied_cap) { $this->role->remove_cap($cap); } } } } } // End loop through existing capabilities. // Loop through the custom granted caps. foreach ($grant_new_caps as $grant_new_cap) { $_cap = members_sanitize_cap($grant_new_cap); // If not an existing cap, add it. if (!in_array($_cap, $this->capabilities)) { $this->role->add_cap($_cap); $push_caps[] = $_cap; } } // Loop through the custom denied caps. foreach ($deny_new_caps as $deny_new_cap) { $_cap = members_sanitize_cap($deny_new_cap); // If not a granted cap and not an existing cap, add it. if (!in_array($_cap, $this->capabilities) && !in_array($_cap, $grant_new_caps)) { $this->role->add_cap($_cap, false); $push_caps[] = $_cap; } } // If there are new caps, add them to the all and custom groups. if ($push_caps) { if ($all_group) { $all_group->caps[] = $_cap; sort($all_group->caps); } if ($custom_group) { $custom_group->caps[] = $_cap; sort($custom_group->caps); } } // Add the updated role to the role factory. members_role_factory()->add_role($this->role->name); // Reset the Members role object. $this->members_role = members_get_role($this->role->name); // Action hook for when a role is updated. do_action('members_role_updated', $this->role->name); } // End check for form submission. // If successful update. if ($this->role_updated) { add_settings_error('members_edit_role', 'role_updated', sprintf(esc_html__('%s role updated.', 'members'), members_get_role_name($this->role->name)), 'updated'); } // If the role is not editable. if (!$this->is_editable) { add_settings_error('members_edit_role', 'role_uneditable', sprintf(esc_html__('The %s role is not editable. This means that it is most likely added via another plugin for a special use or that you do not have permission to edit it.', 'members'), members_get_role_name($this->role->name))); } // If a new role was added (redirect from new role screen). if (isset($_GET['message']) && 'role_added' === $_GET['message']) { add_settings_error('members_edit_role', 'role_added', sprintf(esc_html__('The %s role has been created.', 'members'), members_get_role_name($this->role->name)), 'updated'); } // Load page hook. do_action('members_load_role_edit'); // Hook for adding in meta boxes. do_action('add_meta_boxes_' . get_current_screen()->id, $this->role->name); do_action('add_meta_boxes', get_current_screen()->id, $this->role->name); // Add layout screen option. add_screen_option('layout_columns', array('max' => 2, 'default' => 2)); }
/** * Adds custom data to the json array. This data is passed to the Underscore template. * * @since 1.0.0 * @access public * @return void */ public function to_json() { // Is the role editable? $is_editable = $this->manager->role ? members_is_role_editable($this->manager->role->name) : true; // Set up the ID and class. $this->json['id'] = $this->section; $this->json['class'] = 'members-tab-content' . ($is_editable ? ' editable-role' : ''); }
/** * Adds custom data to the json array. This data is passed to the Underscore template. * * @since 1.0.0 * @access public * @return void */ public function to_json() { // Is the role editable? $is_editable = $this->manager->role ? members_is_role_editable($this->manager->role->name) : true; // Get the current capability. $this->json['cap'] = $this->cap; // Add the section ID. $this->json['section'] = $this->section; // If the cap is not editable, the inputs should be read-only. $this->json['readonly'] = $is_editable ? '' : ' disabled="disabled" readonly="readonly"'; // Set up the input labels. $this->json['label'] = array('grant' => sprintf(esc_html__('Grant %s capability', 'members'), "<code>{$this->cap}</code>"), 'deny' => sprintf(esc_html__('Deny %s capability', 'members'), "<code>{$this->cap}</code>")); // Set up the input `name` attributes. $this->json['name'] = array('grant' => 'grant-caps[]', 'deny' => 'deny-caps[]'); // Is this a granted or denied cap? $this->json['is_granted_cap'] = isset($this->manager->has_caps[$this->cap]) && $this->manager->has_caps[$this->cap]; $this->json['is_denied_cap'] = isset($this->manager->has_caps[$this->cap]) && false === $this->manager->has_caps[$this->cap]; }
/** * Callback function for handling user role changes. Note that we needed to execute this function * on a different hook, `profile_update`. Using the normal hooks on the edit user screen won't work * because WP will wipe out the role. * * @since 1.0.0 * @access public * @param int $user_id * @return void */ public function role_update($user_id) { // If the current user can't promote users or edit this particular user, bail. if (!current_user_can('promote_users') || !current_user_can('edit_user', $user_id)) { return; } // Is this a role change? if (!isset($_POST['members_new_user_roles_nonce']) || !wp_verify_nonce($_POST['members_new_user_roles_nonce'], 'new_user_roles')) { return; } // Create a new user object. $user = new WP_User($user_id); // If we have an array of roles. if (!empty($_POST['members_user_roles'])) { // Get the current user roles. $old_roles = (array) $user->roles; // Sanitize the posted roles. $new_roles = array_map('members_sanitize_role', $_POST['members_user_roles']); // Loop through the posted roles. foreach ($new_roles as $new_role) { // If the user doesn't already have the role, add it. if (!in_array($new_role, (array) $user->roles)) { $user->add_role($new_role); } } // Loop through the current user roles. foreach ($old_roles as $old_role) { // If the role is editable and not in the new roles array, remove it. if (members_is_role_editable($old_role) && !in_array($old_role, $new_roles)) { $user->remove_role($old_role); } } // If the posted roles are empty. } else { // Loop through the current user roles. foreach ((array) $user->roles as $old_role) { // Remove the role if it is editable. if (members_is_role_editable($old_role)) { $user->remove_role($old_role); } } } }