public static function flt_posts_request($request, $args = array()) { if (pp_unfiltered()) { return $request; } $defaults = array('post_types' => array(), 'source_alias' => '', 'only_append_where' => ''); $args = array_merge($defaults, $args); extract($args, EXTR_SKIP); global $wpdb, $query_interceptor; if (apply_filters('pp_posts_request_bypass', false, $request, $args)) { return $request; } //d_echo( "<br />flt_objects_request: $request<br />" ); if (!preg_match('/\\s*WHERE\\s*1=1/', $request)) { $request = preg_replace('/\\s*WHERE\\s*/', ' WHERE 1=1 AND ', $request); } $clauses = array(); $pos_where = 0; $pos_suffix = 0; $clauses['where'] = agp_parse_after_WHERE_11($request, $pos_where, $pos_suffix); // NOTE: any existing where, orderby or group by clauses remain in $where if (!$pos_where && $pos_suffix) { $request = substr($request, 0, $pos_suffix) . ' WHERE 1=1' . substr($request, $pos_suffix); $pos_where = $pos_suffix; } if (!$only_append_where) { if (!isset($args['source_alias'])) { // If the query uses an alias for the posts table, be sure to use that alias in the WHERE clause also. // // NOTE: if query refers to non-active site, this code will prevent a DB syntax error, but will not cause the correct roles / statuses to be applied. // Other plugins need to use switch_to_blog() rather than just executing a query on a non-main site. $matches = array(); if ($return = preg_match('/SELECT .* FROM [^ ]+posts AS ([^ ]) .*/', $request, $matches)) { $args['source_alias'] = $matches[2]; } elseif ($return = preg_match('/SELECT .* FROM ([^ ]+)posts .*/', $request, $matches)) { $args['source_alias'] = $matches[1] . 'posts'; } } if (false !== strpos($request, ' COUNT( * ) AS num_posts')) { $args['include_trash'] = true; } // attachment filtering is applied here $clauses['where'] = apply_filters('pp_posts_clauses_where', $query_interceptor->flt_posts_where($clauses['where'], $args), $clauses, $args); } //dump($clauses); if ($pos_where === false) { $request .= " WHERE 1=1 {$only_append_where} " . $clauses['where']; } else { $request = substr($request, 0, $pos_where) . " WHERE 1=1 {$only_append_where} " . $clauses['where']; } // any pre-exising join clauses remain in $request //d_echo( "<br /><br />filtered: $request<br /><br />" ); return $request; }
function flt_objects_request($request, $src_name, $object_types = '', $args = array()) { if ($args) { $defaults = array('skip_teaser' => false); $args = array_diff_key($args, array_flip(array('request', 'src_name', 'object_types'))); $args = array_merge($defaults, (array) $args); extract($args); } // if Media Library filtering is disabled, don't filter listing for TinyMCE popup either if (is_admin() && defined('SCOPER_ALL_UPLOADS_EDITABLE') && strpos($_SERVER['SCRIPT_NAME'], 'wp-admin/media-upload.php')) { return $request; } // Filtering in user_has_cap sufficiently controls revision access; a match here should be for internal, pre-validation purposes if (strpos($request, "post_type = 'revision'")) { return $request; } // no need to apply objects query filtering within NextGEN Gallery / Grand Flash Gallery upload operation (was failing with undefined $current_user) if (is_admin()) { if (defined('SCOPER_ALL_UPLOADS_EDITABLE') && $GLOBALS['pagenow'] == 'upload.php') { return $request; } $nofilter_scripts = array('/admin/upload.php'); if ($nofilter_scripts = apply_filters('noqueryfilter_scripts_rs', $nofilter_scripts)) { foreach ($nofilter_scripts as $_script_name) { if (false !== strpos($_SERVER['SCRIPT_NAME'], $_script_name)) { return $request; } } } } // prevent hardway-admin filtering of any queries which may be triggered by this filter $GLOBALS['scoper_status']->querying_db = true; if (empty($skip_teaser)) { $this->last_request[$src_name] = $request; // Store for potential use by subsequent teaser filter } //$request = agp_force_distinct($request); // in case data source didn't provide a hook for objects_distinct if (!preg_match('/\\s*WHERE\\s*1=1/', $request)) { $request = preg_replace('/\\s*WHERE\\s*/', ' WHERE 1=1 AND ', $request); } $pos_where = 0; $pos_suffix = 0; $where = agp_parse_after_WHERE_11($request, $pos_where, $pos_suffix); // any existing where, orderby or group by clauses remain in $where if (!$pos_where && $pos_suffix) { $request = substr($request, 0, $pos_suffix) . ' WHERE 1=1' . substr($request, $pos_suffix); $pos_where = $pos_suffix; } if ('post' == $src_name) { // If the query uses an alias for the posts table, be sure to use that alias in the WHERE clause also. // // NOTE: if query refers to non-active blog, this code will prevent a DB syntax error, but will not cause the correct roles / restrictions to be applied. // Other plugins need to use switch_to_blog() rather than just executing a query on a non-main blog. $matches = array(); if ($return = preg_match('/SELECT .* FROM [^ ]+posts AS ([^ ]) .*/', $request, $matches)) { $args['source_alias'] = $matches[2]; } elseif ($return = preg_match('/SELECT .* FROM ([^ ]+)posts .*/', $request, $matches)) { $args['source_alias'] = $matches[1] . 'posts'; } } // TODO: abstract this if (strpos($request, "post_type = 'attachment'")) { global $wpdb; if (!is_admin() && !empty($_REQUEST['attachment_id']) && !defined('SCOPER_BLOCK_UNATTACHED_UPLOADS')) { if ($_att = get_post($_REQUEST['attachment_id'])) { if (0 === $_att->post_parent) { return $request; } } } // filter attachments by inserting a scoped subquery based on user roles on the post/page attachment is tied to $rs_where = $this->flt_objects_where('', $src_name, '', $args); $subqry = "SELECT ID FROM {$wpdb->posts} WHERE 1=1 {$rs_where}"; if (is_admin()) { // The listed objects are attachments, so query filter is based on objects they inherit from $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 = $this->scoper->user_can_edit_blogwide('post', '', array('require_others_cap' => true, 'status' => 'publish')); } global $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 (is_admin() && (!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}'"; $request = str_replace("{$wpdb->posts}.post_type = 'attachment'", "( {$wpdb->posts}.post_type = 'attachment' AND ( {$unattached_clause} ( {$wpdb->posts}.post_parent IN ({$subqry}) {$attached_clause} ) ) )", $request); } else { $request = str_replace("{$wpdb->posts}.post_type = 'attachment'", "( {$wpdb->posts}.post_type = 'attachment' AND ( {$wpdb->posts}.post_parent IN ({$subqry}) ) )", $request); } } else { // Generate a query filter based on roles for the listed objects $rs_where = $this->flt_objects_where($where, $src_name, $object_types, $args); if ($pos_where === false) { $request = $request . ' WHERE 1=1 ' . $where; } else { $request = substr($request, 0, $pos_where) . ' WHERE 1=1 ' . $rs_where; } // any pre-exising join clauses remain in $request } // re-enable hardway-admin filtering $GLOBALS['scoper_status']->querying_db = false; //d_echo( "<br />filtered: $request<br /><br />" ); return $request; }