function ec_getDaysEvents($query)
 {
     if (strpos($query, 'eventscalendar_main')) {
         static $busy;
         // IMPORTANT: don't execute recursively on db calls below
         if (empty($busy)) {
             $busy = true;
             global $wpdb;
             static $post_id_in;
             // local buffer of readable post IDs which are related to any event
             if (!isset($post_id_in)) {
                 $qry = "SELECT postID FROM {$wpdb->prefix}eventscalendar_main";
                 $event_ids = scoper_get_col($qry);
                 $event_id_in = "'" . implode("','", $event_ids) . "'";
                 // now generate and execute a scoped query for readable/unpublished posts
                 $post_qry = "SELECT ID FROM {$wpdb->posts} WHERE 1=1 AND {$wpdb->posts}.ID IN ({$event_id_in})";
                 // custom arguments to force inclusion of unpublished posts (only relationship to an unreadable published/private posts can make an event unreadable)
                 $reqd_caps = array();
                 $reqd_caps['post'] = array('publish' => array('read'), 'private' => array('read_private_posts'), 'draft' => array('read'), 'pending' => array('read'), 'future' => array('read'));
                 $post_qry = apply_filters('objects_request_rs', $post_qry, 'post', 'post', array('skip_teaser' => true, 'force_reqd_caps' => $reqd_caps));
                 $post_ids = scoper_get_col($post_qry);
                 $post_id_in = "'" . implode("','", $post_ids) . "'";
             }
             $id_clause = "( `postID` IS NULL OR `postID` IN ( {$post_id_in} ) ) AND";
             $table_name = $wpdb->prefix . 'eventscalendar_main';
             $query = str_replace("SELECT * FROM `{$table_name}` WHERE ", "SELECT * FROM `{$table_name}` WHERE {$id_clause} ", $query);
             $busy = false;
         }
     }
     return $query;
 }
function scoper_requested_file_rule_expire()
{
    if (scoper_get_option('file_filtering')) {
        if ($key = scoper_get_option('file_filtering_regen_key')) {
            if (!empty($_GET['key']) && $key == $_GET['key']) {
                // user must store their own non-null key before this will work
                global $wpdb;
                if (IS_MU_RS) {
                    $blog_ids = scoper_get_col("SELECT blog_id FROM {$wpdb->blogs} ORDER BY blog_id");
                    $orig_blog_id = $GLOBALS['blog_id'];
                    foreach ($blog_ids as $id) {
                        switch_to_blog($id);
                        scoper_query("DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_rs_file_key'");
                    }
                } else {
                    scoper_query("DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_rs_file_key'");
                }
                scoper_expire_file_rules();
                if (IS_MU_RS) {
                    _e("File attachment access keys and rewrite rules will be regenerated for each site at next access.", 'scoper');
                } else {
                    _e("File attachment access keys and rewrite rules were regenerated.", 'scoper');
                }
            } else {
                _e('Invalid argument.', 'scoper');
            }
        } else {
            _e('Please configure File Filtering options!', 'scoper');
        }
    } else {
        _e('The function is disabled.', 'scoper');
    }
    exit(0);
}
function rs_get_post_revisions($post_id, $status = 'inherit', $args = array())
{
    global $wpdb;
    $defaults = array('order' => 'DESC', 'orderby' => 'post_modified_gmt', 'use_memcache' => true, 'fields' => COLS_ALL_RS, 'return_flipped' => false, 'where' => '');
    $args = wp_parse_args($args, $defaults);
    extract($args);
    if (COL_ID_RS == $fields) {
        // performance opt for repeated calls by user_has_cap filter
        if ($use_memcache) {
            static $last_results;
            if (!isset($last_results)) {
                $last_results = array();
            } elseif (isset($last_results[$post_id][$status])) {
                return $last_results[$post_id][$status];
            }
        }
        $revisions = scoper_get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent = '{$post_id}' AND post_status = '{$status}' {$where}");
        if ($return_flipped) {
            $revisions = array_fill_keys($revisions, true);
        }
        if ($use_memcache) {
            if (!isset($last_results[$post_id])) {
                $last_results[$post_id] = array();
            }
            $last_results[$post_id][$status] = $revisions;
        }
    } else {
        $order_clause = $order && $orderby ? "ORDER BY {$orderby} {$order}" : '';
        $revisions = scoper_get_results("SELECT * FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent = '{$post_id}' AND post_status = '{$status}' {$order_clause}");
    }
    return $revisions;
}
 function log_object_save($src_name, $object_id, $is_new_object, $col_parent, $set_parent)
 {
     global $wpdb;
     $is_new_object = true;
     $qry = "SELECT assignment_id FROM {$wpdb->user2role2object_rs} WHERE scope = 'object' AND src_or_tx_name = '{$src_name}' AND obj_or_term_id = '{$object_id}'";
     if ($assignment_ids = scoper_get_col($qry)) {
         $is_new_object = false;
     } else {
         $qry = "SELECT requirement_id FROM {$wpdb->role_scope_rs} WHERE topic = 'object' AND src_or_tx_name = '{$src_name}' AND obj_or_term_id = '{$object_id}'";
         if ($requirement_ids = scoper_get_col($qry)) {
             $is_new_object = false;
         }
     }
     if ($col_parent) {
         if (!$is_new_object) {
             $last_parents = get_option("scoper_last_parents_{$src_name}");
             if (!is_array($last_parents)) {
                 $last_parents = array();
             }
             if (isset($last_parents[$object_id])) {
                 $last_parent = $last_parents[$object_id];
             }
         }
         if (isset($set_parent) && $set_parent != $last_parent && ($set_parent || $last_parent)) {
             $last_parents[$object_id] = $set_parent;
             update_option("scoper_last_parents_{$src_name}", $last_parents);
         }
     }
     return $is_new_object;
 }
 function flt_sticky_posts($post_ids)
 {
     if ($post_ids && !is_content_administrator_rs()) {
         global $wpdb;
         $post_ids = scoper_get_col(apply_filters('objects_request_rs', "SELECT ID FROM {$wpdb->posts} WHERE ID IN ('" . implode("','", $post_ids) . "')", 'post'));
     }
     return $post_ids;
 }
 function get_groups_for_user($user_id, $args = array())
 {
     return array();
     if (empty($args['no_cache'])) {
         // use -1 here to ignore accidental storage of other groups for zero user_id
         $cache = wpp_cache_get(-1, 'group_membership_for_user');
         if (is_array($cache)) {
             return $cache;
         }
     }
     global $wpdb;
     if (empty($wpdb->groups_rs)) {
         return array();
     }
     // include WP metagroup for anonymous user
     $user_groups = scoper_get_col("SELECT {$wpdb->groups_id_col} FROM {$wpdb->groups_rs} WHERE {$wpdb->groups_rs}.{$wpdb->groups_meta_id_col} = 'wp_anon'");
     if ($user_groups && empty($args['no_cache'])) {
         // users should always be in at least a metagroup.  Problem with caching empty result on user creation beginning with WP 2.8
         $user_groups = array_fill_keys($user_groups, 1);
         wpp_cache_set(-1, $user_groups, 'group_membership_for_user');
     }
     return $user_groups;
 }
Exemplo n.º 7
0
 function filter_objects_listing($mode, &$role_settings, $src, $object_type)
 {
     global $wpdb;
     $filter_args = array();
     // only list role assignments which the logged-in user can administer
     $filter_args['required_operation'] = OP_EDIT_RS;
     // Possible TODO: re-implement OP_ADMIN distinction with admin-specific capabilities
     /* global $scoper;
     	
     	if ( cr_get_reqd_caps( $src->name, OP_ADMIN_RS, $object_type ) ) {
     		$filter_args['required_operation'] = OP_ADMIN_RS;
     	} else {
     		$reqd_caps = array();
     		foreach (array_keys($src->statuses) as $status_name) {
     			$admin_caps = $scoper->cap_defs->get_matching($src->name, $object_type, OP_ADMIN_RS, $status_name);
     			$delete_caps = $scoper->cap_defs->get_matching($src->name, $object_type, OP_DELETE_RS, $status_name);
     			$reqd_caps[$object_type][$status_name] = array_merge(array_keys($admin_caps), array_keys($delete_caps));
     		}
     		$filter_args['force_reqd_caps'] = $reqd_caps;
     	}
     	*/
     $qry = "SELECT {$src->table}.{$src->cols->id} FROM {$src->table} WHERE 1=1 AND {$src->cols->type} = '{$object_type}'";
     //$filter_args['require_full_object_role'] = true;
     $qry_flt = apply_filters('objects_request_rs', $qry, $src->name, $object_type, $filter_args);
     if ($cu_admin_results = scoper_get_col($qry_flt)) {
         $cu_admin_results = array_fill_keys($cu_admin_results, true);
     }
     if (ROLE_ASSIGNMENT_RS == $mode) {
         foreach (array_keys($role_settings) as $role_basis) {
             foreach (array_keys($role_settings[$role_basis]) as $obj_id) {
                 if (!isset($cu_admin_results[$obj_id])) {
                     unset($role_settings[$role_basis][$obj_id]);
                 }
             }
         }
     } else {
         $setting_types = array('restrictions', 'unrestrictions');
         foreach ($setting_types as $setting_type) {
             if (isset($role_settings[$setting_type])) {
                 foreach (array_keys($role_settings[$setting_type]) as $role_handle) {
                     foreach (array_keys($role_settings[$setting_type][$role_handle]) as $obj_id) {
                         if (!isset($cu_admin_results[$obj_id])) {
                             unset($role_settings[$setting_type][$role_handle][$obj_id]);
                         }
                     }
                 }
             }
         }
     }
     return $cu_admin_results;
 }
 function groups_who_can($reqd_caps, $cols = COLS_ALL_RS, $object_src_name = '', $object_id = 0, $args = array())
 {
     global $wpdb;
     $defaults = array('orderby' => '', 'disable_memcache' => false, 'force_refresh' => false);
     $args = array_merge($defaults, (array) $args);
     extract($args);
     $cache_flag = "rs_groups_who_can";
     $cache_id = md5(serialize($reqd_caps) . $cols . 'src' . $object_src_name . 'id' . $object_id . serialize($args));
     if (!$force_refresh) {
         $groups = wpp_cache_get($cache_id, $cache_flag);
         if (is_array($groups)) {
             return $groups;
         }
     }
     if (!is_array($reqd_caps)) {
         $reqd_caps = $reqd_caps ? array($reqd_caps) : array();
     }
     if (!$orderby && (COLS_ALL_RS == $cols || COLS_ID_DISPLAYNAME_RS == $cols)) {
         $orderby = " ORDER BY display_name";
     }
     if (!is_array($args)) {
         $args = array();
     }
     if (isset($args['ignore_group_roles'])) {
         unset($args['ignore_group_roles']);
     }
     $args['ignore_user_roles'] = 1;
     $args['querying_groups'] = 1;
     $where = $this->flt_users_where('', $reqd_caps, $object_src_name, $object_id, $args);
     if (COL_ID_RS == $cols) {
         $qry = "SELECT DISTINCT group_id as ID FROM {$wpdb->user2role2object_rs} AS gro WHERE 1=1 {$where} AND gro.group_id > 0 {$orderby}";
         $groups = scoper_get_col($qry);
     } else {
         $grp = $wpdb->groups_rs;
         $qry = "SELECT DISTINCT {$grp}.{$wpdb->groups_id_col} AS ID, {$grp}.{$wpdb->groups_name_col} AS display_name, {$grp}.{$wpdb->groups_descript_col} as descript FROM {$grp}" . " INNER JOIN {$wpdb->user2group_rs} as u2g ON u2g.{$wpdb->user2group_gid_col} = {$grp}.{$wpdb->groups_id_col}" . " INNER JOIN {$wpdb->user2role2object_rs} AS gro ON {$grp}.{$wpdb->groups_id_col} = gro.group_id WHERE 1=1 {$where} {$orderby}";
         $groups = scoper_get_results($qry);
     }
     wpp_cache_set($cache_id, $groups, $cache_flag);
     return $groups;
 }
