Esempio n. 1
0
/**
 * WP 3.5 This is fix for inserting to editor.
 * 
 * New GUI checks if current use can 'edit_post' with certain ID
 * even if attachment is in question.
 * 
 * Access logic requires that attachment in this case can be inserted
 * in parent post if user can edit parent post_type.
 * 
 * @param type $null
 * @param type $parse_args
 * @return type 
 */
function wpcf_access_files_override($null, $parse_args)
{
    // To check if on media upload screen use
    // either basename($_SERVER['SCRIPT_NAME']) == 'async-upload.php'
    // or strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/async-upload.php') !== false
    // Fix types upload
    if ($parse_args['cap'] == 'upload_files' && !isset($_REQUEST['action']) && isset($_POST['post_id']) && isset($_SERVER['SCRIPT_NAME']) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/async-upload.php') !== false) {
        // This should be the end of a types image upload
        // temporarily set the $_REQUEST['action'] and process the same as send-attachment-to-editor
        $_REQUEST['action'] = 'types-end-image-upload';
    }
    if ($parse_args['cap'] == 'upload_files' && isset($_REQUEST['fetch']) && isset($_SERVER['SCRIPT_NAME']) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/async-upload.php') !== false) {
        // This should be the crunching part types image upload
        // We assume that if we got here then this request is ok.
        return wpcf_access_parse_caps(true, $parse_args);
    }
    // Fix ending to editor
    if (isset($_REQUEST['action'])) {
        $action = strval($_REQUEST['action']);
        switch ($action) {
            case 'send-attachment-to-editor':
            case 'types-end-image-upload':
                if ($_REQUEST['action'] == 'types-end-image-upload') {
                    // remove the temporary action.
                    unset($_REQUEST['action']);
                }
                $parent_id = intval($_POST['post_id']);
                // If user can edit parent post
                // than he can edit attachment too (at least in this case)
                $map = map_meta_cap($parse_args['cap'], get_current_user_id(), $parent_id);
                $result = wpcf_access_check($parse_args['allcaps'], $map, $parse_args['args'], false);
                if (!$result) {
                    return wpcf_access_parse_caps(false, $parse_args);
                } else {
                    return wpcf_access_parse_caps(true, $parse_args);
                }
                break;
            default:
                break;
        }
    }
    return $null;
}
Esempio n. 2
0
/**
 * Main check function.
 * 
 * @global type $wpcf_access
 * @global type $post
 * @global type $pagenow
 * @staticvar null $current_user
 * @param type $allcaps
 * @param type $caps
 * @param type $args
 * @param type $parse true|false to return $allcaps or boolean
 * @return array|boolean 
 */
