PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 15.0
Jetpack – WP Security, Backup, Speed, & Growth v15.0
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
499 lines 13.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
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\Redirect;
15 use Automattic\Jetpack\Status\Host;
16 use Automattic\Jetpack\Status\Request;
17 use Automattic\Jetpack\Sync\Functions;
18
19 // Disable direct access.
20 if ( ! defined( 'ABSPATH' ) ) {
21 exit( 0 );
22 }
23
24 require_once __DIR__ . '/functions.is-mobile.php';
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 ( ! str_starts_with( $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 doing_action( 'after_setup_theme' ) || did_action( 'after_setup_theme' ) ?
55 /* Translators: 1. Function name. 2. Jetpack version number. */
56 __( 'The %1$s function will be removed from the Jetpack plugin in version %2$s.', 'jetpack' )
57 : 'The %1$s function will be removed from the Jetpack plugin in version %2$s.',
58 $function,
59 $removed_version
60 )
61 );
62
63 }
64 }
65 add_action( 'deprecated_function_run', 'jetpack_deprecated_function', 10, 3 );
66
67 /**
68 * Hook into Core's _deprecated_file
69 * Add more details about when a deprecated file will be removed.
70 *
71 * @since 8.8.0
72 *
73 * @param string $file The file that was called.
74 * @param string $replacement The file that should have been included based on ABSPATH.
75 * @param string $version The version of WordPress that deprecated the file.
76 * @param string $message A message regarding the change.
77 */
78 function jetpack_deprecated_file( $file, $replacement, $version, $message ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
79 // Bail early for non-Jetpack deprecations.
80 if ( ! str_starts_with( $version, 'jetpack-' ) ) {
81 return;
82 }
83
84 // Look for when a file will be removed based on when it was deprecated.
85 $removed_version = jetpack_get_future_removed_version( $version );
86
87 // If we could find a version, let's log a message about when removal will happen.
88 if (
89 ! empty( $removed_version )
90 && ( defined( 'WP_DEBUG' ) && WP_DEBUG )
91 /** This filter is documented in core/src/wp-includes/functions.php */
92 && apply_filters( 'deprecated_file_trigger_error', true )
93 ) {
94 error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
95 sprintf(
96 /* Translators: 1. File name. 2. Jetpack version number. */
97 __( 'The %1$s file will be removed from the Jetpack plugin in version %2$s.', 'jetpack' ),
98 $file,
99 $removed_version
100 )
101 );
102
103 }
104 }
105 add_action( 'deprecated_file_included', 'jetpack_deprecated_file', 10, 4 );
106
107 /**
108 * Get the major version number of Jetpack 6 months after provided version.
109 * Useful to indicate when a deprecated function will be removed from Jetpack.
110 *
111 * @since 8.8.0
112 *
113 * @param string $version The version of WordPress that deprecated the function.
114 *
115 * @return bool|float Return a Jetpack Major version number, or false.
116 */
117 function jetpack_get_future_removed_version( $version ) {
118 /*
119 * Extract the version number from a deprecation notice.
120 * (let's only keep the first decimal, e.g. 8.8 and not 8.8.0)
121 */
122 preg_match( '#(([0-9]+\.([0-9]+))(?:\.[0-9]+)*)#', $version, $matches );
123
124 if ( isset( $matches[2] ) && isset( $matches[3] ) ) {
125 $deprecated_version = (float) $matches[2];
126 $deprecated_minor = (float) $matches[3];
127
128 /*
129 * If the detected minor version number
130 * (e.g. "7" in "8.7")
131 * is higher than 9, we know the version number is malformed.
132 * Jetpack does not use semver yet.
133 * Bail.
134 */
135 if ( 10 <= $deprecated_minor ) {
136 return false;
137 }
138
139 // We'll remove the function from the code 6 months later, thus 6 major versions later.
140 $removed_version = $deprecated_version + 0.6;
141
142 return (float) $removed_version;
143 }
144
145 return false;
146 }
147
148 /**
149 * Determine if this site is an WoA site or not by looking for presence of the wpcomsh plugin.
150 *
151 * @since 4.8.1
152 * @deprecated 10.3.0
153 *
154 * @return bool
155 */
156 function jetpack_is_atomic_site() {
157 jetpack_deprecated_function( __FUNCTION__, 'Automattic/Jetpack/Status/Host::is_woa_site', 'jetpack-10.3.0' );
158 return ( new Host() )->is_woa_site();
159 }
160
161 /**
162 * Register post type for migration.
163 *
164 * @since 5.2
165 */
166 function jetpack_register_migration_post_type() {
167 register_post_type(
168 'jetpack_migration',
169 array(
170 'supports' => array(),
171 'taxonomies' => array(),
172 'hierarchical' => false,
173 'public' => false,
174 'has_archive' => false,
175 'can_export' => true,
176 )
177 );
178 }
179
180 /**
181 * Checks whether the Post DB threat currently exists on the site.
182 *
183 * @since 12.0
184 *
185 * @param string $option_name Option name.
186 *
187 * @return WP_Post|bool
188 */
189 function jetpack_migration_post_exists( $option_name ) {
190 $query = new WP_Query(
191 array(
192 'post_type' => 'jetpack_migration',
193 'title' => $option_name,
194 'post_status' => 'all',
195 'posts_per_page' => 1,
196 'no_found_rows' => true,
197 'ignore_sticky_posts' => true,
198 'update_post_term_cache' => false,
199 'update_post_meta_cache' => false,
200 'orderby' => 'post_date ID',
201 'order' => 'ASC',
202 )
203 );
204 if ( ! empty( $query->post ) ) {
205 return $query->post;
206 }
207
208 return false;
209 }
210
211 /**
212 * Stores migration data in the database.
213 *
214 * @since 5.2
215 *
216 * @param string $option_name Option name.
217 * @param bool $option_value Option value.
218 *
219 * @return int|WP_Error
220 */
221 function jetpack_store_migration_data( $option_name, $option_value ) {
222 jetpack_register_migration_post_type();
223
224 $insert = array(
225 'post_title' => $option_name,
226 'post_content_filtered' => $option_value,
227 'post_type' => 'jetpack_migration',
228 'post_date' => gmdate( 'Y-m-d H:i:s', time() ),
229 );
230
231 $migration_post = jetpack_migration_post_exists( $option_name );
232 if ( $migration_post ) {
233 $insert['ID'] = $migration_post->ID;
234 }
235
236 return wp_insert_post( $insert, true );
237 }
238
239 /**
240 * Retrieves legacy image widget data.
241 *
242 * @since 5.2
243 *
244 * @param string $option_name Option name.
245 *
246 * @return mixed|null
247 */
248 function jetpack_get_migration_data( $option_name ) {
249 $post = jetpack_migration_post_exists( $option_name );
250
251 return null !== $post ? maybe_unserialize( $post->post_content_filtered ) : null;
252 }
253
254 /**
255 * Prints a TOS blurb used throughout the connection prompts.
256 *
257 * @since 5.3
258 *
259 * @echo string
260 */
261 function jetpack_render_tos_blurb() {
262 printf(
263 wp_kses(
264 /* Translators: placeholders are links. */
265 __( 'By clicking <strong>Set up Jetpack</strong>, 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">sync your site‘s data</a> with us.', 'jetpack' ),
266 array(
267 'a' => array(
268 'href' => array(),
269 'target' => array(),
270 'rel' => array(),
271 ),
272 'strong' => true,
273 )
274 ),
275 esc_url( Redirect::get_url( 'wpcom-tos' ) ),
276 esc_url( Redirect::get_url( 'jetpack-support-what-data-does-jetpack-sync' ) )
277 );
278 }
279
280 /**
281 * Intervene upgrade process so Jetpack themes are downloaded with credentials.
282 *
283 * @since 5.3
284 *
285 * @param bool $preempt Whether to preempt an HTTP request's return value. Default false.
286 * @param array $r HTTP request arguments.
287 * @param string $url The request URL.
288 *
289 * @return array|bool|WP_Error
290 */
291 function jetpack_theme_update( $preempt, $r, $url ) {
292 if ( 0 === stripos( $url, JETPACK__WPCOM_JSON_API_BASE . '/rest/v1/themes/download' ) ) {
293 $file = $r['filename'];
294 if ( ! $file ) {
295 return new WP_Error( 'problem_creating_theme_file', esc_html__( 'Problem creating file for theme download', 'jetpack' ) );
296 }
297 $theme = pathinfo( wp_parse_url( $url, PHP_URL_PATH ), PATHINFO_FILENAME );
298
299 // Remove filter to avoid endless loop since wpcom_json_api_request_as_blog uses this too.
300 remove_filter( 'pre_http_request', 'jetpack_theme_update' );
301 $result = Client::wpcom_json_api_request_as_blog(
302 "themes/download/$theme.zip",
303 '1.1',
304 array(
305 'stream' => true,
306 'filename' => $file,
307 )
308 );
309
310 if ( 200 !== wp_remote_retrieve_response_code( $result ) ) {
311 return new WP_Error( 'problem_fetching_theme', esc_html__( 'Problem downloading theme', 'jetpack' ) );
312 }
313 return $result;
314 }
315 return $preempt;
316 }
317
318 /**
319 * Add the filter when a upgrade is going to be downloaded.
320 *
321 * @since 5.3
322 *
323 * @param bool $reply Whether to bail without returning the package. Default false.
324 *
325 * @return bool
326 */
327 function jetpack_upgrader_pre_download( $reply ) {
328 add_filter( 'pre_http_request', 'jetpack_theme_update', 10, 3 );
329 return $reply;
330 }
331
332 add_filter( 'upgrader_pre_download', 'jetpack_upgrader_pre_download' );
333
334 /**
335 * Wraps data in a way so that we can distinguish between objects and array and also prevent object recursion.
336 *
337 * @since 6.1.0
338
339 * @deprecated Automattic\Jetpack\Sync\Functions::json_wrap
340 *
341 * @param mixed $any Source data to be cleaned up.
342 * @param array $seen_nodes Built array of nodes.
343 *
344 * @return array
345 */
346 function jetpack_json_wrap( &$any, $seen_nodes = array() ) {
347 _deprecated_function( __METHOD__, 'jetpack-9.5', 'Automattic\Jetpack\Sync\Functions' );
348
349 return Functions::json_wrap( $any, $seen_nodes );
350 }
351
352 /**
353 * Checks if the mime_content_type function is available and return it if so.
354 *
355 * The function mime_content_type is enabled by default in PHP, but can be disabled. We attempt to
356 * enforce this via composer.json, but that won't be checked in majority of cases where
357 * this would be happening.
358 *
359 * @since 7.8.0
360 *
361 * @param string $file File location.
362 *
363 * @return string|false MIME type or false if functionality is not available.
364 */
365 function jetpack_mime_content_type( $file ) {
366 if ( function_exists( 'mime_content_type' ) ) {
367 return mime_content_type( $file );
368 }
369
370 return false;
371 }
372
373 /**
374 * Checks that the mime type of the specified file is among those in a filterable list of mime types.
375 *
376 * @since 7.8.0
377 *
378 * @param string $file Path to file to get its mime type.
379 *
380 * @return bool
381 */
382 function jetpack_is_file_supported_for_sideloading( $file ) {
383 $type = jetpack_mime_content_type( $file );
384
385 if ( ! $type ) {
386 return false;
387 }
388
389 /**
390 * Filter the list of supported mime types for media sideloading.
391 *
392 * @since 4.0.0
393 *
394 * @module json-api
395 *
396 * @param array $supported_mime_types Array of the supported mime types for media sideloading.
397 */
398 $supported_mime_types = apply_filters(
399 'jetpack_supported_media_sideload_types',
400 array(
401 'image/png',
402 'image/jpeg',
403 'image/gif',
404 'image/bmp',
405 'image/webp',
406 'video/quicktime',
407 'video/mp4',
408 'video/mpeg',
409 'video/ogg',
410 'video/3gpp',
411 'video/3gpp2',
412 'video/h261',
413 'video/h262',
414 'video/h264',
415 'video/x-msvideo',
416 'video/x-ms-wmv',
417 'video/x-ms-asf',
418 )
419 );
420
421 // If the type returned was not an array as expected, then we know we don't have a match.
422 if ( ! is_array( $supported_mime_types ) ) {
423 return false;
424 }
425
426 return in_array( $type, $supported_mime_types, true );
427 }
428
429 /**
430 * Go through headers and get a list of Vary headers to add,
431 * including a Vary Accept header if necessary.
432 *
433 * @since 12.2
434 * @deprecated 14.8
435 *
436 * @param array $headers The headers to be sent.
437 *
438 * @return array $vary_header_parts Vary Headers to be sent.
439 */
440 function jetpack_get_vary_headers( $headers = array() ) {
441 _deprecated_function( __FUNCTION__, '14.8', 'Automattic\Jetpack\Status\Request::get_vary_headers' );
442
443 return ( new Request() )->get_vary_headers( $headers );
444 }
445
446 /**
447 * Determine whether the current request is for accessing the frontend.
448 * Also update Vary headers to indicate that the response may vary by Accept header.
449 *
450 * @deprecated 14.8
451 *
452 * @return bool True if it's a frontend request, false otherwise.
453 */
454 function jetpack_is_frontend() {
455 _deprecated_function( __FUNCTION__, '14.8', 'Automattic\Jetpack\Status\Request::is_frontend' );
456
457 return Request::is_frontend();
458 }
459
460 if ( ! function_exists( 'jetpack_mastodon_get_instance_list' ) ) {
461 /**
462 * Build a list of Mastodon instance hosts.
463 * That list can be extended via a filter.
464 *
465 * @todo This function is now replicated in the Classic Theme Helper package and can be
466 * removed here once Social Links are moved out of Jetpack.
467 *
468 * @since 11.8
469 *
470 * @return array
471 */
472 function jetpack_mastodon_get_instance_list() {
473 $mastodon_instance_list = array(
474 // Regex pattern to match any .tld for the mastodon host name.
475 '#https?:\/\/(www\.)?mastodon\.(\w+)(\.\w+)?#',
476 // Regex pattern to match any .tld for the mstdn host name.
477 '#https?:\/\/(www\.)?mstdn\.(\w+)(\.\w+)?#',
478 'counter.social',
479 'fosstodon.org',
480 'gc2.jp',
481 'hachyderm.io',
482 'infosec.exchange',
483 'mas.to',
484 'pawoo.net',
485 );
486
487 /**
488 * Filter the list of Mastodon instances.
489 *
490 * @since 11.8
491 *
492 * @module widgets, theme-tools
493 *
494 * @param array $mastodon_instance_list Array of Mastodon instances.
495 */
496 return (array) apply_filters( 'jetpack_mastodon_instance_list', $mastodon_instance_list );
497 }
498 }
499