1 | <?php
|
---|
2 | /**
|
---|
3 | * Holds Most of the WordPress classes.
|
---|
4 | *
|
---|
5 | * Some of the other classes are contained in other files. For example, the
|
---|
6 | * WordPress cache is in cache.php and the WordPress roles API is in
|
---|
7 | * capabilities.php. The third party libraries are contained in their own
|
---|
8 | * separate files.
|
---|
9 | *
|
---|
10 | * @package WordPress
|
---|
11 | */
|
---|
12 |
|
---|
13 | /**
|
---|
14 | * WordPress environment setup class.
|
---|
15 | *
|
---|
16 | * @package WordPress
|
---|
17 | * @since 2.0.0
|
---|
18 | */
|
---|
19 | class WP {
|
---|
20 | /**
|
---|
21 | * Public query variables.
|
---|
22 | *
|
---|
23 | * Long list of public query variables.
|
---|
24 | *
|
---|
25 | * @since 2.0.0
|
---|
26 | * @access public
|
---|
27 | * @var array
|
---|
28 | */
|
---|
29 | var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage');
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Private query variables.
|
---|
33 | *
|
---|
34 | * Long list of private query variables.
|
---|
35 | *
|
---|
36 | * @since 2.0.0
|
---|
37 | * @var array
|
---|
38 | */
|
---|
39 | var $private_query_vars = array('offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_type', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page');
|
---|
40 |
|
---|
41 | /**
|
---|
42 | * Extra query variables set by the user.
|
---|
43 | *
|
---|
44 | * @since 2.1.0
|
---|
45 | * @var array
|
---|
46 | */
|
---|
47 | var $extra_query_vars = array();
|
---|
48 |
|
---|
49 | /**
|
---|
50 | * Query variables for setting up the WordPress Query Loop.
|
---|
51 | *
|
---|
52 | * @since 2.0.0
|
---|
53 | * @var array
|
---|
54 | */
|
---|
55 | var $query_vars;
|
---|
56 |
|
---|
57 | /**
|
---|
58 | * String parsed to set the query variables.
|
---|
59 | *
|
---|
60 | * @since 2.0.0
|
---|
61 | * @var string
|
---|
62 | */
|
---|
63 | var $query_string;
|
---|
64 |
|
---|
65 | /**
|
---|
66 | * Permalink or requested URI.
|
---|
67 | *
|
---|
68 | * @since 2.0.0
|
---|
69 | * @var string
|
---|
70 | */
|
---|
71 | var $request;
|
---|
72 |
|
---|
73 | /**
|
---|
74 | * Rewrite rule the request matched.
|
---|
75 | *
|
---|
76 | * @since 2.0.0
|
---|
77 | * @var string
|
---|
78 | */
|
---|
79 | var $matched_rule;
|
---|
80 |
|
---|
81 | /**
|
---|
82 | * Rewrite query the request matched.
|
---|
83 | *
|
---|
84 | * @since 2.0.0
|
---|
85 | * @var string
|
---|
86 | */
|
---|
87 | var $matched_query;
|
---|
88 |
|
---|
89 | /**
|
---|
90 | * Whether already did the permalink.
|
---|
91 | *
|
---|
92 | * @since 2.0.0
|
---|
93 | * @var bool
|
---|
94 | */
|
---|
95 | var $did_permalink = false;
|
---|
96 |
|
---|
97 | /**
|
---|
98 | * Add name to list of public query variables.
|
---|
99 | *
|
---|
100 | * @since 2.1.0
|
---|
101 | *
|
---|
102 | * @param string $qv Query variable name.
|
---|
103 | */
|
---|
104 | function add_query_var($qv) {
|
---|
105 | if ( !in_array($qv, $this->public_query_vars) )
|
---|
106 | $this->public_query_vars[] = $qv;
|
---|
107 | }
|
---|
108 |
|
---|
109 | /**
|
---|
110 | * Set the value of a query variable.
|
---|
111 | *
|
---|
112 | * @since 2.3.0
|
---|
113 | *
|
---|
114 | * @param string $key Query variable name.
|
---|
115 | * @param mixed $value Query variable value.
|
---|
116 | */
|
---|
117 | function set_query_var($key, $value) {
|
---|
118 | $this->query_vars[$key] = $value;
|
---|
119 | }
|
---|
120 |
|
---|
121 | /**
|
---|
122 | * Parse request to find correct WordPress query.
|
---|
123 | *
|
---|
124 | * Sets up the query variables based on the request. There are also many
|
---|
125 | * filters and actions that can be used to further manipulate the result.
|
---|
126 | *
|
---|
127 | * @since 2.0.0
|
---|
128 | *
|
---|
129 | * @param array|string $extra_query_vars Set the extra query variables.
|
---|
130 | */
|
---|
131 | function parse_request($extra_query_vars = '') {
|
---|
132 | global $wp_rewrite;
|
---|
133 |
|
---|
134 | $this->query_vars = array();
|
---|
135 | $taxonomy_query_vars = array();
|
---|
136 |
|
---|
137 | if ( is_array($extra_query_vars) )
|
---|
138 | $this->extra_query_vars = & $extra_query_vars;
|
---|
139 | else if (! empty($extra_query_vars))
|
---|
140 | parse_str($extra_query_vars, $this->extra_query_vars);
|
---|
141 |
|
---|
142 | // Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
|
---|
143 |
|
---|
144 | // Fetch the rewrite rules.
|
---|
145 | $rewrite = $wp_rewrite->wp_rewrite_rules();
|
---|
146 |
|
---|
147 | if (! empty($rewrite)) {
|
---|
148 | // If we match a rewrite rule, this will be cleared.
|
---|
149 | $error = '404';
|
---|
150 | $this->did_permalink = true;
|
---|
151 |
|
---|
152 | if ( isset($_SERVER['PATH_INFO']) )
|
---|
153 | $pathinfo = $_SERVER['PATH_INFO'];
|
---|
154 | else
|
---|
155 | $pathinfo = '';
|
---|
156 | $pathinfo_array = explode('?', $pathinfo);
|
---|
157 | $pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
|
---|
158 | $req_uri = $_SERVER['REQUEST_URI'];
|
---|
159 | $req_uri_array = explode('?', $req_uri);
|
---|
160 | $req_uri = $req_uri_array[0];
|
---|
161 | $self = $_SERVER['PHP_SELF'];
|
---|
162 | $home_path = parse_url(get_option('home'));
|
---|
163 | if ( isset($home_path['path']) )
|
---|
164 | $home_path = $home_path['path'];
|
---|
165 | else
|
---|
166 | $home_path = '';
|
---|
167 | $home_path = trim($home_path, '/');
|
---|
168 |
|
---|
169 | // Trim path info from the end and the leading home path from the
|
---|
170 | // front. For path info requests, this leaves us with the requesting
|
---|
171 | // filename, if any. For 404 requests, this leaves us with the
|
---|
172 | // requested permalink.
|
---|
173 | $req_uri = str_replace($pathinfo, '', rawurldecode($req_uri));
|
---|
174 | $req_uri = trim($req_uri, '/');
|
---|
175 | $req_uri = preg_replace("|^$home_path|", '', $req_uri);
|
---|
176 | $req_uri = trim($req_uri, '/');
|
---|
177 | $pathinfo = trim($pathinfo, '/');
|
---|
178 | $pathinfo = preg_replace("|^$home_path|", '', $pathinfo);
|
---|
179 | $pathinfo = trim($pathinfo, '/');
|
---|
180 | $self = trim($self, '/');
|
---|
181 | $self = preg_replace("|^$home_path|", '', $self);
|
---|
182 | $self = trim($self, '/');
|
---|
183 |
|
---|
184 | // The requested permalink is in $pathinfo for path info requests and
|
---|
185 | // $req_uri for other requests.
|
---|
186 | if ( ! empty($pathinfo) && !preg_match('|^.*' . $wp_rewrite->index . '$|', $pathinfo) ) {
|
---|
187 | $request = $pathinfo;
|
---|
188 | } else {
|
---|
189 | // If the request uri is the index, blank it out so that we don't try to match it against a rule.
|
---|
190 | if ( $req_uri == $wp_rewrite->index )
|
---|
191 | $req_uri = '';
|
---|
192 | $request = $req_uri;
|
---|
193 | }
|
---|
194 |
|
---|
195 | $this->request = $request;
|
---|
196 |
|
---|
197 | // Look for matches.
|
---|
198 | $request_match = $request;
|
---|
199 | foreach ( (array) $rewrite as $match => $query) {
|
---|
200 | // Don't try to match against AtomPub calls
|
---|
201 | if ( $req_uri == 'wp-app.php' )
|
---|
202 | break;
|
---|
203 |
|
---|
204 | // If the requesting file is the anchor of the match, prepend it
|
---|
205 | // to the path info.
|
---|
206 | if ((! empty($req_uri)) && (strpos($match, $req_uri) === 0) && ($req_uri != $request)) {
|
---|
207 | $request_match = $req_uri . '/' . $request;
|
---|
208 | }
|
---|
209 |
|
---|
210 | if (preg_match("#^$match#", $request_match, $matches) ||
|
---|
211 | preg_match("#^$match#", urldecode($request_match), $matches)) {
|
---|
212 | // Got a match.
|
---|
213 | $this->matched_rule = $match;
|
---|
214 |
|
---|
215 | // Trim the query of everything up to the '?'.
|
---|
216 | $query = preg_replace("!^.+\?!", '', $query);
|
---|
217 |
|
---|
218 | // Substitute the substring matches into the query.
|
---|
219 | eval("@\$query = \"" . addslashes($query) . "\";");
|
---|
220 |
|
---|
221 | $this->matched_query = $query;
|
---|
222 |
|
---|
223 | // Parse the query.
|
---|
224 | parse_str($query, $perma_query_vars);
|
---|
225 |
|
---|
226 | // If we're processing a 404 request, clear the error var
|
---|
227 | // since we found something.
|
---|
228 | if (isset($_GET['error']))
|
---|
229 | unset($_GET['error']);
|
---|
230 |
|
---|
231 | if (isset($error))
|
---|
232 | unset($error);
|
---|
233 |
|
---|
234 | break;
|
---|
235 | }
|
---|
236 | }
|
---|
237 |
|
---|
238 | // If req_uri is empty or if it is a request for ourself, unset error.
|
---|
239 | if (empty($request) || $req_uri == $self || strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false) {
|
---|
240 | if (isset($_GET['error']))
|
---|
241 | unset($_GET['error']);
|
---|
242 |
|
---|
243 | if (isset($error))
|
---|
244 | unset($error);
|
---|
245 |
|
---|
246 | if (isset($perma_query_vars) && strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false)
|
---|
247 | unset($perma_query_vars);
|
---|
248 |
|
---|
249 | $this->did_permalink = false;
|
---|
250 | }
|
---|
251 | }
|
---|
252 |
|
---|
253 | $this->public_query_vars = apply_filters('query_vars', $this->public_query_vars);
|
---|
254 |
|
---|
255 | foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t )
|
---|
256 | if ( $t->query_var )
|
---|
257 | $taxonomy_query_vars[$t->query_var] = $taxonomy;
|
---|
258 |
|
---|
259 | for ($i=0; $i<count($this->public_query_vars); $i += 1) {
|
---|
260 | $wpvar = $this->public_query_vars[$i];
|
---|
261 | if (isset($this->extra_query_vars[$wpvar]))
|
---|
262 | $this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar];
|
---|
263 | elseif (isset($GLOBALS[$wpvar]))
|
---|
264 | $this->query_vars[$wpvar] = $GLOBALS[$wpvar];
|
---|
265 | elseif (!empty($_POST[$wpvar]))
|
---|
266 | $this->query_vars[$wpvar] = $_POST[$wpvar];
|
---|
267 | elseif (!empty($_GET[$wpvar]))
|
---|
268 | $this->query_vars[$wpvar] = $_GET[$wpvar];
|
---|
269 | elseif (!empty($perma_query_vars[$wpvar]))
|
---|
270 | $this->query_vars[$wpvar] = $perma_query_vars[$wpvar];
|
---|
271 |
|
---|
272 | if ( !empty( $this->query_vars[$wpvar] ) ) {
|
---|
273 | $this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar];
|
---|
274 | if ( in_array( $wpvar, $taxonomy_query_vars ) ) {
|
---|
275 | $this->query_vars['taxonomy'] = $taxonomy_query_vars[$wpvar];
|
---|
276 | $this->query_vars['term'] = $this->query_vars[$wpvar];
|
---|
277 | }
|
---|
278 | }
|
---|
279 | }
|
---|
280 |
|
---|
281 | foreach ( (array) $this->private_query_vars as $var) {
|
---|
282 | if (isset($this->extra_query_vars[$var]))
|
---|
283 | $this->query_vars[$var] = $this->extra_query_vars[$var];
|
---|
284 | elseif (isset($GLOBALS[$var]) && '' != $GLOBALS[$var])
|
---|
285 | $this->query_vars[$var] = $GLOBALS[$var];
|
---|
286 | }
|
---|
287 |
|
---|
288 | if ( isset($error) )
|
---|
289 | $this->query_vars['error'] = $error;
|
---|
290 |
|
---|
291 | $this->query_vars = apply_filters('request', $this->query_vars);
|
---|
292 |
|
---|
293 | do_action_ref_array('parse_request', array(&$this));
|
---|
294 | }
|
---|
295 |
|
---|
296 | /**
|
---|
297 | * Send additional HTTP headers for caching, content type, etc.
|
---|
298 | *
|
---|
299 | * Sets the X-Pingback header, 404 status (if 404), Content-type. If showing
|
---|
300 | * a feed, it will also send last-modified, etag, and 304 status if needed.
|
---|
301 | *
|
---|
302 | * @since 2.0.0
|
---|
303 | */
|
---|
304 | function send_headers() {
|
---|
305 | $headers = array('X-Pingback' => get_bloginfo('pingback_url'));
|
---|
306 | $status = null;
|
---|
307 | $exit_required = false;
|
---|
308 |
|
---|
309 | if ( is_user_logged_in() )
|
---|
310 | $headers = array_merge($headers, wp_get_nocache_headers());
|
---|
311 | if ( !empty($this->query_vars['error']) && '404' == $this->query_vars['error'] ) {
|
---|
312 | $status = 404;
|
---|
313 | if ( !is_user_logged_in() )
|
---|
314 | $headers = array_merge($headers, wp_get_nocache_headers());
|
---|
315 | $headers['Content-Type'] = get_option('html_type') . '; charset=' . get_option('blog_charset');
|
---|
316 | } else if ( empty($this->query_vars['feed']) ) {
|
---|
317 | $headers['Content-Type'] = get_option('html_type') . '; charset=' . get_option('blog_charset');
|
---|
318 | } else {
|
---|
319 | // We're showing a feed, so WP is indeed the only thing that last changed
|
---|
320 | if ( !empty($this->query_vars['withcomments'])
|
---|
321 | || ( empty($this->query_vars['withoutcomments'])
|
---|
322 | && ( !empty($this->query_vars['p'])
|
---|
323 | || !empty($this->query_vars['name'])
|
---|
324 | || !empty($this->query_vars['page_id'])
|
---|
325 | || !empty($this->query_vars['pagename'])
|
---|
326 | || !empty($this->query_vars['attachment'])
|
---|
327 | || !empty($this->query_vars['attachment_id'])
|
---|
328 | )
|
---|
329 | )
|
---|
330 | )
|
---|
331 | $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastcommentmodified('GMT'), 0).' GMT';
|
---|
332 | else
|
---|
333 | $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT';
|
---|
334 | $wp_etag = '"' . md5($wp_last_modified) . '"';
|
---|
335 | $headers['Last-Modified'] = $wp_last_modified;
|
---|
336 | $headers['ETag'] = $wp_etag;
|
---|
337 |
|
---|
338 | // Support for Conditional GET
|
---|
339 | if (isset($_SERVER['HTTP_IF_NONE_MATCH']))
|
---|
340 | $client_etag = stripslashes(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
|
---|
341 | else $client_etag = false;
|
---|
342 |
|
---|
343 | $client_last_modified = empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? '' : trim($_SERVER['HTTP_IF_MODIFIED_SINCE']);
|
---|
344 | // If string is empty, return 0. If not, attempt to parse into a timestamp
|
---|
345 | $client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0;
|
---|
346 |
|
---|
347 | // Make a timestamp for our most recent modification...
|
---|
348 | $wp_modified_timestamp = strtotime($wp_last_modified);
|
---|
349 |
|
---|
350 | if ( ($client_last_modified && $client_etag) ?
|
---|
351 | (($client_modified_timestamp >= $wp_modified_timestamp) && ($client_etag == $wp_etag)) :
|
---|
352 | (($client_modified_timestamp >= $wp_modified_timestamp) || ($client_etag == $wp_etag)) ) {
|
---|
353 | $status = 304;
|
---|
354 | $exit_required = true;
|
---|
355 | }
|
---|
356 | }
|
---|
357 |
|
---|
358 | $headers = apply_filters('wp_headers', $headers, $this);
|
---|
359 |
|
---|
360 | if ( ! empty( $status ) )
|
---|
361 | status_header( $status );
|
---|
362 | foreach( (array) $headers as $name => $field_value )
|
---|
363 | @header("{$name}: {$field_value}");
|
---|
364 |
|
---|
365 | if ($exit_required)
|
---|
366 | exit();
|
---|
367 |
|
---|
368 | do_action_ref_array('send_headers', array(&$this));
|
---|
369 | }
|
---|
370 |
|
---|
371 | /**
|
---|
372 | * Sets the query string property based off of the query variable property.
|
---|
373 | *
|
---|
374 | * The 'query_string' filter is deprecated, but still works. Plugins should
|
---|
375 | * use the 'request' filter instead.
|
---|
376 | *
|
---|
377 | * @since 2.0.0
|
---|
378 | */
|
---|
379 | function build_query_string() {
|
---|
380 | $this->query_string = '';
|
---|
381 | foreach ( (array) array_keys($this->query_vars) as $wpvar) {
|
---|
382 | if ( '' != $this->query_vars[$wpvar] ) {
|
---|
383 | $this->query_string .= (strlen($this->query_string) < 1) ? '' : '&';
|
---|
384 | if ( !is_scalar($this->query_vars[$wpvar]) ) // Discard non-scalars.
|
---|
385 | continue;
|
---|
386 | $this->query_string .= $wpvar . '=' . rawurlencode($this->query_vars[$wpvar]);
|
---|
387 | }
|
---|
388 | }
|
---|
389 |
|
---|
390 | // query_string filter deprecated. Use request filter instead.
|
---|
391 | if ( has_filter('query_string') ) { // Don't bother filtering and parsing if no plugins are hooked in.
|
---|
392 | $this->query_string = apply_filters('query_string', $this->query_string);
|
---|
393 | parse_str($this->query_string, $this->query_vars);
|
---|
394 | }
|
---|
395 | }
|
---|
396 |
|
---|
397 | /**
|
---|
398 | * Setup the WordPress Globals.
|
---|
399 | *
|
---|
400 | * The query_vars property will be extracted to the GLOBALS. So care should
|
---|
401 | * be taken when naming global variables that might interfere with the
|
---|
402 | * WordPress environment.
|
---|
403 | *
|
---|
404 | * @global string $query_string Query string for the loop.
|
---|
405 | * @global int $more Only set, if single page or post.
|
---|
406 | * @global int $single If single page or post. Only set, if single page or post.
|
---|
407 | *
|
---|
408 | * @since 2.0.0
|
---|
409 | */
|
---|
410 | function register_globals() {
|
---|
411 | global $wp_query;
|
---|
412 | // Extract updated query vars back into global namespace.
|
---|
413 | foreach ( (array) $wp_query->query_vars as $key => $value) {
|
---|
414 | $GLOBALS[$key] = $value;
|
---|
415 | }
|
---|
416 |
|
---|
417 | $GLOBALS['query_string'] = $this->query_string;
|
---|
418 | $GLOBALS['posts'] = & $wp_query->posts;
|
---|
419 | $GLOBALS['post'] = $wp_query->post;
|
---|
420 | $GLOBALS['request'] = $wp_query->request;
|
---|
421 |
|
---|
422 | if ( is_single() || is_page() ) {
|
---|
423 | $GLOBALS['more'] = 1;
|
---|
424 | $GLOBALS['single'] = 1;
|
---|
425 | }
|
---|
426 | }
|
---|
427 |
|
---|
428 | /**
|
---|
429 | * Setup the current user.
|
---|
430 | *
|
---|
431 | * @since 2.0.0
|
---|
432 | */
|
---|
433 | function init() {
|
---|
434 | wp_get_current_user();
|
---|
435 | }
|
---|
436 |
|
---|
437 | /**
|
---|
438 | * Setup the Loop based on the query variables.
|
---|
439 | *
|
---|
440 | * @uses WP::$query_vars
|
---|
441 | * @since 2.0.0
|
---|
442 | */
|
---|
443 | function query_posts() {
|
---|
444 | global $wp_the_query;
|
---|
445 | $this->build_query_string();
|
---|
446 | $wp_the_query->query($this->query_vars);
|
---|
447 | }
|
---|
448 |
|
---|
449 | /**
|
---|
450 | * Set the Headers for 404, if permalink is not found.
|
---|
451 | *
|
---|
452 | * Issue a 404 if a permalink request doesn't match any posts. Don't issue
|
---|
453 | * a 404 if one was already issued, if the request was a search, or if the
|
---|
454 | * request was a regular query string request rather than a permalink
|
---|
455 | * request. Issues a 200, if not 404.
|
---|
456 | *
|
---|
457 | * @since 2.0.0
|
---|
458 | */
|
---|
459 | function handle_404() {
|
---|
460 | global $wp_query;
|
---|
461 |
|
---|
462 | if ( (0 == count($wp_query->posts)) && !is_404() && !is_search() && ( $this->did_permalink || (!empty($_SERVER['QUERY_STRING']) && (false === strpos($_SERVER['REQUEST_URI'], '?'))) ) ) {
|
---|
463 | // Don't 404 for these queries if they matched an object.
|
---|
464 | if ( ( is_tag() || is_category() || is_author() ) && $wp_query->get_queried_object() ) {
|
---|
465 | if ( !is_404() )
|
---|
466 | status_header( 200 );
|
---|
467 | return;
|
---|
468 | }
|
---|
469 | $wp_query->set_404();
|
---|
470 | status_header( 404 );
|
---|
471 | nocache_headers();
|
---|
472 | } elseif ( !is_404() ) {
|
---|
473 | status_header( 200 );
|
---|
474 | }
|
---|
475 | }
|
---|
476 |
|
---|
477 | /**
|
---|
478 | * Sets up all of the variables required by the WordPress environment.
|
---|
479 | *
|
---|
480 | * The action 'wp' has one parameter that references the WP object. It
|
---|
481 | * allows for accessing the properties and methods to further manipulate the
|
---|
482 | * object.
|
---|
483 | *
|
---|
484 | * @since 2.0.0
|
---|
485 | *
|
---|
486 | * @param string|array $query_args Passed to {@link parse_request()}
|
---|
487 | */
|
---|
488 | function main($query_args = '') {
|
---|
489 | $this->init();
|
---|
490 | $this->parse_request($query_args);
|
---|
491 | $this->send_headers();
|
---|
492 | $this->query_posts();
|
---|
493 | $this->handle_404();
|
---|
494 | $this->register_globals();
|
---|
495 | do_action_ref_array('wp', array(&$this));
|
---|
496 | }
|
---|
497 |
|
---|
498 | /**
|
---|
499 | * PHP4 Constructor - Does nothing.
|
---|
500 | *
|
---|
501 | * Call main() method when ready to run setup.
|
---|
502 | *
|
---|
503 | * @since 2.0.0
|
---|
504 | *
|
---|
505 | * @return WP
|
---|
506 | */
|
---|
507 | function WP() {
|
---|
508 | // Empty.
|
---|
509 | }
|
---|
510 | }
|
---|
511 |
|
---|
512 | /**
|
---|
513 | * WordPress Error class.
|
---|
514 | *
|
---|
515 | * Container for checking for WordPress errors and error messages. Return
|
---|
516 | * WP_Error and use {@link is_wp_error()} to check if this class is returned.
|
---|
517 | * Many core WordPress functions pass this class in the event of an error and
|
---|
518 | * if not handled properly will result in code errors.
|
---|
519 | *
|
---|
520 | * @package WordPress
|
---|
521 | * @since 2.1.0
|
---|
522 | */
|
---|
523 | class WP_Error {
|
---|
524 | /**
|
---|
525 | * Stores the list of errors.
|
---|
526 | *
|
---|
527 | * @since 2.1.0
|
---|
528 | * @var array
|
---|
529 | * @access private
|
---|
530 | */
|
---|
531 | var $errors = array();
|
---|
532 |
|
---|
533 | /**
|
---|
534 | * Stores the list of data for error codes.
|
---|
535 | *
|
---|
536 | * @since 2.1.0
|
---|
537 | * @var array
|
---|
538 | * @access private
|
---|
539 | */
|
---|
540 | var $error_data = array();
|
---|
541 |
|
---|
542 | /**
|
---|
543 | * PHP4 Constructor - Sets up error message.
|
---|
544 | *
|
---|
545 | * If code parameter is empty then nothing will be done. It is possible to
|
---|
546 | * add multiple messages to the same code, but with other methods in the
|
---|
547 | * class.
|
---|
548 | *
|
---|
549 | * All parameters are optional, but if the code parameter is set, then the
|
---|
550 | * data parameter is optional.
|
---|
551 | *
|
---|
552 | * @since 2.1.0
|
---|
553 | *
|
---|
554 | * @param string|int $code Error code
|
---|
555 | * @param string $message Error message
|
---|
556 | * @param mixed $data Optional. Error data.
|
---|
557 | * @return WP_Error
|
---|
558 | */
|
---|
559 | function WP_Error($code = '', $message = '', $data = '') {
|
---|
560 | if ( empty($code) )
|
---|
561 | return;
|
---|
562 |
|
---|
563 | $this->errors[$code][] = $message;
|
---|
564 |
|
---|
565 | if ( ! empty($data) )
|
---|
566 | $this->error_data[$code] = $data;
|
---|
567 | }
|
---|
568 |
|
---|
569 | /**
|
---|
570 | * Retrieve all error codes.
|
---|
571 | *
|
---|
572 | * @since 2.1.0
|
---|
573 | * @access public
|
---|
574 | *
|
---|
575 | * @return array List of error codes, if avaiable.
|
---|
576 | */
|
---|
577 | function get_error_codes() {
|
---|
578 | if ( empty($this->errors) )
|
---|
579 | return array();
|
---|
580 |
|
---|
581 | return array_keys($this->errors);
|
---|
582 | }
|
---|
583 |
|
---|
584 | /**
|
---|
585 | * Retrieve first error code available.
|
---|
586 | *
|
---|
587 | * @since 2.1.0
|
---|
588 | * @access public
|
---|
589 | *
|
---|
590 | * @return string|int Empty string, if no error codes.
|
---|
591 | */
|
---|
592 | function get_error_code() {
|
---|
593 | $codes = $this->get_error_codes();
|
---|
594 |
|
---|
595 | if ( empty($codes) )
|
---|
596 | return '';
|
---|
597 |
|
---|
598 | return $codes[0];
|
---|
599 | }
|
---|
600 |
|
---|
601 | /**
|
---|
602 | * Retrieve all error messages or error messages matching code.
|
---|
603 | *
|
---|
604 | * @since 2.1.0
|
---|
605 | *
|
---|
606 | * @param string|int $code Optional. Retrieve messages matching code, if exists.
|
---|
607 | * @return array Error strings on success, or empty array on failure (if using codee parameter).
|
---|
608 | */
|
---|
609 | function get_error_messages($code = '') {
|
---|
610 | // Return all messages if no code specified.
|
---|
611 | if ( empty($code) ) {
|
---|
612 | $all_messages = array();
|
---|
613 | foreach ( (array) $this->errors as $code => $messages )
|
---|
614 | $all_messages = array_merge($all_messages, $messages);
|
---|
615 |
|
---|
616 | return $all_messages;
|
---|
617 | }
|
---|
618 |
|
---|
619 | if ( isset($this->errors[$code]) )
|
---|
620 | return $this->errors[$code];
|
---|
621 | else
|
---|
622 | return array();
|
---|
623 | }
|
---|
624 |
|
---|
625 | /**
|
---|
626 | * Get single error message.
|
---|
627 | *
|
---|
628 | * This will get the first message available for the code. If no code is
|
---|
629 | * given then the first code available will be used.
|
---|
630 | *
|
---|
631 | * @since 2.1.0
|
---|
632 | *
|
---|
633 | * @param string|int $code Optional. Error code to retrieve message.
|
---|
634 | * @return string
|
---|
635 | */
|
---|
636 | function get_error_message($code = '') {
|
---|
637 | if ( empty($code) )
|
---|
638 | $code = $this->get_error_code();
|
---|
639 | $messages = $this->get_error_messages($code);
|
---|
640 | if ( empty($messages) )
|
---|
641 | return '';
|
---|
642 | return $messages[0];
|
---|
643 | }
|
---|
644 |
|
---|
645 | /**
|
---|
646 | * Retrieve error data for error code.
|
---|
647 | *
|
---|
648 | * @since 2.1.0
|
---|
649 | *
|
---|
650 | * @param string|int $code Optional. Error code.
|
---|
651 | * @return mixed Null, if no errors.
|
---|
652 | */
|
---|
653 | function get_error_data($code = '') {
|
---|
654 | if ( empty($code) )
|
---|
655 | $code = $this->get_error_code();
|
---|
656 |
|
---|
657 | if ( isset($this->error_data[$code]) )
|
---|
658 | return $this->error_data[$code];
|
---|
659 | return null;
|
---|
660 | }
|
---|
661 |
|
---|
662 | /**
|
---|
663 | * Append more error messages to list of error messages.
|
---|
664 | *
|
---|
665 | * @since 2.1.0
|
---|
666 | * @access public
|
---|
667 | *
|
---|
668 | * @param string|int $code Error code.
|
---|
669 | * @param string $message Error message.
|
---|
670 | * @param mixed $data Optional. Error data.
|
---|
671 | */
|
---|
672 | function add($code, $message, $data = '') {
|
---|
673 | $this->errors[$code][] = $message;
|
---|
674 | if ( ! empty($data) )
|
---|
675 | $this->error_data[$code] = $data;
|
---|
676 | }
|
---|
677 |
|
---|
678 | /**
|
---|
679 | * Add data for error code.
|
---|
680 | *
|
---|
681 | * The error code can only contain one error data.
|
---|
682 | *
|
---|
683 | * @since 2.1.0
|
---|
684 | *
|
---|
685 | * @param mixed $data Error data.
|
---|
686 | * @param string|int $code Error code.
|
---|
687 | */
|
---|
688 | function add_data($data, $code = '') {
|
---|
689 | if ( empty($code) )
|
---|
690 | $code = $this->get_error_code();
|
---|
691 |
|
---|
692 | $this->error_data[$code] = $data;
|
---|
693 | }
|
---|
694 | }
|
---|
695 |
|
---|
696 | /**
|
---|
697 | * Check whether variable is a WordPress Error.
|
---|
698 | *
|
---|
699 | * Looks at the object and if a WP_Error class. Does not check to see if the
|
---|
700 | * parent is also WP_Error, so can't inherit WP_Error and still use this
|
---|
701 | * function.
|
---|
702 | *
|
---|
703 | * @since 2.1.0
|
---|
704 | *
|
---|
705 | * @param mixed $thing Check if unknown variable is WordPress Error object.
|
---|
706 | * @return bool True, if WP_Error. False, if not WP_Error.
|
---|
707 | */
|
---|
708 | function is_wp_error($thing) {
|
---|
709 | if ( is_object($thing) && is_a($thing, 'WP_Error') )
|
---|
710 | return true;
|
---|
711 | return false;
|
---|
712 | }
|
---|
713 |
|
---|
714 | /**
|
---|
715 | * A class for displaying various tree-like structures.
|
---|
716 | *
|
---|
717 | * Extend the Walker class to use it, see examples at the below. Child classes
|
---|
718 | * do not need to implement all of the abstract methods in the class. The child
|
---|
719 | * only needs to implement the methods that are needed. Also, the methods are
|
---|
720 | * not strictly abstract in that the parameter definition needs to be followed.
|
---|
721 | * The child classes can have additional parameters.
|
---|
722 | *
|
---|
723 | * @package WordPress
|
---|
724 | * @since 2.1.0
|
---|
725 | * @abstract
|
---|
726 | */
|
---|
727 | class Walker {
|
---|
728 | /**
|
---|
729 | * What the class handles.
|
---|
730 | *
|
---|
731 | * @since 2.1.0
|
---|
732 | * @var string
|
---|
733 | * @access public
|
---|
734 | */
|
---|
735 | var $tree_type;
|
---|
736 |
|
---|
737 | /**
|
---|
738 | * DB fields to use.
|
---|
739 | *
|
---|
740 | * @since 2.1.0
|
---|
741 | * @var array
|
---|
742 | * @access protected
|
---|
743 | */
|
---|
744 | var $db_fields;
|
---|
745 |
|
---|
746 | /**
|
---|
747 | * Max number of pages walked by the paged walker
|
---|
748 | *
|
---|
749 | * @since 2.7.0
|
---|
750 | * @var int
|
---|
751 | * @access protected
|
---|
752 | */
|
---|
753 | var $max_pages = 1;
|
---|
754 |
|
---|
755 | /**
|
---|
756 | * Starts the list before the elements are added.
|
---|
757 | *
|
---|
758 | * Additional parameters are used in child classes. The args parameter holds
|
---|
759 | * additional values that may be used with the child class methods. This
|
---|
760 | * method is called at the start of the output list.
|
---|
761 | *
|
---|
762 | * @since 2.1.0
|
---|
763 | * @abstract
|
---|
764 | *
|
---|
765 | * @param string $output Passed by reference. Used to append additional content.
|
---|
766 | */
|
---|
767 | function start_lvl(&$output) {}
|
---|
768 |
|
---|
769 | /**
|
---|
770 | * Ends the list of after the elements are added.
|
---|
771 | *
|
---|
772 | * Additional parameters are used in child classes. The args parameter holds
|
---|
773 | * additional values that may be used with the child class methods. This
|
---|
774 | * method finishes the list at the end of output of the elements.
|
---|
775 | *
|
---|
776 | * @since 2.1.0
|
---|
777 | * @abstract
|
---|
778 | *
|
---|
779 | * @param string $output Passed by reference. Used to append additional content.
|
---|
780 | */
|
---|
781 | function end_lvl(&$output) {}
|
---|
782 |
|
---|
783 | /**
|
---|
784 | * Start the element output.
|
---|
785 | *
|
---|
786 | * Additional parameters are used in child classes. The args parameter holds
|
---|
787 | * additional values that may be used with the child class methods. Includes
|
---|
788 | * the element output also.
|
---|
789 | *
|
---|
790 | * @since 2.1.0
|
---|
791 | * @abstract
|
---|
792 | *
|
---|
793 | * @param string $output Passed by reference. Used to append additional content.
|
---|
794 | */
|
---|
795 | function start_el(&$output) {}
|
---|
796 |
|
---|
797 | /**
|
---|
798 | * Ends the element output, if needed.
|
---|
799 | *
|
---|
800 | * Additional parameters are used in child classes. The args parameter holds
|
---|
801 | * additional values that may be used with the child class methods.
|
---|
802 | *
|
---|
803 | * @since 2.1.0
|
---|
804 | * @abstract
|
---|
805 | *
|
---|
806 | * @param string $output Passed by reference. Used to append additional content.
|
---|
807 | */
|
---|
808 | function end_el(&$output) {}
|
---|
809 |
|
---|
810 | /**
|
---|
811 | * Traverse elements to create list from elements.
|
---|
812 | *
|
---|
813 | * Display one element if the element doesn't have any children otherwise,
|
---|
814 | * display the element and its children. Will only traverse up to the max
|
---|
815 | * depth and no ignore elements under that depth. It is possible to set the
|
---|
816 | * max depth to include all depths, see walk() method.
|
---|
817 | *
|
---|
818 | * This method shouldn't be called directly, use the walk() method instead.
|
---|
819 | *
|
---|
820 | * @since 2.5.0
|
---|
821 | *
|
---|
822 | * @param object $element Data object
|
---|
823 | * @param array $children_elements List of elements to continue traversing.
|
---|
824 | * @param int $max_depth Max depth to traverse.
|
---|
825 | * @param int $depth Depth of current element.
|
---|
826 | * @param array $args
|
---|
827 | * @param string $output Passed by reference. Used to append additional content.
|
---|
828 | * @return null Null on failure with no changes to parameters.
|
---|
829 | */
|
---|
830 | function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
|
---|
831 |
|
---|
832 | if ( !$element )
|
---|
833 | return;
|
---|
834 |
|
---|
835 | $id_field = $this->db_fields['id'];
|
---|
836 |
|
---|
837 | //display this element
|
---|
838 | if ( is_array( $args[0] ) )
|
---|
839 | $args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
|
---|
840 | $cb_args = array_merge( array(&$output, $element, $depth), $args);
|
---|
841 | call_user_func_array(array(&$this, 'start_el'), $cb_args);
|
---|
842 |
|
---|
843 | $id = $element->$id_field;
|
---|
844 |
|
---|
845 | // descend only when the depth is right and there are childrens for this element
|
---|
846 | if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) {
|
---|
847 |
|
---|
848 | foreach( $children_elements[ $id ] as $child ){
|
---|
849 |
|
---|
850 | if ( !isset($newlevel) ) {
|
---|
851 | $newlevel = true;
|
---|
852 | //start the child delimiter
|
---|
853 | $cb_args = array_merge( array(&$output, $depth), $args);
|
---|
854 | call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
|
---|
855 | }
|
---|
856 | $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
|
---|
857 | }
|
---|
858 | unset( $children_elements[ $id ] );
|
---|
859 | }
|
---|
860 |
|
---|
861 | if ( isset($newlevel) && $newlevel ){
|
---|
862 | //end the child delimiter
|
---|
863 | $cb_args = array_merge( array(&$output, $depth), $args);
|
---|
864 | call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
|
---|
865 | }
|
---|
866 |
|
---|
867 | //end this element
|
---|
868 | $cb_args = array_merge( array(&$output, $element, $depth), $args);
|
---|
869 | call_user_func_array(array(&$this, 'end_el'), $cb_args);
|
---|
870 | }
|
---|
871 |
|
---|
872 | /**
|
---|
873 | * Display array of elements hierarchically.
|
---|
874 | *
|
---|
875 | * It is a generic function which does not assume any existing order of
|
---|
876 | * elements. max_depth = -1 means flatly display every element. max_depth =
|
---|
877 | * 0 means display all levels. max_depth > 0 specifies the number of
|
---|
878 | * display levels.
|
---|
879 | *
|
---|
880 | * @since 2.1.0
|
---|
881 | *
|
---|
882 | * @param array $elements
|
---|
883 | * @param int $max_depth
|
---|
884 | * @return string
|
---|
885 | */
|
---|
886 | function walk( $elements, $max_depth) {
|
---|
887 |
|
---|
888 | $args = array_slice(func_get_args(), 2);
|
---|
889 | $output = '';
|
---|
890 |
|
---|
891 | if ($max_depth < -1) //invalid parameter
|
---|
892 | return $output;
|
---|
893 |
|
---|
894 | if (empty($elements)) //nothing to walk
|
---|
895 | return $output;
|
---|
896 |
|
---|
897 | $id_field = $this->db_fields['id'];
|
---|
898 | $parent_field = $this->db_fields['parent'];
|
---|
899 |
|
---|
900 | // flat display
|
---|
901 | if ( -1 == $max_depth ) {
|
---|
902 | $empty_array = array();
|
---|
903 | foreach ( $elements as $e )
|
---|
904 | $this->display_element( $e, $empty_array, 1, 0, $args, $output );
|
---|
905 | return $output;
|
---|
906 | }
|
---|
907 |
|
---|
908 | /*
|
---|
909 | * need to display in hierarchical order
|
---|
910 | * seperate elements into two buckets: top level and children elements
|
---|
911 | * children_elements is two dimensional array, eg.
|
---|
912 | * children_elements[10][] contains all sub-elements whose parent is 10.
|
---|
913 | */
|
---|
914 | $top_level_elements = array();
|
---|
915 | $children_elements = array();
|
---|
916 | foreach ( $elements as $e) {
|
---|
917 | if ( 0 == $e->$parent_field )
|
---|
918 | $top_level_elements[] = $e;
|
---|
919 | else
|
---|
920 | $children_elements[ $e->$parent_field ][] = $e;
|
---|
921 | }
|
---|
922 |
|
---|
923 | /*
|
---|
924 | * when none of the elements is top level
|
---|
925 | * assume the first one must be root of the sub elements
|
---|
926 | */
|
---|
927 | if ( empty($top_level_elements) ) {
|
---|
928 |
|
---|
929 | $first = array_slice( $elements, 0, 1 );
|
---|
930 | $root = $first[0];
|
---|
931 |
|
---|
932 | $top_level_elements = array();
|
---|
933 | $children_elements = array();
|
---|
934 | foreach ( $elements as $e) {
|
---|
935 | if ( $root->$parent_field == $e->$parent_field )
|
---|
936 | $top_level_elements[] = $e;
|
---|
937 | else
|
---|
938 | $children_elements[ $e->$parent_field ][] = $e;
|
---|
939 | }
|
---|
940 | }
|
---|
941 |
|
---|
942 | foreach ( $top_level_elements as $e )
|
---|
943 | $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
|
---|
944 |
|
---|
945 | /*
|
---|
946 | * if we are displaying all levels, and remaining children_elements is not empty,
|
---|
947 | * then we got orphans, which should be displayed regardless
|
---|
948 | */
|
---|
949 | if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
|
---|
950 | $empty_array = array();
|
---|
951 | foreach ( $children_elements as $orphans )
|
---|
952 | foreach( $orphans as $op )
|
---|
953 | $this->display_element( $op, $empty_array, 1, 0, $args, $output );
|
---|
954 | }
|
---|
955 |
|
---|
956 | return $output;
|
---|
957 | }
|
---|
958 |
|
---|
959 | /**
|
---|
960 | * paged_walk() - produce a page of nested elements
|
---|
961 | *
|
---|
962 | * Given an array of hierarchical elements, the maximum depth, a specific page number,
|
---|
963 | * and number of elements per page, this function first determines all top level root elements
|
---|
964 | * belonging to that page, then lists them and all of their children in hierarchical order.
|
---|
965 | *
|
---|
966 | * @package WordPress
|
---|
967 | * @since 2.7
|
---|
968 | * @param $max_depth = 0 means display all levels; $max_depth > 0 specifies the number of display levels.
|
---|
969 | * @param $page_num the specific page number, beginning with 1.
|
---|
970 | * @return XHTML of the specified page of elements
|
---|
971 | */
|
---|
972 | function paged_walk( $elements, $max_depth, $page_num, $per_page ) {
|
---|
973 |
|
---|
974 | /* sanity check */
|
---|
975 | if ( empty($elements) || $max_depth < -1 )
|
---|
976 | return '';
|
---|
977 |
|
---|
978 | $args = array_slice( func_get_args(), 4 );
|
---|
979 | $output = '';
|
---|
980 |
|
---|
981 | $id_field = $this->db_fields['id'];
|
---|
982 | $parent_field = $this->db_fields['parent'];
|
---|
983 |
|
---|
984 | $count = -1;
|
---|
985 | if ( -1 == $max_depth )
|
---|
986 | $total_top = count( $elements );
|
---|
987 | if ( $page_num < 1 || $per_page < 0 ) {
|
---|
988 | // No paging
|
---|
989 | $paging = false;
|
---|
990 | $start = 0;
|
---|
991 | if ( -1 == $max_depth )
|
---|
992 | $end = $total_top;
|
---|
993 | $this->max_pages = 1;
|
---|
994 | } else {
|
---|
995 | $paging = true;
|
---|
996 | $start = ( (int)$page_num - 1 ) * (int)$per_page;
|
---|
997 | $end = $start + $per_page;
|
---|
998 | if ( -1 == $max_depth )
|
---|
999 | $this->max_pages = ceil($total_top / $per_page);
|
---|
1000 | }
|
---|
1001 |
|
---|
1002 | // flat display
|
---|
1003 | if ( -1 == $max_depth ) {
|
---|
1004 | if ( !empty($args[0]['reverse_top_level']) ) {
|
---|
1005 | $elements = array_reverse( $elements );
|
---|
1006 | $oldstart = $start;
|
---|
1007 | $start = $total_top - $end;
|
---|
1008 | $end = $total_top - $oldstart;
|
---|
1009 | }
|
---|
1010 |
|
---|
1011 | $empty_array = array();
|
---|
1012 | foreach ( $elements as $e ) {
|
---|
1013 | $count++;
|
---|
1014 | if ( $count < $start )
|
---|
1015 | continue;
|
---|
1016 | if ( $count >= $end )
|
---|
1017 | break;
|
---|
1018 | $this->display_element( $e, $empty_array, 1, 0, $args, $output );
|
---|
1019 | }
|
---|
1020 | return $output;
|
---|
1021 | }
|
---|
1022 |
|
---|
1023 | /*
|
---|
1024 | * seperate elements into two buckets: top level and children elements
|
---|
1025 | * children_elements is two dimensional array, eg.
|
---|
1026 | * children_elements[10][] contains all sub-elements whose parent is 10.
|
---|
1027 | */
|
---|
1028 | $top_level_elements = array();
|
---|
1029 | $children_elements = array();
|
---|
1030 | foreach ( $elements as $e) {
|
---|
1031 | if ( 0 == $e->$parent_field )
|
---|
1032 | $top_level_elements[] = $e;
|
---|
1033 | else
|
---|
1034 | $children_elements[ $e->$parent_field ][] = $e;
|
---|
1035 | }
|
---|
1036 |
|
---|
1037 | $total_top = count( $top_level_elements );
|
---|
1038 | if ( $paging )
|
---|
1039 | $this->max_pages = ceil($total_top / $per_page);
|
---|
1040 | else
|
---|
1041 | $end = $total_top;
|
---|
1042 |
|
---|
1043 | if ( !empty($args[0]['reverse_top_level']) ) {
|
---|
1044 | $top_level_elements = array_reverse( $top_level_elements );
|
---|
1045 | $oldstart = $start;
|
---|
1046 | $start = $total_top - $end;
|
---|
1047 | $end = $total_top - $oldstart;
|
---|
1048 | }
|
---|
1049 | if ( !empty($args[0]['reverse_children']) ) {
|
---|
1050 | foreach ( $children_elements as $parent => $children )
|
---|
1051 | $children_elements[$parent] = array_reverse( $children );
|
---|
1052 | }
|
---|
1053 |
|
---|
1054 | foreach ( $top_level_elements as $e ) {
|
---|
1055 | $count++;
|
---|
1056 |
|
---|
1057 | //for the last page, need to unset earlier children in order to keep track of orphans
|
---|
1058 | if ( $end >= $total_top && $count < $start )
|
---|
1059 | $this->unset_children( $e, $children_elements );
|
---|
1060 |
|
---|
1061 | if ( $count < $start )
|
---|
1062 | continue;
|
---|
1063 |
|
---|
1064 | if ( $count >= $end )
|
---|
1065 | break;
|
---|
1066 |
|
---|
1067 | $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
|
---|
1068 | }
|
---|
1069 |
|
---|
1070 | if ( $end >= $total_top && count( $children_elements ) > 0 ) {
|
---|
1071 | $empty_array = array();
|
---|
1072 | foreach ( $children_elements as $orphans )
|
---|
1073 | foreach( $orphans as $op )
|
---|
1074 | $this->display_element( $op, $empty_array, 1, 0, $args, $output );
|
---|
1075 | }
|
---|
1076 |
|
---|
1077 | return $output;
|
---|
1078 | }
|
---|
1079 |
|
---|
1080 | function get_number_of_root_elements( $elements ){
|
---|
1081 |
|
---|
1082 | $num = 0;
|
---|
1083 | $parent_field = $this->db_fields['parent'];
|
---|
1084 |
|
---|
1085 | foreach ( $elements as $e) {
|
---|
1086 | if ( 0 == $e->$parent_field )
|
---|
1087 | $num++;
|
---|
1088 | }
|
---|
1089 | return $num;
|
---|
1090 | }
|
---|
1091 |
|
---|
1092 | // unset all the children for a given top level element
|
---|
1093 | function unset_children( $e, &$children_elements ){
|
---|
1094 |
|
---|
1095 | if ( !$e || !$children_elements )
|
---|
1096 | return;
|
---|
1097 |
|
---|
1098 | $id_field = $this->db_fields['id'];
|
---|
1099 | $id = $e->$id_field;
|
---|
1100 |
|
---|
1101 | if ( !empty($children_elements[$id]) && is_array($children_elements[$id]) )
|
---|
1102 | foreach ( (array) $children_elements[$id] as $child )
|
---|
1103 | $this->unset_children( $child, $children_elements );
|
---|
1104 |
|
---|
1105 | if ( isset($children_elements[$id]) )
|
---|
1106 | unset( $children_elements[$id] );
|
---|
1107 |
|
---|
1108 | }
|
---|
1109 | }
|
---|
1110 |
|
---|
1111 | /**
|
---|
1112 | * Create HTML list of pages.
|
---|
1113 | *
|
---|
1114 | * @package WordPress
|
---|
1115 | * @since 2.1.0
|
---|
1116 | * @uses Walker
|
---|
1117 | */
|
---|
1118 | class Walker_Page extends Walker {
|
---|
1119 | /**
|
---|
1120 | * @see Walker::$tree_type
|
---|
1121 | * @since 2.1.0
|
---|
1122 | * @var string
|
---|
1123 | */
|
---|
1124 | var $tree_type = 'page';
|
---|
1125 |
|
---|
1126 | /**
|
---|
1127 | * @see Walker::$db_fields
|
---|
1128 | * @since 2.1.0
|
---|
1129 | * @todo Decouple this.
|
---|
1130 | * @var array
|
---|
1131 | */
|
---|
1132 | var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
|
---|
1133 |
|
---|
1134 | /**
|
---|
1135 | * @see Walker::start_lvl()
|
---|
1136 | * @since 2.1.0
|
---|
1137 | *
|
---|
1138 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1139 | * @param int $depth Depth of page. Used for padding.
|
---|
1140 | */
|
---|
1141 | function start_lvl(&$output, $depth) {
|
---|
1142 | $indent = str_repeat("\t", $depth);
|
---|
1143 | $output .= "\n$indent<ul>\n";
|
---|
1144 | }
|
---|
1145 |
|
---|
1146 | /**
|
---|
1147 | * @see Walker::end_lvl()
|
---|
1148 | * @since 2.1.0
|
---|
1149 | *
|
---|
1150 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1151 | * @param int $depth Depth of page. Used for padding.
|
---|
1152 | */
|
---|
1153 | function end_lvl(&$output, $depth) {
|
---|
1154 | $indent = str_repeat("\t", $depth);
|
---|
1155 | $output .= "$indent</ul>\n";
|
---|
1156 | }
|
---|
1157 |
|
---|
1158 | /**
|
---|
1159 | * @see Walker::start_el()
|
---|
1160 | * @since 2.1.0
|
---|
1161 | *
|
---|
1162 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1163 | * @param object $page Page data object.
|
---|
1164 | * @param int $depth Depth of page. Used for padding.
|
---|
1165 | * @param int $current_page Page ID.
|
---|
1166 | * @param array $args
|
---|
1167 | */
|
---|
1168 | function start_el(&$output, $page, $depth, $args, $current_page) {
|
---|
1169 | if ( $depth )
|
---|
1170 | $indent = str_repeat("\t", $depth);
|
---|
1171 | else
|
---|
1172 | $indent = '';
|
---|
1173 |
|
---|
1174 | extract($args, EXTR_SKIP);
|
---|
1175 | $css_class = array('page_item', 'page-item-'.$page->ID);
|
---|
1176 | if ( !empty($current_page) ) {
|
---|
1177 | $_current_page = get_page( $current_page );
|
---|
1178 | if ( isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors) )
|
---|
1179 | $css_class[] = 'current_page_ancestor';
|
---|
1180 | if ( $page->ID == $current_page )
|
---|
1181 | $css_class[] = 'current_page_item';
|
---|
1182 | elseif ( $_current_page && $page->ID == $_current_page->post_parent )
|
---|
1183 | $css_class[] = 'current_page_parent';
|
---|
1184 | } elseif ( $page->ID == get_option('page_for_posts') ) {
|
---|
1185 | $css_class[] = 'current_page_parent';
|
---|
1186 | }
|
---|
1187 |
|
---|
1188 | $css_class = implode(' ', apply_filters('page_css_class', $css_class, $page));
|
---|
1189 |
|
---|
1190 | $output .= $indent . '<li class="' . $css_class . '"><a href="' . get_page_link($page->ID) . '" title="' . esc_attr(apply_filters('the_title', $page->post_title)) . '">' . $link_before . apply_filters('the_title', $page->post_title) . $link_after . '</a>';
|
---|
1191 |
|
---|
1192 | if ( !empty($show_date) ) {
|
---|
1193 | if ( 'modified' == $show_date )
|
---|
1194 | $time = $page->post_modified;
|
---|
1195 | else
|
---|
1196 | $time = $page->post_date;
|
---|
1197 |
|
---|
1198 | $output .= " " . mysql2date($date_format, $time);
|
---|
1199 | }
|
---|
1200 | }
|
---|
1201 |
|
---|
1202 | /**
|
---|
1203 | * @see Walker::end_el()
|
---|
1204 | * @since 2.1.0
|
---|
1205 | *
|
---|
1206 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1207 | * @param object $page Page data object. Not used.
|
---|
1208 | * @param int $depth Depth of page. Not Used.
|
---|
1209 | */
|
---|
1210 | function end_el(&$output, $page, $depth) {
|
---|
1211 | $output .= "</li>\n";
|
---|
1212 | }
|
---|
1213 |
|
---|
1214 | }
|
---|
1215 |
|
---|
1216 | /**
|
---|
1217 | * Create HTML dropdown list of pages.
|
---|
1218 | *
|
---|
1219 | * @package WordPress
|
---|
1220 | * @since 2.1.0
|
---|
1221 | * @uses Walker
|
---|
1222 | */
|
---|
1223 | class Walker_PageDropdown extends Walker {
|
---|
1224 | /**
|
---|
1225 | * @see Walker::$tree_type
|
---|
1226 | * @since 2.1.0
|
---|
1227 | * @var string
|
---|
1228 | */
|
---|
1229 | var $tree_type = 'page';
|
---|
1230 |
|
---|
1231 | /**
|
---|
1232 | * @see Walker::$db_fields
|
---|
1233 | * @since 2.1.0
|
---|
1234 | * @todo Decouple this
|
---|
1235 | * @var array
|
---|
1236 | */
|
---|
1237 | var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
|
---|
1238 |
|
---|
1239 | /**
|
---|
1240 | * @see Walker::start_el()
|
---|
1241 | * @since 2.1.0
|
---|
1242 | *
|
---|
1243 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1244 | * @param object $page Page data object.
|
---|
1245 | * @param int $depth Depth of page in reference to parent pages. Used for padding.
|
---|
1246 | * @param array $args Uses 'selected' argument for selected page to set selected HTML attribute for option element.
|
---|
1247 | */
|
---|
1248 | function start_el(&$output, $page, $depth, $args) {
|
---|
1249 | $pad = str_repeat(' ', $depth * 3);
|
---|
1250 |
|
---|
1251 | $output .= "\t<option class=\"level-$depth\" value=\"$page->ID\"";
|
---|
1252 | if ( $page->ID == $args['selected'] )
|
---|
1253 | $output .= ' selected="selected"';
|
---|
1254 | $output .= '>';
|
---|
1255 | $title = esc_html($page->post_title);
|
---|
1256 | $output .= "$pad$title";
|
---|
1257 | $output .= "</option>\n";
|
---|
1258 | }
|
---|
1259 | }
|
---|
1260 |
|
---|
1261 | /**
|
---|
1262 | * Create HTML list of categories.
|
---|
1263 | *
|
---|
1264 | * @package WordPress
|
---|
1265 | * @since 2.1.0
|
---|
1266 | * @uses Walker
|
---|
1267 | */
|
---|
1268 | class Walker_Category extends Walker {
|
---|
1269 | /**
|
---|
1270 | * @see Walker::$tree_type
|
---|
1271 | * @since 2.1.0
|
---|
1272 | * @var string
|
---|
1273 | */
|
---|
1274 | var $tree_type = 'category';
|
---|
1275 |
|
---|
1276 | /**
|
---|
1277 | * @see Walker::$db_fields
|
---|
1278 | * @since 2.1.0
|
---|
1279 | * @todo Decouple this
|
---|
1280 | * @var array
|
---|
1281 | */
|
---|
1282 | var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
|
---|
1283 |
|
---|
1284 | /**
|
---|
1285 | * @see Walker::start_lvl()
|
---|
1286 | * @since 2.1.0
|
---|
1287 | *
|
---|
1288 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1289 | * @param int $depth Depth of category. Used for tab indentation.
|
---|
1290 | * @param array $args Will only append content if style argument value is 'list'.
|
---|
1291 | */
|
---|
1292 | function start_lvl(&$output, $depth, $args) {
|
---|
1293 | if ( 'list' != $args['style'] )
|
---|
1294 | return;
|
---|
1295 |
|
---|
1296 | $indent = str_repeat("\t", $depth);
|
---|
1297 | $output .= "$indent<ul class='children'>\n";
|
---|
1298 | }
|
---|
1299 |
|
---|
1300 | /**
|
---|
1301 | * @see Walker::end_lvl()
|
---|
1302 | * @since 2.1.0
|
---|
1303 | *
|
---|
1304 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1305 | * @param int $depth Depth of category. Used for tab indentation.
|
---|
1306 | * @param array $args Will only append content if style argument value is 'list'.
|
---|
1307 | */
|
---|
1308 | function end_lvl(&$output, $depth, $args) {
|
---|
1309 | if ( 'list' != $args['style'] )
|
---|
1310 | return;
|
---|
1311 |
|
---|
1312 | $indent = str_repeat("\t", $depth);
|
---|
1313 | $output .= "$indent</ul>\n";
|
---|
1314 | }
|
---|
1315 |
|
---|
1316 | /**
|
---|
1317 | * @see Walker::start_el()
|
---|
1318 | * @since 2.1.0
|
---|
1319 | *
|
---|
1320 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1321 | * @param object $category Category data object.
|
---|
1322 | * @param int $depth Depth of category in reference to parents.
|
---|
1323 | * @param array $args
|
---|
1324 | */
|
---|
1325 | function start_el(&$output, $category, $depth, $args) {
|
---|
1326 | extract($args);
|
---|
1327 |
|
---|
1328 | $cat_name = esc_attr( $category->name);
|
---|
1329 | $cat_name = apply_filters( 'list_cats', $cat_name, $category );
|
---|
1330 | $link = '<a href="' . get_category_link( $category->term_id ) . '" ';
|
---|
1331 | if ( $use_desc_for_title == 0 || empty($category->description) )
|
---|
1332 | $link .= 'title="' . sprintf(__( 'View all posts filed under %s' ), $cat_name) . '"';
|
---|
1333 | else
|
---|
1334 | $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
|
---|
1335 | $link .= '>';
|
---|
1336 | $link .= $cat_name . '</a>';
|
---|
1337 |
|
---|
1338 | if ( (! empty($feed_image)) || (! empty($feed)) ) {
|
---|
1339 | $link .= ' ';
|
---|
1340 |
|
---|
1341 | if ( empty($feed_image) )
|
---|
1342 | $link .= '(';
|
---|
1343 |
|
---|
1344 | $link .= '<a href="' . get_category_feed_link($category->term_id, $feed_type) . '"';
|
---|
1345 |
|
---|
1346 | if ( empty($feed) )
|
---|
1347 | $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
|
---|
1348 | else {
|
---|
1349 | $title = ' title="' . $feed . '"';
|
---|
1350 | $alt = ' alt="' . $feed . '"';
|
---|
1351 | $name = $feed;
|
---|
1352 | $link .= $title;
|
---|
1353 | }
|
---|
1354 |
|
---|
1355 | $link .= '>';
|
---|
1356 |
|
---|
1357 | if ( empty($feed_image) )
|
---|
1358 | $link .= $name;
|
---|
1359 | else
|
---|
1360 | $link .= "<img src='$feed_image'$alt$title" . ' />';
|
---|
1361 | $link .= '</a>';
|
---|
1362 | if ( empty($feed_image) )
|
---|
1363 | $link .= ')';
|
---|
1364 | }
|
---|
1365 |
|
---|
1366 | if ( isset($show_count) && $show_count )
|
---|
1367 | $link .= ' (' . intval($category->count) . ')';
|
---|
1368 |
|
---|
1369 | if ( isset($show_date) && $show_date ) {
|
---|
1370 | $link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp);
|
---|
1371 | }
|
---|
1372 |
|
---|
1373 | if ( isset($current_category) && $current_category )
|
---|
1374 | $_current_category = get_category( $current_category );
|
---|
1375 |
|
---|
1376 | if ( 'list' == $args['style'] ) {
|
---|
1377 | $output .= "\t<li";
|
---|
1378 | $class = 'cat-item cat-item-'.$category->term_id;
|
---|
1379 | if ( isset($current_category) && $current_category && ($category->term_id == $current_category) )
|
---|
1380 | $class .= ' current-cat';
|
---|
1381 | elseif ( isset($_current_category) && $_current_category && ($category->term_id == $_current_category->parent) )
|
---|
1382 | $class .= ' current-cat-parent';
|
---|
1383 | $output .= ' class="'.$class.'"';
|
---|
1384 | $output .= ">$link\n";
|
---|
1385 | } else {
|
---|
1386 | $output .= "\t$link<br />\n";
|
---|
1387 | }
|
---|
1388 | }
|
---|
1389 |
|
---|
1390 | /**
|
---|
1391 | * @see Walker::end_el()
|
---|
1392 | * @since 2.1.0
|
---|
1393 | *
|
---|
1394 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1395 | * @param object $page Not used.
|
---|
1396 | * @param int $depth Depth of category. Not used.
|
---|
1397 | * @param array $args Only uses 'list' for whether should append to output.
|
---|
1398 | */
|
---|
1399 | function end_el(&$output, $page, $depth, $args) {
|
---|
1400 | if ( 'list' != $args['style'] )
|
---|
1401 | return;
|
---|
1402 |
|
---|
1403 | $output .= "</li>\n";
|
---|
1404 | }
|
---|
1405 |
|
---|
1406 | }
|
---|
1407 |
|
---|
1408 | /**
|
---|
1409 | * Create HTML dropdown list of Categories.
|
---|
1410 | *
|
---|
1411 | * @package WordPress
|
---|
1412 | * @since 2.1.0
|
---|
1413 | * @uses Walker
|
---|
1414 | */
|
---|
1415 | class Walker_CategoryDropdown extends Walker {
|
---|
1416 | /**
|
---|
1417 | * @see Walker::$tree_type
|
---|
1418 | * @since 2.1.0
|
---|
1419 | * @var string
|
---|
1420 | */
|
---|
1421 | var $tree_type = 'category';
|
---|
1422 |
|
---|
1423 | /**
|
---|
1424 | * @see Walker::$db_fields
|
---|
1425 | * @since 2.1.0
|
---|
1426 | * @todo Decouple this
|
---|
1427 | * @var array
|
---|
1428 | */
|
---|
1429 | var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
|
---|
1430 |
|
---|
1431 | /**
|
---|
1432 | * @see Walker::start_el()
|
---|
1433 | * @since 2.1.0
|
---|
1434 | *
|
---|
1435 | * @param string $output Passed by reference. Used to append additional content.
|
---|
1436 | * @param object $category Category data object.
|
---|
1437 | * @param int $depth Depth of category. Used for padding.
|
---|
1438 | * @param array $args Uses 'selected', 'show_count', and 'show_last_update' keys, if they exist.
|
---|
1439 | */
|
---|
1440 | function start_el(&$output, $category, $depth, $args) {
|
---|
1441 | $pad = str_repeat(' ', $depth * 3);
|
---|
1442 |
|
---|
1443 | $cat_name = apply_filters('list_cats', $category->name, $category);
|
---|
1444 | $output .= "\t<option class=\"level-$depth\" value=\"".$category->term_id."\"";
|
---|
1445 | if ( $category->term_id == $args['selected'] )
|
---|
1446 | $output .= ' selected="selected"';
|
---|
1447 | $output .= '>';
|
---|
1448 | $output .= $pad.$cat_name;
|
---|
1449 | if ( $args['show_count'] )
|
---|
1450 | $output .= ' ('. $category->count .')';
|
---|
1451 | if ( $args['show_last_update'] ) {
|
---|
1452 | $format = 'Y-m-d';
|
---|
1453 | $output .= ' ' . gmdate($format, $category->last_update_timestamp);
|
---|
1454 | }
|
---|
1455 | $output .= "</option>\n";
|
---|
1456 | }
|
---|
1457 | }
|
---|
1458 |
|
---|
1459 | /**
|
---|
1460 | * Send XML response back to AJAX request.
|
---|
1461 | *
|
---|
1462 | * @package WordPress
|
---|
1463 | * @since 2.1.0
|
---|
1464 | */
|
---|
1465 | class WP_Ajax_Response {
|
---|
1466 | /**
|
---|
1467 | * Store XML responses to send.
|
---|
1468 | *
|
---|
1469 | * @since 2.1.0
|
---|
1470 | * @var array
|
---|
1471 | * @access private
|
---|
1472 | */
|
---|
1473 | var $responses = array();
|
---|
1474 |
|
---|
1475 | /**
|
---|
1476 | * PHP4 Constructor - Passes args to {@link WP_Ajax_Response::add()}.
|
---|
1477 | *
|
---|
1478 | * @since 2.1.0
|
---|
1479 | * @see WP_Ajax_Response::add()
|
---|
1480 | *
|
---|
1481 | * @param string|array $args Optional. Will be passed to add() method.
|
---|
1482 | * @return WP_Ajax_Response
|
---|
1483 | */
|
---|
1484 | function WP_Ajax_Response( $args = '' ) {
|
---|
1485 | if ( !empty($args) )
|
---|
1486 | $this->add($args);
|
---|
1487 | }
|
---|
1488 |
|
---|
1489 | /**
|
---|
1490 | * Append to XML response based on given arguments.
|
---|
1491 | *
|
---|
1492 | * The arguments that can be passed in the $args parameter are below. It is
|
---|
1493 | * also possible to pass a WP_Error object in either the 'id' or 'data'
|
---|
1494 | * argument. The parameter isn't actually optional, content should be given
|
---|
1495 | * in order to send the correct response.
|
---|
1496 | *
|
---|
1497 | * 'what' argument is a string that is the XMLRPC response type.
|
---|
1498 | * 'action' argument is a boolean or string that acts like a nonce.
|
---|
1499 | * 'id' argument can be WP_Error or an integer.
|
---|
1500 | * 'old_id' argument is false by default or an integer of the previous ID.
|
---|
1501 | * 'position' argument is an integer or a string with -1 = top, 1 = bottom,
|
---|
1502 | * html ID = after, -html ID = before.
|
---|
1503 | * 'data' argument is a string with the content or message.
|
---|
1504 | * 'supplemental' argument is an array of strings that will be children of
|
---|
1505 | * the supplemental element.
|
---|
1506 | *
|
---|
1507 | * @since 2.1.0
|
---|
1508 | *
|
---|
1509 | * @param string|array $args Override defaults.
|
---|
1510 | * @return string XML response.
|
---|
1511 | */
|
---|
1512 | function add( $args = '' ) {
|
---|
1513 | $defaults = array(
|
---|
1514 | 'what' => 'object', 'action' => false,
|
---|
1515 | 'id' => '0', 'old_id' => false,
|
---|
1516 | 'position' => 1,
|
---|
1517 | 'data' => '', 'supplemental' => array()
|
---|
1518 | );
|
---|
1519 |
|
---|
1520 | $r = wp_parse_args( $args, $defaults );
|
---|
1521 | extract( $r, EXTR_SKIP );
|
---|
1522 | $position = preg_replace( '/[^a-z0-9:_-]/i', '', $position );
|
---|
1523 |
|
---|
1524 | if ( is_wp_error($id) ) {
|
---|
1525 | $data = $id;
|
---|
1526 | $id = 0;
|
---|
1527 | }
|
---|
1528 |
|
---|
1529 | $response = '';
|
---|
1530 | if ( is_wp_error($data) ) {
|
---|
1531 | foreach ( (array) $data->get_error_codes() as $code ) {
|
---|
1532 | $response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message($code) . "]]></wp_error>";
|
---|
1533 | if ( !$error_data = $data->get_error_data($code) )
|
---|
1534 | continue;
|
---|
1535 | $class = '';
|
---|
1536 | if ( is_object($error_data) ) {
|
---|
1537 | $class = ' class="' . get_class($error_data) . '"';
|
---|
1538 | $error_data = get_object_vars($error_data);
|
---|
1539 | }
|
---|
1540 |
|
---|
1541 | $response .= "<wp_error_data code='$code'$class>";
|
---|
1542 |
|
---|
1543 | if ( is_scalar($error_data) ) {
|
---|
1544 | $response .= "<![CDATA[$error_data]]>";
|
---|
1545 | } elseif ( is_array($error_data) ) {
|
---|
1546 | foreach ( $error_data as $k => $v )
|
---|
1547 | $response .= "<$k><![CDATA[$v]]></$k>";
|
---|
1548 | }
|
---|
1549 |
|
---|
1550 | $response .= "</wp_error_data>";
|
---|
1551 | }
|
---|
1552 | } else {
|
---|
1553 | $response = "<response_data><![CDATA[$data]]></response_data>";
|
---|
1554 | }
|
---|
1555 |
|
---|
1556 | $s = '';
|
---|
1557 | if ( is_array($supplemental) ) {
|
---|
1558 | foreach ( $supplemental as $k => $v )
|
---|
1559 | $s .= "<$k><![CDATA[$v]]></$k>";
|
---|
1560 | $s = "<supplemental>$s</supplemental>";
|
---|
1561 | }
|
---|
1562 |
|
---|
1563 | if ( false === $action )
|
---|
1564 | $action = $_POST['action'];
|
---|
1565 |
|
---|
1566 | $x = '';
|
---|
1567 | $x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action
|
---|
1568 | $x .= "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>";
|
---|
1569 | $x .= $response;
|
---|
1570 | $x .= $s;
|
---|
1571 | $x .= "</$what>";
|
---|
1572 | $x .= "</response>";
|
---|
1573 |
|
---|
1574 | $this->responses[] = $x;
|
---|
1575 | return $x;
|
---|
1576 | }
|
---|
1577 |
|
---|
1578 | /**
|
---|
1579 | * Display XML formatted responses.
|
---|
1580 | *
|
---|
1581 | * Sets the content type header to text/xml.
|
---|
1582 | *
|
---|
1583 | * @since 2.1.0
|
---|
1584 | */
|
---|
1585 | function send() {
|
---|
1586 | header('Content-Type: text/xml');
|
---|
1587 | echo "<?xml version='1.0' standalone='yes'?><wp_ajax>";
|
---|
1588 | foreach ( (array) $this->responses as $response )
|
---|
1589 | echo $response;
|
---|
1590 | echo '</wp_ajax>';
|
---|
1591 | die();
|
---|
1592 | }
|
---|
1593 | }
|
---|
1594 |
|
---|
1595 | ?>
|
---|