function wpcf_access_check($allcaps, $caps, $args, $parse = true)
{
    global $wpcf_access;
    // Set user (changed after noticed WP signon empty user)
    static $current_user = null;
    if (is_null($current_user)) {
        if (isset($_POST['log']) && basename($_SERVER['PHP_SELF']) == 'wp-login.php') {
            $current_user = get_user_by('login', esc_sql($_POST['log']));
        } else {
            $current_user = new WP_User(get_current_user_id());
        }
    }
    // Debug if some args[0] is array
    if (WPCF_ACCESS_DEBUG) {
        if (empty($args[0]) || !is_string($args[0])) {
            $wpcf_access->errors['cap_args'][] = array('file' => __FILE__ . ' #' . __LINE__, 'args' => func_get_args(), 'debug_backtrace' => debug_backtrace());
        }
    }
    if (empty($args[0]) || !is_string($args[0])) {
        return $allcaps;
    }
    // Main capability queried
    $capability_requested = $capability_original = $args[0];
    // Other capabilities required to be true
    $caps_clone = $caps;
    // All user capabilities
    $allcaps_clone = $allcaps;
    $map = wpcf_access_role_to_level_map();
    $allow = null;
    $parse_args = array('caps' => $caps_clone, 'allcaps' => $allcaps_clone, 'data' => array(), 'args' => func_get_args(), 'role' => '');
    // Allow check to be altered
    list($capability_requested, $parse_args) = apply_filters('types_access_check', array($capability_requested, $parse_args, $args));
    // TODO Monitor this
    // I saw mixup of $key => $cap and $cap => $true filteres by collect.php
    // Also we're adding sets of capabilities to 'caps'
    //    foreach ($parse_args['caps'] as $k => $v) {
    //        if (is_string($k)) {
    //            $parse_args['caps'][] = $k;
    //            unset($parse_args['caps'][$k]);
    //        }
    //    }
    // Debug
    if ($capability_original != $capability_requested) {
        $wpcf_access->converted[$capability_original][$capability_requested] = 1;
    }
    $parse_args['cap'] = $capability_requested;
    // Allow rules to be altered
    $wpcf_access->rules = apply_filters('types_access_rules', $wpcf_access->rules, $parse_args);
    $override = apply_filters('types_access_check_override', null, $parse_args);
    if (!is_null($override)) {
        return $override;
    }
    // Check post_types($wpcf_access->rules->types)
    // See if main requested capability ($capability_requested)
    // is in collected post types rules and process it.
    if (!empty($wpcf_access->rules->types[$capability_requested])) {
        $types = $wpcf_access->rules->types[$capability_requested];
        $types_role = !empty($types['role']) ? $types['role'] : false;
        $types_role_mapped = !empty($map[$types_role]) ? $map[$types_role] : false;
        $types_users = !empty($types['users']) ? $types['users'] : false;
        $parse_args['role'] = $types_role;
        // Return true for guest
        // Presumption that any capability that requires user to be not-logged
        // (guest) should be allowed. Because other roles have level ranked higher
        // than guest, means it's actually unrestricted by any means.
        if ($types_role == 'guest') {
            return $parse ? wpcf_access_parse_caps(true, $parse_args) : true;
        }
        // Set data
        $parse_args['data'] = wpcf_access_types_caps();
        $parse_args['data'] = isset($parse_args['data'][$capability_requested]) ? $parse_args['data'][$capability_requested] : array();
        // Set level and user checks
        $level_needed = $types_role && $types_role_mapped ? $types_role_mapped : false;
        $user_needed = $types_users ? $types_users : false;
        $level_passed = false;
        if ($level_needed || is_array($user_needed)) {
            $allow = false;
            // Check level
            if ($level_needed) {
                if (!empty($current_user->allcaps[$level_needed])) {
                    $allow = $level_passed = true;
                }
            }
            // Check user
            if (!$level_passed && is_array($user_needed)) {
                if (in_array($current_user->ID, $user_needed)) {
                    $allow = true;
                }
            }
        }
        return $parse ? wpcf_access_parse_caps((bool) $allow, $parse_args) : (bool) $allow;
    }
    // Check taxonomies ($wpcf_access->rules->taxonomies)
    // See if main requested capability ($capability_requested)
    // is in collected taxonomies rules and process it.
    if (!empty($wpcf_access->rules->taxonomies[$capability_requested])) {
        $tax = $wpcf_access->rules->taxonomies[$capability_requested];
        $tax_role = !empty($tax['role']) ? $tax['role'] : false;
        $tax_role_mapped = !empty($map[$tax_role]) ? $map[$tax_role] : false;
        $tax_users = !empty($tax['users']) ? $tax['users'] : false;
        $parse_args['role'] = $tax_role;
        // Check taxonomies 'follow'
        if (!isset($tax['taxonomy'])) {
            $wpcf_access->errors['no_taxonomy_recorded'] = $tax;
        }
        $shared = wpcf_access_is_taxonomy_shared($tax['taxonomy']);
        $follow = $shared ? false : $tax['follow'];
        // Return true for guest (same as for post types)
        if ($tax_role == 'guest') {
            return $parse ? wpcf_access_parse_caps(true, $parse_args) : true;
        }
        // Set level and user
        $level_needed = $tax_role && $tax_role_mapped ? $tax_role_mapped : false;
        $user_needed = $tax_users ? $tax_users : false;
        $level_passed = false;
        // Set data
        $parse_args['data'] = wpcf_access_tax_caps();
        $parse_args['data'] = isset($parse_args['data'][$capability_requested]) ? $parse_args['data'][$capability_requested] : array();
        // Check if taxonomy use 'Same as parent' setting ('follow').
        if (!$follow) {
            if ($level_needed || is_array($user_needed)) {
                $allow = false;
                if ($level_needed) {
                    if (!empty($current_user->allcaps[$level_needed])) {
                        $allow = $level_passed = true;
                    }
                }
                if (!$level_passed && is_array($user_needed)) {
                    if (in_array($current_user->ID, $user_needed)) {
                        $allow = true;
                    }
                }
                return $parse ? wpcf_access_parse_caps((bool) $allow, $parse_args) : (bool) $allow;
            }
        } else {
            global $post, $pagenow;
            // Determine post type
            $post_type = wpcf_access_determine_post_type();
            // If no post type determined, return FALSE
            if (!$post_type) {
                $allow = false;
                return $parse ? wpcf_access_parse_caps((bool) $allow, $parse_args) : (bool) $allow;
            } else {
                $post_type = get_post_type_object($post_type);
                $post_type = sanitize_title($post_type->labels->name);
                $tax_caps = wpcf_access_tax_caps();
                foreach ($tax_caps as $tax_cap_slug => $tax_slug_data) {
                    foreach ($tax_slug_data['match'] as $match => $replace) {
                        $level_passed = true;
                        if (strpos($capability_requested, $match) === 0) {
                            $post_type_check = $post_type;
                            if ($post_type_check && !empty($wpcf_access->rules->types[$replace['match'] . $post_type_check])) {
                                $level_needed = !empty($wpcf_access->rules->types[$replace['match'] . $post_type_check]['role']) && isset($map[$wpcf_access->rules->types[$replace['match'] . $post_type_check]['role']]) ? $map[$wpcf_access->rules->types[$replace['match'] . $post_type_check]['role']] : false;
                                $user_needed = !empty($wpcf_access->rules->types[$replace['match'] . $post_type_check]['users']) ? $wpcf_access->rules->types[$replace['match'] . $post_type_check]['users'] : false;
                                if ($level_needed || is_array($user_needed)) {
                                    $allow = false;
                                    if ($level_needed) {
                                        if (!empty($current_user->allcaps[$level_needed])) {
                                            $allow = $level_passed = true;
                                        }
                                    }
                                    if (!$level_passed && is_array($user_needed)) {
                                        if (in_array($current_user->ID, $user_needed)) {
                                            $allow = true;
                                        }
                                    }
                                    return $parse ? wpcf_access_parse_caps((bool) $allow, $parse_args) : (bool) $allow;
                                }
                            } else {
                                if (!empty($allcaps_clone[$replace['default']])) {
                                    $allow = true;
                                    return $parse ? wpcf_access_parse_caps((bool) $allow, $parse_args) : (bool) $allow;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // Check 3rd party saved settings (option 'wpcf-access-3rd-party')
    // After that check on-the-fly registered capabilities to use default data
    // This is already collected with wpcf_access_hooks_collect
    if (!empty($wpcf_access->third_party_caps[$capability_requested])) {
        // check only requested cap not all
        $data = $wpcf_access->third_party_caps[$capability_requested];
        //foreach ($wpcf_access->third_party_caps as $cap => $data) {
        $wpcf_access->third_party_debug[$capability_requested] = 1;
        // Set saved role if available
        if (isset($data['saved_data']['role'])) {
            $data['role'] = $data['saved_data']['role'];
        }
        $parse_args['role'] = $data['role'];
        // Return true for guest (same as post_types)
        if ($data['role'] == 'guest') {
            return $parse ? wpcf_access_parse_caps(true, $parse_args) : true;
        }
        // removing level testing for custom 3rd party capabilities
        $level_needed = isset($map[$data['role']]) ? $map[$data['role']] : false;
        $user_needed = !empty($data['users']) ? $data['users'] : false;
        $level_passed = false;
        if ($level_needed || is_array($user_needed)) {
            $parse_args['data'] = array();
            $allow = false;
            if ($level_needed) {
                if (!empty($current_user->allcaps[$level_needed])) {
                    $allow = $level_passed = true;
                }
            }
            if (!$level_passed && is_array($user_needed)) {
                if (!in_array($current_user->ID, $user_needed)) {
                    $allow = true;
                }
            }
            return $parse ? wpcf_access_parse_caps((bool) $allow, $parse_args) : (bool) $allow;
        }
        //}
    }
    //    $third_party = get_option('wpcf-access-3rd-party', array());
    //    foreach ($third_party as $areas => $area) {
    //    foreach ($wpcf_access->third_party as $area) {
    //        foreach ($area as $group) {
    //            if (isset($group['permissions']) && is_array($group['permissions'])) {
    //                foreach ($group['permissions'] as $cap => $data) {
    //                    if (isset($caps_clone[0]) && $cap == $caps_clone[0]) {
    //                        $parse_args['role'] = $data['role'];
    //                        // Return true for guest (same as post_types)
    //                        if ($data['role'] == 'guest') {
    //                            return $parse ? wpcf_access_parse_caps(true,
    //                                            $parse_args) : true;
    //                        }
    //                        $level_needed = isset($map[$data['role']]) ? $map[$data['role']] : false;
    //                        $user_needed = !empty($data['users']) ? $data['users'] : false;
    //
    //                        $level_passed = false;
    //
    //                        if ($level_needed || is_array($user_needed)) {
    //                            $parse_args['data'] = array();
    //                            $allow = false;
    //                            if ($level_needed) {
    //                                if (!empty($current_user->allcaps[$level_needed])) {
    //                                    $allow = $level_passed = true;
    //                                }
    //                            }
    //                            if (!$level_passed && is_array($user_needed)) {
    //                                if (!in_array($current_user->ID, $user_needed)) {
    //                                    $allow = true;
    //                                }
    //                            }
    //                            return $parse ? wpcf_access_parse_caps((bool) $allow,
    //                                            $parse_args) : (bool) $allow;
    //                        }
    //                        break;
    //                    }
    //                }
    //            }
    //        }
    //    }
    $wpcf_access->debug_all_hooks[$capability_requested][] = $parse_args;
    return is_null($allow) ? $allcaps : wpcf_access_parse_caps((bool) $allow, $parse_args);
}