|
1 <?php |
|
2 /** |
|
3 * Main WordPress API |
|
4 * |
|
5 * @package WordPress |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Converts MySQL DATETIME field to user specified date format. |
|
10 * |
|
11 * If $dateformatstring has 'G' value, then gmmktime() function will be used to |
|
12 * make the time. If $dateformatstring is set to 'U', then mktime() function |
|
13 * will be used to make the time. |
|
14 * |
|
15 * The $translate will only be used, if it is set to true and it is by default |
|
16 * and if the $wp_locale object has the month and weekday set. |
|
17 * |
|
18 * @since 0.71 |
|
19 * |
|
20 * @param string $dateformatstring Either 'G', 'U', or php date format. |
|
21 * @param string $mysqlstring Time from mysql DATETIME field. |
|
22 * @param bool $translate Optional. Default is true. Will switch format to locale. |
|
23 * @return string Date formated by $dateformatstring or locale (if available). |
|
24 */ |
|
25 function mysql2date( $dateformatstring, $mysqlstring, $translate = true ) { |
|
26 global $wp_locale; |
|
27 $m = $mysqlstring; |
|
28 if ( empty( $m ) ) |
|
29 return false; |
|
30 |
|
31 if( 'G' == $dateformatstring ) { |
|
32 return strtotime( $m . ' +0000' ); |
|
33 } |
|
34 |
|
35 $i = strtotime( $m ); |
|
36 |
|
37 if( 'U' == $dateformatstring ) |
|
38 return $i; |
|
39 |
|
40 if ( $translate) |
|
41 return date_i18n( $dateformatstring, $i ); |
|
42 else |
|
43 return date( $dateformatstring, $i ); |
|
44 } |
|
45 |
|
46 /** |
|
47 * Retrieve the current time based on specified type. |
|
48 * |
|
49 * The 'mysql' type will return the time in the format for MySQL DATETIME field. |
|
50 * The 'timestamp' type will return the current timestamp. |
|
51 * |
|
52 * If $gmt is set to either '1' or 'true', then both types will use GMT time. |
|
53 * if $gmt is false, the output is adjusted with the GMT offset in the WordPress option. |
|
54 * |
|
55 * @since 1.0.0 |
|
56 * |
|
57 * @param string $type Either 'mysql' or 'timestamp'. |
|
58 * @param int|bool $gmt Optional. Whether to use GMT timezone. Default is false. |
|
59 * @return int|string String if $type is 'gmt', int if $type is 'timestamp'. |
|
60 */ |
|
61 function current_time( $type, $gmt = 0 ) { |
|
62 switch ( $type ) { |
|
63 case 'mysql': |
|
64 return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', ( time() + ( get_option( 'gmt_offset' ) * 3600 ) ) ); |
|
65 break; |
|
66 case 'timestamp': |
|
67 return ( $gmt ) ? time() : time() + ( get_option( 'gmt_offset' ) * 3600 ); |
|
68 break; |
|
69 } |
|
70 } |
|
71 |
|
72 /** |
|
73 * Retrieve the date in localized format, based on timestamp. |
|
74 * |
|
75 * If the locale specifies the locale month and weekday, then the locale will |
|
76 * take over the format for the date. If it isn't, then the date format string |
|
77 * will be used instead. |
|
78 * |
|
79 * @since 0.71 |
|
80 * |
|
81 * @param string $dateformatstring Format to display the date. |
|
82 * @param int $unixtimestamp Optional. Unix timestamp. |
|
83 * @param bool $gmt Optional, default is false. Whether to convert to GMT for time. |
|
84 * @return string The date, translated if locale specifies it. |
|
85 */ |
|
86 function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) { |
|
87 global $wp_locale; |
|
88 $i = $unixtimestamp; |
|
89 // Sanity check for PHP 5.1.0- |
|
90 if ( false === $i || intval($i) < 0 ) { |
|
91 if ( ! $gmt ) |
|
92 $i = current_time( 'timestamp' ); |
|
93 else |
|
94 $i = time(); |
|
95 // we should not let date() interfere with our |
|
96 // specially computed timestamp |
|
97 $gmt = true; |
|
98 } |
|
99 |
|
100 // store original value for language with untypical grammars |
|
101 // see http://core.trac.wordpress.org/ticket/9396 |
|
102 $req_format = $dateformatstring; |
|
103 |
|
104 $datefunc = $gmt? 'gmdate' : 'date'; |
|
105 |
|
106 if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) { |
|
107 $datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) ); |
|
108 $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth ); |
|
109 $dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) ); |
|
110 $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday ); |
|
111 $datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) ); |
|
112 $datemeridiem_capital = $wp_locale->get_meridiem( $datefunc( 'A', $i ) ); |
|
113 $dateformatstring = ' '.$dateformatstring; |
|
114 $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring ); |
|
115 $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring ); |
|
116 $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring ); |
|
117 $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring ); |
|
118 $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring ); |
|
119 $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring ); |
|
120 |
|
121 $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 ); |
|
122 } |
|
123 $j = @$datefunc( $dateformatstring, $i ); |
|
124 // allow plugins to redo this entirely for languages with untypical grammars |
|
125 $j = apply_filters('date_i18n', $j, $req_format, $i, $gmt); |
|
126 return $j; |
|
127 } |
|
128 |
|
129 /** |
|
130 * Convert number to format based on the locale. |
|
131 * |
|
132 * @since 2.3.0 |
|
133 * |
|
134 * @param mixed $number The number to convert based on locale. |
|
135 * @param int $decimals Precision of the number of decimal places. |
|
136 * @return string Converted number in string format. |
|
137 */ |
|
138 function number_format_i18n( $number, $decimals = null ) { |
|
139 global $wp_locale; |
|
140 // let the user override the precision only |
|
141 $decimals = ( is_null( $decimals ) ) ? $wp_locale->number_format['decimals'] : intval( $decimals ); |
|
142 |
|
143 $num = number_format( $number, $decimals, $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep'] ); |
|
144 |
|
145 // let the user translate digits from latin to localized language |
|
146 return apply_filters( 'number_format_i18n', $num ); |
|
147 } |
|
148 |
|
149 /** |
|
150 * Convert number of bytes largest unit bytes will fit into. |
|
151 * |
|
152 * It is easier to read 1kB than 1024 bytes and 1MB than 1048576 bytes. Converts |
|
153 * number of bytes to human readable number by taking the number of that unit |
|
154 * that the bytes will go into it. Supports TB value. |
|
155 * |
|
156 * Please note that integers in PHP are limited to 32 bits, unless they are on |
|
157 * 64 bit architecture, then they have 64 bit size. If you need to place the |
|
158 * larger size then what PHP integer type will hold, then use a string. It will |
|
159 * be converted to a double, which should always have 64 bit length. |
|
160 * |
|
161 * Technically the correct unit names for powers of 1024 are KiB, MiB etc. |
|
162 * @link http://en.wikipedia.org/wiki/Byte |
|
163 * |
|
164 * @since 2.3.0 |
|
165 * |
|
166 * @param int|string $bytes Number of bytes. Note max integer size for integers. |
|
167 * @param int $decimals Precision of number of decimal places. |
|
168 * @return bool|string False on failure. Number string on success. |
|
169 */ |
|
170 function size_format( $bytes, $decimals = null ) { |
|
171 $quant = array( |
|
172 // ========================= Origin ==== |
|
173 'TB' => 1099511627776, // pow( 1024, 4) |
|
174 'GB' => 1073741824, // pow( 1024, 3) |
|
175 'MB' => 1048576, // pow( 1024, 2) |
|
176 'kB' => 1024, // pow( 1024, 1) |
|
177 'B ' => 1, // pow( 1024, 0) |
|
178 ); |
|
179 |
|
180 foreach ( $quant as $unit => $mag ) |
|
181 if ( doubleval($bytes) >= $mag ) |
|
182 return number_format_i18n( $bytes / $mag, $decimals ) . ' ' . $unit; |
|
183 |
|
184 return false; |
|
185 } |
|
186 |
|
187 /** |
|
188 * Get the week start and end from the datetime or date string from mysql. |
|
189 * |
|
190 * @since 0.71 |
|
191 * |
|
192 * @param string $mysqlstring Date or datetime field type from mysql. |
|
193 * @param int $start_of_week Optional. Start of the week as an integer. |
|
194 * @return array Keys are 'start' and 'end'. |
|
195 */ |
|
196 function get_weekstartend( $mysqlstring, $start_of_week = '' ) { |
|
197 $my = substr( $mysqlstring, 0, 4 ); // Mysql string Year |
|
198 $mm = substr( $mysqlstring, 8, 2 ); // Mysql string Month |
|
199 $md = substr( $mysqlstring, 5, 2 ); // Mysql string day |
|
200 $day = mktime( 0, 0, 0, $md, $mm, $my ); // The timestamp for mysqlstring day. |
|
201 $weekday = date( 'w', $day ); // The day of the week from the timestamp |
|
202 $i = 86400; // One day |
|
203 if( !is_numeric($start_of_week) ) |
|
204 $start_of_week = get_option( 'start_of_week' ); |
|
205 |
|
206 if ( $weekday < $start_of_week ) |
|
207 $weekday = 7 - $start_of_week - $weekday; |
|
208 |
|
209 while ( $weekday > $start_of_week ) { |
|
210 $weekday = date( 'w', $day ); |
|
211 if ( $weekday < $start_of_week ) |
|
212 $weekday = 7 - $start_of_week - $weekday; |
|
213 |
|
214 $day -= 86400; |
|
215 $i = 0; |
|
216 } |
|
217 $week['start'] = $day + 86400 - $i; |
|
218 $week['end'] = $week['start'] + 604799; |
|
219 return $week; |
|
220 } |
|
221 |
|
222 /** |
|
223 * Unserialize value only if it was serialized. |
|
224 * |
|
225 * @since 2.0.0 |
|
226 * |
|
227 * @param string $original Maybe unserialized original, if is needed. |
|
228 * @return mixed Unserialized data can be any type. |
|
229 */ |
|
230 function maybe_unserialize( $original ) { |
|
231 if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in |
|
232 return @unserialize( $original ); |
|
233 return $original; |
|
234 } |
|
235 |
|
236 /** |
|
237 * Check value to find if it was serialized. |
|
238 * |
|
239 * If $data is not an string, then returned value will always be false. |
|
240 * Serialized data is always a string. |
|
241 * |
|
242 * @since 2.0.5 |
|
243 * |
|
244 * @param mixed $data Value to check to see if was serialized. |
|
245 * @return bool False if not serialized and true if it was. |
|
246 */ |
|
247 function is_serialized( $data ) { |
|
248 // if it isn't a string, it isn't serialized |
|
249 if ( !is_string( $data ) ) |
|
250 return false; |
|
251 $data = trim( $data ); |
|
252 if ( 'N;' == $data ) |
|
253 return true; |
|
254 if ( !preg_match( '/^([adObis]):/', $data, $badions ) ) |
|
255 return false; |
|
256 switch ( $badions[1] ) { |
|
257 case 'a' : |
|
258 case 'O' : |
|
259 case 's' : |
|
260 if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) ) |
|
261 return true; |
|
262 break; |
|
263 case 'b' : |
|
264 case 'i' : |
|
265 case 'd' : |
|
266 if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) ) |
|
267 return true; |
|
268 break; |
|
269 } |
|
270 return false; |
|
271 } |
|
272 |
|
273 /** |
|
274 * Check whether serialized data is of string type. |
|
275 * |
|
276 * @since 2.0.5 |
|
277 * |
|
278 * @param mixed $data Serialized data |
|
279 * @return bool False if not a serialized string, true if it is. |
|
280 */ |
|
281 function is_serialized_string( $data ) { |
|
282 // if it isn't a string, it isn't a serialized string |
|
283 if ( !is_string( $data ) ) |
|
284 return false; |
|
285 $data = trim( $data ); |
|
286 if ( preg_match( '/^s:[0-9]+:.*;$/s', $data ) ) // this should fetch all serialized strings |
|
287 return true; |
|
288 return false; |
|
289 } |
|
290 |
|
291 /** |
|
292 * Retrieve option value based on setting name. |
|
293 * |
|
294 * If the option does not exist or does not have a value, then the return value |
|
295 * will be false. This is useful to check whether you need to install an option |
|
296 * and is commonly used during installation of plugin options and to test |
|
297 * whether upgrading is required. |
|
298 * |
|
299 * You can "short-circuit" the retrieval of the option from the database for |
|
300 * your plugin or core options that aren't protected. You can do so by hooking |
|
301 * into the 'pre_option_$option' with the $option being replaced by the option |
|
302 * name. You should not try to override special options, but you will not be |
|
303 * prevented from doing so. |
|
304 * |
|
305 * There is a second filter called 'option_$option' with the $option being |
|
306 * replaced with the option name. This gives the value as the only parameter. |
|
307 * |
|
308 * If the option was serialized, when the option was added and, or updated, then |
|
309 * it will be unserialized, when it is returned. |
|
310 * |
|
311 * @since 1.5.0 |
|
312 * @package WordPress |
|
313 * @subpackage Option |
|
314 * @uses apply_filters() Calls 'pre_option_$optionname' false to allow |
|
315 * overwriting the option value in a plugin. |
|
316 * @uses apply_filters() Calls 'option_$optionname' with the option name value. |
|
317 * |
|
318 * @param string $setting Name of option to retrieve. Should already be SQL-escaped |
|
319 * @return mixed Value set for the option. |
|
320 */ |
|
321 function get_option( $setting, $default = false ) { |
|
322 global $wpdb; |
|
323 |
|
324 // Allow plugins to short-circuit options. |
|
325 $pre = apply_filters( 'pre_option_' . $setting, false ); |
|
326 if ( false !== $pre ) |
|
327 return $pre; |
|
328 |
|
329 // prevent non-existent options from triggering multiple queries |
|
330 $notoptions = wp_cache_get( 'notoptions', 'options' ); |
|
331 if ( isset( $notoptions[$setting] ) ) |
|
332 return $default; |
|
333 |
|
334 $alloptions = wp_load_alloptions(); |
|
335 |
|
336 if ( isset( $alloptions[$setting] ) ) { |
|
337 $value = $alloptions[$setting]; |
|
338 } else { |
|
339 $value = wp_cache_get( $setting, 'options' ); |
|
340 |
|
341 if ( false === $value ) { |
|
342 if ( defined( 'WP_INSTALLING' ) ) |
|
343 $suppress = $wpdb->suppress_errors(); |
|
344 // expected_slashed ($setting) |
|
345 $row = $wpdb->get_row( "SELECT option_value FROM $wpdb->options WHERE option_name = '$setting' LIMIT 1" ); |
|
346 if ( defined( 'WP_INSTALLING' ) ) |
|
347 $wpdb->suppress_errors($suppress); |
|
348 |
|
349 if ( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values |
|
350 $value = $row->option_value; |
|
351 wp_cache_add( $setting, $value, 'options' ); |
|
352 } else { // option does not exist, so we must cache its non-existence |
|
353 $notoptions[$setting] = true; |
|
354 wp_cache_set( 'notoptions', $notoptions, 'options' ); |
|
355 return $default; |
|
356 } |
|
357 } |
|
358 } |
|
359 |
|
360 // If home is not set use siteurl. |
|
361 if ( 'home' == $setting && '' == $value ) |
|
362 return get_option( 'siteurl' ); |
|
363 |
|
364 if ( in_array( $setting, array('siteurl', 'home', 'category_base', 'tag_base') ) ) |
|
365 $value = untrailingslashit( $value ); |
|
366 |
|
367 return apply_filters( 'option_' . $setting, maybe_unserialize( $value ) ); |
|
368 } |
|
369 |
|
370 /** |
|
371 * Protect WordPress special option from being modified. |
|
372 * |
|
373 * Will die if $option is in protected list. Protected options are 'alloptions' |
|
374 * and 'notoptions' options. |
|
375 * |
|
376 * @since 2.2.0 |
|
377 * @package WordPress |
|
378 * @subpackage Option |
|
379 * |
|
380 * @param string $option Option name. |
|
381 */ |
|
382 function wp_protect_special_option( $option ) { |
|
383 $protected = array( 'alloptions', 'notoptions' ); |
|
384 if ( in_array( $option, $protected ) ) |
|
385 die( sprintf( __( '%s is a protected WP option and may not be modified' ), esc_html( $option ) ) ); |
|
386 } |
|
387 |
|
388 /** |
|
389 * Print option value after sanitizing for forms. |
|
390 * |
|
391 * @uses attr Sanitizes value. |
|
392 * @since 1.5.0 |
|
393 * @package WordPress |
|
394 * @subpackage Option |
|
395 * |
|
396 * @param string $option Option name. |
|
397 */ |
|
398 function form_option( $option ) { |
|
399 echo esc_attr(get_option( $option ) ); |
|
400 } |
|
401 |
|
402 /** |
|
403 * Retrieve all autoload options or all options, if no autoloaded ones exist. |
|
404 * |
|
405 * This is different from wp_load_alloptions() in that this function does not |
|
406 * cache its results and will retrieve all options from the database every time |
|
407 * |
|
408 * it is called. |
|
409 * |
|
410 * @since 1.0.0 |
|
411 * @package WordPress |
|
412 * @subpackage Option |
|
413 * @uses apply_filters() Calls 'pre_option_$optionname' hook with option value as parameter. |
|
414 * @uses apply_filters() Calls 'all_options' on options list. |
|
415 * |
|
416 * @return array List of all options. |
|
417 */ |
|
418 function get_alloptions() { |
|
419 global $wpdb; |
|
420 $show = $wpdb->hide_errors(); |
|
421 if ( !$options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'" ) ) |
|
422 $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ); |
|
423 $wpdb->show_errors($show); |
|
424 |
|
425 foreach ( (array) $options as $option ) { |
|
426 // "When trying to design a foolproof system, |
|
427 // never underestimate the ingenuity of the fools :)" -- Dougal |
|
428 if ( in_array( $option->option_name, array( 'siteurl', 'home', 'category_base', 'tag_base' ) ) ) |
|
429 $option->option_value = untrailingslashit( $option->option_value ); |
|
430 $value = maybe_unserialize( $option->option_value ); |
|
431 $all_options->{$option->option_name} = apply_filters( 'pre_option_' . $option->option_name, $value ); |
|
432 } |
|
433 return apply_filters( 'all_options', $all_options ); |
|
434 } |
|
435 |
|
436 /** |
|
437 * Loads and caches all autoloaded options, if available or all options. |
|
438 * |
|
439 * This is different from get_alloptions(), in that this function will cache the |
|
440 * options and will return the cached options when called again. |
|
441 * |
|
442 * @since 2.2.0 |
|
443 * @package WordPress |
|
444 * @subpackage Option |
|
445 * |
|
446 * @return array List all options. |
|
447 */ |
|
448 function wp_load_alloptions() { |
|
449 global $wpdb; |
|
450 |
|
451 $alloptions = wp_cache_get( 'alloptions', 'options' ); |
|
452 |
|
453 if ( !$alloptions ) { |
|
454 $suppress = $wpdb->suppress_errors(); |
|
455 if ( !$alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'" ) ) |
|
456 $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ); |
|
457 $wpdb->suppress_errors($suppress); |
|
458 $alloptions = array(); |
|
459 foreach ( (array) $alloptions_db as $o ) |
|
460 $alloptions[$o->option_name] = $o->option_value; |
|
461 wp_cache_add( 'alloptions', $alloptions, 'options' ); |
|
462 } |
|
463 return $alloptions; |
|
464 } |
|
465 |
|
466 /** |
|
467 * Update the value of an option that was already added. |
|
468 * |
|
469 * You do not need to serialize values, if the value needs to be serialize, then |
|
470 * it will be serialized before it is inserted into the database. Remember, |
|
471 * resources can not be serialized or added as an option. |
|
472 * |
|
473 * If the option does not exist, then the option will be added with the option |
|
474 * value, but you will not be able to set whether it is autoloaded. If you want |
|
475 * to set whether an option autoloaded, then you need to use the add_option(). |
|
476 * |
|
477 * Before the option is updated, then the filter named |
|
478 * 'pre_update_option_$option_name', with the $option_name as the $option_name |
|
479 * parameter value, will be called. The hook should accept two parameters, the |
|
480 * first is the new value and the second is the old value. Whatever is |
|
481 * returned will be used as the new value. |
|
482 * |
|
483 * After the value has been updated the action named 'update_option_$option_name' |
|
484 * will be called. This action receives two parameters the first being the old |
|
485 * value and the second the new value. |
|
486 * |
|
487 * @since 1.0.0 |
|
488 * @package WordPress |
|
489 * @subpackage Option |
|
490 * |
|
491 * @param string $option_name Option name. Expected to not be SQL-escaped |
|
492 * @param mixed $newvalue Option value. |
|
493 * @return bool False if value was not updated and true if value was updated. |
|
494 */ |
|
495 function update_option( $option_name, $newvalue ) { |
|
496 global $wpdb; |
|
497 |
|
498 wp_protect_special_option( $option_name ); |
|
499 |
|
500 $safe_option_name = $wpdb->escape( $option_name ); |
|
501 $newvalue = sanitize_option( $option_name, $newvalue ); |
|
502 |
|
503 $oldvalue = get_option( $safe_option_name ); |
|
504 |
|
505 $newvalue = apply_filters( 'pre_update_option_' . $option_name, $newvalue, $oldvalue ); |
|
506 |
|
507 // If the new and old values are the same, no need to update. |
|
508 if ( $newvalue === $oldvalue ) |
|
509 return false; |
|
510 |
|
511 if ( false === $oldvalue ) { |
|
512 add_option( $option_name, $newvalue ); |
|
513 return true; |
|
514 } |
|
515 |
|
516 $notoptions = wp_cache_get( 'notoptions', 'options' ); |
|
517 if ( is_array( $notoptions ) && isset( $notoptions[$option_name] ) ) { |
|
518 unset( $notoptions[$option_name] ); |
|
519 wp_cache_set( 'notoptions', $notoptions, 'options' ); |
|
520 } |
|
521 |
|
522 $_newvalue = $newvalue; |
|
523 $newvalue = maybe_serialize( $newvalue ); |
|
524 |
|
525 $alloptions = wp_load_alloptions(); |
|
526 if ( isset( $alloptions[$option_name] ) ) { |
|
527 $alloptions[$option_name] = $newvalue; |
|
528 wp_cache_set( 'alloptions', $alloptions, 'options' ); |
|
529 } else { |
|
530 wp_cache_set( $option_name, $newvalue, 'options' ); |
|
531 } |
|
532 |
|
533 $wpdb->update($wpdb->options, array('option_value' => $newvalue), array('option_name' => $option_name) ); |
|
534 |
|
535 if ( $wpdb->rows_affected == 1 ) { |
|
536 do_action( "update_option_{$option_name}", $oldvalue, $_newvalue ); |
|
537 return true; |
|
538 } |
|
539 return false; |
|
540 } |
|
541 |
|
542 /** |
|
543 * Add a new option. |
|
544 * |
|
545 * You do not need to serialize values, if the value needs to be serialize, then |
|
546 * it will be serialized before it is inserted into the database. Remember, |
|
547 * resources can not be serialized or added as an option. |
|
548 * |
|
549 * You can create options without values and then add values later. Does not |
|
550 * check whether the option has already been added, but does check that you |
|
551 * aren't adding a protected WordPress option. Care should be taken to not name |
|
552 * options, the same as the ones which are protected and to not add options |
|
553 * that were already added. |
|
554 * |
|
555 * The filter named 'add_option_$optionname', with the $optionname being |
|
556 * replaced with the option's name, will be called. The hook should accept two |
|
557 * parameters, the first is the option name, and the second is the value. |
|
558 * |
|
559 * @package WordPress |
|
560 * @subpackage Option |
|
561 * @since 1.0.0 |
|
562 * @link http://alex.vort-x.net/blog/ Thanks Alex Stapleton |
|
563 * |
|
564 * @param string $name Option name to add. Expects to NOT be SQL escaped. |
|
565 * @param mixed $value Optional. Option value, can be anything. |
|
566 * @param mixed $deprecated Optional. Description. Not used anymore. |
|
567 * @param bool $autoload Optional. Default is enabled. Whether to load the option when WordPress starts up. |
|
568 * @return null returns when finished. |
|
569 */ |
|
570 function add_option( $name, $value = '', $deprecated = '', $autoload = 'yes' ) { |
|
571 global $wpdb; |
|
572 |
|
573 wp_protect_special_option( $name ); |
|
574 $safe_name = $wpdb->escape( $name ); |
|
575 $value = sanitize_option( $name, $value ); |
|
576 |
|
577 // Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query |
|
578 $notoptions = wp_cache_get( 'notoptions', 'options' ); |
|
579 if ( !is_array( $notoptions ) || !isset( $notoptions[$name] ) ) |
|
580 if ( false !== get_option( $safe_name ) ) |
|
581 return; |
|
582 |
|
583 $value = maybe_serialize( $value ); |
|
584 $autoload = ( 'no' === $autoload ) ? 'no' : 'yes'; |
|
585 |
|
586 if ( 'yes' == $autoload ) { |
|
587 $alloptions = wp_load_alloptions(); |
|
588 $alloptions[$name] = $value; |
|
589 wp_cache_set( 'alloptions', $alloptions, 'options' ); |
|
590 } else { |
|
591 wp_cache_set( $name, $value, 'options' ); |
|
592 } |
|
593 |
|
594 // This option exists now |
|
595 $notoptions = wp_cache_get( 'notoptions', 'options' ); // yes, again... we need it to be fresh |
|
596 if ( is_array( $notoptions ) && isset( $notoptions[$name] ) ) { |
|
597 unset( $notoptions[$name] ); |
|
598 wp_cache_set( 'notoptions', $notoptions, 'options' ); |
|
599 } |
|
600 |
|
601 $wpdb->insert($wpdb->options, array('option_name' => $name, 'option_value' => $value, 'autoload' => $autoload) ); |
|
602 |
|
603 do_action( "add_option_{$name}", $name, $value ); |
|
604 return; |
|
605 } |
|
606 |
|
607 /** |
|
608 * Removes option by name and prevents removal of protected WordPress options. |
|
609 * |
|
610 * @package WordPress |
|
611 * @subpackage Option |
|
612 * @since 1.2.0 |
|
613 * |
|
614 * @param string $name Option name to remove. |
|
615 * @return bool True, if succeed. False, if failure. |
|
616 */ |
|
617 function delete_option( $name ) { |
|
618 global $wpdb; |
|
619 |
|
620 wp_protect_special_option( $name ); |
|
621 |
|
622 // Get the ID, if no ID then return |
|
623 // expected_slashed ($name) |
|
624 $option = $wpdb->get_row( "SELECT option_id, autoload FROM $wpdb->options WHERE option_name = '$name'" ); |
|
625 if ( is_null($option) || !$option->option_id ) |
|
626 return false; |
|
627 // expected_slashed ($name) |
|
628 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name = '$name'" ); |
|
629 if ( 'yes' == $option->autoload ) { |
|
630 $alloptions = wp_load_alloptions(); |
|
631 if ( isset( $alloptions[$name] ) ) { |
|
632 unset( $alloptions[$name] ); |
|
633 wp_cache_set( 'alloptions', $alloptions, 'options' ); |
|
634 } |
|
635 } else { |
|
636 wp_cache_delete( $name, 'options' ); |
|
637 } |
|
638 return true; |
|
639 } |
|
640 |
|
641 /** |
|
642 * Delete a transient |
|
643 * |
|
644 * @since 2.8.0 |
|
645 * @package WordPress |
|
646 * @subpackage Transient |
|
647 * |
|
648 * @param string $transient Transient name. Expected to not be SQL-escaped |
|
649 * @return bool true if successful, false otherwise |
|
650 */ |
|
651 function delete_transient($transient) { |
|
652 global $_wp_using_ext_object_cache, $wpdb; |
|
653 |
|
654 if ( $_wp_using_ext_object_cache ) { |
|
655 return wp_cache_delete($transient, 'transient'); |
|
656 } else { |
|
657 $transient = '_transient_' . $wpdb->escape($transient); |
|
658 return delete_option($transient); |
|
659 } |
|
660 } |
|
661 |
|
662 /** |
|
663 * Get the value of a transient |
|
664 * |
|
665 * If the transient does not exist or does not have a value, then the return value |
|
666 * will be false. |
|
667 * |
|
668 * @since 2.8.0 |
|
669 * @package WordPress |
|
670 * @subpackage Transient |
|
671 * |
|
672 * @param string $transient Transient name. Expected to not be SQL-escaped |
|
673 * @return mixed Value of transient |
|
674 */ |
|
675 function get_transient($transient) { |
|
676 global $_wp_using_ext_object_cache, $wpdb; |
|
677 |
|
678 $pre = apply_filters( 'pre_transient_' . $transient, false ); |
|
679 if ( false !== $pre ) |
|
680 return $pre; |
|
681 |
|
682 if ( $_wp_using_ext_object_cache ) { |
|
683 $value = wp_cache_get($transient, 'transient'); |
|
684 } else { |
|
685 $transient_option = '_transient_' . $wpdb->escape($transient); |
|
686 // If option is not in alloptions, it is not autoloaded and thus has a timeout |
|
687 $alloptions = wp_load_alloptions(); |
|
688 if ( !isset( $alloptions[$transient_option] ) ) { |
|
689 $transient_timeout = '_transient_timeout_' . $wpdb->escape($transient); |
|
690 if ( get_option($transient_timeout) < time() ) { |
|
691 delete_option($transient_option); |
|
692 delete_option($transient_timeout); |
|
693 return false; |
|
694 } |
|
695 } |
|
696 |
|
697 $value = get_option($transient_option); |
|
698 } |
|
699 |
|
700 return apply_filters('transient_' . $transient, $value); |
|
701 } |
|
702 |
|
703 /** |
|
704 * Set/update the value of a transient |
|
705 * |
|
706 * You do not need to serialize values, if the value needs to be serialize, then |
|
707 * it will be serialized before it is set. |
|
708 * |
|
709 * @since 2.8.0 |
|
710 * @package WordPress |
|
711 * @subpackage Transient |
|
712 * |
|
713 * @param string $transient Transient name. Expected to not be SQL-escaped |
|
714 * @param mixed $value Transient value. |
|
715 * @param int $expiration Time until expiration in seconds, default 0 |
|
716 * @return bool False if value was not set and true if value was set. |
|
717 */ |
|
718 function set_transient($transient, $value, $expiration = 0) { |
|
719 global $_wp_using_ext_object_cache, $wpdb; |
|
720 |
|
721 if ( $_wp_using_ext_object_cache ) { |
|
722 return wp_cache_set($transient, $value, 'transient', $expiration); |
|
723 } else { |
|
724 $transient_timeout = '_transient_timeout_' . $transient; |
|
725 $transient = '_transient_' . $transient; |
|
726 $safe_transient = $wpdb->escape($transient); |
|
727 if ( false === get_option( $safe_transient ) ) { |
|
728 $autoload = 'yes'; |
|
729 if ( 0 != $expiration ) { |
|
730 $autoload = 'no'; |
|
731 add_option($transient_timeout, time() + $expiration, '', 'no'); |
|
732 } |
|
733 return add_option($transient, $value, '', $autoload); |
|
734 } else { |
|
735 if ( 0 != $expiration ) |
|
736 update_option($transient_timeout, time() + $expiration); |
|
737 return update_option($transient, $value); |
|
738 } |
|
739 } |
|
740 } |
|
741 |
|
742 /** |
|
743 * Saves and restores user interface settings stored in a cookie. |
|
744 * |
|
745 * Checks if the current user-settings cookie is updated and stores it. When no |
|
746 * cookie exists (different browser used), adds the last saved cookie restoring |
|
747 * the settings. |
|
748 * |
|
749 * @package WordPress |
|
750 * @subpackage Option |
|
751 * @since 2.7.0 |
|
752 */ |
|
753 function wp_user_settings() { |
|
754 |
|
755 if ( ! is_admin() ) |
|
756 return; |
|
757 |
|
758 if ( defined('DOING_AJAX') ) |
|
759 return; |
|
760 |
|
761 if ( ! $user = wp_get_current_user() ) |
|
762 return; |
|
763 |
|
764 $settings = get_user_option( 'user-settings', $user->ID, false ); |
|
765 |
|
766 if ( isset( $_COOKIE['wp-settings-' . $user->ID] ) ) { |
|
767 $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user->ID] ); |
|
768 |
|
769 if ( ! empty( $cookie ) && strpos( $cookie, '=' ) ) { |
|
770 if ( $cookie == $settings ) |
|
771 return; |
|
772 |
|
773 $last_time = (int) get_user_option( 'user-settings-time', $user->ID, false ); |
|
774 $saved = isset( $_COOKIE['wp-settings-time-' . $user->ID]) ? preg_replace( '/[^0-9]/', '', $_COOKIE['wp-settings-time-' . $user->ID] ) : 0; |
|
775 |
|
776 if ( $saved > $last_time ) { |
|
777 update_user_option( $user->ID, 'user-settings', $cookie, false ); |
|
778 update_user_option( $user->ID, 'user-settings-time', time() - 5, false ); |
|
779 return; |
|
780 } |
|
781 } |
|
782 } |
|
783 |
|
784 setcookie( 'wp-settings-' . $user->ID, $settings, time() + 31536000, SITECOOKIEPATH ); |
|
785 setcookie( 'wp-settings-time-' . $user->ID, time(), time() + 31536000, SITECOOKIEPATH ); |
|
786 $_COOKIE['wp-settings-' . $user->ID] = $settings; |
|
787 } |
|
788 |
|
789 /** |
|
790 * Retrieve user interface setting value based on setting name. |
|
791 * |
|
792 * @package WordPress |
|
793 * @subpackage Option |
|
794 * @since 2.7.0 |
|
795 * |
|
796 * @param string $name The name of the setting. |
|
797 * @param string $default Optional default value to return when $name is not set. |
|
798 * @return mixed the last saved user setting or the default value/false if it doesn't exist. |
|
799 */ |
|
800 function get_user_setting( $name, $default = false ) { |
|
801 |
|
802 $all = get_all_user_settings(); |
|
803 |
|
804 return isset($all[$name]) ? $all[$name] : $default; |
|
805 } |
|
806 |
|
807 /** |
|
808 * Add or update user interface setting. |
|
809 * |
|
810 * Both $name and $value can contain only ASCII letters, numbers and underscores. |
|
811 * This function has to be used before any output has started as it calls setcookie(). |
|
812 * |
|
813 * @package WordPress |
|
814 * @subpackage Option |
|
815 * @since 2.8.0 |
|
816 * |
|
817 * @param string $name The name of the setting. |
|
818 * @param string $value The value for the setting. |
|
819 * @return bool true if set successfully/false if not. |
|
820 */ |
|
821 function set_user_setting( $name, $value ) { |
|
822 |
|
823 if ( headers_sent() ) |
|
824 return false; |
|
825 |
|
826 $all = get_all_user_settings(); |
|
827 $name = preg_replace( '/[^A-Za-z0-9_]+/', '', $name ); |
|
828 |
|
829 if ( empty($name) ) |
|
830 return false; |
|
831 |
|
832 $all[$name] = $value; |
|
833 |
|
834 return wp_set_all_user_settings($all); |
|
835 } |
|
836 |
|
837 /** |
|
838 * Delete user interface settings. |
|
839 * |
|
840 * Deleting settings would reset them to the defaults. |
|
841 * This function has to be used before any output has started as it calls setcookie(). |
|
842 * |
|
843 * @package WordPress |
|
844 * @subpackage Option |
|
845 * @since 2.7.0 |
|
846 * |
|
847 * @param mixed $names The name or array of names of the setting to be deleted. |
|
848 * @return bool true if deleted successfully/false if not. |
|
849 */ |
|
850 function delete_user_setting( $names ) { |
|
851 |
|
852 if ( headers_sent() ) |
|
853 return false; |
|
854 |
|
855 $all = get_all_user_settings(); |
|
856 $names = (array) $names; |
|
857 |
|
858 foreach ( $names as $name ) { |
|
859 if ( isset($all[$name]) ) { |
|
860 unset($all[$name]); |
|
861 $deleted = true; |
|
862 } |
|
863 } |
|
864 |
|
865 if ( isset($deleted) ) |
|
866 return wp_set_all_user_settings($all); |
|
867 |
|
868 return false; |
|
869 } |
|
870 |
|
871 /** |
|
872 * Retrieve all user interface settings. |
|
873 * |
|
874 * @package WordPress |
|
875 * @subpackage Option |
|
876 * @since 2.7.0 |
|
877 * |
|
878 * @return array the last saved user settings or empty array. |
|
879 */ |
|
880 function get_all_user_settings() { |
|
881 global $_updated_user_settings; |
|
882 |
|
883 if ( ! $user = wp_get_current_user() ) |
|
884 return array(); |
|
885 |
|
886 if ( isset($_updated_user_settings) && is_array($_updated_user_settings) ) |
|
887 return $_updated_user_settings; |
|
888 |
|
889 $all = array(); |
|
890 if ( isset($_COOKIE['wp-settings-' . $user->ID]) ) { |
|
891 $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user->ID] ); |
|
892 |
|
893 if ( $cookie && strpos($cookie, '=') ) // the '=' cannot be 1st char |
|
894 parse_str($cookie, $all); |
|
895 |
|
896 } else { |
|
897 $option = get_user_option('user-settings', $user->ID); |
|
898 if ( $option && is_string($option) ) |
|
899 parse_str( $option, $all ); |
|
900 } |
|
901 |
|
902 return $all; |
|
903 } |
|
904 |
|
905 /** |
|
906 * Private. Set all user interface settings. |
|
907 * |
|
908 * @package WordPress |
|
909 * @subpackage Option |
|
910 * @since 2.8.0 |
|
911 * |
|
912 */ |
|
913 function wp_set_all_user_settings($all) { |
|
914 global $_updated_user_settings; |
|
915 |
|
916 if ( ! $user = wp_get_current_user() ) |
|
917 return false; |
|
918 |
|
919 $_updated_user_settings = $all; |
|
920 $settings = ''; |
|
921 foreach ( $all as $k => $v ) { |
|
922 $v = preg_replace( '/[^A-Za-z0-9_]+/', '', $v ); |
|
923 $settings .= $k . '=' . $v . '&'; |
|
924 } |
|
925 |
|
926 $settings = rtrim($settings, '&'); |
|
927 |
|
928 update_user_option( $user->ID, 'user-settings', $settings, false ); |
|
929 update_user_option( $user->ID, 'user-settings-time', time(), false ); |
|
930 |
|
931 return true; |
|
932 } |
|
933 |
|
934 /** |
|
935 * Delete the user settings of the current user. |
|
936 * |
|
937 * @package WordPress |
|
938 * @subpackage Option |
|
939 * @since 2.7.0 |
|
940 */ |
|
941 function delete_all_user_settings() { |
|
942 if ( ! $user = wp_get_current_user() ) |
|
943 return; |
|
944 |
|
945 update_user_option( $user->ID, 'user-settings', '', false ); |
|
946 setcookie('wp-settings-' . $user->ID, ' ', time() - 31536000, SITECOOKIEPATH); |
|
947 } |
|
948 |
|
949 /** |
|
950 * Serialize data, if needed. |
|
951 * |
|
952 * @since 2.0.5 |
|
953 * |
|
954 * @param mixed $data Data that might be serialized. |
|
955 * @return mixed A scalar data |
|
956 */ |
|
957 function maybe_serialize( $data ) { |
|
958 if ( is_array( $data ) || is_object( $data ) ) |
|
959 return serialize( $data ); |
|
960 |
|
961 if ( is_serialized( $data ) ) |
|
962 return serialize( $data ); |
|
963 |
|
964 return $data; |
|
965 } |
|
966 |
|
967 /** |
|
968 * Strip HTML and put links at the bottom of stripped content. |
|
969 * |
|
970 * Searches for all of the links, strips them out of the content, and places |
|
971 * them at the bottom of the content with numbers. |
|
972 * |
|
973 * @since 0.71 |
|
974 * |
|
975 * @param string $content Content to get links |
|
976 * @return string HTML stripped out of content with links at the bottom. |
|
977 */ |
|
978 function make_url_footnote( $content ) { |
|
979 preg_match_all( '/<a(.+?)href=\"(.+?)\"(.*?)>(.+?)<\/a>/', $content, $matches ); |
|
980 $links_summary = "\n"; |
|
981 for ( $i=0; $i<count($matches[0]); $i++ ) { |
|
982 $link_match = $matches[0][$i]; |
|
983 $link_number = '['.($i+1).']'; |
|
984 $link_url = $matches[2][$i]; |
|
985 $link_text = $matches[4][$i]; |
|
986 $content = str_replace( $link_match, $link_text . ' ' . $link_number, $content ); |
|
987 $link_url = ( ( strtolower( substr( $link_url, 0, 7 ) ) != 'http://' ) && ( strtolower( substr( $link_url, 0, 8 ) ) != 'https://' ) ) ? get_option( 'home' ) . $link_url : $link_url; |
|
988 $links_summary .= "\n" . $link_number . ' ' . $link_url; |
|
989 } |
|
990 $content = strip_tags( $content ); |
|
991 $content .= $links_summary; |
|
992 return $content; |
|
993 } |
|
994 |
|
995 /** |
|
996 * Retrieve post title from XMLRPC XML. |
|
997 * |
|
998 * If the title element is not part of the XML, then the default post title from |
|
999 * the $post_default_title will be used instead. |
|
1000 * |
|
1001 * @package WordPress |
|
1002 * @subpackage XMLRPC |
|
1003 * @since 0.71 |
|
1004 * |
|
1005 * @global string $post_default_title Default XMLRPC post title. |
|
1006 * |
|
1007 * @param string $content XMLRPC XML Request content |
|
1008 * @return string Post title |
|
1009 */ |
|
1010 function xmlrpc_getposttitle( $content ) { |
|
1011 global $post_default_title; |
|
1012 if ( preg_match( '/<title>(.+?)<\/title>/is', $content, $matchtitle ) ) { |
|
1013 $post_title = $matchtitle[1]; |
|
1014 } else { |
|
1015 $post_title = $post_default_title; |
|
1016 } |
|
1017 return $post_title; |
|
1018 } |
|
1019 |
|
1020 /** |
|
1021 * Retrieve the post category or categories from XMLRPC XML. |
|
1022 * |
|
1023 * If the category element is not found, then the default post category will be |
|
1024 * used. The return type then would be what $post_default_category. If the |
|
1025 * category is found, then it will always be an array. |
|
1026 * |
|
1027 * @package WordPress |
|
1028 * @subpackage XMLRPC |
|
1029 * @since 0.71 |
|
1030 * |
|
1031 * @global string $post_default_category Default XMLRPC post category. |
|
1032 * |
|
1033 * @param string $content XMLRPC XML Request content |
|
1034 * @return string|array List of categories or category name. |
|
1035 */ |
|
1036 function xmlrpc_getpostcategory( $content ) { |
|
1037 global $post_default_category; |
|
1038 if ( preg_match( '/<category>(.+?)<\/category>/is', $content, $matchcat ) ) { |
|
1039 $post_category = trim( $matchcat[1], ',' ); |
|
1040 $post_category = explode( ',', $post_category ); |
|
1041 } else { |
|
1042 $post_category = $post_default_category; |
|
1043 } |
|
1044 return $post_category; |
|
1045 } |
|
1046 |
|
1047 /** |
|
1048 * XMLRPC XML content without title and category elements. |
|
1049 * |
|
1050 * @package WordPress |
|
1051 * @subpackage XMLRPC |
|
1052 * @since 0.71 |
|
1053 * |
|
1054 * @param string $content XMLRPC XML Request content |
|
1055 * @return string XMLRPC XML Request content without title and category elements. |
|
1056 */ |
|
1057 function xmlrpc_removepostdata( $content ) { |
|
1058 $content = preg_replace( '/<title>(.+?)<\/title>/si', '', $content ); |
|
1059 $content = preg_replace( '/<category>(.+?)<\/category>/si', '', $content ); |
|
1060 $content = trim( $content ); |
|
1061 return $content; |
|
1062 } |
|
1063 |
|
1064 /** |
|
1065 * Open the file handle for debugging. |
|
1066 * |
|
1067 * This function is used for XMLRPC feature, but it is general purpose enough |
|
1068 * to be used in anywhere. |
|
1069 * |
|
1070 * @see fopen() for mode options. |
|
1071 * @package WordPress |
|
1072 * @subpackage Debug |
|
1073 * @since 0.71 |
|
1074 * @uses $debug Used for whether debugging is enabled. |
|
1075 * |
|
1076 * @param string $filename File path to debug file. |
|
1077 * @param string $mode Same as fopen() mode parameter. |
|
1078 * @return bool|resource File handle. False on failure. |
|
1079 */ |
|
1080 function debug_fopen( $filename, $mode ) { |
|
1081 global $debug; |
|
1082 if ( 1 == $debug ) { |
|
1083 $fp = fopen( $filename, $mode ); |
|
1084 return $fp; |
|
1085 } else { |
|
1086 return false; |
|
1087 } |
|
1088 } |
|
1089 |
|
1090 /** |
|
1091 * Write contents to the file used for debugging. |
|
1092 * |
|
1093 * Technically, this can be used to write to any file handle when the global |
|
1094 * $debug is set to 1 or true. |
|
1095 * |
|
1096 * @package WordPress |
|
1097 * @subpackage Debug |
|
1098 * @since 0.71 |
|
1099 * @uses $debug Used for whether debugging is enabled. |
|
1100 * |
|
1101 * @param resource $fp File handle for debugging file. |
|
1102 * @param string $string Content to write to debug file. |
|
1103 */ |
|
1104 function debug_fwrite( $fp, $string ) { |
|
1105 global $debug; |
|
1106 if ( 1 == $debug ) |
|
1107 fwrite( $fp, $string ); |
|
1108 } |
|
1109 |
|
1110 /** |
|
1111 * Close the debugging file handle. |
|
1112 * |
|
1113 * Technically, this can be used to close any file handle when the global $debug |
|
1114 * is set to 1 or true. |
|
1115 * |
|
1116 * @package WordPress |
|
1117 * @subpackage Debug |
|
1118 * @since 0.71 |
|
1119 * @uses $debug Used for whether debugging is enabled. |
|
1120 * |
|
1121 * @param resource $fp Debug File handle. |
|
1122 */ |
|
1123 function debug_fclose( $fp ) { |
|
1124 global $debug; |
|
1125 if ( 1 == $debug ) |
|
1126 fclose( $fp ); |
|
1127 } |
|
1128 |
|
1129 /** |
|
1130 * Check content for video and audio links to add as enclosures. |
|
1131 * |
|
1132 * Will not add enclosures that have already been added and will |
|
1133 * remove enclosures that are no longer in the post. This is called as |
|
1134 * pingbacks and trackbacks. |
|
1135 * |
|
1136 * @package WordPress |
|
1137 * @since 1.5.0 |
|
1138 * |
|
1139 * @uses $wpdb |
|
1140 * |
|
1141 * @param string $content Post Content |
|
1142 * @param int $post_ID Post ID |
|
1143 */ |
|
1144 function do_enclose( $content, $post_ID ) { |
|
1145 global $wpdb; |
|
1146 include_once( ABSPATH . WPINC . '/class-IXR.php' ); |
|
1147 |
|
1148 $log = debug_fopen( ABSPATH . 'enclosures.log', 'a' ); |
|
1149 $post_links = array(); |
|
1150 debug_fwrite( $log, 'BEGIN ' . date( 'YmdHis', time() ) . "\n" ); |
|
1151 |
|
1152 $pung = get_enclosed( $post_ID ); |
|
1153 |
|
1154 $ltrs = '\w'; |
|
1155 $gunk = '/#~:.?+=&%@!\-'; |
|
1156 $punc = '.:?\-'; |
|
1157 $any = $ltrs . $gunk . $punc; |
|
1158 |
|
1159 preg_match_all( "{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp ); |
|
1160 |
|
1161 debug_fwrite( $log, 'Post contents:' ); |
|
1162 debug_fwrite( $log, $content . "\n" ); |
|
1163 |
|
1164 foreach ( $pung as $link_test ) { |
|
1165 if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post |
|
1166 $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, $link_test . '%') ); |
|
1167 } |
|
1168 } |
|
1169 |
|
1170 foreach ( (array) $post_links_temp[0] as $link_test ) { |
|
1171 if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already |
|
1172 $test = parse_url( $link_test ); |
|
1173 if ( isset( $test['query'] ) ) |
|
1174 $post_links[] = $link_test; |
|
1175 elseif ( $test['path'] != '/' && $test['path'] != '' ) |
|
1176 $post_links[] = $link_test; |
|
1177 } |
|
1178 } |
|
1179 |
|
1180 foreach ( (array) $post_links as $url ) { |
|
1181 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, $url . '%' ) ) ) { |
|
1182 if ( $headers = wp_get_http_headers( $url) ) { |
|
1183 $len = (int) $headers['content-length']; |
|
1184 $type = $headers['content-type']; |
|
1185 $allowed_types = array( 'video', 'audio' ); |
|
1186 if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) { |
|
1187 $meta_value = "$url\n$len\n$type\n"; |
|
1188 $wpdb->insert($wpdb->postmeta, array('post_id' => $post_ID, 'meta_key' => 'enclosure', 'meta_value' => $meta_value) ); |
|
1189 } |
|
1190 } |
|
1191 } |
|
1192 } |
|
1193 } |
|
1194 |
|
1195 /** |
|
1196 * Perform a HTTP HEAD or GET request. |
|
1197 * |
|
1198 * If $file_path is a writable filename, this will do a GET request and write |
|
1199 * the file to that path. |
|
1200 * |
|
1201 * @since 2.5.0 |
|
1202 * |
|
1203 * @param string $url URL to fetch. |
|
1204 * @param string|bool $file_path Optional. File path to write request to. |
|
1205 * @param bool $deprecated Deprecated. Not used. |
|
1206 * @return bool|string False on failure and string of headers if HEAD request. |
|
1207 */ |
|
1208 function wp_get_http( $url, $file_path = false, $deprecated = false ) { |
|
1209 @set_time_limit( 60 ); |
|
1210 |
|
1211 $options = array(); |
|
1212 $options['redirection'] = 5; |
|
1213 |
|
1214 if ( false == $file_path ) |
|
1215 $options['method'] = 'HEAD'; |
|
1216 else |
|
1217 $options['method'] = 'GET'; |
|
1218 |
|
1219 $response = wp_remote_request($url, $options); |
|
1220 |
|
1221 if ( is_wp_error( $response ) ) |
|
1222 return false; |
|
1223 |
|
1224 $headers = wp_remote_retrieve_headers( $response ); |
|
1225 $headers['response'] = $response['response']['code']; |
|
1226 |
|
1227 if ( false == $file_path ) |
|
1228 return $headers; |
|
1229 |
|
1230 // GET request - write it to the supplied filename |
|
1231 $out_fp = fopen($file_path, 'w'); |
|
1232 if ( !$out_fp ) |
|
1233 return $headers; |
|
1234 |
|
1235 fwrite( $out_fp, $response['body']); |
|
1236 fclose($out_fp); |
|
1237 |
|
1238 return $headers; |
|
1239 } |
|
1240 |
|
1241 /** |
|
1242 * Retrieve HTTP Headers from URL. |
|
1243 * |
|
1244 * @since 1.5.1 |
|
1245 * |
|
1246 * @param string $url |
|
1247 * @param bool $deprecated Not Used. |
|
1248 * @return bool|string False on failure, headers on success. |
|
1249 */ |
|
1250 function wp_get_http_headers( $url, $deprecated = false ) { |
|
1251 $response = wp_remote_head( $url ); |
|
1252 |
|
1253 if ( is_wp_error( $response ) ) |
|
1254 return false; |
|
1255 |
|
1256 return wp_remote_retrieve_headers( $response ); |
|
1257 } |
|
1258 |
|
1259 /** |
|
1260 * Whether today is a new day. |
|
1261 * |
|
1262 * @since 0.71 |
|
1263 * @uses $day Today |
|
1264 * @uses $previousday Previous day |
|
1265 * |
|
1266 * @return int 1 when new day, 0 if not a new day. |
|
1267 */ |
|
1268 function is_new_day() { |
|
1269 global $day, $previousday; |
|
1270 if ( $day != $previousday ) |
|
1271 return 1; |
|
1272 else |
|
1273 return 0; |
|
1274 } |
|
1275 |
|
1276 /** |
|
1277 * Build URL query based on an associative and, or indexed array. |
|
1278 * |
|
1279 * This is a convenient function for easily building url queries. It sets the |
|
1280 * separator to '&' and uses _http_build_query() function. |
|
1281 * |
|
1282 * @see _http_build_query() Used to build the query |
|
1283 * @link http://us2.php.net/manual/en/function.http-build-query.php more on what |
|
1284 * http_build_query() does. |
|
1285 * |
|
1286 * @since 2.3.0 |
|
1287 * |
|
1288 * @param array $data URL-encode key/value pairs. |
|
1289 * @return string URL encoded string |
|
1290 */ |
|
1291 function build_query( $data ) { |
|
1292 return _http_build_query( $data, null, '&', '', false ); |
|
1293 } |
|
1294 |
|
1295 /** |
|
1296 * Retrieve a modified URL query string. |
|
1297 * |
|
1298 * You can rebuild the URL and append a new query variable to the URL query by |
|
1299 * using this function. You can also retrieve the full URL with query data. |
|
1300 * |
|
1301 * Adding a single key & value or an associative array. Setting a key value to |
|
1302 * emptystring removes the key. Omitting oldquery_or_uri uses the $_SERVER |
|
1303 * value. |
|
1304 * |
|
1305 * @since 1.5.0 |
|
1306 * |
|
1307 * @param mixed $param1 Either newkey or an associative_array |
|
1308 * @param mixed $param2 Either newvalue or oldquery or uri |
|
1309 * @param mixed $param3 Optional. Old query or uri |
|
1310 * @return string New URL query string. |
|
1311 */ |
|
1312 function add_query_arg() { |
|
1313 $ret = ''; |
|
1314 if ( is_array( func_get_arg(0) ) ) { |
|
1315 if ( @func_num_args() < 2 || false === @func_get_arg( 1 ) ) |
|
1316 $uri = $_SERVER['REQUEST_URI']; |
|
1317 else |
|
1318 $uri = @func_get_arg( 1 ); |
|
1319 } else { |
|
1320 if ( @func_num_args() < 3 || false === @func_get_arg( 2 ) ) |
|
1321 $uri = $_SERVER['REQUEST_URI']; |
|
1322 else |
|
1323 $uri = @func_get_arg( 2 ); |
|
1324 } |
|
1325 |
|
1326 if ( $frag = strstr( $uri, '#' ) ) |
|
1327 $uri = substr( $uri, 0, -strlen( $frag ) ); |
|
1328 else |
|
1329 $frag = ''; |
|
1330 |
|
1331 if ( preg_match( '|^https?://|i', $uri, $matches ) ) { |
|
1332 $protocol = $matches[0]; |
|
1333 $uri = substr( $uri, strlen( $protocol ) ); |
|
1334 } else { |
|
1335 $protocol = ''; |
|
1336 } |
|
1337 |
|
1338 if ( strpos( $uri, '?' ) !== false ) { |
|
1339 $parts = explode( '?', $uri, 2 ); |
|
1340 if ( 1 == count( $parts ) ) { |
|
1341 $base = '?'; |
|
1342 $query = $parts[0]; |
|
1343 } else { |
|
1344 $base = $parts[0] . '?'; |
|
1345 $query = $parts[1]; |
|
1346 } |
|
1347 } elseif ( !empty( $protocol ) || strpos( $uri, '=' ) === false ) { |
|
1348 $base = $uri . '?'; |
|
1349 $query = ''; |
|
1350 } else { |
|
1351 $base = ''; |
|
1352 $query = $uri; |
|
1353 } |
|
1354 |
|
1355 wp_parse_str( $query, $qs ); |
|
1356 $qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string |
|
1357 if ( is_array( func_get_arg( 0 ) ) ) { |
|
1358 $kayvees = func_get_arg( 0 ); |
|
1359 $qs = array_merge( $qs, $kayvees ); |
|
1360 } else { |
|
1361 $qs[func_get_arg( 0 )] = func_get_arg( 1 ); |
|
1362 } |
|
1363 |
|
1364 foreach ( (array) $qs as $k => $v ) { |
|
1365 if ( $v === false ) |
|
1366 unset( $qs[$k] ); |
|
1367 } |
|
1368 |
|
1369 $ret = build_query( $qs ); |
|
1370 $ret = trim( $ret, '?' ); |
|
1371 $ret = preg_replace( '#=(&|$)#', '$1', $ret ); |
|
1372 $ret = $protocol . $base . $ret . $frag; |
|
1373 $ret = rtrim( $ret, '?' ); |
|
1374 return $ret; |
|
1375 } |
|
1376 |
|
1377 /** |
|
1378 * Removes an item or list from the query string. |
|
1379 * |
|
1380 * @since 1.5.0 |
|
1381 * |
|
1382 * @param string|array $key Query key or keys to remove. |
|
1383 * @param bool $query When false uses the $_SERVER value. |
|
1384 * @return string New URL query string. |
|
1385 */ |
|
1386 function remove_query_arg( $key, $query=false ) { |
|
1387 if ( is_array( $key ) ) { // removing multiple keys |
|
1388 foreach ( $key as $k ) |
|
1389 $query = add_query_arg( $k, false, $query ); |
|
1390 return $query; |
|
1391 } |
|
1392 return add_query_arg( $key, false, $query ); |
|
1393 } |
|
1394 |
|
1395 /** |
|
1396 * Walks the array while sanitizing the contents. |
|
1397 * |
|
1398 * @uses $wpdb Used to sanitize values |
|
1399 * @since 0.71 |
|
1400 * |
|
1401 * @param array $array Array to used to walk while sanitizing contents. |
|
1402 * @return array Sanitized $array. |
|
1403 */ |
|
1404 function add_magic_quotes( $array ) { |
|
1405 global $wpdb; |
|
1406 |
|
1407 foreach ( (array) $array as $k => $v ) { |
|
1408 if ( is_array( $v ) ) { |
|
1409 $array[$k] = add_magic_quotes( $v ); |
|
1410 } else { |
|
1411 $array[$k] = $wpdb->escape( $v ); |
|
1412 } |
|
1413 } |
|
1414 return $array; |
|
1415 } |
|
1416 |
|
1417 /** |
|
1418 * HTTP request for URI to retrieve content. |
|
1419 * |
|
1420 * @since 1.5.1 |
|
1421 * @uses wp_remote_get() |
|
1422 * |
|
1423 * @param string $uri URI/URL of web page to retrieve. |
|
1424 * @return bool|string HTTP content. False on failure. |
|
1425 */ |
|
1426 function wp_remote_fopen( $uri ) { |
|
1427 $parsed_url = @parse_url( $uri ); |
|
1428 |
|
1429 if ( !$parsed_url || !is_array( $parsed_url ) ) |
|
1430 return false; |
|
1431 |
|
1432 $options = array(); |
|
1433 $options['timeout'] = 10; |
|
1434 |
|
1435 $response = wp_remote_get( $uri, $options ); |
|
1436 |
|
1437 if ( is_wp_error( $response ) ) |
|
1438 return false; |
|
1439 |
|
1440 return $response['body']; |
|
1441 } |
|
1442 |
|
1443 /** |
|
1444 * Setup the WordPress query. |
|
1445 * |
|
1446 * @since 2.0.0 |
|
1447 * |
|
1448 * @param string $query_vars Default WP_Query arguments. |
|
1449 */ |
|
1450 function wp( $query_vars = '' ) { |
|
1451 global $wp, $wp_query, $wp_the_query; |
|
1452 $wp->main( $query_vars ); |
|
1453 |
|
1454 if( !isset($wp_the_query) ) |
|
1455 $wp_the_query = $wp_query; |
|
1456 } |
|
1457 |
|
1458 /** |
|
1459 * Retrieve the description for the HTTP status. |
|
1460 * |
|
1461 * @since 2.3.0 |
|
1462 * |
|
1463 * @param int $code HTTP status code. |
|
1464 * @return string Empty string if not found, or description if found. |
|
1465 */ |
|
1466 function get_status_header_desc( $code ) { |
|
1467 global $wp_header_to_desc; |
|
1468 |
|
1469 $code = absint( $code ); |
|
1470 |
|
1471 if ( !isset( $wp_header_to_desc ) ) { |
|
1472 $wp_header_to_desc = array( |
|
1473 100 => 'Continue', |
|
1474 101 => 'Switching Protocols', |
|
1475 102 => 'Processing', |
|
1476 |
|
1477 200 => 'OK', |
|
1478 201 => 'Created', |
|
1479 202 => 'Accepted', |
|
1480 203 => 'Non-Authoritative Information', |
|
1481 204 => 'No Content', |
|
1482 205 => 'Reset Content', |
|
1483 206 => 'Partial Content', |
|
1484 207 => 'Multi-Status', |
|
1485 226 => 'IM Used', |
|
1486 |
|
1487 300 => 'Multiple Choices', |
|
1488 301 => 'Moved Permanently', |
|
1489 302 => 'Found', |
|
1490 303 => 'See Other', |
|
1491 304 => 'Not Modified', |
|
1492 305 => 'Use Proxy', |
|
1493 306 => 'Reserved', |
|
1494 307 => 'Temporary Redirect', |
|
1495 |
|
1496 400 => 'Bad Request', |
|
1497 401 => 'Unauthorized', |
|
1498 402 => 'Payment Required', |
|
1499 403 => 'Forbidden', |
|
1500 404 => 'Not Found', |
|
1501 405 => 'Method Not Allowed', |
|
1502 406 => 'Not Acceptable', |
|
1503 407 => 'Proxy Authentication Required', |
|
1504 408 => 'Request Timeout', |
|
1505 409 => 'Conflict', |
|
1506 410 => 'Gone', |
|
1507 411 => 'Length Required', |
|
1508 412 => 'Precondition Failed', |
|
1509 413 => 'Request Entity Too Large', |
|
1510 414 => 'Request-URI Too Long', |
|
1511 415 => 'Unsupported Media Type', |
|
1512 416 => 'Requested Range Not Satisfiable', |
|
1513 417 => 'Expectation Failed', |
|
1514 422 => 'Unprocessable Entity', |
|
1515 423 => 'Locked', |
|
1516 424 => 'Failed Dependency', |
|
1517 426 => 'Upgrade Required', |
|
1518 |
|
1519 500 => 'Internal Server Error', |
|
1520 501 => 'Not Implemented', |
|
1521 502 => 'Bad Gateway', |
|
1522 503 => 'Service Unavailable', |
|
1523 504 => 'Gateway Timeout', |
|
1524 505 => 'HTTP Version Not Supported', |
|
1525 506 => 'Variant Also Negotiates', |
|
1526 507 => 'Insufficient Storage', |
|
1527 510 => 'Not Extended' |
|
1528 ); |
|
1529 } |
|
1530 |
|
1531 if ( isset( $wp_header_to_desc[$code] ) ) |
|
1532 return $wp_header_to_desc[$code]; |
|
1533 else |
|
1534 return ''; |
|
1535 } |
|
1536 |
|
1537 /** |
|
1538 * Set HTTP status header. |
|
1539 * |
|
1540 * @since 2.0.0 |
|
1541 * @uses apply_filters() Calls 'status_header' on status header string, HTTP |
|
1542 * HTTP code, HTTP code description, and protocol string as separate |
|
1543 * parameters. |
|
1544 * |
|
1545 * @param int $header HTTP status code |
|
1546 * @return null Does not return anything. |
|
1547 */ |
|
1548 function status_header( $header ) { |
|
1549 $text = get_status_header_desc( $header ); |
|
1550 |
|
1551 if ( empty( $text ) ) |
|
1552 return false; |
|
1553 |
|
1554 $protocol = $_SERVER["SERVER_PROTOCOL"]; |
|
1555 if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol ) |
|
1556 $protocol = 'HTTP/1.0'; |
|
1557 $status_header = "$protocol $header $text"; |
|
1558 if ( function_exists( 'apply_filters' ) ) |
|
1559 $status_header = apply_filters( 'status_header', $status_header, $header, $text, $protocol ); |
|
1560 |
|
1561 return @header( $status_header, true, $header ); |
|
1562 } |
|
1563 |
|
1564 /** |
|
1565 * Gets the header information to prevent caching. |
|
1566 * |
|
1567 * The several different headers cover the different ways cache prevention is handled |
|
1568 * by different browsers |
|
1569 * |
|
1570 * @since 2.8 |
|
1571 * |
|
1572 * @uses apply_filters() |
|
1573 * @return array The associative array of header names and field values. |
|
1574 */ |
|
1575 function wp_get_nocache_headers() { |
|
1576 $headers = array( |
|
1577 'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT', |
|
1578 'Last-Modified' => gmdate( 'D, d M Y H:i:s' ) . ' GMT', |
|
1579 'Cache-Control' => 'no-cache, must-revalidate, max-age=0', |
|
1580 'Pragma' => 'no-cache', |
|
1581 ); |
|
1582 |
|
1583 if ( function_exists('apply_filters') ) { |
|
1584 $headers = apply_filters('nocache_headers', $headers); |
|
1585 } |
|
1586 return $headers; |
|
1587 } |
|
1588 |
|
1589 /** |
|
1590 * Sets the headers to prevent caching for the different browsers. |
|
1591 * |
|
1592 * Different browsers support different nocache headers, so several headers must |
|
1593 * be sent so that all of them get the point that no caching should occur. |
|
1594 * |
|
1595 * @since 2.0.0 |
|
1596 * @uses wp_get_nocache_headers() |
|
1597 */ |
|
1598 function nocache_headers() { |
|
1599 $headers = wp_get_nocache_headers(); |
|
1600 foreach( (array) $headers as $name => $field_value ) |
|
1601 @header("{$name}: {$field_value}"); |
|
1602 } |
|
1603 |
|
1604 /** |
|
1605 * Set the headers for caching for 10 days with JavaScript content type. |
|
1606 * |
|
1607 * @since 2.1.0 |
|
1608 */ |
|
1609 function cache_javascript_headers() { |
|
1610 $expiresOffset = 864000; // 10 days |
|
1611 header( "Content-Type: text/javascript; charset=" . get_bloginfo( 'charset' ) ); |
|
1612 header( "Vary: Accept-Encoding" ); // Handle proxies |
|
1613 header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . " GMT" ); |
|
1614 } |
|
1615 |
|
1616 /** |
|
1617 * Retrieve the number of database queries during the WordPress execution. |
|
1618 * |
|
1619 * @since 2.0.0 |
|
1620 * |
|
1621 * @return int Number of database queries |
|
1622 */ |
|
1623 function get_num_queries() { |
|
1624 global $wpdb; |
|
1625 return $wpdb->num_queries; |
|
1626 } |
|
1627 |
|
1628 /** |
|
1629 * Whether input is yes or no. Must be 'y' to be true. |
|
1630 * |
|
1631 * @since 1.0.0 |
|
1632 * |
|
1633 * @param string $yn Character string containing either 'y' or 'n' |
|
1634 * @return bool True if yes, false on anything else |
|
1635 */ |
|
1636 function bool_from_yn( $yn ) { |
|
1637 return ( strtolower( $yn ) == 'y' ); |
|
1638 } |
|
1639 |
|
1640 /** |
|
1641 * Loads the feed template from the use of an action hook. |
|
1642 * |
|
1643 * If the feed action does not have a hook, then the function will die with a |
|
1644 * message telling the visitor that the feed is not valid. |
|
1645 * |
|
1646 * It is better to only have one hook for each feed. |
|
1647 * |
|
1648 * @since 2.1.0 |
|
1649 * @uses $wp_query Used to tell if the use a comment feed. |
|
1650 * @uses do_action() Calls 'do_feed_$feed' hook, if a hook exists for the feed. |
|
1651 */ |
|
1652 function do_feed() { |
|
1653 global $wp_query; |
|
1654 |
|
1655 $feed = get_query_var( 'feed' ); |
|
1656 |
|
1657 // Remove the pad, if present. |
|
1658 $feed = preg_replace( '/^_+/', '', $feed ); |
|
1659 |
|
1660 if ( $feed == '' || $feed == 'feed' ) |
|
1661 $feed = get_default_feed(); |
|
1662 |
|
1663 $hook = 'do_feed_' . $feed; |
|
1664 if ( !has_action($hook) ) { |
|
1665 $message = sprintf( __( 'ERROR: %s is not a valid feed template' ), esc_html($feed)); |
|
1666 wp_die($message); |
|
1667 } |
|
1668 |
|
1669 do_action( $hook, $wp_query->is_comment_feed ); |
|
1670 } |
|
1671 |
|
1672 /** |
|
1673 * Load the RDF RSS 0.91 Feed template. |
|
1674 * |
|
1675 * @since 2.1.0 |
|
1676 */ |
|
1677 function do_feed_rdf() { |
|
1678 load_template( ABSPATH . WPINC . '/feed-rdf.php' ); |
|
1679 } |
|
1680 |
|
1681 /** |
|
1682 * Load the RSS 1.0 Feed Template |
|
1683 * |
|
1684 * @since 2.1.0 |
|
1685 */ |
|
1686 function do_feed_rss() { |
|
1687 load_template( ABSPATH . WPINC . '/feed-rss.php' ); |
|
1688 } |
|
1689 |
|
1690 /** |
|
1691 * Load either the RSS2 comment feed or the RSS2 posts feed. |
|
1692 * |
|
1693 * @since 2.1.0 |
|
1694 * |
|
1695 * @param bool $for_comments True for the comment feed, false for normal feed. |
|
1696 */ |
|
1697 function do_feed_rss2( $for_comments ) { |
|
1698 if ( $for_comments ) |
|
1699 load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' ); |
|
1700 else |
|
1701 load_template( ABSPATH . WPINC . '/feed-rss2.php' ); |
|
1702 } |
|
1703 |
|
1704 /** |
|
1705 * Load either Atom comment feed or Atom posts feed. |
|
1706 * |
|
1707 * @since 2.1.0 |
|
1708 * |
|
1709 * @param bool $for_comments True for the comment feed, false for normal feed. |
|
1710 */ |
|
1711 function do_feed_atom( $for_comments ) { |
|
1712 if ($for_comments) |
|
1713 load_template( ABSPATH . WPINC . '/feed-atom-comments.php'); |
|
1714 else |
|
1715 load_template( ABSPATH . WPINC . '/feed-atom.php' ); |
|
1716 } |
|
1717 |
|
1718 /** |
|
1719 * Display the robot.txt file content. |
|
1720 * |
|
1721 * The echo content should be with usage of the permalinks or for creating the |
|
1722 * robot.txt file. |
|
1723 * |
|
1724 * @since 2.1.0 |
|
1725 * @uses do_action() Calls 'do_robotstxt' hook for displaying robot.txt rules. |
|
1726 */ |
|
1727 function do_robots() { |
|
1728 header( 'Content-Type: text/plain; charset=utf-8' ); |
|
1729 |
|
1730 do_action( 'do_robotstxt' ); |
|
1731 |
|
1732 if ( '0' == get_option( 'blog_public' ) ) { |
|
1733 echo "User-agent: *\n"; |
|
1734 echo "Disallow: /\n"; |
|
1735 } else { |
|
1736 echo "User-agent: *\n"; |
|
1737 echo "Disallow:\n"; |
|
1738 } |
|
1739 } |
|
1740 |
|
1741 /** |
|
1742 * Test whether blog is already installed. |
|
1743 * |
|
1744 * The cache will be checked first. If you have a cache plugin, which saves the |
|
1745 * cache values, then this will work. If you use the default WordPress cache, |
|
1746 * and the database goes away, then you might have problems. |
|
1747 * |
|
1748 * Checks for the option siteurl for whether WordPress is installed. |
|
1749 * |
|
1750 * @since 2.1.0 |
|
1751 * @uses $wpdb |
|
1752 * |
|
1753 * @return bool Whether blog is already installed. |
|
1754 */ |
|
1755 function is_blog_installed() { |
|
1756 global $wpdb; |
|
1757 |
|
1758 // Check cache first. If options table goes away and we have true cached, oh well. |
|
1759 if ( wp_cache_get( 'is_blog_installed' ) ) |
|
1760 return true; |
|
1761 |
|
1762 $suppress = $wpdb->suppress_errors(); |
|
1763 $alloptions = wp_load_alloptions(); |
|
1764 // If siteurl is not set to autoload, check it specifically |
|
1765 if ( !isset( $alloptions['siteurl'] ) ) |
|
1766 $installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" ); |
|
1767 else |
|
1768 $installed = $alloptions['siteurl']; |
|
1769 $wpdb->suppress_errors( $suppress ); |
|
1770 |
|
1771 $installed = !empty( $installed ); |
|
1772 wp_cache_set( 'is_blog_installed', $installed ); |
|
1773 |
|
1774 return $installed; |
|
1775 } |
|
1776 |
|
1777 /** |
|
1778 * Retrieve URL with nonce added to URL query. |
|
1779 * |
|
1780 * @package WordPress |
|
1781 * @subpackage Security |
|
1782 * @since 2.0.4 |
|
1783 * |
|
1784 * @param string $actionurl URL to add nonce action |
|
1785 * @param string $action Optional. Nonce action name |
|
1786 * @return string URL with nonce action added. |
|
1787 */ |
|
1788 function wp_nonce_url( $actionurl, $action = -1 ) { |
|
1789 $actionurl = str_replace( '&', '&', $actionurl ); |
|
1790 return esc_html( add_query_arg( '_wpnonce', wp_create_nonce( $action ), $actionurl ) ); |
|
1791 } |
|
1792 |
|
1793 /** |
|
1794 * Retrieve or display nonce hidden field for forms. |
|
1795 * |
|
1796 * The nonce field is used to validate that the contents of the form came from |
|
1797 * the location on the current site and not somewhere else. The nonce does not |
|
1798 * offer absolute protection, but should protect against most cases. It is very |
|
1799 * important to use nonce field in forms. |
|
1800 * |
|
1801 * If you set $echo to true and set $referer to true, then you will need to |
|
1802 * retrieve the {@link wp_referer_field() wp referer field}. If you have the |
|
1803 * $referer set to true and are echoing the nonce field, it will also echo the |
|
1804 * referer field. |
|
1805 * |
|
1806 * The $action and $name are optional, but if you want to have better security, |
|
1807 * it is strongly suggested to set those two parameters. It is easier to just |
|
1808 * call the function without any parameters, because validation of the nonce |
|
1809 * doesn't require any parameters, but since crackers know what the default is |
|
1810 * it won't be difficult for them to find a way around your nonce and cause |
|
1811 * damage. |
|
1812 * |
|
1813 * The input name will be whatever $name value you gave. The input value will be |
|
1814 * the nonce creation value. |
|
1815 * |
|
1816 * @package WordPress |
|
1817 * @subpackage Security |
|
1818 * @since 2.0.4 |
|
1819 * |
|
1820 * @param string $action Optional. Action name. |
|
1821 * @param string $name Optional. Nonce name. |
|
1822 * @param bool $referer Optional, default true. Whether to set the referer field for validation. |
|
1823 * @param bool $echo Optional, default true. Whether to display or return hidden form field. |
|
1824 * @return string Nonce field. |
|
1825 */ |
|
1826 function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true , $echo = true ) { |
|
1827 $name = esc_attr( $name ); |
|
1828 $nonce_field = '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />'; |
|
1829 if ( $echo ) |
|
1830 echo $nonce_field; |
|
1831 |
|
1832 if ( $referer ) |
|
1833 wp_referer_field( $echo, 'previous' ); |
|
1834 |
|
1835 return $nonce_field; |
|
1836 } |
|
1837 |
|
1838 /** |
|
1839 * Retrieve or display referer hidden field for forms. |
|
1840 * |
|
1841 * The referer link is the current Request URI from the server super global. The |
|
1842 * input name is '_wp_http_referer', in case you wanted to check manually. |
|
1843 * |
|
1844 * @package WordPress |
|
1845 * @subpackage Security |
|
1846 * @since 2.0.4 |
|
1847 * |
|
1848 * @param bool $echo Whether to echo or return the referer field. |
|
1849 * @return string Referer field. |
|
1850 */ |
|
1851 function wp_referer_field( $echo = true) { |
|
1852 $ref = esc_attr( $_SERVER['REQUEST_URI'] ); |
|
1853 $referer_field = '<input type="hidden" name="_wp_http_referer" value="'. $ref . '" />'; |
|
1854 |
|
1855 if ( $echo ) |
|
1856 echo $referer_field; |
|
1857 return $referer_field; |
|
1858 } |
|
1859 |
|
1860 /** |
|
1861 * Retrieve or display original referer hidden field for forms. |
|
1862 * |
|
1863 * The input name is '_wp_original_http_referer' and will be either the same |
|
1864 * value of {@link wp_referer_field()}, if that was posted already or it will |
|
1865 * be the current page, if it doesn't exist. |
|
1866 * |
|
1867 * @package WordPress |
|
1868 * @subpackage Security |
|
1869 * @since 2.0.4 |
|
1870 * |
|
1871 * @param bool $echo Whether to echo the original http referer |
|
1872 * @param string $jump_back_to Optional, default is 'current'. Can be 'previous' or page you want to jump back to. |
|
1873 * @return string Original referer field. |
|
1874 */ |
|
1875 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) { |
|
1876 $jump_back_to = ( 'previous' == $jump_back_to ) ? wp_get_referer() : $_SERVER['REQUEST_URI']; |
|
1877 $ref = ( wp_get_original_referer() ) ? wp_get_original_referer() : $jump_back_to; |
|
1878 $orig_referer_field = '<input type="hidden" name="_wp_original_http_referer" value="' . esc_attr( stripslashes( $ref ) ) . '" />'; |
|
1879 if ( $echo ) |
|
1880 echo $orig_referer_field; |
|
1881 return $orig_referer_field; |
|
1882 } |
|
1883 |
|
1884 /** |
|
1885 * Retrieve referer from '_wp_http_referer', HTTP referer, or current page respectively. |
|
1886 * |
|
1887 * @package WordPress |
|
1888 * @subpackage Security |
|
1889 * @since 2.0.4 |
|
1890 * |
|
1891 * @return string|bool False on failure. Referer URL on success. |
|
1892 */ |
|
1893 function wp_get_referer() { |
|
1894 $ref = ''; |
|
1895 if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) |
|
1896 $ref = $_REQUEST['_wp_http_referer']; |
|
1897 else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) |
|
1898 $ref = $_SERVER['HTTP_REFERER']; |
|
1899 |
|
1900 if ( $ref !== $_SERVER['REQUEST_URI'] ) |
|
1901 return $ref; |
|
1902 return false; |
|
1903 } |
|
1904 |
|
1905 /** |
|
1906 * Retrieve original referer that was posted, if it exists. |
|
1907 * |
|
1908 * @package WordPress |
|
1909 * @subpackage Security |
|
1910 * @since 2.0.4 |
|
1911 * |
|
1912 * @return string|bool False if no original referer or original referer if set. |
|
1913 */ |
|
1914 function wp_get_original_referer() { |
|
1915 if ( !empty( $_REQUEST['_wp_original_http_referer'] ) ) |
|
1916 return $_REQUEST['_wp_original_http_referer']; |
|
1917 return false; |
|
1918 } |
|
1919 |
|
1920 /** |
|
1921 * Recursive directory creation based on full path. |
|
1922 * |
|
1923 * Will attempt to set permissions on folders. |
|
1924 * |
|
1925 * @since 2.0.1 |
|
1926 * |
|
1927 * @param string $target Full path to attempt to create. |
|
1928 * @return bool Whether the path was created or not. True if path already exists. |
|
1929 */ |
|
1930 function wp_mkdir_p( $target ) { |
|
1931 // from php.net/mkdir user contributed notes |
|
1932 $target = str_replace( '//', '/', $target ); |
|
1933 if ( file_exists( $target ) ) |
|
1934 return @is_dir( $target ); |
|
1935 |
|
1936 // Attempting to create the directory may clutter up our display. |
|
1937 if ( @mkdir( $target ) ) { |
|
1938 $stat = @stat( dirname( $target ) ); |
|
1939 $dir_perms = $stat['mode'] & 0007777; // Get the permission bits. |
|
1940 @chmod( $target, $dir_perms ); |
|
1941 return true; |
|
1942 } elseif ( is_dir( dirname( $target ) ) ) { |
|
1943 return false; |
|
1944 } |
|
1945 |
|
1946 // If the above failed, attempt to create the parent node, then try again. |
|
1947 if ( ( $target != '/' ) && ( wp_mkdir_p( dirname( $target ) ) ) ) |
|
1948 return wp_mkdir_p( $target ); |
|
1949 |
|
1950 return false; |
|
1951 } |
|
1952 |
|
1953 /** |
|
1954 * Test if a give filesystem path is absolute ('/foo/bar', 'c:\windows'). |
|
1955 * |
|
1956 * @since 2.5.0 |
|
1957 * |
|
1958 * @param string $path File path |
|
1959 * @return bool True if path is absolute, false is not absolute. |
|
1960 */ |
|
1961 function path_is_absolute( $path ) { |
|
1962 // this is definitive if true but fails if $path does not exist or contains a symbolic link |
|
1963 if ( realpath($path) == $path ) |
|
1964 return true; |
|
1965 |
|
1966 if ( strlen($path) == 0 || $path{0} == '.' ) |
|
1967 return false; |
|
1968 |
|
1969 // windows allows absolute paths like this |
|
1970 if ( preg_match('#^[a-zA-Z]:\\\\#', $path) ) |
|
1971 return true; |
|
1972 |
|
1973 // a path starting with / or \ is absolute; anything else is relative |
|
1974 return (bool) preg_match('#^[/\\\\]#', $path); |
|
1975 } |
|
1976 |
|
1977 /** |
|
1978 * Join two filesystem paths together (e.g. 'give me $path relative to $base'). |
|
1979 * |
|
1980 * If the $path is absolute, then it the full path is returned. |
|
1981 * |
|
1982 * @since 2.5.0 |
|
1983 * |
|
1984 * @param string $base |
|
1985 * @param string $path |
|
1986 * @return string The path with the base or absolute path. |
|
1987 */ |
|
1988 function path_join( $base, $path ) { |
|
1989 if ( path_is_absolute($path) ) |
|
1990 return $path; |
|
1991 |
|
1992 return rtrim($base, '/') . '/' . ltrim($path, '/'); |
|
1993 } |
|
1994 |
|
1995 /** |
|
1996 * Get an array containing the current upload directory's path and url. |
|
1997 * |
|
1998 * Checks the 'upload_path' option, which should be from the web root folder, |
|
1999 * and if it isn't empty it will be used. If it is empty, then the path will be |
|
2000 * 'WP_CONTENT_DIR/uploads'. If the 'UPLOADS' constant is defined, then it will |
|
2001 * override the 'upload_path' option and 'WP_CONTENT_DIR/uploads' path. |
|
2002 * |
|
2003 * The upload URL path is set either by the 'upload_url_path' option or by using |
|
2004 * the 'WP_CONTENT_URL' constant and appending '/uploads' to the path. |
|
2005 * |
|
2006 * If the 'uploads_use_yearmonth_folders' is set to true (checkbox if checked in |
|
2007 * the administration settings panel), then the time will be used. The format |
|
2008 * will be year first and then month. |
|
2009 * |
|
2010 * If the path couldn't be created, then an error will be returned with the key |
|
2011 * 'error' containing the error message. The error suggests that the parent |
|
2012 * directory is not writable by the server. |
|
2013 * |
|
2014 * On success, the returned array will have many indices: |
|
2015 * 'path' - base directory and sub directory or full path to upload directory. |
|
2016 * 'url' - base url and sub directory or absolute URL to upload directory. |
|
2017 * 'subdir' - sub directory if uploads use year/month folders option is on. |
|
2018 * 'basedir' - path without subdir. |
|
2019 * 'baseurl' - URL path without subdir. |
|
2020 * 'error' - set to false. |
|
2021 * |
|
2022 * @since 2.0.0 |
|
2023 * @uses apply_filters() Calls 'upload_dir' on returned array. |
|
2024 * |
|
2025 * @param string $time Optional. Time formatted in 'yyyy/mm'. |
|
2026 * @return array See above for description. |
|
2027 */ |
|
2028 function wp_upload_dir( $time = null ) { |
|
2029 $siteurl = get_option( 'siteurl' ); |
|
2030 $upload_path = get_option( 'upload_path' ); |
|
2031 $upload_path = trim($upload_path); |
|
2032 if ( empty($upload_path) ) |
|
2033 $dir = WP_CONTENT_DIR . '/uploads'; |
|
2034 else |
|
2035 $dir = $upload_path; |
|
2036 |
|
2037 // $dir is absolute, $path is (maybe) relative to ABSPATH |
|
2038 $dir = path_join( ABSPATH, $dir ); |
|
2039 |
|
2040 if ( !$url = get_option( 'upload_url_path' ) ) { |
|
2041 if ( empty($upload_path) or ( $upload_path == $dir ) ) |
|
2042 $url = WP_CONTENT_URL . '/uploads'; |
|
2043 else |
|
2044 $url = trailingslashit( $siteurl ) . $upload_path; |
|
2045 } |
|
2046 |
|
2047 if ( defined('UPLOADS') ) { |
|
2048 $dir = ABSPATH . UPLOADS; |
|
2049 $url = trailingslashit( $siteurl ) . UPLOADS; |
|
2050 } |
|
2051 |
|
2052 $bdir = $dir; |
|
2053 $burl = $url; |
|
2054 |
|
2055 $subdir = ''; |
|
2056 if ( get_option( 'uploads_use_yearmonth_folders' ) ) { |
|
2057 // Generate the yearly and monthly dirs |
|
2058 if ( !$time ) |
|
2059 $time = current_time( 'mysql' ); |
|
2060 $y = substr( $time, 0, 4 ); |
|
2061 $m = substr( $time, 5, 2 ); |
|
2062 $subdir = "/$y/$m"; |
|
2063 } |
|
2064 |
|
2065 $dir .= $subdir; |
|
2066 $url .= $subdir; |
|
2067 |
|
2068 $uploads = apply_filters( 'upload_dir', array( 'path' => $dir, 'url' => $url, 'subdir' => $subdir, 'basedir' => $bdir, 'baseurl' => $burl, 'error' => false ) ); |
|
2069 |
|
2070 // Make sure we have an uploads dir |
|
2071 if ( ! wp_mkdir_p( $uploads['path'] ) ) { |
|
2072 $message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $uploads['path'] ); |
|
2073 return array( 'error' => $message ); |
|
2074 } |
|
2075 |
|
2076 return $uploads; |
|
2077 } |
|
2078 |
|
2079 /** |
|
2080 * Get a filename that is sanitized and unique for the given directory. |
|
2081 * |
|
2082 * If the filename is not unique, then a number will be added to the filename |
|
2083 * before the extension, and will continue adding numbers until the filename is |
|
2084 * unique. |
|
2085 * |
|
2086 * The callback must accept two parameters, the first one is the directory and |
|
2087 * the second is the filename. The callback must be a function. |
|
2088 * |
|
2089 * @since 2.5 |
|
2090 * |
|
2091 * @param string $dir |
|
2092 * @param string $filename |
|
2093 * @param string $unique_filename_callback Function name, must be a function. |
|
2094 * @return string New filename, if given wasn't unique. |
|
2095 */ |
|
2096 function wp_unique_filename( $dir, $filename, $unique_filename_callback = null ) { |
|
2097 // sanitize the file name before we begin processing |
|
2098 $filename = sanitize_file_name($filename); |
|
2099 |
|
2100 // separate the filename into a name and extension |
|
2101 $info = pathinfo($filename); |
|
2102 $ext = !empty($info['extension']) ? $info['extension'] : ''; |
|
2103 $name = basename($filename, ".{$ext}"); |
|
2104 |
|
2105 // edge case: if file is named '.ext', treat as an empty name |
|
2106 if( $name === ".$ext" ) |
|
2107 $name = ''; |
|
2108 |
|
2109 // Increment the file number until we have a unique file to save in $dir. Use $override['unique_filename_callback'] if supplied. |
|
2110 if ( $unique_filename_callback && function_exists( $unique_filename_callback ) ) { |
|
2111 $filename = $unique_filename_callback( $dir, $name ); |
|
2112 } else { |
|
2113 $number = ''; |
|
2114 |
|
2115 if ( !empty( $ext ) ) |
|
2116 $ext = ".$ext"; |
|
2117 |
|
2118 while ( file_exists( $dir . "/$filename" ) ) { |
|
2119 if ( '' == "$number$ext" ) |
|
2120 $filename = $filename . ++$number . $ext; |
|
2121 else |
|
2122 $filename = str_replace( "$number$ext", ++$number . $ext, $filename ); |
|
2123 } |
|
2124 } |
|
2125 |
|
2126 return $filename; |
|
2127 } |
|
2128 |
|
2129 /** |
|
2130 * Create a file in the upload folder with given content. |
|
2131 * |
|
2132 * If there is an error, then the key 'error' will exist with the error message. |
|
2133 * If success, then the key 'file' will have the unique file path, the 'url' key |
|
2134 * will have the link to the new file. and the 'error' key will be set to false. |
|
2135 * |
|
2136 * This function will not move an uploaded file to the upload folder. It will |
|
2137 * create a new file with the content in $bits parameter. If you move the upload |
|
2138 * file, read the content of the uploaded file, and then you can give the |
|
2139 * filename and content to this function, which will add it to the upload |
|
2140 * folder. |
|
2141 * |
|
2142 * The permissions will be set on the new file automatically by this function. |
|
2143 * |
|
2144 * @since 2.0.0 |
|
2145 * |
|
2146 * @param string $name |
|
2147 * @param null $deprecated Not used. Set to null. |
|
2148 * @param mixed $bits File content |
|
2149 * @param string $time Optional. Time formatted in 'yyyy/mm'. |
|
2150 * @return array |
|
2151 */ |
|
2152 function wp_upload_bits( $name, $deprecated, $bits, $time = null ) { |
|
2153 if ( empty( $name ) ) |
|
2154 return array( 'error' => __( 'Empty filename' ) ); |
|
2155 |
|
2156 $wp_filetype = wp_check_filetype( $name ); |
|
2157 if ( !$wp_filetype['ext'] ) |
|
2158 return array( 'error' => __( 'Invalid file type' ) ); |
|
2159 |
|
2160 $upload = wp_upload_dir( $time ); |
|
2161 |
|
2162 if ( $upload['error'] !== false ) |
|
2163 return $upload; |
|
2164 |
|
2165 $filename = wp_unique_filename( $upload['path'], $name ); |
|
2166 |
|
2167 $new_file = $upload['path'] . "/$filename"; |
|
2168 if ( ! wp_mkdir_p( dirname( $new_file ) ) ) { |
|
2169 $message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) ); |
|
2170 return array( 'error' => $message ); |
|
2171 } |
|
2172 |
|
2173 $ifp = @ fopen( $new_file, 'wb' ); |
|
2174 if ( ! $ifp ) |
|
2175 return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) ); |
|
2176 |
|
2177 @fwrite( $ifp, $bits ); |
|
2178 fclose( $ifp ); |
|
2179 // Set correct file permissions |
|
2180 $stat = @ stat( dirname( $new_file ) ); |
|
2181 $perms = $stat['mode'] & 0007777; |
|
2182 $perms = $perms & 0000666; |
|
2183 @ chmod( $new_file, $perms ); |
|
2184 |
|
2185 // Compute the URL |
|
2186 $url = $upload['url'] . "/$filename"; |
|
2187 |
|
2188 return array( 'file' => $new_file, 'url' => $url, 'error' => false ); |
|
2189 } |
|
2190 |
|
2191 /** |
|
2192 * Retrieve the file type based on the extension name. |
|
2193 * |
|
2194 * @package WordPress |
|
2195 * @since 2.5.0 |
|
2196 * @uses apply_filters() Calls 'ext2type' hook on default supported types. |
|
2197 * |
|
2198 * @param string $ext The extension to search. |
|
2199 * @return string|null The file type, example: audio, video, document, spreadsheet, etc. Null if not found. |
|
2200 */ |
|
2201 function wp_ext2type( $ext ) { |
|
2202 $ext2type = apply_filters('ext2type', array( |
|
2203 'audio' => array('aac','ac3','aif','aiff','mp1','mp2','mp3','m3a','m4a','m4b','ogg','ram','wav','wma'), |
|
2204 'video' => array('asf','avi','divx','dv','mov','mpg','mpeg','mp4','mpv','ogm','qt','rm','vob','wmv', 'm4v'), |
|
2205 'document' => array('doc','docx','pages','odt','rtf','pdf'), |
|
2206 'spreadsheet' => array('xls','xlsx','numbers','ods'), |
|
2207 'interactive' => array('ppt','pptx','key','odp','swf'), |
|
2208 'text' => array('txt'), |
|
2209 'archive' => array('tar','bz2','gz','cab','dmg','rar','sea','sit','sqx','zip'), |
|
2210 'code' => array('css','html','php','js'), |
|
2211 )); |
|
2212 foreach ( $ext2type as $type => $exts ) |
|
2213 if ( in_array($ext, $exts) ) |
|
2214 return $type; |
|
2215 } |
|
2216 |
|
2217 /** |
|
2218 * Retrieve the file type from the file name. |
|
2219 * |
|
2220 * You can optionally define the mime array, if needed. |
|
2221 * |
|
2222 * @since 2.0.4 |
|
2223 * |
|
2224 * @param string $filename File name or path. |
|
2225 * @param array $mimes Optional. Key is the file extension with value as the mime type. |
|
2226 * @return array Values with extension first and mime type. |
|
2227 */ |
|
2228 function wp_check_filetype( $filename, $mimes = null ) { |
|
2229 if ( empty($mimes) ) |
|
2230 $mimes = get_allowed_mime_types(); |
|
2231 $type = false; |
|
2232 $ext = false; |
|
2233 |
|
2234 foreach ( $mimes as $ext_preg => $mime_match ) { |
|
2235 $ext_preg = '!\.(' . $ext_preg . ')$!i'; |
|
2236 if ( preg_match( $ext_preg, $filename, $ext_matches ) ) { |
|
2237 $type = $mime_match; |
|
2238 $ext = $ext_matches[1]; |
|
2239 break; |
|
2240 } |
|
2241 } |
|
2242 |
|
2243 return compact( 'ext', 'type' ); |
|
2244 } |
|
2245 |
|
2246 /** |
|
2247 * Retrieve list of allowed mime types and file extensions. |
|
2248 * |
|
2249 * @since 2.8.6 |
|
2250 * |
|
2251 * @return array Array of mime types keyed by the file extension regex corresponding to those types. |
|
2252 */ |
|
2253 function get_allowed_mime_types() { |
|
2254 static $mimes = false; |
|
2255 |
|
2256 if ( !$mimes ) { |
|
2257 // Accepted MIME types are set here as PCRE unless provided. |
|
2258 $mimes = apply_filters( 'upload_mimes', array( |
|
2259 'jpg|jpeg|jpe' => 'image/jpeg', |
|
2260 'gif' => 'image/gif', |
|
2261 'png' => 'image/png', |
|
2262 'bmp' => 'image/bmp', |
|
2263 'tif|tiff' => 'image/tiff', |
|
2264 'ico' => 'image/x-icon', |
|
2265 'asf|asx|wax|wmv|wmx' => 'video/asf', |
|
2266 'avi' => 'video/avi', |
|
2267 'divx' => 'video/divx', |
|
2268 'mov|qt' => 'video/quicktime', |
|
2269 'mpeg|mpg|mpe' => 'video/mpeg', |
|
2270 'txt|c|cc|h' => 'text/plain', |
|
2271 'rtx' => 'text/richtext', |
|
2272 'css' => 'text/css', |
|
2273 'htm|html' => 'text/html', |
|
2274 'mp3|m4a' => 'audio/mpeg', |
|
2275 'mp4|m4v' => 'video/mp4', |
|
2276 'ra|ram' => 'audio/x-realaudio', |
|
2277 'wav' => 'audio/wav', |
|
2278 'ogg' => 'audio/ogg', |
|
2279 'mid|midi' => 'audio/midi', |
|
2280 'wma' => 'audio/wma', |
|
2281 'rtf' => 'application/rtf', |
|
2282 'js' => 'application/javascript', |
|
2283 'pdf' => 'application/pdf', |
|
2284 'doc|docx' => 'application/msword', |
|
2285 'pot|pps|ppt|pptx' => 'application/vnd.ms-powerpoint', |
|
2286 'wri' => 'application/vnd.ms-write', |
|
2287 'xla|xls|xlsx|xlt|xlw' => 'application/vnd.ms-excel', |
|
2288 'mdb' => 'application/vnd.ms-access', |
|
2289 'mpp' => 'application/vnd.ms-project', |
|
2290 'swf' => 'application/x-shockwave-flash', |
|
2291 'class' => 'application/java', |
|
2292 'tar' => 'application/x-tar', |
|
2293 'zip' => 'application/zip', |
|
2294 'gz|gzip' => 'application/x-gzip', |
|
2295 'exe' => 'application/x-msdownload', |
|
2296 // openoffice formats |
|
2297 'odt' => 'application/vnd.oasis.opendocument.text', |
|
2298 'odp' => 'application/vnd.oasis.opendocument.presentation', |
|
2299 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', |
|
2300 'odg' => 'application/vnd.oasis.opendocument.graphics', |
|
2301 'odc' => 'application/vnd.oasis.opendocument.chart', |
|
2302 'odb' => 'application/vnd.oasis.opendocument.database', |
|
2303 'odf' => 'application/vnd.oasis.opendocument.formula', |
|
2304 ) ); |
|
2305 } |
|
2306 |
|
2307 return $mimes; |
|
2308 } |
|
2309 |
|
2310 /** |
|
2311 * Retrieve nonce action "Are you sure" message. |
|
2312 * |
|
2313 * The action is split by verb and noun. The action format is as follows: |
|
2314 * verb-action_extra. The verb is before the first dash and has the format of |
|
2315 * letters and no spaces and numbers. The noun is after the dash and before the |
|
2316 * underscore, if an underscore exists. The noun is also only letters. |
|
2317 * |
|
2318 * The filter will be called for any action, which is not defined by WordPress. |
|
2319 * You may use the filter for your plugin to explain nonce actions to the user, |
|
2320 * when they get the "Are you sure?" message. The filter is in the format of |
|
2321 * 'explain_nonce_$verb-$noun' with the $verb replaced by the found verb and the |
|
2322 * $noun replaced by the found noun. The two parameters that are given to the |
|
2323 * hook are the localized "Are you sure you want to do this?" message with the |
|
2324 * extra text (the text after the underscore). |
|
2325 * |
|
2326 * @package WordPress |
|
2327 * @subpackage Security |
|
2328 * @since 2.0.4 |
|
2329 * |
|
2330 * @param string $action Nonce action. |
|
2331 * @return string Are you sure message. |
|
2332 */ |
|
2333 function wp_explain_nonce( $action ) { |
|
2334 if ( $action !== -1 && preg_match( '/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches ) ) { |
|
2335 $verb = $matches[1]; |
|
2336 $noun = $matches[2]; |
|
2337 |
|
2338 $trans = array(); |
|
2339 $trans['update']['attachment'] = array( __( 'Your attempt to edit this attachment: “%s” has failed.' ), 'get_the_title' ); |
|
2340 |
|
2341 $trans['add']['category'] = array( __( 'Your attempt to add this category has failed.' ), false ); |
|
2342 $trans['delete']['category'] = array( __( 'Your attempt to delete this category: “%s” has failed.' ), 'get_cat_name' ); |
|
2343 $trans['update']['category'] = array( __( 'Your attempt to edit this category: “%s” has failed.' ), 'get_cat_name' ); |
|
2344 |
|
2345 $trans['delete']['comment'] = array( __( 'Your attempt to delete this comment: “%s” has failed.' ), 'use_id' ); |
|
2346 $trans['unapprove']['comment'] = array( __( 'Your attempt to unapprove this comment: “%s” has failed.' ), 'use_id' ); |
|
2347 $trans['approve']['comment'] = array( __( 'Your attempt to approve this comment: “%s” has failed.' ), 'use_id' ); |
|
2348 $trans['update']['comment'] = array( __( 'Your attempt to edit this comment: “%s” has failed.' ), 'use_id' ); |
|
2349 $trans['bulk']['comments'] = array( __( 'Your attempt to bulk modify comments has failed.' ), false ); |
|
2350 $trans['moderate']['comments'] = array( __( 'Your attempt to moderate comments has failed.' ), false ); |
|
2351 |
|
2352 $trans['add']['bookmark'] = array( __( 'Your attempt to add this link has failed.' ), false ); |
|
2353 $trans['delete']['bookmark'] = array( __( 'Your attempt to delete this link: “%s” has failed.' ), 'use_id' ); |
|
2354 $trans['update']['bookmark'] = array( __( 'Your attempt to edit this link: “%s” has failed.' ), 'use_id' ); |
|
2355 $trans['bulk']['bookmarks'] = array( __( 'Your attempt to bulk modify links has failed.' ), false ); |
|
2356 |
|
2357 $trans['add']['page'] = array( __( 'Your attempt to add this page has failed.' ), false ); |
|
2358 $trans['delete']['page'] = array( __( 'Your attempt to delete this page: “%s” has failed.' ), 'get_the_title' ); |
|
2359 $trans['update']['page'] = array( __( 'Your attempt to edit this page: “%s” has failed.' ), 'get_the_title' ); |
|
2360 |
|
2361 $trans['edit']['plugin'] = array( __( 'Your attempt to edit this plugin file: “%s” has failed.' ), 'use_id' ); |
|
2362 $trans['activate']['plugin'] = array( __( 'Your attempt to activate this plugin: “%s” has failed.' ), 'use_id' ); |
|
2363 $trans['deactivate']['plugin'] = array( __( 'Your attempt to deactivate this plugin: “%s” has failed.' ), 'use_id' ); |
|
2364 $trans['upgrade']['plugin'] = array( __( 'Your attempt to upgrade this plugin: “%s” has failed.' ), 'use_id' ); |
|
2365 |
|
2366 $trans['add']['post'] = array( __( 'Your attempt to add this post has failed.' ), false ); |
|
2367 $trans['delete']['post'] = array( __( 'Your attempt to delete this post: “%s” has failed.' ), 'get_the_title' ); |
|
2368 $trans['update']['post'] = array( __( 'Your attempt to edit this post: “%s” has failed.' ), 'get_the_title' ); |
|
2369 |
|
2370 $trans['add']['user'] = array( __( 'Your attempt to add this user has failed.' ), false ); |
|
2371 $trans['delete']['users'] = array( __( 'Your attempt to delete users has failed.' ), false ); |
|
2372 $trans['bulk']['users'] = array( __( 'Your attempt to bulk modify users has failed.' ), false ); |
|
2373 $trans['update']['user'] = array( __( 'Your attempt to edit this user: “%s” has failed.' ), 'get_the_author_meta', 'display_name' ); |
|
2374 $trans['update']['profile'] = array( __( 'Your attempt to modify the profile for: “%s” has failed.' ), 'get_the_author_meta', 'display_name' ); |
|
2375 |
|
2376 $trans['update']['options'] = array( __( 'Your attempt to edit your settings has failed.' ), false ); |
|
2377 $trans['update']['permalink'] = array( __( 'Your attempt to change your permalink structure to: %s has failed.' ), 'use_id' ); |
|
2378 $trans['edit']['file'] = array( __( 'Your attempt to edit this file: “%s” has failed.' ), 'use_id' ); |
|
2379 $trans['edit']['theme'] = array( __( 'Your attempt to edit this theme file: “%s” has failed.' ), 'use_id' ); |
|
2380 $trans['switch']['theme'] = array( __( 'Your attempt to switch to this theme: “%s” has failed.' ), 'use_id' ); |
|
2381 |
|
2382 $trans['log']['out'] = array( sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'sitename' ) ), false ); |
|
2383 |
|
2384 if ( isset( $trans[$verb][$noun] ) ) { |
|
2385 if ( !empty( $trans[$verb][$noun][1] ) ) { |
|
2386 $lookup = $trans[$verb][$noun][1]; |
|
2387 if ( isset($trans[$verb][$noun][2]) ) |
|
2388 $lookup_value = $trans[$verb][$noun][2]; |
|
2389 $object = $matches[4]; |
|
2390 if ( 'use_id' != $lookup ) { |
|
2391 if ( isset( $lookup_value ) ) |
|
2392 $object = call_user_func( $lookup, $lookup_value, $object ); |
|
2393 else |
|
2394 $object = call_user_func( $lookup, $object ); |
|
2395 } |
|
2396 return sprintf( $trans[$verb][$noun][0], esc_html($object) ); |
|
2397 } else { |
|
2398 return $trans[$verb][$noun][0]; |
|
2399 } |
|
2400 } |
|
2401 |
|
2402 return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __( 'Are you sure you want to do this?' ), $matches[4] ); |
|
2403 } else { |
|
2404 return apply_filters( 'explain_nonce_' . $action, __( 'Are you sure you want to do this?' ) ); |
|
2405 } |
|
2406 } |
|
2407 |
|
2408 /** |
|
2409 * Display "Are You Sure" message to confirm the action being taken. |
|
2410 * |
|
2411 * If the action has the nonce explain message, then it will be displayed along |
|
2412 * with the "Are you sure?" message. |
|
2413 * |
|
2414 * @package WordPress |
|
2415 * @subpackage Security |
|
2416 * @since 2.0.4 |
|
2417 * |
|
2418 * @param string $action The nonce action. |
|
2419 */ |
|
2420 function wp_nonce_ays( $action ) { |
|
2421 $title = __( 'WordPress Failure Notice' ); |
|
2422 $html = esc_html( wp_explain_nonce( $action ) ); |
|
2423 if ( wp_get_referer() ) |
|
2424 $html .= "</p><p><a href='" . esc_url( remove_query_arg( 'updated', wp_get_referer() ) ) . "'>" . __( 'Please try again.' ) . "</a>"; |
|
2425 elseif ( 'log-out' == $action ) |
|
2426 $html .= "</p><p>" . sprintf( __( "Do you really want to <a href='%s'>log out</a>?"), wp_logout_url() ); |
|
2427 |
|
2428 wp_die( $html, $title); |
|
2429 } |
|
2430 |
|
2431 /** |
|
2432 * Kill WordPress execution and display HTML message with error message. |
|
2433 * |
|
2434 * Call this function complements the die() PHP function. The difference is that |
|
2435 * HTML will be displayed to the user. It is recommended to use this function |
|
2436 * only, when the execution should not continue any further. It is not |
|
2437 * recommended to call this function very often and try to handle as many errors |
|
2438 * as possible siliently. |
|
2439 * |
|
2440 * @since 2.0.4 |
|
2441 * |
|
2442 * @param string $message Error message. |
|
2443 * @param string $title Error title. |
|
2444 * @param string|array $args Optional arguements to control behaviour. |
|
2445 */ |
|
2446 function wp_die( $message, $title = '', $args = array() ) { |
|
2447 global $wp_locale; |
|
2448 |
|
2449 $defaults = array( 'response' => 500 ); |
|
2450 $r = wp_parse_args($args, $defaults); |
|
2451 |
|
2452 $have_gettext = function_exists('__'); |
|
2453 |
|
2454 if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { |
|
2455 if ( empty( $title ) ) { |
|
2456 $error_data = $message->get_error_data(); |
|
2457 if ( is_array( $error_data ) && isset( $error_data['title'] ) ) |
|
2458 $title = $error_data['title']; |
|
2459 } |
|
2460 $errors = $message->get_error_messages(); |
|
2461 switch ( count( $errors ) ) : |
|
2462 case 0 : |
|
2463 $message = ''; |
|
2464 break; |
|
2465 case 1 : |
|
2466 $message = "<p>{$errors[0]}</p>"; |
|
2467 break; |
|
2468 default : |
|
2469 $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>"; |
|
2470 break; |
|
2471 endswitch; |
|
2472 } elseif ( is_string( $message ) ) { |
|
2473 $message = "<p>$message</p>"; |
|
2474 } |
|
2475 |
|
2476 if ( isset( $r['back_link'] ) && $r['back_link'] ) { |
|
2477 $back_text = $have_gettext? __('« Back') : '« Back'; |
|
2478 $message .= "\n<p><a href='javascript:history.back()'>$back_text</p>"; |
|
2479 } |
|
2480 |
|
2481 if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL ) |
|
2482 $admin_dir = WP_SITEURL . '/wp-admin/'; |
|
2483 elseif ( function_exists( 'get_bloginfo' ) && '' != get_bloginfo( 'wpurl' ) ) |
|
2484 $admin_dir = get_bloginfo( 'wpurl' ) . '/wp-admin/'; |
|
2485 elseif ( strpos( $_SERVER['PHP_SELF'], 'wp-admin' ) !== false ) |
|
2486 $admin_dir = ''; |
|
2487 else |
|
2488 $admin_dir = 'wp-admin/'; |
|
2489 |
|
2490 if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : |
|
2491 if( !headers_sent() ){ |
|
2492 status_header( $r['response'] ); |
|
2493 nocache_headers(); |
|
2494 header( 'Content-Type: text/html; charset=utf-8' ); |
|
2495 } |
|
2496 |
|
2497 if ( empty($title) ) { |
|
2498 $title = $have_gettext? __('WordPress › Error') : 'WordPress › Error'; |
|
2499 } |
|
2500 |
|
2501 $text_direction = 'ltr'; |
|
2502 if ( isset($r['text_direction']) && $r['text_direction'] == 'rtl' ) $text_direction = 'rtl'; |
|
2503 if ( ( $wp_locale ) && ( 'rtl' == $wp_locale->text_direction ) ) $text_direction = 'rtl'; |
|
2504 ?> |
|
2505 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|
2506 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) ) language_attributes(); ?>> |
|
2507 <head> |
|
2508 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|
2509 <title><?php echo $title ?></title> |
|
2510 <link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install.css" type="text/css" /> |
|
2511 <?php |
|
2512 if ( 'rtl' == $text_direction ) : ?> |
|
2513 <link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install-rtl.css" type="text/css" /> |
|
2514 <?php endif; ?> |
|
2515 </head> |
|
2516 <body id="error-page"> |
|
2517 <?php endif; ?> |
|
2518 <?php echo $message; ?> |
|
2519 </body> |
|
2520 <!-- Ticket #8942, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono --> |
|
2521 </html> |
|
2522 <?php |
|
2523 die(); |
|
2524 } |
|
2525 |
|
2526 /** |
|
2527 * Retrieve the WordPress home page URL. |
|
2528 * |
|
2529 * If the constant named 'WP_HOME' exists, then it willl be used and returned by |
|
2530 * the function. This can be used to counter the redirection on your local |
|
2531 * development environment. |
|
2532 * |
|
2533 * @access private |
|
2534 * @package WordPress |
|
2535 * @since 2.2.0 |
|
2536 * |
|
2537 * @param string $url URL for the home location |
|
2538 * @return string Homepage location. |
|
2539 */ |
|
2540 function _config_wp_home( $url = '' ) { |
|
2541 if ( defined( 'WP_HOME' ) ) |
|
2542 return WP_HOME; |
|
2543 return $url; |
|
2544 } |
|
2545 |
|
2546 /** |
|
2547 * Retrieve the WordPress site URL. |
|
2548 * |
|
2549 * If the constant named 'WP_SITEURL' is defined, then the value in that |
|
2550 * constant will always be returned. This can be used for debugging a site on |
|
2551 * your localhost while not having to change the database to your URL. |
|
2552 * |
|
2553 * @access private |
|
2554 * @package WordPress |
|
2555 * @since 2.2.0 |
|
2556 * |
|
2557 * @param string $url URL to set the WordPress site location. |
|
2558 * @return string The WordPress Site URL |
|
2559 */ |
|
2560 function _config_wp_siteurl( $url = '' ) { |
|
2561 if ( defined( 'WP_SITEURL' ) ) |
|
2562 return WP_SITEURL; |
|
2563 return $url; |
|
2564 } |
|
2565 |
|
2566 /** |
|
2567 * Set the localized direction for MCE plugin. |
|
2568 * |
|
2569 * Will only set the direction to 'rtl', if the WordPress locale has the text |
|
2570 * direction set to 'rtl'. |
|
2571 * |
|
2572 * Fills in the 'directionality', 'plugins', and 'theme_advanced_button1' array |
|
2573 * keys. These keys are then returned in the $input array. |
|
2574 * |
|
2575 * @access private |
|
2576 * @package WordPress |
|
2577 * @subpackage MCE |
|
2578 * @since 2.1.0 |
|
2579 * |
|
2580 * @param array $input MCE plugin array. |
|
2581 * @return array Direction set for 'rtl', if needed by locale. |
|
2582 */ |
|
2583 function _mce_set_direction( $input ) { |
|
2584 global $wp_locale; |
|
2585 |
|
2586 if ( 'rtl' == $wp_locale->text_direction ) { |
|
2587 $input['directionality'] = 'rtl'; |
|
2588 $input['plugins'] .= ',directionality'; |
|
2589 $input['theme_advanced_buttons1'] .= ',ltr'; |
|
2590 } |
|
2591 |
|
2592 return $input; |
|
2593 } |
|
2594 |
|
2595 |
|
2596 /** |
|
2597 * Convert smiley code to the icon graphic file equivalent. |
|
2598 * |
|
2599 * You can turn off smilies, by going to the write setting screen and unchecking |
|
2600 * the box, or by setting 'use_smilies' option to false or removing the option. |
|
2601 * |
|
2602 * Plugins may override the default smiley list by setting the $wpsmiliestrans |
|
2603 * to an array, with the key the code the blogger types in and the value the |
|
2604 * image file. |
|
2605 * |
|
2606 * The $wp_smiliessearch global is for the regular expression and is set each |
|
2607 * time the function is called. |
|
2608 * |
|
2609 * The full list of smilies can be found in the function and won't be listed in |
|
2610 * the description. Probably should create a Codex page for it, so that it is |
|
2611 * available. |
|
2612 * |
|
2613 * @global array $wpsmiliestrans |
|
2614 * @global array $wp_smiliessearch |
|
2615 * @since 2.2.0 |
|
2616 */ |
|
2617 function smilies_init() { |
|
2618 global $wpsmiliestrans, $wp_smiliessearch; |
|
2619 |
|
2620 // don't bother setting up smilies if they are disabled |
|
2621 if ( !get_option( 'use_smilies' ) ) |
|
2622 return; |
|
2623 |
|
2624 if ( !isset( $wpsmiliestrans ) ) { |
|
2625 $wpsmiliestrans = array( |
|
2626 ':mrgreen:' => 'icon_mrgreen.gif', |
|
2627 ':neutral:' => 'icon_neutral.gif', |
|
2628 ':twisted:' => 'icon_twisted.gif', |
|
2629 ':arrow:' => 'icon_arrow.gif', |
|
2630 ':shock:' => 'icon_eek.gif', |
|
2631 ':smile:' => 'icon_smile.gif', |
|
2632 ':???:' => 'icon_confused.gif', |
|
2633 ':cool:' => 'icon_cool.gif', |
|
2634 ':evil:' => 'icon_evil.gif', |
|
2635 ':grin:' => 'icon_biggrin.gif', |
|
2636 ':idea:' => 'icon_idea.gif', |
|
2637 ':oops:' => 'icon_redface.gif', |
|
2638 ':razz:' => 'icon_razz.gif', |
|
2639 ':roll:' => 'icon_rolleyes.gif', |
|
2640 ':wink:' => 'icon_wink.gif', |
|
2641 ':cry:' => 'icon_cry.gif', |
|
2642 ':eek:' => 'icon_surprised.gif', |
|
2643 ':lol:' => 'icon_lol.gif', |
|
2644 ':mad:' => 'icon_mad.gif', |
|
2645 ':sad:' => 'icon_sad.gif', |
|
2646 '8-)' => 'icon_cool.gif', |
|
2647 '8-O' => 'icon_eek.gif', |
|
2648 ':-(' => 'icon_sad.gif', |
|
2649 ':-)' => 'icon_smile.gif', |
|
2650 ':-?' => 'icon_confused.gif', |
|
2651 ':-D' => 'icon_biggrin.gif', |
|
2652 ':-P' => 'icon_razz.gif', |
|
2653 ':-o' => 'icon_surprised.gif', |
|
2654 ':-x' => 'icon_mad.gif', |
|
2655 ':-|' => 'icon_neutral.gif', |
|
2656 ';-)' => 'icon_wink.gif', |
|
2657 '8)' => 'icon_cool.gif', |
|
2658 '8O' => 'icon_eek.gif', |
|
2659 ':(' => 'icon_sad.gif', |
|
2660 ':)' => 'icon_smile.gif', |
|
2661 ':?' => 'icon_confused.gif', |
|
2662 ':D' => 'icon_biggrin.gif', |
|
2663 ':P' => 'icon_razz.gif', |
|
2664 ':o' => 'icon_surprised.gif', |
|
2665 ':x' => 'icon_mad.gif', |
|
2666 ':|' => 'icon_neutral.gif', |
|
2667 ';)' => 'icon_wink.gif', |
|
2668 ':!:' => 'icon_exclaim.gif', |
|
2669 ':?:' => 'icon_question.gif', |
|
2670 ); |
|
2671 } |
|
2672 |
|
2673 if (count($wpsmiliestrans) == 0) { |
|
2674 return; |
|
2675 } |
|
2676 |
|
2677 /* |
|
2678 * NOTE: we sort the smilies in reverse key order. This is to make sure |
|
2679 * we match the longest possible smilie (:???: vs :?) as the regular |
|
2680 * expression used below is first-match |
|
2681 */ |
|
2682 krsort($wpsmiliestrans); |
|
2683 |
|
2684 $wp_smiliessearch = '/(?:\s|^)'; |
|
2685 |
|
2686 $subchar = ''; |
|
2687 foreach ( (array) $wpsmiliestrans as $smiley => $img ) { |
|
2688 $firstchar = substr($smiley, 0, 1); |
|
2689 $rest = substr($smiley, 1); |
|
2690 |
|
2691 // new subpattern? |
|
2692 if ($firstchar != $subchar) { |
|
2693 if ($subchar != '') { |
|
2694 $wp_smiliessearch .= ')|(?:\s|^)'; |
|
2695 } |
|
2696 $subchar = $firstchar; |
|
2697 $wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:'; |
|
2698 } else { |
|
2699 $wp_smiliessearch .= '|'; |
|
2700 } |
|
2701 $wp_smiliessearch .= preg_quote($rest, '/'); |
|
2702 } |
|
2703 |
|
2704 $wp_smiliessearch .= ')(?:\s|$)/m'; |
|
2705 } |
|
2706 |
|
2707 /** |
|
2708 * Merge user defined arguments into defaults array. |
|
2709 * |
|
2710 * This function is used throughout WordPress to allow for both string or array |
|
2711 * to be merged into another array. |
|
2712 * |
|
2713 * @since 2.2.0 |
|
2714 * |
|
2715 * @param string|array $args Value to merge with $defaults |
|
2716 * @param array $defaults Array that serves as the defaults. |
|
2717 * @return array Merged user defined values with defaults. |
|
2718 */ |
|
2719 function wp_parse_args( $args, $defaults = '' ) { |
|
2720 if ( is_object( $args ) ) |
|
2721 $r = get_object_vars( $args ); |
|
2722 elseif ( is_array( $args ) ) |
|
2723 $r =& $args; |
|
2724 else |
|
2725 wp_parse_str( $args, $r ); |
|
2726 |
|
2727 if ( is_array( $defaults ) ) |
|
2728 return array_merge( $defaults, $r ); |
|
2729 return $r; |
|
2730 } |
|
2731 |
|
2732 /** |
|
2733 * Determines if Widgets library should be loaded. |
|
2734 * |
|
2735 * Checks to make sure that the widgets library hasn't already been loaded. If |
|
2736 * it hasn't, then it will load the widgets library and run an action hook. |
|
2737 * |
|
2738 * @since 2.2.0 |
|
2739 * @uses add_action() Calls '_admin_menu' hook with 'wp_widgets_add_menu' value. |
|
2740 */ |
|
2741 function wp_maybe_load_widgets() { |
|
2742 if ( ! apply_filters('load_default_widgets', true) ) |
|
2743 return; |
|
2744 require_once( ABSPATH . WPINC . '/default-widgets.php' ); |
|
2745 add_action( '_admin_menu', 'wp_widgets_add_menu' ); |
|
2746 } |
|
2747 |
|
2748 /** |
|
2749 * Append the Widgets menu to the themes main menu. |
|
2750 * |
|
2751 * @since 2.2.0 |
|
2752 * @uses $submenu The administration submenu list. |
|
2753 */ |
|
2754 function wp_widgets_add_menu() { |
|
2755 global $submenu; |
|
2756 $submenu['themes.php'][7] = array( __( 'Widgets' ), 'switch_themes', 'widgets.php' ); |
|
2757 ksort( $submenu['themes.php'], SORT_NUMERIC ); |
|
2758 } |
|
2759 |
|
2760 /** |
|
2761 * Flush all output buffers for PHP 5.2. |
|
2762 * |
|
2763 * Make sure all output buffers are flushed before our singletons our destroyed. |
|
2764 * |
|
2765 * @since 2.2.0 |
|
2766 */ |
|
2767 function wp_ob_end_flush_all() { |
|
2768 $levels = ob_get_level(); |
|
2769 for ($i=0; $i<$levels; $i++) |
|
2770 ob_end_flush(); |
|
2771 } |
|
2772 |
|
2773 /** |
|
2774 * Load the correct database class file. |
|
2775 * |
|
2776 * This function is used to load the database class file either at runtime or by |
|
2777 * wp-admin/setup-config.php We must globalise $wpdb to ensure that it is |
|
2778 * defined globally by the inline code in wp-db.php. |
|
2779 * |
|
2780 * @since 2.5.0 |
|
2781 * @global $wpdb WordPress Database Object |
|
2782 */ |
|
2783 function require_wp_db() { |
|
2784 global $wpdb; |
|
2785 if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) |
|
2786 require_once( WP_CONTENT_DIR . '/db.php' ); |
|
2787 else |
|
2788 require_once( ABSPATH . WPINC . '/wp-db.php' ); |
|
2789 } |
|
2790 |
|
2791 /** |
|
2792 * Load custom DB error or display WordPress DB error. |
|
2793 * |
|
2794 * If a file exists in the wp-content directory named db-error.php, then it will |
|
2795 * be loaded instead of displaying the WordPress DB error. If it is not found, |
|
2796 * then the WordPress DB error will be displayed instead. |
|
2797 * |
|
2798 * The WordPress DB error sets the HTTP status header to 500 to try to prevent |
|
2799 * search engines from caching the message. Custom DB messages should do the |
|
2800 * same. |
|
2801 * |
|
2802 * This function was backported to the the WordPress 2.3.2, but originally was |
|
2803 * added in WordPress 2.5.0. |
|
2804 * |
|
2805 * @since 2.3.2 |
|
2806 * @uses $wpdb |
|
2807 */ |
|
2808 function dead_db() { |
|
2809 global $wpdb; |
|
2810 |
|
2811 // Load custom DB error template, if present. |
|
2812 if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) { |
|
2813 require_once( WP_CONTENT_DIR . '/db-error.php' ); |
|
2814 die(); |
|
2815 } |
|
2816 |
|
2817 // If installing or in the admin, provide the verbose message. |
|
2818 if ( defined('WP_INSTALLING') || defined('WP_ADMIN') ) |
|
2819 wp_die($wpdb->error); |
|
2820 |
|
2821 // Otherwise, be terse. |
|
2822 status_header( 500 ); |
|
2823 nocache_headers(); |
|
2824 header( 'Content-Type: text/html; charset=utf-8' ); |
|
2825 ?> |
|
2826 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|
2827 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) ) language_attributes(); ?>> |
|
2828 <head> |
|
2829 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|
2830 <title>Database Error</title> |
|
2831 |
|
2832 </head> |
|
2833 <body> |
|
2834 <h1>Error establishing a database connection</h1> |
|
2835 </body> |
|
2836 </html> |
|
2837 <?php |
|
2838 die(); |
|
2839 } |
|
2840 |
|
2841 /** |
|
2842 * Converts value to nonnegative integer. |
|
2843 * |
|
2844 * @since 2.5.0 |
|
2845 * |
|
2846 * @param mixed $maybeint Data you wish to have convered to an nonnegative integer |
|
2847 * @return int An nonnegative integer |
|
2848 */ |
|
2849 function absint( $maybeint ) { |
|
2850 return abs( intval( $maybeint ) ); |
|
2851 } |
|
2852 |
|
2853 /** |
|
2854 * Determines if the blog can be accessed over SSL. |
|
2855 * |
|
2856 * Determines if blog can be accessed over SSL by using cURL to access the site |
|
2857 * using the https in the siteurl. Requires cURL extension to work correctly. |
|
2858 * |
|
2859 * @since 2.5.0 |
|
2860 * |
|
2861 * @return bool Whether or not SSL access is available |
|
2862 */ |
|
2863 function url_is_accessable_via_ssl($url) |
|
2864 { |
|
2865 if (in_array('curl', get_loaded_extensions())) { |
|
2866 $ssl = preg_replace( '/^http:\/\//', 'https://', $url ); |
|
2867 |
|
2868 $ch = curl_init(); |
|
2869 curl_setopt($ch, CURLOPT_URL, $ssl); |
|
2870 curl_setopt($ch, CURLOPT_FAILONERROR, true); |
|
2871 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
|
2872 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); |
|
2873 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); |
|
2874 |
|
2875 curl_exec($ch); |
|
2876 |
|
2877 $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
|
2878 curl_close ($ch); |
|
2879 |
|
2880 if ($status == 200 || $status == 401) { |
|
2881 return true; |
|
2882 } |
|
2883 } |
|
2884 return false; |
|
2885 } |
|
2886 |
|
2887 /** |
|
2888 * Secure URL, if available or the given URL. |
|
2889 * |
|
2890 * @since 2.5.0 |
|
2891 * |
|
2892 * @param string $url Complete URL path with transport. |
|
2893 * @return string Secure or regular URL path. |
|
2894 */ |
|
2895 function atom_service_url_filter($url) |
|
2896 { |
|
2897 if ( url_is_accessable_via_ssl($url) ) |
|
2898 return preg_replace( '/^http:\/\//', 'https://', $url ); |
|
2899 else |
|
2900 return $url; |
|
2901 } |
|
2902 |
|
2903 /** |
|
2904 * Marks a function as deprecated and informs when it has been used. |
|
2905 * |
|
2906 * There is a hook deprecated_function_run that will be called that can be used |
|
2907 * to get the backtrace up to what file and function called the deprecated |
|
2908 * function. |
|
2909 * |
|
2910 * The current behavior is to trigger an user error if WP_DEBUG is defined and |
|
2911 * is true. |
|
2912 * |
|
2913 * This function is to be used in every function in depreceated.php |
|
2914 * |
|
2915 * @package WordPress |
|
2916 * @package Debug |
|
2917 * @since 2.5.0 |
|
2918 * @access private |
|
2919 * |
|
2920 * @uses do_action() Calls 'deprecated_function_run' and passes the function name and what to use instead. |
|
2921 * @uses apply_filters() Calls 'deprecated_function_trigger_error' and expects boolean value of true to do trigger or false to not trigger error. |
|
2922 * |
|
2923 * @param string $function The function that was called |
|
2924 * @param string $version The version of WordPress that deprecated the function |
|
2925 * @param string $replacement Optional. The function that should have been called |
|
2926 */ |
|
2927 function _deprecated_function($function, $version, $replacement=null) { |
|
2928 |
|
2929 do_action('deprecated_function_run', $function, $replacement); |
|
2930 |
|
2931 // Allow plugin to filter the output error trigger |
|
2932 if( defined('WP_DEBUG') && ( true === WP_DEBUG ) && apply_filters( 'deprecated_function_trigger_error', true )) { |
|
2933 if( !is_null($replacement) ) |
|
2934 trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) ); |
|
2935 else |
|
2936 trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $function, $version ) ); |
|
2937 } |
|
2938 } |
|
2939 |
|
2940 /** |
|
2941 * Marks a file as deprecated and informs when it has been used. |
|
2942 * |
|
2943 * There is a hook deprecated_file_included that will be called that can be used |
|
2944 * to get the backtrace up to what file and function included the deprecated |
|
2945 * file. |
|
2946 * |
|
2947 * The current behavior is to trigger an user error if WP_DEBUG is defined and |
|
2948 * is true. |
|
2949 * |
|
2950 * This function is to be used in every file that is depreceated |
|
2951 * |
|
2952 * @package WordPress |
|
2953 * @package Debug |
|
2954 * @since 2.5.0 |
|
2955 * @access private |
|
2956 * |
|
2957 * @uses do_action() Calls 'deprecated_file_included' and passes the file name and what to use instead. |
|
2958 * @uses apply_filters() Calls 'deprecated_file_trigger_error' and expects boolean value of true to do trigger or false to not trigger error. |
|
2959 * |
|
2960 * @param string $file The file that was included |
|
2961 * @param string $version The version of WordPress that deprecated the function |
|
2962 * @param string $replacement Optional. The function that should have been called |
|
2963 */ |
|
2964 function _deprecated_file($file, $version, $replacement=null) { |
|
2965 |
|
2966 do_action('deprecated_file_included', $file, $replacement); |
|
2967 |
|
2968 // Allow plugin to filter the output error trigger |
|
2969 if( defined('WP_DEBUG') && ( true === WP_DEBUG ) && apply_filters( 'deprecated_file_trigger_error', true )) { |
|
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 ) ); |
|
2972 else |
|
2973 trigger_error( sprintf( __('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $file, $version ) ); |
|
2974 } |
|
2975 } |
|
2976 |
|
2977 /** |
|
2978 * Is the server running earlier than 1.5.0 version of lighttpd |
|
2979 * |
|
2980 * @since 2.5.0 |
|
2981 * |
|
2982 * @return bool Whether the server is running lighttpd < 1.5.0 |
|
2983 */ |
|
2984 function is_lighttpd_before_150() { |
|
2985 $server_parts = explode( '/', isset( $_SERVER['SERVER_SOFTWARE'] )? $_SERVER['SERVER_SOFTWARE'] : '' ); |
|
2986 $server_parts[1] = isset( $server_parts[1] )? $server_parts[1] : ''; |
|
2987 return 'lighttpd' == $server_parts[0] && -1 == version_compare( $server_parts[1], '1.5.0' ); |
|
2988 } |
|
2989 |
|
2990 /** |
|
2991 * Does the specified module exist in the apache config? |
|
2992 * |
|
2993 * @since 2.5.0 |
|
2994 * |
|
2995 * @param string $mod e.g. mod_rewrite |
|
2996 * @param bool $default The default return value if the module is not found |
|
2997 * @return bool |
|
2998 */ |
|
2999 function apache_mod_loaded($mod, $default = false) { |
|
3000 global $is_apache; |
|
3001 |
|
3002 if ( !$is_apache ) |
|
3003 return false; |
|
3004 |
|
3005 if ( function_exists('apache_get_modules') ) { |
|
3006 $mods = apache_get_modules(); |
|
3007 if ( in_array($mod, $mods) ) |
|
3008 return true; |
|
3009 } elseif ( function_exists('phpinfo') ) { |
|
3010 ob_start(); |
|
3011 phpinfo(8); |
|
3012 $phpinfo = ob_get_clean(); |
|
3013 if ( false !== strpos($phpinfo, $mod) ) |
|
3014 return true; |
|
3015 } |
|
3016 return $default; |
|
3017 } |
|
3018 |
|
3019 /** |
|
3020 * File validates against allowed set of defined rules. |
|
3021 * |
|
3022 * A return value of '1' means that the $file contains either '..' or './'. A |
|
3023 * return value of '2' means that the $file contains ':' after the first |
|
3024 * character. A return value of '3' means that the file is not in the allowed |
|
3025 * files list. |
|
3026 * |
|
3027 * @since 1.2.0 |
|
3028 * |
|
3029 * @param string $file File path. |
|
3030 * @param array $allowed_files List of allowed files. |
|
3031 * @return int 0 means nothing is wrong, greater than 0 means something was wrong. |
|
3032 */ |
|
3033 function validate_file( $file, $allowed_files = '' ) { |
|
3034 if ( false !== strpos( $file, '..' )) |
|
3035 return 1; |
|
3036 |
|
3037 if ( false !== strpos( $file, './' )) |
|
3038 return 1; |
|
3039 |
|
3040 if (':' == substr( $file, 1, 1 )) |
|
3041 return 2; |
|
3042 |
|
3043 if (!empty ( $allowed_files ) && (!in_array( $file, $allowed_files ) ) ) |
|
3044 return 3; |
|
3045 |
|
3046 return 0; |
|
3047 } |
|
3048 |
|
3049 /** |
|
3050 * Determine if SSL is used. |
|
3051 * |
|
3052 * @since 2.6.0 |
|
3053 * |
|
3054 * @return bool True if SSL, false if not used. |
|
3055 */ |
|
3056 function is_ssl() { |
|
3057 if ( isset($_SERVER['HTTPS']) ) { |
|
3058 if ( 'on' == strtolower($_SERVER['HTTPS']) ) |
|
3059 return true; |
|
3060 if ( '1' == $_SERVER['HTTPS'] ) |
|
3061 return true; |
|
3062 } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) { |
|
3063 return true; |
|
3064 } |
|
3065 return false; |
|
3066 } |
|
3067 |
|
3068 /** |
|
3069 * Whether SSL login should be forced. |
|
3070 * |
|
3071 * @since 2.6.0 |
|
3072 * |
|
3073 * @param string|bool $force Optional. |
|
3074 * @return bool True if forced, false if not forced. |
|
3075 */ |
|
3076 function force_ssl_login($force = '') { |
|
3077 static $forced; |
|
3078 |
|
3079 if ( '' != $force ) { |
|
3080 $old_forced = $forced; |
|
3081 $forced = $force; |
|
3082 return $old_forced; |
|
3083 } |
|
3084 |
|
3085 return $forced; |
|
3086 } |
|
3087 |
|
3088 /** |
|
3089 * Whether to force SSL used for the Administration Panels. |
|
3090 * |
|
3091 * @since 2.6.0 |
|
3092 * |
|
3093 * @param string|bool $force |
|
3094 * @return bool True if forced, false if not forced. |
|
3095 */ |
|
3096 function force_ssl_admin($force = '') { |
|
3097 static $forced; |
|
3098 |
|
3099 if ( '' != $force ) { |
|
3100 $old_forced = $forced; |
|
3101 $forced = $force; |
|
3102 return $old_forced; |
|
3103 } |
|
3104 |
|
3105 return $forced; |
|
3106 } |
|
3107 |
|
3108 /** |
|
3109 * Guess the URL for the site. |
|
3110 * |
|
3111 * Will remove wp-admin links to retrieve only return URLs not in the wp-admin |
|
3112 * directory. |
|
3113 * |
|
3114 * @since 2.6.0 |
|
3115 * |
|
3116 * @return string |
|
3117 */ |
|
3118 function wp_guess_url() { |
|
3119 if ( defined('WP_SITEURL') && '' != WP_SITEURL ) { |
|
3120 $url = WP_SITEURL; |
|
3121 } else { |
|
3122 $schema = ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://'; |
|
3123 $url = preg_replace('|/wp-admin/.*|i', '', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); |
|
3124 } |
|
3125 return $url; |
|
3126 } |
|
3127 |
|
3128 /** |
|
3129 * Suspend cache invalidation. |
|
3130 * |
|
3131 * Turns cache invalidation on and off. Useful during imports where you don't wont to do invalidations |
|
3132 * every time a post is inserted. Callers must be sure that what they are doing won't lead to an inconsistent |
|
3133 * cache when invalidation is suspended. |
|
3134 * |
|
3135 * @since 2.7.0 |
|
3136 * |
|
3137 * @param bool $suspend Whether to suspend or enable cache invalidation |
|
3138 * @return bool The current suspend setting |
|
3139 */ |
|
3140 function wp_suspend_cache_invalidation($suspend = true) { |
|
3141 global $_wp_suspend_cache_invalidation; |
|
3142 |
|
3143 $current_suspend = $_wp_suspend_cache_invalidation; |
|
3144 $_wp_suspend_cache_invalidation = $suspend; |
|
3145 return $current_suspend; |
|
3146 } |
|
3147 |
|
3148 function get_site_option( $key, $default = false, $use_cache = true ) { |
|
3149 return get_option($key, $default); |
|
3150 } |
|
3151 |
|
3152 // expects $key, $value not to be SQL escaped |
|
3153 function add_site_option( $key, $value ) { |
|
3154 return add_option($key, $value); |
|
3155 } |
|
3156 |
|
3157 // expects $key, $value not to be SQL escaped |
|
3158 function update_site_option( $key, $value ) { |
|
3159 return update_option($key, $value); |
|
3160 } |
|
3161 |
|
3162 /** |
|
3163 * gmt_offset modification for smart timezone handling |
|
3164 * |
|
3165 * Overrides the gmt_offset option if we have a timezone_string available |
|
3166 */ |
|
3167 function wp_timezone_override_offset() { |
|
3168 if ( !wp_timezone_supported() ) { |
|
3169 return false; |
|
3170 } |
|
3171 if ( !$timezone_string = get_option( 'timezone_string' ) ) { |
|
3172 return false; |
|
3173 } |
|
3174 |
|
3175 @date_default_timezone_set( $timezone_string ); |
|
3176 $timezone_object = timezone_open( $timezone_string ); |
|
3177 $datetime_object = date_create(); |
|
3178 if ( false === $timezone_object || false === $datetime_object ) { |
|
3179 return false; |
|
3180 } |
|
3181 return round( timezone_offset_get( $timezone_object, $datetime_object ) / 3600, 2 ); |
|
3182 } |
|
3183 |
|
3184 /** |
|
3185 * Check for PHP timezone support |
|
3186 */ |
|
3187 function wp_timezone_supported() { |
|
3188 $support = false; |
|
3189 if ( |
|
3190 function_exists( 'date_default_timezone_set' ) && |
|
3191 function_exists( 'timezone_identifiers_list' ) && |
|
3192 function_exists( 'timezone_open' ) && |
|
3193 function_exists( 'timezone_offset_get' ) |
|
3194 ) { |
|
3195 $support = true; |
|
3196 } |
|
3197 return apply_filters( 'timezone_support', $support ); |
|
3198 } |
|
3199 |
|
3200 function _wp_timezone_choice_usort_callback( $a, $b ) { |
|
3201 // Don't use translated versions of Etc |
|
3202 if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) { |
|
3203 // Make the order of these more like the old dropdown |
|
3204 if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) { |
|
3205 return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) ); |
|
3206 } |
|
3207 if ( 'UTC' === $a['city'] ) { |
|
3208 if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) { |
|
3209 return 1; |
|
3210 } |
|
3211 return -1; |
|
3212 } |
|
3213 if ( 'UTC' === $b['city'] ) { |
|
3214 if ( 'GMT+' === substr( $a['city'], 0, 4 ) ) { |
|
3215 return -1; |
|
3216 } |
|
3217 return 1; |
|
3218 } |
|
3219 return strnatcasecmp( $a['city'], $b['city'] ); |
|
3220 } |
|
3221 if ( $a['t_continent'] == $b['t_continent'] ) { |
|
3222 if ( $a['t_city'] == $b['t_city'] ) { |
|
3223 return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] ); |
|
3224 } |
|
3225 return strnatcasecmp( $a['t_city'], $b['t_city'] ); |
|
3226 } else { |
|
3227 // Force Etc to the bottom of the list |
|
3228 if ( 'Etc' === $a['continent'] ) { |
|
3229 return 1; |
|
3230 } |
|
3231 if ( 'Etc' === $b['continent'] ) { |
|
3232 return -1; |
|
3233 } |
|
3234 return strnatcasecmp( $a['t_continent'], $b['t_continent'] ); |
|
3235 } |
|
3236 } |
|
3237 |
|
3238 /** |
|
3239 * Gives a nicely formatted list of timezone strings // temporary! Not in final |
|
3240 * |
|
3241 * @param $selected_zone string Selected Zone |
|
3242 * |
|
3243 */ |
|
3244 function wp_timezone_choice( $selected_zone ) { |
|
3245 static $mo_loaded = false; |
|
3246 |
|
3247 $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific', 'Etc' ); |
|
3248 |
|
3249 // Load translations for continents and cities |
|
3250 if ( !$mo_loaded ) { |
|
3251 $locale = get_locale(); |
|
3252 $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo'; |
|
3253 load_textdomain( 'continents-cities', $mofile ); |
|
3254 $mo_loaded = true; |
|
3255 } |
|
3256 |
|
3257 $zonen = array(); |
|
3258 foreach ( timezone_identifiers_list() as $zone ) { |
|
3259 $zone = explode( '/', $zone ); |
|
3260 if ( !in_array( $zone[0], $continents ) ) { |
|
3261 continue; |
|
3262 } |
|
3263 if ( 'Etc' === $zone[0] && in_array( $zone[1], array( 'UCT', 'GMT', 'GMT0', 'GMT+0', 'GMT-0', 'Greenwich', 'Universal', 'Zulu' ) ) ) { |
|
3264 continue; |
|
3265 } |
|
3266 |
|
3267 // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later |
|
3268 $exists = array( |
|
3269 0 => ( isset( $zone[0] ) && $zone[0] ) ? true : false, |
|
3270 1 => ( isset( $zone[1] ) && $zone[1] ) ? true : false, |
|
3271 2 => ( isset( $zone[2] ) && $zone[2] ) ? true : false |
|
3272 ); |
|
3273 $exists[3] = ( $exists[0] && 'Etc' !== $zone[0] ) ? true : false; |
|
3274 $exists[4] = ( $exists[1] && $exists[3] ) ? true : false; |
|
3275 $exists[5] = ( $exists[2] && $exists[3] ) ? true : false; |
|
3276 |
|
3277 $zonen[] = array( |
|
3278 'continent' => ( $exists[0] ? $zone[0] : '' ), |
|
3279 'city' => ( $exists[1] ? $zone[1] : '' ), |
|
3280 'subcity' => ( $exists[2] ? $zone[2] : '' ), |
|
3281 't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ), |
|
3282 't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ), |
|
3283 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ) |
|
3284 ); |
|
3285 } |
|
3286 usort( $zonen, '_wp_timezone_choice_usort_callback' ); |
|
3287 |
|
3288 $structure = array(); |
|
3289 |
|
3290 if ( empty( $selected_zone ) ) { |
|
3291 $structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>'; |
|
3292 } |
|
3293 |
|
3294 foreach ( $zonen as $key => $zone ) { |
|
3295 // Build value in an array to join later |
|
3296 $value = array( $zone['continent'] ); |
|
3297 |
|
3298 if ( empty( $zone['city'] ) ) { |
|
3299 // It's at the continent level (generally won't happen) |
|
3300 $display = $zone['t_continent']; |
|
3301 } else { |
|
3302 // It's inside a continent group |
|
3303 |
|
3304 // Continent optgroup |
|
3305 if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) { |
|
3306 $label = ( 'Etc' === $zone['continent'] ) ? __( 'Manual offsets' ) : $zone['t_continent']; |
|
3307 $structure[] = '<optgroup label="'. esc_attr( $label ) .'">'; |
|
3308 } |
|
3309 |
|
3310 // Add the city to the value |
|
3311 $value[] = $zone['city']; |
|
3312 if ( 'Etc' === $zone['continent'] ) { |
|
3313 if ( 'UTC' === $zone['city'] ) { |
|
3314 $display = ''; |
|
3315 } else { |
|
3316 $display = str_replace( 'GMT', '', $zone['city'] ); |
|
3317 $display = strtr( $display, '+-', '-+' ) . ':00'; |
|
3318 } |
|
3319 $display = sprintf( __( 'UTC %s' ), $display ); |
|
3320 } else { |
|
3321 $display = $zone['t_city']; |
|
3322 if ( !empty( $zone['subcity'] ) ) { |
|
3323 // Add the subcity to the value |
|
3324 $value[] = $zone['subcity']; |
|
3325 $display .= ' - ' . $zone['t_subcity']; |
|
3326 } |
|
3327 } |
|
3328 } |
|
3329 |
|
3330 // Build the value |
|
3331 $value = join( '/', $value ); |
|
3332 $selected = ''; |
|
3333 if ( $value === $selected_zone ) { |
|
3334 $selected = 'selected="selected" '; |
|
3335 } |
|
3336 $structure[] = '<option ' . $selected . 'value="' . esc_attr( $value ) . '">' . esc_html( $display ) . "</option>"; |
|
3337 |
|
3338 // Close continent optgroup |
|
3339 if ( !empty( $zone['city'] ) && ( !isset($zonen[$key + 1]) || (isset( $zonen[$key + 1] ) && $zonen[$key + 1]['continent'] !== $zone['continent']) ) ) { |
|
3340 $structure[] = '</optgroup>'; |
|
3341 } |
|
3342 } |
|
3343 |
|
3344 return join( "\n", $structure ); |
|
3345 } |
|
3346 |
|
3347 |
|
3348 |
|
3349 /** |
|
3350 * Strip close comment and close php tags from file headers used by WP |
|
3351 * See http://core.trac.wordpress.org/ticket/8497 |
|
3352 * |
|
3353 * @since 2.8 |
|
3354 **/ |
|
3355 function _cleanup_header_comment($str) { |
|
3356 return trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $str)); |
|
3357 } |
|
3358 ?> |