cap->edit_posts ) ) { $test_cap = $type_obj->cap->edit_posts; $default_cap_prefix = 'edit_'; } elseif( isset( $type_obj->cap->manage_terms ) ) { $test_cap = $type_obj->cap->manage_terms; $default_cap_prefix = 'manage_'; } else return isset( $type_obj->name ) ? $type_obj->name . 's' : ''; if ( ( 0 === strpos( $test_cap, $default_cap_prefix ) ) && ( false === strpos( $test_cap, '_', strlen($default_cap_prefix) ) ) ) return substr( $test_cap, strlen($default_cap_prefix) ); else return $type_obj->name . 's'; } class WP_Cap_Helper_CR { function establish_status_caps() { global $wp_post_types; $use_post_types = scoper_get_option( 'use_post_types' ); $post_types = array_diff_key( get_post_types( array( 'public' => true ) ), array( 'attachment' => true ) ); $stati = get_post_stati( array( 'internal' => false ), 'object' ); foreach( $post_types as $post_type ) { $plural_name = plural_name_from_cap_rs( $wp_post_types[$post_type] ); // copy existing cap values so we don't overwrite them $type_caps = (array) $wp_post_types[$post_type]->cap; if ( 'attachment' == $post_type ) { $is_attachment_type = true; $post_type = 'post'; } else { $is_attachment_type = false; if ( empty( $use_post_types[$post_type] ) ) continue; } // force edit_published, edit_private, delete_published, delete_private cap definitions foreach ( $stati as $status => $status_obj ) { if ( empty($status_obj->moderation) && ! $status_obj->public && ! $status_obj->private ) // don't mess with draft or future continue; foreach( array( 'read', 'edit', 'delete' ) as $op ) { if ( ( 'read' == $op ) && ( $status_obj->public || ! empty( $status_obj->moderation ) ) ) continue; $status_string = ( 'publish' == $status ) ? 'published' : $status; $posts_cap_name = "{$op}_{$status_string}_posts"; // only alter the cap setting if it's not already set if ( empty( $type_caps[$posts_cap_name] ) ) { if ( ! empty( $status_obj->customize_caps ) ) { // TODO: RS Options to set this // this status is built in or was marked for full enforcement of custom capabilities $type_caps[$posts_cap_name] = "{$op}_{$status_string}_{$plural_name}"; } else { // default to this post type's own equivalent private or published cap if ( $status_obj->private ) $type_caps[$posts_cap_name] = "{$op}_private_{$plural_name}"; elseif ( $status_obj->public ) $type_caps[$posts_cap_name] = "{$op}_published_{$plural_name}"; } } } // end foreach op (read/edit/delete) // also define a "set_status" cap for custom statuses (to accompany "publish_posts" cap requirement when setting or removing this post status) if ( ! in_array( $status, array( 'publish', 'private' ) ) ) { $posts_cap_name = "set_{$status}_posts"; if ( empty( $type_caps[$posts_cap_name] ) ) { if ( ! empty( $status_obj->customize_caps ) ) { // TODO: RS Options to set this // this status was marked for full enforcement of custom capabilities $type_caps[$posts_cap_name] = "set_{$status}_{$plural_name}"; } elseif( $status_obj->public || $status_obj->private ) { $type_caps[$posts_cap_name] = "publish_{$plural_name}"; } } } } // end foreach front end status if ( empty( $type_caps['delete_posts'] ) ) $type_caps['delete_posts'] = "delete_{$plural_name}"; if ( empty( $type_caps['delete_others_posts'] ) ) $type_caps['delete_others_posts'] = "delete_others_{$plural_name}"; if ( $is_attachment_type ) $post_type = 'attachment'; $wp_post_types[$post_type]->cap = (object) $type_caps; } // end foreach post type } function force_distinct_post_caps() { // but only if the post type has RS usage enabled global $wp_post_types; $type_caps = array(); $customized = array(); //scoper_refresh_default_otype_options(); $use_post_types = scoper_get_option( 'use_post_types' ); $generic_caps = array(); foreach( array( 'post', 'page' ) as $post_type ) $generic_caps[$post_type] = (array) $wp_post_types[$post_type]->cap; foreach( array_keys($wp_post_types) as $post_type ) { if ( empty( $use_post_types[$post_type] ) ) continue; if ( 'post' === $wp_post_types[$post_type]->capability_type ) $wp_post_types[$post_type]->capability_type = $post_type; $type_caps = (array) $wp_post_types[$post_type]->cap; /* $plural_name = */ // as of WP 3.1, no basis for determinining this unless type-specific caps are set // don't allow any capability defined for this type to match any capability defined for post or page (unless this IS post or page type) foreach( $type_caps as $cap_property => $type_cap ) foreach( array( 'post', 'page' ) as $generic_type ) if ( ( $post_type != $generic_type ) && in_array( $type_cap, $generic_caps[$generic_type] ) && ( 'read' != $type_cap ) ) { $type_caps[$cap_property] = str_replace( $generic_type, $post_type, $cap_property ); $customized[$post_type] = true; } $wp_post_types[$post_type]->cap = (object) $type_caps; } // One-time message alerting Administrators that custom types were auto-enabled for RS filtering if ( $customized ) { $logged = ( ! empty($_POST['rs_defaults'] ) ) ? array() : (array) scoper_get_option( 'log_customized_types' ); if ( $new_customized = array_diff_key( $customized, $logged ) ) { $labels = array(); foreach( array_keys($new_customized) as $post_type ) { $type_obj = get_post_type_object( $post_type ); $labels[$post_type] = ( ! empty($type_obj->labels->name) ) ? $type_obj->labels->name : $post_type; $label_str = implode( ', ', $labels ); } $msg_format = __( 'The following Custom Post Types are enabled for RS filtering: %1$s. Non-administrators will be unable to edit them until you either disable filtering (Roles > Options > Realm > Post Type Usage) or assign type-specific Roles (Roles > General). Disregard this message if you have already done so.', 'scoper' ); $message = sprintf( $msg_format, $label_str ); add_action('admin_notices', create_function('', 'echo \'