function scoper_limit_subscribe2_autosub($query)
{
    global $wpdb;
    if ("SELECT DISTINCT user_id FROM {$wpdb->usermeta} WHERE {$wpdb->usermeta}.meta_key='s2_autosub' AND {$wpdb->usermeta}.meta_value='yes'" == $query) {
        global $scoper, $subscribe2_category_rs;
        //rs_errlog("subscribe2 cat creation: $subscribe2_category_rs");
        $post_roles = $scoper->role_defs->qualify_roles('read', 'rs', 'post');
        // WP roles containing the 'activate plugins' capability are always honored regardless of object or term restritions
        $admin_roles_wp = array();
        global $wp_roles;
        if (isset($wp_roles->roles)) {
            $admin_cap_name = defined('SCOPER_CONTENT_ADMIN_CAP') ? constant('SCOPER_CONTENT_ADMIN_CAP') : 'activate_plugins';
            foreach (array_keys($wp_roles->roles) as $wp_role_name) {
                if (!empty($wp_roles->roles[$wp_role_name]['capabilities'])) {
                    if (array_intersect_key($wp_roles->roles[$wp_role_name]['capabilities'], array($admin_cap_name => 1))) {
                        $admin_roles_wp = array_merge($admin_roles_wp, array($wp_role_name => 1));
                    }
                }
            }
        }
        if ($admin_roles_wp) {
            $admin_roles_wp = scoper_role_names_to_handles(array_keys($admin_roles_wp), 'wp', true);
        }
        //arg: return as array keys
        $args = array('id' => $subscribe2_category_rs);
        $restrictions = $scoper->get_restrictions(TERM_SCOPE_RS, 'category', $args);
        $restricted_roles = array();
        if (!empty($restrictions['unrestrictions'])) {
            if ($restrictions['unrestrictions'] = array_intersect_key($restrictions['unrestrictions'], $post_roles)) {
                foreach ($restrictions['unrestrictions'] as $role_handle => $entries) {
                    if (!isset($entries[$subscribe2_category_rs]) || 'children' == $entries[$subscribe2_category_rs]) {
                        $restricted_roles[$role_handle] = true;
                    }
                }
            }
        }
        if (!empty($restrictions['restrictions'])) {
            if ($restrictions['restrictions'] = array_intersect_key($restrictions['restrictions'], $post_roles)) {
                foreach ($restrictions['restrictions'] as $role_handle => $entries) {
                    if (isset($entries[$subscribe2_category_rs]) && 'children' != $entries[$subscribe2_category_rs]) {
                        $restricted_roles[$role_handle] = true;
                    }
                }
            }
        }
        $unrestricted_roles = array_diff_key($post_roles, $restricted_roles);
        // for our purposes, a role is only restricted if all its contained qualifying roles are also restricted
        if ($restricted_roles) {
            foreach (array_keys($restricted_roles) as $role_handle) {
                if ($contained_roles = $scoper->role_defs->get_contained_roles($role_handle, false, 'rs')) {
                    if ($contained_roles = array_intersect_key($contained_roles, $unrestricted_roles)) {
                        unset($restricted_roles[$role_handle]);
                    }
                }
            }
            $unrestricted_roles = array_diff_key($post_roles, $restricted_roles);
        }
        // account for WP blog roles
        $unrestricted_roles_wp = array();
        $restricted_roles_wp = array();
        if ($post_roles_wp = $scoper->role_defs->qualify_roles('read', 'wp', 'post')) {
            foreach (array_keys($post_roles_wp) as $wp_role) {
                if ($contains_rs_roles = $scoper->role_defs->get_contained_roles($wp_role, false, 'rs')) {
                    if ($contains_rs_roles = array_intersect_key($contains_rs_roles, $unrestricted_roles)) {
                        $unrestricted_roles_wp = array_merge($unrestricted_roles_wp, array($wp_role => true));
                    }
                }
            }
            $restricted_roles_wp = array_diff_key($post_roles_wp, $unrestricted_roles_wp);
        }
        $unrestricted_roles_wp = array_merge($unrestricted_roles_wp, $admin_roles_wp);
        $role_in_wp = implode("', '", scoper_role_handles_to_names(array_keys($unrestricted_roles_wp)));
        /*
        dump($post_roles);
        dump($restricted_roles);
        dump($restricted_roles_wp);
        dump($unrestricted_roles);
        dump($unrestricted_roles_wp);
        */
        // account for blog roles, where allowed
        if ($unrestricted_roles) {
            $wp_role_clause = !empty($role_in_wp) ? "OR ( role_type = 'wp' AND scope = 'blog' AND role_name IN ('{$role_in_wp}') )" : '';
            $role_in = implode("', '", scoper_role_handles_to_names(array_keys($unrestricted_roles)));
            $qry = "SELECT DISTINCT user_id FROM {$wpdb->user2role2object_rs}" . " WHERE user_id > 0 AND (" . " ( role_type = 'rs' AND scope = 'blog' AND role_name IN ('{$role_in}') ) {$wp_role_clause} )";
            $users = scoper_get_col($qry);
            $qry = "SELECT DISTINCT group_id FROM {$wpdb->user2role2object_rs}" . " WHERE group_id > 0 AND (" . " ( role_type = 'rs' AND scope = 'blog' AND role_name IN ('{$role_in}') ) {$wp_role_clause} )";
            if ($groups = scoper_get_col($qry)) {
                foreach ($groups as $group_id) {
                    if ($group_members = ScoperAdminLib::get_group_members($group_id, $cols, true)) {
                        $users = array_merge($users, $group_members);
                    }
                }
                $users = array_unique($users);
            }
        } else {
            $users = array();
        }
        // account for category roles
        $role_in = implode("', '", scoper_role_handles_to_names(array_keys($post_roles)));
        $qry = "SELECT DISTINCT user_id FROM {$wpdb->user2role2object_rs}" . " WHERE user_id > 0 AND role_type = 'rs' AND scope = 'term' AND role_name IN ('{$role_in}')" . " AND assign_for IN ('entity', 'both')" . " AND src_or_tx_name = 'category' AND obj_or_term_id = '{$subscribe2_category_rs}'";
        $catrole_users = scoper_get_col($qry);
        $users = array_merge($users, $catrole_users);
        $qry = "SELECT DISTINCT group_id FROM {$wpdb->user2role2object_rs}" . " WHERE group_id > 0 AND role_type = 'rs' AND scope = 'term' AND role_name IN ('{$role_in}')" . " AND assign_for IN ('entity', 'both')" . " AND src_or_tx_name = 'category' AND obj_or_term_id = '{$subscribe2_category_rs}'";
        if ($groups = scoper_get_col($qry)) {
            foreach ($groups as $group_id) {
                if ($group_members = ScoperAdminLib::get_group_members($group_id, $cols, true)) {
                    $users = array_merge($users, $group_members);
                }
            }
            $users = array_unique($users);
        }
        if ($users) {
            $query .= " AND user_id IN ('" . implode("', '", $users) . "')";
        } else {
            $query .= ' AND 1=2';
        }
        remove_filter('query', 'scoper_limit_subscribe2_autosub', 99);
    }
    return $query;
}
Exemplo n.º 10
0
 function get_applied_object_roles($user = '')
 {
     if (is_object($user)) {
         $cache_flag = 'rs_object-roles';
         // v 1.1: changed cache key from "object_roles" to "object-roles" to match new key format for blog, term roles
         $cache = $user->cache_get($cache_flag);
         $limit = '';
         $u_g_clause = $user->get_user_clause('');
     } else {
         $cache_flag = 'rs_applied_object-roles';
         // v 1.1: changed cache key from "object_roles" to "object-roles" to match new key format for blog, term roles
         $cache_id = 'all';
         $cache = wpp_cache_get($cache_id, $cache_flag);
         $u_g_clause = '';
     }
     if (is_array($cache)) {
         return $cache;
     }
     $role_handles = array();
     global $wpdb;
     // object roles support date limits, but content date limits (would be redundant and a needless performance hit)
     $duration_clause = scoper_get_duration_clause('', $wpdb->user2role2object_rs);
     if ($role_names = scoper_get_col("SELECT DISTINCT role_name FROM {$wpdb->user2role2object_rs} WHERE role_type='rs' AND scope='object' {$duration_clause} {$u_g_clause}")) {
         $role_handles = scoper_role_names_to_handles($role_names, 'rs', true);
     }
     //arg: return role keys as array key
     if (is_object($user)) {
         $user->cache_force_set($role_handles, $cache_flag);
     } else {
         wpp_cache_force_set($cache_id, $role_handles, $cache_flag);
     }
     return $role_handles;
 }
 function update_rs_role_defs($sitewide = false, $customize_defaults = false)
 {
     $default_prefix = $customize_defaults ? 'default_' : '';
     $default_role_caps = apply_filters('define_role_caps_rs', cr_role_caps());
     $cap_defs = new CR_Capabilities();
     $cap_defs = apply_filters('define_capabilities_rs', $cap_defs);
     $cap_defs->add_member_objects(cr_cap_defs());
     global $scoper, $scoper_role_types;
     $role_defs = new CR_Roles();
     $role_defs->add_member_objects(cr_role_defs());
     $role_defs = apply_filters('define_roles_rs', $role_defs);
     $reviewed_roles = explode(',', $_POST['reviewed_roles']);
     $disable_caps = array();
     $add_caps = array();
     foreach ($default_role_caps as $role_handle => $default_caps) {
         if (!in_array($role_handle, $reviewed_roles)) {
             continue;
         }
         if ($role_defs->member_property($role_handle, 'no_custom_caps') || $role_defs->member_property($role_handle, 'anon_user_blogrole')) {
             continue;
         }
         $posted_set_caps = empty($_POST["{$role_handle}_caps"]) ? array() : $_POST["{$role_handle}_caps"];
         // html IDs have any spaces stripped out of cap names.  Replace them for processing.
         $set_caps = array();
         foreach ($posted_set_caps as $cap_name) {
             if (strpos($cap_name, ' ')) {
                 $set_caps[] = str_replace('_', ' ', $cap_name);
             } else {
                 $set_caps[] = $cap_name;
             }
         }
         // deal with caps which are locked into role, therefore displayed as a disabled checkbox and not included in $_POST
         foreach (array_keys($default_caps) as $cap_name) {
             if (!in_array($cap_name, $set_caps) && $cap_defs->member_property($cap_name, 'no_custom_remove')) {
                 $set_caps[] = $cap_name;
             }
         }
         $disable_caps[$role_handle] = array_fill_keys(array_diff(array_keys($default_caps), $set_caps), true);
         $add_caps[$role_handle] = array_fill_keys(array_diff($set_caps, array_keys($default_caps)), true);
     }
     scoper_update_option($default_prefix . 'disabled_role_caps', $disable_caps, $sitewide);
     scoper_update_option($default_prefix . 'user_role_caps', $add_caps, $sitewide);
     scoper_refresh_options();
     $scoper->load_definition('cap_defs');
     global $wp_roles;
     // synchronize WP roles as requested
     if (!empty($_POST['sync_wp_roles'])) {
         foreach ($_POST['sync_wp_roles'] as $sync_request) {
             $scoper->log_cap_usage($scoper->role_defs, $scoper->cap_defs);
             $sync_handles = explode(':', $sync_request);
             $rs_role_handle = $sync_handles[0];
             $wp_role_handle = $sync_handles[1];
             $wp_role_name = str_replace('wp_', '', $wp_role_handle);
             // only remove caps which are defined for this RS role's data source and object type
             $role_attributes = $scoper->role_defs->get_role_attributes($rs_role_handle);
             $otype_caps = $scoper->cap_defs->get_matching($role_attributes->src_name, $role_attributes->object_type, '', STATUS_ANY_RS);
             // make the roledef change for all blogs if RS role def is sitewide
             if (IS_MU_RS && $sitewide) {
                 global $wpdb, $blog_id;
                 $blog_ids = scoper_get_col("SELECT blog_id FROM {$wpdb->blogs}");
                 $orig_blog_id = $blog_id;
             } else {
                 $blog_ids = array('');
             }
             foreach ($blog_ids as $id) {
                 if (count($blog_ids) > 1) {
                     switch_to_blog($id);
                 }
                 if (!isset($wp_roles->role_objects[$wp_role_name])) {
                     continue;
                 }
                 if ($wp_missing_caps = array_diff_key($scoper->role_defs->role_caps[$rs_role_handle], $wp_roles->role_objects[$wp_role_name]->capabilities)) {
                     foreach (array_keys($wp_missing_caps) as $cap_name) {
                         $wp_roles->add_cap($wp_role_name, $cap_name);
                     }
                 }
                 $wp_defined_caps = array_intersect_key($wp_roles->role_objects[$wp_role_name]->capabilities, $otype_caps);
                 if ($wp_extra_caps = array_diff_key($wp_defined_caps, $scoper->role_defs->role_caps[$rs_role_handle])) {
                     foreach (array_keys($wp_extra_caps) as $cap_name) {
                         $wp_roles->remove_cap($wp_role_name, $cap_name);
                     }
                 }
             }
             if (count($blog_ids) > 1) {
                 switch_to_blog($orig_blog_id);
             }
             $wp_roles = new WP_Roles();
         }
     }
     $scoper->role_defs->locked = false;
     $scoper->log_wp_roles($scoper->role_defs);
     $scoper->role_defs->lock();
 }
 function flt_nav_menu_items($items, $menu_name, $args)
 {
     global $wpdb;
     $item_types = array();
     foreach ($items as $key => $item) {
         if (!isset($item_types[$item->type])) {
             $item_types["{$item->type}"] = array();
         }
         if (!isset($item_types[$item->type][$item->object])) {
             $item_types[$item->type][$item->object] = array($key => $item->object_id);
         } else {
             $item_types[$item->type][$item->object][$key] = $item->object_id;
         }
     }
     $teaser_enabled = scoper_get_otype_option('do_teaser', 'post');
     // remove unreadable terms
     if (isset($item_types['taxonomy'])) {
         foreach ($item_types['taxonomy'] as $taxonomy => $item_ids) {
             if ($teaser_enabled) {
                 if ($taxonomy_obj = get_taxonomy($taxonomy)) {
                     foreach ($taxonomy_obj->object_type as $post_type) {
                         // don't remove a term if it is associated with a post type that's being teased
                         if (scoper_get_otype_option('use_teaser', 'post', $post_type)) {
                             continue 2;
                         }
                     }
                 }
             }
             /*
             $query_base = "SELECT t.term_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE 1=1 AND tt.taxonomy = '$taxonomy'";
             $query = apply_filters( 'terms_request_rs', $query_base, $taxonomy ); //, array( 'skip_teaser' => true ) );
             $okay_ids = scoper_get_col($query);
             */
             $hide_empty = isset($args['hide_empty']) ? $args['hide_empty'] : 0;
             $okay_ids = get_terms($taxonomy, "fields=ids&hierarchical=0&hide_empty={$hide_empty}");
             if ($remove_ids = array_diff($item_ids, $okay_ids)) {
                 $items = array_diff_key($items, $remove_ids);
             }
         }
     }
     // remove unreadable posts
     if (isset($item_types['post_type'])) {
         foreach ($item_types['post_type'] as $post_type => $item_ids) {
             $where = apply_filters('objects_where_rs', '', 'post', $post_type, array('skip_teaser' => true));
             $okay_ids = scoper_get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = '{$post_type}' {$where} AND ID IN ('" . implode("','", $item_ids) . "')");
             if ($remove_ids = array_diff($item_ids, $okay_ids)) {
                 if ($teaser_enabled && scoper_get_otype_option('use_teaser', 'post', $post_type)) {
                     require_once dirname(__FILE__) . '/teaser_rs.php';
                     $teaser_prepend = ScoperTeaser::get_teaser_text('prepend', 'name', 'post', $post_type);
                     $teaser_append = ScoperTeaser::get_teaser_text('append', 'name', 'post', $post_type);
                     foreach (array_keys($remove_ids) as $key) {
                         $items[$key]->title = $teaser_prepend . $items[$key]->title . $teaser_append;
                     }
                 } else {
                     $items = array_diff_key($items, $remove_ids);
                 }
             }
         }
     }
     return $items;
 }
 function item_deletion_aftermath($scope, $src_or_tx_name, $obj_or_term_id)
 {
     global $wpdb;
     // delete role assignments for deleted term
     if ($ass_ids = scoper_get_col("SELECT assignment_id FROM {$wpdb->user2role2object_rs} WHERE src_or_tx_name = '{$src_or_tx_name}' AND scope = '{$scope}' AND obj_or_term_id = '{$obj_or_term_id}'")) {
         $id_in = "'" . implode("', '", $ass_ids) . "'";
         scoper_query("DELETE FROM {$wpdb->user2role2object_rs} WHERE assignment_id IN ({$id_in})");
         // Propagated roles will be converted to direct-assigned roles if the original progenetor goes away.  Removal of a "link" in the parent/child propagation chain has no effect.
         scoper_query("UPDATE {$wpdb->user2role2object_rs} SET inherited_from = '0' WHERE inherited_from IN ({$id_in})");
     }
     if ($req_ids = scoper_get_col("SELECT requirement_id FROM {$wpdb->role_scope_rs} WHERE topic = '{$scope}' AND src_or_tx_name = '{$src_or_tx_name}' AND obj_or_term_id = '{$obj_or_term_id}'")) {
         $id_in = "'" . implode("', '", $req_ids) . "'";
         scoper_query("DELETE FROM {$wpdb->role_scope_rs} WHERE requirement_id IN ({$id_in})");
         // Propagated requirements will be converted to direct-assigned roles if the original progenetor goes away.  Removal of a "link" in the parent/child propagation chain has no effect.
         scoper_query("UPDATE {$wpdb->role_scope_rs} SET inherited_from = '0' WHERE inherited_from IN ({$id_in})");
     }
 }
