Example #1
0
 function &add($name, $defining_module, $display_name = '', $abbrev = '', $role_type = 'rs', $args = array())
 {
     if ($this->locked) {
         $notice = sprintf('A plugin or theme (%1$s) is too late in its attempt to define a role (%2$s).', $defining_module, $name) . '<br /><br />' . 'This must be done via the define_roles_rs hook.';
         rs_notice($notice);
         return;
     }
     $key = $name == ANON_ROLEHANDLE_RS ? $name : scoper_get_role_handle($name, $role_type);
     if ('wp' == $role_type) {
         if (!$display_name) {
             $display_name = ucwords(str_replace('_', ' ', $name));
         }
         if (!$abbrev) {
             $abbrev = $display_name;
         }
     }
     if ($display_name) {
         $this->display_names[$key] = $display_name;
     }
     if ($abbrev) {
         $this->abbrevs[$key] = $abbrev;
     }
     if (isset($this->members[$key])) {
         unset($this->members[$key]);
     }
     $this->members[$key] = new CR_Role($name, $defining_module, $role_type, $args);
     $this->process($this->members[$key]);
     return $this->members[$key];
 }
 function add_member_objects($arr)
 {
     if (!is_array($arr)) {
         return;
     }
     if (!empty($this->locked)) {
         rs_notice('Config items cannot not be added at this time.  Maybe the calling function must be registered to a hook.  Consult developer documentation.');
         return;
     }
     $this->members = array_merge($this->members, $arr);
     $this->process_added_members($arr);
 }
 function get_terms_query_vars($tx, $terms_only = false)
 {
     global $scoper;
     // query on custom taxonomy schema does not involve any object data, so refer to term_id in term table
     if ($terms_only) {
         $tx_src = $scoper->data_sources->get($tx->source);
         $tmp = array();
         $tmp['table'] = $tx_src->table;
         $tmp['alias'] = $tx_src->table_alias ? $tx_src->table_alias : $tmp['table'];
         $tmp['as'] = $tx_src->table_alias && $tx_src->table_alias != $tx_src->table ? "AS {$tmp['alias']}" : '';
         $tmp['col_id'] = $tx_src->cols->id;
         $arr['term'] = (object) $tmp;
         // this corresponds to 'category_id' in wp_post2cat (WP < 2.3), or some equivalent custom table
     } elseif (!empty($tx->cols->term2obj_tid)) {
         $tmp = array();
         $tmp['table'] = $tx->table_term2obj;
         $tmp['alias'] = $tx->table_term2obj_alias ? $tx->table_term2obj_alias : $tmp['table'];
         $tmp['as'] = $tmp['alias'] && $tmp['alias'] != $tmp['table'] ? "AS {$tmp['alias']}" : '';
         $tmp['col_id'] = $tx->cols->term2obj_tid;
         $tmp['col_obj_id'] = $tx->cols->term2obj_oid;
         $arr['term'] = (object) $tmp;
         $obj_src = $scoper->data_sources->get($tx->object_source);
         $tmp = array();
         $tmp['table'] = $obj_src->table;
         $tmp['alias'] = $obj_src->table_alias ? $obj_src->table_alias : $tmp['table'];
         $tmp['as'] = $tmp['alias'] && $tmp['alias'] != $tmp['table'] ? "AS {$tmp['alias']}" : '';
         $tmp['col_id'] = $obj_src->cols->id;
         $arr['obj'] = (object) $tmp;
         // also support custom taxonomies which store a single term_id right in object table
     } elseif (!empty($tx->cols->objtable_tid)) {
         global $scoper;
         $obj_src = $scoper->data_sources->get($tx->object_source);
         $tmp = array();
         $tmp['table'] = $obj_src->table;
         $tmp['alias'] = $obj_src->table_alias ? $obj_src->table_alias : $tmp['table'];
         $tmp['as'] = $tmp['alias'] && $tmp['alias'] != $tmp['table'] ? "AS {$tmp['alias']}" : '';
         $tmp['col_id'] = $tx->cols->objtable_tid;
         $tmp['col_obj_id'] = $obj_src->cols->id;
         $arr['term'] = (object) $tmp;
         $tmp = array();
         $tmp['table'] = $tmp['table'];
         $tmp['alias'] = $tmp['alias'];
         $tmp['as'] = $tmp['as'];
         $tmp['col_id'] = $tmp['col_obj_id'];
         $arr['obj'] = (object) $tmp;
     } else {
         rs_notice(sprintf('Role Scoper Config Error: the specified taxonomy (%s) has not defined its relation to the object data source.  A col_term2obj_tid or col_objtable_tid setting is required.', $tx->name));
         return;
     }
     return (object) $arr;
 }
 function &add($name, $defining_module, $label_singular, $label_name, $uses_standard_schema = true, $default_strict = true, $args = array())
 {
     if ($this->locked) {
         $notice = sprintf('A plugin or theme (%1$s) is too late in its attempt to define a taxonomy (%2$s).', $defining_module, $name) . '<br /><br />' . 'This must be done via the define_taxonomies_rs hook.';
         rs_notice($notice);
         return;
     }
     if (isset($this->members[$name])) {
         unset($this->members[$name]);
     }
     $this->members[$name] = new CR_Taxonomy($name, $defining_module, $label_singular, $label_name, $uses_standard_schema, $default_strict, $args);
     $this->process($this->members[$name]);
     return $this->members[$name];
 }
 function &add($name, $defining_module, $src_name, $object_type, $op_type, $args = array())
 {
     if ($this->locked) {
         $notice = sprintf('A plugin or theme (%1$s) is too late in its attempt to define a capability (%2$s).', $defining_module, $name) . '<br /><br />' . 'This must be done via the define_capabilities_rs hook.';
         rs_notice($notice);
         return;
     }
     if (isset($this->members[$name])) {
         unset($this->members[$name]);
     }
     $this->members[$name] = new CR_Capability($name, $defining_module, $src_name, $object_type, $op_type, $args);
     $this->process($this->members[$name]);
     return $this->members[$name];
 }
 function &add($name, $defining_module, $label_singular, $label_name, $table_basename, $col_id, $col_name, $args)
 {
     if ($this->locked) {
         $notice = sprintf('A plugin or theme (%1$s) is too late in its attempt to define a data source (%2$s).', $defining_module, $name) . '<br /><br />' . 'This must be done via the define_data_sources_rs hook.';
         rs_notice($notice);
         return;
     }
     if (isset($this->members[$name])) {
         unset($this->members[$name]);
     }
     $this->members[$name] = new CR_Data_Source($name, $defining_module, $label_singular, $label_name, $table_basename, $col_id, $col_name, $args);
     $this->process($this->members[$name]);
     return $this->members[$name];
 }
