示例#1
0
 function get_page_ancestors()
 {
     $ancestors = get_option("scoper_page_ancestors");
     if (is_array($ancestors)) {
         return $ancestors;
     }
     $ancestors = array();
     global $wpdb;
     if (awp_ver('3.0')) {
         $post_types = get_post_types(array('hierarchical' => true, 'public' => true));
         $where = "WHERE post_type IN ('" . implode("','", $post_types) . "') AND post_status != 'auto-draft'";
     } else {
         $where = "WHERE post_type != 'revision' AND post_type != 'post' AND post_status != 'auto-draft'";
     }
     if ($pages = scoper_get_results("SELECT ID, post_parent FROM {$wpdb->posts} {$where}")) {
         $parents = array();
         foreach ($pages as $page) {
             if ($page->post_parent) {
                 $parents[$page->ID] = $page->post_parent;
             }
         }
         foreach ($pages as $page) {
             $ancestors[$page->ID] = ScoperAncestry::_walk_ancestors($page->ID, array(), $parents);
             if (empty($ancestors[$page->ID])) {
                 unset($ancestors[$page->ID]);
             }
         }
         update_option("scoper_page_ancestors", $ancestors);
     }
     return $ancestors;
 }
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;
}
示例#3
0
 function get_user_level($user_ids)
 {
     static $user_levels;
     $return_array = is_array($user_ids);
     // if an array was passed in, return results as an array
     if (!is_array($user_ids)) {
         if (IS_MU_RS && function_exists('is_super_admin') && is_super_admin()) {
             // mu site administrator may not be a user for the current blog
             return 10;
         }
         $orig_user_id = $user_ids;
         $user_ids = (array) $user_ids;
     }
     if (!isset($user_levels)) {
         $user_levels = array();
     }
     if (array_diff($user_ids, array_keys($user_levels))) {
         // one or more of the users were not already logged
         $role_levels = ScoperUserEdit::get_role_levels();
         // local buffer for performance
         // If the listed user ids were logged following a search operation, save extra DB queries by getting the levels of all those users now
         global $wp_user_search;
         if (!empty($wp_user_search->results)) {
             $query_users = $wp_user_search->results;
             $query_users = array_unique(array_merge($query_users, $user_ids));
         } else {
             $query_users = $user_ids;
         }
         // get the WP roles for user
         global $wpdb;
         $results = scoper_get_results("SELECT user_id, role_name FROM {$wpdb->user2role2object_rs} WHERE scope = 'blog' AND role_type = 'wp' AND user_id IN ('" . implode("','", array_map('intval', $query_users)) . "')");
         //echo("SELECT user_id, role_name FROM $wpdb->user2role2object_rs WHERE scope = 'blog' AND role_type = 'wp' AND user_id IN ('" . implode( "','", $query_users ) . "')");
         // credit each user for the highest role level they have
         foreach ($results as $row) {
             if (!isset($role_levels[$row->role_name])) {
                 continue;
             }
             if (!isset($user_levels[$row->user_id]) || $role_levels[$row->role_name] > $user_levels[$row->user_id]) {
                 $user_levels[$row->user_id] = $role_levels[$row->role_name];
             }
         }
         // note any "No Role" users
         if ($no_role_users = array_diff($query_users, array_keys($user_levels))) {
             $user_levels = $user_levels + array_fill_keys($no_role_users, 0);
         }
     }
     if ($return_array) {
         $return = array_intersect_key($user_levels, array_fill_keys($user_ids, true));
     } else {
         $return = isset($user_levels[$orig_user_id]) ? $user_levels[$orig_user_id] : 0;
     }
     return $return;
 }
function scoper_apply_custom_default_options($options_var)
{
    global $wpdb, $scoper_options_sitewide;
    if ($results = scoper_get_results("SELECT meta_key, meta_value FROM {$wpdb->sitemeta} WHERE site_id = '{$wpdb->siteid}' AND meta_key LIKE 'scoper_default_%'")) {
        foreach ($results as $row) {
            $option_basename = str_replace('scoper_default_', '', $row->meta_key);
            if (!empty($scoper_options_sitewide[$option_basename])) {
                continue;
            }
            // custom defaults are only for blog-specific options
            if (isset($GLOBALS[$options_var][$option_basename])) {
                $GLOBALS[$options_var][$option_basename] = maybe_unserialize($row->meta_value);
            }
        }
    }
}
function scoper_fix_page_parent_recursion()
{
    global $wpdb;
    $arr_parent = array();
    $arr_children = array();
    if ($results = scoper_get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page'")) {
        foreach ($results as $row) {
            $arr_parent[$row->ID] = $row->post_parent;
            if (!isset($arr_children[$row->post_parent])) {
                $arr_children[$row->post_parent] = array();
            }
            $arr_children[$row->post_parent][] = $row->ID;
        }
        // if a page's parent is also one of its children, set parent to Main
        foreach ($arr_parent as $page_id => $parent_id) {
            if (isset($arr_children[$page_id]) && in_array($parent_id, $arr_children[$page_id])) {
                scoper_query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_parent = '0' WHERE ID = %d", $page_id));
            }
        }
    }
}
 function get_assigned_roles($scope, $role_basis, $src_or_tx_name, $args = array())
 {
     global $wpdb;
     $defaults = array('id' => false, 'ug_id' => 0, 'join' => '', 'role_handles' => '');
     $args = array_merge($defaults, (array) $args);
     extract($args);
     $id = is_string($id) ? (int) $id : $id;
     $ug_id = is_string($ug_id) ? (int) $ug_id : $ug_id;
     if (BLOG_SCOPE_RS == $scope) {
         return ScoperRoleAssignments::get_assigned_blog_roles($role_basis);
     }
     $roles = array();
     switch ($role_basis) {
         case ROLE_BASIS_USER:
             $col_ug_id = 'user_id';
             $ug_clause = $ug_id ? " AND user_id = '{$ug_id}'" : 'AND user_id > 0';
             break;
         case ROLE_BASIS_GROUPS:
             $col_ug_id = 'group_id';
             $ug_clause = $ug_id ? " AND group_id = '{$ug_id}'" : 'AND group_id > 0';
             break;
     }
     $id_clause = false === $id ? '' : "AND obj_or_term_id = '{$id}'";
     if ($role_handles) {
         if (!is_array($role_handles)) {
             $role_handles = (array) $role_handles;
         }
         $role_clause = $role_handles ? "AND role_name IN ('" . implode("', '", scoper_role_handles_to_names($role_handles)) . "')" : '';
     } else {
         $role_clause = '';
     }
     $qry = "SELECT {$col_ug_id}, obj_or_term_id, role_name, assign_for, assignment_id, inherited_from, date_limited, start_date_gmt, end_date_gmt, content_date_limited, content_min_date_gmt, content_max_date_gmt FROM {$wpdb->user2role2object_rs} AS uro " . "{$join} WHERE role_type = 'rs' {$role_clause} AND scope = %s AND src_or_tx_name = %s {$id_clause} {$ug_clause}";
     $results = scoper_get_results($wpdb->prepare($qry, $scope, $src_or_tx_name));
     foreach ($results as $role) {
         $role_handle = 'rs_' . $role->role_name;
         $roles[$role->obj_or_term_id][$role_handle][$role->{$col_ug_id}] = (array) $role;
     }
     return $roles;
 }
 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_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 flt_get_others_drafts($results)
 {
     global $wpdb, $current_user, $scoper;
     // buffer titles in case they were filtered previously
     $titles = scoper_get_property_array($results, 'ID', 'post_title');
     // WP 2.3 added pending status, but no new hook or hook argument
     $draft_query = strpos($wpdb->last_query, 'draft');
     $pending_query = strpos($wpdb->last_query, 'pending');
     if ($draft_query && $pending_query) {
         $status_clause = "AND ( post_status = 'draft' OR post_status = 'pending' )";
     } elseif ($draft_query) {
         $status_clause = "AND post_status = 'draft'";
     } else {
         $status_clause = "AND post_status = 'pending'";
     }
     $object_type = cr_find_post_type();
     if (!$object_type) {
         $object_type = 'post';
     }
     if (!($otype_val = $scoper->data_sources->member_property('post', 'object_types', $object_type, 'val'))) {
         $otype_val = $object_type;
     }
     $qry = "SELECT ID, post_title, post_author FROM {$wpdb->posts} WHERE post_type = '{$otype_val}' AND post_author != '{$current_user->ID}' {$status_clause}";
     $qry = apply_filters('objects_request_rs', $qry, 'post', '', '');
     $items = scoper_get_results($qry);
     // restore buffered titles in case they were filtered previously
     scoper_restore_property_array($items, $titles, 'ID', 'post_title');
     return $items;
 }
