admin-notices
2 months ago
features
2 weeks ago
plugin-capabilities
2 months ago
redirects
2 months ago
roles
1 month ago
admin-load.php
1 month ago
admin.php
2 weeks ago
application-passwords.php
2 weeks ago
backup-handler.php
2 weeks ago
backup.php
1 month ago
cap-helper.php
6 months ago
dashboard.php
2 months ago
extractor-capabilities.php
6 months ago
filters-admin.php
6 months ago
filters-woocommerce.php
6 months ago
filters-wp_rest_workarounds.php
6 months ago
filters.php
5 months ago
functions-admin.php
2 weeks ago
functions.php
2 weeks ago
handler.php
2 weeks ago
inflect-cme.php
6 months ago
manager.php
2 weeks ago
network.php
6 months ago
plugin-capabilities.php
2 months ago
pp-handler.php
6 months ago
pp-ui.php
3 months ago
publishpress-roles.php
6 months ago
settings-handler.php
6 months ago
settings-ui.php
2 weeks ago
settings.php
6 months ago
test-user-ui.php
1 month ago
test-user.php
5 months ago
handler.php
509 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() { |
| 25 | global $wpdb, $wp_roles; |
| 26 | |
| 27 | check_admin_referer('capsman-general-manager'); |
| 28 | |
| 29 | if ( empty ($_POST['caps']) ) { |
| 30 | $_POST['caps'] = array(); |
| 31 | } |
| 32 | |
| 33 | if (!empty($_REQUEST['page']) && ('pp-capabilities-settings' == $_REQUEST['page'])) { |
| 34 | do_action('publishpress-caps_process_update'); |
| 35 | return; |
| 36 | } |
| 37 | |
| 38 | // Create a new role. |
| 39 | if ( ! empty($_POST['CreateRole']) ) { |
| 40 | if (!empty($_POST['create-name'])) { |
| 41 | $newrole = $this->createRole(sanitize_text_field($_POST['create-name'])); |
| 42 | } |
| 43 | |
| 44 | if (!empty($newrole)) { |
| 45 | ak_admin_notify(__('New role created.', 'capability-manager-enhanced')); |
| 46 | $this->cm->set_current_role($newrole); |
| 47 | } else { |
| 48 | if ( empty($_POST['create-name']) && in_array(get_locale(), ['en_EN', 'en_US']) ) |
| 49 | ak_admin_error('Error: No role name specified.'); |
| 50 | else |
| 51 | ak_admin_error(__('Error: Failed creating the new role.', 'capability-manager-enhanced')); |
| 52 | } |
| 53 | |
| 54 | // Save role changes. Already saved at start with self::saveRoleCapabilities() |
| 55 | } elseif ( ! empty($_POST['SaveRole']) && !empty($_POST['current'])) { |
| 56 | if ( defined( 'MULTISITE' ) && MULTISITE ) { |
| 57 | ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit(); |
| 58 | } |
| 59 | |
| 60 | $current_subject = sanitize_key($_POST['current']); |
| 61 | |
| 62 | if (function_exists('pp_capabilities_can_manage_application_password_subject') && pp_capabilities_can_manage_application_password_subject($current_subject)) { |
| 63 | $this->saveApplicationPasswordCapabilities( |
| 64 | $current_subject, |
| 65 | isset($_POST['caps']) && is_array($_POST['caps']) ? $_POST['caps'] : [] |
| 66 | ); |
| 67 | return; |
| 68 | } |
| 69 | |
| 70 | if (!pp_capabilities_is_editable_role($current_subject)) { |
| 71 | ak_admin_error(__('The selected role is not editable.', 'capability-manager-enhanced')); |
| 72 | return; |
| 73 | } |
| 74 | |
| 75 | $level = (isset($_POST['level'])) ? (int) $_POST['level'] : 0; |
| 76 | $this->saveRoleCapabilities($current_subject, array_map('boolval', $_POST['caps']), $level); |
| 77 | |
| 78 | if (defined( 'PRESSPERMIT_ACTIVE' ) && !empty($_POST['role'])) { // log customized role caps for subsequent restoration |
| 79 | // for bbPress < 2.2, need to log customization of roles following bbPress activation |
| 80 | $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat |
| 81 | |
| 82 | if ( ! $customized_roles = get_option( 'pp_customized_roles' ) ) |
| 83 | $customized_roles = array(); |
| 84 | |
| 85 | $_role = sanitize_key($_POST['role']); |
| 86 | |
| 87 | $customized_roles[$_role] = (object) array( 'caps' => array_map( 'boolval', $_POST['caps'] ), 'plugins' => $plugins ); |
| 88 | update_option( 'pp_customized_roles', $customized_roles, false ); |
| 89 | } |
| 90 | // Create New Capability and adds it to current role. |
| 91 | } elseif (!empty($_POST['AddCap']) && !empty($_POST['current']) && !empty($_POST['capability-name'])) { |
| 92 | if ( defined( 'MULTISITE' ) && MULTISITE ) { |
| 93 | ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit(); |
| 94 | } |
| 95 | |
| 96 | if (empty($_POST['current']) || !pp_capabilities_is_editable_role(sanitize_key($_POST['current']))) { |
| 97 | ak_admin_error(__('The selected role is not editable.', 'capability-manager-enhanced')); |
| 98 | return; |
| 99 | } |
| 100 | |
| 101 | $role = get_role(sanitize_key($_POST['current'])); |
| 102 | $role->name = sanitize_key($_POST['current']); // bbPress workaround |
| 103 | |
| 104 | $newname = $this->createNewName(sanitize_text_field($_POST['capability-name']), ['allow_dashes' => true]); |
| 105 | |
| 106 | if (empty($newname['error'])) { |
| 107 | $role->add_cap($newname['name']); |
| 108 | |
| 109 | // for bbPress < 2.2, need to log customization of roles following bbPress activation |
| 110 | $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat |
| 111 | |
| 112 | if ( ! $customized_roles = get_option( 'pp_customized_roles' ) ) |
| 113 | $customized_roles = array(); |
| 114 | |
| 115 | $customized_roles[sanitize_key($_POST['role'])] = (object) array( 'caps' => array_merge( $role->capabilities, array( $newname['name'] => 1 ) ), 'plugins' => $plugins ); |
| 116 | update_option( 'pp_customized_roles', $customized_roles, false ); |
| 117 | |
| 118 | $redirect_role = (!empty($_POST['role'])) ? sanitize_key($_POST['role']) : ''; |
| 119 | |
| 120 | $url = admin_url('admin.php?page=pp-capabilities&role=' . esc_attr($redirect_role) . '&added=1'); |
| 121 | wp_redirect($url); |
| 122 | exit; |
| 123 | } else { |
| 124 | add_action('all_admin_notices', function() { |
| 125 | ak_admin_notify(__('Incorrect capability name.', 'capability-manager-enhanced')); |
| 126 | }); |
| 127 | } |
| 128 | |
| 129 | } elseif ( ! empty($_POST['update_filtered_types']) || ! empty($_POST['update_filtered_taxonomies']) || ! empty($_POST['update_detailed_taxonomies']) ) { |
| 130 | ak_admin_notify(__('Type / Taxonomy settings saved.', 'capability-manager-enhanced')); |
| 131 | } else { |
| 132 | if (!apply_filters('publishpress-caps_submission_ok', false)) { |
| 133 | ak_admin_error(__('Bad form received.', 'capability-manager-enhanced')); |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | if ( ! empty($newrole) && defined('PRESSPERMIT_ACTIVE') ) { |
| 138 | if ( ( ! empty($_POST['CreateRole']) && ! empty( $_REQUEST['new_role_pp_only'] ) ) || ( ! empty($_POST['CopyRole']) && ! empty( $_REQUEST['copy_role_pp_only'] ) ) ) { |
| 139 | $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' ); |
| 140 | $pp_only[]= $newrole; |
| 141 | |
| 142 | pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only); |
| 143 | |
| 144 | _cme_pp_default_pattern_role( $newrole ); |
| 145 | pp_refresh_options(); |
| 146 | } |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | |
| 151 | /** |
| 152 | * Creates a new role/capability name from user input name. |
| 153 | * Name rules are: |
| 154 | * - 2-40 charachers lenght. |
| 155 | * - Only letters, digits, spaces and underscores. |
| 156 | * - Must to start with a letter. |
| 157 | * |
| 158 | * @param string $name Name from user input. |
| 159 | * @return array|false An array with the name and display_name, or false if not valid $name. |
| 160 | */ |
| 161 | public function createNewName( $name, $args=[] ) { |
| 162 | // Allow max 40 characters, letters, digits and spaces |
| 163 | $name = trim(substr($name, 0, 40)); |
| 164 | $pattern = (!empty($args['allow_dashes'])) ? '/^[a-zA-Z][a-zA-Z0-9 _\-]+$/' : '/^[a-zA-Z][a-zA-Z0-9 _]+$/'; |
| 165 | |
| 166 | if ( preg_match($pattern, $name) ) { |
| 167 | $roles = ak_get_roles(); |
| 168 | |
| 169 | $name = str_replace(' ', '_', $name); |
| 170 | if ( in_array($name, $roles) || array_key_exists($name, $this->cm->capabilities) ) { |
| 171 | return ['error' => 'role_exists', 'name' => $name]; // Already a role or capability with this name. |
| 172 | } |
| 173 | |
| 174 | $display = explode('_', $name); |
| 175 | $name = strtolower($name); |
| 176 | |
| 177 | // Apply ucfirst proper caps unless capitalization already provided |
| 178 | foreach($display as $i => $word) { |
| 179 | if ($word === strtolower($word)) { |
| 180 | $display[$i] = ucfirst($word); |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | $display = implode(' ', $display); |
| 185 | |
| 186 | return compact('name', 'display'); |
| 187 | } else { |
| 188 | return ['error' => 'invalid_name', 'name' => $name]; |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * Creates a new role. |
| 194 | * |
| 195 | * @param string $name Role name to create. |
| 196 | * @param array $caps Role capabilities. |
| 197 | * @return string|false Returns the name of the new role created or false if failed. |
| 198 | */ |
| 199 | public function createRole( $name, $caps = [], $args = [] ) { |
| 200 | if ( ! is_array($caps) ) |
| 201 | $caps = array(); |
| 202 | |
| 203 | $role = $this->createNewName($name); |
| 204 | if (!empty($role['error'])) { |
| 205 | return false; |
| 206 | } |
| 207 | |
| 208 | $new_role = add_role($role['name'], $role['display'], $caps); |
| 209 | if ( is_object($new_role) ) { |
| 210 | return $role['name']; |
| 211 | } else { |
| 212 | return false; |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | /** |
| 217 | * Saves capability changes to roles. |
| 218 | * |
| 219 | * @param string $role_name Role name to change its capabilities |
| 220 | * @param array $caps New capabilities for the role. |
| 221 | * @return void |
| 222 | */ |
| 223 | private function saveRoleCapabilities( $role_name, $caps, $level ) { |
| 224 | $this->cm->generateNames(); |
| 225 | $role = get_role($role_name); |
| 226 | |
| 227 | // workaround to ensure db storage of customizations to bbp dynamic roles |
| 228 | $role->name = $role_name; |
| 229 | |
| 230 | $stored_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(true, 1) ) : array(); |
| 231 | $stored_negative_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(false) ) : array(); |
| 232 | |
| 233 | $old_caps = array_intersect_key( $stored_role_caps, $this->cm->capabilities); |
| 234 | $new_caps = ( is_array($caps) ) ? array_map('boolval', $caps) : array(); |
| 235 | $new_caps = array_merge($new_caps, ak_level2caps($level)); |
| 236 | |
| 237 | // Find caps to add and remove |
| 238 | $add_caps = array_diff_key($new_caps, $old_caps); |
| 239 | $del_caps = array_diff_key(array_merge($old_caps, $stored_negative_role_caps), $new_caps); |
| 240 | |
| 241 | $changed_caps = array(); |
| 242 | foreach( array_intersect_key( $new_caps, $old_caps ) as $cap_name => $cap_val ) { |
| 243 | if ( $new_caps[$cap_name] != $old_caps[$cap_name] ) |
| 244 | $changed_caps[$cap_name] = $cap_val; |
| 245 | } |
| 246 | |
| 247 | $add_caps = array_merge( $add_caps, $changed_caps ); |
| 248 | |
| 249 | if ( ! $is_administrator = current_user_can('administrator') ) { |
| 250 | unset($add_caps['manage_capabilities']); |
| 251 | unset($del_caps['manage_capabilities']); |
| 252 | } |
| 253 | |
| 254 | if ( 'administrator' == $role_name && isset($del_caps['manage_capabilities']) ) { |
| 255 | unset($del_caps['manage_capabilities']); |
| 256 | ak_admin_error(__('You cannot remove Manage Capabilities from Administrators', 'capability-manager-enhanced')); |
| 257 | } |
| 258 | |
| 259 | // additional safeguard against removal of read capability |
| 260 | if ( isset( $del_caps['read'] ) && _cme_is_read_removal_blocked( $role_name ) ) { |
| 261 | unset( $del_caps['read'] ); |
| 262 | } |
| 263 | |
| 264 | // Add new capabilities to role |
| 265 | foreach ( $add_caps as $cap => $grant ) { |
| 266 | if ( $is_administrator || current_user_can($cap) ) |
| 267 | $role->add_cap( $cap, $grant ); |
| 268 | } |
| 269 | |
| 270 | // Remove capabilities from role |
| 271 | foreach ( $del_caps as $cap => $grant) { |
| 272 | if ( $is_administrator || current_user_can($cap) ) |
| 273 | $role->remove_cap($cap); |
| 274 | } |
| 275 | |
| 276 | $this->cm->log_db_roles(); |
| 277 | |
| 278 | if (is_multisite() && is_super_admin() && is_main_site()) { |
| 279 | if ( ! $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) ) |
| 280 | $autocreate_roles = array(); |
| 281 | |
| 282 | $this_role_autocreate = ! empty($_REQUEST['cme_autocreate_role']); |
| 283 | |
| 284 | if ( $this_role_autocreate && ! in_array( $role_name, $autocreate_roles ) ) { |
| 285 | $autocreate_roles []= $role_name; |
| 286 | update_site_option( 'cme_autocreate_roles', $autocreate_roles ); |
| 287 | } |
| 288 | |
| 289 | if ( ! $this_role_autocreate && in_array( $role_name, $autocreate_roles ) ) { |
| 290 | $autocreate_roles = array_diff( $autocreate_roles, array( $role_name ) ); |
| 291 | update_site_option( 'cme_autocreate_roles', $autocreate_roles ); |
| 292 | } |
| 293 | |
| 294 | $do_role_sync = !empty($_REQUEST['cme_net_sync_role']); |
| 295 | $do_option_sync = !empty($_REQUEST['cme_net_sync_options']); |
| 296 | |
| 297 | if ($do_role_sync || $do_option_sync) { |
| 298 | $token = $this->processNetworkSyncBatch( |
| 299 | $role_name, |
| 300 | $caps, |
| 301 | $level, |
| 302 | $do_role_sync, |
| 303 | $do_option_sync |
| 304 | ); |
| 305 | |
| 306 | if (!empty($token)) { |
| 307 | $this->cm->network_sync_token = $token; |
| 308 | } |
| 309 | |
| 310 | } |
| 311 | } // endif multisite installation with super admin editing a main site role |
| 312 | |
| 313 | pp_capabilities_autobackup(); |
| 314 | } |
| 315 | |
| 316 | private function saveApplicationPasswordCapabilities($subject, $caps) |
| 317 | { |
| 318 | $this->cm->generateNames(); |
| 319 | |
| 320 | if (method_exists($this->cm, 'initPluginCapabilities')) { |
| 321 | $this->cm->initPluginCapabilities(); |
| 322 | } |
| 323 | |
| 324 | if (defined('CME_FILE')) { |
| 325 | $extractor_capabilities_file = dirname(CME_FILE) . '/includes/extractor-capabilities.php'; |
| 326 | |
| 327 | if (is_readable($extractor_capabilities_file)) { |
| 328 | require_once $extractor_capabilities_file; |
| 329 | } |
| 330 | } |
| 331 | |
| 332 | $managed_capabilities = function_exists('pp_capabilities_get_application_password_managed_capabilities') |
| 333 | ? pp_capabilities_get_application_password_managed_capabilities(array_keys($this->cm->capabilities)) |
| 334 | : array_keys($this->cm->capabilities); |
| 335 | |
| 336 | if (!pp_capabilities_save_application_password_capabilities($subject, $caps, $managed_capabilities)) { |
| 337 | ak_admin_error(__('The selected application password is not editable.', 'capability-manager-enhanced')); |
| 338 | return; |
| 339 | } |
| 340 | |
| 341 | $this->cm->message = __('Application password capabilities saved.', 'capability-manager-enhanced'); |
| 342 | } |
| 343 | |
| 344 | public function continueNetworkSync($token) |
| 345 | { |
| 346 | return $this->runNetworkSyncBatch($token); |
| 347 | } |
| 348 | |
| 349 | public function runNetworkSyncBatch($token) |
| 350 | { |
| 351 | $token = sanitize_key($token); |
| 352 | $state = get_site_transient('cme_network_sync_' . $token); |
| 353 | |
| 354 | if (empty($state) || !is_array($state)) { |
| 355 | return false; |
| 356 | } |
| 357 | |
| 358 | $this->cm->generateSysNames(); |
| 359 | $this->processNetworkSyncBatchFromState($state); |
| 360 | |
| 361 | return true; |
| 362 | } |
| 363 | |
| 364 | private function processNetworkSyncBatch($role_name, $caps, $level, $do_role_sync, $do_option_sync) |
| 365 | { |
| 366 | $state = [ |
| 367 | 'role_name' => sanitize_key($role_name), |
| 368 | 'caps' => (is_array($caps)) ? array_map('boolval', $caps) : array(), |
| 369 | 'level' => (int) $level, |
| 370 | 'do_role_sync' => (bool) $do_role_sync, |
| 371 | 'do_option_sync' => (bool) $do_option_sync, |
| 372 | 'offset' => 0, |
| 373 | 'token' => function_exists('wp_generate_uuid4') ? wp_generate_uuid4() : strtolower(wp_generate_password(32, false, false)), |
| 374 | ]; |
| 375 | |
| 376 | set_site_transient('cme_network_sync_' . $state['token'], $state, DAY_IN_SECONDS); |
| 377 | |
| 378 | if (!wp_next_scheduled('cme_network_sync_batch', [$state['token']])) { |
| 379 | wp_schedule_single_event(time() + 1, 'cme_network_sync_batch', [$state['token']]); |
| 380 | } |
| 381 | |
| 382 | return $state['token']; |
| 383 | } |
| 384 | |
| 385 | private function processNetworkSyncBatchFromState($state) |
| 386 | { |
| 387 | global $wpdb, $wp_roles, $blog_id; |
| 388 | |
| 389 | $role_name = !empty($state['role_name']) ? sanitize_key($state['role_name']) : ''; |
| 390 | $caps = (!empty($state['caps']) && is_array($state['caps'])) ? array_map('boolval', $state['caps']) : array(); |
| 391 | $level = !empty($state['level']) ? (int) $state['level'] : 0; |
| 392 | $do_role_sync = !empty($state['do_role_sync']); |
| 393 | $do_option_sync = !empty($state['do_option_sync']); |
| 394 | $offset = !empty($state['offset']) ? absint($state['offset']) : 0; |
| 395 | $token = !empty($state['token']) ? sanitize_key($state['token']) : ''; |
| 396 | |
| 397 | if (!$role_name) { |
| 398 | return; |
| 399 | } |
| 400 | |
| 401 | $batch_size = (int) apply_filters('cme_network_sync_batch_size', 50, $role_name, $do_role_sync, $do_option_sync); |
| 402 | if ($batch_size < 1) { |
| 403 | $batch_size = 50; |
| 404 | } |
| 405 | |
| 406 | $blog_ids = get_sites([ |
| 407 | 'fields' => 'ids', |
| 408 | 'number' => $batch_size, |
| 409 | 'offset' => $offset, |
| 410 | 'orderby' => 'ID', |
| 411 | 'order' => 'ASC', |
| 412 | ]); |
| 413 | |
| 414 | $orig_blog_id = $blog_id; |
| 415 | |
| 416 | if ($do_role_sync) { |
| 417 | $role_caption = !empty($wp_roles->role_names[$role_name]) ? $wp_roles->role_names[$role_name] : $role_name; |
| 418 | $new_caps = array_merge($caps, ak_level2caps($level)); |
| 419 | $admin_role = $wp_roles->get_role('administrator'); |
| 420 | $main_admin_caps = array_merge($admin_role->capabilities, ak_level2caps(10)); |
| 421 | } |
| 422 | |
| 423 | $sync_options = !empty($state['sync_options']) ? $state['sync_options'] : []; |
| 424 | |
| 425 | if ($do_option_sync && empty($sync_options)) { |
| 426 | $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit'; |
| 427 | |
| 428 | foreach (['define_create_posts_cap', 'enabled_post_types', 'enabled_taxonomies'] as $option_name) { |
| 429 | $sync_options["{$pp_prefix}_$option_name"] = get_option("{$pp_prefix}_$option_name"); |
| 430 | } |
| 431 | |
| 432 | $sync_options['cme_detailed_taxonomies'] = get_option('cme_detailed_taxonomies'); |
| 433 | $sync_options['cme_enabled_post_types'] = get_option('cme_enabled_post_types'); |
| 434 | $sync_options['presspermit_supplemental_role_defs'] = get_option('presspermit_supplemental_role_defs'); |
| 435 | } |
| 436 | |
| 437 | foreach ($blog_ids as $id) { |
| 438 | if (is_main_site($id)) { |
| 439 | continue; |
| 440 | } |
| 441 | |
| 442 | switch_to_blog($id); |
| 443 | |
| 444 | if ($do_role_sync) { |
| 445 | ( method_exists($wp_roles, 'for_site') ) ? $wp_roles->for_site() : $wp_roles->reinit(); |
| 446 | |
| 447 | if ($blog_role = $wp_roles->get_role($role_name)) { |
| 448 | $stored_role_caps = (!empty($blog_role->capabilities) && is_array($blog_role->capabilities)) ? array_intersect($blog_role->capabilities, array(true, 1)) : array(); |
| 449 | $old_caps = array_intersect_key($stored_role_caps, $this->cm->capabilities); |
| 450 | |
| 451 | $add_caps = array_diff_key($new_caps, $old_caps); |
| 452 | $del_caps = array_intersect_key(array_diff_key($old_caps, $new_caps), $main_admin_caps); |
| 453 | |
| 454 | foreach ($add_caps as $cap => $grant) { |
| 455 | $wp_roles->roles[$role_name]['capabilities'][$cap] = $grant; |
| 456 | } |
| 457 | |
| 458 | foreach ($del_caps as $cap => $grant) { |
| 459 | unset($wp_roles->roles[$role_name]['capabilities'][$cap]); |
| 460 | } |
| 461 | |
| 462 | if ($wp_roles->use_db) { |
| 463 | update_option($wp_roles->role_key, $wp_roles->roles); |
| 464 | } |
| 465 | } else { |
| 466 | $wp_roles->add_role($role_name, $role_caption, $new_caps); |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | foreach ($sync_options as $option_name => $option_val) { |
| 471 | update_option($option_name, $option_val); |
| 472 | } |
| 473 | |
| 474 | restore_current_blog(); |
| 475 | } |
| 476 | |
| 477 | ( method_exists($wp_roles, 'for_site') ) ? $wp_roles->for_site() : $wp_roles->reinit(); |
| 478 | |
| 479 | if ($token && count($blog_ids) === $batch_size) { |
| 480 | $state['role_name'] = $role_name; |
| 481 | $state['caps'] = $caps; |
| 482 | $state['level'] = $level; |
| 483 | $state['do_role_sync'] = $do_role_sync; |
| 484 | $state['do_option_sync'] = $do_option_sync; |
| 485 | $state['sync_options'] = $sync_options; |
| 486 | $state['offset'] = $offset + $batch_size; |
| 487 | $state['token'] = $token; |
| 488 | |
| 489 | set_site_transient('cme_network_sync_' . $token, $state, DAY_IN_SECONDS); |
| 490 | |
| 491 | wp_schedule_single_event(time() + 1, 'cme_network_sync_batch', [$token]); |
| 492 | return; |
| 493 | } |
| 494 | |
| 495 | if ($token) { |
| 496 | delete_site_transient('cme_network_sync_' . $token); |
| 497 | set_site_transient('cme_network_sync_done_' . $token, [ |
| 498 | 'role_name' => $role_name, |
| 499 | ], HOUR_IN_SECONDS); |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | if ( ! function_exists('boolval') ) { |
| 505 | function boolval( $val ) { |
| 506 | return (bool) $val; |
| 507 | } |
| 508 | } |
| 509 |