function agp_array_flatten($arr_md, $go_deep = true) { //flattens multi-dim arrays (destroys keys) $arr_flat = array(); if (!is_array($arr_md)) { return $arr_flat; } foreach ($arr_md as $element) { if (is_array($element)) { if ($go_deep) { $arr_flat = array_merge($arr_flat, agp_array_flatten($element)); } else { $arr_flat = array_merge($arr_flat, $element); } } else { array_push($arr_flat, $element); } } return $arr_flat; }
function identify_protected_posts($attachment_id = 0, $attachments = false, $cols = '', $args = array()) { $defaults = array('use_object_restrictions' => true, 'use_term_restrictions' => true, 'use_private_status' => true, 'guid' => ''); $args = array_merge($defaults, (array) $args); extract($args); global $wpdb, $scoper; if (!isset($scoper) || is_null($scoper)) { scoper_get_init_options(); scoper_init(); } if (empty($scoper->taxonomies)) { $scoper->load_config(); } $restricted_roles = array(); $unrestricted_roles = array(); // TODO: also protect uploads based on restriction of other taxonomies $restricted_terms = array(); $restricted_objects = array(); $term_restriction_clause = ''; $object_restriction_clause = ''; $limit_clause = ''; $unattached_clause = ''; global $scoper; $reader_roles = array(); foreach ($scoper->role_defs->role_caps as $role_handle => $role_caps) { $caps_by_op = $scoper->cap_defs->organize_caps_by_op(array_keys($role_caps)); if (count($caps_by_op) == 1 && 'read' == key($caps_by_op)) { $reader_roles[] = $role_handle; } } $role_clause = "AND rs.role_name IN ('" . implode("','", scoper_role_handles_to_names($reader_roles)) . "')"; //if ( $use_private_status ) // $role_clause = ( 'rs' == SCOPER_ROLE_TYPE ) ? "AND rs.role_name IN ('post_reader', 'page_reader')" : ''; // if also checking for private status, don't need to check for restriction of private_reader roles //else // $role_clause = ( 'rs' == SCOPER_ROLE_TYPE ) ? "AND rs.role_name IN ('post_reader', 'page_reader', 'private_post_reader', 'private_page_reader')" : ''; if ($use_term_restrictions) { $term_restriction_query = "SELECT rs.obj_or_term_id AS term_id, rs.role_name, rs.max_scope FROM {$wpdb->role_scope_rs} AS rs " . "INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.taxonomy = rs.src_or_tx_name AND tt.taxonomy = 'category' AND tt.term_taxonomy_id = rs.obj_or_term_id " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('entity', 'both') AND rs.topic = 'term' {$role_clause}"; $term_default_restriction_query = "SELECT rs.role_name FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('children', 'both') AND rs.topic = 'term' AND rs.max_scope = 'term' AND rs.src_or_tx_name = 'category' AND rs.obj_or_term_id = '0' {$role_clause}"; $all_terms = array(); $all_terms['category'] = $scoper->get_terms('category', false, COL_ID_RS); if ($results = scoper_get_results($term_restriction_query)) { foreach ($results as $row) { if ('blog' == $row->max_scope) { $unrestricted_roles['category'][$row->role_name][] = $row->term_id; } else { $restricted_roles['category'][$row->role_name][] = $row->term_id; } } } // if there a role is default-restricted, mark all terms as restricted (may be unrestricted later) if ($results = scoper_get_col($term_default_restriction_query)) { foreach ($results as $role_name) { if (isset($unrestricted_roles['category'][$role_name])) { $default_restricted = array_diff($all_terms['category'], $unrestricted_roles['category'][$role_name]); } else { $default_restricted = $all_terms['category']; } if (isset($restricted_roles['category'][$role_name])) { $restricted_roles['category'][$role_name] = array_unique(array_merge($restricted_roles['category'][$role_name], $default_restricted)); } else { $restricted_roles['category'][$role_name] = $default_restricted; } } } $restricted_terms['category'] = isset($restricted_roles['category']) ? agp_array_flatten($restricted_roles['category']) : array(); if ($restricted_terms['category']) { $term_restriction_clause = "OR post_parent IN ( SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} " . "INNER JOIN {$wpdb->term_relationships} AS tr ON tr.object_id = {$wpdb->posts}.ID " . "WHERE tr.term_taxonomy_id IN ('" . implode("','", $restricted_terms['category']) . "') )"; } } if ($attachment_id) { if (is_array($attachment_id)) { $id_clause = "AND ID IN ('" . implode("','", $attachment_id) . "')"; } else { $id_clause = "AND ID = '{$attachment_id}'"; $limit_clause = 'LIMIT 1'; } } elseif ($guid) { $id_clause = "AND guid = '{$file_path}'"; } else { $id_clause = ''; } if (defined('SCOPER_NO_THUMBNAIL_FILTER')) { if ($thumbnail_ids = scoper_get_col("SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_thumbnail_id'")) { $id_clause .= " AND ID NOT IN ('" . implode("','", $thumbnail_ids) . "')"; } } if ($attachments) { // to reduce pool of objects, we only care about those that have an attachment $attachment_query = "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE {$wpdb->posts}.ID IN ( SELECT post_parent FROM {$wpdb->posts} WHERE post_type = 'attachment' {$id_clause} ) "; } if ($use_object_restrictions) { $object_restriction_query = "SELECT rs.obj_or_term_id AS obj_id, rs.role_name, rs.max_scope FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('entity', 'both') AND rs.topic = 'object' AND rs.src_or_tx_name = 'post' {$role_clause} AND rs.obj_or_term_id IN ( {$attachment_query} )"; $object_default_restriction_query = "SELECT rs.role_name FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.require_for IN ('children', 'both') AND rs.topic = 'object' AND rs.max_scope = 'object' AND rs.src_or_tx_name = 'post' AND rs.obj_or_term_id = '0' {$role_clause}"; $all_objects = array(); $all_objects['post'] = scoper_get_col($attachment_query); $restricted_roles = array(); $unrestricted_roles = array(); if ($results = scoper_get_results($object_restriction_query)) { foreach ($results as $row) { if ('blog' == $row->max_scope) { $unrestricted_roles['post'][$row->role_name][] = $row->obj_id; } else { $restricted_roles['post'][$row->role_name][] = $row->obj_id; } } } // if there a role is default-restricted, mark all terms as restricted (may be unrestricted later) if ($results = scoper_get_col($object_default_restriction_query)) { foreach ($results as $role_name) { if (isset($unrestricted_roles['category'][$role_name])) { $default_restricted = array_diff($all_terms['post'], $unrestricted_roles['post'][$role_name]); } else { $default_restricted = $all_objects['post']; } if (isset($restricted_roles['post'][$role_name])) { $restricted_roles['post'][$role_name] = array_unique(array_merge($restricted_roles['post'][$role_name], $default_restricted)); } else { $restricted_roles['post'][$role_name] = $default_restricted; } } } if (!empty($restricted_roles)) { $restricted_objects['post'] = array_unique(agp_array_flatten($restricted_roles['post'])); if ($restricted_objects['post']) { $object_restriction_clause = "OR post_parent IN ( SELECT ID FROM {$wpdb->posts} WHERE ID IN ('" . implode("','", $restricted_objects['post']) . "') )"; } } } if ($use_private_status) { $status_query = "AND post_parent IN ( SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_status = 'private' )"; } if ($attachments) { $attachment_type_clause = "post_type = 'attachment' AND"; $unattached_clause = defined('SCOPER_BLOCK_UNATTACHED_UPLOADS') ? " OR post_parent < 1" : ''; } $single_col = false; if (COLS_ALL_RS === $cols) { $query_cols = '*'; } elseif (COL_ID_RS == $cols) { $query_cols = 'ID'; $single_col = true; } elseif (COLS_ID_DISPLAYNAME_RS == $cols) { if ($attachment) { $query_cols = 'ID, post_title, guid'; } else { $query_cols = 'ID, post_title'; } } else { if ($attachments) { $query_cols = 'ID, guid'; } else { $query_cols = 'ID'; $single_col = true; } } $query = "SELECT {$query_cols} FROM {$wpdb->posts} WHERE {$attachment_type_clause} ( 1=1 {$status_query} {$term_restriction_clause} {$object_restriction_clause} {$unattached_clause} ) {$id_clause} ORDER BY ID DESC {$limit_clause}"; if ($attachment_id && !is_array($attachment_id)) { if ($single_col) { $results = scoper_get_var($query); } else { $results = scoper_get_row($query); } } else { if ($single_col) { $results = scoper_get_col($query); } else { $results = scoper_get_results($query); } } return $results; }
function scoper_filter_terms_for_status($taxonomy, $selected_terms, &$user_terms, $args = array()) { if (defined('DISABLE_QUERYFILTERS_RS') || defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $selected_terms; } global $scoper; $defaults = array('object_id' => 0, 'object_type' => '', 'status' => ''); $args = array_merge($defaults, $args); extract($args); if (!($tx = $scoper->taxonomies->get($taxonomy))) { return $selected_terms; } if (!($src = $scoper->data_sources->get($tx->object_source))) { return $selected_terms; } if (!isset($src->statuses) || count($src->statuses) < 2) { return $selected_terms; } if (!$object_id) { $object_id = scoper_get_object_id($src->name); } if (!$status) { // determine current post status if (defined('XMLRPC_REQUEST') && !empty($GLOBALS['scoper_xmlrpc_post_status'])) { $status = $GLOBALS['scoper_xmlrpc_post_status']; } else { if (!($status = $scoper->data_sources->get_from_http_post('status', $src))) { if ($object_id) { $status = $scoper->data_sources->get_from_db('status', $src, $object_id); } } } } if (!$object_type) { if (!($object_type = cr_find_object_type($src->name, $object_id))) { if (defined('XMLRPC_REQUEST')) { $object_type = 'post'; } else { return $selected_terms; } } } if ('auto-draft' == $status) { $status = 'draft'; } // make sure _others caps are required only for objects current user doesn't own $base_caps_only = true; if ($object_id && !empty($src->cols->owner)) { $col_owner = $src->cols->owner; if ($object = $scoper->data_sources->get_object($src->name, $object_id)) { if (!empty($object->{$col_owner}) && $object->{$col_owner} != $GLOBALS['current_user']->ID) { $base_caps_only = false; } } } if (!($reqd_caps = cr_get_reqd_caps($src->name, OP_EDIT_RS, $object_type, $status, $base_caps_only))) { return $selected_terms; } $qualifying_roles = $scoper->role_defs->qualify_roles($reqd_caps); if ($qualifying_term_assigner_roles = $scoper->role_defs->qualify_roles(array("assign_{$taxonomy}"))) { $qualifying_roles = array_merge($qualifying_roles, $qualifying_term_assigner_roles); } $user_terms = $scoper->qualify_terms_daterange($reqd_caps, $taxonomy, $qualifying_roles); foreach (array_keys($user_terms) as $date_key) { $date_clause = ''; if ($date_key && is_serialized($date_key)) { // Check stored post date against any role date limits associated whith this set of terms (if not stored, check current date) $content_date_limits = unserialize($date_key); $post_date_gmt = $object_id ? $scoper->data_sources->get_from_db('date', $src, $object_id) : 0; if (!$post_date_gmt) { $post_date_gmt = agp_time_gmt(); } if ($post_date_gmt < $content_date_limits->content_min_date_gmt || $post_date_gmt > $content_date_limits->content_max_date_gmt) { unset($user_terms[$date_key]); } } } $user_terms = agp_array_flatten($user_terms); $selected_terms = array_intersect($selected_terms, $user_terms); return $selected_terms; }
function group_members_checklist($group_id, $user_class = 'member', $all_users = '') { global $scoper; if (!$all_users) { $all_users = $scoper->users_who_can('', COLS_ID_NAME_RS); } if ($group_id) { $group = ScoperAdminLib::get_group($group_id); } if ('member' == $user_class) { $current_ids = $group_id ? array_flip(ScoperAdminLib::get_group_members($group_id, COL_ID_RS)) : array(); if (!empty($group) && in_array($group->meta_id, array('rv_pending_rev_notice_ed_nr_', 'rv_scheduled_rev_notice_ed_nr_'))) { $args = array('any_object' => true); $eligible_ids = array(); foreach (get_post_types(array('public' => true), 'object') as $_type => $_type_obj) { $args['object_type'] = $_type; $type_eligible_ids = $scoper->users_who_can(array($_type_obj->cap->edit_published_posts, $_type_obj->cap->edit_others_posts), COL_ID_RS, 'post', 0, $args); $eligible_ids = array_merge($eligible_ids, $type_eligible_ids); } $eligible_ids = array_unique($eligible_ids); } else { // force_all_users arg is a temporary measure to ensure that any user can be viewed / added to a sitewide MU group regardless of what blog backend it's edited through $_args = IS_MU_RS && scoper_get_option('mu_sitewide_groups', true) ? array('force_all_users' => true) : array(); $eligible_ids = $scoper->users_who_can('', COL_ID_RS, '', '', $_args); } $admin_ids = array(); } else { $group_role_defs = 'moderator' == $user_class ? array('rs_group_moderator') : array('rs_group_manager'); if ($group_id) { require_once dirname(__FILE__) . '/role_assignment_lib_rs.php'; $current_roles = ScoperRoleAssignments::organize_assigned_roles(OBJECT_SCOPE_RS, 'group', $group_id, $group_role_defs, ROLE_BASIS_USER); $current_roles = agp_array_flatten($current_roles, false); $current_ids = isset($current_roles['assigned']) ? $current_roles['assigned'] : array(); } else { $current_ids = array(); } $cap_name = defined('SCOPER_USER_ADMIN_CAP') ? constant('SCOPER_USER_ADMIN_CAP') : 'edit_users'; $admin_ids = $scoper->users_who_can($cap_name, COL_ID_RS); // optionally, limit available group managers according to role_admin_blogwide_editor_only option if ('manager' == $user_class) { $require_blogwide_editor = false; if (!empty($group)) { if (!strpos($group->meta_id, '_nr_')) { // don't limit manager selection for groups that don't have role assignments $require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only'); } } if ('admin' == $require_blogwide_editor) { $eligible_ids = $admin_ids; } elseif ('admin_content' == $require_blogwide_editor) { $cap_name = defined('SCOPER_CONTENT_ADMIN_CAP') ? constant('SCOPER_CONTENT_ADMIN_CAP') : 'activate_plugins'; $eligible_ids = array_unique(array_merge($admin_ids, $scoper->users_who_can($cap_name, COL_ID_RS))); } elseif ($require_blogwide_editor) { $post_editors = $scoper->users_who_can('edit_others_posts', COL_ID_RS); $page_editors = $scoper->users_who_can('edit_others_pages', COL_ID_RS); $eligible_ids = array_unique(array_merge($post_editors, $page_editors, $admin_ids)); } else { $eligible_ids = ''; } } else { $eligible_ids = ''; } } // endif user class is not "member" $css_id = $user_class; $args = array('eligible_ids' => $eligible_ids, 'via_other_scope_ids' => $admin_ids, 'suppress_extra_prefix' => true); require_once dirname(__FILE__) . '/agents_checklist_rs.php'; ScoperAgentsChecklist::agents_checklist(ROLE_BASIS_USER, $all_users, $css_id, $current_ids, $args); }
function qualify_terms_daterange($reqd_caps, $taxonomy = 'category', $qualifying_roles = '', $args = array()) { $defaults = array('user' => '', 'return_id_type' => COL_ID_RS, 'use_blog_roles' => true, 'ignore_restrictions' => false); if (isset($args['qualifying_roles'])) { unset($args['qualifying_roles']); } if (isset($args['reqd_caps'])) { unset($args['reqd_caps']); } $args = array_merge($defaults, (array) $args); extract($args); if (!$qualifying_roles) { // calling function might save a little work or limit to a subset of qualifying roles $qualifying_roles = $this->role_defs->qualify_roles($reqd_caps); } if (!$this->taxonomies->is_member($taxonomy)) { return array('' => array()); } if (!is_object($user)) { $user = $GLOBALS['current_rs_user']; } // If the taxonomy does not require objects to have at least one term, there are no strict terms. if (!$this->taxonomies->member_property($taxonomy, 'requires_term')) { $ignore_restrictions = true; } if (!is_array($qualifying_roles)) { $qualifying_roles = array($qualifying_roles => 1); } // no need to serialize and md5 the whole user object if (!empty($user)) { $args['user'] = $user->ID; } // try to pull previous result out of memcache ksort($qualifying_roles); $rolereq_key = md5(serialize($reqd_caps) . serialize(array_keys($qualifying_roles)) . serialize($args)); if (isset($user->qualified_terms[$taxonomy][$rolereq_key])) { return $user->qualified_terms[$taxonomy][$rolereq_key]; } if (!$qualifying_roles) { return array('' => array()); } $all_terms = $this->get_terms($taxonomy, UNFILTERED_RS, COL_ID_RS); // returns term_id, even for WP > 2.3 if (!isset($user->term_roles[$taxonomy])) { $user->get_term_roles_daterange($taxonomy); } // returns term_id for categories $good_terms = array('' => array()); if ($user->term_roles[$taxonomy]) { foreach (array_keys($user->term_roles[$taxonomy]) as $date_key) { //narrow down to roles which satisfy this call AND are owned by current user if ($good_terms[$date_key] = array_intersect_key($user->term_roles[$taxonomy][$date_key], $qualifying_roles)) { // flatten from term_roles_terms[role_handle] = array of term_ids // to term_roles_terms = array of term_ids $good_terms[$date_key] = agp_array_flatten($good_terms[$date_key]); } } } if ($use_blog_roles) { foreach (array_keys($user->blog_roles) as $date_key) { $user_blog_roles = array_intersect_key($user->blog_roles[$date_key], $qualifying_roles); // Also include user's WP blogrole(s) which correspond to the qualifying RS role(s) if ($wp_qualifying_roles = $this->role_defs->qualify_roles($reqd_caps, 'wp')) { if ($user_blog_roles_wp = array_intersect_key($user->blog_roles[$date_key], $wp_qualifying_roles)) { // Credit user's qualifying WP blogrole via equivalent RS role(s) // so we can also enforce "term restrictions", which are based on RS roles $user_blog_roles_via_wp = $this->role_defs->get_contained_roles(array_keys($user_blog_roles_wp), false, 'rs'); $user_blog_roles_via_wp = array_intersect_key($user_blog_roles_via_wp, $qualifying_roles); $user_blog_roles = array_merge($user_blog_roles, $user_blog_roles_via_wp); } } if ($user_blog_roles) { if (empty($ignore_restrictions)) { // array of term_ids that require the specified role to be assigned via taxonomy or object role (user blog caps ignored) $strict_terms = $this->get_restrictions(TERM_SCOPE_RS, $taxonomy); } else { $strict_terms = array(); } foreach (array_keys($user_blog_roles) as $role_handle) { if (isset($strict_terms['restrictions'][$role_handle]) && is_array($strict_terms['restrictions'][$role_handle])) { $terms_via_this_role = array_diff($all_terms, array_keys($strict_terms['restrictions'][$role_handle])); } elseif (isset($strict_terms['unrestrictions'][$role_handle]) && is_array($strict_terms['unrestrictions'][$role_handle])) { $terms_via_this_role = array_intersect($all_terms, array_keys($strict_terms['unrestrictions'][$role_handle])); } else { $terms_via_this_role = $all_terms; } if ($good_terms[$date_key]) { $good_terms[$date_key] = array_merge($good_terms[$date_key], $terms_via_this_role); } else { $good_terms[$date_key] = $terms_via_this_role; } } } } } foreach (array_keys($good_terms) as $date_key) { if ($good_terms[$date_key] = array_intersect($good_terms[$date_key], $all_terms)) { // prevent orphaned category roles from skewing access $good_terms[$date_key] = array_unique($good_terms[$date_key]); } // if COL_TAXONOMY_ID_RS, return a term_taxonomy_id instead of term_id if ($good_terms[$date_key] && COL_TAXONOMY_ID_RS == $return_id_type && taxonomy_exists($taxonomy)) { $all_terms_cols = $this->get_terms($taxonomy, UNFILTERED_RS); $good_tt_ids = array(); foreach ($good_terms[$date_key] as $term_id) { foreach (array_keys($all_terms_cols) as $termkey) { if ($all_terms_cols[$termkey]->term_id == $term_id) { $good_tt_ids[] = $all_terms_cols[$termkey]->term_taxonomy_id; break; } } } $good_terms[$date_key] = $good_tt_ids; } } $user->qualified_terms[$taxonomy][$rolereq_key] = $good_terms; return $good_terms; }
function update_user_groups_multi_status($user_id, $stored_groups, $editable_group_ids) { global $current_rs_user; $posted_groups = array(); $is_administrator = is_user_administrator_rs(); $can_manage = $is_administrator || current_user_can('manage_groups'); $can_moderate = $can_manage || current_user_can('recommend_group_membership'); if (!$can_moderate && !current_user_can('request_group_membership')) { return; } if ($can_manage) { $posted_groups['active'] = explode(',', trim($_POST['current_agents_rs_csv'], '')); } else { $stored_groups = array_diff_key($stored_groups, array('active' => true)); } if ($can_moderate) { $posted_groups['recommended'] = !empty($_POST['recommended_agents_rs_csv']) ? explode(',', trim($_POST['recommended_agents_rs_csv'], '')) : array(); $stored_groups['recommended'] = array_fill_keys($current_rs_user->get_groups_for_user($current_rs_user->ID, array('status' => 'recommended')), true); $editable_group_ids['recommended'] = ScoperAdminLib::get_all_groups(FILTERED_RS, COL_ID_RS, array('reqd_caps' => 'recommend_group_membership')); if (isset($editable_group_ids['active'])) { $editable_group_ids['recommended'] = array_unique($editable_group_ids['recommended'] + $editable_group_ids['active']); } } $stored_groups['requested'] = array_fill_keys($current_rs_user->get_groups_for_user($current_rs_user->ID, array('status' => 'requested')), true); $editable_group_ids['requested'] = ScoperAdminLib::get_all_groups(FILTERED_RS, COL_ID_RS, array('reqd_caps' => 'request_group_membership')); if (isset($editable_group_ids['recommended'])) { $editable_group_ids['requested'] = array_unique($editable_group_ids['requested'] + $editable_group_ids['recommended']); } $posted_groups['requested'] = !empty($_POST['requested_agents_rs_csv']) ? explode(',', trim($_POST['requested_agents_rs_csv'], '')) : array(); $all_posted_groups = agp_array_flatten($posted_groups); $all_stored_groups = array(); foreach (array_keys($stored_groups) as $status) { $all_stored_groups = $all_stored_groups + $stored_groups[$status]; } foreach ($stored_groups as $status => $stored) { if (!$editable_group_ids[$status]) { continue; } // remove group memberships which were not posted for any status, if logged user can edit the group foreach (array_keys($stored) as $group_id) { if (!in_array($group_id, $all_posted_groups)) { if (in_array($group_id, $editable_group_ids[$status])) { ScoperAdminLib::remove_group_user($group_id, $user_id); } } } } foreach ($posted_groups as $status => $posted) { if (!$editable_group_ids[$status]) { continue; } // insert or update group memberships as specified, if logged user can edit the group foreach ($posted as $group_id) { if (in_array($group_id, $editable_group_ids[$status])) { if (!in_array($group_id, $all_stored_groups)) { ScoperAdminLib::add_group_user($group_id, $user_id, $status); } elseif (!in_array($group_id, $stored_groups[$status])) { ScoperAdminLib::update_group_user($group_id, $user_id, $status); } } } } }
function user_can_for_any_term($reqd_caps, $user = '') { if (!is_object($user)) { $user = $GLOBALS['current_rs_user']; } // Instead of just intersecting the missing reqd_caps with termcaps from all term_roles, // require each subset of caps with matching src_name, object type and op_type to // all be satisfied by the same role (any assigned term role). This simulates flt_objects_where behavior (which does so to support role restrictions. $grant_caps = array(); $caps_by_otype = $this->scoper->cap_defs->organize_caps_by_otype($reqd_caps); // temp workaround if ('manage_categories' == current($reqd_caps) && isset($caps_by_otype['post']['link'])) { $caps_by_otype['link']['link_category'] = $caps_by_otype['post']['link']; unset($caps_by_otype['post']['link']); } foreach ($caps_by_otype as $src_name => $otypes) { $object_types = $this->scoper->data_sources->member_property($src_name, 'object_types'); // deal with upload_files and other capabilities which have no specific object type if (!array_diff_key($otypes, array('' => true))) { foreach (array_keys($object_types) as $_object_type) { $otypes[$_object_type] = $otypes['']; } unset($otypes['']); } $uses_taxonomies = scoper_get_taxonomy_usage($src_name, array_keys($otypes)); // this ensures we don't credit term roles on custom taxonomies which have been disabled if (!($uses_taxonomies = array_intersect($uses_taxonomies, $this->scoper->taxonomies->get_all_keys()))) { continue; } foreach ($otypes as $this_otype_caps) { // keyed by object_type $caps_by_op = $this->scoper->cap_defs->organize_caps_by_op((array) $this_otype_caps); foreach ($caps_by_op as $this_op_caps) { // keyed by op_type $roles = $this->scoper->role_defs->qualify_roles($this_op_caps); foreach ($uses_taxonomies as $taxonomy) { if (!isset($user->term_roles[$taxonomy])) { $user->term_roles[$taxonomy] = $user->get_term_roles_daterange($taxonomy); } // call daterange function populate term_roles property - possible perf enhancement for subsequent code even though we don't conider content_date-limited roles here if (array_intersect_key($roles, agp_array_flatten($user->term_roles[$taxonomy], false))) { // okay to include all content date ranges because can_for_any_term checks are only preliminary measures to keep the admin UI open $grant_caps = array_merge($grant_caps, $this_op_caps); break; } } } } } if ($grant_caps) { return array_fill_keys(array_unique($grant_caps), true); } else { return array(); } }