Exemplo n.º 14
0
 function clear_all_file_rules()
 {
     global $wpdb, $blog_id;
     $blog_ids = scoper_get_col("SELECT blog_id FROM {$wpdb->blogs} ORDER BY blog_id");
     $orig_blog_id = $blog_id;
     foreach ($blog_ids as $id) {
         switch_to_blog($id);
         require_once dirname(__FILE__) . '/uploads_rs.php';
         $uploads = scoper_get_upload_info();
         $htaccess_path = trailingslashit($uploads['basedir']) . '.htaccess';
         if (file_exists($htaccess_path)) {
             ScoperRewrite::insert_with_markers($htaccess_path, 'Role Scoper', '');
         }
     }
     switch_to_blog($orig_blog_id);
 }
 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;
 }
Exemplo n.º 16
0
 function posts_teaser_prep_results($results, $tease_otypes, $args = '')
 {
     $defaults = array('user' => '', 'use_object_roles' => -1, 'use_term_roles' => -1, 'request' => '', 'object_type' => '');
     $args = array_merge($defaults, (array) $args);
     extract($args);
     global $wpdb, $scoper, $wp_query;
     global $query_interceptor;
     if (did_action('wp_meta') && !did_action('wp_head')) {
         return $results;
     }
     if (empty($request)) {
         // TODO: teaser logs last_request itself
         global $query_interceptor;
         if (empty($query_interceptor->last_request['post'])) {
             // try to get it from wpdb instead
             if (!empty($wpdb->last_query)) {
                 $request = $wpdb->last_query;
             } else {
                 // don't risk exposing hidden content if something goes wrong with query logging
                 return array();
             }
         } else {
             $request = $query_interceptor->last_request['post'];
         }
     }
     // Pagination could be broken by subsequent query for filtered ids, so buffer current paging parameters
     // ( this code mimics WP_Query::get_posts() )
     if (!empty($wp_query->query_vars['posts_per_page'])) {
         $found_posts_query = apply_filters('found_posts_query', 'SELECT FOUND_ROWS()');
         $buffer_found_posts = $wpdb->get_var($found_posts_query);
         if ($buffer_found_posts >= $wp_query->query_vars['posts_per_page']) {
             $restore_pagination = true;
             $buffer_found_posts = apply_filters('found_posts', $buffer_found_posts);
         }
     }
     $list_private = array();
     if (awp_ver('3.0')) {
         $private_stati = get_post_stati(array('private' => true));
     } else {
         $private_stati = array('private');
     }
     if (is_single() || is_page()) {
         $maybe_fudge_private = true;
         $maybe_strip_private = false;
     } else {
         $maybe_strip_private = true;
         $maybe_fudge_private = false;
     }
     if (!is_object($user)) {
         global $current_user;
         $user = $current_user;
     }
     // don't risk exposing hidden content if there is a problem with query parsing
     if (!($pos = strpos(strtoupper($request), " FROM"))) {
         return array();
     }
     $distinct = stripos($request, " DISTINCT ") ? 'DISTINCT' : '';
     // RS does not add any joins, but if DISTINCT clause exists in query, retain it
     $request = "SELECT {$distinct} {$wpdb->posts}.ID " . substr($request, $pos);
     if ($limitpos = strpos($request, ' LIMIT ')) {
         $request = substr($request, 0, $limitpos);
     }
     $args['skip_teaser'] = true;
     $filtered_request = $query_interceptor->flt_objects_request($request, 'post', $object_type, $args);
     global $scoper_teaser_filtered_ids;
     $scoper_teaser_filtered_ids = scoper_get_col($filtered_request);
     if (!isset($scoper->teaser_ids)) {
         $scoper->teaser_ids = array();
     }
     $hide_ungranted_private = array();
     foreach ($tease_otypes as $object_type) {
         $hide_ungranted_private[$object_type] = scoper_get_otype_option('teaser_hide_private', 'post', $object_type);
     }
     foreach (array_keys($results) as $key) {
         if (is_array($results[$key])) {
             $id = $results[$key]['ID'];
         } else {
             $id = $results[$key]->ID;
         }
         if (!$scoper_teaser_filtered_ids || !in_array($id, $scoper_teaser_filtered_ids)) {
             if (isset($results[$key]->post_type)) {
                 $object_type = $results[$key]->post_type;
             } else {
                 $object_type = $scoper->data_sources->get_from_db('type', 'post', $id);
             }
             if (!in_array($object_type, $tease_otypes)) {
                 continue;
             }
             // Defeat a WP core secondary safeguard so we can apply the teaser message rather than 404
             if (in_array($results[$key]->post_status, $private_stati)) {
                 // don't want the teaser message (or presence in category archive listing) if we're hiding a page from listing
                 $type_obj = get_post_type_object($object_type);
                 if ($type_obj && $type_obj->hierarchical) {
                     // TODO: review implementation of this option with custom types
                     if (!isset($list_private[$object_type])) {
                         $list_private[$object_type] = scoper_get_otype_option('private_items_listable', 'post', 'page');
                     }
                 } else {
                     $list_private[$object_type] = true;
                 }
                 if ($hide_ungranted_private[$object_type] || $maybe_strip_private && !$list_private[$object_type]) {
                     $need_reindex = true;
                     unset($results[$key]);
                     // Actually, don't do this because the current method of removing private items from the paged result set will not move items from one result page to another
                     //$buffer_found_posts--;	// since we're removing this item from the teased results, decrement the paging total
                     continue;
                 } elseif (!empty($maybe_fudge_private) && $list_private[$object_type]) {
                     $results[$key]->post_status = 'publish';
                 }
             }
         }
     }
     if (!empty($need_reindex)) {
         // re-index the array so paging isn't confused
         $results = array_values($results);
     }
     // pagination could be broken by the filtered ids query performed in this function, so original paging parameters were buffered
     if (!empty($restore_pagination)) {
         // WP query will apply found_posts filter shortly after this function returns.  Feed it the buffered value from original unfiltered results.
         // Static flag in created function ensures it is only applied once.
         $func_name = create_function('$a', 'static $been_here; if ( ! empty($been_here) ) return $a; else {$been_here = true; ' . "return {$buffer_found_posts};}");
         add_filter('found_posts', $func_name, 1);
     }
     return $results;
 }
 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;
             }
         }
     }
 }
 function _flt_user_has_cap($wp_blogcaps, $orig_reqd_caps, $args)
 {
     // =============================== STATIC VARIABLE DECLARATION AND INITIALIZATION (to memcache filtering results) =====
     static $cache_tested_ids;
     static $cache_okay_ids;
     static $cache_where_clause;
     if (empty($cache_tested_ids)) {
         $cache_where_clause = array();
         $cache_tested_ids = array();
         $cache_okay_ids = array();
     }
     // ====================================================================================================================
     // =============================================== TEMPORARY DEBUG CODE ================================================
     //dump($orig_reqd_caps);
     //dump($args);
     //if ( strpos( $_SERVER['REQUEST_URI'], 'ajax' ) ) {
     //if ( ! empty($_REQUEST) )
     //	rs_errlog( serialize($_REQUEST) );
     //rs_errlog( '' );
     //rs_errlog('flt_user_has_cap');
     //rs_errlog(serialize($orig_reqd_caps));
     //rs_errlog(serialize($args));
     //rs_errlog('');
     //}
     // ============================================= (end temporary debug code) ==============================================
     // convert 'rs_role_name' to corresponding caps (and also make a tinkerable copy of orig_reqd_caps)
     $orig_reqd_caps = $this->scoper->role_defs->role_handles_to_caps($orig_reqd_caps);
     // ================= EARLY EXIT CHECKS (if the provided reqd_caps do not need filtering or need special case filtering ==================
     global $pagenow;
     // Disregard caps which are not defined in Role Scoper config
     if (!($rs_reqd_caps = array_intersect($orig_reqd_caps, $this->scoper->cap_defs->get_all_keys()))) {
         return $wp_blogcaps;
     }
     // log initial set of RS-filtered caps (in case we swap in equivalent caps for intermediate processing)
     $orig_reqd_caps = $rs_reqd_caps;
     // permitting this filter to execute early in an attachment request resets the found_posts record, preventing display in the template
     if (is_attachment() && !is_admin() && !did_action('template_redirect')) {
         if (empty($GLOBALS['scoper_checking_attachment_access'])) {
             return $wp_blogcaps;
         }
     }
     // work around bug in mw_EditPost method (requires publish_pages AND publish_posts cap)
     if (defined('XMLRPC_REQUEST') && 'publish_posts' == $orig_reqd_caps[0]) {
         if (!empty($GLOBALS['xmlrpc_post_type_rs']) && 'page' == $GLOBALS['xmlrpc_post_type_rs']) {
             return array('publish_posts' => true);
         }
     }
     // backdoor to deal with rare cases where one of the caps included in RS role defs cannot be filtered properly
     if (defined('UNSCOPED_CAPS_RS') && !array_diff($orig_reqd_caps, explode(',', UNSCOPED_CAPS_RS))) {
         return $wp_blogcaps;
     }
     // custom workaround to reveal all private / restricted content in all blogs if logged into main blog
     if (defined('SCOPER_MU_MAIN_BLOG_RULES')) {
         include_once dirname(__FILE__) . '/mu-custom.php';
         if (!array_diff($orig_reqd_caps, array('read', 'read_private_pages', 'read_private_posts'))) {
             if ($return_caps = ScoperMU_Custom::current_user_logged_into_main($wp_blogcaps, $orig_reqd_caps)) {
                 return $return_caps;
             }
         }
     }
     //define( 'SCOPER_NO_COMMENT_FILTERING', true );
     if (defined('SCOPER_NO_COMMENT_FILTERING') && 'moderate_comments' == $orig_reqd_caps[0] && empty($GLOBALS['current_rs_user']->allcaps['moderate_comments'])) {
         return $wp_blogcaps;
     }
     if (defined('SCOPER_ALL_UPLOADS_EDITABLE') && $pagenow == 'upload.php' && in_array($orig_reqd_caps[0], array('upload_files', 'edit_others_posts', 'delete_others_posts'))) {
         return $wp_blogcaps;
     }
     // =================================================== (end early exit checks) ======================================================
     // ============================ GLOBAL VARIABLE DECLARATIONS, ARGUMENT TRANSLATION AND STATUS DETECTION =============================
     global $current_rs_user;
     $user_id = isset($args[1]) ? $args[1] : 0;
     if ($user_id && $user_id != $current_rs_user->ID) {
         $user = rs_get_user($user_id);
     } else {
         $user = $current_rs_user;
     }
     // currently needed for filtering async-upload.php
     if (empty($user->blog_roles) || empty($user->blog_roles[''])) {
         $this->scoper->refresh_blogroles();
     }
     $object_id = isset($args[2]) ? (int) $args[2] : 0;
     // WP passes comment ID with 'edit_comment' metacap
     if ($object_id && 'edit_comment' == $args[0]) {
         if (!in_array('moderate_comments', $rs_reqd_caps)) {
             // as of WP 3.2.1, 'edit_comment' maps to related post's 'edit_post' caps without requiring moderate_comments
             if (scoper_get_option('require_moderate_comments_cap')) {
                 $rs_reqd_caps[] = 'moderate_comments';
                 $modified_caps = true;
             }
         }
         if ($comment = get_comment($object_id)) {
             $object_id = $comment->comment_post_ID;
         } else {
             $object_id = 0;
         }
     }
     // note the data source and object type(s) which are associated with the required caps (based on inclusion in RS Role Definitions)
     $is_taxonomy_cap = false;
     $src_name = '';
     $cap_types = $this->scoper->cap_defs->src_otypes_from_caps($rs_reqd_caps, $src_name);
     // note: currently only needed for src_name determination
     $doing_admin_menus = is_admin() && (did_action('_admin_menu') && !did_action('admin_menu') || did_action('admin_head') && !did_action('adminmenu'));
     // for scoped menu management roles, satisfy edit_theme_options cap requirement
     if (array_key_exists(0, $orig_reqd_caps) && 'edit_theme_options' == $orig_reqd_caps[0] && empty($wp_blogcaps['edit_theme_options'])) {
         if (in_array($GLOBALS['pagenow'], array('nav-menus.php', 'admin-ajax.php')) || $doing_admin_menus) {
             $key = array_search('edit_theme_options', $rs_reqd_caps);
             if (false !== $key) {
                 $tx = get_taxonomy('nav_menu');
                 $rs_reqd_caps[$key] = $tx->cap->manage_terms;
                 $src_name = 'nav_menu';
                 // menu-specific manager assignment does not permit deletion of the menu
                 if (!empty($_REQUEST['action']) && 'delete' == $_REQUEST['action']) {
                     $this->skip_any_term_check = true;
                 }
             }
         }
     }
     if (!$src_name) {
         // required capabilities correspond to multiple data sources
         return $wp_blogcaps;
     }
     // slight simplification: assume a single cap object type for a few cap substitution checks
     $is_taxonomy_cap = $this->scoper->cap_defs->member_property(reset($rs_reqd_caps), 'is_taxonomy_cap');
     // Establish some context by detecting object type - based on object ID if provided, or otherwise based on http variables.
     if (in_array($pagenow, array('media-upload.php', 'async-upload.php'))) {
         if (!empty($GLOBALS['post'])) {
             $object_type = $GLOBALS['post']->post_type;
         }
     } elseif (is_admin() && 'edit-tags.php' == $GLOBALS['pagenow'] && 'link_category' == $_REQUEST['taxonomy']) {
         $src_name = 'link';
         $object_type = 'link_category';
     } elseif (array_key_exists(0, $orig_reqd_caps) && in_array($orig_reqd_caps[0], array('manage_nav_menus', 'edit_theme_options'))) {
         $src_name = 'nav_menu';
     }
     if (empty($object_type)) {
         $object_type = cr_find_object_type($src_name, $object_id);
     }
     $object_type_obj = cr_get_type_object($src_name, $object_type);
     $is_att_rev = false;
     if ('post' == $src_name) {
         if (in_array($object_type, array('attachment', 'revision'))) {
             $is_att_rev = true;
             if ($object_id) {
                 if ($_post = get_post($object_id)) {
                     if ($_parent = get_post($_post->post_parent)) {
                         $object_type = $_parent->post_type;
                         $object_id = $_parent->ID;
                         // deal with case of edit_posts cap check on attachments to revision (with Revisionary)
                         if ('revision' == $object_type) {
                             if ($_orig_post = get_post($_parent->post_parent)) {
                                 $object_type = $_orig_post->post_type;
                                 $object_id = $_orig_post->ID;
                             }
                         }
                         $object_type_obj = get_post_type_object($object_type);
                     }
                 }
             }
         } elseif (!$is_taxonomy_cap) {
             $use_post_types = scoper_get_option('use_post_types');
             if (empty($use_post_types[$object_type])) {
                 return $wp_blogcaps;
             }
         }
     }
     // =====================================================================================================================================
     // ======================================== SUBVERT MISGUIDED CAPABILITY REQUIREMENTS ==================================================
     if ('post' == $src_name) {
         if (!$is_taxonomy_cap) {
             $modified_caps = false;
             if ('post' != $object_type) {
                 $replace_post_caps = array('publish_posts', 'edit_others_posts', 'edit_published_posts');
                 // Replace edit_posts requirement with corresponding type-specific requirement, but only after admin menu is drawn, or on a submission before the menu is drawn
                 if (did_action('admin_init')) {
                     // otherwise extra padding between menu items due to some items populated but unpermitted
                     $replace_post_caps[] = 'edit_posts';
                 }
                 if (in_array($pagenow, array('upload.php', 'media.php'))) {
                     $replace_post_caps = array_merge($replace_post_caps, array('delete_posts', 'delete_others_posts'));
                 }
                 foreach ($replace_post_caps as $post_cap_name) {
                     $key = array_search($post_cap_name, $rs_reqd_caps);
                     if (false !== $key && !$doing_admin_menus && in_array($pagenow, array('edit.php', 'post.php', 'post-new.php', 'press-this.php', 'admin-ajax.php', 'upload.php', 'media.php'))) {
                         $rs_reqd_caps[$key] = $object_type_obj->cap->{$post_cap_name};
                         $modified_caps = true;
                     }
                 }
             }
             // WP core quirk workaround: edit_others_posts is required as preliminary check for populating authors dropdown for any post type.  Instead, we need to do our own validation based on scoped roles.
             // (but don't mess if this cap requirement is part of an edit_post metacap check for a specific post)
             if (!$object_id && count($rs_reqd_caps) == 1) {
                 if (in_array(reset($rs_reqd_caps), array('edit_others_posts'))) {
                     require_once dirname(__FILE__) . '/lib/agapetry_wp_admin_lib.php';
                     // function awp_metaboxes_started()
                     if (!awp_metaboxes_started($object_type) && 'revision.php' != $pagenow && 'revisions' != $GLOBALS['plugin_page_cr']) {
                         // don't enable contributors to view/restore revisions
                         $rs_reqd_caps[0] = $object_type_obj->cap->edit_posts;
                     } else {
                         $rs_reqd_caps[0] = $object_type_obj->cap->edit_published_posts;
                     }
                     // we will filter / suppress the author dropdown downstream from here
                     $modified_caps = true;
                 }
             }
             // as of WP 3.1, addition of new nav menu items requires edit_posts capability (otherwise nav menu item is orphaned with no menu relationship)
             if (is_admin() && strpos($_SERVER['SCRIPT_NAME'], 'nav-menus.php')) {
                 if ('edit_posts' == $orig_reqd_caps[0]) {
                     $type_obj = get_taxonomy('nav_menu');
                     $rs_reqd_caps[0] = $type_obj->cap->manage_terms;
                     $modified_caps = true;
                 }
             }
         }
         // endif not taxonomy cap
     }
     // endif caps correspond to 'post' data source
     //====================================== (end subvert misguided capability requirements) =============================================
     if (defined('RVY_VERSION')) {
         require_once dirname(__FILE__) . '/revisionary-helper_rs.php';
         $rs_reqd_caps = Rvy_Helper::convert_post_edit_caps($rs_reqd_caps, $object_type);
     }
     //rs_errlog( "matched context for $object_id : $matched_context" );
     // don't apply object-specific filtering for auto-drafts
     if ('post' == $src_name) {
         if ($object_id) {
             if ($_post = get_post($object_id)) {
                 if ('auto-draft' == $_post->post_status) {
                     // && ! empty($_POST['action']) )
                     $object_id = 0;
                     if (!$doing_admin_menus) {
                         $this->skip_id_generation = true;
                     }
                 }
             }
         } else {
             if (!empty($GLOBALS['post']) && !is_object($GLOBALS['post'])) {
                 $GLOBALS['post'] = get_post($GLOBALS['post']);
             }
             if (!empty($GLOBALS['post']) && 'auto-draft' == $GLOBALS['post']->post_status && !$doing_admin_menus) {
                 $this->skip_id_generation = true;
             }
         }
     }
     //dump($object_id);
     // If no object id was passed in...
     if (!$object_id) {
         // || ! $matched_context ) {
         //if ( $missing_caps = array_diff($rs_reqd_caps, array_keys($wp_blogcaps) ) ) {
         if (!$doing_admin_menus) {
             if (!empty($_REQUEST['action']) && in_array($pagenow, array('edit.php', 'edit-tags.php'))) {
                 $this->skip_id_generation = true;
             }
             // ============================================ OBJECT ID DETERMINATION ========================================
             if (!$this->skip_id_generation && !defined('XMLRPC_REQUEST') && !in_array($pagenow, array('media-upload.php', 'async-upload.php'))) {
                 // lots of superfluous queries in media upload popup otherwise
                 // Try to generate missing object_id argument for problematic current_user_can calls
                 static $generated_id;
                 if (!isset($generated_id)) {
                     $generated_id = array();
                 }
                 // if the id was not already detected and stored to the static variable...
                 $caps_key = serialize($rs_reqd_caps);
                 if (!isset($generated_id[$object_type][$caps_key])) {
                     $gen_id = 0;
                     foreach ($rs_reqd_caps as $cap_name) {
                         if ($gen_id = (int) $this->_detect_object_id($cap_name)) {
                             break;
                             // means we are accepting the generated id
                         }
                     }
                     $generated_id[$object_type][$caps_key] = $gen_id;
                     $object_id = $gen_id;
                 } else {
                     $object_id = $generated_id[$object_type][$caps_key];
                 }
                 //rs_errlog( "detected ID: $object_id" );
             } else {
                 $this->skip_id_generation = false;
             }
             // this is a one-time flag
             // ========================================= (end object id determination) =======================================
         }
         // If we still have no object id (detection was skipped or failed to identify it)...
         if (!$object_id) {
             // || ! $matched_context ) {
             // ============================================ "CAN FOR ANY" CHECKS ===========================================
             if ($missing_caps = array_diff($rs_reqd_caps, array_keys($wp_blogcaps))) {
                 // These checks are only relevant since no object_id was provided.  Otherwise (in the main body of this function), taxonomy and object caps will be credited via scoped query.
                 // If we are about to fail the blogcap requirement, credit a missing cap if the user has it by term role for ANY term.
                 // This prevents failing initial UI entrance exams that only consider blog-wide roles.
                 if (!$this->skip_any_term_check) {
                     if ($tax_caps = $this->user_can_for_any_term($missing_caps)) {
                         $wp_blogcaps = array_merge($wp_blogcaps, $tax_caps);
                     }
                     //rs_errlog( "can for any term: " . serialize($tax_caps) );
                 } else {
                     $this->skip_any_term_check = false;
                 }
                 // this is a one-time flag
                 // If we are still missing required caps, credit a missing scoper-defined cap if the user has it by object role for ANY object.
                 // (i.e. don't bar user from "Edit Pages" if they have edit_pages cap for at least one page)
                 if ($missing_caps = array_diff($rs_reqd_caps, array_keys($wp_blogcaps))) {
                     // prevent object-specific editing roles from allowing new object creation w/o sitewide capability
                     $add_new_check = strpos($_SERVER['SCRIPT_NAME'], 'post-new.php') && 'post' == $src_name && reset($rs_reqd_caps) == $object_type_obj->cap->edit_posts;
                     if (!$this->skip_any_object_check && !$add_new_check) {
                         //if ( ! $this->skip_any_object_check ) {
                         if ($object_caps = $this->user_can_for_any_object($missing_caps)) {
                             $wp_blogcaps = array_merge($wp_blogcaps, $object_caps);
                         }
                         //rs_errlog( "can for any object: " . serialize($object_caps) );
                     } else {
                         $this->skip_any_object_check = false;
                     }
                     // this is a one-time flag
                 }
             }
             // ========================================== (end "can for any" checks ) =========================================
             //rs_errlog( serialize( $wp_blogcaps) );
             if ($missing_caps = array_diff($rs_reqd_caps, array_keys($wp_blogcaps))) {
                 // normal exit point when no object ID is passed or detected, or when detected object type does not match required capabilities
                 return $wp_blogcaps;
             } else {
                 if ($restore_caps = array_diff($orig_reqd_caps, $rs_reqd_caps)) {
                     // restore original reqd_caps which we substituted for the type-specific scoped query
                     $wp_blogcaps = array_merge($wp_blogcaps, array_fill_keys($restore_caps, true));
                 }
                 return $wp_blogcaps;
             }
         }
         //} else
         //return $wp_blogcaps;
     }
     if ($object_id && 'post' == $src_name) {
         $_post = get_post($object_id);
         $object_type = $_post->post_type;
         $object_type_obj = cr_get_type_object($src_name, $object_type);
         if (defined('RVY_VERSION') && in_array($pagenow, array('edit.php', 'edit-tags.php', 'admin-ajax.php')) && (!empty($_REQUEST['action']) && -1 != $_REQUEST['action'])) {
             $rs_reqd_caps = Rvy_Helper::fix_table_edit_reqd_caps($rs_reqd_caps, $args[0], $_post, $object_type_obj);
         }
         // if the top level page structure is locked, don't allow non-administrator to delete a top level page either
         if ('page' == $object_type || defined('SCOPER_LOCK_OPTION_ALL_TYPES') && !is_content_administrator_rs()) {
             $delete_metacap = !empty($object_type_obj->hierarchical) ? $object_type_obj->cap->delete_post : 'delete_page';
             // if the top level page structure is locked, don't allow non-administrator to delete a top level page either
             if ($delete_metacap == $args[0]) {
                 if ('1' === scoper_get_option('lock_top_pages')) {
                     // stored value of 1 means only Administrators are allowed to modify top-level page structure
                     if ($page = get_post($args[2])) {
                         if (empty($page->post_parent)) {
                             $in_process = false;
                             return false;
                         }
                     }
                 }
             }
         }
     }
     // Note: At this point, we have a nonzero object_id...
     // if this is a term administration request, route to user_can_admin_terms()
     if ($is_taxonomy_cap) {
         if ('post' == $src_name) {
             $cap_otype_obj = get_taxonomy($object_type);
         }
         if (('post' != $src_name || $cap_otype_obj && $rs_reqd_caps[0] == $cap_otype_obj->cap->manage_terms) && count($rs_reqd_caps) == 1) {
             // don't re-route if multiple caps are being required
             // always pass through any assigned blog caps which will not be involved in this filtering
             $rs_reqd_caps = array_fill_keys($rs_reqd_caps, 1);
             $undefined_reqd_caps = array_diff_key($wp_blogcaps, $rs_reqd_caps);
             require_once dirname(__FILE__) . '/admin/permission_lib_rs.php';
             if (user_can_admin_terms_rs($object_type, $object_id, $user)) {
                 return array_merge($undefined_reqd_caps, $rs_reqd_caps);
             } else {
                 return $undefined_reqd_caps;
                 // required caps we scrutinized are excluded from this array
             }
         }
     }
     // Workaround to deal with WP core's checking of publish cap prior to storing categories
     // Store terms to DB in advance of any cap-checking query which may use those terms to qualify an operation
     if (!empty($_REQUEST['action']) && (in_array($_REQUEST['action'], array('editpost', 'post')) || 'autosave' == $_REQUEST['action'])) {
         if (array_intersect(array('publish_posts', 'edit_posts', $object_type_obj->cap->publish_posts, $object_type_obj->cap->edit_posts), $rs_reqd_caps)) {
             $uses_taxonomies = scoper_get_taxonomy_usage($src_name, $object_type);
             static $inserted_terms;
             if (!isset($inserted_terms)) {
                 $inserted_terms = array();
             }
             foreach ($uses_taxonomies as $taxonomy) {
                 // TODO: only if tx->requires_term is true?
                 if (isset($inserted_terms[$taxonomy][$object_id])) {
                     continue;
                 }
                 $inserted_terms[$taxonomy][$object_id] = true;
                 //if ( $stored_terms = wp_get_object_terms( $object_id, $taxonomy ) ) // note: this will cause trouble if WP core ever auto-stores object terms on post creation
                 //	continue;
                 $stored_terms = $this->scoper->get_terms($taxonomy, UNFILTERED_RS, COL_ID_RS, $object_id);
                 require_once dirname(__FILE__) . '/admin/filters-admin-save_rs.php';
                 $selected_terms = cr_get_posted_object_terms($taxonomy);
                 if (is_array($selected_terms)) {
                     // non-hierarchical terms do not need to be pre-inserted
                     if ($set_terms = $GLOBALS['scoper_admin_filters']->flt_pre_object_terms($selected_terms, $taxonomy)) {
                         $set_terms = array_unique(array_map('intval', $set_terms));
                         if ($set_terms != $stored_terms && $set_terms && $set_terms != array(1)) {
                             // safeguard against unintended clearing of stored categories
                             wp_set_object_terms($object_id, $set_terms, $taxonomy);
                             // delete any buffered cap check results which were queried prior to storage of these object terms
                             unset($cache_tested_ids);
                             unset($cache_where_clause);
                             unset($cache_okay_ids);
                         }
                     }
                 }
             }
             // also avoid chicken-egg situation when publish cap is granted by a propagating page role
             if ($object_type_obj->hierarchical && isset($_POST['parent_id'])) {
                 if ($_POST['parent_id'] != get_post_field('post_parent', $object_id)) {
                     global $wpdb;
                     $set_parent = $GLOBALS['scoper_admin_filters']->flt_page_parent($_POST['parent_id']);
                     $GLOBALS['wpdb']->query("UPDATE {$wpdb->posts} SET post_parent = '{$set_parent}' WHERE ID = '{$object_id}'");
                     require_once dirname(__FILE__) . '/admin/filters-admin-save_rs.php';
                     scoper_inherit_parent_roles($object_id, OBJECT_SCOPE_RS, $src_name, $set_parent, $object_type);
                     scoper_inherit_parent_restrictions($object_id, OBJECT_SCOPE_RS, $src_name, $set_parent, $object_type);
                 }
             }
         }
     }
     // generate a string key for this set of required caps, for use below in checking, caching the scoped results
     $arg_append = '';
     $arg_append .= !empty($this->require_full_object_role) ? '-require_full_object_role-' : '';
     $arg_append .= !empty($GLOBALS['revisionary']->skip_revision_allowance) ? '-skip_revision_allowance-' : '';
     sort($rs_reqd_caps);
     $capreqs_key = implode($rs_reqd_caps) . $arg_append;
     // see ScoperAdmin::user_can_admin_object
     // ================================ SPECIAL HANDLING FOR ATTACHMENTS AND REVISIONS ==========================================
     $maybe_revision = 'post' == $src_name && !isset($cache_tested_ids[$src_name][$object_type][$capreqs_key][$object_id]);
     $maybe_attachment = in_array($pagenow, array('upload.php', 'media.php'));
     if ($maybe_revision || $maybe_attachment) {
         global $wpdb;
         if ($_post = get_post($object_id)) {
             if ('revision' == $_post->post_type) {
                 require_once dirname(__FILE__) . '/lib/revisions_lib_rs.php';
                 $rev_where = defined('RVY_VERSION') && rvy_get_option('revisor_lock_others_revisions') ? " AND post_author = '{$current_rs_user->ID}'" : '';
                 // might need to apply different cap requirement for other users' revisions. todo: skip this clause for sitewide editors
                 $revisions = rs_get_post_revisions($_post->post_parent, 'inherit', array('fields' => constant('COL_ID_RS'), 'return_flipped' => true, 'where' => $rev_where));
             }
             if ('revision' == $_post->post_type || 'attachment' == $_post->post_type) {
                 $is_att_rev = true;
                 if ($_post->post_parent) {
                     $object_id = $_post->post_parent;
                     if ($_parent = get_post($_post->post_parent)) {
                         $object_type = $_parent->post_type;
                         $object_type_obj = get_post_type_object($object_type);
                     }
                 } elseif ('attachment' == $_post->post_type) {
                     // special case for unattached uploads: uploading user should have their way with them
                     if ($_post->post_author == $current_rs_user->ID) {
                         $rs_reqd_caps[0] = 'read';
                         if ($restore_caps = array_diff($orig_reqd_caps, array_keys($rs_reqd_caps))) {
                             // restore original reqd_caps which we substituted for the type-specific scoped query
                             $wp_blogcaps = array_merge($wp_blogcaps, array_fill_keys($restore_caps, true));
                         }
                     }
                     return $wp_blogcaps;
                 }
             }
             //endif retrieved post is a revision or attachment
         }
         // endif post retrieved
     }
     // endif specified id might be a revision or attachment
     if ($is_att_rev) {
         if ('post' != $object_type_obj->name) {
             // Compensate for WP's requirement of posts cap for attachment editing, regardless of whether it's attached to a post or page
             if ('edit_others_posts' == $rs_reqd_caps[0]) {
                 $rs_reqd_caps[0] = $object_type_obj->cap->edit_others_posts;
             } elseif ('delete_others_posts' == $rs_reqd_caps[0]) {
                 $rs_reqd_caps[0] = $object_type_obj->cap->delete_others_posts;
             } elseif ('edit_posts' == $rs_reqd_caps[0]) {
                 $rs_reqd_caps[0] = $object_type_obj->cap->edit_posts;
             } elseif ('delete_posts' == $rs_reqd_caps[0]) {
                 $rs_reqd_caps[0] = $object_type_obj->cap->delete_posts;
             }
         }
     }
     //endif retrieved post is a revision or attachment
     // ============================== (end special handling for attachments and revisions) ==========================================
     // ============ SCOPED QUERY for required caps on object id (if other listed ids are known, query for them also).  Cache results to static var. ===============
     // $force_refresh = 'async-upload.php' == $pagenow;
     // Page refresh following publishing of new page by users who can edit by way of Term Role fails without this workaround
     if (!empty($_POST) && (defined('SCOPER_CACHE_SAFE_MODE') || in_array($pagenow, array('post.php', 'press-this.php')) && $args[0] == $object_type_obj->cap->edit_post)) {
         $force_refresh = true;
         $cache_tested_ids = array();
         $cache_okay_ids = array();
         $cache_where_clause = array();
     } else {
         $force_refresh = false;
     }
     // Check whether this object id was already tested for the same reqd_caps in a previous execution of this function within the same http request
     if ($force_refresh || !isset($cache_tested_ids[$src_name][$object_type][$capreqs_key][$object_id])) {
         //if ( ! isset($cache_tested_ids[$src_name][$object_type][$capreqs_key][$object_id]) ) {
         // retrieve CR_Data_Source object, which contains database column names
         $src_table = $this->scoper->data_sources->member_property($src_name, 'table');
         $cols = $this->scoper->data_sources->member_property($src_name, 'cols');
         // Before querying for caps on this object, check whether we have a record of other posts listed alongside it.
         // If so, run the scoped query for ALL listed objects in that buffer, and buffer the results to static variable hascap_object_ids.
         //
         // (This is useful when front end code must check caps for each post
         //  to determine whether to display 'edit' link, etc.)
         if (is_admin() && 'index.php' == $pagenow) {
             // there's too much happening on the dashboard (and too much low-level query filtering) to buffer listed IDs reliably.
             $listed_ids = array();
         } else {
             if (isset($this->scoper->listed_ids[$src_name])) {
                 $listed_ids = array_keys($this->scoper->listed_ids[$src_name]);
             } else {
                 // note: don't use wp_object_cache because it includes posts not present in currently displayed resultset listing page
                 $listed_ids = array();
             }
         }
         // make sure our current object_id is in the list
         $listed_ids[] = $object_id;
         // since the objects_where_role_clauses() output itself is not id-specific, also statically buffer it per reqd_caps
         if ($force_refresh || !isset($cache_where_clause[$src_name][$object_type][$capreqs_key])) {
             $check_otype = 'link_category' == $object_type ? 'link' : $object_type;
             $use_term_roles = scoper_get_otype_option('use_term_roles', $src_name, $check_otype);
             $no_object_roles = $this->scoper->data_sources->member_property($src_name, 'no_object_roles');
             $use_object_roles = $no_object_roles ? false : scoper_get_otype_option('use_object_roles', $src_name, $object_type);
             $this_args = array('object_type' => $object_type, 'user' => $user, 'otype_use_term_roles' => $use_term_roles, 'otype_use_object_roles' => $use_object_roles, 'skip_teaser' => true, 'require_full_object_role' => !empty($this->require_full_object_role));
             //rs_errlog( serialize($rs_reqd_caps) );
             //rs_errlog( serialize($this_args) );
             $where = $this->query_interceptor->objects_where_role_clauses($src_name, $rs_reqd_caps, $this_args);
             if ($where) {
                 $where = "AND ( {$where} )";
             }
             // update static variable
             $cache_where_clause[$src_name][$object_type][$capreqs_key] = $where;
         } else {
             $where = $cache_where_clause[$src_name][$object_type][$capreqs_key];
         }
         // run the query
         $query = "SELECT {$src_table}.{$cols->id} FROM {$src_table} WHERE 1=1 {$where} AND {$src_table}.{$cols->id} IN ('" . implode("', '", array_unique($listed_ids)) . "')";
         if (isset($cache_okay_ids[$query])) {
             $okay_ids = $cache_okay_ids[$query];
         } else {
             if ($okay_ids = scoper_get_col($query)) {
                 $okay_ids = array_fill_keys($okay_ids, true);
             }
         }
         //dump($rs_reqd_caps);
         //dump($query);
         //dump($okay_ids);
         //rs_errlog( $query );
         //rs_errlog( 'results: ' . serialize( $okay_ids ) );
         // update static cache_tested_ids to log scoped results for this object id, and possibly also for other listed IDs
         if (empty($_GET['doaction']) || 'delete_post' != $args[0] && $object_type_obj->cap->delete_post != $args[0]) {
             // bulk post/page deletion is broken by hascap buffering
             foreach ($listed_ids as $_id) {
                 $cache_tested_ids[$src_name][$object_type][$capreqs_key][$_id] = isset($okay_ids[$_id]);
             }
             $cache_okay_ids[$query] = $okay_ids;
         }
         $this_id_okay = isset($okay_ids[$object_id]);
     } else {
         // results of this same has_cap inquiry are already stored (from another call within current http request)
         $this_id_okay = $cache_tested_ids[$src_name][$object_type][$capreqs_key][$object_id];
     }
     //rs_errlog( "okay ids: " . serialize( $okay_ids ) );
     // if we redirected the cap check to revision parent, also credit all the revisions for passing results
     if ($this_id_okay && !empty($revisions)) {
         if (empty($_GET['doaction']) || 'delete_post' != $args[0] && $object_type_obj->cap->delete_post != $args[0]) {
             // bulk post/page deletion is broken by hascap buffering
             $cache_tested_ids[$src_name][$object_type][$capreqs_key] = $cache_tested_ids[$src_name][$object_type][$capreqs_key] + array_fill_keys($revisions, true);
         }
     }
     $rs_reqd_caps = array_fill_keys($rs_reqd_caps, true);
     if (!$this_id_okay) {
         if (array_key_exists(0, $orig_reqd_caps) && 'edit_posts' == $orig_reqd_caps[0] && strpos($_SERVER['REQUEST_URI'], 'async-upload.php')) {
             // temp workaround for ACF with Revisionary
             return $wp_blogcaps;
         }
         // ================= TEMPORARY DEBUG CODE ===================
         //d_echo("object_id $object_id FAILED !!!!!!!!!!!!!!!!!" );
         //rs_errlog( "object_id $object_id FAILED !!!!!!!!!!!!!!!!!"  );
         //rs_errlog(serialize($orig_reqd_caps));
         //rs_errlog(serialize($rs_reqd_caps));
         //rs_errlog('');
         /*
         $log .= "checked caps: " . serialize($rs_reqd_caps) . "\r\n";
         $log .= "object_id $object_id FAILED !!!!!!!!!!!!!!!!!\r\n";
         $log .= $query;
         rs_errlog( "\r\n{$log}\r\n" );
         */
         //d_echo( "FAILED for " . serialize($rs_reqd_caps) );
         // ============== (end temporary debug code ==================
         return array_diff_key($wp_blogcaps, $rs_reqd_caps);
         // required caps we scrutinized are excluded from this array
     } else {
         if ($restore_caps = array_diff($orig_reqd_caps, array_keys($rs_reqd_caps))) {
             // restore original reqd_caps which we substituted for the type-specific scoped query
             $rs_reqd_caps = $rs_reqd_caps + array_fill_keys($restore_caps, true);
         }
         //d_echo( 'OKAY:' );
         //dump($args);
         //dump($rs_reqd_caps);
         //d_echo( '<br />' );
         return array_merge($wp_blogcaps, $rs_reqd_caps);
     }
 }
