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

Revision 3356, 48.4 kB (checked in by ryan, 3 years ago)

Fix page permalink 404 when pages are reordered. Props David House. fixes #2071

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