define('OP_EDIT_RS', 'edit');
define('OP_PUBLISH_RS', 'publish');
define('OP_DELETE_RS', 'delete');
define('OP_ADMIN_RS', 'admin');
define('OP_ASSIGN_RS', 'assign');
define('ROLE_BASIS_GROUPS', 'groups');
define('ROLE_BASIS_USER', 'user');
define('ROLE_BASIS_USER_AND_GROUPS', 'ug');
define('ANY_CONTENT_DATE_RS', '');
define('NO_OBJSCOPE_CLAUSE_RS', '');
global $scoper_role_types;
$scoper_role_types = array('rs', 'wp', 'wp_cap');
global $wpdb;
$bail = 0;
if (!awp_ver('3.0')) {
    rs_notice('Sorry, this version of Role Scoper requires WordPress 3.0 or higher.  Please upgrade Wordpress or deactivate Role Scoper.  If you must run WP 2.7 - 2.9.2, try <a href="http://agapetry.net/downloads/role-scoper_legacy">Role Scoper 1.2.x</a>.');
    $bail = 1;
}
if (is_admin() || defined('XMLRPC_REQUEST')) {
    // Early bailout for problematic 3rd party plugin ajax calls
    if (strpos($_SERVER['SCRIPT_NAME'], 'wp-wall-ajax.php')) {
        return;
    }
} elseif (!$bail) {
    require_once dirname(__FILE__) . '/feed-interceptor_rs.php';
    // must define get_currentuserinfo early
}
//log_mem_usage_rs( 'initial requires' );
if (!$bail) {
    require_once dirname(__FILE__) . '/defaults_rs.php';
    //log_mem_usage_rs( 'defaults_rs' );
 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;
 }