function scoper_retrieve_options($sitewide = false)
{
    global $wpdb;
    if ($sitewide) {
        global $scoper_site_options;
        $scoper_site_options = array();
        if ($results = scoper_get_results("SELECT meta_key, meta_value FROM {$wpdb->sitemeta} WHERE site_id = '{$wpdb->siteid}' AND meta_key LIKE 'scoper_%'")) {
            foreach ($results as $row) {
                $scoper_site_options[$row->meta_key] = $row->meta_value;
            }
        }
        $scoper_site_options = apply_filters('site_options_rs', $scoper_site_options);
        return $scoper_site_options;
    } else {
        global $scoper_blog_options;
        $scoper_blog_options = array();
        if ($results = scoper_get_results("SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE 'scoper_%'")) {
            foreach ($results as $row) {
                $scoper_blog_options[$row->option_name] = $row->option_value;
            }
        }
        $scoper_blog_options = apply_filters('options_rs', $scoper_blog_options);
        return $scoper_blog_options;
    }
}
function scoper_get_parent_roles($obj_or_term_id, $scope, $src_or_tx_name, $parent_id, $object_type = '')
{
    global $wpdb, $scoper;
    $role_clause = '';
    if (!$parent_id && OBJECT_SCOPE_RS == $scope) {
        // for default roles, need to distinguish between otype-specific roles
        // (note: this only works w/ RS role type. Default object roles are disabled for WP role type because we'd be stuck assigning all default roles to both post & page.)
        $src = $scoper->data_sources->get($src_or_tx_name);
        if (!empty($src->cols->type)) {
            if (!$object_type) {
                $object_type = cr_find_object_type($src_name, $object_id);
            }
            if ($object_type) {
                $role_defs = $scoper->role_defs->get_matching('rs', $src_or_tx_name, $object_type);
                if ($role_names = scoper_role_handles_to_names(array_keys($role_defs))) {
                    $role_clause = "AND role_type = 'rs' AND role_name IN ('" . implode("', '", $role_names) . "')";
                }
            }
        }
    }
    // Since this is a new object, propagate roles from parent (if any are marked for propagation)
    $qry = "SELECT * FROM {$wpdb->user2role2object_rs} WHERE scope = %s AND assign_for IN ('children', 'both') {$role_clause} AND src_or_tx_name = %s AND obj_or_term_id = %d ORDER BY role_type, role_name";
    $results = scoper_get_results($wpdb->prepare($qry, $scope, $src_or_tx_name, $parent_id));
    return $results;
}
 function restrict_roles($scope, $src_or_tx_name, $item_id, $roles, $args = array())
 {
     $defaults = array('implicit_removal' => false, 'is_auto_insertion' => false, 'force_flush' => false);
     $args = array_merge($defaults, (array) $args);
     extract($args);
     global $wpdb;
     $is_administrator = is_administrator_rs($src_or_tx_name, 'user');
     $delete_reqs = array();
     $role_change = false;
     $default_strict_modes = array(false);
     $strict_role_in = '';
     // for object restriction, handle auto-setting of equivalent object roles ( 'post reader' for 'private post reader', 'post author' for 'post editor' ).  There is no logical distinction between these roles where a single object is concerned.
     if (OBJECT_SCOPE_RS == $scope) {
         foreach (array_keys($roles) as $role_handle) {
             $equiv_role_handles = array();
             if ($objscope_equivalents = $this->scoper->role_defs->member_property($role_handle, 'objscope_equivalents')) {
                 foreach ($objscope_equivalents as $equiv_role_handle) {
                     if (!isset($roles[$equiv_role_handle])) {
                         // if the equiv role was set manually, leave it alone.  This would not be normal RS behavior
                         $roles[$equiv_role_handle] = $roles[$role_handle];
                     }
                 }
             }
         }
     }
     if ($item_id) {
         $default_restrictions = $this->scoper->get_default_restrictions($scope);
         $default_strict_roles = !empty($default_restrictions[$src_or_tx_name]) ? array_keys($default_restrictions[$src_or_tx_name]) : array();
         if ($default_strict_roles) {
             $strict_role_in = "'" . implode("', '", scoper_role_handles_to_names($default_strict_roles)) . "'";
             $default_strict_modes[] = true;
         }
     }
     foreach ($default_strict_modes as $default_strict) {
         $stored_reqs = array();
         $req_ids = array();
         if ($default_strict && $strict_role_in) {
             $role_clause = "AND role_name IN ({$strict_role_in})";
         } elseif ($strict_role_in) {
             $role_clause = "AND role_name NOT IN ({$strict_role_in})";
         } else {
             $role_clause = '';
         }
         // IMPORTANT: max_scope value determines whether we are inserting / updating RESTRICTIONS or UNRESTRICTIONS
         if (TERM_SCOPE_RS == $scope) {
             $query_max_scope = $default_strict ? 'blog' : 'term';
         } else {
             $query_max_scope = $default_strict ? 'blog' : 'object';
         }
         // Storage of 'blog' max_scope as object restriction does not eliminate any term restrictions.  It merely indicates, for data sources that are default strict, that this object does not restrict roles
         $qry = "SELECT requirement_id AS assignment_id, require_for AS assign_for, inherited_from, role_name FROM {$wpdb->role_scope_rs} WHERE topic = %s AND max_scope = %s" . " AND src_or_tx_name = %s AND obj_or_term_id = %d AND role_type = 'rs' {$role_clause}";
         if ($results = scoper_get_results($wpdb->prepare($qry, $scope, $query_max_scope, $src_or_tx_name, $item_id))) {
             foreach ($results as $key => $req) {
                 $role_handle = 'rs_' . $req->role_name;
                 if (OBJECT_SCOPE_RS == $scope && isset($is_objscope_equiv[$role_handle])) {
                     $role_handle = $is_objscope_equiv[$role_handle];
                 }
                 $stored_reqs[$role_handle] = array('assignment_id' => $req->assignment_id, 'assign_for' => $req->assign_for, 'inherited_from' => $req->inherited_from);
                 $req_ids[$role_handle][$req->assignment_id] = array();
             }
         }
         if (!$is_administrator) {
             $user_has_role = $this->_validate_assigner_roles($scope, $src_or_tx_name, $item_id, $roles);
         }
         if ($implicit_removal) {
             // Stored restrictions which are not mirrored in $roles will be deleted (along with their prodigy)
             foreach (array_keys($stored_reqs) as $role_handle) {
                 $max_scope = isset($roles[$role_handle]['max_scope']) ? $roles[$role_handle]['max_scope'] : false;
                 if ($max_scope != $query_max_scope) {
                     $delete_reqs = $delete_reqs + $req_ids[$role_handle];
                 }
             }
         }
         foreach ($roles as $role_handle => $setting) {
             if (!$is_administrator && empty($user_has_role[$role_handle])) {
                 continue;
             }
             if ($default_strict && !in_array($role_handle, $default_strict_roles)) {
                 continue;
             }
             if (!$default_strict && !empty($default_strict_roles) && in_array($role_handle, $default_strict_roles)) {
                 continue;
             }
             $max_scope = $setting['max_scope'];
             if ($max_scope != $query_max_scope) {
                 $require_for = REMOVE_ASSIGNMENT_RS;
             } elseif ($setting['for_item']) {
                 $require_for = $setting['for_children'] ? ASSIGN_FOR_BOTH_RS : ASSIGN_FOR_ENTITY_RS;
             } else {
                 $require_for = $setting['for_children'] ? ASSIGN_FOR_CHILDREN_RS : REMOVE_ASSIGNMENT_RS;
             }
             $update_require_for = array(ASSIGN_FOR_ENTITY_RS => array(), ASSIGN_FOR_CHILDREN_RS => array(), ASSIGN_FOR_BOTH_RS => array());
             $stored_req = isset($stored_reqs[$role_handle]) ? $stored_reqs[$role_handle] : array();
             $unused_byref_arg = '';
             $comparison = $this->_compare_role_settings($require_for, $stored_req, $delete_reqs, $update_require_for, $unused_byref_arg, $unused_byref_arg);
             $insert_restriction = $comparison['unset'] ? false : $require_for;
             // Mark assignment for propagation to child items (But don't do so on storage of default restriction to root item. Default restrictions are only applied at item creation.)
             $propagate_restriction = $item_id && isset($comparison['new_propagation']) ? $comparison['new_propagation'] : '';
             if ($comparison['role_change']) {
                 $role_change = true;
             }
             if (!empty($req_ids[$role_handle])) {
                 $id_in = "'" . implode("', '", array_keys($req_ids[$role_handle])) . "'";
                 // do this for each role prior to insert call because insert function will consider inherited_from value
                 foreach ($update_require_for as $require_for => $this_ass_ids) {
                     if ($this_ass_ids) {
                         $id_in = "'" . implode("', '", $this_ass_ids) . "'";
                         $qry = "UPDATE {$wpdb->role_scope_rs} SET require_for = '{$require_for}', inherited_from = '0' WHERE requirement_id IN ({$id_in})";
                         scoper_query($qry);
                         if ('entity' == $require_for) {
                             // If a parent restriction is changed from "both" or "children" to "entity", delete propagated restrictions
                             $qry = "DELETE FROM {$wpdb->role_scope_rs} WHERE inherited_from IN ({$id_in})";
                             scoper_query($qry);
                         }
                     }
                 }
             }
             if ($insert_restriction || $propagate_restriction) {
                 $this->insert_role_restrictions($scope, $max_scope, $role_handle, $src_or_tx_name, $item_id, $insert_restriction, $propagate_restriction, $args);
             }
         }
         // end foreach roles
     }
     // delete assignments; flush user,group results cache
     if ($role_change || !empty($delete_reqs) || $update_require_for || $force_flush) {
         $this->role_restriction_aftermath($scope, $delete_reqs);
         if (!$item_id) {
             $this->scoper->default_restrictions = array();
         }
     }
     // possible TODO: reinstate this after further testing
     //$this->delete_orphan_restrictions($scope, $src_or_tx_name);
 }
 function dropdown_pages($object_id = '', $stored_parent_id = '')
 {
     global $scoper, $wpdb;
     // buffer titles in case they are filtered on get_pages hook
     $titles = ScoperAdminBulkParent::get_page_titles();
     if (!is_numeric($object_id)) {
         global $post_ID;
         if (empty($post_ID)) {
             $object_id = $scoper->data_sources->detect('id', 'post', 0, 'post');
         } else {
             $object_id = $post_ID;
         }
     }
     if ($object_id && !is_numeric($stored_parent_id)) {
         $stored_parent_id = $scoper->data_sources->detect('parent', 'post', $object_id);
     }
     // make sure the currently stored parent page remains in dropdown regardless of current user roles
     if ($stored_parent_id) {
         $preserve_or_clause = " {$wpdb->posts}.ID = '{$stored_parent_id}' ";
         $args['preserve_or_clause'] = array();
         foreach (array_keys($scoper->data_sources->member_property('post', 'statuses')) as $status_name) {
             $args['preserve_or_clause'][$status_name] = $preserve_or_clause;
         }
     }
     // alternate_caps is a 2D array because objects_request / objects_where filter supports multiple alternate sets of qualifying caps
     $args['force_reqd_caps']['page'] = array();
     foreach (array_keys($scoper->data_sources->member_property('post', 'statuses')) as $status_name) {
         $args['force_reqd_caps']['page'][$status_name] = array('edit_others_pages');
     }
     $args['alternate_reqd_caps'][0] = array('create_child_pages');
     $all_pages_by_id = array();
     if ($results = scoper_get_results("SELECT ID, post_parent, post_title FROM {$wpdb->posts} WHERE post_type = 'page'")) {
         foreach ($results as $row) {
             $all_pages_by_id[$row->ID] = $row;
         }
     }
     $object_type = awp_post_type_from_uri();
     // Editable / associable draft and pending pages will be included in Page Parent dropdown in Edit Forms, but not elsewhere
     if (is_admin() && 'page' != $object_type) {
         $status_clause = "AND {$wpdb->posts}.post_status IN ('publish', 'private')";
     } else {
         $status_clause = "AND {$wpdb->posts}.post_status IN ('publish', 'private', 'pending', 'draft')";
     }
     $qry_parents = "SELECT ID, post_parent, post_title FROM {$wpdb->posts} WHERE post_type = 'page' {$status_clause} ORDER BY menu_order";
     $qry_parents = apply_filters('objects_request_rs', $qry_parents, 'post', 'page', $args);
     $filtered_pages_by_id = array();
     if ($results = scoper_get_results($qry_parents)) {
         foreach ($results as $row) {
             $filtered_pages_by_id[$row->ID] = $row;
         }
     }
     $hidden_pages_by_id = array_diff_key($all_pages_by_id, $filtered_pages_by_id);
     // temporarily add in the hidden parents so we can order the visible pages by hierarchy
     $pages = ScoperAdminBulkParent::add_missing_parents($filtered_pages_by_id, $hidden_pages_by_id, 'post_parent');
     // convert keys from post ID to title+ID so we can alpha sort them
     $args['pages'] = array();
     foreach (array_keys($pages) as $id) {
         $args['pages'][$pages[$id]->post_title . chr(11) . $id] = $pages[$id];
     }
     // natural case alpha sort
     uksort($args['pages'], "strnatcasecmp");
     $args['pages'] = ScoperAdminBulkParent::order_by_hierarchy($args['pages'], 'ID', 'post_parent');
     // take the hidden parents back out
     foreach ($args['pages'] as $key => $page) {
         if (isset($hidden_pages_by_id[$page->ID])) {
             unset($args['pages'][$key]);
         }
     }
     $output = '';
     // restore buffered titles in case they were filtered on get_pages hook
     scoper_restore_property_array($args['pages'], $titles, 'ID', 'post_title');
     if ($object_id) {
         $args['object_id'] = $object_id;
         $args['retain_page_ids'] = true;
         // retain static log to avoid redundant entries by subsequent call with use_parent_clause=false
         ScoperHardwayParentLegacy::walk_parent_dropdown($output, $args, true, $stored_parent_id);
     }
     // next we'll add disjointed branches, but don't allow this page's descendants to be offered as a parent
     $arr_parent = array();
     $arr_children = array();
     if ($results = scoper_get_results("SELECT ID, post_parent FROM {$wpdb->posts} WHERE post_type = 'page' {$status_clause}")) {
         foreach ($results as $row) {
             $arr_parent[$row->ID] = $row->post_parent;
             if (!isset($arr_children[$row->post_parent])) {
                 $arr_children[$row->post_parent] = array();
             }
             $arr_children[$row->post_parent][] = $row->ID;
         }
         $descendants = array();
         if (!empty($arr_children[$object_id])) {
             foreach ($arr_parent as $page_id => $parent_id) {
                 if (!$parent_id || $page_id == $object_id) {
                     continue;
                 }
                 do {
                     if ($object_id == $parent_id) {
                         $descendants[$page_id] = true;
                         break;
                     }
                     $parent_id = $arr_parent[$parent_id];
                 } while ($parent_id);
             }
         }
         $args['descendants'] = $descendants;
     }
     ScoperHardwayParentLegacy::walk_parent_dropdown($output, $args, false, $stored_parent_id);
     //log_mem_usage_rs( 'end dropdown_pages()' );
     return $output;
 }
 function load_roles($src_name, $object_type, $object_id)
 {
     //log_mem_usage_rs( 'start ItemRolesUI::load_roles()' );
     if ('edit.php' == $GLOBALS['pagenow']) {
         return;
     }
     if (!scoper_get_otype_option('use_object_roles', $src_name, $object_type)) {
         return;
     }
     if (!($src = $this->scoper->data_sources->get($src_name))) {
         return;
     }
     $this->loaded_src_name = $src_name;
     $this->loaded_object_type = $object_type;
     $this->loaded_object_id = $object_id;
     $this->indicate_blended_roles = scoper_get_option('indicate_blended_roles');
     $this->all_agents = array();
     $this->agent_captions = array();
     $this->agent_captions_plural = array();
     $this->eligible_agent_ids = array();
     // note: if object_id = 0, default roles will be retrieved
     $get_defaults = !$object_id;
     $obj_roles = array();
     $role_defs = $this->scoper->role_defs->get_matching('rs', $src_name, $object_type);
     $this->role_handles = array_keys($role_defs);
     // for default roles, distinguish between various object types
     $filter_role_handles = $object_id ? '' : array_keys($role_defs);
     if (GROUP_ROLES_RS) {
         $this->current_roles[ROLE_BASIS_GROUPS] = ScoperRoleAssignments::organize_assigned_roles(OBJECT_SCOPE_RS, $src_name, $object_id, $filter_role_handles, ROLE_BASIS_GROUPS, $get_defaults);
     }
     //log_mem_usage_rs( 'load_roles: organize_assigned_roles for groups' );
     if (USER_ROLES_RS) {
         $this->current_roles[ROLE_BASIS_USER] = ScoperRoleAssignments::organize_assigned_roles(OBJECT_SCOPE_RS, $src_name, $object_id, $filter_role_handles, ROLE_BASIS_USER, $get_defaults);
     }
     //log_mem_usage_rs( 'load_roles: organize_assigned_roles for users' );
     if (GROUP_ROLES_RS) {
         $this->all_groups = ScoperAdminLib::get_all_groups(UNFILTERED_RS);
         //log_mem_usage_rs( 'load_roles: get_all_groups' );
         if (!empty($this->all_groups)) {
             $this->agent_captions[ROLE_BASIS_GROUPS] = __('Group', 'scoper');
             $this->agent_captions_plural[ROLE_BASIS_GROUPS] = __('Groups', 'scoper');
             $this->all_agents[ROLE_BASIS_GROUPS] = $this->all_groups;
             $this->all_agents[ROLE_BASIS_GROUPS] = $this->all_groups;
         }
         //log_mem_usage_rs( 'load_roles: set all_groups properties' );
     }
     if (USER_ROLES_RS) {
         $this->agent_captions[ROLE_BASIS_USER] = __('User', 'scoper');
         $this->agent_captions_plural[ROLE_BASIS_USER] = __awp('Users');
         // note: all users are eligible for a reading role assignment, but we may not be displaying user checkboxes
         $user_csv_input = scoper_get_option("user_role_assignment_csv");
         if (!$user_csv_input) {
             $this->all_agents[ROLE_BASIS_USER] = $this->scoper->users_who_can('', COLS_ID_NAME_RS);
         } elseif ($object_id) {
             $assignees = array();
             if ($this->current_roles[ROLE_BASIS_USER]) {
                 foreach (array_keys($this->current_roles[ROLE_BASIS_USER]) as $role_handle) {
                     $assignees = array_merge($assignees, array_keys($this->current_roles[ROLE_BASIS_USER][$role_handle]['assigned']));
                 }
             }
             $assignees = array_unique($assignees);
             global $wpdb;
             $this->all_agents[ROLE_BASIS_USER] = scoper_get_results("SELECT ID, display_name FROM {$wpdb->users} WHERE ID IN ('" . implode("','", $assignees) . "')");
         } else {
             $this->all_agents[ROLE_BASIS_USER] = array();
         }
         //log_mem_usage_rs( 'load_roles: users_who_can for all_agents' );
         //users eligible for an editing role assignments are those who have the basic edit cap via taxonomy or blog role
         if (scoper_get_otype_option('limit_object_editors', $src_name, $object_type)) {
             // Limit eligible page contribs/editors based on blog ownership of "edit_posts"
             // Otherwise, since pages are generally not categorized, only Blog Editors and Admins are eligible for object role ass'n
             // It's more useful to exclude Blog Subscribers while including all others
             $role_object_type = 'page' == $object_type ? 'post' : $object_type;
             $reqd_caps = $this->scoper->cap_defs->get_matching($src_name, $role_object_type, OP_EDIT_RS, '', BASE_CAPS_RS);
             // status-specific and 'others' caps will not be returned
             $args = array('ignore_strict_terms' => true, 'ignore_group_roles' => true, 'skip_object_roles' => true);
             $this->eligible_agent_ids[ROLE_BASIS_USER][OP_EDIT_RS] = $this->scoper->users_who_can(array_keys($reqd_caps), COL_ID_RS, '', 0, $args);
             //log_mem_usage_rs( 'load_roles: users_who_can for eligible_agent_ids' );
         }
     }
     $this->blog_term_roles = array();
     // Pull object and blog/term role assignments for all roles
     // Do this first so contained / containing roles can be accounted for in UI
     foreach ($role_defs as $role_handle => $role_def) {
         if ($this->indicate_blended_roles && isset($role_def->valid_scopes[OBJECT_SCOPE_RS])) {
             // might need to check term/blog assignment of a different role to reflect object's current status
             if (!empty($role_def->other_scopes_check_role) && !empty($src->cols->status)) {
                 $status = $this->scoper->data_sources->detect('status', $src, $object_id);
                 if (isset($role_def->other_scopes_check_role[$status])) {
                     $blog_term_role_handle = $role_def->other_scopes_check_role[$status];
                 } elseif (isset($role_def->other_scopes_check_role[''])) {
                     $blog_term_role_handle = $role_def->other_scopes_check_role[''];
                 } else {
                     $blog_term_role_handle = $role_handle;
                 }
             } else {
                 $blog_term_role_handle = $role_handle;
             }
             $this_args = array('skip_object_roles' => true, 'object_type' => $object_type, 'ignore_group_roles' => true);
             if (empty($user_csv_input)) {
                 $this->blog_term_roles[ROLE_BASIS_USER][$role_handle] = $this->scoper->users_who_can($blog_term_role_handle, COL_ID_RS, $src_name, $object_id, $this_args);
                 //log_mem_usage_rs( "load_roles: users_who_can for $role_handle users" );
             } else {
                 $this->blog_term_roles[ROLE_BASIS_USER][$role_handle] = array();
             }
             $this->blog_term_roles[ROLE_BASIS_GROUPS][$role_handle] = $this->scoper->groups_who_can($blog_term_role_handle, COL_ID_RS, $src_name, $object_id, $this_args);
             //log_mem_usage_rs( "load_roles: groups_who_can for $role_handle groups" );
         }
     }
     $this->do_propagation_cboxes = !empty($src->cols->parent) && !$this->scoper->data_sources->member_property($src_name, 'object_types', $object_type, 'ignore_object_hierarchy');
     $this->object_strict_roles = array();
     $this->child_strict_roles = array();
     $args = array('id' => $object_id, 'include_child_restrictions' => true);
     if ($restrictions = $this->scoper->get_restrictions(OBJECT_SCOPE_RS, $src_name, $args)) {
         //log_mem_usage_rs( "load_roles: get_restrictions" );
         foreach ($this->role_handles as $role_handle) {
             // defaults for this role
             if (isset($restrictions['unrestrictions'][$role_handle]) && is_array($restrictions['unrestrictions'][$role_handle])) {
                 $this->object_strict_roles[$role_handle] = true;
                 $this->child_strict_roles[$role_handle] = true;
             } else {
                 $this->object_strict_roles[$role_handle] = false;
                 $this->child_strict_roles[$role_handle] = false;
             }
             // role is not default strict, and a restriction is set
             if (isset($restrictions['restrictions'][$role_handle][$object_id])) {
                 switch ($restrictions['restrictions'][$role_handle][$object_id]) {
                     case ASSIGN_FOR_ENTITY_RS:
                         $this->object_strict_roles[$role_handle] = true;
                         $this->child_strict_roles[$role_handle] = false;
                         break;
                     case ASSIGN_FOR_CHILDREN_RS:
                         $this->object_strict_roles[$role_handle] = false;
                         $this->child_strict_roles[$role_handle] = true;
                         break;
                     case ASSIGN_FOR_BOTH_RS:
                         $this->object_strict_roles[$role_handle] = true;
                         $this->child_strict_roles[$role_handle] = true;
                 }
                 // end switch
                 // role IS default strict, and no unrestriction is set
             } elseif (isset($restrictions['unrestrictions'][$role_handle][$object_id])) {
                 switch ($restrictions['unrestrictions'][$role_handle][$object_id]) {
                     case ASSIGN_FOR_ENTITY_RS:
                         $this->object_strict_roles[$role_handle] = false;
                         $this->child_strict_roles[$role_handle] = true;
                         break;
                     case ASSIGN_FOR_CHILDREN_RS:
                         $this->object_strict_roles[$role_handle] = true;
                         $this->child_strict_roles[$role_handle] = false;
                         break;
                     case ASSIGN_FOR_BOTH_RS:
                         $this->object_strict_roles[$role_handle] = false;
                         $this->child_strict_roles[$role_handle] = false;
                 }
                 // end switch
             }
         }
         // end foreach Role Handle
     }
     //log_mem_usage_rs( 'end ItemRolesUI::load_roles()' );
 }
 function flt_get_terms($results, $taxonomies, $args)
 {
     global $wpdb;
     $empty_array = array();
     //d_echo( 'flt_get_terms input:' );
     $single_taxonomy = false;
     if (!is_array($taxonomies)) {
         $single_taxonomy = true;
         $taxonomies = array($taxonomies);
     } elseif (count($taxonomies) < 2) {
         $single_taxonomy = true;
     }
     // === END Role Scoper MODIFICATION ===
     foreach ((array) $taxonomies as $taxonomy) {
         if (!taxonomy_exists($taxonomy)) {
             // === BEGIN Role Scoper MODIFICATION: this caused plugin activation error in some situations (though at that time, the error object was created and return on a single line, not byRef as now) ===
             //
             //$error = & new WP_Error('invalid_taxonomy', __awp('Invalid Taxonomy'));
             //return $error;
             return array();
             //
             // === END Role Scoper MODIFICATION ===
         }
     }
     // === BEGIN Role Scoper ADDITION: global var; various special case exemption checks ===
     //
     global $scoper;
     if ($tx_obj = get_taxonomy($taxonomies[0])) {
         // don't require use_taxonomies setting for link_categories or other non-post taxonomies
         if (array_intersect($tx_obj->object_type, get_post_types(array('public' => true)))) {
             $use_taxonomies = scoper_get_option('use_taxonomies');
             if (empty($use_taxonomies[$taxonomy])) {
                 return $results;
             }
         }
     }
     // no backend filter for administrators
     $parent_or = '';
     if (is_admin() || defined('XMLRPC_REQUEST')) {
         if (is_content_administrator_rs()) {
             return $results;
         } else {
             if ($tx = $scoper->taxonomies->get($taxonomies[0])) {
                 // is a Category Edit form being displayed?
                 if (!empty($tx->uri_vars)) {
                     $term_id = $scoper->data_sources->detect('id', $tx);
                 } else {
                     $term_id = $scoper->data_sources->detect('id', $tx->source);
                 }
                 if ($term_id) {
                     // don't filter current parent category out of selection UI even if current user can't manage it
                     $parent_or = " OR t.term_id = (SELECT parent FROM {$wpdb->term_taxonomy} WHERE term_id = '{$term_id}') ";
                 }
             }
         }
     }
     // need to skip cache retrieval if QTranslate is filtering get_terms with a priority of 1 or less
     static $no_cache;
     if (!isset($no_cache)) {
         $no_cache = defined('SCOPER_NO_TERMS_CACHE') || !defined('SCOPER_QTRANSLATE_COMPAT') && awp_is_plugin_active('qtranslate');
     }
     // this filter currently only supports a single taxonomy for each get_terms call
     // (although the terms_where filter does support multiple taxonomies and this function could be made to do so)
     if (!$single_taxonomy) {
         return $results;
     }
     // link category roles / restrictions are only scoped for management (TODO: abstract this)
     if ($single_taxonomy && 'link_category' == $taxonomies[0] && $scoper->is_front()) {
         return $results;
     }
     // depth is not really a get_terms arg, but remap exclude arg to exclude_tree if wp_list_terms called with depth=1
     if (!empty($args['exclude']) && empty($args['exclude_tree']) && !empty($args['depth']) && 1 == $args['depth']) {
         $args['exclude_tree'] = $args['exclude'];
     }
     // don't offer to set a category as its own parent
     if ('edit-tags.php' == $GLOBALS['pagenow']) {
         if ($tx_obj->hierarchical) {
             if ($editing_cat_id = $scoper->data_sources->get_from_uri('id', 'term')) {
                 if (!empty($args['exclude'])) {
                     $args['exclude'] .= ',';
                 }
                 $args['exclude'] .= $editing_cat_id;
             }
         }
     }
     // we'll need this array in most cases, to support a disjointed tree with some parents missing (note alternate function call - was _get_term_hierarchy)
     $children = ScoperAncestry::get_terms_children($taxonomies[0]);
     //
     // === END Role Scoper ADDITION ===
     // =================================
     $in_taxonomies = "'" . implode("', '", $taxonomies) . "'";
     $defaults = array('orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'exclude' => '', 'exclude_tree' => '', 'include' => '', 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'pad_counts' => false, 'offset' => '', 'search' => '', 'skip_teaser' => false, 'depth' => 0, 'remap_parents' => -1, 'enforce_actual_depth' => -1, 'remap_thru_excluded_parent' => -1, 'post_type' => '');
     // Role Scoper arguments added above
     $args = wp_parse_args($args, $defaults);
     $args['number'] = (int) $args['number'];
     $args['offset'] = absint($args['offset']);
     $args['child_of'] = (int) $args['child_of'];
     // Role Scoper modification: null value will confuse children array check
     if (!$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' !== $args['parent']) {
         $args['child_of'] = 0;
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     if ('all' == $args['get']) {
         $args['child_of'] = 0;
         $args['hide_empty'] = 0;
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     extract($args, EXTR_SKIP);
     // === BEGIN Role Scoper MODIFICATION: use the $children array we already have ===
     //
     if ('nav-menus.php' == $GLOBALS['pagenow']) {
         if ('nav_menu' != $taxonomies[0]) {
             if (!scoper_get_option('admin_nav_menu_filter_items')) {
                 return $results;
             } else {
                 $hide_empty = 1;
             }
         }
     }
     if ($child_of && !isset($children[$child_of])) {
         return array();
     }
     if ($parent && !isset($children[$parent])) {
         return array();
     }
     if ($post_type && is_string($post_type)) {
         $post_type = explode(',', $post_type);
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     $is_term_admin = in_array($GLOBALS['pagenow'], array('edit-tags.php', 'edit-link-categories.php'));
     $filter_key = has_filter('list_terms_exclusions') ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
     $key = md5(serialize(compact(array_keys($defaults))) . serialize($taxonomies) . $filter_key);
     // === BEGIN Role Scoper MODIFICATION: cache key specific to access type and user/groups ===
     // support Quick Post Widget plugin
     if (isset($name) && 'quick_post_cat' == $name) {
         $required_operation = 'edit';
         $post_type = 'post';
         $remap_parents = true;
     } elseif (isset($name) && 'quick_post_new_cat_parent' == $name) {
         $is_term_admin = true;
         $required_operation = '';
         $remap_parents = true;
     } else {
         $required_operation = '';
     }
     $object_src_name = $scoper->taxonomies->member_property($taxonomies[0], 'object_source', 'name');
     $ckey = md5($key . serialize($scoper->get_terms_reqd_caps($taxonomies[0], $required_operation, $is_term_admin)));
     global $current_rs_user;
     $cache_flag = 'rs_get_terms';
     $cache = $current_rs_user->cache_get($cache_flag);
     if (false !== $cache) {
         if (!is_array($cache)) {
             $cache = array();
         }
         if (!$no_cache && isset($cache[$ckey])) {
             // RS Modification: alternate filter name (get_terms filter is already applied by WP)
             remove_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
             $terms = apply_filters('get_terms', $cache[$ckey], $taxonomies, $args);
             $terms = apply_filters('get_terms_rs', $terms, $taxonomies, $args);
             add_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
             return $terms;
         }
     }
     // buffer term names in case they were filtered previously
     if ('all' == $fields) {
         $term_names = scoper_get_property_array($results, 'term_id', 'name');
     }
     //
     // === END Role Scoper MODIFICATION ===
     // =====================================
     $_orderby = strtolower($orderby);
     if ('count' == $_orderby) {
         $orderby = 'tt.count';
     } else {
         if ('name' == $_orderby) {
             $orderby = 't.name';
         } else {
             if ('slug' == $_orderby) {
                 $orderby = 't.slug';
             } else {
                 if ('term_group' == $_orderby) {
                     $orderby = 't.term_group';
                 } else {
                     if ('none' == $_orderby) {
                         $orderby = '';
                         $order = '';
                     } else {
                         if (empty($_orderby) || 'id' == $_orderby) {
                             $orderby = 't.term_id';
                         } elseif ('order' == $_orderby) {
                             $orderby = 't.term_order';
                         } else {
                             $orderby = 't.name';
                         }
                     }
                 }
             }
         }
     }
     $orderby = apply_filters('get_terms_orderby', $orderby, $args);
     if (!empty($orderby)) {
         $orderby = "ORDER BY {$orderby}";
     }
     $where = '';
     // === Role Scoper MODIFICATION: if an include argument is provided, strip out non-matching terms after filtering is done. ===
     /*
     $inclusions = '';
     if ( !empty($include) ) {
     	$exclude = '';
     	$exclude_tree = '';
     	$interms = wp_parse_id_list($include);
     	if ( count($interms) ) {
     		foreach ( $interms as $interm ) {
     			if (empty($inclusions))
     				$inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
     			else
     				$inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
     		}
     	}
     }
     	
     if ( !empty($inclusions) )
     	$inclusions .= ')';
     $where .= $inclusions;
     */
     // === END Role Scoper MODIFICATION ===
     $exclusions = '';
     if (!empty($exclude_tree)) {
         // === BEGIN Role Scoper MODIFICATION: temporarily unhook this filter for unfiltered get_terms calls ===
         remove_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
         // === END Role Scoper MODIFICATION ===
         $excluded_trunks = wp_parse_id_list($exclude_tree);
         foreach ((array) $excluded_trunks as $extrunk) {
             $excluded_children = (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids'));
             $excluded_children[] = $extrunk;
             foreach ($excluded_children as $exterm) {
                 if (empty($exclusions)) {
                     $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
                 } else {
                     $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
                 }
             }
         }
         // === BEGIN Role Scoper MODIFICATION: re-hook this filter
         add_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
         // === END Role Scoper MODIFICATION ===
     }
     if (!empty($exclude)) {
         $exterms = wp_parse_id_list($exclude);
         foreach ($exterms as $exterm) {
             if (empty($exclusions)) {
                 $exclusions = ' AND ( t.term_id <> "' . intval($exterm) . '" ';
             } else {
                 $exclusions .= ' AND t.term_id <> "' . intval($exterm) . '" ';
             }
         }
     }
     if (!empty($exclusions)) {
         $exclusions .= ')';
     }
     // WPML attempts to pull taxonomy out of debug_backtrace() unless set in $_GET or $_POST; previous filter execution throws it off
     if (defined('ICL_SITEPRESS_VERSION') && !isset($_GET['taxonomy'])) {
         $_GET['taxonomy'] = current($taxonomies);
     }
     $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args);
     $where .= $exclusions;
     if (!empty($slug)) {
         $slug = sanitize_title($slug);
         $where .= " AND t.slug = '{$slug}'";
     }
     if (!empty($name__like)) {
         $where .= " AND t.name LIKE '{$name__like}%'";
     }
     if ('' !== $parent) {
         $parent = (int) $parent;
         // === BEGIN Role Scoper MODIFICATION: otherwise termroles only work if parent terms also have role
         if ($parent || 'ids' != $fields) {
             $where .= " AND tt.parent = '{$parent}'";
         }
         // === END Role Scoper MODIFICATION ===
     }
     // === BEGIN Role Scoper MODIFICATION: instead, manually remove truly empty cats at the bottom of this function, so we don't exclude cats with private but readable posts
     //if ( $hide_empty && !$hierarchical )
     //	$where .= ' AND tt.count > 0';
     // === END Role Scoper MODIFICATION ===
     // don't limit the query results when we have to descend the family tree
     if (!empty($number) && !$hierarchical && empty($child_of) && '' == $parent) {
         if ($offset) {
             $limit = 'LIMIT ' . $offset . ',' . $number;
         } else {
             $limit = 'LIMIT ' . $number;
         }
     } else {
         $limit = '';
     }
     if (!empty($search)) {
         $search = like_escape($search);
         $where .= " AND (t.name LIKE '%{$search}%')";
     }
     $selects = array();
     switch ($fields) {
         case 'all':
             $selects = array('t.*', 'tt.*');
             break;
         case 'ids':
         case 'id=>parent':
             $selects = array('t.term_id', 'tt.term_taxonomy_id', 'tt.parent', 'tt.count');
             break;
         case 'names':
             $selects = array('t.term_id', 'tt.term_taxonomy_id', 'tt.parent', 'tt.count', 't.name');
             break;
         case 'count':
             $orderby = '';
             $order = '';
             $selects = array('COUNT(*)');
     }
     $select_this = implode(', ', apply_filters('get_terms_fields', $selects, $args));
     // === BEGIN Role Scoper MODIFICATION: run the query through scoping filter
     //
     $query_base = "SELECT DISTINCT {$select_this} 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 IN ({$in_taxonomies}) {$where} {$parent_or} {$orderby} {$order} {$limit}";
     // only force application of scoped query filter if we're NOT doing a teaser
     if ('all' == $fields) {
         $do_teaser = $scoper->is_front() && empty($skip_teaser) && scoper_get_otype_option('do_teaser', 'post');
     } else {
         $do_teaser = false;
     }
     $query = apply_filters('terms_request_rs', $query_base, $taxonomies[0], array('skip_teaser' => !$do_teaser, 'is_term_admin' => $is_term_admin, 'required_operation' => $required_operation, 'post_type' => $post_type));
     // if no filering was applied because the teaser is enabled, prevent a redundant query
     if (!empty($exclude_tree) || $query_base != $query || $parent || 'all' != $fields) {
         $terms = scoper_get_results($query);
     } else {
         $terms = $results;
     }
     if ('count' == $fields) {
         $term_count = $wpdb->get_var($query);
         return $term_count;
     }
     if ('all' == $fields && empty($include)) {
         update_term_cache($terms);
     }
     // RS: don't cache an empty array, just in case something went wrong
     if (empty($terms)) {
         return array();
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     // === BEGIN Role Scoper ADDITION: Support a disjointed terms tree with some parents hidden
     //
     if ('all' == $fields) {
         $ancestors = ScoperAncestry::get_term_ancestors($taxonomy);
         // array of all ancestor IDs for keyed term_id, with direct parent first
         if ($parent > 0 || !$hierarchical) {
             // in Category Edit form, need to list all editable cats even if parent is not editable
             $remap_parents = false;
             $enforce_actual_depth = true;
             $remap_thru_excluded_parent = false;
         } else {
             // if these settings were passed into this get_terms call, use them
             if (is_admin()) {
                 $remap_parents = true;
             } else {
                 if (-1 === $remap_parents) {
                     $remap_parents = scoper_get_option('remap_term_parents');
                 }
                 if ($remap_parents) {
                     if (-1 === $enforce_actual_depth) {
                         $enforce_actual_depth = scoper_get_option('enforce_actual_term_depth');
                     }
                     if (-1 === $remap_thru_excluded_parent) {
                         $remap_thru_excluded_parent = scoper_get_option('remap_thru_excluded_term_parent');
                     }
                 }
             }
         }
         $remap_args = compact('child_of', 'parent', 'depth', 'orderby', 'remap_parents', 'enforce_actual_depth', 'remap_thru_excluded_parent');
         // one or more of these args may have been modified after extraction
         ScoperHardway::remap_tree($terms, $ancestors, 'term_id', 'parent', $remap_args);
     }
     //
     // === END Role Scoper ADDITION ===
     // ================================
     // === BEGIN Role Scoper MODIFICATION: call alternate functions
     // rs_tally_term_counts() replaces _pad_term_counts()
     // rs_get_term_descendants replaces _get_term_children()
     //
     if (($child_of || $hierarchical) && !empty($children)) {
         $terms = rs_get_term_descendants($child_of, $terms, $taxonomies[0]);
     }
     if (!$terms) {
         return array();
     }
     // Replace DB-stored term counts with actual number of posts this user can read.
     // In addition, without the rs_tally_term_counts call, WP will hide categories that have no public posts (even if this user can read some of the pvt posts).
     // Post counts will be incremented to include child categories only if $pad_counts is true
     if (!defined('XMLRPC_REQUEST') && in_array($fields, array('all', 'ids', 'names')) && !$is_term_admin) {
         if (!is_admin() || !in_array($GLOBALS['pagenow'], array('post.php', 'post-new.php'))) {
             //-- RoleScoper Modification - alternate function call (was _pad_term_counts) --//
             rs_tally_term_counts($terms, $taxonomies[0], array('pad_counts' => $pad_counts, 'skip_teaser' => !$do_teaser, 'post_type' => $post_type));
         }
     }
     // Make sure we show empty categories that have children.
     if ($hierarchical && $hide_empty) {
         foreach ($terms as $k => $term) {
             if (!$term->count) {
                 //-- RoleScoper Modification - call alternate function (was _get_term_children) --//
                 if ($children = rs_get_term_descendants($term->term_id, $terms, $taxonomies[0])) {
                     foreach ($children as $child) {
                         if ($child->count) {
                             continue 2;
                         }
                     }
                 }
                 // It really is empty
                 unset($terms[$k]);
             }
         }
     }
     reset($terms);
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     // === BEGIN Role Scoper ADDITION: hide empty cats based on actual query result instead of 'count > 0' clause, so we don't exclude cats with private but readable posts
     if ($terms && empty($hierarchical) && !empty($hide_empty)) {
         foreach ($terms as $key => $term) {
             if (!$term->count) {
                 unset($terms[$key]);
             }
         }
     }
     //
     // === END Role Scoper ADDITION ===
     // ================================
     if (!empty($include)) {
         $interms = wp_parse_id_list($include);
         foreach ($terms as $key => $term) {
             if (!in_array($term->term_id, $interms)) {
                 unset($terms[$key]);
             }
         }
     }
     $_terms = array();
     if ('id=>parent' == $fields) {
         while ($term = array_shift($terms)) {
             $_terms[$term->term_id] = $term->parent;
         }
         $terms = $_terms;
     } elseif ('ids' == $fields) {
         while ($term = array_shift($terms)) {
             $_terms[] = $term->term_id;
         }
         $terms = $_terms;
     } elseif ('names' == $fields) {
         while ($term = array_shift($terms)) {
             $_terms[] = $term->name;
         }
         $terms = $_terms;
     }
     if (0 < $number && intval(@count($terms)) > $number) {
         $terms = array_slice($terms, $offset, $number);
     }
     // === BEGIN Role Scoper MODIFICATION: cache key is specific to user/group
     //
     if (!$no_cache) {
         $cache[$ckey] = $terms;
         $current_rs_user->cache_set($cache, $cache_flag);
     }
     // RS Modification: alternate filter name (get_terms filter is already applied by WP)
     remove_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
     $terms = apply_filters('get_terms', $terms, $taxonomies, $args);
     $terms = apply_filters('get_terms_rs', $terms, $taxonomies, $args);
     add_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
     // restore buffered term names in case they were filtered previously
     if ('all' == $fields) {
         scoper_restore_property_array($terms, $term_names, 'term_id', 'name');
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     //dump($terms);
     return $terms;
 }
function rs_tally_term_counts(&$terms, $taxonomy, $args = array())
{
    global $wpdb, $scoper;
    $defaults = array('pad_counts' => true, 'skip_teaser' => false, 'post_type' => '');
    $args = array_merge($defaults, (array) $args);
    extract($args);
    if (!$terms) {
        return;
    }
    $term_items = array();
    $terms_by_id = array();
    foreach ($terms as $key => $term) {
        $terms_by_id[$term->term_id] =& $terms[$key];
        $term_ids[$term->term_taxonomy_id] = $term->term_id;
        // key and value will match for non-taxonomy category types
    }
    $tx_obj = get_taxonomy($taxonomy);
    $post_types = array_unique((array) $tx_obj->object_type);
    $enabled_types = array();
    foreach ($post_types as $_post_type) {
        if (scoper_get_otype_option('use_term_roles', 'post', $_post_type)) {
            $enabled_types[] = $_post_type;
        }
    }
    if (!$enabled_types) {
        return;
    }
    if ($post_type) {
        $post_type = (array) $post_type;
        $enabled_types = array_intersect($enabled_types, $post_type);
    }
    // Get the object and term ids and stick them in a lookup table
    $request = "SELECT DISTINCT {$wpdb->posts}.ID, tt.term_taxonomy_id, tt.term_id, tr.object_id" . " FROM {$wpdb->posts}" . " INNER JOIN {$wpdb->term_relationships} AS tr ON {$wpdb->posts}.ID = tr.object_id " . " INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " . " WHERE tt.taxonomy = '{$taxonomy}' AND tt.term_id IN ('" . implode("','", $term_ids) . "') " . " AND {$wpdb->posts}.post_type IN ('" . implode("','", $enabled_types) . "')";
    // no need to pass any parameters which do not pertain to the objects_request filter
    $args = array_intersect_key($args, array_flip(array('skip_teaser')));
    //$post_type = reset($enabled_types);
    $post_type = $enabled_types;
    // note: don't pass in a taxonomies arg because we need to consider restrictions associated with any taxonomy to determine readable objects for terms of this taxonomy
    $request = apply_filters('objects_request_rs', $request, 'post', $post_type, $args);
    $results = scoper_get_results($request);
    foreach ($results as $row) {
        $id = $term_ids[$row->term_taxonomy_id];
        if (isset($term_items[$id][$row->object_id])) {
            ++$term_items[$id][$row->object_id];
        } else {
            $term_items[$id][$row->object_id] = 1;
        }
    }
    // credit each term for every object contained in any of its descendant terms
    if ($pad_counts && ScoperAncestry::get_terms_children($taxonomy)) {
        foreach ($term_ids as $term_id) {
            $child_term_id = $term_id;
            while (isset($terms_by_id[$child_term_id]->parent)) {
                if (!($parent_term_id = $terms_by_id[$child_term_id]->parent)) {
                    break;
                }
                if (!empty($term_items[$term_id])) {
                    foreach (array_keys($term_items[$term_id]) as $item_id) {
                        $term_items[$parent_term_id][$item_id] = 1;
                    }
                }
                $child_term_id = $parent_term_id;
            }
        }
    }
    // Tally and apply the item credits
    foreach ($term_items as $term_id => $items) {
        if (isset($terms_by_id[$term_id])) {
            $terms_by_id[$term_id]->count = count($items);
        }
    }
    // update count property for zero-item terms too
    foreach (array_keys($terms_by_id) as $term_id) {
        if (!isset($term_items[$term_id])) {
            if (is_object($terms_by_id[$term_id])) {
                $terms_by_id[$term_id]->count = 0;
            }
        }
    }
}
 /** 
  * Updates the status of a User-Group relationship
  *
  * @param int $group_id - Group Identifier
  * @param int $user_id - Identifier of the User to remove
  **/
 function update_group_user($group_id, $user_ids, $status)
 {
     global $wpdb;
     $user_ids = (array) $user_ids;
     $id_in = "'" . implode("', '", $user_ids) . "'";
     $prev_status = array();
     $qry = "SELECT {$wpdb->user2group_uid_col} AS user_id, {$wpdb->user2group_status_col} AS status FROM {$wpdb->user2group_rs} WHERE {$wpdb->user2group_gid_col}='{$group_id}' AND {$wpdb->user2group_uid_col} IN ({$id_in})";
     if ($results = scoper_get_results($qry)) {
         foreach ($results as $row) {
             $prev_status[$row->user_id] = $row->status;
         }
     }
     $qry = "UPDATE {$wpdb->user2group_rs} SET {$wpdb->user2group_status_col}='{$status}' WHERE {$wpdb->user2group_gid_col}='{$group_id}' AND {$wpdb->user2group_uid_col} IN ({$id_in})";
     scoper_query($qry);
     foreach ($user_ids as $user_id) {
         $prev = isset($prev_status[$user_id]) ? $prev_status[$user_id] : '';
         do_action('update_group_user_rs', $group_id, $user_id, $status, $prev);
     }
     ScoperAdminLib::flush_groups_cache_for_user($user_ids);
 }
 function flt_get_tags($results, $taxonomies, $args)
 {
     if (!is_array($taxonomies)) {
         $taxonomies = (array) $taxonomies;
     }
     if ('post_tag' != $taxonomies[0] || count($taxonomies) > 1) {
         return $results;
     }
     global $wpdb;
     $defaults = array('exclude' => '', 'include' => '', 'number' => '', 'offset' => '', 'slug' => '', 'name__like' => '', 'search' => '', 'hide_empty' => true);
     $args = wp_parse_args($args, $defaults);
     extract($args, EXTR_SKIP);
     if ('ids' == $fields || !$hide_empty) {
         return $results;
     }
     global $scoper, $current_rs_user;
     $filter_key = has_filter('list_terms_exclusions') ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
     $ckey = md5(serialize(compact(array_keys($defaults))) . serialize($taxonomies) . $filter_key);
     $cache_flag = 'rs_get_terms';
     if ($cache = $current_rs_user->cache_get($cache_flag)) {
         if (isset($cache[$ckey])) {
             return apply_filters('get_tags_rs', $cache[$ckey], 'post_tag', $args);
         }
     }
     //------------ WP argument application code from get_terms(), with hierarchy-related portions removed -----------------
     //
     // NOTE: must change 'tt.count' to 'count' in orderby and hide_empty settings
     //		 Also change default orderby to name
     //
     $where = '';
     $inclusions = '';
     if (!empty($include)) {
         $exclude = '';
         $exclude_tree = '';
         $interms = wp_parse_id_list($include);
         if (count($interms)) {
             foreach ((array) $interms as $interm) {
                 if (empty($inclusions)) {
                     $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
                 } else {
                     $inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
                 }
             }
         }
     }
     if (!empty($inclusions)) {
         $inclusions .= ')';
     }
     $where .= $inclusions;
     $exclusions = '';
     if (!empty($exclude)) {
         $exterms = wp_parse_id_list($exclude);
         if (count($exterms)) {
             foreach ((array) $exterms as $exterm) {
                 if (empty($exclusions)) {
                     $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
                 } else {
                     $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
                 }
             }
         }
     }
     if (!empty($exclusions)) {
         $exclusions .= ')';
     }
     $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args);
     $where .= $exclusions;
     if (!empty($slug)) {
         $slug = sanitize_title($slug);
         $where .= " AND t.slug = '{$slug}'";
     }
     if (!empty($name__like)) {
         $where .= " AND t.name LIKE '{$name__like}%'";
     }
     // don't limit the query results when we have to descend the family tree
     if (!empty($number)) {
         if ($offset) {
             $limit = 'LIMIT ' . $offset . ',' . $number;
         } else {
             $limit = 'LIMIT ' . $number;
         }
     } else {
         $limit = '';
     }
     if (!empty($search)) {
         $search = like_escape($search);
         $where .= " AND (t.name LIKE '%{$search}%')";
     }
     // ------------- end get_terms() argument application code --------------
     $post_type = cr_find_post_type();
     // embedded select statement for posts ID IN clause
     $posts_qry = "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE 1=1";
     $posts_qry = apply_filters('objects_request_rs', $posts_qry, 'post', $post_type, array('skip_teaser' => true));
     $qry = "SELECT DISTINCT t.*, tt.*, COUNT(p.ID) AS count FROM {$wpdb->terms} AS t" . " INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.term_id = t.term_id AND tt.taxonomy = 'post_tag'" . " INNER JOIN {$wpdb->term_relationships} AS tagr ON tagr.term_taxonomy_id = tt.term_taxonomy_id" . " INNER JOIN {$wpdb->posts} AS p ON p.ID = tagr.object_id WHERE p.ID IN ({$posts_qry})" . " {$where} GROUP BY t.term_id ORDER BY count DESC {$limit}";
     // must hardcode orderby clause to always query top tags
     $results = scoper_get_results($qry);
     $cache[$ckey] = $results;
     $current_rs_user->cache_set($cache, $cache_flag);
     $results = apply_filters('get_tags_rs', $results, 'post_tag', $args);
     return $results;
 }
function scoper_sync_wproles($user_ids = '', $role_name_arg = '', $blog_id_arg = '')
{
    global $wpdb, $wp_roles;
    if ($user_ids && !is_array($user_ids)) {
        $user_ids = array($user_ids);
    }
    if (empty($wp_roles->role_objects)) {
        return;
    }
    $wp_rolenames = array_keys($wp_roles->role_objects);
    $uro_table = $blog_id_arg ? $wpdb->base_prefix . $blog_id_arg . '_' . 'user2role2object_rs' : $wpdb->user2role2object_rs;
    $groups_table = $wpdb->groups_rs;
    $user2group_table = $wpdb->user2group_rs;
    // Delete any role entries for WP roles which were deleted or renamed while Role Scoper was deactivated
    // (users will be re-synched to new role name)
    $name_in = "'" . implode("', '", $wp_rolenames) . "'";
    $qry = "DELETE FROM {$uro_table} WHERE role_type = 'wp' AND scope = 'blog' AND role_name NOT IN ({$name_in})";
    scoper_query($qry);
    // also sync WP Role metagroups
    if (!empty($user_ids)) {
        foreach ($user_ids as $user_id) {
            wpp_cache_delete($user_id, 'group_membership_for_user');
        }
    }
    $metagroup_ids = array();
    $metagroup_names = array();
    $metagroup_descripts = array();
    foreach ($wp_rolenames as $role_name) {
        $metagroup_id = "wp_role_" . trim(substr($role_name, 0, 40));
        // if the name is too long and its truncated ID already taken, just exclude it from eligible metagroups
        if (in_array($metagroup_id, $metagroup_ids)) {
            continue;
        }
        $metagroup_ids[] = $metagroup_id;
        $metagroup_names["wp_role_{$role_name}"] = sprintf('[WP %s]', $role_name);
        $metagroup_descripts["wp_role_{$role_name}"] = sprintf('All users with the WordPress %s blog role', $role_name);
    }
    // add a metagroup for anonymous users
    $metagroup_ids[] = "wp_anon";
    $metagroup_names["wp_anon"] = '[Anonymous]';
    $metagroup_descripts["wp_anon"] = 'Anonymous users (not logged in)';
    // add a metagroup for pending revision e-mail notification recipients
    $metagroup_ids[] = "rv_pending_rev_notice_ed_nr_";
    $metagroup_names["rv_pending_rev_notice_ed_nr_"] = '[Pending Revision Monitors]';
    $metagroup_descripts["rv_pending_rev_notice_ed_nr_"] = 'Administrators / Publishers to notify (by default) of pending revisions';
    // add a metagroup for pending revision e-mail notification recipients
    $metagroup_ids[] = "rv_scheduled_rev_notice_ed_nr_";
    $metagroup_names["rv_scheduled_rev_notice_ed_nr_"] = '[Scheduled Revision Monitors]';
    $metagroup_descripts["rv_scheduled_rev_notice_ed_nr_"] = 'Administrators / Publishers to notify when any scheduled revision is published';
    $stored_metagroup_ids = array();
    $qry = "SELECT {$wpdb->groups_meta_id_col}, {$wpdb->groups_id_col}, {$wpdb->groups_name_col} FROM {$groups_table} WHERE NOT ISNULL({$wpdb->groups_meta_id_col}) AND ( {$wpdb->groups_meta_id_col} != '' )";
    // LIKE 'wp_%'";
    if ($results = scoper_get_results($qry)) {
        //rs_errlog("metagroup results: " . serialize($stored_metagroup_ids)');
        $delete_metagroup_ids = array();
        $update_metagroup_ids = array();
        foreach ($results as $row) {
            if (!in_array($row->{$wpdb->groups_meta_id_col}, $metagroup_ids)) {
                $delete_metagroup_ids[] = $row->{$wpdb->groups_id_col};
            } else {
                $stored_metagroup_ids[] = $row->{$wpdb->groups_meta_id_col};
                if ($row->{$wpdb->groups_name_col} != $metagroup_names[$row->{$wpdb->groups_meta_id_col}]) {
                    $update_metagroup_ids[] = $row->{$wpdb->groups_meta_id_col};
                }
            }
        }
        if ($delete_metagroup_ids) {
            $id_in = "'" . implode("', '", $delete_metagroup_ids) . "'";
            scoper_query("DELETE FROM {$groups_table} WHERE {$wpdb->groups_id_col} IN ({$id_in})");
        }
        if ($update_metagroup_ids) {
            foreach ($update_metagroup_ids as $metagroup_id) {
                if ($metagroup_id) {
                    scoper_query("UPDATE {$groups_table} SET {$wpdb->groups_name_col} = '{$metagroup_names[$metagroup_id]}', {$wpdb->groups_descript_col} = '{$metagroup_descripts[$metagroup_id]}' WHERE {$wpdb->groups_meta_id_col} = '{$metagroup_id}'");
                }
            }
        }
    }
    if ($insert_metagroup_ids = array_diff($metagroup_ids, $stored_metagroup_ids)) {
        //rs_errlog("inserting metagroup ids: " . serialize($insert_metagroup_ids)');
        foreach ($insert_metagroup_ids as $metagroup_id) {
            scoper_query("INSERT INTO {$groups_table} ( {$wpdb->groups_meta_id_col}, {$wpdb->groups_name_col}, {$wpdb->groups_descript_col} ) VALUES ( '{$metagroup_id}', '{$metagroup_names[$metagroup_id]}', '{$metagroup_descripts[$metagroup_id]}' )");
            //rs_errlog( "INSERT INTO $groups_table ( $wpdb->groups_meta_id_col, $wpdb->groups_name_col, $wpdb->groups_descript_col ) VALUES ( '$metagroup_id', '$metagroup_names[$metagroup_id]', '$metagroup_descripts[$metagroup_id]' )" );
        }
    }
    if (!empty($delete_metagroup_ids) || !empty($update_metagroup_ids)) {
        wpp_cache_flush();
        // role deletion / rename might affect other cached data or settings, so flush the whole cache
    } elseif (!empty($insert_group_ids)) {
        wpp_cache_flush_group('all_usergroups');
        wpp_cache_flush_group('usergroups_for_groups');
        wpp_cache_flush_group('usergroups_for_user');
        wpp_cache_flush_group('usergroups_for_ug');
    }
    // Now step through every WP usermeta record,
    // synchronizing the user's user2role2object_rs blog role entries with their WP role and custom caps
    // get each user's WP roles and caps
    $user_clause = $user_ids ? 'AND user_id IN (' . implode(', ', $user_ids) . ')' : '';
    $qry = "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = '{$wpdb->prefix}capabilities' {$user_clause}";
    if (!($usermeta = scoper_get_results($qry))) {
        return;
    }
    //rs_errlog("got " . count($usermeta) . " usermeta records");
    $wp_rolecaps = array();
    foreach ($wp_roles->role_objects as $role_name => $role) {
        $wp_rolecaps[$role_name] = $role->capabilities;
    }
    //rs_errlog(serialize($wp_rolecaps));
    $strip_vals = array('', 0, false);
    $stored_assignments = array('wp' => array(), 'wp_cap' => array());
    foreach (array_keys($stored_assignments) as $role_type) {
        $results = scoper_get_results("SELECT user_id, role_name, assignment_id FROM {$uro_table} WHERE role_type = '{$role_type}' AND user_id > 0 {$user_clause}");
        foreach ($results as $key => $row) {
            $stored_assignments[$role_type][$row->user_id][$row->assignment_id] = $row->role_name;
            unset($results[$key]);
        }
    }
    foreach (array_keys($usermeta) as $key) {
        $user_id = $usermeta[$key]->user_id;
        $user_caps = maybe_unserialize($usermeta[$key]->meta_value);
        if (empty($user_caps) || !is_array($user_caps)) {
            continue;
        }
        //rs_errlog("user caps: " . serialize($user_caps));
        $user_roles = array();
        // just in case, strip out any entries with false value
        $user_caps = array_diff($user_caps, $strip_vals);
        $user_roles = array('wp' => array(), 'wp_cap' => array());
        //Filter out caps that are not role names
        $user_roles['wp'] = array_intersect(array_keys($user_caps), $wp_rolenames);
        // Store any custom-assigned caps as single-cap roles
        // This will be invisible and only used to support the users query filter
        // With current implementation, the custom cap will only be honored when
        // users_who_can is called with a single capreq
        $user_roles['wp_cap'] = array_diff(array_keys($user_caps), $user_roles['wp']);
        // which roles are already stored in user2role2object_rs table?
        $stored_roles = array();
        $delete_roles = array();
        foreach (array_keys($user_roles) as $role_type) {
            //$results = scoper_get_results("SELECT role_name, assignment_id FROM $uro_table WHERE role_type = '$role_type' AND user_id = '$user_id'");
            //if ( $results ) {
            if (isset($stored_assignments[$role_type][$user_id])) {
                //rs_errlog("results: " . serialize($results));
                foreach ($stored_assignments[$role_type][$user_id] as $assignment_id => $role_name) {
                    // Log stored roles, and delete any roles which user no longer has (possibly because the WP role definition was deleted).
                    // Only Role Scoper's mirroring of WP blog roles is involved here unless Role Scoper was configured and used with a Role Type of "WP".
                    // This also covers any WP role changes made while Role Scoper was deactivated.
                    if (in_array($role_name, $user_roles[$role_type])) {
                        $stored_roles[$role_type][] = $role_name;
                    } else {
                        $delete_roles[] = $assignment_id;
                    }
                }
            } else {
                $stored_roles[$role_type] = array();
            }
        }
        if ($delete_roles) {
            $id_in = implode(', ', $delete_roles);
            scoper_query("DELETE FROM {$uro_table} WHERE assignment_id IN ({$id_in})");
        }
        //rs_errlog("user roles " . serialize($user_roles) ');
        //rs_errlog("stored roles " . serialize($stored_roles)');
        // add any missing roles
        foreach (array_keys($user_roles) as $role_type) {
            if (!empty($stored_roles[$role_type])) {
                $user_roles[$role_type] = array_diff($user_roles[$role_type], $stored_roles[$role_type]);
            }
            if (!empty($user_roles[$role_type])) {
                foreach ($user_roles[$role_type] as $role_name) {
                    //rs_errlog("INSERT INTO $uro_table (user_id, role_name, role_type, scope) VALUES ('$user_id', '$role_name', '$role_type', 'blog')");
                    scoper_query("INSERT INTO {$uro_table} (user_id, role_name, role_type, scope) VALUES ('{$user_id}', '{$role_name}', '{$role_type}', 'blog')");
                }
            }
        }
    }
    // end foreach WP usermeta
    // disable orphaned role deletion until we can recreate and eliminate improper deletion as reported in support forum (http://agapetry.net/forum/role-scoper/permissions-reset-randomly-for-a-section-of-pages/page-1/post-3513/)
    // Delete any role assignments for users which no longer exist
    //delete_roles_orphaned_from_user();
    // Delete any role assignments for WP groups which no longer exist
    //delete_roles_orphaned_from_group();
    // Delete any role assignments for posts/pages which no longer exist
    //delete_roles_orphaned_from_item( OBJECT_SCOPE_RS, 'post' );
    //delete_restrictions_orphaned_from_item( OBJECT_SCOPE_RS, 'post' );	// hold off on this until delete_roles_orphaned_from_item() call has a long, clear track record
    // Delete any role assignments for categories which no longer exist
    //delete_roles_orphaned_from_item( TERM_SCOPE_RS, 'category' );
    //delete_restrictions_orphaned_from_item( TERM_SCOPE_RS, 'category' );
    //rs_errlog("finished syncroles "');
}
 function flt_wp_dropdown_users($wp_output)
 {
     // just filter Post Author dropdown
     if (!strpos($wp_output, "name='post_author_override'")) {
         return $wp_output;
     }
     // this is meant to filter the post author selection
     if (!is_admin()) {
         return $wp_output;
     }
     // if (even after our blogcap tinkering) the author list is already locked due to insufficient blog-wide caps, don't mess
     if (!($pos = strpos($wp_output, '<option'))) {
         return $wp_output;
     }
     if (!strpos($wp_output, '<option', $pos + 1)) {
         return $wp_output;
     }
     global $wpdb, $scoper;
     $last_query = $wpdb->last_query;
     if (!($object_type = cr_find_post_type())) {
         return $wp_output;
     }
     if (!($post_type_obj = get_post_type_object($object_type))) {
         return $wp_output;
     }
     global $current_user;
     $is_ngg_edit = strpos($_SERVER['REQUEST_URI'], 'nggallery-manage-gallery');
     if (!$is_ngg_edit) {
         $src_name = 'post';
         $object_id = scoper_get_object_id('post', $object_type);
         // only modify the default authors list if current user has Editor role for the current post/page
         $have_cap = cr_user_can($post_type_obj->cap->edit_others_posts, $object_id, 0, array('require_full_object_role' => true));
     } else {
         $src_name = 'ngg_gallery';
         $object_id = $_REQUEST['gid'];
         $have_cap = !empty($current_user->allcaps[$post_type_obj->cap->edit_others_posts]);
         // $post_type_obj defaults to 'post' type on NGG Manage Gallery page
     }
     //if ( ! $have_cap )
     //	return $wp_output;
     $orderpos = strpos($last_query, 'ORDER BY');
     $orderby = $orderpos ? substr($last_query, $orderpos) : '';
     if (!strpos($orderby, 'display_name')) {
         // sanity check in case the last_query buffer gets messed up
         $orderby = '';
     }
     $id_in = $id_not_in = $show_option_all = $show_option_none = '';
     $pos = strpos($last_query, 'AND ID IN(');
     if ($pos) {
         $pos_close = strpos($last_query, ')', $pos);
         if ($pos_close) {
             $id_in = substr($last_query, $pos, $pos_close - $pos + 1);
         }
     }
     $pos = strpos($last_query, 'AND ID NOT IN(');
     if ($pos) {
         $pos_close = strpos($last_query, ')', $pos);
         if ($pos_close) {
             $id_not_in = substr($last_query, $pos, $pos_close - $pos + 1);
         }
     }
     $search = "<option value='0'>";
     $pos = strpos($wp_output, $search . __awp('Any'));
     if ($pos) {
         $pos_close = strpos($wp_output, '</option>', $pos);
         if ($pos_close) {
             $show_option_all = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = "<option value='-1'>";
     $pos = strpos($wp_output, $search . __awp('None'));
     if ($pos) {
         $pos_close = strpos($wp_output, '</option>', $pos);
         if ($pos_close) {
             $show_option_none = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = "<select name='";
     $pos = strpos($wp_output, $search);
     if (false !== $pos) {
         $pos_close = strpos($wp_output, "'", $pos + strlen($search));
         if ($pos_close) {
             $name = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = " id='";
     $multi = !strpos($wp_output, $search);
     // beginning with WP 2.7, some users dropdowns lack id attribute
     $search = " class='";
     $pos = strpos($wp_output, $search);
     if ($pos) {
         $pos_close = strpos($wp_output, "'", $pos + strlen($search));
         if ($pos_close) {
             $class = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = " selected='selected'";
     $pos = strpos($wp_output, $search);
     if ($pos) {
         $search = "<option value='";
         $str_left = substr($wp_output, 0, $pos);
         $pos = strrpos($str_left, $search);
         //back up to previous option tag
         $pos_close = strpos($wp_output, "'", $pos + strlen($search));
         if ($pos_close) {
             $selected = substr($wp_output, $pos + strlen($search), $pos_close - ($pos + strlen($search)));
         }
     }
     if (empty($selected)) {
         $selected = $current_user->ID;
     }
     // precaution prevents default-selection of non-current user
     // Role Scoper filter application
     $where = "{$id_in} {$id_not_in}";
     $args = array();
     $args['where'] = $where;
     $args['orderby'] = $orderby;
     if ($object_id > 0) {
         if ($current_author = $scoper->data_sources->get_from_db('owner', $src_name, $object_id)) {
             $force_user_id = $current_author;
         }
     } else {
         $force_user_id = $current_user->ID;
     }
     if ($have_cap) {
         if ($force_user_id) {
             $args['preserve_or_clause'] = " uro.user_id = '{$force_user_id}'";
         }
         $users = $scoper->users_who_can($post_type_obj->cap->edit_posts, COLS_ID_DISPLAYNAME_RS, 'post', $object_id, $args);
     } else {
         $display_name = $wpdb->get_var("SELECT display_name FROM {$wpdb->users} WHERE ID = '{$force_user_id}'");
         $users = array((object) array('ID' => $force_user_id, 'display_name' => $display_name));
     }
     if (empty($users)) {
         // sanity check: users_who_can should always return Administrators
         if ($admin_roles = awp_administrator_roles()) {
             $users = scoper_get_results("SELECT DISTINCT ID, display_name FROM {$wpdb->users} INNER JOIN {$wpdb->user2role2object_rs} AS uro ON uro.user_id = {$wpdb->users}.ID AND uro.scope = 'blog' AND uro.role_type = 'wp' AND uro.role_name IN ('" . implode("','", $admin_roles) . "')");
         } else {
             return $wp_output;
         }
         // the user data must be messed up
     }
     $show = 'display_name';
     // no way to back this out
     // ----------- begin wp_dropdown_users code copy (from WP 2.7) -------------
     $id = $multi ? "" : "id='{$name}'";
     $output = "<select name='{$name}' {$id} class='{$class}'>\n";
     if ($show_option_all) {
         $output .= "\t<option value='0'>{$show_option_all}</option>\n";
     }
     if ($show_option_none) {
         $output .= "\t<option value='-1'>{$show_option_none}</option>\n";
     }
     foreach ((array) $users as $user) {
         $user->ID = (int) $user->ID;
         $_selected = $user->ID == $selected ? " selected='selected'" : '';
         $display = !empty($user->{$show}) ? $user->{$show} : '(' . $user->user_login . ')';
         $output .= "\t<option value='{$user->ID}'{$_selected}>" . esc_html($display) . "</option>\n";
     }
     $output .= "</select>";
     // ----------- end wp_dropdown_users code copy (from WP 2.7) -------------
     return $output;
 }
示例#21
0
 function get_objects_info($object_ids, &$object_names, &$object_status, &$unlisted_objects, $src, $otype, $ignore_hierarchy)
 {
     global $wpdb;
     // buffer titles in case they are translated
     if ('page' == $otype->name) {
         // todo: other hierarchical types?
         $titles = ScoperAdminBulkParent::get_page_titles();
     }
     $col_id = $src->cols->id;
     $col_name = $src->cols->name;
     $cols = "{$col_name}, {$col_id}";
     if (isset($src->cols->parent) && !$ignore_hierarchy) {
         $col_parent = $src->cols->parent;
         $cols .= ", {$col_parent}";
     } else {
         $col_parent = '';
     }
     $col_status = !empty($src->cols->status) ? $src->cols->status : '';
     if ($col_status) {
         $cols .= ", {$col_status}";
     }
     $unroled_count = 0;
     $unroled_limit = !empty($otype->admin_max_unroled_objects) ? $otype->admin_max_unroled_objects : 999999;
     if (!empty($src->cols->type)) {
         $otype_clause = "AND {$src->cols->type} = '{$otype->name}'";
         if ('post' == $src->name) {
             $otype_clause .= "AND {$src->cols->status} != 'auto-draft'";
         }
     } else {
         $otype_clause = '';
     }
     $obj = '';
     if ($results = scoper_get_results("SELECT {$cols} FROM {$src->table} WHERE 1=1 {$otype_clause} ORDER BY {$col_id} DESC")) {
         foreach ($results as $row) {
             if (isset($titles[$row->{$col_id}])) {
                 $object_names[$row->{$col_id}] = $titles[$row->{$col_id}];
             } elseif ('post' == $src->name) {
                 $object_names[$row->{$col_id}] = apply_filters('the_title', $row->{$col_name}, $row->{$col_id});
             } else {
                 $object_names[$row->{$col_id}] = $row->{$col_name};
             }
             if ($col_status) {
                 $object_status[$row->{$col_id}] = $row->{$col_status};
             }
             unset($obj);
             if ($col_parent) {
                 // temporarily key by name for alpha sort of additional items prior to hierarchy sort
                 $obj = (object) array($col_id => $row->{$col_id}, $col_name => $row->{$col_name}, $col_parent => $row->{$col_parent});
             } else {
                 $obj = (object) array($col_id => $row->{$col_id}, $col_name => $row->{$col_name});
             }
             // List only a limited number of unroled objects
             if ($unroled_limit >= 0 && !isset($object_ids[$row->{$col_id}])) {
                 if ($unroled_count >= $unroled_limit) {
                     $unlisted_objects[$row->{$col_id}] = $obj;
                     continue;
                 }
                 $unroled_count++;
             }
             $listed_objects[$row->{$col_id}] = $obj;
         }
     }
     // restore buffered page titles in case they were filtered previously
     if ('page' == $otype->name) {
         scoper_restore_property_array($listed_objects, $titles, 'ID', 'post_title');
         scoper_restore_property_array($unlisted_objects, $titles, 'ID', 'post_title');
     }
     return $listed_objects;
 }
 function flt_get_pages($results, $args = array())
 {
     $results = (array) $results;
     global $wpdb;
     // === BEGIN Role Scoper ADDITION: global var; various special case exemption checks ===
     //
     global $scoper, $current_rs_user;
     // need to skip cache retrieval if QTranslate is filtering get_pages with a priority of 1 or less
     $no_cache = !defined('SCOPER_QTRANSLATE_COMPAT') && awp_is_plugin_active('qtranslate');
     // buffer titles in case they were filtered previously
     $titles = scoper_get_property_array($results, 'ID', 'post_title');
     // depth is not really a get_pages arg, but remap exclude arg to exclude_tree if wp_list_terms called with depth=1
     if (!empty($args['exclude']) && empty($args['exclude_tree']) && !empty($args['depth']) && 1 == $args['depth']) {
         if (0 !== strpos($args['exclude'], ',')) {
             // work around wp_list_pages() bug of attaching leading comma if a plugin uses wp_list_pages_excludes filter
             $args['exclude_tree'] = $args['exclude'];
         }
     }
     //
     // === END Role Scoper ADDITION ===
     // =================================
     $defaults = array('child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => '', 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish', 'depth' => 0, 'suppress_filters' => 0, 'remap_parents' => -1, 'enforce_actual_depth' => -1, 'remap_thru_excluded_parent' => -1);
     // Role Scoper arguments added above
     // === BEGIN Role Scoper ADDITION: support front-end optimization
     $post_type = isset($args['post_type']) ? $args['post_type'] : $defaults['post_type'];
     $use_post_types = (array) scoper_get_option('use_post_types');
     if (empty($use_post_types[$post_type])) {
         return $results;
     }
     if ($scoper->is_front()) {
         if ('page' == $post_type && defined('SCOPER_GET_PAGES_LEAN')) {
             // custom types are likely to have custom fields
             $defaults['fields'] = "{$wpdb->posts}.ID, {$wpdb->posts}.post_title, {$wpdb->posts}.post_parent, {$wpdb->posts}.post_date, {$wpdb->posts}.post_date_gmt, {$wpdb->posts}.post_status, {$wpdb->posts}.post_name, {$wpdb->posts}.post_modified, {$wpdb->posts}.post_modified_gmt, {$wpdb->posts}.guid, {$wpdb->posts}.menu_order, {$wpdb->posts}.comment_count";
         } else {
             $defaults['fields'] = "{$wpdb->posts}.*";
             if (!defined('SCOPER_FORCE_PAGES_CACHE')) {
                 $no_cache = true;
             }
             // serialization / unserialization of post_content for all pages is too memory-intensive for sites with a lot of pages
         }
     } else {
         // required for xmlrpc getpagelist method
         $defaults['fields'] = "{$wpdb->posts}.*";
         if (!defined('SCOPER_FORCE_PAGES_CACHE')) {
             $no_cache = true;
         }
     }
     // === END Role Scoper MODIFICATION ===
     $r = wp_parse_args($args, $defaults);
     extract($r, EXTR_SKIP);
     $number = (int) $number;
     $offset = (int) $offset;
     $child_of = (int) $child_of;
     // Role Scoper modification: null value will confuse children array check
     // Make sure the post type is hierarchical
     $hierarchical_post_types = get_post_types(array('public' => true, 'hierarchical' => true));
     if (!in_array($post_type, $hierarchical_post_types)) {
         return $results;
     }
     // Make sure we have a valid post status
     if (!in_array($post_status, get_post_stati())) {
         return $results;
     }
     // for the page parent dropdown, return no available selections for a published main page if the logged user isn't allowed to de-associate it from Main
     if (!empty($name) && 'parent_id' == $name) {
         global $post;
         if (!$post->post_parent && !$GLOBALS['scoper_admin_filters']->user_can_associate_main($post_type)) {
             $status_obj = get_post_status_object($post->post_status);
             if ($status_obj->public || $status_obj->private) {
                 return array();
             }
         }
         if (!empty($post) && $post_type == $post->post_type) {
             if ($post->post_parent) {
                 $append_page = get_post($post->post_parent);
             }
             $exclude_tree = $post->ID;
         }
     }
     //$scoper->last_get_pages_args = $r; // don't copy entire args array unless it proves necessary
     $scoper->last_get_pages_depth = $depth;
     $scoper->last_get_pages_suppress_filters = $suppress_filters;
     if ($suppress_filters) {
         return $results;
     }
     // === BEGIN Role Scoper MODIFICATION: wp-cache key and flag specific to access type and user/groups
     //
     if (!scoper_get_otype_option('use_object_roles', 'post', $post_type)) {
         return $results;
     }
     $key = md5(serialize(compact(array_keys($defaults))));
     $ckey = md5($key . CURRENT_ACCESS_NAME_RS);
     $cache_flag = 'rs_get_pages';
     $cache = $current_rs_user->cache_get($cache_flag);
     if (false !== $cache) {
         if (!is_array($cache)) {
             $cache = array();
         }
         if (!$no_cache && isset($cache[$ckey])) {
             // alternate filter name (WP core already applied get_pages filter)
             return apply_filters('get_pages_rs', $cache[$ckey], $r);
         }
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     $inclusions = '';
     if (!empty($include)) {
         $child_of = 0;
         //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
         $parent = -1;
         $exclude = '';
         $meta_key = '';
         $meta_value = '';
         $hierarchical = false;
         $incpages = wp_parse_id_list($include);
         if (!empty($incpages)) {
             foreach ($incpages as $incpage) {
                 if (empty($inclusions)) {
                     $inclusions = ' AND ( ID = ' . intval($incpage) . ' ';
                 } else {
                     $inclusions .= ' OR ID = ' . intval($incpage) . ' ';
                 }
             }
         }
     }
     if (!empty($inclusions)) {
         $inclusions .= ')';
     }
     $exclusions = '';
     if (!empty($exclude)) {
         $expages = wp_parse_id_list($exclude);
         if (!empty($expages)) {
             foreach ($expages as $expage) {
                 if (empty($exclusions)) {
                     $exclusions = ' AND ( ID <> ' . intval($expage) . ' ';
                 } else {
                     $exclusions .= ' AND ID <> ' . intval($expage) . ' ';
                 }
             }
         }
     }
     if (!empty($exclusions)) {
         $exclusions .= ')';
     }
     $author_query = '';
     if (!empty($authors)) {
         $post_authors = wp_parse_id_list($authors);
         if (!empty($post_authors)) {
             foreach ($post_authors as $post_author) {
                 //Do we have an author id or an author login?
                 if (0 == intval($post_author)) {
                     $post_author = get_userdatabylogin($post_author);
                     if (empty($post_author)) {
                         continue;
                     }
                     if (empty($post_author->ID)) {
                         continue;
                     }
                     $post_author = $post_author->ID;
                 }
                 if ('' == $author_query) {
                     $author_query = ' post_author = ' . intval($post_author) . ' ';
                 } else {
                     $author_query .= ' OR post_author = ' . intval($post_author) . ' ';
                 }
             }
             if ('' != $author_query) {
                 $author_query = " AND ({$author_query})";
             }
         }
     }
     $join = '';
     $where = "{$exclusions} {$inclusions} ";
     if (!empty($meta_key) || !empty($meta_value)) {
         $join = " INNER JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
         // Role Scoper modification: was LEFT JOIN in WP 3.0 core (TODO: would that botch uro join results?
         // meta_key and meta_value might be slashed
         $meta_key = stripslashes($meta_key);
         $meta_value = stripslashes($meta_value);
         if (!empty($meta_key)) {
             $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_key = %s", $meta_key);
         }
         if (!empty($meta_value)) {
             $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_value = %s", $meta_value);
         }
     }
     if ($parent >= 0) {
         $where .= $wpdb->prepare(' AND post_parent = %d ', $parent);
     }
     // === BEGIN Role Scoper MODIFICATION:
     // allow pages of multiple statuses to be displayed (requires default status=publish to be ignored)
     //
     $where_post_type = $wpdb->prepare("post_type = '%s'", $post_type);
     $where_status = '';
     $is_front = $scoper->is_front();
     $is_teaser_active = $scoper->is_front() && scoper_get_otype_option('do_teaser', 'post') && scoper_get_otype_option('use_teaser', 'post', $post_type);
     $private_teaser = $is_teaser_active && scoper_get_otype_option('use_teaser', 'post', $post_type) && !scoper_get_otype_option('teaser_hide_private', 'post', $post_type);
     if ($is_front && (!empty($current_rs_user->ID) || $private_teaser)) {
         $frontend_list_private = scoper_get_otype_option('private_items_listable', 'post', 'page');
     } else {
         $frontend_list_private = false;
     }
     // WP core does not include private pages in query.  Include private statuses in anticipation of user-specific filtering
     if ($post_status && ('publish' != $post_status || $is_front && !$frontend_list_private)) {
         $where_status = $wpdb->prepare("post_status = '%s'", $post_status);
     } else {
         // since we will be applying status clauses based on content-specific roles and restrictions, only a sanity check safeguard is needed when post_status is unspecified or defaulted to "publish"
         $safeguard_statuses = array();
         foreach (get_post_stati(array('internal' => false), 'object') as $status_name => $status_obj) {
             if (!$is_front || $status_obj->private || $status_obj->public) {
                 $safeguard_statuses[] = $status_name;
             }
         }
         $where_status = "post_status IN ('" . implode("','", $safeguard_statuses) . "')";
     }
     $query = "SELECT {$fields} FROM {$wpdb->posts} {$join} WHERE 1=1 AND {$where_post_type} AND ( {$where_status} {$where} {$author_query} ) ORDER BY {$sort_column} {$sort_order}";
     if (!empty($number)) {
         $query .= ' LIMIT ' . $offset . ',' . $number;
     }
     if ($is_teaser_active && !defined('SCOPER_TEASER_HIDE_PAGE_LISTING')) {
         // We are in the front end and the teaser is enabled for pages
         $query = apply_filters('objects_request_rs', $query, 'post', $post_type, array('force_teaser' => true));
         $pages = scoper_get_results($query);
         // execute unfiltered query
         // Pass results of unfiltered query through the teaser filter.
         // If listing private pages is disabled, they will be omitted completely, but restricted published pages
         // will still be teased.  This is a slight design compromise to satisfy potentially conflicting user goals without yet another option
         $pages = apply_filters('objects_results_rs', $pages, 'post', (array) $post_type, array('request' => $query, 'force_teaser' => true, 'object_type' => $post_type));
         // restore buffered titles in case they were filtered previously
         scoper_restore_property_array($pages, $titles, 'ID', 'post_title');
         $pages = apply_filters('objects_teaser_rs', $pages, 'post', $post_type, array('request' => $query, 'force_teaser' => true));
         if ($frontend_list_private) {
             if (!scoper_get_otype_option('teaser_hide_private', 'post', $post_type)) {
                 $tease_all = true;
             }
         }
     } else {
         $_args = array('skip_teaser' => true);
         if (in_array($GLOBALS['pagenow'], array('post.php', 'post-new.php'))) {
             if ($post_type_obj = get_post_type_object($post_type)) {
                 $plural_name = plural_name_from_cap_rs($post_type_obj);
                 $_args['alternate_reqd_caps'][0] = array("create_child_{$plural_name}");
             }
         }
         // Pass query through the request filter
         $query = apply_filters('objects_request_rs', $query, 'post', $post_type, $_args);
         // Execute the filtered query
         $pages = scoper_get_results($query);
         // restore buffered titles in case they were filtered previously
         scoper_restore_property_array($pages, $titles, 'ID', 'post_title');
     }
     if (empty($pages)) {
         // alternate hook name (WP core already applied get_pages filter)
         return apply_filters('get_pages_rs', array(), $r);
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     // Role Scoper note: WP core get_pages has already updated wp_cache and pagecache with unfiltered results.
     update_page_cache($pages);
     // === BEGIN Role Scoper MODIFICATION: Support a disjointed pages tree with some parents hidden ========
     if ($child_of || empty($tease_all)) {
         // if we're including all pages with teaser, no need to continue thru tree remapping
         $ancestors = ScoperAncestry::get_page_ancestors();
         // array of all ancestor IDs for keyed page_id, with direct parent first
         $orderby = $sort_column;
         if ($parent > 0 || !$hierarchical) {
             $remap_parents = false;
         } else {
             // if these settings were passed into this get_pages call, use them
             if (-1 === $remap_parents) {
                 $remap_parents = scoper_get_option('remap_page_parents');
             }
             if ($remap_parents) {
                 if (-1 === $enforce_actual_depth) {
                     $enforce_actual_depth = scoper_get_option('enforce_actual_page_depth');
                 }
                 if (-1 === $remap_thru_excluded_parent) {
                     $remap_thru_excluded_parent = scoper_get_option('remap_thru_excluded_page_parent');
                 }
             }
         }
         $remap_args = compact('child_of', 'parent', 'exclude', 'depth', 'orderby', 'remap_parents', 'enforce_actual_depth', 'remap_thru_excluded_parent');
         // one or more of these args may have been modified after extraction
         ScoperHardway::remap_tree($pages, $ancestors, 'ID', 'post_parent', $remap_args);
     }
     // === END Role Scoper MODIFICATION ===
     // ====================================
     if (!empty($exclude_tree)) {
         $exclude = array();
         $exclude = (int) $exclude_tree;
         $children = get_page_children($exclude, $pages);
         // RS note: okay to use unfiltered function here since it's only used for excluding
         $excludes = array();
         foreach ($children as $child) {
             $excludes[] = $child->ID;
         }
         $excludes[] = $exclude;
         $total = count($pages);
         for ($i = 0; $i < $total; $i++) {
             if (in_array($pages[$i]->ID, $excludes)) {
                 unset($pages[$i]);
             }
         }
     }
     if (!empty($append_page) && !empty($pages)) {
         $found = false;
         foreach (array_keys($pages) as $key) {
             if ($post->post_parent == $pages[$key]->ID) {
                 $found = true;
                 break;
             }
         }
         if (empty($found)) {
             $pages[] = $append_page;
         }
     }
     // re-index the array, just in case anyone cares
     $pages = array_values($pages);
     // === BEGIN Role Scoper MODIFICATION: cache key and flag specific to access type and user/groups
     //
     if (!$no_cache) {
         $cache[$ckey] = $pages;
         $current_rs_user->cache_set($cache, $cache_flag);
     }
     // alternate hook name (WP core already applied get_pages filter)
     $pages = apply_filters('get_pages_rs', $pages, $r);
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     return $pages;
 }
 function flt_get_bookmarks($results, $args)
 {
     global $wpdb;
     $defaults = array('orderby' => 'name', 'order' => 'ASC', 'limit' => -1, 'category' => '', 'category_name' => '', 'hide_invisible' => 1, 'show_updated' => 0, 'include' => '', 'exclude' => '', 'search' => '');
     $r = wp_parse_args($args, $defaults);
     extract($r, EXTR_SKIP);
     // === BEGIN RoleScoper ADDITION: exemption for content administrators
     if (is_content_administrator_rs()) {
         return $results;
     }
     // === END RoleScoper ADDITION ===
     // === BEGIN RoleScoper MODIFICATION: wp-cache key and flag specific to access type and user/groups --//
     //
     global $current_rs_user;
     $ckey = md5(serialize($r) . CURRENT_ACCESS_NAME_RS);
     $cache_flag = 'rs_get_bookmarks';
     $cache = $current_rs_user->cache_get($cache_flag);
     if (false !== $cache) {
         if (!is_array($cache)) {
             $cache = array();
         }
         if (isset($cache[$ckey])) {
             //alternate filter name (WP core already called get_bookmarks filter)
             return apply_filters('get_bookmarks_rs', $cache[$ckey], $r);
         }
     }
     //
     // === END RoleScoper MODIFICATION ===
     // ===================================
     $inclusions = '';
     if (!empty($include)) {
         $exclude = '';
         //ignore exclude, category, and category_name params if using include
         $category = '';
         $category_name = '';
         $inclinks = wp_parse_id_list($include);
         if (count($inclinks)) {
             foreach ($inclinks as $inclink) {
                 if (empty($inclusions)) {
                     $inclusions = ' AND ( link_id = ' . intval($inclink) . ' ';
                 } else {
                     $inclusions .= ' OR link_id = ' . intval($inclink) . ' ';
                 }
             }
         }
     }
     if (!empty($inclusions)) {
         $inclusions .= ')';
     }
     $exclusions = '';
     if (!empty($exclude)) {
         $exlinks = wp_parse_id_list($exclude);
         if (count($exlinks)) {
             foreach ($exlinks as $exlink) {
                 if (empty($exclusions)) {
                     $exclusions = ' AND ( link_id <> ' . intval($exlink) . ' ';
                 } else {
                     $exclusions .= ' AND link_id <> ' . intval($exlink) . ' ';
                 }
             }
         }
     }
     if (!empty($exclusions)) {
         $exclusions .= ')';
     }
     if (!empty($category_name)) {
         if ($category = get_term_by('name', $category_name, 'link_category')) {
             $category = $category->term_id;
         } else {
             return array();
         }
     }
     if (!empty($search)) {
         $search = like_escape($search);
         $search = " AND ( (link_url LIKE '%{$search}%') OR (link_name LIKE '%{$search}%') OR (link_description LIKE '%{$search}%') ) ";
     }
     $category_query = '';
     $join = '';
     if (!empty($category)) {
         $incategories = wp_parse_id_list($category);
         if (count($incategories)) {
             foreach ($incategories as $incat) {
                 if (empty($category_query)) {
                     $category_query = ' AND ( tt.term_id = ' . intval($incat) . ' ';
                 } else {
                     $category_query .= ' OR tt.term_id = ' . intval($incat) . ' ';
                 }
             }
         }
     }
     if (!empty($category_query)) {
         $category_query .= ") AND taxonomy = 'link_category'";
         $join = " INNER JOIN {$wpdb->term_relationships} AS tr ON ({$wpdb->links}.link_id = tr.object_id) INNER JOIN {$wpdb->term_taxonomy} as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id";
     }
     if (get_option('links_recently_updated_time')) {
         $recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL " . get_option('links_recently_updated_time') . " MINUTE) >= NOW(), 1,0) as recently_updated ";
     } else {
         $recently_updated_test = '';
     }
     if ($show_updated) {
         $get_updated = ", UNIX_TIMESTAMP(link_updated) AS link_updated_f ";
     } else {
         $get_updated = '';
     }
     $orderby = strtolower($orderby);
     $length = '';
     switch ($orderby) {
         case 'length':
             $length = ", CHAR_LENGTH(link_name) AS length";
             break;
         case 'rand':
             $orderby = 'rand()';
             break;
         default:
             $orderparams = array();
             foreach (explode(',', $orderby) as $ordparam) {
                 $orderparams[] = 'link_' . trim($ordparam);
             }
             $orderby = implode(',', $orderparams);
     }
     if ('link_id' == $orderby) {
         $orderby = "{$wpdb->links}.link_id";
     }
     $visible = '';
     if ($hide_invisible) {
         $visible = "AND link_visible = 'Y'";
     }
     $query = "SELECT * {$length} {$recently_updated_test} {$get_updated} FROM {$wpdb->links} {$join} WHERE 1=1 {$visible} {$category_query}";
     $query .= " {$exclusions} {$inclusions} {$search}";
     $query .= " ORDER BY {$orderby} {$order}";
     if ($limit != -1) {
         $query .= " LIMIT {$limit}";
     }
     // === BEGIN RoleScoper MODIFICATION:  run query through scoping filter, cache key specific to user/group
     $query = apply_filters('objects_request_rs', $query, 'link', '', '');
     $results = scoper_get_results($query);
     // cache key and flag specific to access type and user/groups
     $cache[$ckey] = $results;
     $current_rs_user->cache_set($cache, $cache_flag);
     // alternate hook name (WP core already applied get_bookmarks)
     $links = apply_filters('get_bookmarks_rs', $results, $r);
     //
     // === END RoleScoper MODIFICATION ===
     // ===================================
     // === BEGIN RoleScoper ADDITION: memory cache akin to page_cache to assist bulk operations
     //
     global $scoper;
     $ilim = count($links);
     for ($i = 0; $i < $ilim; $i++) {
         $scoper->listed_ids['link'][$links[$i]->link_id] = true;
     }
     //
     // === END RoleScoper ADDITION ===
     // ===================================
     return $links;
 }
 function &build_blog_file_rules()
 {
     $new_rules = '';
     require_once dirname(__FILE__) . '/analyst_rs.php';
     if (!($attachment_results = ScoperAnalyst::identify_protected_attachments())) {
         return $new_rules;
     }
     global $wpdb;
     require_once dirname(__FILE__) . '/uploads_rs.php';
     $home_root = parse_url(get_option('home'));
     $home_root = trailingslashit($home_root['path']);
     $uploads = scoper_get_upload_info();
     $baseurl = trailingslashit($uploads['baseurl']);
     $arr_url = parse_url($baseurl);
     $rewrite_base = $arr_url['path'];
     $file_keys = array();
     $has_postmeta = array();
     if ($key_results = scoper_get_results("SELECT pm.meta_value, p.guid, p.ID FROM {$wpdb->postmeta} AS pm INNER JOIN {$wpdb->posts} AS p ON p.ID = pm.post_id WHERE pm.meta_key = '_rs_file_key'")) {
         foreach ($key_results as $row) {
             $file_keys[$row->guid] = $row->meta_value;
             $has_postmeta[$row->ID] = $row->meta_value;
         }
     }
     $new_rules = "<IfModule mod_rewrite.c>\n";
     $new_rules .= "RewriteEngine On\n";
     $new_rules .= "RewriteBase {$rewrite_base}\n\n";
     $main_rewrite_rule = "RewriteRule ^(.*) {$home_root}index.php?attachment=\$1&rs_rewrite=1 [NC,L]\n";
     $htaccess_urls = array();
     foreach ($attachment_results as $row) {
         if (false !== strpos($row->guid, $baseurl)) {
             // no need to include any attachments which are not in the uploads folder
             if (!empty($file_keys[$row->guid])) {
                 $key = $file_keys[$row->guid];
             } else {
                 $key = urlencode(str_replace('.', '', uniqid(strval(rand()), true)));
                 $file_keys[$row->guid] = $key;
             }
             if (!isset($has_postmeta[$row->ID]) || $key != $has_postmeta[$row->ID]) {
                 update_post_meta($row->ID, "_rs_file_key", $key);
             }
             if (isset($htaccess_urls[$row->guid])) {
                 // if a file is attached to multiple protected posts, use a single rewrite rule for it
                 continue;
             }
             $htaccess_urls[$row->guid] = true;
             $rel_path = str_replace($baseurl, '', $row->guid);
             // escape spaces
             $file_path = str_replace(' ', '\\s', $rel_path);
             // escape horiz tabs (yes, at least one user has them in filenames)
             $file_path = str_replace(chr(9), '\\t', $file_path);
             // strip out all other nonprintable characters.  Affected files will not be filtered, but we avoid 500 error.  Possible TODO: advisory in file attachment utility
             $file_path = preg_replace('/[\\x00-\\x1f\\x7f]/', '', $file_path);
             // escape all other regular expression operator characters
             $file_path = preg_replace('/[\\^\\$\\.\\+\\[\\]\\(\\)\\{\\}]/', '\\\\$0', $file_path);
             $new_rules .= "RewriteCond %{REQUEST_URI} ^(.*)/{$file_path}" . "\$ [NC]\n";
             $new_rules .= "RewriteCond %{QUERY_STRING} !^(.*)rs_file_key={$key}(.*)\n";
             $new_rules .= $main_rewrite_rule;
             if ($pos_ext = strrpos($file_path, '\\.')) {
                 $thumb_path = substr($file_path, 0, $pos_ext);
                 $ext = substr($file_path, $pos_ext + 2);
                 $new_rules .= "RewriteCond %{REQUEST_URI} ^(.*)/{$thumb_path}" . '-[0-9]{2,4}x[0-9]{2,4}\\.' . $ext . "\$ [NC]\n";
                 $new_rules .= "RewriteCond %{QUERY_STRING} !^(.*)rs_file_key={$key}(.*)\n";
                 $new_rules .= $main_rewrite_rule;
                 // if resized image file(s) exist, include rules for them
                 $guid_pos_ext = strrpos($rel_path, '.');
                 $pattern = $uploads['path'] . '/' . substr($rel_path, 0, $guid_pos_ext) . '-??????????????' . substr($rel_path, $guid_pos_ext);
                 if (glob($pattern)) {
                     $new_rules .= "RewriteCond %{REQUEST_URI} ^(.*)/{$thumb_path}" . '-[0-9,a-f]{14}\\.' . $ext . "\$ [NC]\n";
                     $new_rules .= "RewriteCond %{QUERY_STRING} !^(.*)rs_file_key={$key}(.*)\n";
                     $new_rules .= $main_rewrite_rule;
                 }
             }
         }
     }
     // end foreach protected attachment
     if (IS_MU_RS) {
         global $blog_id;
         $file_filtered_sites = (array) get_site_option('scoper_file_filtered_sites');
         if (!in_array($blog_id, $file_filtered_sites)) {
             // this site needs a file redirect rule in root .htaccess
             scoper_flush_site_rules();
         }
         if (defined('SCOPER_MU_FILE_PROCESSING')) {
             // unless SCOPER_MU_FILE_PROCESSING is defined (indicating blogs.php has been modified for compatibility), blogs.php processing will be bypassed for all files
             $content_path = trailingslashit(str_replace($strip_path, '', str_replace('\\', '/', WP_CONTENT_DIR)));
             $new_rules .= "\n# Default WordPress cache handling\n";
             $new_rules .= "RewriteRule ^(.*) {$content_path}blogs.php?file=\$1 [L]\n";
         }
     }
     $new_rules .= "</IfModule>\n";
     return $new_rules;
 }
示例#25
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;
    }
}
示例#26
0
 function get_term_roles_daterange($taxonomy = 'category', $role_type = 'rs', $args = array())
 {
     $defaults = array('enforce_duration_limits' => true, 'retrieve_content_date_limits' => true, 'include_role_duration_key' => false, 'no_cache' => false);
     $args = array_merge($defaults, (array) $args);
     extract($args);
     $taxonomy = sanitize_key($taxonomy);
     global $wpdb;
     if ($enforce_duration_limits = $enforce_duration_limits && scoper_get_option('role_duration_limits')) {
         $duration_clause = $enforce_duration_limits ? scoper_get_duration_clause() : '';
         $no_cache = $no_cache || strpos($duration_clause, 'start_date_gmt') || strpos($duration_clause, 'end_date_gmt');
     } else {
         $duration_clause = '';
     }
     $no_cache = $no_cache || $include_role_duration_key || !$retrieve_content_date_limits;
     if (!$no_cache) {
         $cache_flag = "{$role_type}_term-roles_{$taxonomy}";
         // changed cache key from "term_roles" to "term-roles" to prevent retrieval of arrays stored without date_key dimension
         $tx_term_roles = $this->cache_get($cache_flag);
     } else {
         $tx_term_roles = '';
     }
     if (!is_array($tx_term_roles)) {
         // no need to check for this on cache retrieval, since a role_type change results in a rol_defs change, which triggers a full scoper cache flush
         $tx_term_roles = array('' => array());
         $u_g_clause = $this->get_user_clause('uro');
         $extra_cols = $include_role_duration_key ? ", uro.date_limited, uro.start_date_gmt, uro.end_date_gmt" : '';
         $qry = "SELECT uro.obj_or_term_id, uro.role_name, uro.assignment_id, uro.content_date_limited, uro.content_min_date_gmt, uro.content_max_date_gmt {$extra_cols} FROM {$wpdb->user2role2object_rs} AS uro ";
         $qry .= "WHERE uro.scope = 'term' AND uro.assign_for IN ('entity', 'both') AND uro.role_type = 'rs' AND uro.src_or_tx_name = '{$taxonomy}' {$duration_clause} {$u_g_clause}";
         if ($results = scoper_get_results($qry)) {
             foreach ($results as $termrole) {
                 $date_key = $retrieve_content_date_limits && $termrole->content_date_limited ? serialize((object) array('content_min_date_gmt' => $termrole->content_min_date_gmt, 'content_max_date_gmt' => $termrole->content_max_date_gmt)) : '';
                 $role_handle = 'rs_' . $termrole->role_name;
                 if ($include_role_duration_key) {
                     $role_duration_key = $termrole->date_limited ? serialize((object) array('start_date_gmt' => $termrole->start_date_gmt, 'end_date_gmt' => $termrole->end_date_gmt)) : '';
                     $tx_term_roles[$role_duration_key][$date_key][$role_handle][] = $termrole->obj_or_term_id;
                 } else {
                     $tx_term_roles[$date_key][$role_handle][] = $termrole->obj_or_term_id;
                 }
             }
         }
         if (!$no_cache) {
             $this->cache_set($tx_term_roles, $cache_flag);
         }
     }
     if ($retrieve_content_date_limits && !$include_role_duration_key) {
         // normal usage (only internal call to skip this block is for user profile)
         $this->assigned_term_roles[$taxonomy] = $tx_term_roles;
         global $scoper;
         if (!empty($scoper)) {
             // this method is only called after Scoper is initialized, but include this sanity check
             foreach (array_keys($this->assigned_term_roles[$taxonomy]) as $date_key) {
                 // strip out any assignments for roles which are no longer defined (such as Revisionary roles after Revisionary is deactivated)
                 $this->assigned_term_roles[$taxonomy][$date_key] = array_intersect_key($this->assigned_term_roles[$taxonomy][$date_key], $scoper->role_defs->role_caps);
                 $this->term_roles[$taxonomy][$date_key] = $scoper->role_defs->add_contained_term_roles($this->assigned_term_roles[$taxonomy][$date_key]);
             }
             // support legacy template code using $current_user->term_roles or $current_user->assigned_term_roles
             if (!awp_ver('3.3-dev')) {
                 if ($this->ID == $GLOBALS['current_user']->ID) {
                     $GLOBALS['current_user']->assigned_term_roles[$taxonomy] = $this->assigned_term_roles[$taxonomy];
                     $GLOBALS['current_user']->term_roles[$taxonomy] = $this->term_roles[$taxonomy];
                 }
             }
         }
     }
     return $tx_term_roles;
 }
 function flt_objects_listing($results, $src_name, $object_types, $args = array())
 {
     global $wpdb;
     // it's not currently necessary or possible to log listed revisions from here
     //if ( isset($wpdb->last_query) && strpos( $wpdb->last_query, "post_type = 'revision'") )
     //	return $results;
     // if currently listed IDs are not already in post_cache, make our own equivalent memcache
     // ( create this cache for any data source, front end or admin )
     if ('post' == $src_name) {
         global $wp_object_cache;
     }
     $listed_ids = array();
     //if ( ('post' != $src_name) || empty($wp_object_cache->cache['posts']) ) {
     if (empty($this->scoper->listed_ids[$src_name])) {
         if ($col_id = $this->scoper->data_sources->member_property($src_name, 'cols', 'id')) {
             $listed_ids = array();
             // In edit.php, WP forces all objects into recordset for hierarchical post types.  But for perf enchancement, we need to know IDs of items which are actually listed
             if ('edit.php' == $GLOBALS['pagenow']) {
                 $post_type = !empty($_GET['post_type']) ? sanitize_key($_GET['post_type']) : 'post';
                 $determine_listed_ids = !is_content_administrator_rs() && is_post_type_hierarchical($post_type) && !empty($GLOBALS['query_interceptor']->last_request[$src_name]) && !strpos($GLOBALS['query_interceptor']->last_request[$src_name], 'LIMIT ');
                 if ($determine_listed_ids) {
                     // mimic recordset paging used in edit.php
                     $pagenum = isset($_GET['paged']) ? absint($_GET['paged']) : 0;
                     if (empty($pagenum)) {
                         $pagenum = 1;
                     }
                     $edit_per_page = 'edit_' . $post_type . '_per_page';
                     $per_page = (int) get_user_option($edit_per_page);
                     if (empty($per_page) || $per_page < 1) {
                         $per_page = 20;
                     }
                     $per_page = apply_filters($edit_per_page, $per_page);
                     $per_page = apply_filters('edit_posts_per_page', $per_page, $post_type);
                     if (count($results) <= $per_page) {
                         $determine_listed_ids = false;
                     }
                 }
             } else {
                 $determine_listed_ids = false;
             }
             if ($determine_listed_ids) {
                 // Construct and execute a secondary query (for IDs only) which includes the paging clause that would be used if edit.php did not defeat it
                 $pgstrt = ($pagenum - 1) * $per_page . ', ';
                 $limits = ' LIMIT ' . $pgstrt . $per_page;
                 global $wpdb;
                 $qry = $GLOBALS['query_interceptor']->last_request[$src_name] . $limits;
                 $qry = str_replace("{$wpdb->posts}.*", "{$wpdb->posts}.ID", $qry);
                 $_results = scoper_get_results($qry);
                 foreach ($_results as $row) {
                     if (isset($row->{$col_id})) {
                         $listed_ids[$row->{$col_id}] = true;
                     }
                 }
             } else {
                 // No secondary query, just buffer all IDs in the results set
                 foreach ($results as $row) {
                     if (isset($row->{$col_id})) {
                         $listed_ids[$row->{$col_id}] = true;
                     }
                 }
             }
             if (empty($this->scoper->listed_ids)) {
                 $this->scoper->listed_ids = array();
             }
             $this->scoper->listed_ids[$src_name] = $listed_ids;
         }
     } else {
         return $results;
     }
     //}
     // now determine what restrictions were in place on these results
     // (currently only for post data source, front end or manage posts/pages)
     //
     // possible todo: support other data sources, WP role type
     if ('edit.php' == $GLOBALS['pagenow']) {
         if (scoper_get_otype_option('restrictions_column', 'post') || scoper_get_otype_option('term_roles_column', 'post') || scoper_get_otype_option('object_roles_column', 'post')) {
             global $scoper_role_usage;
             require_once dirname(__FILE__) . '/role_usage_rs.php';
             $scoper_role_usage = new Role_Usage_RS();
             $scoper_role_usage->determine_role_usage_rs('post', $listed_ids);
         }
     }
     return $results;
 }
示例#28
0
 function users_who_can($reqd_caps, $cols = COLS_ALL_RS, $object_src_name = '', $object_id = 0, $args = array())
 {
     // if there are not capability requirements, no need to load Users_Interceptor filtering class
     if (!$reqd_caps) {
         if (COL_ID_RS == $cols) {
             $qcols = 'ID';
         } elseif (COLS_ID_NAME_RS == $cols) {
             $qcols = "ID, user_login AS display_name";
         } elseif (COLS_ID_DISPLAYNAME_RS == $cols) {
             $qcols = "ID, display_name";
         } elseif (COLS_ALL_RS == $cols) {
             $qcols = "*";
         } else {
             $qcols = $cols;
         }
         global $wpdb;
         $orderby = $cols == COL_ID_RS ? '' : 'ORDER BY display_name';
         if (IS_MU_RS && !scoper_get_option('mu_sitewide_groups') && !defined('FORCE_ALL_SITE_USERS_RS')) {
             $qry = "SELECT {$qcols} FROM {$wpdb->users} INNER JOIN {$wpdb->usermeta} AS um ON {$wpdb->users}.ID = um.user_id AND um.meta_key = '{$wpdb->prefix}capabilities' {$orderby}";
         } else {
             $qry = "SELECT {$qcols} FROM {$wpdb->users} {$orderby}";
         }
         if (COL_ID_RS == $cols) {
             return scoper_get_col($qry);
         } else {
             return scoper_get_results($qry);
         }
     } else {
         $defaults = array('where' => '', 'orderby' => '', 'disable_memcache' => false, 'group_ids' => '', 'force_refresh' => false, 'force_all_users' => false);
         $args = array_merge($defaults, (array) $args);
         extract($args);
         $cache_flag = "rs_users_who_can";
         $cache_id = md5(serialize($reqd_caps) . $cols . 'src' . $object_src_name . 'id' . $object_id . serialize($args));
         if (!$force_refresh) {
             // if we already have the results cached, no need to load Users_Interceptor filtering class
             $users = wpp_cache_get($cache_id, $cache_flag);
             if (is_array($users)) {
                 return $users;
             }
         }
         $this->init_users_interceptor();
         $users = $GLOBALS['users_interceptor']->users_who_can($reqd_caps, $cols, $object_src_name, $object_id, $args);
         wpp_cache_set($cache_id, $users, $cache_flag);
         return $users;
     }
 }
 function identify_protected_posts($attachment_id = 0, $attachments = false, $cols = '', $args = array())
 {
     $defaults = array('use_object_restrictions' => true, 'use_term_restrictions' => true, 'use_private_status' => true, 'guid' => '');
     $args = array_merge($defaults, (array) $args);
     extract($args);
     global $wpdb, $scoper;
     if (!isset($scoper) || is_null($scoper)) {
         scoper_get_init_options();
         scoper_init();
     }
     if (empty($scoper->taxonomies)) {
         $scoper->load_config();
     }
     $restricted_roles = array();
     $unrestricted_roles = array();
     // TODO: also protect uploads based on restriction of other taxonomies
     $restricted_terms = array();
     $restricted_objects = array();
     $term_restriction_clause = '';
     $object_restriction_clause = '';
     $limit_clause = '';
     $unattached_clause = '';
     global $scoper;
     $reader_roles = array();
     foreach ($scoper->role_defs->role_caps as $role_handle => $role_caps) {
         $caps_by_op = $scoper->cap_defs->organize_caps_by_op(array_keys($role_caps));
         if (count($caps_by_op) == 1 && 'read' == key($caps_by_op)) {
             $reader_roles[] = $role_handle;
         }
     }
     $role_clause = "AND rs.role_name IN ('" . implode("','", scoper_role_handles_to_names($reader_roles)) . "')";
     //if ( $use_private_status )
     //	$role_clause = ( 'rs' == SCOPER_ROLE_TYPE ) ? "AND rs.role_name IN ('post_reader', 'page_reader')" : '';	// if also checking for private status, don't need to check for restriction of private_reader roles
     //else
     //	$role_clause = ( 'rs' == SCOPER_ROLE_TYPE ) ? "AND rs.role_name IN ('post_reader', 'page_reader', 'private_post_reader', 'private_page_reader')" : '';
     if ($use_term_restrictions) {
         $term_restriction_query = "SELECT rs.obj_or_term_id AS term_id, rs.role_name, rs.max_scope FROM {$wpdb->role_scope_rs} AS rs " . "INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.taxonomy = rs.src_or_tx_name AND tt.taxonomy = 'category' AND tt.term_taxonomy_id = rs.obj_or_term_id " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('entity', 'both') AND rs.topic = 'term' {$role_clause}";
         $term_default_restriction_query = "SELECT rs.role_name FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('children', 'both') AND rs.topic = 'term' AND rs.max_scope = 'term' AND rs.src_or_tx_name = 'category' AND rs.obj_or_term_id = '0' {$role_clause}";
         $all_terms = array();
         $all_terms['category'] = $scoper->get_terms('category', false, COL_ID_RS);
         if ($results = scoper_get_results($term_restriction_query)) {
             foreach ($results as $row) {
                 if ('blog' == $row->max_scope) {
                     $unrestricted_roles['category'][$row->role_name][] = $row->term_id;
                 } else {
                     $restricted_roles['category'][$row->role_name][] = $row->term_id;
                 }
             }
         }
         // if there a role is default-restricted, mark all terms as restricted (may be unrestricted later)
         if ($results = scoper_get_col($term_default_restriction_query)) {
             foreach ($results as $role_name) {
                 if (isset($unrestricted_roles['category'][$role_name])) {
                     $default_restricted = array_diff($all_terms['category'], $unrestricted_roles['category'][$role_name]);
                 } else {
                     $default_restricted = $all_terms['category'];
                 }
                 if (isset($restricted_roles['category'][$role_name])) {
                     $restricted_roles['category'][$role_name] = array_unique(array_merge($restricted_roles['category'][$role_name], $default_restricted));
                 } else {
                     $restricted_roles['category'][$role_name] = $default_restricted;
                 }
             }
         }
         $restricted_terms['category'] = isset($restricted_roles['category']) ? agp_array_flatten($restricted_roles['category']) : array();
         if ($restricted_terms['category']) {
             $term_restriction_clause = "OR post_parent IN ( SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} " . "INNER JOIN {$wpdb->term_relationships} AS tr ON tr.object_id = {$wpdb->posts}.ID " . "WHERE tr.term_taxonomy_id IN ('" . implode("','", $restricted_terms['category']) . "') )";
         }
     }
     if ($attachment_id) {
         if (is_array($attachment_id)) {
             $id_clause = "AND ID IN ('" . implode("','", $attachment_id) . "')";
         } else {
             $id_clause = "AND ID = '{$attachment_id}'";
             $limit_clause = 'LIMIT 1';
         }
     } elseif ($guid) {
         $id_clause = "AND guid = '{$file_path}'";
     } else {
         $id_clause = '';
     }
     if (defined('SCOPER_NO_THUMBNAIL_FILTER')) {
         if ($thumbnail_ids = scoper_get_col("SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_thumbnail_id'")) {
             $id_clause .= " AND ID NOT IN ('" . implode("','", $thumbnail_ids) . "')";
         }
     }
     if ($attachments) {
         // to reduce pool of objects, we only care about those that have an attachment
         $attachment_query = "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE {$wpdb->posts}.ID IN ( SELECT post_parent FROM {$wpdb->posts} WHERE post_type = 'attachment' {$id_clause} ) ";
     }
     if ($use_object_restrictions) {
         $object_restriction_query = "SELECT rs.obj_or_term_id AS obj_id, rs.role_name, rs.max_scope FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.role_type = 'rs' AND rs.require_for IN ('entity', 'both') AND rs.topic = 'object' AND rs.src_or_tx_name = 'post' {$role_clause} AND rs.obj_or_term_id IN ( {$attachment_query} )";
         $object_default_restriction_query = "SELECT rs.role_name FROM {$wpdb->role_scope_rs} AS rs " . "WHERE rs.require_for IN ('children', 'both') AND rs.topic = 'object' AND rs.max_scope = 'object' AND rs.src_or_tx_name = 'post' AND rs.obj_or_term_id = '0' {$role_clause}";
         $all_objects = array();
         $all_objects['post'] = scoper_get_col($attachment_query);
         $restricted_roles = array();
         $unrestricted_roles = array();
         if ($results = scoper_get_results($object_restriction_query)) {
             foreach ($results as $row) {
                 if ('blog' == $row->max_scope) {
                     $unrestricted_roles['post'][$row->role_name][] = $row->obj_id;
                 } else {
                     $restricted_roles['post'][$row->role_name][] = $row->obj_id;
                 }
             }
         }
         // if there a role is default-restricted, mark all terms as restricted (may be unrestricted later)
         if ($results = scoper_get_col($object_default_restriction_query)) {
             foreach ($results as $role_name) {
                 if (isset($unrestricted_roles['category'][$role_name])) {
                     $default_restricted = array_diff($all_terms['post'], $unrestricted_roles['post'][$role_name]);
                 } else {
                     $default_restricted = $all_objects['post'];
                 }
                 if (isset($restricted_roles['post'][$role_name])) {
                     $restricted_roles['post'][$role_name] = array_unique(array_merge($restricted_roles['post'][$role_name], $default_restricted));
                 } else {
                     $restricted_roles['post'][$role_name] = $default_restricted;
                 }
             }
         }
         if (!empty($restricted_roles)) {
             $restricted_objects['post'] = array_unique(agp_array_flatten($restricted_roles['post']));
             if ($restricted_objects['post']) {
                 $object_restriction_clause = "OR post_parent IN ( SELECT ID FROM {$wpdb->posts} WHERE ID IN ('" . implode("','", $restricted_objects['post']) . "') )";
             }
         }
     }
     if ($use_private_status) {
         $status_query = "AND post_parent IN ( SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_status = 'private' )";
     }
     if ($attachments) {
         $attachment_type_clause = "post_type = 'attachment' AND";
         $unattached_clause = defined('SCOPER_BLOCK_UNATTACHED_UPLOADS') ? " OR post_parent < 1" : '';
     }
     $single_col = false;
     if (COLS_ALL_RS === $cols) {
         $query_cols = '*';
     } elseif (COL_ID_RS == $cols) {
         $query_cols = 'ID';
         $single_col = true;
     } elseif (COLS_ID_DISPLAYNAME_RS == $cols) {
         if ($attachment) {
             $query_cols = 'ID, post_title, guid';
         } else {
             $query_cols = 'ID, post_title';
         }
     } else {
         if ($attachments) {
             $query_cols = 'ID, guid';
         } else {
             $query_cols = 'ID';
             $single_col = true;
         }
     }
     $query = "SELECT {$query_cols} FROM {$wpdb->posts} WHERE {$attachment_type_clause} ( 1=1 {$status_query} {$term_restriction_clause} {$object_restriction_clause} {$unattached_clause} ) {$id_clause} ORDER BY ID DESC {$limit_clause}";
     if ($attachment_id && !is_array($attachment_id)) {
         if ($single_col) {
             $results = scoper_get_var($query);
         } else {
             $results = scoper_get_row($query);
         }
     } else {
         if ($single_col) {
             $results = scoper_get_col($query);
         } else {
             $results = scoper_get_results($query);
         }
     }
     return $results;
 }
 function _user_can_read_file($file, &$return_attachment_id, &$matched_published_post, $uploads = '')
 {
     // don't filter the direct file URL request if filtering is disabled, or if the request is from wp-admin
     if (defined('DISABLE_QUERYFILTERS_RS') || is_content_administrator_rs() || !scoper_get_option('file_filtering') || !empty($_SERVER['HTTP_REFERER']) && false !== strpos($_SERVER['HTTP_REFERER'], '/wp-admin') && false !== strpos($_SERVER['HTTP_REFERER'], get_option('siteurl') . '/wp-admin')) {
         // note: image links from wp-admin should now never get here due to http_referer RewriteRule, but leave above check just in case - inexpensive since we're checking for wp-admin before calling get_option
         //rs_errlog("skipping filtering for $file");
         return true;
     }
     if (!is_array($uploads) || empty($uploads['basedir'])) {
         require_once dirname(__FILE__) . '/uploads_rs.php';
         $uploads = scoper_get_upload_info();
     }
     //rs_errlog('_user_can_read_file');
     $file_path = $uploads['basedir'] . "/{$file}";
     //rs_errlog("$file_path exists.");
     global $wpdb, $wp_query;
     $file_url = $uploads['baseurl'] . "/{$file}";
     // auto-resized copies have -NNNxNNN suffix, but the base filename is stored as attachment.  Strip the suffix out for db query.
     $orig_file_url = preg_replace("/-[0-9]{2,4}x[0-9]{2,4}./", '.', $file_url);
     // manually resized copies have -?????????????? suffix, but the base filename is stored as attachment.  Strip the suffix out for db query.
     $orig_file_url = preg_replace("/-[0-9,a-z]{14}./", '.', $orig_file_url);
     $qry = "SELECT * FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent > 0 AND guid = '{$orig_file_url}'";
     $results = scoper_get_results($qry);
     $matched_published_post = array();
     $return_attachment_id = 0;
     if (empty($results)) {
         $args = array('skip_any_object_check' => true, 'skip_any_term_check' => true);
         return cr_user_can('edit_others_posts', 0, 0, $args) || cr_user_can('edit_others_pages', 0, 0, $args);
     } else {
         // set global flag (checked by flt_user_has_cap, which filters current_user_Can)
         global $scoper_checking_attachment_access;
         $scoper_checking_attachment_access = true;
         foreach ($results as $attachment) {
             //rs_errlog( "found attachment: " . serialize($attachment) );
             if (is_content_administrator_rs()) {
                 $return_attachment_id = $attachment->ID;
                 break;
             }
             if ($attachment->post_parent) {
                 if ($parent_post = scoper_get_row("SELECT post_type, post_status FROM {$wpdb->posts} WHERE ID = '{$attachment->post_parent}' LIMIT 1")) {
                     $object_type = $parent_post->post_type;
                     $containing_post_status = $parent_post->post_status;
                     // Only return content that is attached to published (potentially including private) posts/pages
                     // If some other statuses for published posts are introduced in later WP versions,
                     // the failure mode here will be to overly suppress attachments
                     if ('publish' == $containing_post_status || 'private' == $containing_post_status) {
                         if (current_user_can("read_{$object_type}", $attachment->post_parent)) {
                             $return_attachment_id = $attachment->ID;
                             break;
                         } else {
                             global $current_user;
                             $matched_published_post[$object_type] = $attachment->post_name;
                         }
                     }
                 }
             }
         }
         // clear global flag
         $scoper_checking_attachment_access = false;
     }
     if ($return_attachment_id) {
         return true;
     }
 }