function scoper_attach_linked_uploads($echo = false)
{
    global $wpdb;
    require_once SCOPER_ABSPATH . '/uploads_rs.php';
    if (MULTISITE) {
        global $wpdb, $blog_id;
        $blog_ids = scoper_get_col("SELECT blog_id FROM {$wpdb->blogs} ORDER BY blog_id");
        $orig_blog_id = $blog_id;
    } else {
        $blog_ids = array('1');
    }
    foreach ($blog_ids as $id) {
        if (count($blog_ids) > 1) {
            switch_to_blog($id);
            _e("<br /><strong>site {$id} :</strong><br />");
        }
        $uploads = scoper_get_upload_info();
        $site_url = untrailingslashit(get_option('siteurl'));
        if (false === strpos($uploads['baseurl'], $site_url)) {
            if ($echo) {
                _e('<strong>Note</strong>: Direct access to uploaded file attachments cannot be filtered because your WP_CONTENT_DIR is not in the WordPress branch.', 'scoper');
                echo '<br /><br />';
                _e('The operation was terminated due to an invalid configuration.', 'scoper');
            }
            return false;
        }
        $post_types = array_diff(get_post_types(array('public' => true)), array('attachment'));
        $post_type_in = "'" . implode("','", $post_types) . "'";
        if ($post_ids = scoper_get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type IN ({$post_type_in}) ORDER BY post_type, post_title")) {
            $stored_attachments = array();
            if ($results = scoper_get_results("SELECT post_parent, guid FROM {$wpdb->posts} WHERE post_type = 'attachment'")) {
                foreach ($results as $row) {
                    if (!isset($stored_attachments[$row->post_parent])) {
                        $stored_attachments[$row->post_parent] = array();
                    }
                    $stored_attachments[$row->post_parent][$row->guid] = true;
                }
            }
            // for reasonable memory usage, only hold 10 posts in memory at a time
            $found_links = 0;
            $num_inserted = 0;
            $num_posts = count($post_ids);
            $bite_size = 10;
            $num_bites = $num_posts / $bite_size;
            if ($num_posts % $bite_size) {
                $num_bites++;
            }
            $upload_path = $uploads['baseurl'];
            $upload_dir = $uploads['basedir'];
            if ($echo) {
                printf(__("<strong>checking %s posts / pages...</strong>", 'scoper'), $num_posts);
                echo '<br /><br />';
            }
            for ($i = 0; $i < $num_bites; $i++) {
                $id_in = "'" . implode("','", array_slice($post_ids, $i * $bite_size, $bite_size)) . "'";
                if (!($results = scoper_get_results("SELECT ID, post_content, post_author, post_title, post_type FROM {$wpdb->posts} WHERE ID IN ({$id_in})"))) {
                    continue;
                }
                foreach ($results as $row) {
                    $linked_uploads = array();
                    // preg_match technique learned from http://stackoverflow.com/questions/138313/how-to-extract-img-src-title-and-alt-from-html-using-php
                    $tags = array('img' => array(), 'a' => array());
                    $content = $row->post_content;
                    preg_match_all('/<img[^>]+>/i', $row->post_content, $tags['img']);
                    preg_match_all('/<a[^>]+>/i', $row->post_content, $tags['a']);
                    // don't care that this will terminate with any enclosed tags (i.e. img)
                    foreach (array_keys($tags) as $tag_type) {
                        foreach ($tags[$tag_type]['0'] as $found_tag) {
                            $found_attribs = array('src' => '', 'href' => '', 'title' => '', 'alt' => '');
                            if (!preg_match_all('/(alt|title|src|href)=("[^"]*")/i', $found_tag, $tag_attributes)) {
                                continue;
                            }
                            foreach ($tag_attributes[1] as $key => $attrib_name) {
                                $found_attribs[$attrib_name] = trim($tag_attributes[2][$key], "'" . '"');
                            }
                            if (!$found_attribs['href'] && !$found_attribs['src']) {
                                continue;
                            }
                            $file_url = $found_attribs['src'] ? $found_attribs['src'] : $found_attribs['href'];
                            if (!strpos($file_url, '.')) {
                                continue;
                            }
                            if (MULTISITE && strpos($uploads['url'], 'blogs.dir')) {
                                $file_url = str_replace('/files/', "/wp-content/blogs.dir/{$blog_id}/files/", $file_url);
                            }
                            // links can't be registered as attachments unless they're in the WP uploads path
                            if (false === strpos($file_url, $upload_path)) {
                                if ($echo) {
                                    //printf( _ x( '<span class="rs-brown">skipping unfilterable file in %1$s "%2$s":</span> %3$s', 'post_type, post_title, file_url', 'scoper' ), __(ucwords($row->post_type)), $row->post_title, $file_url);
                                    printf(__('<span class="rs-brown">skipping unfilterable file in %1$s "%2$s":</span> %3$s', 'scoper'), __(ucwords($row->post_type)), $row->post_title, $file_url);
                                    echo '<br /><br />';
                                }
                                continue;
                            }
                            // make sure the linked file actually exists
                            if (!file_exists(str_replace($upload_path, $upload_dir, $file_url))) {
                                if ($echo) {
                                    //printf( _ x( '<span class="rs-brown">skipping unfilterable file in %1$s "%2$s":</span> %3$s', 'post_type, post_title, file_url', 'scoper' ), __(ucwords($row->post_type)), $row->post_title, $file_url);
                                    printf(__('<span class="rs-red">skipping missing file in %1$s "%2$s":</span> %3$s', 'scoper'), __(ucwords($row->post_type)), $row->post_title, $file_url);
                                    echo '<br /><br />';
                                }
                                continue;
                            }
                            $caption = $found_attribs['title'] ? $found_attribs['title'] : $found_attribs['alt'];
                            // we might find the same file sourced in both link and img tags
                            if (!isset($linked_uploads[$file_url]) || !$linked_uploads[$file_url]) {
                                $found_links++;
                                $linked_uploads[$file_url] = $caption;
                            }
                        }
                        // end foreach found tag
                    }
                    // end foreach loop on 'img' and 'a'
                    foreach ($linked_uploads as $file_url => $caption) {
                        $unsuffixed_file_url = preg_replace("/-[0-9]{2,4}x[0-9]{2,4}./", '.', $file_url);
                        $file_info = wp_check_filetype($unsuffixed_file_url);
                        if (!isset($stored_attachments[$row->ID][$unsuffixed_file_url])) {
                            $att = array();
                            $att['guid'] = $unsuffixed_file_url;
                            $info = pathinfo($unsuffixed_file_url);
                            if (isset($info['filename'])) {
                                $att['post_name'] = $info['filename'];
                                $att['post_title'] = $info['filename'];
                            }
                            $att['post_excerpt'] = $caption;
                            $att['post_author'] = $row->post_author;
                            $att['post_parent'] = $row->ID;
                            $att['post_category'] = wp_get_post_categories($row->ID);
                            if (isset($file_info['type'])) {
                                $att['post_mime_type'] = $file_info['type'];
                            }
                            $num_inserted++;
                            if ($echo) {
                                printf(__('<span class="rs-green"><strong>new attachment</strong> in %1$s "%2$s":</span> %3$s', 'scoper'), __(ucwords($row->post_type)), $row->post_title, $file_url);
                            }
                            //printf(_ x( '<span class="rs-green"><strong>new attachment</strong> in %1$s "%2$s":</span> %3$s', 'post_type, post_title, file_url', 'scoper' ), __(ucwords($row->post_type)), $row->post_title, $file_url);
                            wp_insert_attachment($att);
                        } else {
                            if ($echo) {
                                printf(__('<span class="rs-blue">attachment OK in %1$s "%2$s":</span> %3$s', 'scoper'), __(ucwords($row->post_type)), $row->post_title, $file_url);
                            }
                            //printf(_ x( '<span class="rs-blue">attachment OK in %1$s "%2$s":</span> %3$s', 'post_type, post_title, file_url', 'scoper' ), __(ucwords($row->post_type)), $row->post_title, $file_url);
                        }
                        if ($echo) {
                            echo '<br /><br />';
                        }
                    }
                    // end foreach linked_uploads
                }
                // end foreach post in this bite
            }
            // endif for each 10-post bite
            if ($echo) {
                echo '<strong>';
                printf(__("Operation complete: %s linked uploads were found in your post / page content.", 'scoper'), $found_links);
                echo '<br /><br />';
                if ($num_inserted) {
                    printf(__('<strong>%s attachment records were added to the database.</strong>', 'scoper'), $num_inserted);
                    echo '<br /><br />';
                } elseif ($found_links) {
                    _e('All linked uploads are already registered as attachments.', 'scoper');
                    echo '<br /><br />';
                }
            }
        }
        if (count($blog_ids) > 1) {
            echo '<hr />';
        }
    }
    // end foreach site
    if (count($blog_ids) > 1) {
        switch_to_blog($orig_blog_id);
    }
    return true;
}
 function clear_restrictions($scope, $src_or_tx_name, $obj_or_term_id, $args = array())
 {
     $defaults = array('inherited_only' => false, 'clear_propagated' => false);
     $args = array_merge($defaults, (array) $args);
     extract($args);
     global $wpdb;
     $inherited_clause = $inherited_only ? "AND inherited_from > 0" : '';
     $qry = "SELECT requirement_id FROM {$wpdb->role_scope_rs} WHERE topic = '{$scope}' AND src_or_tx_name = '{$src_or_tx_name}' {$inherited_clause} AND obj_or_term_id = '{$obj_or_term_id}'";
     $req_ids = scoper_get_col($qry);
     if ($req_ids) {
         $qry = "DELETE FROM {$wpdb->role_scope_rs} WHERE requirement_id IN ('" . implode("', '", $req_ids) . "')";
         if ($clear_propagated) {
             $qry .= " OR inherited_from IN ('" . implode("', '", $req_ids) . "') ";
         }
         scoper_query($qry);
     }
 }
