hierarchical ) return; $stored_term = get_term_by( 'id', $_POST['tag_ID'], $taxonomy ); $selected_parent = $_POST['parent']; if ( -1 == $selected_parent ) $selected_parent = 0; if ( $stored_term->parent != $selected_parent ) { global $scoper; if ( $tx_obj = get_taxonomy( $taxonomy ) ) { if ( $selected_parent ) { $user_terms = $scoper->qualify_terms( $tx_obj->cap->manage_terms, $taxonomy ); $permit = in_array( $selected_parent, $user_terms ); } else { $permit = cr_user_can( $tx_obj->cap->manage_terms, 0, 0, array( 'skip_id_generation' => true, 'skip_any_term_check' => true ) ); } } if ( ! $permit ) wp_die( __('You do not have permission to select that Category Parent', 'scoper') ); } } elseif ( 'update-nav_menu' == $referer_name ) { $tx = get_taxonomy( 'nav_menu' ); $use_term_roles = scoper_get_otype_option( 'use_term_roles', 'post', 'nav_menu' ); if ( empty ( $GLOBALS['current_user']->allcaps['edit_theme_options'] ) || ! empty( $use_term_roles['nav_menu'] ) ) { if ( ! cr_user_can( $tx->cap->manage_terms, $_REQUEST['menu'], 0, array( 'skip_id_generation' => true, 'skip_any_term_check' => true ) ) ) { if ( $_REQUEST['menu'] ) wp_die( __('You do not have permission to update that Navigation Menu', 'scoper') ); else wp_die( __('You do not have permission to create new Navigation Menus', 'scoper') ); } } } elseif ( false !== strpos( $referer_name, 'delete-menu_item_' ) ) { if ( scoper_get_option( 'admin_nav_menu_filter_items' ) ) { $menu_item_id = substr( $referer_name, strlen( 'delete-menu_item_' ) ); require_once( SCOPER_ABSPATH . '/admin/filters-admin-nav_menus_rs.php' ); _rs_mnt_modify_nav_menu_item( $menu_item_id, 'delete' ); } } elseif ( $referer_name == 'move-menu_item' ) { if ( scoper_get_option( 'admin_nav_menu_filter_items' ) ) { require_once( SCOPER_ABSPATH . '/admin/filters-admin-nav_menus_rs.php' ); _rs_mnt_modify_nav_menu_item( $_REQUEST['menu-item'], 'move' ); } } elseif ( 'add-bookmark' == $referer_name ) { require_once( dirname(__FILE__).'/hardway-admin-links_rs.php' ); $link_category = ! empty( $_POST['link_category'] ) ? $_POST['link_category'] : array(); $_POST['link_category'] = scoper_flt_newlink_category( $link_category ); } elseif ( 0 === strpos( $referer_name, 'update-bookmark_' ) ) { require_once( dirname(__FILE__).'/hardway-admin-links_rs.php' ); $link_category = ! empty( $_POST['link_category'] ) ? $_POST['link_category'] : array(); $_POST['link_category'] = scoper_flt_link_category( $link_category ); } } // next-best way to handle permission checks for Ajax operations which can't be done via has_cap filter function act_check_ajax_referer( $referer_name ) { if ( 'add-tag' == $referer_name ) { if ( $tx_obj = get_taxonomy( $_POST['taxonomy'] ) ) $cap_name = $tx_obj->cap->manage_terms; if ( empty($cap_name) ) $cap_name = 'manage_categories'; // Concern here is for addition of top level terms. Subcat addition attempts will already be filtered by has_cap filter. if ( ( empty( $_POST['parent'] ) || $_POST['parent'] < 0 ) && ! cr_user_can( $cap_name, BLOG_SCOPE_RS ) ) die('-1'); } elseif ( 'add-link-category' == $referer_name ) { if ( ! cr_user_can( 'manage_categories', BLOG_SCOPE_RS ) ) die('-1'); } } function flt_last_resort_query($query) { static $in_process = false; if ( $in_process ) return $query; $in_process = true; $query = ScoperAdminHardway_Ltd::_flt_last_resort_query($query); $in_process = false; return $query; } // low-level filtering of otherwise unhookable queries // // Todo: review all queries for version-specificity; apply regular expressions to make it less brittle function _flt_last_resort_query($query) { // no recursion if ( scoper_querying_db() || $GLOBALS['cap_interceptor']->in_process ) return $query; global $wpdb, $pagenow, $scoper; $posts = $wpdb->posts; // Search on query portions to make this as forward-compatible as possible. // Important to include " FROM table WHERE " as a strpos requirement because scoped queries (which should not be further altered here) will insert a JOIN clause // strpos search for "ELECT " rather than "SELECT" so we don't have to distinguish 0 from false // wp_count_posts() : // SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s $matches = array(); if ( strpos($query, "ELECT post_status, COUNT( * ) AS num_posts ") && preg_match("/FROM\s*{$posts}\s*WHERE post_type\s*=\s*'([^ ]+)'/", $query, $matches) ) { $_post_type = ( ! empty( $matches[1] ) ) ? $matches[1] : cr_find_post_type(); if ( $_post_type ) { global $current_user; foreach( get_post_stati( array( 'private' => true ) ) as $_status ) $query = str_replace( "AND (post_status != '$_status' OR ( post_author = '{$current_user->ID}' AND post_status = '$_status' ))", '', $query); $query = str_replace( "post_status", "$posts.post_status", $query); $query = apply_filters( 'objects_request_rs', $query, 'post', $_post_type, array( 'objrole_revisions_clause' => true ) ); // as of WP 3.0.1, additional queries triggered by objects_request filter breaks all subsequent filters which would have operated on this query if ( defined( 'RVY_VERSION' ) ) { if ( class_exists( 'RevisionaryAdminHardway_Ltd' ) ) $query = RevisionaryAdminHardway_Ltd::flt_last_resort_query( $query ); $query = RevisionaryAdminHardway::flt_include_pending_revisions( $query ); } } return $query; } // parent_dropdown() : // SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' ORDER BY menu_order if ( 'admin.php' == $pagenow ) { if ( strpos ($query, "ELECT ID, post_parent, post_title") && strpos($query, "FROM $posts WHERE post_parent =") && function_exists('parent_dropdown') ) { $page_temp = ''; $object_id = $scoper->data_sources->detect( 'id', 'post' ); if ( $object_id ) $page_temp = get_post( $object_id ); if ( empty($page_temp) || ! isset($page_temp->post_parent) || $page_temp->post_parent ) { require_once( SCOPER_ABSPATH . '/hardway/hardway-parent-legacy_rs.php'); $output = ScoperHardwayParentLegacy::dropdown_pages(); echo $output; } $query = "SELECT ID, post_parent FROM $posts WHERE 1=2"; return $query; } } // Media Library - unattached // // WP_MediaListTable::get_views() : // SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' AND post_parent < 1 if ( strpos($query, "post_type = 'attachment'") && strpos($query, "post_parent < 1") && strpos($query, '* FROM') ) { if ( $where_pos = strpos($query, 'WHERE ') ) { // optionally hide other users' unattached uploads, but not from blog-wide Editors if ( ( ! scoper_get_option( 'admin_others_unattached_files' ) ) && ! $scoper->user_can_edit_blogwide( 'post', '', array( 'require_others_cap' => true, 'status' => 'publish' ) ) ) { global $current_user; $author_clause = "AND $wpdb->posts.post_author = '{$current_user->ID}'"; $query = str_replace( "post_type = 'attachment'", "post_type = 'attachment' $author_clause", $query); return $query; } } } // wp_count_attachments() : //SELECT post_mime_type, COUNT( * ) AS num_posts FROM wp_trunk_posts WHERE post_type = 'attachment' GROUP BY post_mime_type if ( strpos($query, "post_type = 'attachment'") && ( 0 === strpos($query, "SELECT " ) ) ) { if ( $where_pos = strpos($query, 'WHERE ') ) { if ( ! defined( 'SCOPER_ALL_UPLOADS_EDITABLE' ) ) { // note: this constant actually just prevents Media Library filtering, falling back to WP Roles for attachment editability and leaving uneditable uploads viewable in Library static $att_sanity_count = 0; if ( $att_sanity_count > 5 ) // TODO: why does this apply filtering to 300+ queries on at least one MS installation? return $query; $att_sanity_count++; $admin_others_attached = scoper_get_option( 'admin_others_attached_files' ); $admin_others_unattached = scoper_get_option( 'admin_others_unattached_files' ); if ( ( ! $admin_others_attached ) || ! $admin_others_unattached ) $can_edit_others_blogwide = $scoper->user_can_edit_blogwide( 'post', '', array( 'require_others_cap' => true, 'status' => 'publish' ) ); global $wpdb, $current_user; // optionally hide other users' unattached uploads, but not from blog-wide Editors if ( $admin_others_unattached || $can_edit_others_blogwide ) $author_clause = ''; else $author_clause = "AND $wpdb->posts.post_author = '{$current_user->ID}'"; if ( ! defined('SCOPER_BLOCK_UNATTACHED_UPLOADS') || ! SCOPER_BLOCK_UNATTACHED_UPLOADS ) $unattached_clause = "( $wpdb->posts.post_parent = 0 $author_clause ) OR"; else $unattached_clause = ''; $attached_clause = ( $admin_others_attached || $can_edit_others_blogwide ) ? '' : "AND $wpdb->posts.post_author = '{$current_user->ID}'"; $parent_query = "SELECT $wpdb->posts.ID FROM $wpdb->posts WHERE 1=1"; $parent_query = apply_filters('objects_request_rs', $parent_query, 'post' ); $where_insert = "( $unattached_clause ( $wpdb->posts.post_parent IN ($parent_query) $attached_clause ) ) AND "; $query = substr( $query, 0, $where_pos + strlen('WHERE ') ) . $where_insert . substr($query, $where_pos + strlen('WHERE ') ); } return $query; } } // admin-ajax.php 'find_posts' : // SELECT ID, post_title, post_status, post_date FROM $wpdb->posts WHERE post_type = '$what' AND post_status IN ('draft', 'publish') AND ($search) ORDER BY post_date_gmt DESC LIMIT 50 if ( strpos( $query, "ELECT ID, post_title, post_status, post_date FROM" ) ) { if ( ! empty( $_POST['post_type'] ) ) $query = apply_filters('objects_request_rs', $query, 'post', $_POST['post_type'] ); } return $query; } // end function flt_last_resort_query } // end class ?>