* @copyright Copyright (c) 2010 - 2016, Vladimir Garagulya **/ class URE_Capabilities_Groups_Manager { private static $instance = null; private $lib = null; private $groups = null; private $built_in_wp_caps = null; private $cpt_caps = null; public static function get_instance() { if (self::$instance === null) { // new static() will work too self::$instance = new URE_Capabilities_Groups_Manager(); } return self::$instance; } // end of get_instance() private function __construct() { $this->lib = URE_Lib::get_instance(); $this->_get_built_in_wp_caps(); $this->_get_all_custom_post_types_caps(); } // end of __construct() public function add_custom_post_types() { $this->groups['custom_post_types'] = array( 'caption'=>esc_html__('Custom Post Types', 'user-role-editor'), 'parent'=>'all', 'level'=>1 ); $post_types = get_post_types( array(), 'objects'); $_post_types = $this->lib->_get_post_types(); $built_in_pt = array('post', 'page'); if ( $post_types['attachment']->cap->edit_posts=='edit_posts') { $built_in_pt[] = 'attachment'; } $show_wc_post_types_under_wc_only = apply_filters('ure_show_wc_post_types_under_wc_only', false); foreach( $post_types as $post_type ) { if ( !isset( $_post_types[$post_type->name] ) || in_array( $post_type->name, $built_in_pt ) ) { continue; } if ( $show_wc_post_types_under_wc_only && in_array( $post_type->name, URE_Woocommerce_Capabilities::$post_types ) ) { continue; } /* if (!$post_type->public) { continue; } * */ $this->groups[$post_type->name] = array( 'caption'=>$post_type->labels->name, 'parent'=>'custom_post_types', 'level'=>2 ); } } // end of add_custom_post_types() private function add_ure_group() { $this->groups['user_role_editor'] = array( 'caption'=>esc_html__('User Role Editor', 'user-role-editor'), 'parent'=>'custom', 'level'=>2 ); } // end of get_ure_group() private function add_woocommerce_groups() { $full_caps = $this->lib->init_full_capabilities( 'role' ); if ( !isset( $full_caps['manage_woocommerce'] ) ) { return; } $post_types = get_post_types( array(), 'objects'); $this->groups['woocommerce'] = array( 'caption'=>esc_html__('WooCommerce', 'user-role-editor'), 'parent'=>'custom', 'level'=>2 ); $this->groups['woocommerce_core'] = array( 'caption'=>esc_html__('Core', 'user-role-editor'), 'parent'=>'woocommerce', 'level'=>3 ); foreach( URE_Woocommerce_Capabilities::$post_types as $post_type ) { if ( !isset( $post_types[$post_type] ) ) { continue; } $this->groups['woocommerce_'. $post_type] = array( 'caption'=>$post_types[$post_type]->labels->name, 'parent'=>'woocommerce', 'level'=>3 ); } } // end of add_woocommerce_group() private function get_base_wp_groups() { $groups = array( 'all'=>array( 'caption'=>esc_html__('All', 'user-role-editor'), 'parent'=>null, 'level'=>0 ), 'core'=>array( 'caption'=>esc_html__('Core', 'user-role-editor'), 'parent'=>'all', 'level'=>1 ), 'general'=>array( 'caption'=>esc_html__('General', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ), 'themes'=>array( 'caption'=>esc_html__('Themes', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ), 'posts'=>array( 'caption'=>esc_html__('Posts', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ), 'pages'=>array( 'caption'=>esc_html__('Pages', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ), 'plugins'=>array( 'caption'=>esc_html__('Plugins', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ), 'users'=>array( 'caption'=>esc_html__('Users', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ) ); return $groups; } // end of get_base_wp_groups public function get_groups_tree() { if ($this->groups!==null) { return $this->groups; } $this->groups = $this->get_base_wp_groups(); $multisite = $this->lib->get('multisite'); if ( $multisite ) { $this->groups['multisite'] = array( 'caption'=>esc_html__('Multisite', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ); } $this->groups['deprecated'] = array( 'caption'=>esc_html__('Deprecated', 'user-role-editor'), 'parent'=>'core', 'level'=>2 ); $this->add_custom_post_types(); $this->groups['custom'] = array( 'caption'=>esc_html__('Custom capabilities', 'user-role-editor'), 'parent'=>'all', 'level'=>1 ); $this->add_ure_group(); $this->add_woocommerce_groups(); $this->groups = apply_filters('ure_capabilities_groups_tree', $this->groups); return $this->groups; } // end of get_groups_tree() /** * return array of built-in WP capabilities (WP 3.1 wp-admin/includes/schema.php) * * @return array */ private function _get_built_in_wp_caps() { $wp_version = get_bloginfo('version'); $multisite = $this->lib->get('multisite'); $caps = array(); $caps['switch_themes'] = array('core', 'themes'); $caps['edit_themes'] = array('core', 'themes'); $caps['activate_plugins'] = array('core', 'plugins'); $caps['edit_plugins'] = array('core', 'plugins'); $caps['edit_users'] = array('core', 'users'); $caps['edit_files'] = array('core', 'deprecated'); $caps['manage_options'] = array('core', 'general'); $caps['moderate_comments'] = array('core', 'posts', 'general'); $caps['manage_categories'] = array('core', 'posts', 'general'); $caps['manage_links'] = array('core', 'general'); $caps['upload_files'] = array('core', 'general'); $caps['import'] = array('core', 'general'); $caps['unfiltered_html'] = array('core','general'); if ( $multisite ) { $caps['unfiltered_html'] = array('deprecated'); } $caps['edit_posts'] = array('core', 'posts'); $caps['edit_others_posts'] = array('core', 'posts'); $caps['edit_published_posts'] = array('core', 'posts'); $caps['publish_posts'] = array('core', 'posts'); $caps['edit_pages'] = array('core', 'pages'); $caps['read'] = array('core', 'general'); $caps['level_10'] = array('core', 'deprecated'); $caps['level_9'] = array('core', 'deprecated'); $caps['level_8'] = array('core', 'deprecated'); $caps['level_7'] = array('core', 'deprecated'); $caps['level_6'] = array('core', 'deprecated'); $caps['level_5'] = array('core', 'deprecated'); $caps['level_4'] = array('core', 'deprecated'); $caps['level_3'] = array('core', 'deprecated'); $caps['level_2'] = array('core', 'deprecated'); $caps['level_1'] = array('core', 'deprecated'); $caps['level_0'] = array('core', 'deprecated'); $caps['edit_others_pages'] = array('core', 'pages'); $caps['edit_published_pages'] = array('core', 'pages'); $caps['publish_pages'] = array('core', 'pages'); $caps['delete_pages'] = array('core', 'pages'); $caps['delete_others_pages'] = array('core', 'pages'); $caps['delete_published_pages'] = array('core', 'pages'); $caps['delete_posts'] = array('core', 'posts'); $caps['delete_others_posts'] = array('core', 'posts'); $caps['delete_published_posts'] = array('core', 'posts'); $caps['delete_private_posts'] = array('core', 'posts'); $caps['edit_private_posts'] = array('core', 'posts'); $caps['read_private_posts'] = array('core', 'posts'); $caps['delete_private_pages'] = array('core', 'pages'); $caps['edit_private_pages'] = array('core', 'pages'); $caps['read_private_pages'] = array('core', 'pages'); $caps['unfiltered_upload'] = array('core', 'general'); $caps['edit_dashboard'] = array('core', 'general'); $caps['update_plugins'] = array('core', 'plugins'); $caps['delete_plugins'] = array('core', 'plugins'); $caps['install_plugins'] = array('core', 'plugins'); $caps['update_themes'] = array('core', 'themes'); $caps['install_themes'] = array('core', 'themes'); $caps['update_core'] = array('core', 'general'); $caps['list_users'] = array('core', 'users'); $caps['remove_users'] = array('core', 'users'); if ( version_compare( $wp_version, '4.4', '<') ) { $caps['add_users'] = array('core', 'users'); // removed from WP v. 4.4. } $caps['promote_users'] = array('core', 'users'); $caps['edit_theme_options'] = array('core', 'themes'); $caps['delete_themes'] = array('core', 'themes'); $caps['export'] = array('core', 'general'); $caps['delete_users'] = array('core', 'users'); $caps['create_users'] = array('core', 'users'); if ( $multisite ) { $caps['create_sites'] = array('core', 'multisite', 'general'); $caps['delete_sites'] = array('core', 'multisite', 'general'); $caps['manage_network'] = array('core', 'multisite', 'general'); $caps['manage_sites'] = array('core', 'multisite', 'general'); $caps['manage_network_users'] = array('core', 'multisite', 'users'); $caps['manage_network_plugins'] = array('core', 'multisite', 'plugins'); $caps['manage_network_themes'] = array('core', 'multisite', 'themes'); $caps['manage_network_options'] = array('core', 'multisite', 'general'); $caps['upgrade_network'] = array('core', 'multisite', 'general'); } $caps['install_languages'] = array('core', 'general'); $caps['resume_plugins'] = array('core', 'plugins'); $caps['resume_themes'] = array('core', 'themes'); $caps['view_site_health_checks'] = array('core', 'general'); $caps = apply_filters('ure_built_in_wp_caps', $caps ); $this->built_in_wp_caps = $caps; return $this->built_in_wp_caps; } // end of _get_built_in_wp_caps() public function get_built_in_wp_caps() { return $this->built_in_wp_caps; } // end of get_built_in_wp_caps() private function get_post_types_without_caps() { $pt_without_caps = array(); $wc_pts = URE_Woocommerce_Capabilities::get_post_types_without_caps(); $pt_without_caps = ure_array_merge( $pt_without_caps, $wc_pts ); return $pt_without_caps; } // end of get_post_types_without_caps() /** * Get capabilities registered with custom post type * * @param object $post_type * @param array $post_edit_caps */ private function get_registered_cpt_caps( $post_type, $post_edit_caps ) { foreach ( $post_edit_caps as $capability ) { if ( isset( $post_type->cap->$capability ) ) { $cap = $post_type->cap->$capability; } else { continue; } if ( !isset( $this->cpt_caps[$cap] ) ) { $this->cpt_caps[$cap] = array(); } else if ( in_array( $post_type->name, $this->cpt_caps[$cap] ) ) { continue; } if ( !isset($this->built_in_wp_caps[$cap]) && !in_array( 'custom', $this->cpt_caps[$cap] ) ) { $this->cpt_caps[$cap][] = 'custom'; } if ( !in_array( 'custom_post_types', $this->cpt_caps[$cap] ) ) { $this->cpt_caps[$cap][] = 'custom_post_types'; } $this->cpt_caps[$cap][] = $post_type->name; } } // end of get_registered_cpt_caps() private function add_group_to_edit_post_cap( $post_type, $post_edit_caps ) { foreach( $post_edit_caps as $cap_id ) { $this->built_in_wp_caps[$cap_id][] = $post_type->name; if ( !in_array('custom_post_types', $this->built_in_wp_caps[$cap_id] ) ) { $this->built_in_wp_caps[$cap_id][] = 'custom_post_types'; } } } // end of add_group_to_edit_post_cap() private function get_custom_post_type_caps( $post_type, $post_edit_caps ) { $pt_without_caps = $this->get_post_types_without_caps(); if ( in_array($post_type->name, $pt_without_caps ) ) { return; } // take into account custom post types, which uses built-in post or page capabilities if ( in_array( $post_type->capability_type, array('post', 'page') ) ) { $this->add_group_to_edit_post_cap( $post_type, $post_edit_caps ); return; } $this->get_registered_cpt_caps( $post_type, $post_edit_caps ); } // end of get_custom_post_type_caps() private function _get_all_custom_post_types_caps() { $post_edit_caps = $this->lib->get_edit_post_capabilities(); $post_types = get_post_types( array(), 'objects' ); $_post_types = $this->lib->_get_post_types(); $built_in_pt = array('post', 'page'); if ( $post_types['attachment']->cap->edit_posts=='edit_posts') { $built_in_pt[] = 'attachment'; } $this->cpt_caps = array(); foreach( $post_types as $post_type ) { if ( !isset( $_post_types[$post_type->name] ) ) { continue; } if ( in_array( $post_type->name, $built_in_pt ) ) { continue; } if ( !isset( $post_type->cap ) ) { continue; } $this->get_custom_post_type_caps( $post_type, $post_edit_caps ); } return $this->cpt_caps; } // end of _get_all_custom_post_types_capabilities() private function get_groups_for_custom_cap( $cap_id ) { $ure_caps = URE_Own_Capabilities::get_caps_groups(); if ( isset( $ure_caps[$cap_id] ) ) { $groups1 = $ure_caps[$cap_id]; } if ( empty( $groups1 ) ) { $wc_caps = URE_Woocommerce_Capabilities::get_caps_groups(); if ( isset($wc_caps[$cap_id] ) ) { $groups1 = $wc_caps[$cap_id]; } } if ( isset( $this->cpt_caps[$cap_id] ) ) { $groups2 = $this->cpt_caps[$cap_id]; } $groups = array('custom'); if ( !empty( $groups1 ) ) { $groups = ure_array_merge( $groups, $groups1 ); } if ( !empty( $groups2 ) ) { $groups = ure_array_merge( $groups, $groups2 ); } return $groups; } // end of get_groups_for_custom_cap() public function get_cap_groups( $cap_id, $built_in_wp_caps=null ) { if ( isset( $this->built_in_wp_caps[$cap_id] ) ) { $groups = $built_in_wp_caps[$cap_id]; } else { $groups = $this->get_groups_for_custom_cap( $cap_id ); } $groups = apply_filters('ure_custom_capability_groups', $groups, $cap_id ); $groups[] = 'all'; // Every capability belongs to the 'all' group $groups = array_unique( $groups ); foreach( $groups as $key=>$value ) { $groups[$key] = 'ure-'. $value; } return $groups; } // end of get_cap_groups() /** * Prevent cloning of the instance of the *Singleton* instance. * * @return void */ public function __clone() { throw new \Exception('Do not clone a singleton instance.'); } // end of __clone() /** * Prevent unserializing of the *Singleton* instance. * * @return void */ public function __wakeup() { throw new \Exception('Do not unserialize a singleton instance.'); } // end of __wakeup() } // end of class URE_Capabilities_Groups_Manager