PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 9.0.2
Admin and Site Enhancements (ASE) v9.0.2
9.1.1 9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 8.3.2 8.4.0 8.4.1 8.4.2 8.5.0 8.5.1 8.5.2 8.6.0 8.6.1 8.6.2 8.7.0 5.0.1 5.0.2 5.0.2.1 5.0.2.2 5.0.2.3 5.0.2.4 5.1.0 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.8.0 5.8.1 6.0.0 6.0.3 6.0.4 6.0.5 6.0.5.1 6.0.6 6.0.7 6.0.8.1 6.1.0 6.1.3 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.3.0 6.3.1 6.3.2 6.4.0 6.5.0 6.5.1 6.6.0 6.7.0 6.8.0 6.8.2 6.8.3 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13.1 6.9.13.2 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.2 7.0.2.1 7.0.2.2 7.0.2.3 7.0.3 7.1.0 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2.0 7.2.1 7.3.0 7.3.1 7.3.2 7.3.3 7.4.0 7.4.2 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.6.0 7.6.1 7.6.1.1 7.6.10 7.6.11 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.7.1 7.6.8 7.6.9 7.7.0 7.8.0 7.8.1 7.8.10 7.8.11 7.8.12 7.8.13 7.8.14 7.8.15 7.8.16 7.8.17 7.8.18 7.8.2 7.8.3 7.8.4 7.8.5 7.8.5.1 7.8.6 7.8.7 7.8.8 7.8.9 7.9.0 7.9.1 7.9.10 7.9.11 7.9.2 7.9.3 7.9.4 7.9.5 7.9.6 7.9.7 7.9.8 7.9.9 8.0.0 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.1.0 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.1 3.7.0 3.8.0 3.9.0 3.9.1 3.9.2 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.9.0 4.9.1 4.9.2 4.9.3 5.0.0
admin-site-enhancements / classes / class-multiple-user-roles.php
admin-site-enhancements / classes Last commit date
class-activation.php 2 weeks ago class-admin-menu-organizer.php 2 weeks ago class-admin-menu-svg-icon-mask.php 2 weeks ago class-auto-publish-posts-with-missed-schedule.php 2 weeks ago class-avif-upload.php 2 weeks ago class-captcha-protection.php 2 weeks ago class-change-login-url.php 2 weeks ago class-cleanup-admin-bar.php 2 weeks ago class-common-methods.php 2 weeks ago class-content-duplication.php 2 weeks ago class-content-order.php 2 weeks ago class-custom-admin-footer-text.php 2 weeks ago class-custom-body-class.php 2 weeks ago class-custom-css.php 2 weeks ago class-custom-nav-menu-items-in-new-tab.php 2 weeks ago class-deactivation.php 2 weeks ago class-disable-author-archives.php 2 weeks ago class-disable-comments.php 2 weeks ago class-disable-dashboard-widgets.php 2 weeks ago class-disable-embeds.php 2 weeks ago class-disable-feeds.php 2 weeks ago class-disable-gutenberg.php 2 weeks ago class-disable-rest-api.php 2 weeks ago class-disable-smaller-components.php 2 weeks ago class-disable-updates.php 2 weeks ago class-disable-user-account.php 2 weeks ago class-disable-xml-rpc.php 2 weeks ago class-display-system-summary.php 2 weeks ago class-email-address-obfuscator.php 2 weeks ago class-email-delivery.php 2 weeks ago class-enhance-list-tables.php 2 weeks ago class-external-permalinks.php 2 weeks ago class-heartbeat-control.php 2 weeks ago class-hide-admin-bar.php 2 weeks ago class-hide-admin-notices.php 2 weeks ago class-image-sizes-panel.php 2 weeks ago class-image-upload-control.php 2 weeks ago class-insert-head-body-footer-code.php 2 weeks ago class-last-login-column.php 2 weeks ago class-limit-login-attempts.php 2 weeks ago class-login-id-type.php 2 weeks ago class-login-logout-menu.php 2 weeks ago class-maintenance-mode.php 2 weeks ago class-manage-ads-appads-txt.php 2 weeks ago class-manage-robots-txt.php 2 weeks ago class-media-files-visibility-control.php 2 weeks ago class-media-replacement.php 2 weeks ago class-multiple-user-roles.php 2 weeks ago class-navigation-menu-duplicator.php 2 weeks ago class-obfuscate-author-slugs.php 2 weeks ago class-open-external-links-in-new-tab.php 2 weeks ago class-password-protection.php 2 weeks ago class-redirect-after-login.php 2 weeks ago class-redirect-after-logout.php 2 weeks ago class-redirect-fourofour.php 2 weeks ago class-registration-date-column.php 2 weeks ago class-revisions-control.php 2 weeks ago class-search-engines-visibility.php 2 weeks ago class-settings-fields-render.php 2 weeks ago class-settings-sanitization.php 2 weeks ago class-settings-sections-fields.php 2 weeks ago class-show-custom-taxonomy-filters.php 2 weeks ago class-site-identity-on-login-page.php 2 weeks ago class-svg-upload.php 2 weeks ago class-third-party-compat.php 2 weeks ago class-various-admin-ui-enhancements.php 2 weeks ago class-view-admin-as-role.php 2 weeks ago class-wider-admin-menu.php 2 weeks ago class-wp-config-transformer.php 2 weeks ago
class-multiple-user-roles.php
172 lines
1 <?php
2
3 namespace ASENHA\Classes;
4
5 /**
6 * Class for Multiple User Roles module
7 *
8 * @since 6.9.5
9 */
10 class Multiple_User_Roles {
11
12 /**
13 * Add UI to enable multiple user roles selection
14 *
15 * @since 4.8.0
16 */
17 public function add_multiple_roles_ui( $user ) {
18 // Get user roles that the current user is allowed to edit
19 $roles = get_editable_roles();
20
21 $current_user = wp_get_current_user();
22 $current_user_roles = array_intersect( array_values( $current_user->roles ), array_keys( $roles ) ); // indexed array of role slugs
23
24 // Get the roles of the user being shown / edited / created
25 if ( ! empty( $user->roles ) ) {
26 $user_roles = array_intersect( array_values( $user->roles ), array_keys( $roles ) ); // indexed array of role slugs
27 } else {
28 $user_roles = array();
29 }
30
31 $is_self = (
32 is_object( $user )
33 && is_object( $current_user )
34 && isset( $user->ID )
35 && isset( $current_user->ID )
36 && (int) $user->ID === (int) $current_user->ID
37 );
38 $user_is_administrator = is_object( $user ) && in_array( 'administrator', (array) $user->roles, true );
39
40 // Only show roles checkboxes for users that can assign roles to other users
41 if ( current_user_can( 'promote_users', get_current_user_id() ) ) {
42
43 ?>
44 <div class="asenha-roles-temporary-container">
45 <table class="form-table">
46 <tr class="asenha-multiple-roles-row">
47 <th>
48 <label>Roles</label>
49 </th>
50 <td>
51 <?php
52 foreach ( $roles as $role_slug => $role_info ) {
53
54 $checkbox_id = $role_slug . '_role';
55 $role_name = translate_user_role( $role_info['name'] );
56 if ( ! empty( $user_roles ) && in_array( $role_slug, $user_roles ) ) {
57 $checked = 'checked="checked"';
58 } else {
59 $checked = '';
60 }
61
62 // On own profile: lock Administrator checkbox. Only emit a hidden retain field when
63 // the user already has administrator — never force-grant it to non-admins.
64 $disabled = '';
65 $lock_own_administrator = false;
66
67 if ( 'administrator' === $role_slug && $is_self ) {
68 $disabled = 'disabled ';
69 if ( $user_is_administrator ) {
70 $lock_own_administrator = true;
71 }
72 }
73
74 // Output roles checkboxes
75 ?>
76 <label for="<?php esc_attr_e( $checkbox_id ); ?>"><input type="checkbox" id="<?php esc_attr_e( $checkbox_id ); ?>" value="<?php esc_attr_e( $role_slug ); ?>" name="asenha_assigned_roles[]" <?php esc_attr_e( $checked ); ?> <?php esc_attr_e( $disabled ); ?>/> <?php esc_html_e( $role_name ); ?></label><br />
77 <?php
78 if ( $lock_own_administrator ) {
79 ?>
80 <input type="hidden" name="asenha_assigned_roles[]" value="administrator" />
81 <?php
82 }
83
84 }
85
86 wp_nonce_field( 'asenha_set_multiple_roles', 'asenha_multiple_roles_nonce' );
87
88 ?>
89 </td>
90 </tr>
91 </table>
92 </div>
93 <?php
94
95 }
96
97 }
98
99 /**
100 * Save changes in roles assignment
101 *
102 * @since 4.8.0
103 */
104 public function save_roles_assignment( $user_id ) {
105
106 if ( ! isset( $_POST['asenha_multiple_roles_nonce'] ) ) {
107 return;
108 }
109
110 if ( ! current_user_can( 'promote_users', get_current_user_id() ) || ! wp_verify_nonce( $_POST['asenha_multiple_roles_nonce'], 'asenha_set_multiple_roles' ) ) {
111 return;
112 }
113
114 // Get user roles that the current user is allowed to edit
115 $roles = get_editable_roles();
116
117 $current_user = wp_get_current_user();
118 $current_user_roles = array_intersect( array_values( $current_user->roles ), array_keys( $roles ) ); // indexed array of role slugs
119
120 // Get the roles of the user being shown / edited / created
121 $user = get_user_by( 'id', (int) $user_id ); // WP_User object
122
123 if ( ! $user ) {
124 return;
125 }
126
127 $user_roles = array_intersect( array_values( $user->roles ), array_keys( $roles ) ); // Current/existing roles
128
129 $assigned_roles = array();
130
131 if ( isset( $_POST['asenha_assigned_roles'] ) && is_array( $_POST['asenha_assigned_roles'] ) ) {
132 $assigned_roles = array_map( 'sanitize_text_field', wp_unslash( $_POST['asenha_assigned_roles'] ) );
133 }
134
135 // Make sure only valid roles are processed
136 $assigned_roles = array_intersect( $assigned_roles, array_keys( $roles ) );
137
138 // Self-edit: retain administrator only if already held; otherwise strip it
139 // so non-admins with promote_users cannot self-escalate via POST.
140 $is_self = ( (int) $user->ID === (int) $current_user->ID );
141 $user_is_administrator = in_array( 'administrator', (array) $user->roles, true );
142
143 if ( $is_self ) {
144 if ( $user_is_administrator ) {
145 $assigned_roles[] = 'administrator';
146 $assigned_roles = array_unique( $assigned_roles );
147 } else {
148 $assigned_roles = array_values( array_diff( $assigned_roles, array( 'administrator' ) ) );
149 }
150 }
151
152 // Identify and remove roles not present in the newly assigned roles
153 $roles_to_remove = array_diff( $user_roles, $assigned_roles );
154
155 if ( ! empty( $roles_to_remove ) ) {
156 foreach ( $roles_to_remove as $role_to_remove ) {
157 $user->remove_role( $role_to_remove );
158 }
159 }
160
161 // Identify and add roles not present in the existing roles
162 $roles_to_add = array_diff( $assigned_roles, $user_roles );
163
164 if ( ! empty( $roles_to_add ) ) {
165 foreach ( $roles_to_add as $role_to_add ) {
166 $user->add_role( $role_to_add );
167 }
168 }
169
170 }
171
172 }