Exemplo n.º 21
0
function awp_query_descendant_ids($table_name, $col_id, $col_parent, $parent_id)
{
    global $wpdb;
    $descendant_ids = array();
    // todo: abstract this
    $type_clause = $table_name == $wpdb->posts ? "AND post_type != 'revision'" : '';
    $query = "SELECT {$col_id} FROM {$table_name} WHERE {$col_parent} = '{$parent_id}' {$type_clause}";
    if ($results = scoper_get_col($query)) {
        foreach ($results as $id) {
            if (!in_array($id, $descendant_ids)) {
                $descendant_ids[] = $id;
                $next_generation = awp_query_descendant_ids($table_name, $col_id, $col_parent, $id, $descendant_ids);
                $descendant_ids = array_merge($descendant_ids, $next_generation);
            }
        }
    }
    return $descendant_ids;
}
 function display_ui_group_roles($group_id)
 {
     $users = ScoperAdminLib::get_group_members($group_id, COL_ID_RS);
     $args = array('disable_user_roles' => true, 'filter_usergroups' => array($group_id => true), 'disable_wp_roles' => true);
     $user_id = $users ? $users[0] : 0;
     $user = new WP_Scoped_User($user_id, '', $args);
     if (!$users) {
         $user->groups = array($group_id => true);
     }
     if ($group = ScoperAdminLib::get_group($group_id)) {
         if (!strpos($group->meta_id, '_nr_')) {
             global $wpdb;
             echo '<div class="rs-group-profile">';
             if (IS_MU_RS && scoper_get_option('mu_sitewide_groups')) {
                 global $blog_id;
                 $blog_ids = scoper_get_col("SELECT blog_id FROM {$wpdb->blogs} ORDER BY blog_id");
                 $orig_blog_id = $blog_id;
             } else {
                 $blog_ids = array('1');
             }
             foreach ($blog_ids as $id) {
                 if (count($blog_ids) > 1) {
                     switch_to_blog($id);
                 }
                 if (!$wpdb->get_results("SHOW TABLES LIKE '{$wpdb->user2role2object_rs}'")) {
                     continue;
                 }
                 ScoperProfileUI::display_ui_user_roles($user, true);
                 //arg: groups only
             }
             echo '</div>';
             if (count($blog_ids) > 1) {
                 switch_to_blog($orig_blog_id);
             }
         }
     }
 }
