136
|
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 |
$query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); |
|
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 |
/** |
|
1596 |
* Helper class to remove the need to use eval to replace $matches[] in query strings. |
|
1597 |
* |
|
1598 |
* @since 2.9.0 |
|
1599 |
*/ |
|
1600 |
class WP_MatchesMapRegex { |
|
1601 |
/** |
|
1602 |
* store for matches |
|
1603 |
* |
|
1604 |
* @access private |
|
1605 |
* @var array |
|
1606 |
*/ |
|
1607 |
var $_matches; |
|
1608 |
|
|
1609 |
/** |
|
1610 |
* store for mapping result |
|
1611 |
* |
|
1612 |
* @access public |
|
1613 |
* @var string |
|
1614 |
*/ |
|
1615 |
var $output; |
|
1616 |
|
|
1617 |
/** |
|
1618 |
* subject to perform mapping on (query string containing $matches[] references |
|
1619 |
* |
|
1620 |
* @access private |
|
1621 |
* @var string |
|
1622 |
*/ |
|
1623 |
var $_subject; |
|
1624 |
|
|
1625 |
/** |
|
1626 |
* regexp pattern to match $matches[] references |
|
1627 |
* |
|
1628 |
* @var string |
|
1629 |
*/ |
|
1630 |
var $_pattern = '(\$matches\[[1-9]+[0-9]*\])'; // magic number |
|
1631 |
|
|
1632 |
/** |
|
1633 |
* constructor |
|
1634 |
* |
|
1635 |
* @param string $subject subject if regex |
|
1636 |
* @param array $matches data to use in map |
|
1637 |
* @return self |
|
1638 |
*/ |
|
1639 |
function WP_MatchesMapRegex($subject, $matches) { |
|
1640 |
$this->_subject = $subject; |
|
1641 |
$this->_matches = $matches; |
|
1642 |
$this->output = $this->_map(); |
|
1643 |
} |
|
1644 |
|
|
1645 |
/** |
|
1646 |
* Substitute substring matches in subject. |
|
1647 |
* |
|
1648 |
* static helper function to ease use |
|
1649 |
* |
|
1650 |
* @access public |
|
1651 |
* @param string $subject subject |
|
1652 |
* @param array $matches data used for subsitution |
|
1653 |
* @return string |
|
1654 |
*/ |
|
1655 |
function apply($subject, $matches) { |
|
1656 |
$oSelf =& new WP_MatchesMapRegex($subject, $matches); |
|
1657 |
return $oSelf->output; |
|
1658 |
} |
|
1659 |
|
|
1660 |
/** |
|
1661 |
* do the actual mapping |
|
1662 |
* |
|
1663 |
* @access private |
|
1664 |
* @return string |
|
1665 |
*/ |
|
1666 |
function _map() { |
|
1667 |
$callback = array(&$this, 'callback'); |
|
1668 |
return preg_replace_callback($this->_pattern, $callback, $this->_subject); |
|
1669 |
} |
|
1670 |
|
|
1671 |
/** |
|
1672 |
* preg_replace_callback hook |
|
1673 |
* |
|
1674 |
* @access public |
|
1675 |
* @param array $matches preg_replace regexp matches |
|
1676 |
* @return string |
|
1677 |
*/ |
|
1678 |
function callback($matches) { |
|
1679 |
$index = intval(substr($matches[0], 9, -1)); |
|
1680 |
return ( isset( $this->_matches[$index] ) ? $this->_matches[$index] : '' ); |
|
1681 |
} |
|
1682 |
|
|
1683 |
} |
|
1684 |
|
|
1685 |
?> |