php cross reference - wordpress - source: /wp-includes...

Download PHP Cross Reference - WordPress - Source: /wp-includes ...phpcrossref.com/xref/wordpress/wp-includes/functions.php.html$wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload

If you can't read please download the document

Upload: dokhanh

Post on 25-Feb-2018

221 views

Category:

Documents


1 download

TRANSCRIPT

PHP Cross Reference - WordPress - Source: /wp-includes/functions.php

WordPressPHP Cross ReferenceBlogging Systems

Statistics - IndexVariables - Functions - Classes - Constants

Source: /wp-includes/functions.php - 5466 lines - 169435 bytes - Summary - Text - Print

Description: Main WordPress API

1 postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post_ID, $wpdb->esc_like( $link_test ) . '%') ); 577 foreach ( $mids as $mid ) 578 delete_metadata_by_mid( 'post', $mid ); 579 } 580 } 581 582 foreach ( (array) $post_links_temp as $link_test ) { 583 if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already 584 $test = @parse_url( $link_test ); 585 if ( false === $test ) 586 continue; 587 if ( isset( $test['query'] ) ) 588 $post_links[] = $link_test; 589 elseif ( isset($test['path']) && ( $test['path'] != '/' ) && ($test['path'] != '' ) ) 590 $post_links[] = $link_test; 591 } 592 } 593 594 /** 595 * Filters the list of enclosure links before querying the database. 596 * 597 * Allows for the addition and/or removal of potential enclosures to save 598 * to postmeta before checking the database for existing enclosures. 599 * 600 * @since 4.4.0 601 * 602 * @param array $post_links An array of enclosure links. 603 * @param int $post_ID Post ID. 604 */ 605 $post_links = apply_filters( 'enclosure_links', $post_links, $post_ID ); 606 607 foreach ( (array) $post_links as $url ) { 608 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, $wpdb->esc_like( $url ) . '%' ) ) ) { 609 610 if ( $headers = wp_get_http_headers( $url) ) { 611 $len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0; 612 $type = isset( $headers['content-type'] ) ? $headers['content-type'] : ''; 613 $allowed_types = array( 'video', 'audio' ); 614 615 // Check to see if we can figure out the mime type from 616 // the extension 617 $url_parts = @parse_url( $url ); 618 if ( false !== $url_parts ) { 619 $extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION ); 620 if ( !empty( $extension ) ) { 621 foreach ( wp_get_mime_types() as $exts => $mime ) { 622 if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) { 623 $type = $mime; 624 break; 625 } 626 } 627 } 628 } 629 630 if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) { 631 add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" ); 632 } 633 } 634 } 635 } 636 } 637 638 /** 639 * Retrieve HTTP Headers from URL. 640 * 641 * @since 1.5.1 642 * 643 * @param string $url URL to retrieve HTTP headers from. 644 * @param bool $deprecated Not Used. 645 * @return bool|string False on failure, headers on success. 646 */ 647 function wp_get_http_headers( $url, $deprecated = false ) { 648 if ( !empty( $deprecated ) ) 649 _deprecated_argument( __FUNCTION__, '2.7.0' ); 650 651 $response = wp_safe_remote_head( $url ); 652 653 if ( is_wp_error( $response ) ) 654 return false; 655 656 return wp_remote_retrieve_headers( $response ); 657 } 658 659 /** 660 * Whether the publish date of the current post in the loop is different from the 661 * publish date of the previous post in the loop. 662 * 663 * @since 0.71 664 * 665 * @global string $currentday The day of the current post in the loop. 666 * @global string $previousday The day of the previous post in the loop. 667 * 668 * @return int 1 when new day, 0 if not a new day. 669 */ 670 function is_new_day() { 671 global $currentday, $previousday; 672 if ( $currentday != $previousday ) 673 return 1; 674 else 675 return 0; 676 } 677 678 /** 679 * Build URL query based on an associative and, or indexed array. 680 * 681 * This is a convenient function for easily building url queries. It sets the 682 * separator to '&' and uses _http_build_query() function. 683 * 684 * @since 2.3.0 685 * 686 * @see _http_build_query() Used to build the query 687 * @link https://secure.php.net/manual/en/function.http-build-query.php for more on what 688 * http_build_query() does. 689 * 690 * @param array $data URL-encode key/value pairs. 691 * @return string URL-encoded string. 692 */ 693 function build_query( $data ) { 694 return _http_build_query( $data, null, '&', '', false ); 695 } 696 697 /** 698 * From php.net (modified by Mark Jaquith to behave like the native PHP5 function). 699 * 700 * @since 3.2.0 701 * @access private 702 * 703 * @see https://secure.php.net/manual/en/function.http-build-query.php 704 * 705 * @param array|object $data An array or object of data. Converted to array. 706 * @param string $prefix Optional. Numeric index. If set, start parameter numbering with it. 707 * Default null. 708 * @param string $sep Optional. Argument separator; defaults to 'arg_separator.output'. 709 * Default null. 710 * @param string $key Optional. Used to prefix key name. Default empty. 711 * @param bool $urlencode Optional. Whether to use urlencode() in the result. Default true. 712 * 713 * @return string The query string. 714 */ 715 function _http_build_query( $data, $prefix = null, $sep = null, $key = '', $urlencode = true ) { 716 $ret = array(); 717 718 foreach ( (array) $data as $k => $v ) { 719 if ( $urlencode) 720 $k = urlencode($k); 721 if ( is_int($k) && $prefix != null ) 722 $k = $prefix.$k; 723 if ( !empty($key) ) 724 $k = $key . '%5B' . $k . '%5D'; 725 if ( $v === null ) 726 continue; 727 elseif ( $v === false ) 728 $v = '0'; 729 730 if ( is_array($v) || is_object($v) ) 731 array_push($ret,_http_build_query($v, '', $sep, $k, $urlencode)); 732 elseif ( $urlencode ) 733 array_push($ret, $k.'='.urlencode($v)); 734 else 735 array_push($ret, $k.'='.$v); 736 } 737 738 if ( null === $sep ) 739 $sep = ini_get('arg_separator.output'); 740 741 return implode($sep, $ret); 742 } 743 744 /** 745 * Retrieves a modified URL query string. 746 * 747 * You can rebuild the URL and append query variables to the URL query by using this function. 748 * There are two ways to use this function; either a single key and value, or an associative array. 749 * 750 * Using a single key and value: 751 * 752 * add_query_arg( 'key', 'value', 'http://example.com' ); 753 * 754 * Using an associative array: 755 * 756 * add_query_arg( array( 757 * 'key1' => 'value1', 758 * 'key2' => 'value2', 759 * ), 'http://example.com' ); 760 * 761 * Omitting the URL from either use results in the current URL being used 762 * (the value of `$_SERVER['REQUEST_URI']`). 763 * 764 * Values are expected to be encoded appropriately with urlencode() or rawurlencode(). 765 * 766 * Setting any query variable's value to boolean false removes the key (see remove_query_arg()). 767 * 768 * Important: The return value of add_query_arg() is not escaped by default. Output should be 769 * late-escaped with esc_url() or similar to help prevent vulnerability to cross-site scripting 770 * (XSS) attacks. 771 * 772 * @since 1.5.0 773 * 774 * @param string|array $key Either a query variable key, or an associative array of query variables. 775 * @param string $value Optional. Either a query variable value, or a URL to act upon. 776 * @param string $url Optional. A URL to act upon. 777 * @return string New URL query string (unescaped). 778 */ 779 function add_query_arg() { 780 $args = func_get_args(); 781 if ( is_array( $args[0] ) ) { 782 if ( count( $args ) < 2 || false === $args[1] ) 783 $uri = $_SERVER['REQUEST_URI']; 784 else 785 $uri = $args[1]; 786 } else { 787 if ( count( $args ) < 3 || false === $args[2] ) 788 $uri = $_SERVER['REQUEST_URI']; 789 else 790 $uri = $args[2]; 791 } 792 793 if ( $frag = strstr( $uri, '#' ) ) 794 $uri = substr( $uri, 0, -strlen( $frag ) ); 795 else 796 $frag = ''; 797 798 if ( 0 === stripos( $uri, 'http://' ) ) { 799 $protocol = 'http://'; 800 $uri = substr( $uri, 7 ); 801 } elseif ( 0 === stripos( $uri, 'https://' ) ) { 802 $protocol = 'https://'; 803 $uri = substr( $uri, 8 ); 804 } else { 805 $protocol = ''; 806 } 807 808 if ( strpos( $uri, '?' ) !== false ) { 809 list( $base, $query ) = explode( '?', $uri, 2 ); 810 $base .= '?'; 811 } elseif ( $protocol || strpos( $uri, '=' ) === false ) { 812 $base = $uri . '?'; 813 $query = ''; 814 } else { 815 $base = ''; 816 $query = $uri; 817 } 818 819 wp_parse_str( $query, $qs ); 820 $qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string 821 if ( is_array( $args[0] ) ) { 822 foreach ( $args[0] as $k => $v ) { 823 $qs[ $k ] = $v; 824 } 825 } else { 826 $qs[ $args[0] ] = $args[1]; 827 } 828 829 foreach ( $qs as $k => $v ) { 830 if ( $v === false ) 831 unset( $qs[$k] ); 832 } 833 834 $ret = build_query( $qs ); 835 $ret = trim( $ret, '?' ); 836 $ret = preg_replace( '#=(&|$)#', '$1', $ret ); 837 $ret = $protocol . $base . $ret . $frag; 838 $ret = rtrim( $ret, '?' ); 839 return $ret; 840 } 841 842 /** 843 * Removes an item or items from a query string. 844 * 845 * @since 1.5.0 846 * 847 * @param string|array $key Query key or keys to remove. 848 * @param bool|string $query Optional. When false uses the current URL. Default false. 849 * @return string New URL query string. 850 */ 851 function remove_query_arg( $key, $query = false ) { 852 if ( is_array( $key ) ) { // removing multiple keys 853 foreach ( $key as $k ) 854 $query = add_query_arg( $k, false, $query ); 855 return $query; 856 } 857 return add_query_arg( $key, false, $query ); 858 } 859 860 /** 861 * Returns an array of single-use query variable names that can be removed from a URL. 862 * 863 * @since 4.4.0 864 * 865 * @return array An array of parameters to remove from the URL. 866 */ 867 function wp_removable_query_args() { 868 $removable_query_args = array( 869 'activate', 870 'activated', 871 'approved', 872 'deactivate', 873 'deleted', 874 'disabled', 875 'enabled', 876 'error', 877 'hotkeys_highlight_first', 878 'hotkeys_highlight_last', 879 'locked', 880 'message', 881 'same', 882 'saved', 883 'settings-updated', 884 'skipped', 885 'spammed', 886 'trashed', 887 'unspammed', 888 'untrashed', 889 'update', 890 'updated', 891 'wp-post-new-reload', 892 ); 893 894 /** 895 * Filters the list of query variables to remove. 896 * 897 * @since 4.2.0 898 * 899 * @param array $removable_query_args An array of query variables to remove from a URL. 900 */ 901 return apply_filters( 'removable_query_args', $removable_query_args ); 902 } 903 904 /** 905 * Walks the array while sanitizing the contents. 906 * 907 * @since 0.71 908 * 909 * @param array $array Array to walk while sanitizing contents. 910 * @return array Sanitized $array. 911 */ 912 function add_magic_quotes( $array ) { 913 foreach ( (array) $array as $k => $v ) { 914 if ( is_array( $v ) ) { 915 $array[$k] = add_magic_quotes( $v ); 916 } else { 917 $array[$k] = addslashes( $v ); 918 } 919 } 920 return $array; 921 } 922 923 /** 924 * HTTP request for URI to retrieve content. 925 * 926 * @since 1.5.1 927 * 928 * @see wp_safe_remote_get() 929 * 930 * @param string $uri URI/URL of web page to retrieve. 931 * @return false|string HTTP content. False on failure. 932 */ 933 function wp_remote_fopen( $uri ) { 934 $parsed_url = @parse_url( $uri ); 935 936 if ( !$parsed_url || !is_array( $parsed_url ) ) 937 return false; 938 939 $options = array(); 940 $options['timeout'] = 10; 941 942 $response = wp_safe_remote_get( $uri, $options ); 943 944 if ( is_wp_error( $response ) ) 945 return false; 946 947 return wp_remote_retrieve_body( $response ); 948 } 949 950 /** 951 * Set up the WordPress query. 952 * 953 * @since 2.0.0 954 * 955 * @global WP $wp_locale 956 * @global WP_Query $wp_query 957 * @global WP_Query $wp_the_query 958 * 959 * @param string|array $query_vars Default WP_Query arguments. 960 */ 961 function wp( $query_vars = '' ) { 962 global $wp, $wp_query, $wp_the_query; 963 $wp->main( $query_vars ); 964 965 if ( !isset($wp_the_query) ) 966 $wp_the_query = $wp_query; 967 } 968 969 /** 970 * Retrieve the description for the HTTP status. 971 * 972 * @since 2.3.0 973 * 974 * @global array $wp_header_to_desc 975 * 976 * @param int $code HTTP status code. 977 * @return string Empty string if not found, or description if found. 978 */ 979 function get_status_header_desc( $code ) { 980 global $wp_header_to_desc; 981 982 $code = absint( $code ); 983 984 if ( !isset( $wp_header_to_desc ) ) { 985 $wp_header_to_desc = array( 986 100 => 'Continue', 987 101 => 'Switching Protocols', 988 102 => 'Processing', 989 990 200 => 'OK', 991 201 => 'Created', 992 202 => 'Accepted', 993 203 => 'Non-Authoritative Information', 994 204 => 'No Content', 995 205 => 'Reset Content', 996 206 => 'Partial Content', 997 207 => 'Multi-Status', 998 226 => 'IM Used', 999 1000 300 => 'Multiple Choices',1001 301 => 'Moved Permanently',1002 302 => 'Found',1003 303 => 'See Other',1004 304 => 'Not Modified',1005 305 => 'Use Proxy',1006 306 => 'Reserved',1007 307 => 'Temporary Redirect',1008 308 => 'Permanent Redirect',1009 1010 400 => 'Bad Request',1011 401 => 'Unauthorized',1012 402 => 'Payment Required',1013 403 => 'Forbidden',1014 404 => 'Not Found',1015 405 => 'Method Not Allowed',1016 406 => 'Not Acceptable',1017 407 => 'Proxy Authentication Required',1018 408 => 'Request Timeout',1019 409 => 'Conflict',1020 410 => 'Gone',1021 411 => 'Length Required',1022 412 => 'Precondition Failed',1023 413 => 'Request Entity Too Large',1024 414 => 'Request-URI Too Long',1025 415 => 'Unsupported Media Type',1026 416 => 'Requested Range Not Satisfiable',1027 417 => 'Expectation Failed',1028 418 => 'I\'m a teapot',1029 421 => 'Misdirected Request',1030 422 => 'Unprocessable Entity',1031 423 => 'Locked',1032 424 => 'Failed Dependency',1033 426 => 'Upgrade Required',1034 428 => 'Precondition Required',1035 429 => 'Too Many Requests',1036 431 => 'Request Header Fields Too Large',1037 451 => 'Unavailable For Legal Reasons',1038 1039 500 => 'Internal Server Error',1040 501 => 'Not Implemented',1041 502 => 'Bad Gateway',1042 503 => 'Service Unavailable',1043 504 => 'Gateway Timeout',1044 505 => 'HTTP Version Not Supported',1045 506 => 'Variant Also Negotiates',1046 507 => 'Insufficient Storage',1047 510 => 'Not Extended',1048 511 => 'Network Authentication Required',1049 );1050 }1051 1052 if ( isset( $wp_header_to_desc[$code] ) )1053 return $wp_header_to_desc[$code];1054 else1055 return '';1056 }1057 1058 /**1059 * Set HTTP status header.1060 *1061 * @since 2.0.01062 * @since 4.4.0 Added the `$description` parameter.1063 *1064 * @see get_status_header_desc()1065 *1066 * @param int $code HTTP status code.1067 * @param string $description Optional. A custom description for the HTTP status.1068 */1069 function status_header( $code, $description = '' ) {1070 if ( ! $description ) {1071 $description = get_status_header_desc( $code );1072 }1073 1074 if ( empty( $description ) ) {1075 return;1076 }1077 1078 $protocol = wp_get_server_protocol();1079 $status_header = "$protocol $code $description";1080 if ( function_exists( 'apply_filters' ) )1081 1082 /**1083 * Filters an HTTP status header.1084 *1085 * @since 2.2.01086 *1087 * @param string $status_header HTTP status header.1088 * @param int $code HTTP status code.1089 * @param string $description Description for the status code.1090 * @param string $protocol Server protocol.1091 */1092 $status_header = apply_filters( 'status_header', $status_header, $code, $description, $protocol );1093 1094 @header( $status_header, true, $code );1095 }1096 1097 /**1098 * Get the header information to prevent caching.1099 *1100 * The several different headers cover the different ways cache prevention1101 * is handled by different browsers1102 *1103 * @since 2.8.01104 *1105 * @return array The associative array of header names and field values.1106 */1107 function wp_get_nocache_headers() {1108 $headers = array(1109 'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',1110 'Cache-Control' => 'no-cache, must-revalidate, max-age=0',1111 );1112 1113 if ( function_exists('apply_filters') ) {1114 /**1115 * Filters the cache-controlling headers.1116 *1117 * @since 2.8.01118 *1119 * @see wp_get_nocache_headers()1120 *1121 * @param array $headers {1122 * Header names and field values.1123 *1124 * @type string $Expires Expires header.1125 * @type string $Cache-Control Cache-Control header.1126 * }1127 */1128 $headers = (array) apply_filters( 'nocache_headers', $headers );1129 }1130 $headers['Last-Modified'] = false;1131 return $headers;1132 }1133 1134 /**1135 * Set the headers to prevent caching for the different browsers.1136 *1137 * Different browsers support different nocache headers, so several1138 * headers must be sent so that all of them get the point that no1139 * caching should occur.1140 *1141 * @since 2.0.01142 *1143 * @see wp_get_nocache_headers()1144 */1145 function nocache_headers() {1146 $headers = wp_get_nocache_headers();1147 1148 unset( $headers['Last-Modified'] );1149 1150 // In PHP 5.3+, make sure we are not sending a Last-Modified header.1151 if ( function_exists( 'header_remove' ) ) {1152 @header_remove( 'Last-Modified' );1153 } else {1154 // In PHP 5.2, send an empty Last-Modified header, but only as a1155 // last resort to override a header already sent. #WP230211156 foreach ( headers_list() as $header ) {1157 if ( 0 === stripos( $header, 'Last-Modified' ) ) {1158 $headers['Last-Modified'] = '';1159 break;1160 }1161 }1162 }1163 1164 foreach ( $headers as $name => $field_value )1165 @header("{$name}: {$field_value}");1166 }1167 1168 /**1169 * Set the headers for caching for 10 days with JavaScript content type.1170 *1171 * @since 2.1.01172 */1173 function cache_javascript_headers() {1174 $expiresOffset = 10 * DAY_IN_SECONDS;1175 1176 header( "Content-Type: text/javascript; charset=" . get_bloginfo( 'charset' ) );1177 header( "Vary: Accept-Encoding" ); // Handle proxies1178 header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $expiresOffset ) . " GMT" );1179 }1180 1181 /**1182 * Retrieve the number of database queries during the WordPress execution.1183 *1184 * @since 2.0.01185 *1186 * @global wpdb $wpdb WordPress database abstraction object.1187 *1188 * @return int Number of database queries.1189 */1190 function get_num_queries() {1191 global $wpdb;1192 return $wpdb->num_queries;1193 }1194 1195 /**1196 * Whether input is yes or no.1197 *1198 * Must be 'y' to be true.1199 *1200 * @since 1.0.01201 *1202 * @param string $yn Character string containing either 'y' (yes) or 'n' (no).1203 * @return bool True if yes, false on anything else.1204 */1205 function bool_from_yn( $yn ) {1206 return ( strtolower( $yn ) == 'y' );1207 }1208 1209 /**1210 * Load the feed template from the use of an action hook.1211 *1212 * If the feed action does not have a hook, then the function will die with a1213 * message telling the visitor that the feed is not valid.1214 *1215 * It is better to only have one hook for each feed.1216 *1217 * @since 2.1.01218 *1219 * @global WP_Query $wp_query Used to tell if the use a comment feed.1220 */1221 function do_feed() {1222 global $wp_query;1223 1224 $feed = get_query_var( 'feed' );1225 1226 // Remove the pad, if present.1227 $feed = preg_replace( '/^_+/', '', $feed );1228 1229 if ( $feed == '' || $feed == 'feed' )1230 $feed = get_default_feed();1231 1232 if ( ! has_action( "do_feed_{$feed}" ) ) {1233 wp_die( __( 'ERROR: This is not a valid feed template.' ), '', array( 'response' => 404 ) );1234 }1235 1236 /**1237 * Fires once the given feed is loaded.1238 *1239 * The dynamic portion of the hook name, `$feed`, refers to the feed template name.1240 * Possible values include: 'rdf', 'rss', 'rss2', and 'atom'.1241 *1242 * @since 2.1.01243 * @since 4.4.0 The `$feed` parameter was added.1244 *1245 * @param bool $is_comment_feed Whether the feed is a comment feed.1246 * @param string $feed The feed name.1247 */1248 do_action( "do_feed_{$feed}", $wp_query->is_comment_feed, $feed );1249 }1250 1251 /**1252 * Load the RDF RSS 0.91 Feed template.1253 *1254 * @since 2.1.01255 *1256 * @see load_template()1257 */1258 function do_feed_rdf() {1259 load_template( ABSPATH . WPINC . '/feed-rdf.php' );1260 }1261 1262 /**1263 * Load the RSS 1.0 Feed Template.1264 *1265 * @since 2.1.01266 *1267 * @see load_template()1268 */1269 function do_feed_rss() {1270 load_template( ABSPATH . WPINC . '/feed-rss.php' );1271 }1272 1273 /**1274 * Load either the RSS2 comment feed or the RSS2 posts feed.1275 *1276 * @since 2.1.01277 *1278 * @see load_template()1279 *1280 * @param bool $for_comments True for the comment feed, false for normal feed.1281 */1282 function do_feed_rss2( $for_comments ) {1283 if ( $for_comments )1284 load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' );1285 else1286 load_template( ABSPATH . WPINC . '/feed-rss2.php' );1287 }1288 1289 /**1290 * Load either Atom comment feed or Atom posts feed.1291 *1292 * @since 2.1.01293 *1294 * @see load_template()1295 *1296 * @param bool $for_comments True for the comment feed, false for normal feed.1297 */1298 function do_feed_atom( $for_comments ) {1299 if ($for_comments)1300 load_template( ABSPATH . WPINC . '/feed-atom-comments.php');1301 else1302 load_template( ABSPATH . WPINC . '/feed-atom.php' );1303 }1304 1305 /**1306 * Display the robots.txt file content.1307 *1308 * The echo content should be with usage of the permalinks or for creating the1309 * robots.txt file.1310 *1311 * @since 2.1.01312 */1313 function do_robots() {1314 header( 'Content-Type: text/plain; charset=utf-8' );1315 1316 /**1317 * Fires when displaying the robots.txt file.1318 *1319 * @since 2.1.01320 */1321 do_action( 'do_robotstxt' );1322 1323 $output = "User-agent: *\n";1324 $public = get_option( 'blog_public' );1325 if ( '0' == $public ) {1326 $output .= "Disallow: /\n";1327 } else {1328 $site_url = parse_url( site_url() );1329 $path = ( !empty( $site_url['path'] ) ) ? $site_url['path'] : '';1330 $output .= "Disallow: $path/wp-admin/\n";1331 $output .= "Allow: $path/wp-admin/admin-ajax.php\n";1332 }1333 1334 /**1335 * Filters the robots.txt output.1336 *1337 * @since 3.0.01338 *1339 * @param string $output Robots.txt output.1340 * @param bool $public Whether the site is considered "public".1341 */1342 echo apply_filters( 'robots_txt', $output, $public );1343 }1344 1345 /**1346 * Test whether WordPress is already installed.1347 *1348 * The cache will be checked first. If you have a cache plugin, which saves1349 * the cache values, then this will work. If you use the default WordPress1350 * cache, and the database goes away, then you might have problems.1351 *1352 * Checks for the 'siteurl' option for whether WordPress is installed.1353 *1354 * @since 2.1.01355 *1356 * @global wpdb $wpdb WordPress database abstraction object.1357 *1358 * @return bool Whether the site is already installed.1359 */1360 function is_blog_installed() {1361 global $wpdb;1362 1363 /*1364 * Check cache first. If options table goes away and we have true1365 * cached, oh well.1366 */1367 if ( wp_cache_get( 'is_blog_installed' ) )1368 return true;1369 1370 $suppress = $wpdb->suppress_errors();1371 if ( ! wp_installing() ) {1372 $alloptions = wp_load_alloptions();1373 }1374 // If siteurl is not set to autoload, check it specifically1375 if ( !isset( $alloptions['siteurl'] ) )1376 $installed = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'" );1377 else1378 $installed = $alloptions['siteurl'];1379 $wpdb->suppress_errors( $suppress );1380 1381 $installed = !empty( $installed );1382 wp_cache_set( 'is_blog_installed', $installed );1383 1384 if ( $installed )1385 return true;1386 1387 // If visiting repair.php, return true and let it take over.1388 if ( defined( 'WP_REPAIRING' ) )1389 return true;1390 1391 $suppress = $wpdb->suppress_errors();1392 1393 /*1394 * Loop over the WP tables. If none exist, then scratch install is allowed.1395 * If one or more exist, suggest table repair since we got here because the1396 * options table could not be accessed.1397 */1398 $wp_tables = $wpdb->tables();1399 foreach ( $wp_tables as $table ) {1400 // The existence of custom user tables shouldn't suggest an insane state or prevent a clean install.1401 if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table )1402 continue;1403 if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table )1404 continue;1405 1406 if ( ! $wpdb->get_results( "DESCRIBE $table;" ) )1407 continue;1408 1409 // One or more tables exist. We are insane.1410 1411 wp_load_translations_early();1412 1413 // Die with a DB error.1414 $wpdb->error = sprintf( __( 'One or more database tables are unavailable. The database may need to be repaired.' ), 'maint/repair.php?referrer=is_blog_installed' );1415 dead_db();1416 }1417 1418 $wpdb->suppress_errors( $suppress );1419 1420 wp_cache_set( 'is_blog_installed', false );1421 1422 return false;1423 }1424 1425 /**1426 * Retrieve URL with nonce added to URL query.1427 *1428 * @since 2.0.41429 *1430 * @param string $actionurl URL to add nonce action.1431 * @param int|string $action Optional. Nonce action name. Default -1.1432 * @param string $name Optional. Nonce name. Default '_wpnonce'.1433 * @return string Escaped URL with nonce action added.1434 */1435 function wp_nonce_url( $actionurl, $action = -1, $name = '_wpnonce' ) {1436 $actionurl = str_replace( '&', '&', $actionurl );1437 return esc_html( add_query_arg( $name, wp_create_nonce( $action ), $actionurl ) );1438 }1439 1440 /**1441 * Retrieve or display nonce hidden field for forms.1442 *1443 * The nonce field is used to validate that the contents of the form came from1444 * the location on the current site and not somewhere else. The nonce does not1445 * offer absolute protection, but should protect against most cases. It is very1446 * important to use nonce field in forms.1447 *1448 * The $action and $name are optional, but if you want to have better security,1449 * it is strongly suggested to set those two parameters. It is easier to just1450 * call the function without any parameters, because validation of the nonce1451 * doesn't require any parameters, but since crackers know what the default is1452 * it won't be difficult for them to find a way around your nonce and cause1453 * damage.1454 *1455 * The input name will be whatever $name value you gave. The input value will be1456 * the nonce creation value.1457 *1458 * @since 2.0.41459 *1460 * @param int|string $action Optional. Action name. Default -1.1461 * @param string $name Optional. Nonce name. Default '_wpnonce'.1462 * @param bool $referer Optional. Whether to set the referer field for validation. Default true.1463 * @param bool $echo Optional. Whether to display or return hidden form field. Default true.1464 * @return string Nonce field HTML markup.1465 */1466 function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true , $echo = true ) {1467 $name = esc_attr( $name );1468 $nonce_field = '';1469 1470 if ( $referer )1471 $nonce_field .= wp_referer_field( false );1472 1473 if ( $echo )1474 echo $nonce_field;1475 1476 return $nonce_field;1477 }1478 1479 /**1480 * Retrieve or display referer hidden field for forms.1481 *1482 * The referer link is the current Request URI from the server super global. The1483 * input name is '_wp_http_referer', in case you wanted to check manually.1484 *1485 * @since 2.0.41486 *1487 * @param bool $echo Optional. Whether to echo or return the referer field. Default true.1488 * @return string Referer field HTML markup.1489 */1490 function wp_referer_field( $echo = true ) {1491 $referer_field = '';1492 1493 if ( $echo )1494 echo $referer_field;1495 return $referer_field;1496 }1497 1498 /**1499 * Retrieve or display original referer hidden field for forms.1500 *1501 * The input name is '_wp_original_http_referer' and will be either the same1502 * value of wp_referer_field(), if that was posted already or it will be the1503 * current page, if it doesn't exist.1504 *1505 * @since 2.0.41506 *1507 * @param bool $echo Optional. Whether to echo the original http referer. Default true.1508 * @param string $jump_back_to Optional. Can be 'previous' or page you want to jump back to.1509 * Default 'current'.1510 * @return string Original referer field.1511 */1512 function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) {1513 if ( ! $ref = wp_get_original_referer() ) {1514 $ref = 'previous' == $jump_back_to ? wp_get_referer() : wp_unslash( $_SERVER['REQUEST_URI'] );1515 }1516 $orig_referer_field = '';1517 if ( $echo )1518 echo $orig_referer_field;1519 return $orig_referer_field;1520 }1521 1522 /**1523 * Retrieve referer from '_wp_http_referer' or HTTP referer.1524 *1525 * If it's the same as the current request URL, will return false.1526 *1527 * @since 2.0.41528 *1529 * @return false|string False on failure. Referer URL on success.1530 */1531 function wp_get_referer() {1532 if ( ! function_exists( 'wp_validate_redirect' ) ) {1533 return false;1534 }1535 1536 $ref = wp_get_raw_referer();1537 1538 if ( $ref && $ref !== wp_unslash( $_SERVER['REQUEST_URI'] ) && $ref !== home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) ) {1539 return wp_validate_redirect( $ref, false );1540 }1541 1542 return false;1543 }1544 1545 /**1546 * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.1547 *1548 * Do not use for redirects, use wp_get_referer() instead.1549 *1550 * @since 4.5.01551 *1552 * @return string|false Referer URL on success, false on failure.1553 */1554 function wp_get_raw_referer() {1555 if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {1556 return wp_unslash( $_REQUEST['_wp_http_referer'] );1557 } else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {1558 return wp_unslash( $_SERVER['HTTP_REFERER'] );1559 }1560 1561 return false;1562 }1563 1564 /**1565 * Retrieve original referer that was posted, if it exists.1566 *1567 * @since 2.0.41568 *1569 * @return string|false False if no original referer or original referer if set.1570 */1571 function wp_get_original_referer() {1572 if ( ! empty( $_REQUEST['_wp_original_http_referer'] ) && function_exists( 'wp_validate_redirect' ) )1573 return wp_validate_redirect( wp_unslash( $_REQUEST['_wp_original_http_referer'] ), false );1574 return false;1575 }1576 1577 /**1578 * Recursive directory creation based on full path.1579 *1580 * Will attempt to set permissions on folders.1581 *1582 * @since 2.0.11583 *1584 * @param string $target Full path to attempt to create.1585 * @return bool Whether the path was created. True if path already exists.1586 */1587 function wp_mkdir_p( $target ) {1588 $wrapper = null;1589 1590 // Strip the protocol.1591 if ( wp_is_stream( $target ) ) {1592 list( $wrapper, $target ) = explode( '://', $target, 2 );1593 }1594 1595 // From php.net/mkdir user contributed notes.1596 $target = str_replace( '//', '/', $target );1597 1598 // Put the wrapper back on the target.1599 if ( $wrapper !== null ) {1600 $target = $wrapper . '://' . $target;1601 }1602 1603 /*1604 * Safe mode fails with a trailing slash under certain PHP versions.1605 * Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.1606 */1607 $target = rtrim($target, '/');1608 if ( empty($target) )1609 $target = '/';1610 1611 if ( file_exists( $target ) )1612 return @is_dir( $target );1613 1614 // We need to find the permissions of the parent folder that exists and inherit that.1615 $target_parent = dirname( $target );1616 while ( '.' != $target_parent && ! is_dir( $target_parent ) ) {1617 $target_parent = dirname( $target_parent );1618 }1619 1620 // Get the permission bits.1621 if ( $stat = @stat( $target_parent ) ) {1622 $dir_perms = $stat['mode'] & 0007777;1623 } else {1624 $dir_perms = 0777;1625 }1626 1627 if ( @mkdir( $target, $dir_perms, true ) ) {1628 1629 /*1630 * If a umask is set that modifies $dir_perms, we'll have to re-set1631 * the $dir_perms correctly with chmod()1632 */1633 if ( $dir_perms != ( $dir_perms & ~umask() ) ) {1634 $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );1635 for ( $i = 1, $c = count( $folder_parts ); $i __( 'Empty filename' ) );2122 2123 $wp_filetype = wp_check_filetype( $name );2124 if ( ! $wp_filetype['ext'] && ! current_user_can( 'unfiltered_upload' ) )2125 return array( 'error' => __( 'Invalid file type' ) );2126 2127 $upload = wp_upload_dir( $time );2128 2129 if ( $upload['error'] !== false )2130 return $upload;2131 2132 /**2133 * Filters whether to treat the upload bits as an error.2134 *2135 * Passing a non-array to the filter will effectively short-circuit preparing2136 * the upload bits, returning that value instead.2137 *2138 * @since 3.0.02139 *2140 * @param mixed $upload_bits_error An array of upload bits data, or a non-array error to return.2141 */2142 $upload_bits_error = apply_filters( 'wp_upload_bits', array( 'name' => $name, 'bits' => $bits, 'time' => $time ) );2143 if ( !is_array( $upload_bits_error ) ) {2144 $upload[ 'error' ] = $upload_bits_error;2145 return $upload;2146 }2147 2148 $filename = wp_unique_filename( $upload['path'], $name );2149 2150 $new_file = $upload['path'] . "/$filename";2151 if ( ! wp_mkdir_p( dirname( $new_file ) ) ) {2152 if ( 0 === strpos( $upload['basedir'], ABSPATH ) )2153 $error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir'];2154 else2155 $error_path = basename( $upload['basedir'] ) . $upload['subdir'];2156 2157 $message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), $error_path );2158 return array( 'error' => $message );2159 }2160 2161 $ifp = @ fopen( $new_file, 'wb' );2162 if ( ! $ifp )2163 return array( 'error' => sprintf( __( 'Could not write file %s' ), $new_file ) );2164 2165 @fwrite( $ifp, $bits );2166 fclose( $ifp );2167 clearstatcache();2168 2169 // Set correct file permissions2170 $stat = @ stat( dirname( $new_file ) );2171 $perms = $stat['mode'] & 0007777;2172 $perms = $perms & 0000666;2173 @ chmod( $new_file, $perms );2174 clearstatcache();2175 2176 // Compute the URL2177 $url = $upload['url'] . "/$filename";2178 2179 /** This filter is documented in wp-admin/includes/file.php */2180 return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $wp_filetype['type'], 'error' => false ), 'sideload' );2181 }2182 2183 /**2184 * Retrieve the file type based on the extension name.2185 *2186 * @since 2.5.02187 *2188 * @param string $ext The extension to search.2189 * @return string|void The file type, example: audio, video, document, spreadsheet, etc.2190 */2191 function wp_ext2type( $ext ) {2192 $ext = strtolower( $ext );2193 2194 $ext2type = wp_get_ext_types();2195 foreach ( $ext2type as $type => $exts )2196 if ( in_array( $ext, $exts ) )2197 return $type;2198 }2199 2200 /**2201 * Retrieve the file type from the file name.2202 *2203 * You can optionally define the mime array, if needed.2204 *2205 * @since 2.0.42206 *2207 * @param string $filename File name or path.2208 * @param array $mimes Optional. Key is the file extension with value as the mime type.2209 * @return array Values with extension first and mime type.2210 */2211 function wp_check_filetype( $filename, $mimes = null ) {2212 if ( empty($mimes) )2213 $mimes = get_allowed_mime_types();2214 $type = false;2215 $ext = false;2216 2217 foreach ( $mimes as $ext_preg => $mime_match ) {2218 $ext_preg = '!\.(' . $ext_preg . ')$!i';2219 if ( preg_match( $ext_preg, $filename, $ext_matches ) ) {2220 $type = $mime_match;2221 $ext = $ext_matches[1];2222 break;2223 }2224 }2225 2226 return compact( 'ext', 'type' );2227 }2228 2229 /**2230 * Attempt to determine the real file type of a file.2231 *2232 * If unable to, the file name extension will be used to determine type.2233 *2234 * If it's determined that the extension does not match the file's real type,2235 * then the "proper_filename" value will be set with a proper filename and extension.2236 *2237 * Currently this function only supports validating images known to getimagesize().2238 *2239 * @since 3.0.02240 *2241 * @param string $file Full path to the file.2242 * @param string $filename The name of the file (may differ from $file due to $file being2243 * in a tmp directory).2244 * @param array $mimes Optional. Key is the file extension with value as the mime type.2245 * @return array Values for the extension, MIME, and either a corrected filename or false2246 * if original $filename is valid.2247 */2248 function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {2249 $proper_filename = false;2250 2251 // Do basic extension validation and MIME mapping2252 $wp_filetype = wp_check_filetype( $filename, $mimes );2253 $ext = $wp_filetype['ext'];2254 $type = $wp_filetype['type'];2255 2256 // We can't do any further validation without a file to work with2257 if ( ! file_exists( $file ) ) {2258 return compact( 'ext', 'type', 'proper_filename' );2259 }2260 2261 // We're able to validate images using GD2262 if ( $type && 0 === strpos( $type, 'image/' ) && function_exists('getimagesize') ) {2263 2264 // Attempt to figure out what type of image it actually is2265 $imgstats = @getimagesize( $file );2266 2267 // If getimagesize() knows what kind of image it really is and if the real MIME doesn't match the claimed MIME2268 if ( !empty($imgstats['mime']) && $imgstats['mime'] != $type ) {2269 /**2270 * Filters the list mapping image mime types to their respective extensions.2271 *2272 * @since 3.0.02273 *2274 * @param array $mime_to_ext Array of image mime types and their matching extensions.2275 */2276 $mime_to_ext = apply_filters( 'getimagesize_mimes_to_exts', array(2277 'image/jpeg' => 'jpg',2278 'image/png' => 'png',2279 'image/gif' => 'gif',2280 'image/bmp' => 'bmp',2281 'image/tiff' => 'tif',2282 ) );2283 2284 // Replace whatever is after the last period in the filename with the correct extension2285 if ( ! empty( $mime_to_ext[ $imgstats['mime'] ] ) ) {2286 $filename_parts = explode( '.', $filename );2287 array_pop( $filename_parts );2288 $filename_parts[] = $mime_to_ext[ $imgstats['mime'] ];2289 $new_filename = implode( '.', $filename_parts );2290 2291 if ( $new_filename != $filename ) {2292 $proper_filename = $new_filename; // Mark that it changed2293 }2294 // Redefine the extension / MIME2295 $wp_filetype = wp_check_filetype( $new_filename, $mimes );2296 $ext = $wp_filetype['ext'];2297 $type = $wp_filetype['type'];2298 }2299 }2300 }2301 2302 /**2303 * Filters the "real" file type of the given file.2304 *2305 * @since 3.0.02306 *2307 * @param array $wp_check_filetype_and_ext File data array containing 'ext', 'type', and2308 * 'proper_filename' keys.2309 * @param string $file Full path to the file.2310 * @param string $filename The name of the file (may differ from $file due to2311 * $file being in a tmp directory).2312 * @param array $mimes Key is the file extension with value as the mime type.2313 */2314 return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );2315 }2316 2317 /**2318 * Retrieve list of mime types and file extensions.2319 *2320 * @since 3.5.02321 * @since 4.2.0 Support was added for GIMP (xcf) files.2322 *2323 * @return array Array of mime types keyed by the file extension regex corresponding to those types.2324 */2325 function wp_get_mime_types() {2326 /**2327 * Filters the list of mime types and file extensions.2328 *2329 * This filter should be used to add, not remove, mime types. To remove2330 * mime types, use the {@see 'upload_mimes'} filter.2331 *2332 * @since 3.5.02333 *2334 * @param array $wp_get_mime_types Mime types keyed by the file extension regex2335 * corresponding to those types.2336 */2337 return apply_filters( 'mime_types', array(2338 // Image formats.2339 'jpg|jpeg|jpe' => 'image/jpeg',2340 'gif' => 'image/gif',2341 'png' => 'image/png',2342 'bmp' => 'image/bmp',2343 'tiff|tif' => 'image/tiff',2344 'ico' => 'image/x-icon',2345 // Video formats.2346 'asf|asx' => 'video/x-ms-asf',2347 'wmv' => 'video/x-ms-wmv',2348 'wmx' => 'video/x-ms-wmx',2349 'wm' => 'video/x-ms-wm',2350 'avi' => 'video/avi',2351 'divx' => 'video/divx',2352 'flv' => 'video/x-flv',2353 'mov|qt' => 'video/quicktime',2354 'mpeg|mpg|mpe' => 'video/mpeg',2355 'mp4|m4v' => 'video/mp4',2356 'ogv' => 'video/ogg',2357 'webm' => 'video/webm',2358 'mkv' => 'video/x-matroska',2359 '3gp|3gpp' => 'video/3gpp', // Can also be audio2360 '3g2|3gp2' => 'video/3gpp2', // Can also be audio2361 // Text formats.2362 'txt|asc|c|cc|h|srt' => 'text/plain',2363 'csv' => 'text/csv',2364 'tsv' => 'text/tab-separated-values',2365 'ics' => 'text/calendar',2366 'rtx' => 'text/richtext',2367 'css' => 'text/css',2368 'htm|html' => 'text/html',2369 'vtt' => 'text/vtt',2370 'dfxp' => 'application/ttaf+xml',2371 // Audio formats.2372 'mp3|m4a|m4b' => 'audio/mpeg',2373 'ra|ram' => 'audio/x-realaudio',2374 'wav' => 'audio/wav',2375 'ogg|oga' => 'audio/ogg',2376 'mid|midi' => 'audio/midi',2377 'wma' => 'audio/x-ms-wma',2378 'wax' => 'audio/x-ms-wax',2379 'mka' => 'audio/x-matroska',2380 // Misc application formats.2381 'rtf' => 'application/rtf',2382 'js' => 'application/javascript',2383 'pdf' => 'application/pdf',2384 'swf' => 'application/x-shockwave-flash',2385 'class' => 'application/java',2386 'tar' => 'application/x-tar',2387 'zip' => 'application/zip',2388 'gz|gzip' => 'application/x-gzip',2389 'rar' => 'application/rar',2390 '7z' => 'application/x-7z-compressed',2391 'exe' => 'application/x-msdownload',2392 'psd' => 'application/octet-stream',2393 'xcf' => 'application/octet-stream',2394 // MS Office formats.2395 'doc' => 'application/msword',2396 'pot|pps|ppt' => 'application/vnd.ms-powerpoint',2397 'wri' => 'application/vnd.ms-write',2398 'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',2399 'mdb' => 'application/vnd.ms-access',2400 'mpp' => 'application/vnd.ms-project',2401 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',2402 'docm' => 'application/vnd.ms-word.document.macroEnabled.12',2403 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',2404 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',2405 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',2406 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',2407 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',2408 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',2409 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',2410 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',2411 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',2412 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',2413 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',2414 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',2415 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',2416 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',2417 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',2418 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',2419 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',2420 'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',2421 'oxps' => 'application/oxps',2422 'xps' => 'application/vnd.ms-xpsdocument',2423 // OpenOffice formats.2424 'odt' => 'application/vnd.oasis.opendocument.text',2425 'odp' => 'application/vnd.oasis.opendocument.presentation',2426 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',2427 'odg' => 'application/vnd.oasis.opendocument.graphics',2428 'odc' => 'application/vnd.oasis.opendocument.chart',2429 'odb' => 'application/vnd.oasis.opendocument.database',2430 'odf' => 'application/vnd.oasis.opendocument.formula',2431 // WordPerfect formats.2432 'wp|wpd' => 'application/wordperfect',2433 // iWork formats.2434 'key' => 'application/vnd.apple.keynote',2435 'numbers' => 'application/vnd.apple.numbers',2436 'pages' => 'application/vnd.apple.pages',2437 ) );2438 }2439 2440 /**2441 * Retrieves the list of common file extensions and their types.2442 *2443 * @since 4.6.02444 *2445 * @return array Array of file extensions types keyed by the type of file.2446 */2447 function wp_get_ext_types() {2448 2449 /**2450 * Filters file type based on the extension name.2451 *2452 * @since 2.5.02453 *2454 * @see wp_ext2type()2455 *2456 * @param array $ext2type Multi-dimensional array with extensions for a default set2457 * of file types.2458 */2459 return apply_filters( 'ext2type', array(2460 'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico' ),2461 'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),2462 'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),2463 'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),2464 'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),2465 'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),2466 'text' => array( 'asc', 'csv', 'tsv', 'txt' ),2467 'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),2468 'code' => array( 'css', 'htm', 'html', 'php', 'js' ),2469 ) );2470 }2471 2472 /**2473 * Retrieve list of allowed mime types and file extensions.2474 *2475 * @since 2.8.62476 *2477 * @param int|WP_User $user Optional. User to check. Defaults to current user.2478 * @return array Array of mime types keyed by the file extension regex corresponding2479 * to those types.2480 */2481 function get_allowed_mime_types( $user = null ) {2482 $t = wp_get_mime_types();2483 2484 unset( $t['swf'], $t['exe'] );2485 if ( function_exists( 'current_user_can' ) )2486 $unfiltered = $user ? user_can( $user, 'unfiltered_html' ) : current_user_can( 'unfiltered_html' );2487 2488 if ( empty( $unfiltered ) )2489 unset( $t['htm|html'] );2490 2491 /**2492 * Filters list of allowed mime types and file extensions.2493 *2494 * @since 2.0.02495 *2496 * @param array $t Mime types keyed by the file extension regex corresponding to2497 * those types. 'swf' and 'exe' removed from full list. 'htm|html' also2498 * removed depending on '$user' capabilities.2499 * @param int|WP_User|null $user User ID, User object or null if not provided (indicates current user).2500 */2501 return apply_filters( 'upload_mimes', $t, $user );2502 }2503 2504 /**2505 * Display "Are You Sure" message to confirm the action being taken.2506 *2507 * If the action has the nonce explain message, then it will be displayed2508 * along with the "Are you sure?" message.2509 *2510 * @since 2.0.42511 *2512 * @param string $action The nonce action.2513 */2514 function wp_nonce_ays( $action ) {2515 if ( 'log-out' == $action ) {2516 $html = sprintf( __( 'You are attempting to log out of %s' ), get_bloginfo( 'name' ) ) . '

';2517 $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';2518 $html .= sprintf( __( "Do you really want to log out?"), wp_logout_url( $redirect_to ) );2519 } else {2520 $html = __( 'Are you sure you want to do this?' );2521 if ( wp_get_referer() )2522 $html .= "

" . __( 'Please try again.' ) . "";2523 }2524 2525 wp_die( $html, __( 'WordPress Failure Notice' ), 403 );2526 }2527 2528 /**2529 * Kill WordPress execution and display HTML message with error message.2530 *2531 * This function complements the `die()` PHP function. The difference is that2532 * HTML will be displayed to the user. It is recommended to use this function2533 * only when the execution should not continue any further. It is not recommended2534 * to call this function very often, and try to handle as many errors as possible2535 * silently or more gracefully.2536 *2537 * As a shorthand, the desired HTTP response code may be passed as an integer to2538 * the `$title` parameter (the default title would apply) or the `$args` parameter.2539 *2540 * @since 2.0.42541 * @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept2542 * an integer to be used as the response code.2543 *2544 * @param string|WP_Error $message Optional. Error message. If this is a WP_Error object,2545 * the error's messages are used. Default empty.2546 * @param string|int $title Optional. Error title. If `$message` is a `WP_Error` object,2547 * error data with the key 'title' may be used to specify the title.2548 * If `$title` is an integer, then it is treated as the response2549 * code. Default empty.2550 * @param string|array|int $args {2551 * Optional. Arguments to control behavior. If `$args` is an integer, then it is treated2552 * as the response code. Default empty array.2553 *2554 * @type int $response The HTTP response code. Default 500.2555 * @type bool $back_link Whether to include a link to go back. Default false.2556 * @type string $text_direction The text direction. This is only useful internally, when WordPress2557 * is still loading and the site's locale is not set up yet. Accepts 'rtl'.2558 * Default is the value of is_rtl().2559 * }2560 */2561 function wp_die( $message = '', $title = '', $args = array() ) {2562 2563 if ( is_int( $args ) ) {2564 $args = array( 'response' => $args );2565 } elseif ( is_int( $title ) ) {2566 $args = array( 'response' => $title );2567 $title = '';2568 }2569 2570 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {2571 /**2572 * Filters the callback for killing WordPress execution for Ajax requests.2573 *2574 * @since 3.4.02575 *2576 * @param callable $function Callback function name.2577 */2578 $function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );2579 } elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {2580 /**2581 * Filters the callback for killing WordPress execution for XML-RPC requests.2582 *2583 * @since 3.4.02584 *2585 * @param callable $function Callback function name.2586 */2587 $function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );2588 } else {2589 /**2590 * Filters the callback for killing WordPress execution for all non-Ajax, non-XML-RPC requests.2591 *2592 * @since 3.0.02593 *2594 * @param callable $function Callback function name.2595 */2596 $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler' );2597 }2598 2599 call_user_func( $function, $message, $title, $args );2600 }2601 2602 /**2603 * Kills WordPress execution and display HTML message with error message.2604 *2605 * This is the default handler for wp_die if you want a custom one for your2606 * site then you can overload using the {@see 'wp_die_handler'} filter in wp_die().2607 *2608 * @since 3.0.02609 * @access private2610 *2611 * @param string $message Error message.2612 * @param string $title Optional. Error title. Default empty.2613 * @param string|array $args Optional. Arguments to control behavior. Default empty array.2614 */2615 function _default_wp_die_handler( $message, $title = '', $args = array() ) {2616 $defaults = array( 'response' => 500 );2617 $r = wp_parse_args($args, $defaults);2618 2619 $have_gettext = function_exists('__');2620 2621 if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {2622 if ( empty( $title ) ) {2623 $error_data = $message->get_error_data();2624 if ( is_array( $error_data ) && isset( $error_data['title'] ) )2625 $title = $error_data['title'];2626 }2627 $errors = $message->get_error_messages();2628 switch ( count( $errors ) ) {2629 case 0 :2630 $message = '';2631 break;2632 case 1 :2633 $message = "

{$errors[0]}

";2634 break;2635 default :2636 $message = "

  • \n\t\t
  • " . join( "\n\t\t
  • ", $errors ) . "\n\t

";2637 break;2638 }2639 } elseif ( is_string( $message ) ) {2640 $message = "

$message

";2641 }2642 2643 if ( isset( $r['back_link'] ) && $r['back_link'] ) {2644 $back_text = $have_gettext? __(' Back') : ' Back';2645 $message .= "\n

$back_text

";2646 }2647 2648 if ( ! did_action( 'admin_head' ) ) :2649 if ( !headers_sent() ) {2650 status_header( $r['response'] );2651 nocache_headers();2652 header( 'Content-Type: text/html; charset=utf-8' );2653 }2654 2655 if ( empty($title) )2656 $title = $have_gettext ? __('WordPress Error') : 'WordPress Error';2657 2658 $text_direction = 'ltr';2659 if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] )2660 $text_direction = 'rtl';2661 elseif ( function_exists( 'is_rtl' ) && is_rtl() )2662 $text_direction = 'rtl';2663 ?>2664 2665 2667 500 );2820 2821 $r = wp_parse_args($args, $defaults);2822 2823 if ( $wp_xmlrpc_server ) {2824 $error = new IXR_Error( $r['response'] , $message);2825 $wp_xmlrpc_server->output( $error->getXml() );2826 }2827 die();2828 }2829 2830 /**2831 * Kill WordPress ajax execution.2832 *2833 * This is the handler for wp_die when processing Ajax requests.2834 *2835 * @since 3.4.02836 * @access private2837 *2838 * @param string $message Optional. Response to print. Default empty.2839 */2840 function _ajax_wp_die_handler( $message = '' ) {2841 if ( is_scalar( $message ) )2842 die( (string) $message );2843 die( '0' );2844 }2845 2846 /**2847 * Kill WordPress execution.2848 *2849 * This is the handler for wp_die when processing APP requests.2850 *2851 * @since 3.4.02852 * @access private2853 *2854 * @param string $message Optional. Response to print. Default empty.2855 */2856 function _scalar_wp_die_handler( $message = '' ) {2857 if ( is_scalar( $message ) )2858 die( (string) $message );2859 die();2860 }2861 2862 /**2863 * Encode a variable into JSON, with some sanity checks.2864 *2865 * @since 4.1.02866 *2867 * @param mixed $data Variable (usually an array or object) to encode as JSON.2868 * @param int $options Optional. Options to be passed to json_encode(). Default 0.2869 * @param int $depth Optional. Maximum depth to walk through $data. Must be2870 * greater than 0. Default 512.2871 * @return string|false The JSON encoded string, or false if it cannot be encoded.2872 */2873 function wp_json_encode( $data, $options = 0, $depth = 512 ) {2874 /*2875 * json_encode() has had extra params added over the years.2876 * $options was added in 5.3, and $depth in 5.5.2877 * We need to make sure we call it with the correct arguments.2878 */2879 if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {2880 $args = array( $data, $options, $depth );2881 } elseif ( version_compare( PHP_VERSION, '5.3', '>=' ) ) {2882 $args = array( $data, $options );2883 } else {2884 $args = array( $data );2885 }2886 2887 // Prepare the data for JSON serialization.2888 $args[0] = _wp_json_prepare_data( $data );2889 2890 $json = @call_user_func_array( 'json_encode', $args );2891 2892 // If json_encode() was successful, no need to do more sanity checking.2893 // ... unless we're in an old version of PHP, and json_encode() returned2894 // a string containing 'null'. Then we need to do more sanity checking.2895 if ( false !== $json && ( version_compare( PHP_VERSION, '5.5', '>=' ) || false === strpos( $json, 'null' ) ) ) {2896 return $json;2897 }2898 2899 try {2900 $args[0] = _wp_json_sanity_check( $data, $depth );2901 } catch ( Exception $e ) {2902 return false;2903 }2904 2905 return call_user_func_array( 'json_encode', $args );2906 }2907 2908 /**2909 * Perform sanity checks on data that shall be encoded to JSON.2910 *2911 * @ignore2912 * @since 4.1.02913 * @access private2914 *2915 * @see wp_json_encode()2916 *2917 * @param mixed $data Variable (usually an array or object) to encode as JSON.2918 * @param int $depth Maximum depth to walk through $data. Must be greater than 0.2919 * @return mixed The sanitized data that shall be encoded to JSON.2920 */2921 function _wp_json_sanity_check( $data, $depth ) {2922 if ( $depth < 0 ) {2923 throw new Exception( 'Reached depth limit' );2924 }2925 2926 if ( is_array( $data ) ) {2927 $output = array();2928 foreach ( $data as $id => $el ) {2929 // Don't forget to sanitize the ID!2930 if ( is_string( $id ) ) {2931 $clean_id = _wp_json_convert_string( $id );2932 } else {2933 $clean_id = $id;2934 }2935 2936 // Check the element type, so that we're only recursing if we really have to.2937 if ( is_array( $el ) || is_object( $el ) ) {2938 $output[ $clean_id ] = _wp_json_sanity_check( $el, $depth - 1 );2939 } elseif ( is_string( $el ) ) {2940 $output[ $clean_id ] = _wp_json_convert_string( $el );2941 } else {2942 $output[ $clean_id ] = $el;2943 }2944 }2945 } elseif ( is_object( $data ) ) {2946 $output = new stdClass;2947 foreach ( $data as $id => $el ) {2948 if ( is_string( $id ) ) {2949 $clean_id = _wp_json_convert_string( $id );2950 } else {2951 $clean_id = $id;2952 }2953 2954 if ( is_array( $el ) || is_object( $el ) ) {2955 $output->$clean_id = _wp_json_sanity_check( $el, $depth - 1 );2956 } elseif ( is_string( $el ) ) {2957 $output->$clean_id = _wp_json_convert_string( $el );2958 } else {2959 $output->$clean_id = $el;2960 }2961 }2962 } elseif ( is_string( $data ) ) {2963 return _wp_json_convert_string( $data );2964 } else {2965 return $data;2966 }2967 2968 return $output;2969 }2970 2971 /**2972 * Convert a string to UTF-8, so that it can be safely encoded to JSON.2973 *2974 * @ignore2975 * @since 4.1.02976 * @access private2977 *2978 * @see _wp_json_sanity_check()2979 *2980 * @staticvar bool $use_mb2981 *2982 * @param string $string The string which is to be converted.2983 * @return string The checked string.2984 */2985 function _wp_json_convert_string( $string ) {2986 static $use_mb = null;2987 if ( is_null( $use_mb ) ) {2988 $use_mb = function_exists( 'mb_convert_encoding' );2989 }2990 2991 if ( $use_mb ) {2992 $encoding = mb_detect_encoding( $string, mb_detect_order(), true );2993 if ( $encoding ) {2994 return mb_convert_encoding( $string, 'UTF-8', $encoding );2995 } else {2996 return mb_convert_encoding( $string, 'UTF-8', 'UTF-8' );2997 }2998 } else {2999 return wp_check_invalid_utf8( $string, true );3000 }3001 }3002 3003 /**3004 * Prepares response data to be serialized to JSON.3005 *3006 * This supports the JsonSerializable interface for PHP 5.2-5.3 as well.3007 *3008 * @ignore3009 * @since 4.4.03010 * @access private3011 *3012 * @param mixed $data Native representation.3013 * @return bool|int|float|null|string|array Data ready for `json_encode()`.3014 */3015 function _wp_json_prepare_data( $data ) {3016 if ( ! defined( 'WP_JSON_SERIALIZE_COMPATIBLE' ) || WP_JSON_SERIALIZE_COMPATIBLE === false ) {3017 return $data;3018 }3019 3020 switch ( gettype( $data ) ) {3021 case 'boolean':3022 case 'integer':3023 case 'double':3024 case 'string':3025 case 'NULL':3026 // These values can be passed through.3027 return $data;3028 3029 case 'array':3030 // Arrays must be mapped in case they also return objects.3031 return array_map( '_wp_json_prepare_data', $data );3032 3033 case 'object':3034 // If this is an incomplete object (__PHP_Incomplete_Class), bail.3035 if ( ! is_object( $data ) ) {3036 return null;3037 }3038 3039 if ( $data instanceof JsonSerializable ) {3040 $data = $data->jsonSerialize();3041 } else {3042 $data = get_object_vars( $data );3043 }3044 3045 // Now, pass the array (or whatever was returned from jsonSerialize through).3046 return _wp_json_prepare_data( $data );3047 3048 default:3049 return null;3050 }3051 }3052 3053 /**3054 * Send a JSON response back to an Ajax request.3055 *3056 * @since 3.5.03057 *3058 * @param mixed $response Variable (usually an array or object) to encode as JSON,3059 * then print and die.3060 */3061 function wp_send_json( $response ) {3062 @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );3063 echo wp_json_encode( $response );3064 if ( defined( 'DOING_AJAX' ) && DOING_AJAX )3065 wp_die();3066 else3067 die;3068 }3069 3070 /**3071 * Send a JSON response back to an Ajax request, indicating success.3072 *3073 * @since 3.5.03074 *3075 * @param mixed $data Data to encode as JSON, then print and die.3076 */3077 function wp_send_json_success( $data = null ) {3078 $response = array( 'success' => true );3079 3080 if ( isset( $data ) )3081 $response['data'] = $data;3082 3083 wp_send_json( $response );3084 }3085 3086 /**3087 * Send a JSON response back to an Ajax request, indicating failure.3088 *3089 * If the `$data` parameter is a WP_Error object, the errors3090 * within the object are processed and output as an array of error3091 * codes and corresponding messages. All other types are output3092 * without further processing.3093 *3094 * @since 3.5.03095 * @since 4.1.0 The `$data` parameter is now processed if a WP_Error object is passed in.3096 *3097 * @param mixed $data Data to encode as JSON, then print and die.3098 */3099 function wp_send_json_error( $data = null ) {3100 $response = array( 'success' => false );3101 3102 if ( isset( $data ) ) {3103 if ( is_wp_error( $data ) ) {3104 $result = array();3105 foreach ( $data->errors as $code => $messages ) {3106 foreach ( $messages as $message ) {3107 $result[] = array( 'code' => $code, 'message' => $message );3108 }3109 }3110 3111 $response['data'] = $result;3112 } else {3113 $response['data'] = $data;3114 }3115 }3116 3117 wp_send_json( $response );3118 }3119 3120 /**3121 * Checks that a JSONP callback is a valid JavaScript callback.3122 *3123 * Only allows alphanumeric characters and the dot character in callback3124 * function names. This helps to mitigate XSS attacks caused by directly3125 * outputting user input.3126 *3127 * @since 4.6.03128 *3129 * @param string $callback Supplied JSONP callback function.3130 * @return bool True if valid callback, otherwise false.3131 */3132 function wp_check_jsonp_callback( $callback ) {3133 if ( ! is_string( $callback ) ) {3134 return false;3135 }3136 3137 $jsonp_callback = preg_replace( '/[^\w\.]/', '', $callback, -1, $illegal_char_count );3138 3139 return 0 === $illegal_char_count;3140 }3141 3142 /**3143 * Retrieve the WordPress home page URL.3144 *3145 * If the constant named 'WP_HOME' exists, then it will be used and returned3146 * by the function. This can be used to counter the redirection on your local3147 * development environment.3148 *3149 * @since 2.2.03150 * @access private3151 *3152 * @see WP_HOME3153 *3154 * @param string $url URL for the home location.3155 * @return string Homepage location.3156 */3157 function _config_wp_home( $url = '' ) {3158 if ( defined( 'WP_HOME' ) )3159 return untrailingslashit( WP_HOME );3160 return $url;3161 }3162 3163 /**3164 * Retrieve the WordPress site URL.3165 *3166 * If the constant named 'WP_SITEURL' is defined, then the value in that3167 * constant will always be returned. This can be used for debugging a site3168 * on your localhost while not having to change the database to your URL.3169 *3170 * @since 2.2.03171 * @access private3172 *3173 * @see WP_SITEURL3174 *3175 * @param string $url URL to set the WordPress site location.3176 * @return string The WordPress Site URL.3177 */3178 function _config_wp_siteurl( $url = '' ) {3179 if ( defined( 'WP_SITEURL' ) )3180 return untrailingslashit( WP_SITEURL );3181 return $url;3182 }3183 3184 /**3185 * Set the localized direction for MCE plugin.3186 *3187 * Will only set the direction to 'rtl', if the WordPress locale has3188 * the text direction set to 'rtl'.3189 *3190 * Fills in the 'directionality' setting, enables the 'directionality'3191 * plugin, and adds the 'ltr' button to 'toolbar1', formerly3192 * 'theme_advanced_buttons1' array keys. These keys are then returned3193 * in the $mce_init (TinyMCE settings) array.3194 *3195 * @since 2.1.03196 * @access private3197 *3198 * @param array $mce_init MCE settings array.3199 * @return array Direction set for 'rtl', if needed by locale.3200 */3201 function _mce_set_direction( $mce_init ) {3202 if ( is_rtl() ) {3203 $mce_init['directionality'] = 'rtl';3204 $mce_init['rtl_ui'] = true;3205 3206 if ( ! empty( $mce_init['plugins'] ) && strpos( $mce_init['plugins'], 'directionality' ) === false ) {3207 $mce_init['plugins'] .= ',directionality';3208 }3209 3210 if ( ! empty( $mce_init['toolbar1'] ) && ! preg_match( '/\bltr\b/', $mce_init['toolbar1'] ) ) {3211 $mce_init['toolbar1'] .= ',ltr';3212 }3213 }3214 3215 return $mce_init;3216 }3217 3218 3219 /**3220 * Convert smiley code to the icon graphic file equivalent.3221 *3222 * You can turn off smilies, by going to the write setting screen and unchecking3223 * the box, or by setting 'use_smilies' option to false or removing the option.3224 *3225 * Plugins may override the default smiley list by setting the $wpsmiliestrans3226 * to an array, with the key the code the blogger types in and the value the3227 * image file.3228 *3229 * The $wp_smiliessearch global is for the regular expression and is set each3230 * time the function is called.3231 *3232 * The full list of smilies can be found in the function and won't be listed in3233 * the description. Probably should create a Codex page for it, so that it is3234 * available.3235 *3236 * @global array $wpsmiliestrans3237 * @global array $wp_smiliessearch3238 *3239 * @since 2.2.03240 */3241 function smilies_init() {3242 global $wpsmiliestrans, $wp_smiliessearch;3243 3244 // don't bother setting up smilies if they are disabled3245 if ( !get_option( 'use_smilies' ) )3246 return;3247 3248 if ( !isset( $wpsmiliestrans ) ) {3249 $wpsmiliestrans = array(3250 ':mrgreen:' => 'mrgreen.png',3251 ':neutral:' => "\xf0\x9f\x98\x90",3252 ':twisted:' => "\xf0\x9f\x98\x88",3253 ':arrow:' => "\xe2\x9e\xa1",3254 ':shock:' => "\xf0\x9f\x98\xaf",3255 ':smile:' => "\xf0\x9f\x99\x82",3256 ':???:' => "\xf0\x9f\x98\x95",3257 ':cool:' => "\xf0\x9f\x98\x8e",3258 ':evil:' => "\xf0\x9f\x91\xbf",3259 ':grin:' => "\xf0\x9f\x98\x80",3260 ':idea:' => "\xf0\x9f\x92\xa1",3261 ':oops:' => "\xf0\x9f\x98\xb3",3262 ':razz:' => "\xf0\x9f\x98\x9b",3263 ':roll:' => "\xf0\x9f\x99\x84",3264 ':wink:' => "\xf0\x9f\x98\x89",3265 ':cry:' => "\xf0\x9f\x98\xa5",3266 ':eek:' => "\xf0\x9f\x98\xae",3267 ':lol:' => "\xf0\x9f\x98\x86",3268 ':mad:' => "\xf0\x9f\x98\xa1",3269 ':sad:' => "\xf0\x9f\x99\x81",3270 '8-)' => "\xf0\x9f\x98\x8e",3271 '8-O' => "\xf0\x9f\x98\xaf",3272 ':-(' => "\xf0\x9f\x99\x81",3273 ':-)' => "\xf0\x9f\x99\x82",3274 ':-?' => "\xf0\x9f\x98\x95",3275 ':-D' => "\xf0\x9f\x98\x80",3276 ':-P' => "\xf0\x9f\x98\x9b",3277 ':-o' => "\xf0\x9f\x98\xae",3278 ':-x' => "\xf0\x9f\x98\xa1",3279 ':-|' => "\xf0\x9f\x98\x90",3280 ';-)' => "\xf0\x9f\x98\x89",3281 // This one transformation breaks regular text with frequency.3282 // '8)' => "\xf0\x9f\x98\x8e",3283 '8O' => "\xf0\x9f\x98\xaf",3284 ':(' => "\xf0\x9f\x99\x81",3285 ':)' => "\xf0\x9f\x99\x82",3286 ':?' => "\xf0\x9f\x98\x95",3287 ':D' => "\xf0\x9f\x98\x80",3288 ':P' => "\xf0\x9f\x98\x9b",3289 ':o' => "\xf0\x9f\x98\xae",3290 ':x' => "\xf0\x9f\x98\xa1",3291 ':|' => "\xf0\x9f\x98\x90",3292 ';)' => "\xf0\x9f\x98\x89",3293 ':!:' => "\xe2\x9d\x97",3294 ':?:' => "\xe2\x9d\x93",3295 );3296 }3297 3298 if (count($wpsmiliestrans) == 0) {3299 return;3300 }3301 3302 /*3303 * NOTE: we sort the smilies in reverse key order. This is to make sure3304 * we match the longest possible smilie (:???: vs :?) as the regular3305 * expression used below is first-match3306 */3307 krsort($wpsmiliestrans);3308 3309 $spaces = wp_spaces_regexp();3310 3311 // Begin first "subpattern"3312 $wp_smiliessearch = '/(?blog_id;4258 }4259 4260 /**4261 * Determine whether a network is the main network of the Multisite install.4262 *4263 * @since 3.7.04264 *4265 * @param int $network_id Optional. Network ID to test. Defaults to current network.4266 * @return bool True if $network_id is the main network, or if not running Multisite.4267 */4268 function is_main_network( $network_id = null ) {4269 if ( ! is_multisite() ) {4270 return true;4271 }4272 4273 $current_network_id = (int) get_current_site()->id;4274 4275 if ( null === $network_id ) {4276 $network_id = $current_network_id;4277 }4278 4279 $network_id = (int) $network_id;4280 4281 return ( $network_id === get_main_network_id() );4282 }4283 4284 /**4285 * Get the main network ID.4286 *4287 * @since 4.3.04288 *4289 * @global wpdb $wpdb WordPress database abstraction object.4290 *4291 * @return int The ID of the main network.4292 */4293 function get_main_network_id() {4294 global $wpdb;4295 4296 if ( ! is_multisite() ) {4297 return 1;4298 }4299 4300 $current_site = get_current_site();4301 4302 if ( defined( 'PRIMARY_NETWORK_ID' ) ) {4303 $main_network_id = PRIMARY_NETWORK_ID;4304 } elseif ( isset( $current_site->id ) && 1 === (int) $current_site->id ) {4305 // If the current network has an ID of 1, assume it is the main network.4306 $main_network_id = 1;4307 } else {4308 $main_network_id = wp_cache_get( 'primary_network_id', 'site-options' );4309 4310 if ( false === $main_network_id ) {4311 $main_network_id = (int) $wpdb->get_var( "SELECT id FROM {$wpdb->site} ORDER BY id LIMIT 1" );4312 wp_cache_add( 'primary_network_id', $main_network_id, 'site-options' );4313 }4314 }4315 4316 /**4317 * Filters the main network ID.4318 *4319 * @since 4.3.04320 *4321 * @param int $main_network_id The ID of the main network.4322 */4323 return (int) apply_filters( 'get_main_network_id', $main_network_id );4324 }4325 4326 /**4327 * Determine whether global terms are enabled.4328 *4329 * @since 3.0.04330 *4331 * @staticvar bool $global_terms4332 *4333 * @return bool True if multisite and global terms enabled.4334 */4335 function global_terms_enabled() {4336 if ( ! is_multisite() )4337 return false;4338 4339 static $global_terms = null;4340 if ( is_null( $global_terms ) ) {4341 4342 /**4343 * Filters whether global terms are enabled.4344 *4345 * Passing a non-null value to the filter will effectively short-circuit the function,4346 * returning the value of the 'global_terms_enabled' site option instead.4347 *4348 * @since 3.0.04349 *4350 * @param null $enabled Whether global terms are enabled.4351 */4352 $filter = apply_filters( 'global_terms_enabled', null );4353 if ( ! is_null( $filter ) )4354 $global_terms = (bool) $filter;4355 else4356 $global_terms = (bool) get_site_option( 'global_terms_enabled', false );4357 }4358 return $global_terms;4359 }4360 4361 /**4362 * gmt_offset modification for smart timezone handling.4363 *4364 * Overrides the gmt_offset option if we have a timezone_string available.4365 *4366 * @since 2.8.04367 *4368 * @return float|false Timezone GMT offset, false otherwise.4369 */4370 function wp_timezone_override_offset() {4371 if ( !$timezone_string = get_option( 'timezone_string' ) ) {4372 return false;4373 }4374 4375 $timezone_object = timezone_open( $timezone_string );4376 $datetime_object = date_create();4377 if ( false === $timezone_object || false === $datetime_object ) {4378 return false;4379 }4380 return round( timezone_offset_get( $timezone_object, $datetime_object ) / HOUR_IN_SECONDS, 2 );4381 }4382 4383 /**4384 * Sort-helper for timezones.4385 *4386 * @since 2.9.04387 * @access private4388 *4389 * @param array $a4390 * @param array $b4391 * @return int4392 */4393 function _wp_timezone_choice_usort_callback( $a, $b ) {4394 // Don't use translated versions of Etc4395 if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) {4396 // Make the order of these more like the old dropdown4397 if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) {4398 return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) );4399 }4400 if ( 'UTC' === $a['city'] ) {4401 if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) {4402 return 1;4403 }4404 return -1;4405 }4406 if ( 'UTC' === $b['city'] ) {4407 if ( 'GMT+' === substr( $a['city'], 0, 4 ) ) {4408 return -1;4409 }4410 return 1;4411 }4412 return strnatcasecmp( $a['city'], $b['city'] );4413 }4414 if ( $a['t_continent'] == $b['t_continent'] ) {4415 if ( $a['t_city'] == $b['t_city'] ) {4416 return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] );4417 }4418 return strnatcasecmp( $a['t_city'], $b['t_city'] );4419 } else {4420 // Force Etc to the bottom of the list4421 if ( 'Etc' === $a['continent'] ) {4422 return 1;4423 }4424 if ( 'Etc' === $b['continent'] ) {4425 return -1;4426 }4427 return strnatcasecmp( $a['t_continent'], $b['t_continent'] );4428 }4429 }4430 4431 /**4432 * Gives a nicely-formatted list of timezone strings.4433 *4434 * @since 2.9.04435 *4436 * @staticvar bool $mo_loaded4437 *4438 * @param string $selected_zone Selected timezone.4439 * @return string4440 */4441 function wp_timezone_choice( $selected_zone ) {4442 static $mo_loaded = false;4443 4444 $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific');4445 4446 // Load translations for continents and cities4447 if ( !$mo_loaded ) {4448 $locale = get_locale();4449 $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';4450 load_textdomain( 'continents-cities', $mofile );4451 $mo_loaded = true;4452 }4453 4454 $zonen = array();4455 foreach ( timezone_identifiers_list() as $zone ) {4456 $zone = explode( '/', $zone );4457 if ( !in_array( $zone[0], $continents ) ) {4458 continue;4459 }4460 4461 // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later4462 $exists = array(4463 0 => ( isset( $zone[0] ) && $zone[0] ),4464 1 => ( isset( $zone[1] ) && $zone[1] ),4465 2 => ( isset( $zone[2] ) && $zone[2] ),4466 );4467 $exists[3] = ( $exists[0] && 'Etc' !== $zone[0] );4468 $exists[4] = ( $exists[1] && $exists[3] );4469 $exists[5] = ( $exists[2] && $exists[3] );4470 4471 $zonen[] = array(4472 'continent' => ( $exists[0] ? $zone[0] : '' ),4473 'city' => ( $exists[1] ? $zone[1] : '' ),4474 'subcity' => ( $exists[2] ? $zone[2] : '' ),4475 't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ),4476 't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ),4477 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' )4478 );4479 }4480 usort( $zonen, '_wp_timezone_choice_usort_callback' );4481 4482 $structure = array();4483 4484 if ( empty( $selected_zone ) ) {4485 $structure[] = '' . __( 'Select a city' ) . '';4486 }4487 4488 foreach ( $zonen as $key => $zone ) {4489 // Build value in an array to join later4490 $value = array( $zone['continent'] );4491 4492 if ( empty( $zone['city'] ) ) {4493 // It's at the continent level (generally won't happen)4494 $display = $zone['t_continent'];4495 } else {4496 // It's inside a continent group4497 4498 // Continent optgroup4499 if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) {4500 $label = $zone['t_continent'];4501 $structure[] = '';4502 }4503 4504 // Add the city to the value4505 $value[] = $zone['city'];4506 4507 $display = $zone['t_city'];4508 if ( !empty( $zone['subcity'] ) ) {4509 // Add the subcity to the value4510 $value[] = $zone['subcity'];4511 $display .= ' - ' . $zone['t_subcity'];4512 }4513 }4514 4515