function flt_recent_comments($query)
 {
     // Due to missing get_comments hook prior to WP 3.1, this filter operates on every front-end query.
     // If query doesn't pertain to comments, skip out with as little overhead as possible.
     if (strpos($query, 'comment') && strpos($query, "ELECT") && !strpos($query, 'posts as parent') && !strpos($query, "COUNT") && strpos($query, "comment_approved")) {
         if (!is_attachment() && !is_content_administrator_rs()) {
             global $wpdb;
             if (strpos($query, " {$wpdb->posts} ")) {
                 return $query;
             }
             if (awp_is_plugin_active('wp-wall')) {
                 $options = WPWall_GetOptions();
                 if (strpos($query, 'comment_post_ID=' . $options['pageId'])) {
                     return $query;
                 }
             }
             if (strpos($query, $wpdb->comments)) {
                 $query = str_replace(" post_status = 'publish'", " {$wpdb->posts}.post_status = 'publish'", $query);
                 // theoretically, a slight performance enhancement if we can simplify the query to skip filtering of attachment comments
                 if (defined('SCOPER_NO_ATTACHMENT_COMMENTS') || false !== strpos($query, 'comment_post_ID =')) {
                     if (!strpos($query, "JOIN {$wpdb->posts}")) {
                         $query = preg_replace("/FROM\\s*{$wpdb->comments}\\s*WHERE /", "FROM {$wpdb->comments} INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID WHERE ", $query);
                     }
                     $query = apply_filters('objects_request_rs', $query, 'post', '', array('skip_teaser' => true));
                 } else {
                     $query = str_replace("user_id ", "{$wpdb->comments}.user_id ", $query);
                     $query = str_replace("SELECT {$wpdb->comments}.* FROM {$wpdb->comments}", "SELECT DISTINCT {$wpdb->comments}.* FROM {$wpdb->comments}", $query);
                     if (!strpos($query, ' DISTINCT ')) {
                         $query = str_replace("SELECT ", "SELECT DISTINCT ", $query);
                     }
                     $post_types = array_diff(get_post_types(array('public' => true)), array('attachment'));
                     $post_type_in = "'" . implode("','", $post_types) . "'";
                     $join = "LEFT JOIN {$wpdb->posts} as parent ON parent.ID = {$wpdb->posts}.post_parent AND parent.post_type IN ({$post_type_in}) AND {$wpdb->posts}.post_type = 'attachment'";
                     $use_post_types = scoper_get_option('use_post_types');
                     $where = array();
                     foreach ($post_types as $type) {
                         if (!empty($use_post_types[$type])) {
                             $where_post = apply_filters('objects_where_rs', '', 'post', $type, array('skip_teaser' => true));
                         } else {
                             $where_post = "AND 1=1";
                         }
                         $where[] = "{$wpdb->posts}.post_type = '{$type}' {$where_post}";
                         $where[] = "{$wpdb->posts}.post_type = 'attachment' AND parent.post_type = '{$type}' " . str_replace("{$wpdb->posts}.", "parent.", $where_post);
                     }
                     $where = agp_implode(' ) OR ( ', $where, ' ( ', ' ) ');
                     if (!strpos($query, "JOIN {$wpdb->posts}")) {
                         $query = str_replace("WHERE ", "INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->comments}.comment_post_ID {$join} WHERE ( {$where} ) AND ", $query);
                     } else {
                         $query = str_replace("WHERE ", "{$join} WHERE {$where} AND ", $query);
                     }
                 }
             }
         }
     }
     return $query;
 }
 function TermsInterceptor_RS()
 {
     global $scoper;
     // flt_get_pages is required on the front end (even for administrators) to enable the inclusion of private pages
     // flt_get_terms '' so private posts are included in count, as basis for display when hide_empty arg is used
     if (($scoper->is_front() || !is_content_administrator_rs()) && (!defined('DOING_AUTOSAVE') || !DOING_AUTOSAVE)) {
         add_filter('get_terms_args', array(&$this, 'flt_get_terms_args'), 50, 2);
         add_filter('terms_clauses', array(&$this, 'flt_terms_clauses'), 50, 3);
         add_filter('get_terms', array(&$this, 'flt_get_terms'), 0, 3);
         // WPML registers at priority 1
         // Since the NOT IN subquery is a painful aberration for filtering, replace it with the separate term query used by WP prior to 2.7
         add_filter('posts_where', array($this, 'flt_cat_not_in_subquery'), 1);
     }
     $this->no_cache = defined('SCOPER_NO_TERMS_CACHE') || !defined('SCOPER_QTRANSLATE_COMPAT') && awp_is_plugin_active('qtranslate');
 }