Exemplo n.º 23
0
function scoper_object_roles_list($viewing_user, $args = array())
{
    $html = '';
    if (!USER_ROLES_RS && !GROUP_ROLES_RS) {
        wp_die(__awp('Cheatin&#8217; uh?'));
    }
    $defaults = array('enforce_duration_limits' => true, 'is_user_profile' => false, 'echo' => true);
    $args = array_merge($defaults, (array) $args);
    extract($args);
    global $scoper, $wpdb, $current_user;
    if ($viewing_user) {
        if (!is_object($viewing_user)) {
            global $current_rs_user;
            if ($viewing_user == $current_rs_user->ID) {
                $viewing_user = $current_rs_user;
            } else {
                $viewing_user = new WP_Scoped_User($viewing_user);
            }
        }
    }
    $all_roles = array();
    $role_display = array();
    foreach ($scoper->role_defs->get_all_keys() as $role_handle) {
        if ($viewing_user) {
            $role_display[$role_handle] = $scoper->role_defs->get_display_name($role_handle, OBJECT_UI_RS);
        } else {
            $role_display[$role_handle] = $scoper->role_defs->get_abbrev($role_handle, OBJECT_UI_RS);
        }
    }
    if (!$is_user_profile) {
        $require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only');
        if ('admin' === $require_blogwide_editor && !is_user_administrator_rs()) {
            return false;
        }
        if ('admin_content' === $require_blogwide_editor && !is_content_administrator_rs()) {
            return false;
        }
    } else {
        $require_blogwide_editor = false;
    }
    foreach ($scoper->data_sources->get_all() as $src_name => $src) {
        $otype_count = 0;
        if (!empty($src->taxonomy_only) || $src_name == 'group' && !$viewing_user) {
            continue;
        }
        $strict_objects = $scoper->get_restrictions(OBJECT_SCOPE_RS, $src_name);
        foreach ($src->object_types as $object_type => $otype) {
            $otype_count++;
            $disable_role_admin = false;
            if ($require_blogwide_editor) {
                if (!$scoper->user_can_edit_blogwide('post', $object_type, array('require_others_cap' => true))) {
                    $disable_role_admin = true;
                }
            }
            if (!empty($src->cols->type) && !empty($otype->name)) {
                $col_type = $src->cols->type;
                $otype_clause = "AND {$src->table}.{$col_type} = '{$otype->name}'";
            } elseif ($otype_count < 2) {
                $otype_clause = '';
            } else {
                continue;
            }
            $col_id = $src->cols->id;
            $col_name = $src->cols->name;
            $ug_clause_for_user_being_viewed = $viewing_user ? $viewing_user->get_user_clause('uro') : '';
            // TODO: replace join with uro subselect
            $qry = "SELECT DISTINCT {$src->table}.{$col_name}, {$src->table}.{$col_id}, uro.role_name, uro.date_limited, uro.start_date_gmt, uro.end_date_gmt" . " FROM {$src->table} ";
            $join = " 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'";
            $duration_clause = $enforce_duration_limits ? scoper_get_duration_clause("{$src->table}.{$src->cols->date}") : '';
            $status_clause = 'post' == $src_name ? "AND post_status != 'auto-draft'" : '';
            // TODO: version update script to delete post roles on auto-drafts (stored via default roles)
            $where = " WHERE 1=1 {$status_clause} {$otype_clause} {$duration_clause} {$ug_clause_for_user_being_viewed}";
            $orderby = " ORDER BY {$src->table}.{$col_name} ASC, uro.role_name ASC";
            $qry .= $join . $where . $orderby;
            $results = scoper_get_results($qry);
            if (!is_user_administrator_rs()) {
                // no need to filter admins - just query the assignments
                // only list role assignments which the logged-in user can administer
                $args['required_operation'] = OP_EDIT_RS;
                // Possible TODO: re-implement OP_ADMIN distinction with admin-specific capabilities
                /*
                if ( cr_get_reqd_caps( $src_name, OP_ADMIN_RS, $object_type ) {
                	$args['required_operation'] = OP_ADMIN_RS;
                } else {
                	$reqd_caps = array();
                	foreach (array_keys($src->statuses) as $status_name) {
                		$admin_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_ADMIN_RS, $status_name);
                		$delete_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_DELETE_RS, $status_name);
                		$reqd_caps[$object_type][$status_name] = array_merge(array_keys($admin_caps), array_keys($delete_caps));
                	}
                	$args['force_reqd_caps'] = $reqd_caps;
                }
                */
                $qry = "SELECT {$src->table}.{$col_id} FROM {$src->table} WHERE 1=1";
                $args['require_full_object_role'] = true;
                $qry_flt = apply_filters('objects_request_rs', $qry, $src_name, $object_type, $args);
                $cu_admin_results = scoper_get_col($qry_flt);
                if (empty($viewing_user) || $current_user->ID != $viewing_user->ID) {
                    foreach ($results as $key => $row) {
                        if (!in_array($row->{$col_id}, $cu_admin_results)) {
                            unset($results[$key]);
                        }
                    }
                } else {
                    // for current user's view of their own user profile, just de-link unadminable objects
                    $link_roles = array();
                    $link_objects = array();
                    if (!$disable_role_admin) {
                        foreach ($results as $key => $row) {
                            if (in_array($row->{$col_id}, $cu_admin_results)) {
                                $link_roles[$row->{$col_id}] = true;
                            }
                        }
                        $args['required_operation'] = OP_EDIT_RS;
                        $args['require_full_object_role'] = false;
                        if (isset($args['force_reqd_caps'])) {
                            unset($args['force_reqd_caps']);
                        }
                        $qry_flt = apply_filters('objects_request_rs', $qry, $src_name, $object_type, $args);
                        $cu_edit_results = scoper_get_col($qry_flt);
                        foreach ($results as $key => $row) {
                            if (in_array($row->{$col_id}, $cu_edit_results)) {
                                $link_objects[$row->{$col_id}] = true;
                            }
                        }
                    }
                }
            }
            $object_roles = array();
            $objnames = array();
            if ($results) {
                $got_object_roles = true;
                foreach ($results as $row) {
                    if (!isset($objnames[$row->{$col_id}])) {
                        if ('post' == $src->name) {
                            $objnames[$row->{$col_id}] = apply_filters('the_title', $row->{$col_name}, $row->{$col_id});
                        } else {
                            $objnames[$row->{$col_id}] = $row->{$col_name};
                        }
                    }
                    $role_handle = 'rs_' . $row->role_name;
                    if ($row->date_limited) {
                        $duration_key = serialize(array('start_date_gmt' => $row->start_date_gmt, 'end_date_gmt' => $row->end_date_gmt));
                    } else {
                        $duration_key = '';
                    }
                    $object_roles[$duration_key][$row->{$col_id}][$role_handle] = true;
                }
            } else {
                continue;
            }
            ?>

		
		<?php 
            $title_roles = __('edit roles', 'scoper');
            foreach (array_keys($object_roles) as $duration_key) {
                $date_caption = '';
                $limit_class = '';
                $limit_style = '';
                $link_class = '';
                if ($duration_key) {
                    $html .= "<h3 style='margin-bottom:0'>{$date_caption}</h3>";
                    $duration_limits = unserialize($duration_key);
                    $duration_limits['date_limited'] = true;
                    ScoperAdminUI::set_agent_formatting($duration_limits, $date_caption, $limit_class, $link_class, $limit_style);
                    $title = "title='{$date_caption}'";
                    $date_caption = '<span class="rs-gray"> ' . trim($date_caption) . '</span>';
                } else {
                    $title = "title='{$title_roles}'";
                }
                if (!$disable_role_admin && (is_user_administrator_rs() || $cu_admin_results)) {
                    //if ( ( $src_name != $object_type ) && ( 'post' != $object_type ) ) {  // menu links currently assume unique object type names
                    //	$roles_page = "rs-roles-{$object_type}_{$src_name}";
                    //} else {
                    $roles_page = "rs-{$object_type}-roles";
                    //}
                    $url = "admin.php?page={$roles_page}";
                    $html .= "<h4><a name='{$object_type}' href='{$url}'><strong>" . sprintf(__('%1$s Roles%2$s:', 'scoper'), $otype->labels->singular_name, '</strong></a><span style="font-weight:normal">' . $date_caption) . "</span></h4>";
                } else {
                    $html .= "<h4><strong>" . sprintf(__('%1$s Roles%2$s:', 'scoper'), $otype->labels->singular_name, $date_caption) . "</strong></h4>";
                }
                $html .= "<ul class='rs-termlist'><li>" . "<table class='widefat'>" . "<thead>" . "<tr class='thead'>" . "\t<th class='rs-tightcol'>" . __('ID') . "</th>" . "\t<th>" . __awp('Name') . "</th>" . "\t<th>" . __('Role Assignments', 'scoper') . "</th>" . "</tr>" . "</thead>";
                $id_clause = isset($role_codes[$role_handle]) ? "id='roles-{$role_codes[$role_handle]}'" : '';
                $html .= "<tbody {$id_clause}>";
                $style = ' class="rs-backwhite"';
                $title_item = sprintf(__('edit %s', 'scoper'), agp_strtolower($otype->labels->singular_name));
                foreach ($object_roles[$duration_key] as $obj_id => $roles) {
                    $object_name = esc_attr($objnames[$obj_id]);
                    $html .= "\n\t<tr{$style}>";
                    $link_this_object = !isset($link_objects) || isset($link_objects[$obj_id]);
                    // link from object ID to the object type's default editor, if defined
                    if ($link_this_object && !empty($src->edit_url)) {
                        $src_edit_url = sprintf($src->edit_url, $obj_id);
                        $html .= "<td><a href='{$src_edit_url}' class='edit' title='{$title_item}'>{$obj_id}</a></td>";
                    } else {
                        $html .= "<td>{$obj_id}</td>";
                    }
                    $name = !empty($objnames[$obj_id]) ? $objnames[$obj_id] : __('(untitled)', 'scoper');
                    // link from object name to our "Edit Object Role Assignment" interface
                    $link_this_role = !isset($link_roles) || isset($link_roles[$obj_id]);
                    if ($link_this_role) {
                        if ('group' == $object_type) {
                            $rs_edit_url = sprintf($src->edit_url, $obj_id);
                        } else {
                            $rs_edit_url = "admin.php?page=rs-object_role_edit&amp;src_name={$src_name}&amp;object_type={$object_type}&amp;object_id={$obj_id}&amp;object_name={$object_name}";
                        }
                        $html .= "\n\t<td><a {$title}{$limit_style}class='{$link_class}{$limit_class}' href='{$rs_edit_url}'>{$name}</a></td>";
                    } else {
                        $html .= "\n\t<td>{$name}</td>";
                    }
                    $html .= "<td>";
                    $role_list = array();
                    foreach (array_keys($roles) as $role_handle) {
                        // roles which require object assignment are asterisked (bolding would contradict the notation of term roles list, where propogating roles are bolded)
                        if (isset($strict_objects['restrictions'][$role_handle][$obj_id]) || isset($strict_objects['unrestrictions'][$role_handle]) && is_array($strict_objects['unrestrictions'][$role_handle]) && !isset($strict_objects['unrestrictions'][$role_handle][$obj_id])) {
                            $role_list[] = "<span class='rs-backylw'>" . $role_display[$role_handle] . '</span>';
                        } else {
                            $role_list[] = $role_display[$role_handle];
                        }
                    }
                    $html .= implode(', ', $role_list);
                    $html .= '</td></tr>';
                    $style = ' class="alternate"' == $style ? ' class="rs-backwhite"' : ' class="alternate"';
                }
                // end foreach object_roles
                $html .= '</tbody></table>';
                $html .= '</li></ul><br />';
            }
            // end foreach role date range
        }
        // end foreach object_types
    }
    // end foreach data source
    if ($echo) {
        echo $html;
    } else {
        return $html;
    }
}
function scoper_flt_page_parent($parent_id)
{
    if ('no_parent_filter' == scoper_get_option('lock_top_pages')) {
        return (int) $parent_id;
    }
    if (!empty($_REQUEST['post_ID'])) {
        $post_id = $_REQUEST['post_ID'];
    } elseif (!empty($_REQUEST['post_id'])) {
        $post_id = $_REQUEST['post_id'];
    } else {
        return (int) $parent_id;
    }
    if (!empty($post_id)) {
        if ($parent_id == $post_id) {
            // normal revision save
            return (int) $parent_id;
        }
    }
    if (defined('RVY_VERSION')) {
        global $revisionary;
        if (!empty($revisionary->admin->revision_save_in_progress)) {
            return (int) $parent_id;
        }
    }
    if (empty($_POST['post_type'])) {
        return (int) $parent_id;
    }
    // Make sure the selected parent is valid.  Merely an anti-hacking precaution to deal with manually fudged POST data
    global $scoper, $wpdb;
    $post_type = sanitize_key($_POST['post_type']);
    $plural_name = plural_name_from_cap_rs(get_post_type_object($post_type));
    $args = array();
    $args['alternate_reqd_caps'][0] = array("create_child_{$plural_name}");
    if ($descendant_ids = scoper_get_page_descendant_ids($post_id)) {
        $exclusion_clause = "AND ID NOT IN('" . implode("','", $descendant_ids) . "')";
    } else {
        $exclusion_clause = '';
    }
    $qry_parents = "SELECT ID FROM {$wpdb->posts} WHERE post_type = '{$post_type}' AND post_status != 'auto-draft' {$exclusion_clause}";
    $qry_parents = apply_filters('objects_request_rs', $qry_parents, 'post', $post_type, $args);
    $valid_parents = scoper_get_col($qry_parents);
    $post = get_post($post_id);
    if ($parent_id) {
        if ($post && !in_array($parent_id, $valid_parents)) {
            $parent_id = $post->post_parent;
        }
    } else {
        if (!$GLOBALS['scoper_admin_filters']->user_can_associate_main($post_type)) {
            $already_published = false;
            if ($post) {
                if ($saved_status_object = get_post_status_object($post->post_status)) {
                    $already_published = $saved_status_object->public || $saved_status_object->private;
                }
            }
            if ($already_published) {
                // If post was previously published to another parent, revert it
                $parent_id = $post->post_parent;
            } elseif ($valid_parents) {
                // otherwise default to a valid parent
                sort($valid_parents);
                $parent_id = reset($valid_parents);
                $_POST['parent_id'] = (int) $parent_id;
                // for subsequent post_status filter
            }
        }
    }
    return (int) $parent_id;
}
 function identify_protected_posts($attachment_id = 0, $attachments = false, $cols = '', $args = array())
 {
     $defaults = array('use_object_restrictions' => true, 'use_term_restrictions' => true, 'use_private_status' => true, 'guid' => '');
     $args = array_merge($defaults, (array) $args);
     extract($args);
     global $wpdb, $scoper;
     if (!isset($scoper) || is_null($scoper)) {
         scoper_get_init_options();
         scoper_init();
     }
     if (empty($scoper->taxonomies)) {
         $scoper->load_config();
     }
     $restricted_roles = array();
     $unrestricted_roles = array();
     // TODO: also protect uploads based on restriction of other taxonomies
     $restricted_terms = array();
     $restricted_objects = array();
     $term_restriction_clause = '';
     $object_restriction_clause = '';
     $limit_clause = '';
     $unattached_clause = '';
     global $scoper;
     $reader_roles = array();
     foreach ($scoper->role_defs->role_caps as $role_handle => $role_caps) {
         $caps_by_op = $scoper->cap_defs->organize_caps_by_op(array_keys($role_caps));
         if (count($caps_by_op) == 1 && 'read' == key($caps_by_op)) {
             $reader_roles[] = $role_handle;
         }
     }
     $role_clause = "AND rs.role_name IN ('" . implode("','", scoper_role_handles_to_names($reader_roles)) . "')";
     //if ( $use_private_status )
     //	$role_clause = ( 'rs' == SCOPER_ROLE_TYPE ) ? "AND rs.role_name IN ('post_reader', 'page_reader')" : '';	// if also checking for private status, don't need to check for restriction of private_reader roles
     //else
     //	$role_clause = ( 'rs' == SCOPER_ROLE_TYPE ) ? "AND rs.role_name IN ('post_reader', 'page_reader', 'private_post_reader', 'private_page_reader')" : '';
     if ($use_term_restrictions) {
         $term_restriction_query = "SELECT rs.obj_or_term_id AS term_id, rs.role_name, rs.max_scope FROM {$wpdb->role_scope_rs} AS rs " . "INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.taxonomy = rs.src_or_tx_name AND tt.taxonomy = 'category' AND tt.term_taxonomy_id = rs.obj_or_term_id " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('entity', 'both') AND rs.topic = 'term' {$role_clause}";
         $term_default_restriction_query = "SELECT rs.role_name FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('children', 'both') AND rs.topic = 'term' AND rs.max_scope = 'term' AND rs.src_or_tx_name = 'category' AND rs.obj_or_term_id = '0' {$role_clause}";
         $all_terms = array();
         $all_terms['category'] = $scoper->get_terms('category', false, COL_ID_RS);
         if ($results = scoper_get_results($term_restriction_query)) {
             foreach ($results as $row) {
                 if ('blog' == $row->max_scope) {
                     $unrestricted_roles['category'][$row->role_name][] = $row->term_id;
                 } else {
                     $restricted_roles['category'][$row->role_name][] = $row->term_id;
                 }
             }
         }
         // if there a role is default-restricted, mark all terms as restricted (may be unrestricted later)
         if ($results = scoper_get_col($term_default_restriction_query)) {
             foreach ($results as $role_name) {
                 if (isset($unrestricted_roles['category'][$role_name])) {
                     $default_restricted = array_diff($all_terms['category'], $unrestricted_roles['category'][$role_name]);
                 } else {
                     $default_restricted = $all_terms['category'];
                 }
                 if (isset($restricted_roles['category'][$role_name])) {
                     $restricted_roles['category'][$role_name] = array_unique(array_merge($restricted_roles['category'][$role_name], $default_restricted));
                 } else {
                     $restricted_roles['category'][$role_name] = $default_restricted;
                 }
             }
         }
         $restricted_terms['category'] = isset($restricted_roles['category']) ? agp_array_flatten($restricted_roles['category']) : array();
         if ($restricted_terms['category']) {
             $term_restriction_clause = "OR post_parent IN ( SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} " . "INNER JOIN {$wpdb->term_relationships} AS tr ON tr.object_id = {$wpdb->posts}.ID " . "WHERE tr.term_taxonomy_id IN ('" . implode("','", $restricted_terms['category']) . "') )";
         }
     }
     if ($attachment_id) {
         if (is_array($attachment_id)) {
             $id_clause = "AND ID IN ('" . implode("','", $attachment_id) . "')";
         } else {
             $id_clause = "AND ID = '{$attachment_id}'";
             $limit_clause = 'LIMIT 1';
         }
     } elseif ($guid) {
         $id_clause = "AND guid = '{$file_path}'";
     } else {
         $id_clause = '';
     }
     if (defined('SCOPER_NO_THUMBNAIL_FILTER')) {
         if ($thumbnail_ids = scoper_get_col("SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_thumbnail_id'")) {
             $id_clause .= " AND ID NOT IN ('" . implode("','", $thumbnail_ids) . "')";
         }
     }
     if ($attachments) {
         // to reduce pool of objects, we only care about those that have an attachment
         $attachment_query = "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE {$wpdb->posts}.ID IN ( SELECT post_parent FROM {$wpdb->posts} WHERE post_type = 'attachment' {$id_clause} ) ";
     }
     if ($use_object_restrictions) {
         $object_restriction_query = "SELECT rs.obj_or_term_id AS obj_id, rs.role_name, rs.max_scope FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('entity', 'both') AND rs.topic = 'object' AND rs.src_or_tx_name = 'post' {$role_clause} AND rs.obj_or_term_id IN ( {$attachment_query} )";
         $object_default_restriction_query = "SELECT rs.role_name FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.require_for IN ('children', 'both') AND rs.topic = 'object' AND rs.max_scope = 'object' AND rs.src_or_tx_name = 'post' AND rs.obj_or_term_id = '0' {$role_clause}";
         $all_objects = array();
         $all_objects['post'] = scoper_get_col($attachment_query);
         $restricted_roles = array();
         $unrestricted_roles = array();
         if ($results = scoper_get_results($object_restriction_query)) {
             foreach ($results as $row) {
                 if ('blog' == $row->max_scope) {
                     $unrestricted_roles['post'][$row->role_name][] = $row->obj_id;
                 } else {
                     $restricted_roles['post'][$row->role_name][] = $row->obj_id;
                 }
             }
         }
         // if there a role is default-restricted, mark all terms as restricted (may be unrestricted later)
         if ($results = scoper_get_col($object_default_restriction_query)) {
             foreach ($results as $role_name) {
                 if (isset($unrestricted_roles['category'][$role_name])) {
                     $default_restricted = array_diff($all_terms['post'], $unrestricted_roles['post'][$role_name]);
                 } else {
                     $default_restricted = $all_objects['post'];
                 }
                 if (isset($restricted_roles['post'][$role_name])) {
                     $restricted_roles['post'][$role_name] = array_unique(array_merge($restricted_roles['post'][$role_name], $default_restricted));
                 } else {
                     $restricted_roles['post'][$role_name] = $default_restricted;
                 }
             }
         }
         if (!empty($restricted_roles)) {
             $restricted_objects['post'] = array_unique(agp_array_flatten($restricted_roles['post']));
             if ($restricted_objects['post']) {
                 $object_restriction_clause = "OR post_parent IN ( SELECT ID FROM {$wpdb->posts} WHERE ID IN ('" . implode("','", $restricted_objects['post']) . "') )";
             }
         }
     }
     if ($use_private_status) {
         $status_query = "AND post_parent IN ( SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_status = 'private' )";
     }
     if ($attachments) {
         $attachment_type_clause = "post_type = 'attachment' AND";
         $unattached_clause = defined('SCOPER_BLOCK_UNATTACHED_UPLOADS') ? " OR post_parent < 1" : '';
     }
     $single_col = false;
     if (COLS_ALL_RS === $cols) {
         $query_cols = '*';
     } elseif (COL_ID_RS == $cols) {
         $query_cols = 'ID';
         $single_col = true;
     } elseif (COLS_ID_DISPLAYNAME_RS == $cols) {
         if ($attachment) {
             $query_cols = 'ID, post_title, guid';
         } else {
             $query_cols = 'ID, post_title';
         }
     } else {
         if ($attachments) {
             $query_cols = 'ID, guid';
         } else {
             $query_cols = 'ID';
             $single_col = true;
         }
     }
     $query = "SELECT {$query_cols} FROM {$wpdb->posts} WHERE {$attachment_type_clause} ( 1=1 {$status_query} {$term_restriction_clause} {$object_restriction_clause} {$unattached_clause} ) {$id_clause} ORDER BY ID DESC {$limit_clause}";
     if ($attachment_id && !is_array($attachment_id)) {
         if ($single_col) {
             $results = scoper_get_var($query);
         } else {
             $results = scoper_get_row($query);
         }
     } else {
         if ($single_col) {
             $results = scoper_get_col($query);
         } else {
             $results = scoper_get_results($query);
         }
     }
     return $results;
 }
