PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | jetpack_vendor/automattic/jetpack-status/src/class-status.php +62 -14 13.7.2 → 16.3-beta View file →
@@ -44,10 +44,9 @@
44 44
45 45 /**
46 46 * Filters Jetpack's offline mode.
47 47 *
48 - * @see https://jetpack.com/support/development-mode/
49 - * @todo Update documentation ^^.
48 + * @see https://jetpack.com/support/offline-mode/
50 49 *
51 50 * @since 1.3.0
52 51 *
53 52 * @param bool $offline_mode Is Jetpack's offline mode active.
@@ -53,8 +52,25 @@
53 52 * @param bool $offline_mode Is Jetpack's offline mode active.
54 53 */
55 54 $offline_mode = (bool) apply_filters( 'jetpack_offline_mode', $offline_mode );
56 55
56 + if ( ! $offline_mode ) {
57 + // Sentinel default so an absent option isn't confused with a stored null/false.
58 + $sentinel = new \stdClass();
59 + $option = get_option( 'jetpack_offline_mode', $sentinel );
60 +
61 + if ( $sentinel === $option ) {
62 + // Seed an autoloaded default to stop per-request reads, but only where it helps
63 + // (no persistent object cache) and writes are safe (keep front-end reads read-only).
64 + if ( ! wp_using_ext_object_cache() && ( is_admin() || wp_doing_cron() || ( defined( 'WP_CLI' ) && WP_CLI ) ) ) {
65 + add_option( 'jetpack_offline_mode', false, '', true );
66 + }
67 + } else {
68 + // A default_option filter could return a non-scalar; only a scalar is a real value.
69 + $offline_mode = is_scalar( $option ) ? (bool) $option : false;
70 + }
71 + }
72 +
57 73 Cache::set( 'is_offline_mode', $offline_mode );
58 74 return $offline_mode;
59 75 }
60 76
@@ -122,34 +138,64 @@
122 138 if ( null !== $cached ) {
123 139 return $cached;
124 140 }
125 141
126 - $site_url = site_url();
142 + $site_url = trim( (string) site_url() );
127 143
128 - // Check for localhost and sites using an IP only first.
129 - // Note: str_contains() is not used here, as wp-includes/compat.php is not loaded in this file.
130 - $is_local = $site_url && false === strpos( $site_url, '.' );
144 + /*
145 + * Every check below cares about the host, not the rest of the URL. Matching the host
146 + * alone means a port, a subdirectory install, or a trailing slash can't defeat them,
147 + * and a known local domain sitting in the path can't trigger them by accident.
148 + */
149 + $host = wp_parse_url( $site_url, PHP_URL_HOST );
150 + if ( ( ! is_string( $host ) || '' === $host ) && ! preg_match( '#^[a-z][a-z0-9+.\-]*:#i', $site_url ) ) {
151 + /*
152 + * No scheme, so site_url() isn't absolute. Read the value as a bare host.
153 + * A value that does carry a scheme but still won't parse is malformed, and
154 + * guessing at it would read "https:/example.com" as the host "https".
155 + */
156 + $host = wp_parse_url( '//' . ltrim( $site_url, '/' ), PHP_URL_HOST );
157 + }
158 + if ( ! is_string( $host ) ) {
159 + /*
160 + * Nothing host-shaped to test. Treat the site as remote rather than matching the
161 + * raw URL: a false "local" silently drops a live site into offline mode.
162 + */
163 + $host = '';
164 + }
131 165
166 + /*
167 + * Check for localhost and sites using an IP only first. No dot means it can't be a
168 + * public domain. Dotless IPv6 literals land here too, routable ones included:
169 + * WordPress.com won't register an IPv6 site URL, so offline mode is where they belong.
170 + * An IPv4-mapped literal like [::ffff:127.0.0.1] keeps its dots and reads as remote.
171 + */
172 + $is_local = '' !== $host && false === strpos( $host, '.' );
173 +
132 174 // Use Core's environment check, if available.
133 175 if ( 'local' === wp_get_environment_type() ) {
134 176 $is_local = true;
135 177 }
136 178
137 - // Then check for usual usual domains used by local dev tools.
179 + // Then check for usual domains used by local dev tools.
138 180 $known_local = array(
139 181 '#\.local$#i',
140 - '#\.localhost$#i',
182 + '#(^|\.)localhost$#i', // localhost and any subdomain of it.
141 183 '#\.test$#i',
142 - '#\.docksal$#i', // Docksal.
184 + '#\.docksal$#i', // Docksal.
143 185 '#\.docksal\.site$#i', // Docksal.
144 186 '#\.dev\.cc$#i', // ServerPress.
145 187 '#\.lndo\.site$#i', // Lando.
146 - '#^https?://127\.0\.0\.1$#',
188 + '#\.ddev\.site$#i', // DDEV.
189 + // The whole 127.0.0.0/8 range is loopback; each octet is capped at 255.
190 + '#^127\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){2}$#',
191 + '#^0\.0\.0\.0$#', // All-interfaces bind, common under Docker and `wp server`.
192 + '#^playground\.wordpress\.net$#i', // WordPress Playground, which runs entirely in the browser.
147 193 );
148 194
149 - if ( ! $is_local ) {
150 - foreach ( $known_local as $url ) {
151 - if ( preg_match( $url, $site_url ) ) {
195 + if ( ! $is_local && '' !== $host ) {
196 + foreach ( $known_local as $pattern ) {
197 + if ( preg_match( $pattern, $host ) ) {
152 198 $is_local = true;
153 199 break;
154 200 }
155 201 }
@@ -325,8 +371,10 @@
325 371 * A site is considered as being onboarded if it currently has an onboarding token.
326 372 *
327 373 * @since-jetpack 5.8
328 374 *
375 + * @deprecated since 4.0.0
376 + *
329 377 * @access public
330 378 * @static
331 379 *
332 380 * @return bool True if the site is currently onboarding, false otherwise
@@ -373,9 +421,9 @@
373 421 */
374 422 public function is_coming_soon() {
375 423 $ret = Cache::get( 'is_coming_soon' );
376 424 if ( null === $ret ) {
377 - $is_coming_soon = (bool) ( function_exists( 'site_is_coming_soon' ) && \site_is_coming_soon() )
425 + $is_coming_soon = ( function_exists( 'site_is_coming_soon' ) && \site_is_coming_soon() )
378 426 || get_option( 'wpcom_public_coming_soon' );
379 427
380 428 /**
381 429 * Filters the is_coming_soon check.