/**
 * Custom roles form.
 *
 * @param type $roles
 * @return string
 */
function wpcf_access_admin_set_custom_roles_level_form($roles, $enabled = true)
{
    $levels = wpcf_access_role_to_level_map();
    $builtin_roles = array();
    $custom_roles = array();
    $output = '';
    foreach ($roles as $role => $details) {
        if (!in_array($role, array('administrator', 'editor', 'author', 'contributor', 'subscriber'))) {
            $compare = 'init';
            foreach ($details['capabilities'] as $capability => $true) {
                if (strpos($capability, 'level_') !== false && $true) {
                    $current_level = intval(substr($capability, 6));
                    if ($compare === 'init' || $current_level > intval($compare)) {
                        $compare = $current_level;
                    }
                }
            }
            $level = $compare !== 'init' ? $compare : 'not_set';
            $custom_roles[$level][$role] = $details;
            $custom_roles[$level][$role]['level'] = $compare !== 'init' ? $compare : 'not_set';
        } else {
            if (isset($levels[$role])) {
                $level = intval(substr($levels[$role], 6));
                $builtin_roles[$level][$role] = $details;
                $builtin_roles[$level][$role]['name'] = translate_user_role($details['name']);
                $builtin_roles[$level][$role]['level'] = $level;
            }
        }
    }
    if (empty($custom_roles)) {
        return '<div id="wpcf-access-custom-roles-wrapper">' . __('No custom roles defined', 'wpcf_access') . '</div>';
    }
    $output .= '<div id="wpcf-access-custom-roles-wrapper">';
    $output .= '<p>' . __('The user level determines which admin actions WordPress allows different kinds of users to perform.', 'wpcf_access') . '</p>';
    $output .= '<div id="wpcf-access-custom-roles-table-wrapper">';
    $output .= '<table cellpadding="10" cellspacing="0" class="wpcf-access-custom-roles-table"><tbody>';
    for ($index = 10; $index >= 0; $index--) {
        $level_empty = true;
        $row = '<tr><td><div class="wpcf-access-roles-level">' . sprintf(__('Level %d', 'wpcf_access'), $index) . '</div></td><td>';
        if (isset($builtin_roles[$index])) {
            $level_empty = false;
            foreach ($builtin_roles[$index] as $role => $details) {
                $row .= '<div class="wpcf-access-roles-builtin">' . $details['name'] . '</div>';
            }
        }
        if (isset($custom_roles[$index])) {
            $level_empty = false;
            foreach ($custom_roles[$index] as $role => $details) {
                $dropdown = '<div class="wpcf-access-custom-roles-select-wrapper">' . '<select name="roles[' . $role . ']" class="wpcf-access-custom-roles-select">';
                for ($index2 = 10; $index2 > -1; $index2--) {
                    $dropdown .= '<option value="' . $index2 . '"';
                    if ($index == $index2) {
                        $dropdown .= ' selected="selected"';
                    }
                    if (!$enabled) {
                        $dropdown .= ' disabled="disabled"';
                    }
                    $dropdown .= '>' . sprintf(__('Level %d', 'wpcf_access'), $index2);
                    $dropdown .= '</option>';
                }
                $dropdown .= '</select>&nbsp;<a href="javascript:void(0);" ' . 'class="wpcf-access-change-level-apply button-primary">' . __('Apply', 'wpcf_access') . '</a>&nbsp;<a href="javascript:void(0);" ' . 'class="wpcf-access-change-level-cancel button-secondary">' . __('Cancel') . '</a>' . '</div>';
                $row .= '<div class="wpcf-access-roles-custom">' . $details['name'] . '&nbsp;' . '<a href="javascript:void(0);"';
                if ($enabled) {
                    $row .= ' class="wpcf-access-change-level"';
                }
                $row .= '>' . __('Change level', 'wpcf_access') . '</a>' . '&nbsp;';
                if ($enabled) {
                    $row .= $dropdown;
                }
                $row .= ' &nbsp;' . '<a ';
                if ($enabled) {
                    $row .= 'href="#TB_inline?height=155&width=500&inlineId=wpcf-access-reassign-' . sanitize_title($role) . '&modal=true" class="wpcf-access-delete-role thickbox"';
                } else {
                    $row .= 'href="javascript:void(0);"';
                }
                $row .= '>' . __('Delete role', 'wpcf_access') . '</a>' . '&nbsp;';
                if ($enabled) {
                    $row .= wpcf_access_reassign_role_form($role);
                }
                $row .= '</div>';
            }
        }
        $row .= '</td></tr>';
        if (!$level_empty) {
            $output .= $row;
        }
    }
    if (isset($custom_roles['not_set'])) {
        $output .= '<tr><td><div class="wpcf-access-roles-level">' . __('Undefined', 'wpcf_access') . '</div></td><td>';
        foreach ($custom_roles['not_set'] as $role => $details) {
            $dropdown = '<div class="wpcf-access-custom-roles-select-wrapper">' . '<select name="roles[' . $role . ']" class="wpcf-access-custom-roles-select">';
            for ($index2 = 10; $index2 >= 0; $index2--) {
                $dropdown .= '<option value="' . $index2 . '"';
                if ($index2 == 1) {
                    $dropdown .= ' selected="selected"';
                }
                if (!$enabled) {
                    $dropdown .= ' disabled="disabled"';
                }
                $dropdown .= '>' . sprintf(__('Level %d', 'wpcf_access'), $index2) . '</option>';
            }
            $dropdown .= '</select>&nbsp;<a href="javascript:void(0);" ' . 'class="wpcf-access-change-level-apply button-primary">' . __('Apply', 'wpcf_access') . '</a>&nbsp;<a href="javascript:void(0);" ' . 'class="wpcf-access-change-level-cancel button-secondary">' . __('Cancel') . '</a>' . '</div>';
            $output .= '<div class="wpcf-access-roles-custom">' . $details['name'] . '&nbsp;' . '<a href="javascript:void(0);"';
            if ($enabled) {
                $output .= ' class="wpcf-access-change-level"';
            }
            $output .= '>' . __('Change level', 'wpcf_access') . '</a>' . '&nbsp;';
            if ($enabled) {
                $output .= $dropdown;
            }
            $output .= '<a ';
            if ($enabled) {
                $output .= 'href="#TB_inline?height=155&width=500&inlineId=wpcf-access-reassign-' . $role . '&modal=true" class="wpcf-access-delete-role thickbox"';
            } else {
                $output .= 'href="javascript:void(0);"';
            }
            $output .= '>' . __('Delete role', 'wpcf_access') . '</a>' . '&nbsp;';
            if ($enabled) {
                $output .= wpcf_access_reassign_role_form($role);
            }
        }
        $output .= '</div></td></tr>';
    }
    $output .= '</tbody></table>';
    $output .= '</div>';
    $output .= '</div>';
    return $output;
}
예제 #2
0
/**
 * Maps role to level.
 * 
 * @param type $role
 * @return type 
 */
function wpcf_access_role_to_level($role)
{
    $map = wpcf_access_role_to_level_map();
    return isset($map[$role]) ? $map[$role] : false;
}
예제 #3
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);
}