root/tags/1.5.1.3/wp-includes/classes.php

Revision 2535, 36.2 kB (checked in by ryan, 3 years ago)

Fix post paging regex to avoid regex collision between posts with slugs that differ only by a trailing number. http://mosquito.wordpress.org/view.php?id=1235

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2
3 class WP_Query {
4     var $query;
5     var $query_vars;
6     var $queried_object;
7     var $queried_object_id;
8
9     var $posts;
10     var $post_count = 0;
11     var $current_post = -1;
12     var $post;
13
14     var $is_single = false;
15     var $is_page = false;
16     var $is_archive = false;
17     var $is_date = false;
18     var $is_year = false;
19     var $is_month = false;
20     var $is_day = false;
21     var $is_time = false;
22     var $is_author = false;
23     var $is_category = false;
24     var $is_search = false;
25     var $is_feed = false;
26     var $is_trackback = false;
27     var $is_home = false;
28     var $is_404 = false;
29     var $is_comments_popup = false;
30     var $is_admin = false;
31
32     function init () {
33         $this->is_single = false;
34         $this->is_page = false;
35         $this->is_archive = false;
36         $this->is_date = false;
37         $this->is_year = false;
38         $this->is_month = false;
39         $this->is_day = false;
40         $this->is_time = false;
41         $this->is_author = false;
42         $this->is_category = false;
43         $this->is_search = false;
44         $this->is_feed = false;
45         $this->is_trackback = false;
46         $this->is_home = false;
47         $this->is_404 = false;
48         $this->is_paged = false;
49         $this->is_admin = false;
50
51         unset($this->posts);
52         unset($this->query);
53         unset($this->query_vars);
54         unset($this->queried_object);
55         unset($this->queried_object_id);
56         $this->post_count = 0;
57         $this->current_post = -1;
58     }
59
60     // Reparse the query vars.
61     function parse_query_vars() {
62         $this->parse_query('');
63     }
64
65     // Parse a query string and set query type booleans.
66     function parse_query ($query) {
67         if ( !empty($query) || !isset($this->query) ) {
68             $this->init();
69             parse_str($query, $qv);
70             $this->query = $query;
71             $this->query_vars = $qv;
72         }
73
74         $qv['m'] =  (int) $qv['m'];
75         $qv['p'] =  (int) $qv['p'];
76
77         if ('' != $qv['name']) {
78             $this->is_single = true;
79         } elseif ( $qv['p'] ) {
80             $this->is_single = true;
81         } elseif (('' != $qv['hour']) && ('' != $qv['minute']) &&('' != $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day'])) {
82             // If year, month, day, hour, minute, and second are set, a single
83           // post is being queried.       
84             $this->is_single = true;
85         } elseif ('' != $qv['static'] || '' != $qv['pagename'] || '' != $qv['page_id']) {
86             $this->is_page = true;
87             $this->is_single = false;
88         } elseif (!empty($qv['s'])) {
89             $this->is_search = true;
90         } else {
91         // Look for archive queries.  Dates, categories, authors.
92
93             if ( (int) $qv['second']) {
94                 $this->is_time = true;
95                 $this->is_date = true;
96             }
97
98             if ( (int) $qv['minute']) {
99                 $this->is_time = true;
100                 $this->is_date = true;
101             }
102
103             if ( (int) $qv['hour']) {
104                 $this->is_time = true;
105                 $this->is_date = true;
106             }
107
108             if ( (int) $qv['day']) {
109                 if (! $this->is_date) {
110                     $this->is_day = true;
111                     $this->is_date = true;
112                 }
113             }
114
115             if ( (int)  $qv['monthnum']) {
116                 if (! $this->is_date) {
117                     $this->is_month = true;
118                     $this->is_date = true;
119                 }
120             }
121
122             if ( (int)  $qv['year']) {
123                 if (! $this->is_date) {
124                     $this->is_year = true;
125                     $this->is_date = true;
126                 }
127             }
128
129             if ( (int)  $qv['m']) {
130                 $this->is_date = true;
131                 if (strlen($qv['m']) > 9) {
132                     $this->is_time = true;
133                 } else if (strlen($qv['m']) > 7) {
134                     $this->is_day = true;
135                 } else if (strlen($qv['m']) > 5) {
136                     $this->is_month = true;
137                 } else {
138                     $this->is_year = true;
139                 }
140             }
141
142             if ('' != $qv['w']) {
143                 $this->is_date = true;
144             }
145
146             if (empty($qv['cat']) || ($qv['cat'] == '0')) {
147                 $this->is_category = false;
148             } else {
149                 if (stristr($qv['cat'],'-')) {
150                     $this->is_category = false;
151                 } else {
152                     $this->is_category = true;
153                 }
154             }
155
156             if ('' != $qv['category_name']) {
157                 $this->is_category = true;
158             }
159             
160             if ((empty($qv['author'])) || ($qv['author'] == '0')) {
161                 $this->is_author = false;
162             } else {
163                 $this->is_author = true;
164             }
165
166             if ('' != $qv['author_name']) {
167                 $this->is_author = true;
168             }
169
170             if ( ($this->is_date || $this->is_author || $this->is_category)) {
171                 $this->is_archive = true;
172             }
173         }
174
175         if ('' != $qv['feed']) {
176             $this->is_feed = true;
177         }
178
179         if ('' != $qv['tb']) {
180             $this->is_trackback = true;
181         }
182
183         if ('404' == $qv['error']) {
184             $this->is_404 = true;
185         }
186
187         if ('' != $qv['paged']) {
188             $this->is_paged = true;
189         }
190
191         if ('' != $qv['comments_popup']) {
192             $this->is_comments_popup = true;
193         }
194
195         if (strstr($_SERVER['PHP_SELF'], 'wp-admin/')) {
196             $this->is_admin = true;
197         }
198
199         if ( ! ($this->is_archive || $this->is_single || $this->is_page || $this->is_search || $this->is_feed || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_comments_popup)) {
200             $this->is_home = true;
201         }
202
203         if ( !empty($query) ) {
204             do_action('parse_query', array(&$this));
205         }
206     }
207
208     function get($query_var) {
209         if (isset($this->query_vars[$query_var])) {
210             return $this->query_vars[$query_var];
211         }
212
213         return '';
214     }
215
216     function set($query_var, $value) {
217         $this->query_vars[$query_var] = $value;
218     }
219
220     function &get_posts() {
221         global $wpdb, $pagenow, $request, $user_ID;
222
223         // Shorthand.
224         $q = $this->query_vars;   
225
226         // First let's clear some variables
227         $whichcat = '';
228         $whichauthor = '';
229         $result = '';
230         $where = '';
231         $limits = '';
232         $distinct = '';
233         $join = '';
234
235         if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
236             $q['posts_per_page'] = get_settings('posts_per_page');
237         if ( !isset($q['what_to_show']) )
238             $q['what_to_show'] = get_settings('what_to_show');
239         if ( isset($q['showposts']) && $q['showposts'] ) {
240             $q['showposts'] = (int) $q['showposts'];
241             $q['posts_per_page'] = $q['showposts'];
242         }
243         if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
244             $q['posts_per_page'] = $q['posts_per_archive_page'];
245         if ( !isset($q['nopaging']) ) {
246             if ($q['posts_per_page'] == -1) {
247                 $q['nopaging'] = true;
248             } else {
249                 $q['nopaging'] = false;
250             }
251         }
252         if ( $this->is_feed ) {
253             $q['posts_per_page'] = get_settings('posts_per_rss');
254             $q['what_to_show'] = 'posts';
255         }
256
257         if (isset($q['page'])) {
258             $q['page'] = trim($q['page'], '/');
259             $q['page'] = (int) $q['page'];
260         }
261     
262         $add_hours = intval(get_settings('gmt_offset'));
263         $add_minutes = intval(60 * (get_settings('gmt_offset') - $add_hours));
264         $wp_posts_post_date_field = "post_date"; // "DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)";
265
266         // If a month is specified in the querystring, load that month
267         if ( (int) $q['m'] ) {
268             $q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
269             $where .= ' AND YEAR(post_date)=' . substr($q['m'], 0, 4);
270             if (strlen($q['m'])>5)
271                 $where .= ' AND MONTH(post_date)=' . substr($q['m'], 4, 2);
272             if (strlen($q['m'])>7)
273                 $where .= ' AND DAYOFMONTH(post_date)=' . substr($q['m'], 6, 2);
274             if (strlen($q['m'])>9)
275                 $where .= ' AND HOUR(post_date)=' . substr($q['m'], 8, 2);
276             if (strlen($q['m'])>11)
277                 $where .= ' AND MINUTE(post_date)=' . substr($q['m'], 10, 2);
278             if (strlen($q['m'])>13)
279                 $where .= ' AND SECOND(post_date)=' . substr($q['m'], 12, 2);
280         }
281
282         if ( (int) $q['hour'] ) {
283             $q['hour'] = '' . intval($q['hour']);
284             $where .= " AND HOUR(post_date)='" . $q['hour'] . "'";
285         }
286
287         if ( (int) $q['minute'] ) {
288             $q['minute'] = '' . intval($q['minute']);
289             $where .= " AND MINUTE(post_date)='" . $q['minute'] . "'";
290         }
291
292         if ( (int) $q['second'] ) {
293             $q['second'] = '' . intval($q['second']);
294             $where .= " AND SECOND(post_date)='" . $q['second'] . "'";
295         }
296
297         if ( (int) $q['year'] ) {
298             $q['year'] = '' . intval($q['year']);
299             $where .= " AND YEAR(post_date)='" . $q['year'] . "'";
300         }
301
302         if ( (int) $q['monthnum'] ) {
303             $q['monthnum'] = '' . intval($q['monthnum']);
304             $where .= " AND MONTH(post_date)='" . $q['monthnum'] . "'";
305         }
306
307         if ( (int) $q['day'] ) {
308             $q['day'] = '' . intval($q['day']);
309             $where .= " AND DAYOFMONTH(post_date)='" . $q['day'] . "'";
310         }
311
312         if ('' != $q['name']) {
313             $q['name'] = sanitize_title($q['name']);
314             $where .= " AND post_name = '" . $q['name'] . "'";
315         } else if ('' != $q['pagename']) {
316             $q['pagename'] = sanitize_title(basename(str_replace('%2F', '/', urlencode($q['pagename']))));
317             $q['name'] = $q['pagename'];
318             $where .= " AND post_name = '" . $q['pagename'] . "'";
319         }
320
321
322         if ( (int) $q['w'] ) {
323             $q['w'] = ''.intval($q['w']);
324             $where .= " AND WEEK(post_date, 1)='" . $q['w'] . "'";
325         }
326
327         if ( intval($q['comments_popup']) )
328             $q['p'] = intval($q['comments_popup']);
329
330         // If a post number is specified, load that post
331         if (($q['p'] != '') && intval($q['p']) != 0) {
332             $q['p'] =  (int) $q['p'];
333             $where = ' AND ID = ' . $q['p'];
334         }
335
336         if (($q['page_id'] != '') && (intval($q['page_id']) != 0)) {
337             $q['page_id'] = intval($q['page_id']);
338             $q['p'] = $q['page_id'];
339             $where = ' AND ID = '.$q['page_id'];
340         }
341
342         // If a search pattern is specified, load the posts that match
343         if (!empty($q['s'])) {
344             $q['s'] = addslashes_gpc($q['s']);
345             $search = ' AND (';
346             $q['s'] = preg_replace('/, +/', ' ', $q['s']);
347             $q['s'] = str_replace(',', ' ', $q['s']);
348             $q['s'] = str_replace('"', ' ', $q['s']);
349             $q['s'] = trim($q['s']);
350             if ($q['exact']) {
351                 $n = '';
352             } else {
353                 $n = '%';
354             }
355             if (!$q['sentence']) {
356                 $s_array = explode(' ',$q['s']);
357                 $q['search_terms'] = $s_array;
358                 $search .= '((post_title LIKE \''.$n.$s_array[0].$n.'\') OR (post_content LIKE \''.$n.$s_array[0].$n.'\'))';
359                 for ( $i = 1; $i < count($s_array); $i = $i + 1) {
360                     $search .= ' AND ((post_title LIKE \''.$n.$s_array[$i].$n.'\') OR (post_content LIKE \''.$n.$s_array[$i].$n.'\'))';
361                 }
362                 $search .= ' OR (post_title LIKE \''.$n.$q['s'].$n.'\') OR (post_content LIKE \''.$n.$q['s'].$n.'\')';
363                 $search .= ')';
364             } else {
365                 $search = ' AND ((post_title LIKE \''.$n.$q['s'].$n.'\') OR (post_content LIKE \''.$n.$q['s'].$n.'\'))';
366             }
367         }
368
369         // Category stuff
370
371         if ((empty($q['cat'])) || ($q['cat'] == '0') ||
372                 // Bypass cat checks if fetching specific posts
373                 ( $this->is_single || $this->is_page )) {
374             $whichcat='';
375         } else {
376             $q['cat'] = ''.urldecode($q['cat']).'';
377             $q['cat'] = addslashes_gpc($q['cat']);
378             if (stristr($q['cat'],'-')) {
379                 // Note: if we have a negative, we ignore all the positives. It must
380                 // always mean 'everything /except/ this one'. We should be able to do
381                 // multiple negatives but we don't :-(
382                 $eq = '!=';
383                 $andor = 'AND';
384                 $q['cat'] = explode('-',$q['cat']);
385                 $q['cat'] = intval($q['cat'][1]);
386             } else {
387                 $eq = '=';
388                 $andor = 'OR';
389             }
390             $join = " LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) ";
391             $cat_array = preg_split('/[,\s]+/', $q['cat']);
392             $whichcat .= ' AND (category_id '.$eq.' '.intval($cat_array[0]);
393             $whichcat .= get_category_children($cat_array[0], ' '.$andor.' category_id '.$eq.' ');
394             for ($i = 1; $i < (count($cat_array)); $i = $i + 1) {
395                 $whichcat .= ' '.$andor.' category_id '.$eq.' '.intval($cat_array[$i]);
396                 $whichcat .= get_category_children($cat_array[$i], ' '.$andor.' category_id '.$eq.' ');
397             }
398