function define_pattern_caps() { global $pp_role_defs, $wp_roles, $pp_cap_helper; $caps = array(); foreach (array_keys($pp_role_defs->pattern_roles) as $role_name) { if (isset($wp_roles->role_objects[$role_name]->capabilities)) { $caps[$role_name] = array_intersect($wp_roles->role_objects[$role_name]->capabilities, array(1, '1', true)); // if a standard WP role has been deleted, revert to default rolecaps if (in_array($role_name, array('subscriber', 'contributor', 'author', 'editor')) && (empty($caps[$role_name]) || !$this->is_valid_pattern_role($role_name, $caps[$role_name]))) { require_once dirname(__FILE__) . '/default-rolecaps_pp.php'; $caps[$role_name] = PP_Default_Rolecaps::get_default_rolecaps($role_name); } } } $caps = apply_filters('pp_pattern_role_caps', $caps); $type_obj = get_post_type_object('post'); $type_caps = array(); $type_caps['post'] = array_diff_key(get_object_vars($type_obj->cap), array_fill_keys(array('read_post', 'edit_post', 'delete_post'), true)); //foreach( $type_caps['post'] as $prop => $val ) { // force_distinct_post_caps eliminates need for this // // if ( ! is_scalar($val) ) // may be array if running in config mode alongside Role Scoper - TODO: confirm this no longer occurs // $type_caps['post'][$prop] = $prop; // // if ( ( 'edit_posts' == $val ) && ( 'edit_posts' != $prop ) ) // unset( $type_caps['post'][$prop] ); //} $exclude_caps = array_fill_keys(apply_filters('pp_exclude_arbitrary_caps', array('level_0', 'level_1', 'level_2', 'level_3', 'level_4', 'level_5', 'level_6', 'level_7', 'level_8', 'level_9', 'level_10', 'edit_dashboard', 'add_users', 'create_users', 'edit_users', 'list_users', 'promote_users', 'remove_users', 'activate_plugins', 'delete_plugins', 'edit_plugins', 'install_plugins', 'update_plugins', 'delete_themes', 'edit_theme_options', 'edit_themes', 'install_themes', 'switch_themes', 'update_themes', 'export', 'import', 'manage_links', 'manage_categories', 'manage_options', 'update_core', 'pp_manage_settings', 'pp_administer_content', 'pp_unfiltered', 'pp_create_groups', 'pp_delete_groups', 'pp_edit_groups', 'pp_manage_members')), true); foreach (pp_get_operations() as $op) { $exclude_caps["pp_set_{$op}_exceptions"] = true; $exclude_caps["pp_set_term_{$op}_exceptions"] = true; } foreach (array_keys($caps) as $role_name) { // log caps defined for the "post" type $this->pattern_role_type_caps[$role_name] = array_intersect($type_caps['post'], array_keys($caps[$role_name])); // intersect with values of $post_type_obj->cap to account for possible customization of "post" type capabilities if (!$this->is_valid_pattern_role($role_name, $this->pattern_role_type_caps[$role_name])) { // role has no edit_posts cap stored, so use default rolecaps instead require_once dirname(__FILE__) . '/default-rolecaps_pp.php'; if ($def_caps = PP_Default_Rolecaps::get_default_rolecaps($role_name, false)) { $this->pattern_role_type_caps[$role_name] = array_intersect_key($type_caps['post'], array_combine(array_keys($def_caps), array_keys($def_caps))); } } // log caps not defined for any post type or status if ($misc_caps = array_diff_key($caps[$role_name], $pp_cap_helper->all_type_caps, $exclude_caps)) { $this->pattern_role_arbitrary_caps[$role_name] = array_combine(array_keys($misc_caps), array_keys($misc_caps)); } } do_action('pp_define_pattern_caps', $caps); }
function _ppc_count_assigned_exceptions($agent_type, $args = array()) { global $wpdb; $defaults = array('query_agent_ids' => false, 'join_groups' => true); extract(array_merge($defaults, $args), EXTR_SKIP); $item_types = array_merge(pp_get_enabled_post_types(), pp_get_enabled_taxonomies(), pp_get_group_types(array('editable' => true))); $type_clause = "AND e.for_item_type IN ('','" . implode("','", $item_types) . "')"; $type_clause .= " AND e.via_item_type IN ('','" . implode("','", $item_types) . "')"; $ops_clause = "AND operation IN ('" . implode("','", pp_get_operations()) . "')"; $count = array(); $agent_type = pp_sanitize_key($agent_type); if ('user' == $agent_type && $join_groups) { $results = array(); foreach (pp_get_group_types(array(), 'object') as $group_type => $gtype_obj) { global $wpdb; if (!empty($gtype_obj->schema['members'])) { extract($gtype_obj->schema['members']); // members_table, col_group, col_user } else { $members_table = $wpdb->pp_group_members; $col_member_group = 'group_id'; $col_member_user = '******'; } $agent_clause = $query_agent_ids ? "AND gm.{$col_member_user} IN ('" . implode("','", (array) $query_agent_ids) . "')" : ''; if ('groups_only' === $join_groups || 'pp_group' != $group_type) { $agent_type_clause = "( e.agent_type = '{$group_type}' AND gm.{$col_member_group} = e.agent_id )"; } else { $agent_type_clause = "( e.agent_type = 'user' AND gm.user_id = e.agent_id ) OR ( e.agent_type = 'pp_group' AND gm.group_id = e.agent_id )"; } $_results = $wpdb->get_results("SELECT gm.{$col_member_user} as qry_agent_id, e.exception_id, e.for_item_source, e.for_item_type, e.via_item_type, e.operation, COUNT(DISTINCT i.exception_id, i.item_id) AS exc_count FROM {$wpdb->ppc_exception_items} AS i INNER JOIN {$wpdb->ppc_exceptions} AS e ON i.exception_id = e.exception_id INNER JOIN {$members_table} AS gm ON ( {$agent_type_clause} ) WHERE i.inherited_from = '0' {$ops_clause} {$type_clause} {$agent_clause} GROUP BY qry_agent_id, e.for_item_source, e.for_item_type, e.operation"); $results = array_merge($results, $_results); } } else { $agent_clause = $query_agent_ids ? "AND e.agent_id IN ('" . implode("','", (array) $query_agent_ids) . "')" : ''; $results = $wpdb->get_results("SELECT e.agent_id AS qry_agent_id, e.exception_id, e.for_item_source, e.for_item_type, e.operation, e.via_item_type, COUNT(DISTINCT i.exception_id, i.item_id) AS exc_count FROM {$wpdb->ppc_exception_items} AS i INNER JOIN {$wpdb->ppc_exceptions} AS e ON i.exception_id = e.exception_id WHERE i.inherited_from = '0' AND e.agent_type = '{$agent_type}' {$ops_clause} {$type_clause} {$agent_clause} GROUP BY qry_agent_id, e.for_item_source, e.for_item_type, e.operation"); } foreach ($results as $row) { if (!$row->for_item_type) { $type_label = ''; } else { if (!($type_obj = pp_get_type_object($row->for_item_source, $row->for_item_type))) { continue; } $type_label = $type_obj->labels->singular_name; } if ($op_obj = pp_get_op_object($row->operation, $row->for_item_type)) { if ('assign' == $row->operation) { if ($tx_obj = get_taxonomy($row->via_item_type)) { $lbl = str_replace('Term', $tx_obj->labels->singular_name, $op_obj->label); } else { $lbl = $op_obj->label; } //$lbl = sprintf( __('%2$s: %1$s', 'pp'), $op_lbl, $type_label ); } elseif (isset($op_obj->abbrev)) { $lbl = $op_obj->abbrev; } else { $lbl = sprintf(__('%1$s %2$s', 'pp'), $op_obj->label, $type_label); } } else { $lbl = $type_label; } if (!isset($count[$row->qry_agent_id]['exceptions'][$lbl])) { $count[$row->qry_agent_id]['exceptions'][$lbl] = 0; } $count[$row->qry_agent_id]['exceptions'][$lbl] += $row->exc_count; if (!isset($count[$row->qry_agent_id]['exc_count'])) { $count[$row->qry_agent_id]['exc_count'] = 0; } $count[$row->qry_agent_id]['exc_count'] += $row->exc_count; } return $count; }
public static function get_exceptions($args = array()) { $defaults = array('operations' => array(), 'inherited_from' => '', 'for_item_source' => false, 'via_item_source' => false, 'assign_for' => 'item', 'for_item_status' => false, 'post_types' => true, 'taxonomies' => true, 'item_id' => false, 'agent_type' => '', 'agent_id' => 0, 'query_agent_ids' => array(), 'ug_clause' => '', 'return_raw_results' => false, 'extra_cols' => array(), 'cols' => array()); $args = array_merge($defaults, $args); extract($args, EXTR_SKIP); global $wpdb; $except = array(); $operations = (array) $operations; if ($operations) { $operations = array_intersect($operations, pp_get_operations()); } else { $operations = pp_get_operations(); } if (!is_array($post_types)) { $post_types = pp_get_enabled_post_types(); } if (!is_array($taxonomies)) { $taxonomies = pp_get_enabled_taxonomies(); } $default_arr = array('include', 'exclude'); if (!defined('PP_NO_ADDITIONAL_ACCESS')) { $default_arr[] = 'additional'; } $valid_src_types = array('post' => array('post' => array('' => array_fill_keys($default_arr, array_fill_keys($post_types, array()))), 'term' => array()), 'term' => array('term' => array()), 'pp_group' => array('pp_group' => array())); if ($add_source_types = apply_filters('pp_add_exception_source_types', array())) { // valid return array is arr[for_item_source] = arr[via_item_src][via_item_type] = array('include', 'exclude' ) $valid_src_types = array_merge($valid_src_types, $add_source_types); } if ($for_item_source) { $for_item_source = array_flip((array) $for_item_source); if (!($for_item_sources = array_intersect_key($for_item_source, $valid_src_types))) { return array(); } } else { $for_item_sources = $valid_src_types; } $for_item_clauses = array(); foreach (array_keys($for_item_sources) as $for_src_name) { if (isset($valid_src_types[$for_src_name])) { foreach ($operations as $op) { $except["{$op}_{$for_src_name}"] = $valid_src_types[$for_src_name]; } $for_types = array(); foreach (array_keys($valid_src_types[$for_src_name]) as $via_src_name) { if ('post' == $via_src_name) { foreach (array_keys($valid_src_types[$for_src_name][$via_src_name]) as $via_type) { foreach (array_keys($valid_src_types[$for_src_name][$via_src_name][$via_type]) as $mod_type) { $for_types = array_merge($for_types, array_keys($valid_src_types[$for_src_name][$via_src_name][$via_type][$mod_type])); } } } elseif ('term' == $via_src_name) { if ('term' == $for_src_name) { $for_types = $taxonomies; } else { $for_types = $post_types; } } else { $for_types = false; } } if (false === $for_types) { $for_item_clauses[] = "e.for_item_source = '{$for_src_name}'"; } else { $for_item_clauses[] = "e.for_item_source = '{$for_src_name}' AND e.for_item_type IN ('', '" . implode("','", array_unique($for_types)) . "')"; } } } if ($type_clause = pp_implode('OR', $for_item_clauses)) { $type_clause = "AND ( {$type_clause} )"; } if ($via_item_source) { $type_clause .= $wpdb->prepare("AND e.via_item_source = '{$via_item_source}'", $via_item_source); } if ($agent_type && !$ug_clause) { $ug_clause = $wpdb->prepare(" AND e.agent_type = %s AND e.agent_id IN ('" . implode("','", array_map('intval', (array) $agent_id)) . "')", $agent_type); } $operation_clause = "AND e.operation IN ('" . implode("','", $operations) . "')"; $mod_clause = defined('PP_NO_ADDITIONAL_ACCESS') ? "AND e.mod_type != 'additional'" : ''; $assign_for_clause = $assign_for ? $wpdb->prepare("AND i.assign_for = %s", $assign_for) : ''; $inherited_from_clause = $inherited_from !== '' ? $wpdb->prepare("AND i.inherited_from = %d", $inherited_from) : ''; $status_clause = false !== $for_item_status ? $wpdb->prepare("AND e.for_item_status = %s", $for_item_status) : ''; if (!$status_clause && !defined('PPS_VERSION')) { $status_clause = "AND e.for_item_status IN ('','post_status:private','post_status:draft')"; } // exceptions for other statuses will not be applied correctly without custom statuses extension if (!$cols) { $cols = "e.operation, e.for_item_source, e.for_item_type, e.mod_type, e.via_item_source, e.via_item_type, e.for_item_status, i.item_id, i.assign_for"; } $extra_cols_clause = $extra_cols ? ', ' . implode(",", $extra_cols) : ''; $id_clause = false !== $item_id ? $wpdb->prepare("AND i.item_id = %d", $item_id) : ''; $results = $wpdb->get_results("SELECT {$cols}{$extra_cols_clause} FROM {$wpdb->ppc_exceptions} AS e INNER JOIN {$wpdb->ppc_exception_items} AS i ON e.exception_id = i.exception_id WHERE ( 1=1 {$operation_clause} {$assign_for_clause} {$inherited_from_clause} {$mod_clause} {$type_clause} {$status_clause} {$id_clause} ) {$ug_clause}"); if ($return_raw_results) { return $results; } foreach ($results as $row) { // note: currently only additional access can be status-specific $except["{$row->operation}_{$row->for_item_source}"][$row->via_item_source][$row->via_item_type][$row->mod_type][$row->for_item_type][$row->for_item_status][] = $row->item_id; } return $except; }
function pp_get_op_object($operation, $post_type = '') { static $operations; if (!isset($operations)) { $op_captions = apply_filters('pp_operation_captions', array('read' => (object) array('label' => __('Read'), 'noun_label' => __('Reading', 'pp')))); $operations = array_intersect_key($op_captions, array_fill_keys(pp_get_operations(), true)); } $op_obj = isset($operations[$operation]) ? (object) (array) $operations[$operation] : false; // deference op_obj from static array so type-specific filtering is not memcached return apply_filters('pp_operation_object', $op_obj, $operation, $post_type); }