示例#3
0
 function ScoperAdmin()
 {
     global $pagenow, $plugin_page_cr;
     $this->scoper =& $GLOBALS['scoper'];
     add_action('admin_head', array(&$this, 'admin_head_base'));
     if (!defined('DISABLE_QUERYFILTERS_RS') || is_content_administrator_rs()) {
         add_action('admin_head', array(&$this, 'admin_head'));
         if (!defined('XMLRPC_REQUEST') && 'async-upload.php' != $pagenow) {
             // New Network menu with WP 3.1
             if (defined('IS_MU_RS')) {
                 add_action('network_admin_menu', 'scoper_mu_site_menu');
                 add_action('network_admin_menu', 'scoper_mu_users_menu');
             }
             add_action('admin_menu', array(&$this, 'build_menu'));
             add_action('admin_menu', array(&$this, 'ngg_uploader_workaround'));
             add_action('admin_init', array(&$this, 'filter_add_new_content_links'));
             // changed from 'admin_menu' hook to work around WP 3.2 (as of RC1) removal of Edit submenu item if Add New is removed
             add_action('admin_print_scripts', array(&$this, 'filter_add_new_button'), 99);
             if ('plugins.php' == $pagenow) {
                 add_filter('plugin_row_meta', array(&$this, 'flt_plugin_action_links'), 10, 2);
             }
         }
     }
     if (defined('RVY_VERSION')) {
         require_once SCOPER_ABSPATH . '/revisionary-helper_rs.php';
     }
     if (('edit-tags.php' == $pagenow || isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], 'p-admin/edit-tags.php')) && awp_is_plugin_active('subscribe2')) {
         require_once dirname(__FILE__) . '/subscribe2_helper_rs.php';
     }
     if ('index.php' == $GLOBALS['pagenow']) {
         if (!defined('USE_RVY_RIGHTNOW')) {
             include_once dirname(__FILE__) . '/admin-dashboard_rs.php';
         }
         add_action('admin_notices', array(&$this, 'dashboard_notice'));
     }
     if (in_array($pagenow, array('edit.php', 'post.php')) && awp_ver('3.5-beta')) {
         add_action('admin_menu', array(&$this, 'reinstate_solo_submenus'));
         add_action('network_admin_menu', array(&$this, 'reinstate_solo_submenus'));
     }
     if (in_array($plugin_page_cr, array('rs-options', 'rs-about'))) {
         wp_enqueue_style('plugin-install');
         wp_enqueue_script('plugin-install');
         add_thickbox();
     }
 }
 function TemplateInterceptor_RS()
 {
     $this->scoper =& $GLOBALS['scoper'];
     if (scoper_get_option('strip_private_caption')) {
         add_filter('the_title', array(&$this, 'flt_title'), 10, 3);
         if (defined('WPLANG') && WPLANG) {
             add_filter('gettext', array(&$this, 'flt_gettext'), 10, 3);
         }
     }
     if (defined('SCOPER_FILTER_COMMENT_COUNT')) {
         add_filter('get_comments_number', array(&$this, 'flt_get_comments_number'));
     }
     // this filter should pass post_id as 2nd arg, but does not as of WP 2.7
     if (awp_is_plugin_active('events-calendar')) {
         add_filter('query', array(&$this, 'ec_getDaysEvents'));
     }
     if (awp_is_plugin_active('eventcalendar3')) {
         add_filter('query', array(&$this, 'ec3_query'));
     }
 }
 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_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;
 }
