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