8 * Detects which user environment WordPress is being used on. |
8 * Detects which user environment WordPress is being used on. |
9 * Only attempts to check for Apache, Nginx and IIS -- three web |
9 * Only attempts to check for Apache, Nginx and IIS -- three web |
10 * servers with known pretty permalink capability. |
10 * servers with known pretty permalink capability. |
11 * |
11 * |
12 * Note: Though Nginx is detected, WordPress does not currently |
12 * Note: Though Nginx is detected, WordPress does not currently |
13 * generate rewrite rules for it. See https://wordpress.org/support/article/nginx/ |
13 * generate rewrite rules for it. See https://developer.wordpress.org/advanced-administration/server/web-server/nginx/ |
14 * |
14 * |
15 * @package WordPress |
15 * @package WordPress |
16 */ |
16 */ |
17 |
17 |
18 global $pagenow, |
18 global $pagenow, |
19 $is_lynx, $is_gecko, $is_winIE, $is_macIE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone, $is_IE, $is_edge, |
19 $is_lynx, $is_gecko, $is_winIE, $is_macIE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone, $is_IE, $is_edge, |
20 $is_apache, $is_IIS, $is_iis7, $is_nginx; |
20 $is_apache, $is_IIS, $is_iis7, $is_nginx, $is_caddy; |
21 |
21 |
22 // On which page are we? |
22 // On which page are we? |
23 if ( is_admin() ) { |
23 if ( is_admin() ) { |
24 // wp-admin pages are checked more carefully. |
24 // wp-admin pages are checked more carefully. |
25 if ( is_network_admin() ) { |
25 if ( is_network_admin() ) { |
37 if ( '' === $pagenow || 'index' === $pagenow || 'index.php' === $pagenow ) { |
37 if ( '' === $pagenow || 'index' === $pagenow || 'index.php' === $pagenow ) { |
38 $pagenow = 'index.php'; |
38 $pagenow = 'index.php'; |
39 } else { |
39 } else { |
40 preg_match( '#(.*?)(/|$)#', $pagenow, $self_matches ); |
40 preg_match( '#(.*?)(/|$)#', $pagenow, $self_matches ); |
41 $pagenow = strtolower( $self_matches[1] ); |
41 $pagenow = strtolower( $self_matches[1] ); |
42 if ( '.php' !== substr( $pagenow, -4, 4 ) ) { |
42 if ( ! str_ends_with( $pagenow, '.php' ) ) { |
43 $pagenow .= '.php'; // For `Options +Multiviews`: /wp-admin/themes/index.php (themes.php is queried). |
43 $pagenow .= '.php'; // For `Options +Multiviews`: /wp-admin/themes/index.php (themes.php is queried). |
44 } |
44 } |
45 } |
45 } |
46 } else { |
46 } else { |
47 if ( preg_match( '#([^/]+\.php)([?/].*?)?$#i', $_SERVER['PHP_SELF'], $self_matches ) ) { |
47 if ( preg_match( '#([^/]+\.php)([?/].*?)?$#i', $_SERVER['PHP_SELF'], $self_matches ) ) { |
63 $is_chrome = false; |
63 $is_chrome = false; |
64 $is_iphone = false; |
64 $is_iphone = false; |
65 $is_edge = false; |
65 $is_edge = false; |
66 |
66 |
67 if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) { |
67 if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) { |
68 if ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Lynx' ) !== false ) { |
68 if ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Lynx' ) ) { |
69 $is_lynx = true; |
69 $is_lynx = true; |
70 } elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Edg' ) !== false ) { |
70 } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Edg' ) ) { |
71 $is_edge = true; |
71 $is_edge = true; |
|
72 } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'OPR/' ) ) { |
|
73 $is_opera = true; |
72 } elseif ( stripos( $_SERVER['HTTP_USER_AGENT'], 'chrome' ) !== false ) { |
74 } elseif ( stripos( $_SERVER['HTTP_USER_AGENT'], 'chrome' ) !== false ) { |
73 if ( stripos( $_SERVER['HTTP_USER_AGENT'], 'chromeframe' ) !== false ) { |
75 if ( stripos( $_SERVER['HTTP_USER_AGENT'], 'chromeframe' ) !== false ) { |
74 $is_admin = is_admin(); |
76 $is_admin = is_admin(); |
75 /** |
77 /** |
76 * Filters whether Google Chrome Frame should be used, if available. |
78 * Filters whether Google Chrome Frame should be used, if available. |
87 } else { |
89 } else { |
88 $is_chrome = true; |
90 $is_chrome = true; |
89 } |
91 } |
90 } elseif ( stripos( $_SERVER['HTTP_USER_AGENT'], 'safari' ) !== false ) { |
92 } elseif ( stripos( $_SERVER['HTTP_USER_AGENT'], 'safari' ) !== false ) { |
91 $is_safari = true; |
93 $is_safari = true; |
92 } elseif ( ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'], 'Trident' ) !== false ) && strpos( $_SERVER['HTTP_USER_AGENT'], 'Win' ) !== false ) { |
94 } elseif ( ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Trident' ) ) |
|
95 && str_contains( $_SERVER['HTTP_USER_AGENT'], 'Win' ) |
|
96 ) { |
93 $is_winIE = true; |
97 $is_winIE = true; |
94 } elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) !== false && strpos( $_SERVER['HTTP_USER_AGENT'], 'Mac' ) !== false ) { |
98 } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'Mac' ) ) { |
95 $is_macIE = true; |
99 $is_macIE = true; |
96 } elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Gecko' ) !== false ) { |
100 } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Gecko' ) ) { |
97 $is_gecko = true; |
101 $is_gecko = true; |
98 } elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Opera' ) !== false ) { |
102 } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Nav' ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'Mozilla/4.' ) ) { |
99 $is_opera = true; |
|
100 } elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Nav' ) !== false && strpos( $_SERVER['HTTP_USER_AGENT'], 'Mozilla/4.' ) !== false ) { |
|
101 $is_NS4 = true; |
103 $is_NS4 = true; |
102 } |
104 } |
103 } |
105 } |
104 |
106 |
105 if ( $is_safari && stripos( $_SERVER['HTTP_USER_AGENT'], 'mobile' ) !== false ) { |
107 if ( $is_safari && stripos( $_SERVER['HTTP_USER_AGENT'], 'mobile' ) !== false ) { |
109 $is_IE = ( $is_macIE || $is_winIE ); |
111 $is_IE = ( $is_macIE || $is_winIE ); |
110 |
112 |
111 // Server detection. |
113 // Server detection. |
112 |
114 |
113 /** |
115 /** |
114 * Whether the server software is Apache or something else |
116 * Whether the server software is Apache or something else. |
115 * |
117 * |
116 * @global bool $is_apache |
118 * @global bool $is_apache |
117 */ |
119 */ |
118 $is_apache = ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) !== false || strpos( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) !== false ); |
120 $is_apache = ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) || str_contains( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) ); |
119 |
121 |
120 /** |
122 /** |
121 * Whether the server software is Nginx or something else |
123 * Whether the server software is Nginx or something else. |
122 * |
124 * |
123 * @global bool $is_nginx |
125 * @global bool $is_nginx |
124 */ |
126 */ |
125 $is_nginx = ( strpos( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) !== false ); |
127 $is_nginx = ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) ); |
126 |
128 |
127 /** |
129 /** |
128 * Whether the server software is IIS or something else |
130 * Whether the server software is Caddy / FrankenPHP or something else. |
|
131 * |
|
132 * @global bool $is_caddy |
|
133 */ |
|
134 $is_caddy = ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'Caddy' ) || str_contains( $_SERVER['SERVER_SOFTWARE'], 'FrankenPHP' ) ); |
|
135 |
|
136 /** |
|
137 * Whether the server software is IIS or something else. |
129 * |
138 * |
130 * @global bool $is_IIS |
139 * @global bool $is_IIS |
131 */ |
140 */ |
132 $is_IIS = ! $is_apache && ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) !== false || strpos( $_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer' ) !== false ); |
141 $is_IIS = ! $is_apache && ( str_contains( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) || str_contains( $_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer' ) ); |
133 |
142 |
134 /** |
143 /** |
135 * Whether the server software is IIS 7.X or greater |
144 * Whether the server software is IIS 7.X or greater. |
136 * |
145 * |
137 * @global bool $is_iis7 |
146 * @global bool $is_iis7 |
138 */ |
147 */ |
139 $is_iis7 = $is_IIS && (int) substr( $_SERVER['SERVER_SOFTWARE'], strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/' ) + 14 ) >= 7; |
148 $is_iis7 = $is_IIS && (int) substr( $_SERVER['SERVER_SOFTWARE'], strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/' ) + 14 ) >= 7; |
140 |
149 |
141 /** |
150 /** |
142 * Test if the current browser runs on a mobile device (smart phone, tablet, etc.) |
151 * Test if the current browser runs on a mobile device (smart phone, tablet, etc.). |
143 * |
152 * |
144 * @since 3.4.0 |
153 * @since 3.4.0 |
|
154 * @since 6.4.0 Added checking for the Sec-CH-UA-Mobile request header. |
145 * |
155 * |
146 * @return bool |
156 * @return bool |
147 */ |
157 */ |
148 function wp_is_mobile() { |
158 function wp_is_mobile() { |
149 if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) { |
159 if ( isset( $_SERVER['HTTP_SEC_CH_UA_MOBILE'] ) ) { |
|
160 // This is the `Sec-CH-UA-Mobile` user agent client hint HTTP request header. |
|
161 // See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-UA-Mobile>. |
|
162 $is_mobile = ( '?1' === $_SERVER['HTTP_SEC_CH_UA_MOBILE'] ); |
|
163 } elseif ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) { |
150 $is_mobile = false; |
164 $is_mobile = false; |
151 } elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Mobile' ) !== false // Many mobile devices (all iPhone, iPad, etc.) |
165 } elseif ( str_contains( $_SERVER['HTTP_USER_AGENT'], 'Mobile' ) // Many mobile devices (all iPhone, iPad, etc.) |
152 || strpos( $_SERVER['HTTP_USER_AGENT'], 'Android' ) !== false |
166 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Android' ) |
153 || strpos( $_SERVER['HTTP_USER_AGENT'], 'Silk/' ) !== false |
167 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Silk/' ) |
154 || strpos( $_SERVER['HTTP_USER_AGENT'], 'Kindle' ) !== false |
168 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Kindle' ) |
155 || strpos( $_SERVER['HTTP_USER_AGENT'], 'BlackBerry' ) !== false |
169 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'BlackBerry' ) |
156 || strpos( $_SERVER['HTTP_USER_AGENT'], 'Opera Mini' ) !== false |
170 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera Mini' ) |
157 || strpos( $_SERVER['HTTP_USER_AGENT'], 'Opera Mobi' ) !== false ) { |
171 || str_contains( $_SERVER['HTTP_USER_AGENT'], 'Opera Mobi' ) ) { |
158 $is_mobile = true; |
172 $is_mobile = true; |
159 } else { |
173 } else { |
160 $is_mobile = false; |
174 $is_mobile = false; |
161 } |
175 } |
162 |
176 |