PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 11.4.1
Jetpack – WP Security, Backup, Speed, & Growth v11.4.1
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 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / functions.global.php
functions.global.php
488 lines 13.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This file is meant to be the home for any generic & reusable functions
4 * that can be accessed anywhere within Jetpack.
5 *
6 * This file is loaded whether Jetpack is active.
7 *
8 * Please namespace with jetpack_
9 *
10 * @package automattic/jetpack
11 */
12
13 use Automattic\Jetpack\Connection\Client;
14 use Automattic\Jetpack\Device_Detection;
15 use Automattic\Jetpack\Redirect;
16 use Automattic\Jetpack\Status\Host;
17 use Automattic\Jetpack\Sync\Functions;
18
19 /**
20 * Disable direct access.
21 */
22 if ( ! defined( 'ABSPATH' ) ) {
23 exit;
24 }
25
26 /**
27 * Hook into Core's _deprecated_function
28 * Add more details about when a deprecated function will be removed.
29 *
30 * @since 8.8.0
31 *
32 * @param string $function The function that was called.
33 * @param string $replacement Optional. The function that should have been called. Default null.
34 * @param string $version The version of Jetpack that deprecated the function.
35 */
36 function jetpack_deprecated_function( $function, $replacement, $version ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
37 // Bail early for non-Jetpack deprecations.
38 if ( 0 !== strpos( $version, 'jetpack-' ) ) {
39 return;
40 }
41
42 // Look for when a function will be removed based on when it was deprecated.
43 $removed_version = jetpack_get_future_removed_version( $version );
44
45 // If we could find a version, let's log a message about when removal will happen.
46 if (
47 ! empty( $removed_version )
48 && ( defined( 'WP_DEBUG' ) && WP_DEBUG )
49 /** This filter is documented in core/src/wp-includes/functions.php */
50 && apply_filters( 'deprecated_function_trigger_error', true )
51 ) {
52 error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
53 sprintf(
54 /* Translators: 1. Function name. 2. Jetpack version number. */
55 __( 'The %1$s function will be removed from the Jetpack plugin in version %2$s.', 'jetpack' ),
56 $function,
57 $removed_version
58 )
59 );
60
61 }
62 }
63 add_action( 'deprecated_function_run', 'jetpack_deprecated_function', 10, 3 );
64
65 /**
66 * Hook into Core's _deprecated_file
67 * Add more details about when a deprecated file will be removed.
68 *
69 * @since 8.8.0
70 *
71 * @param string $file The file that was called.
72 * @param string $replacement The file that should have been included based on ABSPATH.
73 * @param string $version The version of WordPress that deprecated the file.
74 * @param string $message A message regarding the change.
75 */
76 function jetpack_deprecated_file( $file, $replacement, $version, $message ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
77 // Bail early for non-Jetpack deprecations.
78 if ( 0 !== strpos( $version, 'jetpack-' ) ) {
79 return;
80 }
81
82 // Look for when a file will be removed based on when it was deprecated.
83 $removed_version = jetpack_get_future_removed_version( $version );
84
85 // If we could find a version, let's log a message about when removal will happen.
86 if (
87 ! empty( $removed_version )
88 && ( defined( 'WP_DEBUG' ) && WP_DEBUG )
89 /** This filter is documented in core/src/wp-includes/functions.php */
90 && apply_filters( 'deprecated_file_trigger_error', true )
91 ) {
92 error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
93 sprintf(
94 /* Translators: 1. File name. 2. Jetpack version number. */
95 __( 'The %1$s file will be removed from the Jetpack plugin in version %2$s.', 'jetpack' ),
96 $file,
97 $removed_version
98 )
99 );
100
101 }
102 }
103 add_action( 'deprecated_file_included', 'jetpack_deprecated_file', 10, 4 );
104
105 /**
106 * Get the major version number of Jetpack 6 months after provided version.
107 * Useful to indicate when a deprecated function will be removed from Jetpack.
108 *
109 * @since 8.8.0
110 *
111 * @param string $version The version of WordPress that deprecated the function.
112 *
113 * @return bool|float Return a Jetpack Major version number, or false.
114 */
115 function jetpack_get_future_removed_version( $version ) {
116 /*
117 * Extract the version number from a deprecation notice.
118 * (let's only keep the first decimal, e.g. 8.8 and not 8.8.0)
119 */
120 preg_match( '#(([0-9]+\.([0-9]+))(?:\.[0-9]+)*)#', $version, $matches );
121
122 if ( isset( $matches[2], $matches[3] ) ) {
123 $deprecated_version = (float) $matches[2];
124 $deprecated_minor = (float) $matches[3];
125
126 /*
127 * If the detected minor version number
128 * (e.g. "7" in "8.7")
129 * is higher than 9, we know the version number is malformed.
130 * Jetpack does not use semver yet.
131 * Bail.
132 */
133 if ( 10 <= $deprecated_minor ) {
134 return false;
135 }
136
137 // We'll remove the function from the code 6 months later, thus 6 major versions later.
138 $removed_version = $deprecated_version + 0.6;
139
140 return (float) $removed_version;
141 }
142
143 return false;
144 }
145
146 /**
147 * Determine if this site is an WoA site or not by looking for presence of the wpcomsh plugin.
148 *
149 * @since 4.8.1
150 * @deprecated 10.3.0
151 *
152 * @return bool
153 */
154 function jetpack_is_atomic_site() {
155 jetpack_deprecated_function( __FUNCTION__, 'Automattic/Jetpack/Status/Host::is_woa_site', 'jetpack-10.3.0' );
156 return ( new Host() )->is_woa_site();
157 }
158
159 /**
160 * Register post type for migration.
161 *
162 * @since 5.2
163 */
164 function jetpack_register_migration_post_type() {
165 register_post_type(
166 'jetpack_migration',
167 array(
168 'supports' => array(),
169 'taxonomies' => array(),
170 'hierarchical' => false,
171 'public' => false,
172 'has_archive' => false,
173 'can_export' => true,
174 )
175 );
176 }
177
178 /**
179 * Stores migration data in the database.
180 *
181 * @since 5.2
182 *
183 * @param string $option_name Option name.
184 * @param bool $option_value Option value.
185 *
186 * @return int|WP_Error
187 */
188 function jetpack_store_migration_data( $option_name, $option_value ) {
189 jetpack_register_migration_post_type();
190
191 $insert = array(
192 'post_title' => $option_name,
193 'post_content_filtered' => $option_value,
194 'post_type' => 'jetpack_migration',
195 'post_date' => gmdate( 'Y-m-d H:i:s', time() ),
196 );
197
198 $post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
199
200 if ( null !== $post ) {
201 $insert['ID'] = $post->ID;
202 }
203
204 return wp_insert_post( $insert, true );
205 }
206
207 /**
208 * Retrieves legacy image widget data.
209 *
210 * @since 5.2
211 *
212 * @param string $option_name Option name.
213 *
214 * @return mixed|null
215 */
216 function jetpack_get_migration_data( $option_name ) {
217 $post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
218
219 return null !== $post ? maybe_unserialize( $post->post_content_filtered ) : null;
220 }
221
222 /**
223 * Prints a TOS blurb used throughout the connection prompts.
224 *
225 * Note: custom ToS messages are also defined in Jetpack_Pre_Connection_JITMs->get_raw_messages()
226 *
227 * @since 5.3
228 *
229 * @echo string
230 */
231 function jetpack_render_tos_blurb() {
232 printf(
233 wp_kses(
234 /* Translators: placeholders are links. */
235 __( 'By clicking the <strong>Set up Jetpack</strong> button, you agree to our <a href="%1$s" target="_blank" rel="noopener noreferrer">Terms of Service</a> and to <a href="%2$s" target="_blank" rel="noopener noreferrer">share details</a> with WordPress.com.', 'jetpack' ),
236 array(
237 'a' => array(
238 'href' => array(),
239 'target' => array(),
240 'rel' => array(),
241 ),
242 'strong' => true,
243 )
244 ),
245 esc_url( Redirect::get_url( 'wpcom-tos' ) ),
246 esc_url( Redirect::get_url( 'jetpack-support-what-data-does-jetpack-sync' ) )
247 );
248 }
249
250 /**
251 * Intervene upgrade process so Jetpack themes are downloaded with credentials.
252 *
253 * @since 5.3
254 *
255 * @param bool $preempt Whether to preempt an HTTP request's return value. Default false.
256 * @param array $r HTTP request arguments.
257 * @param string $url The request URL.
258 *
259 * @return array|bool|WP_Error
260 */
261 function jetpack_theme_update( $preempt, $r, $url ) {
262 if ( 0 === stripos( $url, JETPACK__WPCOM_JSON_API_BASE . '/rest/v1/themes/download' ) ) {
263 $file = $r['filename'];
264 if ( ! $file ) {
265 return new WP_Error( 'problem_creating_theme_file', esc_html__( 'Problem creating file for theme download', 'jetpack' ) );
266 }
267 $theme = pathinfo( wp_parse_url( $url, PHP_URL_PATH ), PATHINFO_FILENAME );
268
269 // Remove filter to avoid endless loop since wpcom_json_api_request_as_blog uses this too.
270 remove_filter( 'pre_http_request', 'jetpack_theme_update' );
271 $result = Client::wpcom_json_api_request_as_blog(
272 "themes/download/$theme.zip",
273 '1.1',
274 array(
275 'stream' => true,
276 'filename' => $file,
277 )
278 );
279
280 if ( 200 !== wp_remote_retrieve_response_code( $result ) ) {
281 return new WP_Error( 'problem_fetching_theme', esc_html__( 'Problem downloading theme', 'jetpack' ) );
282 }
283 return $result;
284 }
285 return $preempt;
286 }
287
288 /**
289 * Add the filter when a upgrade is going to be downloaded.
290 *
291 * @since 5.3
292 *
293 * @param bool $reply Whether to bail without returning the package. Default false.
294 *
295 * @return bool
296 */
297 function jetpack_upgrader_pre_download( $reply ) {
298 add_filter( 'pre_http_request', 'jetpack_theme_update', 10, 3 );
299 return $reply;
300 }
301
302 add_filter( 'upgrader_pre_download', 'jetpack_upgrader_pre_download' );
303
304 /**
305 * Wraps data in a way so that we can distinguish between objects and array and also prevent object recursion.
306 *
307 * @since 6.1.0
308
309 * @deprecated Automattic\Jetpack\Sync\Functions::json_wrap
310 *
311 * @param array|obj $any Source data to be cleaned up.
312 * @param array $seen_nodes Built array of nodes.
313 *
314 * @return array
315 */
316 function jetpack_json_wrap( &$any, $seen_nodes = array() ) {
317 _deprecated_function( __METHOD__, 'jetpack-9.5', 'Automattic\Jetpack\Sync\Functions' );
318
319 return Functions::json_wrap( $any, $seen_nodes );
320 }
321
322 /**
323 * Checks if the mime_content_type function is available and return it if so.
324 *
325 * The function mime_content_type is enabled by default in PHP, but can be disabled. We attempt to
326 * enforce this via composer.json, but that won't be checked in majority of cases where
327 * this would be happening.
328 *
329 * @since 7.8.0
330 *
331 * @param string $file File location.
332 *
333 * @return string|false MIME type or false if functionality is not available.
334 */
335 function jetpack_mime_content_type( $file ) {
336 if ( function_exists( 'mime_content_type' ) ) {
337 return mime_content_type( $file );
338 }
339
340 return false;
341 }
342
343 /**
344 * Checks that the mime type of the specified file is among those in a filterable list of mime types.
345 *
346 * @since 7.8.0
347 *
348 * @param string $file Path to file to get its mime type.
349 *
350 * @return bool
351 */
352 function jetpack_is_file_supported_for_sideloading( $file ) {
353 $type = jetpack_mime_content_type( $file );
354
355 if ( ! $type ) {
356 return false;
357 }
358
359 /**
360 * Filter the list of supported mime types for media sideloading.
361 *
362 * @since 4.0.0
363 *
364 * @module json-api
365 *
366 * @param array $supported_mime_types Array of the supported mime types for media sideloading.
367 */
368 $supported_mime_types = apply_filters(
369 'jetpack_supported_media_sideload_types',
370 array(
371 'image/png',
372 'image/jpeg',
373 'image/gif',
374 'image/bmp',
375 'image/webp',
376 'video/quicktime',
377 'video/mp4',
378 'video/mpeg',
379 'video/ogg',
380 'video/3gpp',
381 'video/3gpp2',
382 'video/h261',
383 'video/h262',
384 'video/h264',
385 'video/x-msvideo',
386 'video/x-ms-wmv',
387 'video/x-ms-asf',
388 )
389 );
390
391 // If the type returned was not an array as expected, then we know we don't have a match.
392 if ( ! is_array( $supported_mime_types ) ) {
393 return false;
394 }
395
396 return in_array( $type, $supported_mime_types, true );
397 }
398
399 /**
400 * Determine if the current User Agent matches the passed $kind
401 *
402 * @param string $kind Category of mobile device to check for.
403 * Either: any, dumb, smart.
404 * @param bool $return_matched_agent Boolean indicating if the UA should be returned.
405 *
406 * @return bool|string Boolean indicating if current UA matches $kind. If
407 * $return_matched_agent is true, returns the UA string
408 */
409 function jetpack_is_mobile( $kind = 'any', $return_matched_agent = false ) {
410
411 /**
412 * Filter the value of jetpack_is_mobile before it is calculated.
413 *
414 * Passing a truthy value to the filter will short-circuit determining the
415 * mobile type, returning the passed value instead.
416 *
417 * @since 4.2.0
418 *
419 * @param bool|string $matches Boolean if current UA matches $kind or not. If
420 * $return_matched_agent is true, should return the UA string
421 * @param string $kind Category of mobile device being checked
422 * @param bool $return_matched_agent Boolean indicating if the UA should be returned
423 */
424 $pre = apply_filters( 'pre_jetpack_is_mobile', null, $kind, $return_matched_agent );
425 if ( $pre ) {
426 return $pre;
427 }
428
429 $return = false;
430 $device_info = Device_Detection::get_info();
431
432 if ( 'any' === $kind ) {
433 $return = $device_info['is_phone'];
434 } elseif ( 'smart' === $kind ) {
435 $return = $device_info['is_smartphone'];
436 } elseif ( 'dumb' === $kind ) {
437 $return = $device_info['is_phone'] && ! $device_info['is_smartphone'];
438 }
439
440 if ( $return_matched_agent && true === $return ) {
441 $return = $device_info['is_phone_matched_ua'];
442 }
443
444 /**
445 * Filter the value of jetpack_is_mobile
446 *
447 * @since 4.2.0
448 *
449 * @param bool|string $matches Boolean if current UA matches $kind or not. If
450 * $return_matched_agent is true, should return the UA string
451 * @param string $kind Category of mobile device being checked
452 * @param bool $return_matched_agent Boolean indicating if the UA should be returned
453 */
454 return apply_filters( 'jetpack_is_mobile', $return, $kind, $return_matched_agent );
455 }
456
457 /**
458 * Determine whether the current request is for accessing the frontend.
459 *
460 * @return bool True if it's a frontend request, false otherwise.
461 */
462 function jetpack_is_frontend() {
463 $is_frontend = true;
464
465 if (
466 is_admin() ||
467 wp_doing_ajax() ||
468 wp_is_json_request() ||
469 wp_is_jsonp_request() ||
470 wp_is_xml_request() ||
471 is_feed() ||
472 ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
473 ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) ||
474 ( defined( 'WP_CLI' ) && WP_CLI )
475 ) {
476 $is_frontend = false;
477 }
478
479 /**
480 * Filter whether the current request is for accessing the frontend.
481 *
482 * @since 9.0.0
483 *
484 * @param bool $is_frontend Whether the current request is for accessing the frontend.
485 */
486 return (bool) apply_filters( 'jetpack_is_frontend', $is_frontend );
487 }
488