/** * Handle uploads. * * Set 'upload_files' capability for current user on 'init' hook. * After we set default capabilities, we dynamically set upload_files * to match current action. * * @global type $current_user * @global type $wpcf_access */ function wpcf_access_user_can_upload_files() { global $wpcf_access; $current_user = wp_get_current_user(); list($role, $level) = wpcf_access_rank_user($current_user->ID); // Enqueue add_filter('wpcf_access_exceptions', 'wpcf_access_exceptions_upload_files', 10, 4); add_filter('types_access_check_override', 'wpcf_access_upload_files_check_override'); // First detect if attachment $post_type = wpcf_access_attachment_parent_type(); // Determine post_type if (empty($post_type)) { $post_id = wpcf_access_determine_post_id(); if ($post_id) { $post_type = get_post_type(get_post($post_id)); } else { $post_type = wpcf_access_determine_post_type(); } if (empty($post_type)) { $post_type = 'post'; } } $wpcf_access->upload_files['post_type'] = $post_type; // If rule for post_type exists - follow it if (!empty($current_user->allcaps) && !empty($post_type)) { // TODO Monitor this $post_type_obj = get_post_type_object($post_type); if (is_null($post_type_obj)) { $wpcf_access->errors['post_type_object_missing'][] = $post_type; return false; } $wpcf_access->upload_files['post_type_cap'] = $post_type_obj->cap; if (!empty($post_type_obj->cap->edit_posts)) { $cap_found = wpcf_access_search_cap($post_type_obj->cap->edit_posts); if (!empty($cap_found)) { $wpcf_access->upload_files['cap_found'] = $cap_found; $allow = wpcf_access_is_role_ranked_higher($role, $cap_found['role']); if (!$allow) { $allow = in_array($current_user->ID, $cap_found['users']); } if (!$allow) { unset($current_user->allcaps['upload_files']); unset($current_user->caps['upload_files']); } else { $current_user->allcaps['upload_files'] = 1; $current_user->caps['upload_files'] = 1; } $wpcf_access->upload_files['allow'] = (bool) $allow ? 1 : 0; // If found return $allow return $allow; } } } $wpcf_access->upload_files['handled'] = 0; $wpcf_access->upload_files['allow'] = !empty($current_user->allcaps['upload_files']) ? 1 : 0; // Return default setting if not found return !empty($current_user->allcaps['upload_files']); }
/** * Filters cap. * * @param type $capability_requested * @return string */ function wpcf_access_exceptions_check() { $args = func_get_args(); $capability_requested = $args[0][0]; $parse_args = $args[0][1]; $args = $args[0][2]; $found = wpcf_access_search_cap($capability_requested); // Allow filtering list($capability_requested, $parse_args, $args) = apply_filters('wpcf_access_exceptions', array($capability_requested, $parse_args, $args, $found)); switch ($capability_requested) { case 'edit_comment': $capability_requested = 'edit_posts'; $parse_args['caps'] = array('edit_published_posts', 'edit_comment'); break; case 'moderate_comments': $capability_requested = 'edit_others_posts'; $parse_args['caps'] = array('edit_published_posts', 'edit_comment'); break; // case 'delete_post': // case 'edit_post': // case 'delete_post': // case 'edit_post': default: // TODO Wachout for more! if (isset($args[1]) && isset($args[2])) { $user = get_userdata(intval($args[1])); $post_id = intval($args[2]); $post = get_post($post_id); if (!empty($user->ID) && !empty($post)) { $parse_args_clone = $parse_args; $args_clone = $args; // check post id is valid, avoid capabilities warning if (intval($post->ID) > 0) { $map = map_meta_cap($capability_requested, $user->ID, $post->ID); if (is_array($map) && !empty($map[0])) { foreach ($map as $cap) { $args_clone = array($cap); $result = wpcf_access_check($parse_args_clone['allcaps'], $map, $args_clone, false); if (!$result) { $parse_args['caps'] = array(); } } } } // Not sure why we didn't use this mapping before $capability_requested = wpcf_access_map_cap($capability_requested, $post_id); } if (WPCF_ACCESS_DEBUG) { global $wpcf_access; $wpcf_access->debug_hooks_with_args[$capability_requested][] = array('args' => $args); } } break; } return array($capability_requested, $parse_args, $args); }
/** * Filters default WP capabilities for user. * * WP adds default capabilities depending on built-in role * that sometimes by-pass user_can() check. * * @todo Check if upload_files should be suspended from 3.5 * @global type $current_user * @global type $wpcf_access */ function wpcf_access_user_filter_caps() { $current_user = wp_get_current_user(); if (!empty($current_user->allcaps)) { list($role, $level) = wpcf_access_rank_user($current_user->ID); foreach ($current_user->allcaps as $cap => $true) { $cap_found = wpcf_access_search_cap($cap); if (!empty($cap_found)) { $allow = wpcf_access_is_role_ranked_higher($role, $cap_found['role']); if (!$allow) { $allow = in_array($current_user->ID, $cap_found['users']); } if (!$allow) { unset($current_user->allcaps[$cap]); } } } } }
/** * Filters rules according to sets permitted. * * Settings are defined in /includes/dependencies.php * Each capability is in relationship with some other and can't be used solely * without other. * * @global type $current_user * @global type $wpcf_access * @staticvar null $cache * @return null */ function wpcf_access_filter_rules() { global $current_user, $wpcf_access; static $cache = null; $cache_key = md5(serialize(func_get_args())); if (!empty($cache[$cache_key])) { return $cache[$cache_key]; } $args = func_get_args(); $cap = $args[0][0]; $parse_args = $args[0][1]; $args = $args[0][2]; $found = wpcf_access_search_cap($cap); if ($found) { $wpcf_access->debug_fallbacks_found[$cap] = $found; } else { $wpcf_access->debug_fallbacks_missed[$cap] = 1; return array($cap, $parse_args, $args); } $set = wpcf_access_user_get_caps_by_type($current_user->ID, $found['_context']); if (empty($set)) { $wpcf_access->debug_missing_context[$found['_context']][$cap]['user'] = $current_user->ID; return array($cap, $parse_args, $args); } // Set allowed caps accordin to sets allowed // /includes/dependencies.php will hook on 'access_dependencied' filter // and map capabilities in two arrays depending on main capability. // // Example: // 'edit_own' disabled will have: // 'disallowed_caps' => ('edit_any', 'delete_any', 'publish') // // 'edit_own' enabled will have: // 'allowed_caps' => ('read') $allowed_caps = $disallowed_caps = array(); // Apply dependencies filter list($allowed_caps, $disallowed_caps) = apply_filters('types_access_dependencies', array($allowed_caps, $disallowed_caps, $set)); $filtered = array(); // TODO Monitor this foreach ($disallowed_caps as $disallowed_cap) { if (in_array($disallowed_cap, $parse_args['caps'])) { // Just messup checked caps $filtered['caps'] = array(); $parse_args = array_merge($parse_args, $filtered); $wpcf_access->debug_caps_disallowed[$found['_context']][$cap][] = $disallowed_cap; return array($cap, $parse_args); } } // TODO Monitor this foreach ($allowed_caps as $allowed_cap) { $parse_args['caps'][] = $allowed_cap; $filtered['allcaps'][$allowed_cap] = true; $wpcf_access->debug_caps_allowed[$found['_context']][$cap][] = $allowed_cap; } $parse_args = array_merge($parse_args, $filtered); $cache[$cache_key] = array($cap, $parse_args); return $cache[$cache_key]; }