PluginProbe ʕ •ᴥ•ʔ
PublishPress Capabilities – User Role Editor, Access Permissions, User Capabilities, Admin Menus / 2.1
PublishPress Capabilities – User Role Editor, Access Permissions, User Capabilities, Admin Menus v2.1
2.45.0 2.44.0 trunk 1.10 1.10.1 1.4.1 1.4.10 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5 1.5.1 1.5.10 1.5.11 1.5.2 1.5.3 1.5.4 1.5.5 1.5.7 1.5.8 1.5.9 1.6 1.6.1 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.8.1 1.9 1.9.10 1.9.12 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.9 2.0 2.0.2 2.0.3 2.1 2.1.1 2.10.0 2.10.1 2.10.2 2.10.3 2.11.1 2.12.1 2.12.2 2.13.0 2.14.0 2.15.0 2.16.0 2.17.0 2.18.0 2.18.2 2.19.0 2.19.1 2.19.2 2.2 2.2.1 2.20.0 2.21.0 2.22.0 2.23.0 2.3 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.30.0 2.31.0 2.32.0 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.41.0 2.42.0 2.43.0 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.7.0 2.7.1 2.8.0 2.8.1 2.9.0 2.9.1
capability-manager-enhanced / includes / handler.php
capability-manager-enhanced / includes Last commit date
features 5 years ago roles 5 years ago admin.php 5 years ago backup-handler.php 5 years ago backup.php 5 years ago cap-helper.php 6 years ago filters-admin.php 6 years ago filters-woocommerce.php 7 years ago filters-wp_rest_workarounds.php 5 years ago filters.php 5 years ago functions-admin.php 5 years ago functions.php 5 years ago handler.php 5 years ago inflect-cme.php 7 years ago manager.php 5 years ago network.php 5 years ago pp-handler.php 6 years ago pp-ui.php 5 years ago publishpress-roles.php 5 years ago settings-handler.php 5 years ago settings.php 5 years ago
handler.php
410 lines
1 <?php
2 class CapsmanHandler
3 {
4 var $cm;
5
6 function __construct($manager_obj = false) {
7 if ($manager_obj) {
8 $this->cm = $manager_obj;
9 } else {
10 global $capsman;
11 $this->cm = $capsman;
12 }
13
14 require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
15 }
16
17 function processAdminGeneral( $post ) {
18 global $wp_roles;
19
20 if ('pp-capabilities-settings' == $_REQUEST['page']) {
21 do_action('publishpress-caps_process_update');
22 return;
23 }
24
25 // Create a new role.
26 if ( ! empty($post['CreateRole']) ) {
27 if ( $newrole = $this->createRole($post['create-name']) ) {
28 ak_admin_notify(__('New role created.', 'capsman-enhanced'));
29 $this->cm->current = $newrole;
30 } else {
31 if ( empty($post['create-name']) && in_array(get_locale(), ['en_EN', 'en_US']) )
32 ak_admin_error( 'Error: No role name specified.', 'capsman-enhanced' );
33 else
34 ak_admin_error(__('Error: Failed creating the new role.', 'capsman-enhanced'));
35 }
36
37 // rename role
38 } elseif (!empty($post['RenameRole']) && !empty($post['rename-name'])) {
39 $current = get_role($post['current']);
40 $new_title = sanitize_text_field($post['rename-name']);
41
42 if ($current && isset($wp_roles->roles[$current->name]) && $new_title) {
43 $old_title = $wp_roles->roles[$current->name]['name'];
44 $wp_roles->roles[$current->name]['name'] = $new_title;
45 update_option($wp_roles->role_key, $wp_roles->roles);
46
47 ak_admin_notify(sprintf(__('Role "%s" (id %s) renamed to "%s"', 'capsman-enhanced'), $old_title, strtolower($current->name), $new_title));
48 $this->cm->current = $current->name;
49 }
50 // Copy current role to a new one.
51 } elseif ( ! empty($post['CopyRole']) ) {
52 $current = get_role($post['current']);
53 if ( $newrole = $this->createRole($post['copy-name'], $current->capabilities) ) {
54 ak_admin_notify(__('New role created.', 'capsman-enhanced'));
55 $this->cm->current = $newrole;
56 } else {
57 if ( empty($post['copy-name']) && in_array(get_locale(), ['en_EN', 'en_US']) )
58 ak_admin_error( 'Error: No role name specified.', 'capsman-enhanced' );
59 else
60 ak_admin_error(__('Error: Failed creating the new role.', 'capsman-enhanced'));
61 }
62
63 // Save role changes. Already saved at start with self::saveRoleCapabilities().
64 } elseif ( ! empty($post['SaveRole']) ) {
65 if ( MULTISITE ) {
66 global $wp_roles;
67 ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
68 }
69
70 if (!pp_capabilities_is_editable_role($post['current'])) {
71 ak_admin_error( 'The selected role is not editable.', 'capsman-enhanced' );
72 return;
73 }
74
75 $this->saveRoleCapabilities($post['current'], $post['caps'], $post['level']);
76
77 if ( defined( 'PRESSPERMIT_ACTIVE' ) ) { // log customized role caps for subsequent restoration
78 // for bbPress < 2.2, need to log customization of roles following bbPress activation
79 $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat
80
81 if ( ! $customized_roles = get_option( 'pp_customized_roles' ) )
82 $customized_roles = array();
83
84 $customized_roles[$post['role']] = (object) array( 'caps' => array_map( 'boolval', $post['caps'] ), 'plugins' => $plugins );
85 update_option( 'pp_customized_roles', $customized_roles );
86
87 global $wpdb;
88 $wpdb->query( "UPDATE $wpdb->options SET autoload = 'no' WHERE option_name = 'pp_customized_roles'" );
89 }
90 // Create New Capability and adds it to current role.
91 } elseif ( ! empty($post['AddCap']) ) {
92 if ( MULTISITE ) {
93 global $wp_roles;
94 ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
95 }
96
97 if (!pp_capabilities_is_editable_role($post['current'])) {
98 ak_admin_error( 'The selected role is not editable.', 'capsman-enhanced' );
99 return;
100 }
101
102 $role = get_role($post['current']);
103 $role->name = $post['current']; // bbPress workaround
104
105 $newname = $this->createNewName($post['capability-name']);
106
107 if (empty($newname['error'])) {
108 $role->add_cap($newname['name']);
109
110 // for bbPress < 2.2, need to log customization of roles following bbPress activation
111 $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat
112
113 if ( ! $customized_roles = get_option( 'pp_customized_roles' ) )
114 $customized_roles = array();
115
116 $customized_roles[$post['role']] = (object) array( 'caps' => array_merge( $role->capabilities, array( $newname['name'] => 1 ) ), 'plugins' => $plugins );
117 update_option( 'pp_customized_roles', $customized_roles );
118
119 global $wpdb;
120 $wpdb->query( "UPDATE $wpdb->options SET autoload = 'no' WHERE option_name = 'pp_customized_roles'" );
121
122 $url = admin_url('admin.php?page=pp-capabilities&role=' . $post['role'] . '&added=1');
123 wp_redirect($url);
124 exit;
125 } else {
126 ak_admin_notify(__('Incorrect capability name.'));
127 }
128
129 } elseif ( ! empty($post['update_filtered_types']) || ! empty($post['update_filtered_taxonomies']) || ! empty($post['update_detailed_taxonomies']) ) {
130 //if ( /* settings saved successfully on plugins_loaded action */ ) {
131 ak_admin_notify(__('Type / Taxonomy settings saved.', 'capsman-enhanced'));
132 //} else {
133 // ak_admin_error(__('Error saving capability settings.', 'capsman-enhanced'));
134 //}
135 } else {
136 if (!apply_filters('publishpress-caps_submission_ok', false)) {
137 ak_admin_error(__('Bad form received.', 'capsman-enhanced'));
138 }
139 }
140
141 if ( ! empty($newrole) && defined('PRESSPERMIT_ACTIVE') ) {
142 if ( ( ! empty($post['CreateRole']) && ! empty( $_REQUEST['new_role_pp_only'] ) ) || ( ! empty($post['CopyRole']) && ! empty( $_REQUEST['copy_role_pp_only'] ) ) ) {
143 $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
144 $pp_only[]= $newrole;
145
146 pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only);
147
148 _cme_pp_default_pattern_role( $newrole );
149 pp_refresh_options();
150 }
151 }
152 }
153
154
155 /**
156 * Creates a new role/capability name from user input name.
157 * Name rules are:
158 * - 2-40 charachers lenght.
159 * - Only letters, digits, spaces and underscores.
160 * - Must to start with a letter.
161 *
162 * @param string $name Name from user input.
163 * @return array|false An array with the name and display_name, or false if not valid $name.
164 */
165 public function createNewName( $name ) {
166 // Allow max 40 characters, letters, digits and spaces
167 $name = trim(substr($name, 0, 40));
168 $pattern = '/^[a-zA-Z][a-zA-Z0-9 _]+$/';
169
170 if ( preg_match($pattern, $name) ) {
171 $roles = ak_get_roles();
172
173 $name = str_replace(' ', '_', $name);
174 if ( in_array($name, $roles) || array_key_exists($name, $this->cm->capabilities) ) {
175 return ['error' => 'role_exists', 'name' => $name]; // Already a role or capability with this name.
176 }
177
178 $display = explode('_', $name);
179 $name = strtolower($name);
180
181 // Apply ucfirst proper caps unless capitalization already provided
182 foreach($display as $i => $word) {
183 if ($word === strtolower($word)) {
184 $display[$i] = ucfirst($word);
185 }
186 }
187
188 $display = implode(' ', $display);
189
190 return compact('name', 'display');
191 } else {
192 return ['error' => 'invalid_name', 'name' => $name];
193 }
194 }
195
196 /**
197 * Creates a new role.
198 *
199 * @param string $name Role name to create.
200 * @param array $caps Role capabilities.
201 * @return string|false Returns the name of the new role created or false if failed.
202 */
203 public function createRole( $name, $caps = [], $args = [] ) {
204 if ( ! is_array($caps) )
205 $caps = array();
206
207 $role = $this->createNewName($name);
208 if (!empty($role['error'])) {
209 return false;
210 }
211
212 $new_role = add_role($role['name'], $role['display'], $caps);
213 if ( is_object($new_role) ) {
214 return $role['name'];
215 } else {
216 return false;
217 }
218 }
219
220 /**
221 * Saves capability changes to roles.
222 *
223 * @param string $role_name Role name to change its capabilities
224 * @param array $caps New capabilities for the role.
225 * @return void
226 */
227 private function saveRoleCapabilities( $role_name, $caps, $level ) {
228 $this->cm->generateNames();
229 $role = get_role($role_name);
230
231 // workaround to ensure db storage of customizations to bbp dynamic roles
232 $role->name = $role_name;
233
234 $stored_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(true, 1) ) : array();
235 $stored_negative_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(false) ) : array();
236
237 $old_caps = array_intersect_key( $stored_role_caps, $this->cm->capabilities);
238 $new_caps = ( is_array($caps) ) ? array_map('boolval', $caps) : array();
239 $new_caps = array_merge($new_caps, ak_level2caps($level));
240
241 // Find caps to add and remove
242 $add_caps = array_diff_key($new_caps, $old_caps);
243 $del_caps = array_diff_key(array_merge($old_caps, $stored_negative_role_caps), $new_caps);
244
245 $changed_caps = array();
246 foreach( array_intersect_key( $new_caps, $old_caps ) as $cap_name => $cap_val ) {
247 if ( $new_caps[$cap_name] != $old_caps[$cap_name] )
248 $changed_caps[$cap_name] = $cap_val;
249 }
250
251 $add_caps = array_merge( $add_caps, $changed_caps );
252
253 if ( ! $is_administrator = current_user_can('administrator') ) {
254 unset($add_caps['manage_capabilities']);
255 unset($del_caps['manage_capabilities']);
256 }
257
258 if ( 'administrator' == $role_name && isset($del_caps['manage_capabilities']) ) {
259 unset($del_caps['manage_capabilities']);
260 ak_admin_error(__('You cannot remove Manage Capabilities from Administrators', 'capsman-enhanced'));
261 }
262
263 // additional safeguard against removal of read capability
264 if ( isset( $del_caps['read'] ) && _cme_is_read_removal_blocked( $role_name ) ) {
265 unset( $del_caps['read'] );
266 }
267
268 // Add new capabilities to role
269 foreach ( $add_caps as $cap => $grant ) {
270 if ( $is_administrator || current_user_can($cap) )
271 $role->add_cap( $cap, $grant );
272 }
273
274 // Remove capabilities from role
275 foreach ( $del_caps as $cap => $grant) {
276 if ( $is_administrator || current_user_can($cap) )
277 $role->remove_cap($cap);
278 }
279
280 $this->cm->log_db_roles();
281
282 if (is_multisite() && is_super_admin() && is_main_site()) {
283 if ( ! $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) )
284 $autocreate_roles = array();
285
286 $this_role_autocreate = ! empty($_REQUEST['cme_autocreate_role']);
287
288 if ( $this_role_autocreate && ! in_array( $role_name, $autocreate_roles ) ) {
289 $autocreate_roles []= $role_name;
290 update_site_option( 'cme_autocreate_roles', $autocreate_roles );
291 }
292
293 if ( ! $this_role_autocreate && in_array( $role_name, $autocreate_roles ) ) {
294 $autocreate_roles = array_diff( $autocreate_roles, array( $role_name ) );
295 update_site_option( 'cme_autocreate_roles', $autocreate_roles );
296 }
297
298 $do_role_sync = !empty($_REQUEST['cme_net_sync_role']);
299 $do_option_sync = !empty($_REQUEST['cme_net_sync_options']);
300
301 if ($do_role_sync || $do_option_sync) {
302 // loop through all sites on network, creating or updating role def
303
304 global $wpdb, $wp_roles, $blog_id;
305 $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs ORDER BY blog_id" );
306 $orig_blog_id = $blog_id;
307
308 if ($do_role_sync) {
309 $role_caption = $wp_roles->role_names[$role_name];
310
311 $new_caps = ( is_array($caps) ) ? array_map('boolval', $caps) : array();
312 $new_caps = array_merge($new_caps, ak_level2caps($level) );
313
314 $admin_role = $wp_roles->get_role('administrator');
315 $main_admin_caps = array_merge( $admin_role->capabilities, ak_level2caps(10) );
316 }
317
318 $sync_options = [];
319
320 if ($do_option_sync) {
321 // capability-related options
322 $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
323
324 foreach(['define_create_posts_cap', 'enabled_post_types', 'enabled_taxonomies'] as $option_name) {
325 $sync_options["{$pp_prefix}_$option_name"] = get_option("{$pp_prefix}_$option_name");
326 }
327
328 $sync_options['cme_detailed_taxonomies'] = get_option('cme_detailed_taxonomies');
329 $sync_options['cme_enabled_post_types'] = get_option('cme_enabled_post_types');
330 $sync_options['presspermit_supplemental_role_defs'] = get_option('presspermit_supplemental_role_defs');
331 }
332
333 foreach ( $blog_ids as $id ) {
334 if ( is_main_site($id) )
335 continue;
336
337 switch_to_blog( $id );
338
339 if ($do_role_sync) {
340 ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
341
342 if ( $blog_role = $wp_roles->get_role( $role_name ) ) {
343 $stored_role_caps = ( ! empty($blog_role->capabilities) && is_array($blog_role->capabilities) ) ? array_intersect( $blog_role->capabilities, array(true, 1) ) : array();
344
345 $old_caps = array_intersect_key( $stored_role_caps, $this->cm->capabilities);
346
347 // Find caps to add and remove
348 $add_caps = array_diff_key($new_caps, $old_caps);
349 $del_caps = array_intersect_key( array_diff_key($old_caps, $new_caps), $main_admin_caps ); // don't mess with caps that are totally unused on main site
350
351 // Add new capabilities to role
352 foreach ( $add_caps as $cap => $grant ) {
353 $blog_role->add_cap( $cap, $grant );
354 }
355
356 // Remove capabilities from role
357 foreach ( $del_caps as $cap => $grant) {
358 $blog_role->remove_cap($cap);
359 }
360 } else {
361 $wp_roles->add_role( $role_name, $role_caption, $new_caps );
362 }
363 }
364
365 foreach($sync_options as $option_name => $option_val) {
366 update_option($option_name, $option_val);
367 }
368
369 restore_current_blog();
370 }
371
372 ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
373 }
374 } // endif multisite installation with super admin editing a main site role
375
376 pp_capabilities_autobackup();
377 }
378
379 /**
380 * Deletes a role.
381 * The role comes from the $_GET['role'] var and the nonce has already been checked.
382 * Default WordPress role cannot be deleted and if trying to do it, throws an error.
383 * Users with the deleted role, are moved to the WordPress default role.
384 *
385 * @return void
386 */
387 function adminDeleteRole ()
388 {
389 $role_name = $_GET['role'];
390 check_admin_referer('delete-role_' . $role_name);
391
392 $this->cm->current = $role_name;
393
394 if (!pp_capabilities_is_editable_role($role_name)) {
395 ak_admin_error( 'The selected role is not editable.', 'capsman-enhanced' );
396 }
397
398 if (false !== pp_capabilities_roles()->actions->delete_role($role_name, ['allow_system_role_deletion' => true, 'nonce_check' => false])) {
399 unset($this->cm->roles[$role_name]);
400 $this->cm->current = get_option('default_role');
401 }
402 }
403 }
404
405 if ( ! function_exists('boolval') ) {
406 function boolval( $val ) {
407 return (bool) $val;
408 }
409 }
410