function flt_recent_comments($query)
 {
     // Due to missing get_comments hook prior to WP 3.1, this filter operates on every front-end query.
     // If query doesn't pertain to comments, skip out with as little overhead as possible.
     if (strpos($query, 'comment') && strpos($query, "ELECT") && !strpos($query, 'posts as parent') && !strpos($query, "COUNT") && strpos($query, "comment_approved")) {
         if (!is_attachment() && !is_content_administrator_rs()) {
             global $wpdb;
             if (strpos($query, " {$wpdb->posts} ")) {
                 return $query;
             }
             if (awp_is_plugin_active('wp-wall')) {
                 $options = WPWall_GetOptions();
                 if (strpos($query, 'comment_post_ID=' . $options['pageId'])) {
                     return $query;
                 }
             }
             if (strpos($query, $wpdb->comments)) {
                 $query = str_replace(" post_status = 'publish'", " {$wpdb->posts}.post_status = 'publish'", $query);
                 // theoretically, a slight performance enhancement if we can simplify the query to skip filtering of attachment comments
                 if (defined('SCOPER_NO_ATTACHMENT_COMMENTS') || false !== strpos($query, 'comment_post_ID =')) {
                     if (!strpos($query, "JOIN {$wpdb->posts}")) {
                         $query = preg_replace("/FROM\\s*{$wpdb->comments}\\s*WHERE /", "FROM {$wpdb->comments} INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID WHERE ", $query);
                     }
                     $query = apply_filters('objects_request_rs', $query, 'post', '', array('skip_teaser' => true));
                 } else {
                     $query = str_replace("user_id ", "{$wpdb->comments}.user_id ", $query);
                     $query = str_replace("SELECT {$wpdb->comments}.* FROM {$wpdb->comments}", "SELECT DISTINCT {$wpdb->comments}.* FROM {$wpdb->comments}", $query);
                     if (!strpos($query, ' DISTINCT ')) {
                         $query = str_replace("SELECT ", "SELECT DISTINCT ", $query);
                     }
                     $post_types = array_diff(get_post_types(array('public' => true)), array('attachment'));
                     $post_type_in = "'" . implode("','", $post_types) . "'";
                     $join = "LEFT JOIN {$wpdb->posts} as parent ON parent.ID = {$wpdb->posts}.post_parent AND parent.post_type IN ({$post_type_in}) AND {$wpdb->posts}.post_type = 'attachment'";
                     $use_post_types = scoper_get_option('use_post_types');
                     $where = array();
                     foreach ($post_types as $type) {
                         if (!empty($use_post_types[$type])) {
                             $where_post = apply_filters('objects_where_rs', '', 'post', $type, array('skip_teaser' => true));
                         } else {
                             $where_post = "AND 1=1";
                         }
                         $where[] = "{$wpdb->posts}.post_type = '{$type}' {$where_post}";
                         $where[] = "{$wpdb->posts}.post_type = 'attachment' AND parent.post_type = '{$type}' " . str_replace("{$wpdb->posts}.", "parent.", $where_post);
                     }
                     $where = agp_implode(' ) OR ( ', $where, ' ( ', ' ) ');
                     if (!strpos($query, "JOIN {$wpdb->posts}")) {
                         $query = str_replace("WHERE ", "INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID {$join} WHERE ( {$where} ) AND ", $query);
                     } else {
                         $query = str_replace("WHERE ", "{$join} WHERE {$where} AND ", $query);
                     }
                 }
             }
         }
     }
     return $query;
 }
 function flt_comments_clauses($clauses, &$qry_obj)
 {
     global $wpdb;
     if (is_admin() && defined('SCOPER_NO_COMMENT_FILTERING') && empty($GLOBALS['current_user']->allcaps['moderate_comments'])) {
         return $clauses;
     }
     if (empty($clauses['join'])) {
         $clauses['join'] = "JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID";
     }
     // for WP 3.1 and any manual 3rd-party join construction (subsequent filter will expand to additional statuses as appropriate)
     $clauses['where'] = preg_replace("/ post_status\\s*=\\s*[']?publish[']?/", " {$wpdb->posts}.post_status = 'publish'", $clauses['where']);
     // performance enhancement: simplify comments query if there are no attachment comments to filter (TODO: cache this result)
     $qry_any_attachment_comments = "SELECT ID FROM {$wpdb->posts} AS p INNER JOIN {$wpdb->comments} AS c ON p.ID = c.comment_post_ID WHERE p.post_type = 'attachment' LIMIT 1";
     $post_type_arg = isset($qry_obj->query_vars['post_type']) ? $qry_obj->query_vars['post_type'] : '';
     $post_id = !empty($qry_obj->query_vars['post_id']) ? $qry_obj->query_vars['post_id'] : 0;
     $attachment_query = 'attachment' == $post_type_arg || $post_id && 'attachment' == get_post_field('post_type', $post_id);
     $args = array('skip_teaser' => true);
     if (is_admin()) {
         require_once 'admin/comments-interceptor-admin_rs.php';
         $args['force_reqd_caps'] = CommentsInterceptorAdmin_RS::get_reqd_caps();
     }
     // $attachment_query: current query is for attachment post type, or for a specific post which is an attachment
     // $post_id: current query is for a specific post
     // 	 NOTE: even if not $attachment_query, attachment comments are included by default along with comments on other post types (i.e. for Recent Comments sidebar)
     if (defined('SCOPER_NO_ATTACHMENT_COMMENTS') || !$attachment_query && ($post_id || !defined('SCOPER_ATTACHMENT_COMMENTS') && !scoper_get_var($qry_any_attachment_comments))) {
         $clauses['where'] = " AND " . $clauses['where'];
         $clauses['where'] = "1=1" . apply_filters('objects_where_rs', $clauses['where'], 'post', $post_type_arg, $args);
     } else {
         if (false === strpos($clauses['fields'], 'DISTINCT ')) {
             $clauses['fields'] = 'DISTINCT ' . $clauses['fields'];
         }
         if ($post_type_arg) {
             $post_types = (array) $post_type_arg;
         } else {
             $post_types = array_diff(get_post_types(array('public' => true)), array('attachment'));
         }
         $post_type_in = "'" . implode("','", $post_types) . "'";
         $clauses['join'] .= " LEFT JOIN {$wpdb->posts} as parent ON parent.ID = {$wpdb->posts}.post_parent AND parent.post_type IN ({$post_type_in}) AND {$wpdb->posts}.post_type = 'attachment'";
         $use_post_types = scoper_get_option('use_post_types');
         $where = array();
         foreach ($post_types as $type) {
             if (!empty($use_post_types[$type])) {
                 $where_post = apply_filters('objects_where_rs', '', 'post', $type, $args);
             } else {
                 $where_post = "AND 1=1";
             }
             $where[] = "{$wpdb->posts}.post_type = '{$type}' {$where_post}";
             $where[] = "{$wpdb->posts}.post_type = 'attachment' AND parent.post_type = '{$type}' " . str_replace("{$wpdb->posts}.", "parent.", $where_post);
         }
         $clauses['where'] = preg_replace("/\\s*AND\\s*{$wpdb->posts}.post_status\\s*=\\s*[']?publish[']?/", "", $clauses['where']);
         $clauses['where'] .= ' AND ( ' . agp_implode(' ) OR ( ', $where, ' ( ', ' ) ') . ' )';
     }
     return $clauses;
 }
 function flt_users_where($where, $reqd_caps = '', $object_src_name = '', $object_id = '', $args = array())
 {
     if (!USER_ROLES_RS && !GROUP_ROLES_RS) {
         return $where;
     }
     global $wpdb;
     static $stored_owner_id;
     if (!isset($stored_owner_id)) {
         $stored_owner_id = array();
     }
     $defaults = array('use_term_roles' => 1, 'use_blog_roles' => 1, 'skip_object_roles' => 0, 'querying_groups' => 0, 'ignore_group_roles' => false, 'ignore_user_roles' => false, 'object_type' => '', 'objscope_roles' => '', 'preserve_or_clause' => '', 'enforce_duration_limits' => true, 'enforce_content_date_limits' => true);
     $args = array_merge($defaults, (array) $args);
     extract($args);
     // Default to not honoring custom user caps, but support option
     $custom_user_blogcaps = SCOPER_CUSTOM_USER_BLOGCAPS;
     // if reqd_caps are missing, try to determine context from URI
     if (!$reqd_caps) {
         return $where;
     }
     // no basis for filtering without required caps
     $reqd_caps = (array) $reqd_caps;
     // if rolenames are intermingled with caps in reqd_caps array, convert them to caps
     $reqd_caps = $this->scoper->role_defs->role_handles_to_caps($reqd_caps, true);
     //arg: also check for unprefixed WP rolenames
     if ($object_id && !$object_src_name) {
         $object_id = 0;
     }
     if ($object_id) {
         foreach ($reqd_caps as $cap_name) {
             if ($meta_caps = apply_filters('map_meta_cap_rs', (array) $cap_name, $cap_name, -1, $object_id)) {
                 $reqd_caps = array_diff($reqd_caps, array($cap_name));
                 $reqd_caps = array_unique(array_merge($reqd_caps, $meta_caps));
             }
         }
         if ('post' == $object_src_name && ($use_term_roles || $use_blog_roles)) {
             if ($post = get_post($object_id)) {
                 $object_date_gmt = $post->post_date_gmt;
             }
         } else {
             $object_date_gmt = '';
         }
     }
     $owner_has_all_caps = true;
     // IMPORTANT: set this false downstream as appropriate
     $rs_where = array();
     // Group the required caps by object type (as defined by $scoper->cap_defs).
     // The 2nd arg causes caps without an otype association to be included with a nullstring src_name key
     // The 3rd arg forces caps with a data source other than $object_src to be also lumped in with sourceless caps
     // $caps_by_otype[src_name][object_type] = array of cap names
     $caps_by_otype = $this->scoper->cap_defs->organize_caps_by_otype($reqd_caps, true, $object_src_name, $object_type);
     foreach ($caps_by_otype as $src_name => $otypes) {
         if ($object_type) {
             $otypes = array_intersect_key($otypes, array($object_type => 1));
         }
         // Cap reqs that pertain to other data sources or have no data source association
         // will only be satisfied by blog roles.
         $args['use_term_roles'] = $use_term_roles && $src_name == $object_src_name;
         $args['skip_object_roles'] = $skip_object_roles || $src_name != $object_src_name;
         $this_src_object_id = $src_name == $object_src_name ? $object_id : 0;
         if ($src_name) {
             if (!($src = $this->scoper->data_sources->get($src_name))) {
                 continue;
             }
             $uses_taxonomies = scoper_get_taxonomy_usage($src_name, array_keys($otypes));
             if ($this_src_object_id && $args['use_term_roles'] && !empty($uses_taxonomies)) {
                 $args['object_terms'] = array();
                 foreach ($uses_taxonomies as $taxonomy) {
                     $args['object_terms'][$taxonomy] = $this->scoper->get_terms($taxonomy, UNFILTERED_RS, COL_ID_RS, $this_src_object_id);
                 }
             }
         }
         foreach ($otypes as $object_type => $this_otype_caps) {
             $qry_roles = array();
             $args['use_term_roles'] = $args['use_term_roles'] && scoper_get_otype_option('use_term_roles', $src_name, $object_type);
             //$caps_by_op = $this->scoper->cap_defs->organize_caps_by_op($this_otype_caps, true); //arg: retain caps which are not scoper-defined
             //foreach ( $caps_by_op as $op => $this_op_caps ) {
             foreach ($this_otype_caps as $cap_name) {
                 // If supporting custom user blogcaps, a separate role clause for each cap
                 // Otherwise (default) all reqd_caps from one role assignment (whatever scope it may be)
                 if ($custom_user_blogcaps) {
                     $reqd_caps_arg = array($cap_name);
                 } else {
                     $reqd_caps_arg = $this_otype_caps;
                     $cap_name = '';
                 }
                 // 'blog' argument forces inclusion of qualifying WP roles even if scoping with RS roles
                 // (will later strip out non-scopable roles for term role / object role clauses)
                 $args['roles'] = $this->scoper->role_defs->qualify_roles($reqd_caps_arg, '', '', array('all_wp_caps' => true));
                 if ($args['roles'] || !$src_name) {
                     if (USER_ROLES_RS && !$ignore_user_roles) {
                         $qry_roles[$cap_name]['general'][ROLE_BASIS_USER] = $this->users_queryroles($reqd_caps_arg, $src_name, $this_src_object_id, $args);
                     }
                     if (GROUP_ROLES_RS && !$ignore_group_roles) {
                         $qry_roles[$cap_name]['general'][ROLE_BASIS_GROUPS] = $this->users_queryroles($reqd_caps_arg, $src_name, $this_src_object_id, $args);
                     }
                 }
                 // potentially, a separate set of role clauses for object owner
                 if ($this_src_object_id && $src->cols->owner) {
                     $owner_needs_caps = $this->scoper->cap_defs->get_base_caps($reqd_caps_arg);
                     //returns array of caps the owner needs, after removing those which are credited to owners automatically
                     if ($owner_needs_caps) {
                         $owner_has_all_caps = false;
                     }
                     if ($owner_needs_caps != $reqd_caps_arg) {
                         if (!isset($stored_owner_id[$src_name][$this_src_object_id])) {
                             // DON'T initialize this at top of function
                             $stored_owner_id[$src_name][$this_src_object_id] = scoper_get_var("SELECT {$src->cols->owner} FROM {$src->table} WHERE {$src->cols->id} = '{$object_id}' LIMIT 1");
                         }
                         if ($stored_owner_id[$src_name][$this_src_object_id]) {
                             $owner_roles = $this->scoper->role_defs->qualify_roles($owner_needs_caps);
                             if ($args['roles'] = array_diff_key($owner_roles, $args['roles'])) {
                                 // if owners (needing fewer caps) qualify under different roles than other users:
                                 if (GROUP_ROLES_RS && !$ignore_group_roles) {
                                     if (!isset($owner_groups)) {
                                         $owner_groups = WP_Scoped_User::get_groups_for_user($stored_owner_id[$src_name][$this_src_object_id]);
                                     }
                                     //$owner_groups = scoper_get_col("SELECT $wpdb->user2group_gid_col FROM $wpdb->user2group_rs WHERE $wpdb->user2group_uid_col = '{$stored_owner_id[$src_name][$this_src_object_id]}'");
                                     if ($owner_groups) {
                                         $qry_roles[$cap_name]['owner'][ROLE_BASIS_GROUPS] = $this->users_queryroles($owner_needs_caps, $src_name, $this_src_object_id, $args);
                                     }
                                 }
                                 if (USER_ROLES_RS && !$ignore_user_roles) {
                                     $qry_roles[$cap_name]['owner'][ROLE_BASIS_USER] = $this->users_queryroles($owner_needs_caps, $src_name, $this_src_object_id, $args);
                                 }
                             }
                             // endif owner needs any caps assigned by role
                         }
                         //endif stored owner_id found
                     }
                     // endif any required caps are automatically granted to owner
                 }
                 // endif request is for a specific object from a data source which stores owner_id
                 // If not supporting custom blogcaps, we actually passed all of this object type's caps together
                 if (!$custom_user_blogcaps) {
                     break;
                 }
             }
             // end foreach this_otype_caps
             //d_echo ('scope data');
             //dump($qry_roles);
             // ------------ Construct this object type's where clause from $qry_roles: -----------------
             // ( note: if custom user blogcaps are not enabled, all roles stored into one cap_name dimension )
             // $qry_roles[cap_name][general/owner][user/groups]['object'][''] = array of role handles
             // $qry_roles[cap_name][general/owner][user/groups]['term'][taxonomy] = array of role handles
             // $qry_roles[cap_name][general/owner][user/groups]['blog'][role_type] = array of role handles
             // now construct the query for this iteration's operation type
             $table_aliases = array(ROLE_BASIS_USER => 'uro', ROLE_BASIS_GROUPS => 'gro');
             foreach ($qry_roles as $cap_name => $user_types) {
                 // note: default is to put qualifying roles from all reqd_caps into a single "cap_name" element
                 $ot_where = array();
                 if (!empty($stored_owner_id) && $owner_has_all_caps && USER_ROLES_RS && !$ignore_user_roles) {
                     $ot_where['owner'][ROLE_BASIS_USER] = "uro.user_id = '{$stored_owner_id[$src_name][$this_src_object_id]}'";
                 }
                 foreach ($user_types as $user_type => $role_bases) {
                     foreach ($role_bases as $role_basis => $scopes) {
                         $alias = $table_aliases[$role_basis];
                         $content_date_comparison = $enforce_content_date_limits && !empty($object_date_gmt) ? "'{$object_date_gmt}'" : '';
                         $duration_clause = scoper_get_duration_clause($content_date_comparison, $alias, $enforce_duration_limits);
                         // arg: skip duration clause
                         foreach ($scopes as $scope => $keys) {
                             foreach ($keys as $key => $role_names) {
                                 if (empty($role_names)) {
                                     continue;
                                 }
                                 $role_in = "'" . implode("','", $role_names) . "'";
                                 switch ($scope) {
                                     case OBJECT_SCOPE_RS:
                                         $id_clause = $object_id ? "AND {$alias}.obj_or_term_id = '{$object_id}'" : '';
                                         $ot_where[$user_type][$role_basis][$scope][$key] = "{$alias}.scope = 'object' AND {$alias}.assign_for IN ('entity', 'both') AND {$alias}.src_or_tx_name = '{$src_name}' AND {$alias}.role_type = 'rs' AND {$alias}.role_name IN ({$role_in}) {$duration_clause} {$id_clause}";
                                         break;
                                     case TERM_SCOPE_RS:
                                         $terms_clause = $object_id && $args['object_terms'][$key] ? "AND {$alias}.obj_or_term_id IN ('" . implode("', '", $args['object_terms'][$key]) . "')" : '';
                                         $ot_where[$user_type][$role_basis][$scope][$key] = "{$alias}.scope = 'term' AND {$alias}.assign_for IN ('entity', 'both') AND {$alias}.src_or_tx_name = '{$key}' {$terms_clause} AND {$alias}.role_type = 'rs' AND {$alias}.role_name IN ({$role_in}) {$duration_clause}";
                                         break;
                                     case BLOG_SCOPE_RS:
                                         $ot_where[$user_type][$role_basis][$scope][$key] = "{$alias}.scope = 'blog' AND {$alias}.role_type = '{$key}' AND {$alias}.role_name IN ({$role_in}) {$duration_clause}";
                                         break;
                                 }
                                 // end scope switch
                             }
                             // end foreach key
                             if (!empty($ot_where[$user_type][$role_basis][$scope])) {
                                 // [key 1 clause] [OR] [key 2 clause] [OR] ...
                                 $ot_where[$user_type][$role_basis][$scope] = agp_implode(' ) OR ( ', $ot_where[$user_type][$role_basis][$scope], ' ( ', ' ) ');
                             }
                         }
                         // end foreach scope
                         if (!empty($ot_where[$user_type][$role_basis])) {
                             // [object scope clauses] [OR] [taxonomy scope clauses] [OR] [blog scope clauses]
                             $ot_where[$user_type][$role_basis] = agp_implode(' ) OR ( ', $ot_where[$user_type][$role_basis], ' ( ', ' ) ');
                             if ('owner' == $user_type) {
                                 switch ($role_basis) {
                                     case ROLE_BASIS_GROUPS:
                                         $ot_where[$user_type][$role_basis] .= "AND gro.group_id IN ('" . implode("', '", $owner_groups) . "')";
                                         break;
                                     case ROLE_BASIS_USER:
                                         $ot_where[$user_type][$role_basis] .= "AND uro.user_id = '{$stored_owner_id[$src_name][$this_src_object_id]}'";
                                 }
                                 // end role basis switch
                             }
                             // endif owner
                         }
                         // endif any role clauses for this user_type/role_basis
                     }
                     // end foreach role basis (user or groups)
                 }
                 // end foreach user type (general or owner)
                 foreach ($ot_where as $user_type => $arr) {
                     foreach ($arr as $role_basis => $val) {
                         if (!empty($ot_where[$user_type])) {
                             // [group role clauses] [OR] [user role clauses]
                             $ot_where[$user_type] = agp_implode(' ) OR ( ', $ot_where[$user_type], ' ( ', ' ) ');
                         }
                     }
                 }
                 if (!empty($ot_where)) {
                     // [general user clauses] [OR] [owner clauses]
                     $rs_where[$src_name][$object_type][$cap_name] = agp_implode(' ) OR ( ', $ot_where, ' ( ', ' ) ');
                 }
             }
             // end foreach cap name (for optional support of custom user blogcaps)
             if (!empty($rs_where[$src_name][$object_type])) {
                 // [cap1 clauses] [AND] [cap2 clauses]
                 $rs_where[$src_name][$object_type] = agp_implode(' ) AND ( ', $rs_where[$src_name][$object_type], ' ( ', ' ) ');
             }
         }
         // end foreach otypes
         if (isset($rs_where[$src_name])) {
             // object_type1 clauses [AND] [object_type2 clauses] [AND] ...
             $rs_where[$src_name] = agp_implode(' ) AND ( ', $rs_where[$src_name], ' ( ', ' ) ');
         }
     }
     // end foreach data source
     // data_source 1 clauses [AND] [data_source 2 clauses] [AND] ...
     $rs_where = agp_implode(' ) AND ( ', $rs_where, ' ( ', ' ) ');
     if ($rs_where) {
         if (false !== strpos($where, $rs_where)) {
             return $where;
         }
         if (!empty($preserve_or_clause)) {
             $rs_where = "( ( {$rs_where} ) OR ( {$preserve_or_clause} ) )";
         }
         if ($where) {
             $where = " AND ( {$rs_where} ) {$where}";
         } else {
             $where = " AND {$rs_where}";
         }
     } else {
         // if no valid role clauses were constructed, required caps are invalid; no users can do it
         $where = ' AND 1=2';
     }
     return $where;
 }
 function objects_where_scope_clauses($src_name, $reqd_caps, $args)
 {
     // Optional Args (will be defaulted to meaningful values)
     // Note: ignore_restrictions affects Scoper::qualify_terms() output
     $defaults = array('taxonomies' => '', 'use_blog_roles' => true, 'terms_query' => false, 'qualifying_object_roles' => false, 'skip_objscope_check' => false, 'require_full_object_role' => false, 'objrole_revisions_clause' => false, 'ignore_restrictions' => false);
     // Required Args
     // NOTE: use_object_roles is a boolean for the single object_type in question, but use_term_roles is array[taxonomy] = true or false
     $required = array_fill_keys(array('user', 'object_type', 'qualifying_roles', 'otype_use_term_roles', 'otype_use_object_roles'), true);
     if ($missing = array_diff_key($required, $args)) {
         rs_notice(sprintf('Role Scoper Runtime Error (%1$s) - Missing argument(s): %2$s', 'objects_where_scope_clauses', implode(", ", array_keys($missing))));
         return ' 1=2 ';
     }
     $defaults = array_merge($defaults, $required);
     $args = array_merge($defaults, (array) $args);
     extract($args);
     if (!($src = $this->scoper->data_sources->get($src_name))) {
         rs_notice(sprintf('Role Scoper Config Error (%1$s): Data source (%2$s) is not defined.', 'objects_where_scope_clauses', $src_name));
         return ' 1=2 ';
     }
     $src_table = !empty($source_alias) ? $source_alias : $src->table;
     if ('group' == $src_name) {
         $otype_use_object_roles = true;
     } elseif (!empty($src->no_object_roles)) {
         $otype_use_object_roles = false;
     }
     // primary qualifying_roles array should contain only RS roles
     $qualifying_roles = $this->scoper->role_defs->filter($qualifying_roles, array('role_type' => 'rs'), 'names_as_key');
     if ($otype_use_object_roles) {
         // For object assignment, replace any "others" reqd_caps array.
         // Also exclude any roles which have never been assigned to any object
         if (!is_array($qualifying_object_roles)) {
             $qualifying_object_roles = $this->scoper->confirm_object_scope($qualifying_roles, $user);
         }
         if ($skip_objscope_check) {
             $objscope_objects = array();
         } else {
             $objscope_objects = $this->scoper->get_restrictions(OBJECT_SCOPE_RS, $src_name);
         }
         // this is buffered so redundant calling is not a concern
     }
     //---------------------------------------------------------------------------------
     //dump($qualifying_object_roles);
     //dump($objscope_objects);
     if ($otype_use_object_roles) {
         $user_qualifies_for_obj_roles = $user->ID || defined('SCOPER_ANON_METAGROUP');
     }
     $where = array();
     if ($terms_query) {
         $_taxonomies = $taxonomies;
     } elseif ($otype_use_term_roles && is_array($otype_use_term_roles)) {
         $_taxonomies = array_keys(array_intersect($otype_use_term_roles, array(1, '1', true)));
         // taxonomies arg is for limiting; default is to include all associated taxonomies in where clause
         if ($taxonomies) {
             $_taxonomies = array_intersect($_taxonomies, $taxonomies);
         }
     } else {
         $_taxonomies = array();
     }
     if ($_taxonomies && 'post' == $src_name) {
         $enabled_taxonomies = array_keys(array_intersect(scoper_get_option('use_taxonomies'), array(1, '1', true)));
         $_taxonomies = array_intersect($_taxonomies, $enabled_taxonomies);
     }
     $user_blog_roles = array('' => array());
     if ($use_blog_roles) {
         foreach (array_keys($user->blog_roles) as $date_key) {
             $user_blog_roles[$date_key] = array_intersect_key($user->blog_roles[$date_key], $qualifying_roles);
         }
         // Also include user's WP blogrole(s),
         // but via equivalent RS role(s) to support scoping requirements (strict (i.e. restricted) terms, objects)
         if ($wp_qualifying_roles = $this->scoper->role_defs->qualify_roles($reqd_caps, 'wp')) {
             if ($user_blog_roles_wp = array_intersect_key($user->blog_roles[ANY_CONTENT_DATE_RS], $wp_qualifying_roles)) {
                 // Credit user's qualifying WP blogrole via contained RS role(s)
                 // so we can also enforce "term restrictions", which are based on RS roles
                 $user_blog_roles_via_wp = $this->scoper->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[ANY_CONTENT_DATE_RS] = array_merge($user_blog_roles[ANY_CONTENT_DATE_RS], $user_blog_roles_via_wp);
             }
         }
     }
     /*
     // --- optional hack to require read_private cap via blog role AND object role
     // if the required capabilities include a read_private cap but no edit caps
     $require_blog_and_obj_role = ( in_array('read_private_posts', $reqd_caps) || in_array('read_private_pages', $reqd_caps) )   &&    ( ! array_diff( $reqd_caps, array('read_private_posts', 'read_private_pages', 'read') ) );
     // --- end hack ---
     */
     //dump($qualifying_roles);
     //dump($objscope_objects);
     foreach (array_keys($qualifying_roles) as $role_handle) {
         //dump($role_handle);
         if ($otype_use_object_roles && empty($require_blog_and_obj_role)) {
             if (!empty($objscope_objects['restrictions'][$role_handle])) {
                 $objscope_clause = " AND {$src_table}.{$src->cols->id} NOT IN ('" . implode("', '", array_keys($objscope_objects['restrictions'][$role_handle])) . "')";
             } elseif (isset($objscope_objects['unrestrictions'][$role_handle])) {
                 if (!empty($objscope_objects['unrestrictions'][$role_handle])) {
                     $objscope_clause = " AND {$src_table}.{$src->cols->id} IN ('" . implode("', '", array_keys($objscope_objects['unrestrictions'][$role_handle])) . "')";
                 } else {
                     $objscope_clause = " AND 1=2";
                 }
                 // role is default-restricted for this object type, but objects are unrestrictions are set
             } else {
                 $objscope_clause = '';
             }
         } else {
             $objscope_clause = '';
         }
         //dump($objscope_clause);
         $all_terms_qualified = array();
         $all_taxonomies_qualified = array();
         if ($_taxonomies) {
             $args['return_id_type'] = COL_TAXONOMY_ID_RS;
             $strict_taxonomies = array();
             foreach ($_taxonomies as $taxonomy) {
                 if ($this->scoper->taxonomies->member_property($taxonomy, 'requires_term')) {
                     $strict_taxonomies[$taxonomy] = true;
                 }
             }
             foreach ($_taxonomies as $taxonomy) {
                 // we only need a separate clause for each role if considering object roles (and therefore considering that some objects might require some roles to be object-assigned)
                 if (!$otype_use_object_roles) {
                     $role_handle_arg = $qualifying_roles;
                 } else {
                     $role_handle_arg = array($role_handle => 1);
                 }
                 // If a taxonomy does not require objects to have a term, its term role assignments
                 // will be purely supplemental; there is no basis for ignoring blogrole assignments.
                 //
                 // So if none of the taxonomies require each object to have a term
                 // AND the user has a qualifying role via blog assignment, we can skip the taxonomies clause altogether.
                 // Otherwise, will consider current user's termroles
                 if (!$strict_taxonomies) {
                     if (array_intersect_key($role_handle_arg, $user->blog_roles[ANY_CONTENT_DATE_RS])) {
                         // User has a qualifying role by blog assignment, so term_id clause is not required
                         $all_taxonomies_qualified[ANY_CONTENT_DATE_RS] = true;
                         break;
                     }
                 }
                 // qualify_terms returns:
                 // terms for which current user has a qualifying role
                 // 		- AND -
                 // which are non-restricted (i.e. blend in blog assignments) for a qualifying role which the user has blog-wide
                 //
                 // note: $reqd_caps function arg is used; qualify_terms will ignore reqd_caps element in args array
                 if ($user_terms = $this->scoper->qualify_terms_daterange($reqd_caps, $taxonomy, $role_handle_arg, $args)) {
                     if (!isset($term_count[$taxonomy])) {
                         $term_count[$taxonomy] = $this->scoper->get_terms($taxonomy, UNFILTERED_RS, COL_COUNT_RS);
                     }
                     foreach (array_keys($user_terms) as $date_key) {
                         if (count($user_terms[$date_key])) {
                             // don't bother applying term requirements if user has cap for all terms in this taxonomy
                             if (count($user_terms[$date_key]) >= $term_count[$taxonomy] && $this->scoper->taxonomies->member_property($taxonomy, 'requires_term')) {
                                 // User is qualified for all terms in this taxonomy; no need for any term_id clauses
                                 $all_terms_qualified[$date_key][$taxonomy] = true;
                             } else {
                                 $where[$date_key][$objscope_clause][TERM_SCOPE_RS][$taxonomy] = isset($where[$date_key][$objscope_clause][TERM_SCOPE_RS][$taxonomy]) ? array_unique(array_merge($where[$date_key][$objscope_clause][TERM_SCOPE_RS][$taxonomy], $user_terms[$date_key])) : $user_terms[$date_key];
                             }
                         }
                         $all_taxonomies_qualified[$date_key] = !empty($all_terms_qualified[$date_key]) && count($all_terms_qualified[$date_key]) == count($strict_taxonomies);
                     }
                 }
             }
             // end foreach taxonomy
         }
         foreach (array_keys($user_blog_roles) as $date_key) {
             if (!empty($all_taxonomies_qualified[$date_key]) || !$_taxonomies && !empty($user_blog_roles[$date_key][$role_handle])) {
                 if ($date_key || $objscope_clause || !empty($require_blog_and_obj_role)) {
                     $where[$date_key][$objscope_clause][BLOG_SCOPE_RS] = "1=1";
                 } else {
                     return "1=1";
                     // no need to include other clause if user has a qualifying role blog-wide or in all terms, it is not date-limited, and that role does not require object assignment for any objects
                 }
             }
         }
         // if object roles should be applied, populatate array key to force inclusion of OBJECT_SCOPE_RS query clauses below
         if ($otype_use_object_roles && isset($qualifying_object_roles[$role_handle]) && $user_qualifies_for_obj_roles) {
             // want to apply objscope requirements for anon user, but not apply any obj roles
             if ($role_spec = scoper_explode_role_handle($role_handle)) {
                 $where[ANY_CONTENT_DATE_RS][NO_OBJSCOPE_CLAUSE_RS][OBJECT_SCOPE_RS][$role_spec->role_type][$role_spec->role_name] = true;
             }
         }
         // we only need a separate clause for each role if considering object roles (and therefore considering that some objects might require some roles to be object-assigned)
         if (!$otype_use_object_roles && !empty($where[ANY_CONTENT_DATE_RS])) {
             break;
         }
     }
     // end foreach role
     // also include object scope clauses for any roles which qualify only for object-assignment
     if ($otype_use_object_roles && isset($qualifying_object_roles) && $user_qualifies_for_obj_roles) {
         // want to apply objscope requirements for anon user, but not apply any obj roles
         if ($obj_only_roles = array_diff_key($qualifying_object_roles, $qualifying_roles)) {
             foreach (array_keys($obj_only_roles) as $role_handle) {
                 if ($role_spec = scoper_explode_role_handle($role_handle)) {
                     $where[ANY_CONTENT_DATE_RS][NO_OBJSCOPE_CLAUSE_RS][OBJECT_SCOPE_RS][$role_spec->role_type][$role_spec->role_name] = true;
                 }
             }
         }
     }
     // DB query perf enhancement: if any terms are included regardless of post ID, don't also include those terms in ID-specific clause
     foreach (array_keys($where) as $date_key) {
         foreach (array_keys($where[$date_key]) as $objscope_clause) {
             if ($objscope_clause && isset($where[$date_key][$objscope_clause][TERM_SCOPE_RS])) {
                 foreach ($where[$date_key][$objscope_clause][TERM_SCOPE_RS] as $taxonomy => $terms) {
                     if (!empty($terms) && !empty($where[$date_key][NO_OBJSCOPE_CLAUSE_RS][TERM_SCOPE_RS][$taxonomy])) {
                         $where[$date_key][$objscope_clause][TERM_SCOPE_RS][$taxonomy] = array_diff($where[$date_key][$objscope_clause][TERM_SCOPE_RS][$taxonomy], $where[$date_key][NO_OBJSCOPE_CLAUSE_RS][TERM_SCOPE_RS][$taxonomy]);
                         if (empty($where[$date_key][$objscope_clause][TERM_SCOPE_RS][$taxonomy])) {
                             unset($where[$date_key][$objscope_clause][TERM_SCOPE_RS][$taxonomy]);
                             // if we removed a taxonomy array, don't leave behind a term scope array with no taxonomies
                             if (empty($where[$date_key][$objscope_clause][TERM_SCOPE_RS])) {
                                 unset($where[$date_key][$objscope_clause][TERM_SCOPE_RS]);
                                 // if we removed a term scope array, don't leave behind an objscope array with no scopes
                                 if (empty($where[$date_key][$objscope_clause])) {
                                     unset($where[$date_key][$objscope_clause]);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // since object roles are not pre-loaded prior to this call, role date limits are handled via subselect, within the date_key = '' iteration
     $object_roles_duration_clause = scoper_get_duration_clause();
     // implode the array of where criteria into a query as concisely as possible
     foreach ($where as $date_key => $objscope_clauses) {
         foreach ($objscope_clauses as $objscope_clause => $scope_criteria) {
             foreach (array_keys($scope_criteria) as $scope) {
                 switch ($scope) {
                     case BLOG_SCOPE_RS:
                         $where[$date_key][$objscope_clause][BLOG_SCOPE_RS] = $where[$date_key][$objscope_clause][BLOG_SCOPE_RS] . " {$objscope_clause}";
                         break;
                     case TERM_SCOPE_RS:
                         $taxonomy_clauses = array();
                         foreach ($scope_criteria[TERM_SCOPE_RS] as $taxonomy => $terms) {
                             $is_strict = !empty($strict_taxonomies[$taxonomy]);
                             if ($objscope_clause) {
                                 // Avoid " term_id IN (5) OR ( term_id IN (5) AND ID NOT IN (100) )
                                 // Otherwise this redundancy can occur when various qualifying roles require object role assignment for different objects
                                 if (!empty($where[$date_key][NO_OBJSCOPE_CLAUSE_RS][TERM_SCOPE_RS][$taxonomy])) {
                                     if (!($terms = array_diff($terms, $where[$date_key][NO_OBJSCOPE_CLAUSE_RS][TERM_SCOPE_RS][$taxonomy]))) {
                                         //unset($scope_criteria[TERM_SCOPE_RS][$taxonomy]);  // this doesn't affect anything (removed in v1.1)
                                         continue;
                                     }
                                 }
                             }
                             $terms = array_unique($terms);
                             if ($qvars = $this->scoper->taxonomies->get_terms_query_vars($taxonomy)) {
                                 if ($terms_query && !$otype_use_object_roles) {
                                     $qtv = $this->scoper->taxonomies->get_terms_query_vars($taxonomy, true);
                                     $taxonomy_clauses[false][] = "{$qtv->term->alias}.{$qtv->term->col_id} IN ('" . implode("', '", $terms) . "') {$objscope_clause}";
                                 } else {
                                     $this_tx_clause = "{$qvars->term->alias}.{$qvars->term->col_id} IN ('" . implode("', '", $terms) . "')";
                                     // Use a subselect rather than adding our own LEFT JOIN.
                                     $terms_subselect = "SELECT {$qvars->term->alias}.{$qvars->term->col_obj_id} FROM {$qvars->term->table} {$qvars->term->as} WHERE {$this_tx_clause}";
                                     if (defined('RVY_VERSION') && $objrole_revisions_clause) {
                                         $revision_clause = "OR ( {$src_table}.{$src->cols->type} = 'revision' AND {$src_table}.{$src->cols->parent} IN ( {$terms_subselect} ) )";
                                     } else {
                                         $revision_clause = '';
                                     }
                                     $taxonomy_clauses[$is_strict][] = "( {$src_table}.{$src->cols->id} IN ( {$terms_subselect} ) {$revision_clause} ) {$objscope_clause}";
                                 }
                             }
                         }
                         if ($taxonomy_clauses) {
                             // all taxonomy clauses concat: [taxonomy 1 clauses] [OR] [taxonomy 2 clauses] [OR] ...
                             //$where[$date_key][$objscope_clause][TERM_SCOPE_RS] = agp_implode(' ) OR ( ', $taxonomy_clauses, ' ( ', ' ) ');
                             // strict taxonomy clauses (if any are present, they must all be satisfied)
                             if (!empty($taxonomy_clauses[true])) {
                                 $where[$date_key][$objscope_clause][TERM_SCOPE_RS] = agp_implode(' ) AND ( ', $taxonomy_clauses[true], ' ( ', ' ) ');
                                 // non-strict taxonomy clauses
                             } elseif (!empty($taxonomy_clauses[false])) {
                                 $where[$date_key][$objscope_clause][TERM_SCOPE_RS] = agp_implode(' ) OR ( ', $taxonomy_clauses[false], ' ( ', ' ) ');
                             } else {
                                 $where[$date_key][$objscope_clause][TERM_SCOPE_RS] = '1=2';
                             }
                             // all taxonomy clauses concat: ( [strict taxonomy clause 1] [AND] [strict taxonomy clause 2]... ) [OR] [taxonomy 3 clauses] [OR] ...
                             //$where[$date_key][$objscope_clause][TERM_SCOPE_RS] = agp_implode(' ) OR ( ', $taxonomy_clauses, ' ( ', ' ) ');
                         }
                         break;
                     case OBJECT_SCOPE_RS:
                         // should only exist with nullstring objscope_clause
                         if ($user_qualifies_for_obj_roles) {
                             global $wpdb;
                             $u_g_clause = $user->get_user_clause('uro');
                             foreach (array_keys($scope_criteria[OBJECT_SCOPE_RS]) as $role_type) {
                                 //should be only one
                                 if ($scope_criteria[OBJECT_SCOPE_RS][$role_type]) {
                                     ksort($scope_criteria[OBJECT_SCOPE_RS][$role_type]);
                                 }
                                 // sort array for efficient membuffering of query results
                                 // Combine all qualifying (and applied) object roles into a single OR clause
                                 $role_in = "'" . implode("', '", array_keys($scope_criteria[OBJECT_SCOPE_RS][$role_type])) . "'";
                                 static $cache_obj_ids = array();
                                 if ('post.php' == $GLOBALS['pagenow'] && !empty($_REQUEST['action']) || did_action('save_post') || !empty($_GET['doaction'])) {
                                     $force_refresh = true;
                                 }
                                 $objrole_subselect = "SELECT DISTINCT uro.obj_or_term_id FROM {$wpdb->user2role2object_rs} AS uro WHERE uro.role_type = '{$role_spec->role_type}' AND uro.scope = 'object' AND uro.assign_for IN ('entity', 'both') AND uro.role_name IN ({$role_in}) AND uro.src_or_tx_name = '{$src_name}' {$object_roles_duration_clause} {$u_g_clause} ";
                                 if (!isset($cache_obj_ids[$objrole_subselect]) || !empty($force_refresh)) {
                                     $cache_obj_ids[$objrole_subselect] = scoper_get_col($objrole_subselect);
                                 }
                                 if ($cache_obj_ids[$objrole_subselect]) {
                                     $where[$date_key][$objscope_clause][OBJECT_SCOPE_RS] = "{$src_table}.{$src->cols->id} IN ( '" . implode("','", $cache_obj_ids[$objrole_subselect]) . "' )";
                                 } else {
                                     $where[$date_key][$objscope_clause][OBJECT_SCOPE_RS] = "1=2";
                                 }
                                 if (defined('RVY_VERSION') && $objrole_revisions_clause) {
                                     $where[$date_key][$objscope_clause][OBJECT_SCOPE_RS] = "( {$where[$date_key][$objscope_clause]['object']} OR ( {$src_table}.{$src->cols->type} = 'revision' AND {$src_table}.{$src->cols->parent} IN ( '" . implode("','", $cache_obj_ids[$objrole_subselect]) . "' ) ) )";
                                 }
                             }
                         }
                         break;
                 }
                 // end scope switch
             }
             // end foreach scope
             /*
             // --- optional hack to require read_private cap via blog role AND object role
             if ( ! empty($require_blog_and_obj_role) ) {
             	if ( ! isset($where[$date_key][''][BLOG_SCOPE_RS]) )
             		$where[$date_key][''][BLOG_SCOPE_RS] = '1=2';
             	
             	if ( ! isset($where[$date_key][''][TERM_SCOPE_RS]) )
             		$where[$date_key][''][TERM_SCOPE_RS] = '1=2';
             		
             	if ( ! isset($where[$date_key][''][OBJECT_SCOPE_RS]) )
             		$where[$date_key][''][OBJECT_SCOPE_RS] = '1=2';
             	
             	$where[$date_key][''] = "( ( {$where[$date_key]['']['blog']} ) OR ( {$where[$date_key]['']['term']} ) ) AND ( {$where[$date_key]['']['object']} )";
             } 
             else
             // --- end hack
             */
             // all scope clauses concat: [object roles] OR [term ids] OR [blogrole1 clause] [OR] [blogrole2 clause] [OR] ...
             // Collapse the array to a string even if it's empty
             $where[$date_key][$objscope_clause] = agp_implode(' ) OR ( ', $where[$date_key][$objscope_clause], ' ( ', ' ) ');
         }
         // end foreach objscope clause
         $date_clause = '';
         if ($date_key && is_serialized($date_key)) {
             $content_date_limits = unserialize($date_key);
             if ($content_date_limits->content_min_date_gmt) {
                 $date_clause .= " AND {$src_table}.{$src->cols->date} >= '" . $content_date_limits->content_min_date_gmt . "'";
             }
             if ($content_date_limits->content_max_date_gmt) {
                 $date_clause .= " AND {$src_table}.{$src->cols->date} <= '" . $content_date_limits->content_max_date_gmt . "'";
             }
         }
         foreach (array_keys($where[$date_key]) as $objscope_clause) {
             if (empty($where[$date_key][$objscope_clause])) {
                 unset($where[$date_key][$objscope_clause]);
             }
         }
         // all objscope clauses concat: [clauses w/o objscope] [OR] [objscope 1 clauses] [OR] [objscope 2 clauses]
         $where[$date_key] = agp_implode(' ) OR ( ', $where[$date_key], ' ( ', ' ) ');
         if ($date_clause && $where[$date_key]) {
             $where[$date_key] = "( {$where[$date_key]}{$date_clause} )";
         }
     }
     // end foreach datekey (set of content date limits for which role(s) apply)
     foreach (array_keys($where) as $date_key) {
         if (empty($where[$date_key])) {
             unset($where[$date_key]);
         }
     }
     // all date clauses concat: [clauses w/o content date limits] [OR] [content date range 1 clauses] [OR] [content date range 2 clauses]
     $where = agp_implode(' ) OR ( ', $where, ' ( ', ' ) ');
     if (empty($where)) {
         $where = '1=2';
     }
     return $where;
 }
 function determine_role_usage_rs($src_name = 'post', $listed_ids = '')
 {
     global $scoper, $wpdb;
     if ('post' != $src_name) {
         return;
     }
     if (empty($listed_ids)) {
         if (!empty($scoper->listed_ids[$src_name])) {
             $listed_ids = $scoper->listed_ids[$src_name];
         } else {
             return;
         }
     }
     if (empty($this->checked_ids[$src_name])) {
         $this->checked_ids[$src_name] = array();
     } else {
         if (!array_diff_key($this->checked_ids[$src_name], $listed_ids)) {
             return;
         }
     }
     $this->checked_ids[$src_name] = $this->checked_ids[$src_name] + $listed_ids;
     $src = $scoper->data_sources->get($src_name);
     $col_id = $src->cols->id;
     $col_type = isset($src->cols->type) ? $src->cols->type : '';
     if ($viewing_object_type = cr_find_post_type()) {
         $object_types = (array) $viewing_object_type;
     } else {
         $object_types = array_diff_key(get_post_types(array('public' => true)), array('attachment'));
     }
     // For now, only determine restricted posts if using RS role type.
     // Backing this out will be more convoluted for WP role type; may need to just list which roles are restricted rather than trying to give an Restricted Read/Edit summary
     $roles = array();
     if (is_admin()) {
         foreach ($object_types as $_post_type) {
             $roles["edit"][$_post_type] = array("publish" => "rs_{$_post_type}_editor", "private" => "rs_{$_post_type}_editor", "draft" => "rs_{$_post_type}_contributor", "pending" => "rs_{$_post_type}_contributor", "future" => "rs_{$_post_type}_editor", "trash" => "rs_{$_post_type}_editor");
             $roles["read"][$_post_type] = array("publish" => "rs_{$_post_type}_reader", "private" => "rs_private_{$_post_type}_reader", "draft" => "rs_{$_post_type}_reader", "pending" => "rs_{$_post_type}_reader", "future" => "rs_{$_post_type}_reader", "trash" => "rs_{$_post_type}_editor");
         }
     } else {
         foreach ($object_types as $_post_type) {
             $roles["read"][$_post_type] = array("publish" => "rs_{$_post_type}_reader", "private" => "rs_private_{$_post_type}_reader");
         }
     }
     // which of these results ignore blog role assignments?
     $uses_taxonomies = scoper_get_taxonomy_usage($src_name, $object_types);
     if (!empty($uses_taxonomies)) {
         foreach ($uses_taxonomies as $taxonomy) {
             $tx_object_types = $object_types;
             foreach ($tx_object_types as $key => $object_type) {
                 // ignore term restrictions / roles for object types which have them disabled
                 $_use_term_roles = scoper_get_otype_option('use_term_roles', $src_name, $object_type);
                 if (empty($_use_term_roles[$taxonomy])) {
                     unset($tx_object_types[$key]);
                 }
             }
             if (!$tx_object_types) {
                 continue;
             }
             if (!$scoper->taxonomies->is_member($taxonomy)) {
                 continue;
             }
             $qvars = $scoper->taxonomies->get_terms_query_vars($taxonomy);
             $term_join = " INNER JOIN {$qvars->term->table} {$qvars->term->as} ON {$src->table}.{$src->cols->id} = {$qvars->term->alias}.{$qvars->term->col_obj_id} ";
             // ======== Log term restrictions ========
             //
             if ($scoper->taxonomies->member_property($taxonomy, 'requires_term')) {
                 if ($strict_terms = $scoper->get_restrictions(TERM_SCOPE_RS, $taxonomy)) {
                     $this->any_restricted_terms = true;
                 }
                 $all_terms = $scoper->get_terms($taxonomy, UNFILTERED_RS, COL_ID_RS);
                 foreach (array_keys($roles) as $op_type) {
                     $status_where = array();
                     foreach ($tx_object_types as $object_type) {
                         $term_clauses = array();
                         foreach ($roles[$op_type][$object_type] as $status => $check_role) {
                             if (isset($strict_terms['restrictions'][$check_role]) && is_array($strict_terms['restrictions'][$check_role])) {
                                 $this_strict_terms = array_keys($strict_terms['restrictions'][$check_role]);
                             } elseif (isset($strict_terms['unrestrictions'][$check_role]) && is_array($strict_terms['unrestrictions'][$check_role])) {
                                 $this_strict_terms = array_diff($all_terms, array_keys($strict_terms['unrestrictions'][$check_role]));
                             } else {
                                 $this_strict_terms = array();
                             }
                             if (!$this_strict_terms) {
                                 // no terms in this taxonomy have restricted roles
                                 $term_clauses[$status] = '1=2';
                             } elseif (count($this_strict_terms) < count($all_terms)) {
                                 // some (but not all) terms in this taxonomy honor blog-wide assignment of the pertinent role
                                 $term_clauses[$status] = " {$qvars->term->alias}.{$qvars->term->col_id} IN ('" . implode("', '", $this_strict_terms) . "')";
                             } else {
                                 $term_clauses[$status] = '1=1';
                             }
                             if (isset($term_clauses[$status])) {
                                 $status_where[$object_type][$status] = " {$src->cols->status} = '{$status}' AND ( {$term_clauses[$status]} ) ";
                             }
                         }
                         // end foreach statuses
                         if (isset($status_where[$object_type])) {
                             // object_type='type_val' AND ( (status 1 clause) OR (status 2 clause) ...
                             $status_where[$object_type] = " {$src->cols->type} = '{$object_type}' AND ( " . agp_implode(' ) OR ( ', $status_where[$object_type], ' ( ', ' ) ') . " )";
                         }
                     }
                     // end foreach tx_object_types
                     // NOTE: we are querying for posts/pages which HAVE restrictions that apply to their current post_status
                     //
                     if ($status_where) {
                         // (object type 1 clause) OR (object type 2 clause) ...
                         $where = ' AND (' . agp_implode(' ) OR ( ', $status_where, ' ( ', ' ) ') . ' )';
                         $where .= " AND {$src->table}.{$col_id} IN ('" . implode("', '", array_keys($listed_ids)) . "')";
                         $query = "SELECT DISTINCT {$col_id} FROM {$src->table} {$term_join} WHERE 1=1 {$where}";
                         if (isset($query_results[$query])) {
                             $restricted_ids = $query_results[$query];
                         } else {
                             $restricted_ids = scoper_get_col($query);
                             $query_results[$query] = $restricted_ids;
                         }
                         foreach ($restricted_ids as $id) {
                             $this->termscoped_ids[$src_name][$id][$op_type] = true;
                             $this->restricted_ids[$src_name][$id][$op_type] = true;
                         }
                     }
                 }
                 // end foreach op_type (read/edit)
             }
             // end term restrictions logging
             // ======== Log term roles ========
             //
             if (is_admin() && !empty($qvars)) {
                 if ($src_roles = $scoper->role_defs->get_matching('rs', 'post', $tx_object_types)) {
                     $otype_role_names = array();
                     foreach (array_keys($src_roles) as $role_handle) {
                         $otype_role_names[] = $src_roles[$role_handle]->name;
                     }
                     $role_clause = "AND uro.role_name IN ('" . implode("', '", $otype_role_names) . "')";
                     $join_assigned = $term_join . " INNER JOIN {$wpdb->user2role2object_rs} AS uro ON uro.obj_or_term_id = {$qvars->term->alias}.{$qvars->term->col_id}" . " AND uro.scope = 'term' AND uro.role_type = 'rs' {$role_clause} AND uro.src_or_tx_name = '{$taxonomy}'";
                     $where = " AND {$src->table}.{$col_id} IN ('" . implode("', '", array_keys($listed_ids)) . "')";
                     $query = "SELECT DISTINCT {$col_id}, uro.role_name FROM {$src->table} {$join_assigned} WHERE 1=1 {$where}";
                     $role_results = scoper_get_results($query);
                     foreach ($role_results as $row) {
                         $role_handle = scoper_get_role_handle($row->role_name, 'rs');
                         $this->have_termrole_ids[$src_name][$row->{$col_id}][$role_handle] = true;
                     }
                 }
             }
             // end term roles logging
         }
         // end foreach of this data source's taxonomies
     }
     // endif this data source uses taxonomies
     // which of these results ignore blog AND term role assignments?
     if ($objscope_objects = $scoper->get_restrictions(OBJECT_SCOPE_RS, $src_name)) {
         $this->any_restricted_objects = true;
     }
     foreach (array_keys($roles) as $op_type) {
         foreach ($object_types as $object_type) {
             if (!scoper_get_otype_option('use_object_roles', $src_name, $object_type)) {
                 continue;
             }
             if (is_array($roles[$op_type][$object_type])) {
                 foreach (array_keys($listed_ids) as $id) {
                     foreach ($roles[$op_type][$object_type] as $check_role) {
                         // If a restriction is set for this object and role,
                         // OR if the role is default-restricted with no unrestriction for this object...
                         if (isset($objscope_objects['restrictions'][$check_role][$id]) || isset($objscope_objects['unrestrictions'][$check_role]) && is_array($objscope_objects['unrestrictions'][$check_role]) && !isset($objscope_objects['unrestrictions'][$check_role][$id])) {
                             $this->objscoped_ids[$src_name][$id][$op_type] = true;
                             $this->restricted_ids[$src_name][$id][$op_type] = true;
                         }
                     }
                 }
                 //end foreach listed ids
             }
             // endif any applicable roles defined
         }
         // end forach object type
     }
     // end foreach op_type (read/edit)
     // query for object role assignments
     if (is_admin()) {
         if ($scoper->get_applied_object_roles()) {
             //$this->any_object_roles = true;
             $join_assigned = " INNER JOIN {$wpdb->user2role2object_rs} AS uro ON uro.obj_or_term_id = {$src->table}.{$col_id}" . " AND uro.src_or_tx_name = '{$src_name}' AND uro.scope = 'object' AND uro.role_type = 'rs'";
             $where = " AND {$src->table}.{$col_id} IN ('" . implode("', '", array_keys($listed_ids)) . "')";
             $query = "SELECT DISTINCT {$col_id}, uro.role_name FROM {$src->table} {$join_assigned} WHERE 1=1 {$where}";
             $role_results = scoper_get_results($query);
             foreach ($role_results as $row) {
                 $role_handle = scoper_get_role_handle($row->role_name, 'rs');
                 $this->have_objrole_ids[$src_name][$row->{$col_id}][$role_handle] = true;
                 //$this->any_object_roles = true;
             }
         }
     }
 }