| 1 | Index: wp-includes/plugin.php |
|---|
| 2 | =================================================================== |
|---|
| 3 | --- wp-includes/plugin.php (revision 17624) |
|---|
| 4 | +++ wp-includes/plugin.php (working copy) |
|---|
| 5 | @@ -72,6 +72,31 @@ |
|---|
| 6 | } |
|---|
| 7 | |
|---|
| 8 | /** |
|---|
| 9 | + * Hooks a function or method to a specific filter action, specifying a required context for application. |
|---|
| 10 | + * |
|---|
| 11 | + * @package WordPress |
|---|
| 12 | + * @subpackage Plugin |
|---|
| 13 | + * @global array $wp_filter Stores all of the filters added in the form of |
|---|
| 14 | + * wp_filter['tag']['array of priorities']['array of functions serialized']['array of ['array (functions, accepted_args)']'] |
|---|
| 15 | + * @global array $merged_filters Tracks the tags that need to be merged for later. If the hook is added, it doesn't need to run through that process. |
|---|
| 16 | + * |
|---|
| 17 | + * @param string $tag The name of the filter to hook the $function_to_add to. |
|---|
| 18 | + * @param callback $function_to_add The name of the function to be called when the filter is applied. |
|---|
| 19 | + * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action. |
|---|
| 20 | + * @param int $accepted_args optional. The number of arguments the function accept (default 1). |
|---|
| 21 | + * @param string $context optional. Context to require for filter application (default ''). Nullstring means filter is applied for all query contexts. |
|---|
| 22 | + * @return boolean true |
|---|
| 23 | + */ |
|---|
| 24 | +function add_query_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1, $context = '') { |
|---|
| 25 | + global $wp_filter, $merged_filters; |
|---|
| 26 | + |
|---|
| 27 | + $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); |
|---|
| 28 | + $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args, 'context' => $context); |
|---|
| 29 | + unset( $merged_filters[ $tag ] ); |
|---|
| 30 | + return true; |
|---|
| 31 | +} |
|---|
| 32 | + |
|---|
| 33 | +/** |
|---|
| 34 | * Check if any filter has been registered for a hook. |
|---|
| 35 | * |
|---|
| 36 | * @package WordPress |
|---|
| 37 | @@ -173,7 +198,72 @@ |
|---|
| 38 | return $value; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | + |
|---|
| 42 | /** |
|---|
| 43 | + * Call the functions added to a query filter hook, applying return value validation and context check. |
|---|
| 44 | + * |
|---|
| 45 | + * @package WordPress |
|---|
| 46 | + * @subpackage Plugin |
|---|
| 47 | + * @global array $wp_filter Stores all of the filters |
|---|
| 48 | + * @global array $merged_filters Merges the filter hooks using this function. |
|---|
| 49 | + * @global array $wp_current_filter stores the list of current filters with the current one last |
|---|
| 50 | + * |
|---|
| 51 | + * @param string $tag The name of the filter hook. |
|---|
| 52 | + * @param mixed $value The value on which the filters hooked to <tt>$tag</tt> are applied on. |
|---|
| 53 | + * @param object $query_obj Query object which triggered filter application. |
|---|
| 54 | + * @return mixed The filtered value after all hooked functions are applied to it. |
|---|
| 55 | + */ |
|---|
| 56 | +function apply_query_filters($tag, $value, $query_obj) { |
|---|
| 57 | + global $wp_filter, $merged_filters, $wp_current_filter; |
|---|
| 58 | + |
|---|
| 59 | + $wp_current_filter[] = $tag; |
|---|
| 60 | + |
|---|
| 61 | + // Do 'all' actions first |
|---|
| 62 | + if ( isset($wp_filter['all']) ) { |
|---|
| 63 | + _wp_call_all_hook( func_get_args() ); |
|---|
| 64 | + } |
|---|
| 65 | + |
|---|
| 66 | + if ( !isset($wp_filter[$tag]) ) { |
|---|
| 67 | + array_pop($wp_current_filter); |
|---|
| 68 | + return $value; |
|---|
| 69 | + } |
|---|
| 70 | + |
|---|
| 71 | + // Sort |
|---|
| 72 | + if ( !isset( $merged_filters[ $tag ] ) ) { |
|---|
| 73 | + ksort($wp_filter[$tag]); |
|---|
| 74 | + $merged_filters[ $tag ] = true; |
|---|
| 75 | + } |
|---|
| 76 | + |
|---|
| 77 | + reset( $wp_filter[ $tag ] ); |
|---|
| 78 | + |
|---|
| 79 | + $context = $query_obj->query_vars['query_context']; |
|---|
| 80 | + |
|---|
| 81 | + do { |
|---|
| 82 | + foreach( (array) current($wp_filter[$tag]) as $the_ ) { |
|---|
| 83 | + // Each valid filter hooked to this tag is applied if it was not added for a specific context or if the current context matches |
|---|
| 84 | + if ( !is_null($the_['function']) && ( empty($the_['context']) || ( $context == $the_['context'] ) ) ) { |
|---|
| 85 | + if ( (int) $the_['accepted_args'] > 1 ) |
|---|
| 86 | + $_value = call_user_func($the_['function'], $value, $query_obj); |
|---|
| 87 | + else |
|---|
| 88 | + $_value = call_user_func($the_['function'], $value); |
|---|
| 89 | + |
|---|
| 90 | + if ( is_null($_value) ) { |
|---|
| 91 | + if ( WP_DEBUG ) { |
|---|
| 92 | + trigger_error( sprintf( __('Query filter returned null value for %s hook.'), $tag ), E_USER_WARNING ); |
|---|
| 93 | + } |
|---|
| 94 | + } else |
|---|
| 95 | + $value = $_value; |
|---|
| 96 | + } |
|---|
| 97 | + } |
|---|
| 98 | + |
|---|
| 99 | + } while ( next($wp_filter[$tag]) !== false ); |
|---|
| 100 | + |
|---|
| 101 | + array_pop( $wp_current_filter ); |
|---|
| 102 | + |
|---|
| 103 | + return $value; |
|---|
| 104 | +} |
|---|
| 105 | + |
|---|
| 106 | +/** |
|---|
| 107 | * Execute functions hooked on a specific filter hook, specifying arguments in an array. |
|---|
| 108 | * |
|---|
| 109 | * @see apply_filters() This function is identical, but the arguments passed to the |
|---|
| 110 | Index: wp-includes/query.php |
|---|
| 111 | =================================================================== |
|---|
| 112 | --- wp-includes/query.php (revision 17624) |
|---|
| 113 | +++ wp-includes/query.php (working copy) |
|---|
| 114 | @@ -1369,6 +1369,7 @@ |
|---|
| 115 | , 's' |
|---|
| 116 | , 'sentence' |
|---|
| 117 | , 'fields' |
|---|
| 118 | + , 'query_context' |
|---|
| 119 | ); |
|---|
| 120 | |
|---|
| 121 | foreach ( $keys as $key ) { |
|---|
| 122 | @@ -2167,7 +2168,7 @@ |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | // Allow plugins to contextually add/remove/modify the search section of the database query |
|---|
| 126 | - $search = apply_filters_ref_array('posts_search', array( $search, &$this ) ); |
|---|
| 127 | + $search = apply_query_filters('posts_search', $search, $this); |
|---|
| 128 | |
|---|
| 129 | // Taxonomies |
|---|
| 130 | if ( !$this->is_singular ) { |
|---|
| 131 | @@ -2483,8 +2484,8 @@ |
|---|
| 132 | // Apply filters on where and join prior to paging so that any |
|---|
| 133 | // manipulations to them are reflected in the paging by day queries. |
|---|
| 134 | if ( !$q['suppress_filters'] ) { |
|---|
| 135 | - $where = apply_filters_ref_array('posts_where', array( $where, &$this ) ); |
|---|
| 136 | - $join = apply_filters_ref_array('posts_join', array( $join, &$this ) ); |
|---|
| 137 | + $where = apply_query_filters('posts_where', $where, $this); |
|---|
| 138 | + $join = apply_query_filters('posts_join', $join, $this); |
|---|
| 139 | } |
|---|
| 140 | |
|---|
| 141 | // Paging |
|---|
| 142 | @@ -2517,11 +2518,11 @@ |
|---|
| 143 | } |
|---|
| 144 | |
|---|
| 145 | if ( !$q['suppress_filters'] ) { |
|---|
| 146 | - $cjoin = apply_filters_ref_array('comment_feed_join', array( $cjoin, &$this ) ); |
|---|
| 147 | - $cwhere = apply_filters_ref_array('comment_feed_where', array( $cwhere, &$this ) ); |
|---|
| 148 | - $cgroupby = apply_filters_ref_array('comment_feed_groupby', array( $cgroupby, &$this ) ); |
|---|
| 149 | - $corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); |
|---|
| 150 | - $climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) ); |
|---|
| 151 | + $cjoin = apply_query_filters('comment_feed_join', $cjoin, $this); |
|---|
| 152 | + $cwhere = apply_query_filters('comment_feed_where', $cwhere, $this); |
|---|
| 153 | + $cgroupby = apply_query_filters('comment_feed_groupby', $cgroupby, $this); |
|---|
| 154 | + $corderby = apply_query_filters('comment_feed_orderby', 'comment_date_gmt DESC', $this); |
|---|
| 155 | + $climits = apply_query_filters('comment_feed_limits', 'LIMIT ' . get_option('posts_per_rss'), $this); |
|---|
| 156 | } |
|---|
| 157 | $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; |
|---|
| 158 | $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; |
|---|
| 159 | @@ -2549,16 +2550,16 @@ |
|---|
| 160 | // Apply post-paging filters on where and join. Only plugins that |
|---|
| 161 | // manipulate paging queries should use these hooks. |
|---|
| 162 | if ( !$q['suppress_filters'] ) { |
|---|
| 163 | - $where = apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) ); |
|---|
| 164 | - $groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) ); |
|---|
| 165 | - $join = apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) ); |
|---|
| 166 | - $orderby = apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) ); |
|---|
| 167 | - $distinct = apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) ); |
|---|
| 168 | - $limits = apply_filters_ref_array( 'post_limits', array( $limits, &$this ) ); |
|---|
| 169 | - $fields = apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) ); |
|---|
| 170 | + $where = apply_query_filters( 'posts_where_paged', $where, $this ); |
|---|
| 171 | + $groupby = apply_query_filters( 'posts_groupby', $groupby, $this ); |
|---|
| 172 | + $join = apply_query_filters( 'posts_join_paged', $join, $this ); |
|---|
| 173 | + $orderby = apply_query_filters( 'posts_orderby', $orderby, $this ); |
|---|
| 174 | + $distinct = apply_query_filters( 'posts_distinct', $distinct, $this ); |
|---|
| 175 | + $limits = apply_query_filters( 'post_limits', $limits, $this ); |
|---|
| 176 | + $fields = apply_query_filters( 'posts_fields', $fields, $this ); |
|---|
| 177 | |
|---|
| 178 | // Filter all clauses at once, for convenience |
|---|
| 179 | - $clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) ); |
|---|
| 180 | + $clauses = (array) apply_query_filters( 'posts_clauses', compact( $pieces ), $this ); |
|---|
| 181 | foreach ( $pieces as $piece ) |
|---|
| 182 | $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; |
|---|
| 183 | } |
|---|
| 184 | @@ -2568,16 +2569,16 @@ |
|---|
| 185 | |
|---|
| 186 | // Filter again for the benefit of caching plugins. Regular plugins should use the hooks above. |
|---|
| 187 | if ( !$q['suppress_filters'] ) { |
|---|
| 188 | - $where = apply_filters_ref_array( 'posts_where_request', array( $where, &$this ) ); |
|---|
| 189 | - $groupby = apply_filters_ref_array( 'posts_groupby_request', array( $groupby, &$this ) ); |
|---|
| 190 | - $join = apply_filters_ref_array( 'posts_join_request', array( $join, &$this ) ); |
|---|
| 191 | - $orderby = apply_filters_ref_array( 'posts_orderby_request', array( $orderby, &$this ) ); |
|---|
| 192 | - $distinct = apply_filters_ref_array( 'posts_distinct_request', array( $distinct, &$this ) ); |
|---|
| 193 | - $fields = apply_filters_ref_array( 'posts_fields_request', array( $fields, &$this ) ); |
|---|
| 194 | - $limits = apply_filters_ref_array( 'post_limits_request', array( $limits, &$this ) ); |
|---|
| 195 | + $where = apply_query_filters( 'posts_where_request', $where, $this ); |
|---|
| 196 | + $groupby = apply_query_filters( 'posts_groupby_request', $groupby, $this ); |
|---|
| 197 | + $join = apply_query_filters( 'posts_join_request', $join, $this ); |
|---|
| 198 | + $orderby = apply_query_filters( 'posts_orderby_request', $orderby, $this ); |
|---|
| 199 | + $distinct = apply_query_filters( 'posts_distinct_request', $distinct, $this ); |
|---|
| 200 | + $fields = apply_query_filters( 'posts_fields_request', $fields, $this ); |
|---|
| 201 | + $limits = apply_query_filters( 'post_limits_request', $limits, $this ); |
|---|
| 202 | |
|---|
| 203 | // Filter all clauses at once, for convenience |
|---|
| 204 | - $clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) ); |
|---|
| 205 | + $clauses = (array) apply_query_filters( 'posts_clauses_request', compact( $pieces ), $this ); |
|---|
| 206 | foreach ( $pieces as $piece ) |
|---|
| 207 | $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; |
|---|
| 208 | } |
|---|
| 209 | @@ -2593,7 +2594,7 @@ |
|---|
| 210 | |
|---|
| 211 | $this->request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; |
|---|
| 212 | if ( !$q['suppress_filters'] ) |
|---|
| 213 | - $this->request = apply_filters_ref_array('posts_request', array( $this->request, &$this ) ); |
|---|
| 214 | + $this->request = apply_query_filters('posts_request', $this->request, $this); |
|---|
| 215 | |
|---|
| 216 | if ( 'ids' == $q['fields'] ) { |
|---|
| 217 | $this->posts = $wpdb->get_col($this->request); |
|---|
| 218 | @@ -2615,25 +2616,25 @@ |
|---|
| 219 | |
|---|
| 220 | // Raw results filter. Prior to status checks. |
|---|
| 221 | if ( !$q['suppress_filters'] ) |
|---|
| 222 | - $this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) ); |
|---|
| 223 | + $this->posts = apply_query_filters('posts_results', $this->posts, $this); |
|---|
| 224 | |
|---|
| 225 | if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) { |
|---|
| 226 | - $cjoin = apply_filters_ref_array('comment_feed_join', array( '', &$this ) ); |
|---|
| 227 | - $cwhere = apply_filters_ref_array('comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) ); |
|---|
| 228 | - $cgroupby = apply_filters_ref_array('comment_feed_groupby', array( '', &$this ) ); |
|---|
| 229 | + $cjoin = apply_query_filters('comment_feed_join', '', $this); |
|---|
| 230 | + $cwhere = apply_query_filters('comment_feed_where', "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", $this); |
|---|
| 231 | + $cgroupby = apply_query_filters('comment_feed_groupby', '', $this); |
|---|
| 232 | $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; |
|---|
| 233 | - $corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); |
|---|
| 234 | + $corderby = apply_query_filters('comment_feed_orderby', 'comment_date_gmt DESC', $this); |
|---|
| 235 | $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; |
|---|
| 236 | - $climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) ); |
|---|
| 237 | + $climits = apply_query_filters('comment_feed_limits', 'LIMIT ' . get_option('posts_per_rss'), $this); |
|---|
| 238 | $comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits"; |
|---|
| 239 | $this->comments = $wpdb->get_results($comments_request); |
|---|
| 240 | $this->comment_count = count($this->comments); |
|---|
| 241 | } |
|---|
| 242 | |
|---|
| 243 | if ( !$q['no_found_rows'] && !empty($limits) ) { |
|---|
| 244 | - $found_posts_query = apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ); |
|---|
| 245 | + $found_posts_query = apply_query_filters( 'found_posts_query', 'SELECT FOUND_ROWS()', $this); |
|---|
| 246 | $this->found_posts = $wpdb->get_var( $found_posts_query ); |
|---|
| 247 | - $this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) ); |
|---|
| 248 | + $this->found_posts = apply_query_filters( 'found_posts', $this->found_posts, $this); |
|---|
| 249 | $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); |
|---|
| 250 | } |
|---|
| 251 | |
|---|
| 252 | @@ -2666,7 +2667,7 @@ |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | if ( $this->is_preview && current_user_can( $edit_cap, $this->posts[0]->ID ) ) |
|---|
| 256 | - $this->posts[0] = apply_filters_ref_array('the_preview', array( $this->posts[0], &$this )); |
|---|
| 257 | + $this->posts[0] = apply_query_filters('the_preview', $this->posts[0], $this); |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | // Put sticky posts at the top of the posts array |
|---|
| 261 | @@ -2720,7 +2721,7 @@ |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | if ( !$q['suppress_filters'] ) |
|---|
| 265 | - $this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) ); |
|---|
| 266 | + $this->posts = apply_query_filters('the_posts', $this->posts, $this); |
|---|
| 267 | |
|---|
| 268 | $this->post_count = count($this->posts); |
|---|
| 269 | |
|---|