Exemplo n.º 26
0
 function get_groups_for_user($user_id, $args = array())
 {
     if (empty($args['status'])) {
         $status = 'active';
     } elseif ('any' == $args['status']) {
         $args['no_cache'] = true;
         $status = '';
     } else {
         $args['no_cache'] = true;
         $status = $args['status'];
     }
     if (empty($args['no_cache'])) {
         $cache = wpp_cache_get($user_id, 'group_membership_for_user');
         if (is_array($cache)) {
             return $cache;
         }
     }
     global $wpdb;
     if (!$wpdb->user2group_rs) {
         return array();
     }
     if (!$user_id) {
         // include WP metagroup for anonymous user
         return array_fill_keys(scoper_get_col("SELECT {$wpdb->groups_id_col} FROM {$wpdb->groups_rs} WHERE {$wpdb->groups_rs}.{$wpdb->groups_meta_id_col} = 'wp_anon'"), 'true');
     }
     $status_clause = $status ? "AND status = '{$status}'" : '';
     $query = "SELECT {$wpdb->user2group_gid_col} FROM {$wpdb->user2group_rs} WHERE {$wpdb->user2group_uid_col} = '{$user_id}' {$status_clause} ORDER BY {$wpdb->user2group_gid_col}";
     if (!($user_groups = scoper_get_col($query))) {
         $user_groups = array();
     }
     // include WP metagroup(s) for WP blogrole(s)
     $metagroup_ids = array();
     if (!empty($args['metagroup_roles'])) {
         foreach (array_keys($args['metagroup_roles']) as $role_handle) {
             $metagroup_ids[] = 'wp_role_' . str_replace('wp_', '', $role_handle);
         }
     }
     if ($metagroup_ids) {
         $meta_id_in = "'" . implode("', '", $metagroup_ids) . "'";
         $query = "SELECT {$wpdb->groups_id_col} FROM {$wpdb->groups_rs}" . " WHERE {$wpdb->groups_rs}.{$wpdb->groups_meta_id_col} IN ({$meta_id_in})" . " ORDER BY {$wpdb->groups_id_col}";
         if ($meta_groups = scoper_get_col($query)) {
             $user_groups = array_merge($user_groups, $meta_groups);
         }
     }
     if ($user_groups && empty($args['no_cache'])) {
         // users should always be in at least a metagroup.  Problem with caching empty result on user creation beginning with WP 2.8
         $user_groups = array_fill_keys($user_groups, 1);
         wpp_cache_set($user_id, $user_groups, 'group_membership_for_user');
     }
     return $user_groups;
 }