<?php

if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
    die;
}
add_filter('get_terms', array('ScoperHardwayFront', 'flt_get_tags'), 50, 3);
add_filter('get_the_category_for_list', array('ScoperHardwayFront', 'flt_get_the_category'));
// TODO: eliminate this - published in RS forum as a WP hack for use with a dev version
add_filter('get_the_category', array('ScoperHardwayFront', 'flt_get_the_category'), 10, 2);
// Todo: get this hook added to WP source
if (awp_is_plugin_active('snazzy-archives')) {
    add_filter('query', array('ScoperHardwayFront', 'flt_snazzy_archives'));
}
if (!awp_ver('3.3')) {
    add_action('admin_bar_menu', array('ScoperHardwayFront', 'flt_admin_bar_menu'), 50);
}
//if ( defined( 'SCOPER_FORCE_FRONTEND_JQUERY' ) )
//	add_action( 'wp_head', array('ScoperHardwayFront', 'include_jquery') );
add_action('wp_print_footer_scripts', array('ScoperHardwayFront', 'flt_hide_empty_menus'));
if (_rs_is_active_widget_prefix('calendar-')) {
    add_filter('query', array('ScoperHardwayFront', 'flt_calendar'));
}
function _rs_is_active_widget_prefix($id_prefix)
{
    global $wp_registered_widgets;
    foreach ((array) wp_get_sidebars_widgets() as $sidebar => $widgets) {
        if ('wp_inactive_widgets' != $sidebar && is_array($widgets)) {
            foreach ($widgets as $widget) {
                if (isset($wp_registered_widgets[$widget]['id']) && 0 === strpos($wp_registered_widgets[$widget]['id'], $id_prefix)) {
                    return $sidebar;
                }
function scoper_new_version_notice()
{
    $rechecked = false;
    $check_minutes = scoper_get_option('version_check_minutes');
    $last_check = scoper_get_option('last_version_update_check');
    if (time() - $last_check > $check_minutes * 60 || !($vcheck = get_site_option('scoper_version_info'))) {
        $vcheck = wp_remote_fopen('http://agapetry.net/downloads/role-scoper_version.chk');
        $rechecked = true;
        update_option('scoper_version_info', $vcheck);
    }
    if ($vcheck) {
        if (time() - $last_check > $check_minutes * 60 || !($vcheck_ext = get_site_option('scoper_extension_info'))) {
            $vcheck_ext = awp_remote_fopen('http://agapetry.net/downloads/role-scoper-extensions.chk', 5);
            $rechecked = true;
            update_option('scoper_extension_info', $vcheck_ext);
        }
    } else {
        $vcheck_ext = false;
    }
    if ($rechecked) {
        update_option('scoper_last_version_update_check', time());
    }
    if ($vcheck) {
        $status = explode('@', $vcheck);
        $theVersion = $status[1];
        if (version_compare(strval($theVersion), strval(SCOPER_VERSION), '>') == 1) {
            $msg = '<strong>' . sprintf(__("A new version of Role Scoper is available (%s)", "scoper"), $theVersion);
            if ($rechecked || !($vcheck = get_site_option('scoper_version_message'))) {
                $vcheck = awp_remote_fopen('http://agapetry.net/downloads/role-scoper.chk', 5);
                add_site_option('scoper_version_message', $vcheck);
            }
            if ($vcheck) {
                $status = explode('@', $vcheck);
                $theMessage = $status[3];
                if ($ver_pos = strpos($theMessage, '<br />' . SCOPER_VERSION)) {
                    $theMessage = substr($theMessage, 0, $ver_pos);
                }
                $theMessage = str_replace("'", '&#39;', $theMessage);
                // Despite this precaution, don't include apostrophes in .chk file because older RS versions (< 1.0.0-rc9) will choke on it.
                $theMessage = str_replace('"', '&quot;', $theMessage);
                $msg .= '</strong><small>' . $theMessage . '</small>';
            }
            if (strpos($msg, '<!--more-->')) {
                $more_caption = __('read more...', 'scoper');
                $msg = preg_replace('/\\<\\!\\-\\-more\\-\\-\\>/', '<a href="javascript:void(0)" onclick="rs_display_version_more();">' . $more_caption . '</a><p id="rs_version_more" class="rs_more" style="display:none;">', $msg, 1);
                $msg .= '</p>';
            } else {
                $msg .= '<br />';
            }
            $msg .= '<a href="http://agapetry.net/category/role-scoper/" target="_blank">' . __('Read about the update', 'scoper') . '</a>';
            $msg .= '&nbsp;&nbsp;&nbsp;<a href="http://wordpress.org/extend/plugins/role-scoper/changelog/" target="_blank">' . __('View full changelog', 'scoper') . '</a>';
            if (version_compare(strval($theVersion), '1.0.0', '>=')) {
                $url = awp_plugin_update_url(SCOPER_BASENAME);
                $msg .= '&nbsp;&nbsp;&nbsp;<a href="' . $url . '">' . __awp('Upgrade Automatically') . '</a>';
            } else {
                $msg .= '&nbsp;&nbsp;&nbsp;<a href="http://agapetry.net/downloads/role-scoper_current" target="_blank">' . __('Download for manual install', 'scoper') . '</a>';
            }
            // slick method copied from NextGEN Gallery plugin
            add_action('admin_notices', create_function('', 'echo \'<div id="rs-ver_msg" class="plugin-update rs-ver_msg fade" style="margin:0;"><p>' . $msg . '</p></div>\';'));
        }
    }
    if ($vcheck_ext) {
        $plugin_titles = array();
        $plugin_links = array();
        if ($extensions = explode(';', $vcheck_ext)) {
            foreach ($extensions as $ext) {
                if ($ext_info = explode(',', $ext)) {
                    if (count($ext_info) < 4) {
                        continue;
                    }
                    if (($plugin_file = awp_is_plugin_active($ext_info[0])) && !awp_is_plugin_active($ext_info[1])) {
                        $plugin_path = WP_CONTENT_DIR . '/plugins/' . $plugin_file;
                        if (file_exists($plugin_path)) {
                            $plugin_data = implode('', file($plugin_path));
                            preg_match('|Plugin Name:(.*)$|mi', $plugin_data, $name);
                            if ($name) {
                                $name = trim($name[1]);
                                $plugin_titles[$ext_info[0]] = $name;
                                if (false === strpos($ext_info[3], 'wp_repository') || false !== strpos($ext_info[3], 'is_alpha')) {
                                    $plugin_links[$ext_info[0]] = "http://agapetry.net/category/role-scoper-extensions/";
                                } else {
                                    $plugin_links[$ext_info[0]] = awp_plugin_info_url($ext_info[2]);
                                }
                            }
                        }
                    }
                }
            }
            $plugins = get_option('active_plugins');
            if ($plugin_titles) {
                $plugin_array = array();
                foreach ($plugin_titles as $name => $title) {
                    $plugin_array[] = "<a href=\"{$plugin_links[$name]}\">{$title}</a>";
                }
                $msg = '<strong>' . sprintf(__("Role Scoper Extensions are available for the following plugins: %s", "scoper"), implode(', ', $plugin_array)) . '</strong><br />';
                // slick method copied from NextGEN Gallery plugin
                add_action('admin_notices', create_function('', 'echo \'<div id="rs-ext_ver_msg" class="plugin-update rs-ver_msg fade"><p>' . $msg . '</p></div>\';'));
            }
        }
    }
}