Completed
Push — update/deprecation-errors ( 27ec29 )
by Jeremy
08:40 queued 13s
created

functions.global.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 or not Jetpack is active.
7
 *
8
 * Please namespace with jetpack_
9
 *
10
 * @package Jetpack
11
 */
12
13
use Automattic\Jetpack\Connection\Client;
14
use Automattic\Jetpack\Redirect;
15
use Automattic\Jetpack\Device_Detection;
16
17
/**
18
 * Disable direct access.
19
 */
20
if ( ! defined( 'ABSPATH' ) ) {
21
	exit;
22
}
23
24
/**
25
 * Hook into Core's _deprecated_function
26
 * Add more details about when a deprecated function will be removed.
27
 *
28
 * @since 8.8.0
29
 *
30
 * @param string $function    The function that was called.
31
 * @param string $replacement Optional. The function that should have been called. Default null.
32
 * @param string $version     The version of Jetpack that deprecated the function.
33
 */
34 View Code Duplication
function jetpack_deprecated_function( $function, $replacement, $version ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
35
	// Look for when a function will be removed based on when it was deprecated.
36
	$removed_version = jetpack_get_future_removed_version( $version );
37
38
	// If we could find a version, let's log a message about when removal will happen.
39
	if (
40
		! empty( $removed_version )
41
		&& ( defined( 'WP_DEBUG' ) && WP_DEBUG )
42
	) {
43
		error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
44
			sprintf(
45
				/* Translators: 1. Function name. 2. Jetpack version number. */
46
				__( 'The %1$s function will be removed from the Jetpack plugin in version %2$s.', 'jetpack' ),
47
				$function,
48
				$removed_version
49
			)
50
		);
51
52
	}
53
}
54
add_action( 'deprecated_function_run', 'jetpack_deprecated_function', 10, 3 );
55
56
/**
57
 * Hook into Core's _deprecated_file
58
 * Add more details about when a deprecated file will be removed.
59
 *
60
 * @since 8.8.0
61
 *
62
 * @param string $file        The file that was called.
63
 * @param string $replacement The file that should have been included based on ABSPATH.
64
 * @param string $version     The version of WordPress that deprecated the file.
65
 * @param string $message     A message regarding the change.
66
 */
67 View Code Duplication
function jetpack_deprecated_file( $file, $replacement, $version, $message ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
68
	// Look for when a file will be removed based on when it was deprecated.
69
	$removed_version = jetpack_get_future_removed_version( $version );
70
71
	// If we could find a version, let's log a message about when removal will happen.
72
	if (
73
		! empty( $removed_version )
74
		&& ( defined( 'WP_DEBUG' ) && WP_DEBUG )
75
	) {
76
		error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
77
			sprintf(
78
				/* Translators: 1. File name. 2. Jetpack version number. */
79
				__( 'The %1$s file will be removed from the Jetpack plugin in version %2$s.', 'jetpack' ),
80
				$file,
81
				$removed_version
82
			)
83
		);
84
85
	}
86
}
87
add_action( 'deprecated_file_included', 'jetpack_deprecated_file', 10, 4 );
88
89
/**
90
 * Get the major version number of Jetpack 6 months after provided version.
91
 * Useful to indicate when a deprecated function will be removed from Jetpack.
92
 *
93
 * @since 8.8.0
94
 *
95
 * @param string $version The version of WordPress that deprecated the function.
96
 *
97
 * @return string|float Return a Jetpack Major version number, or an empty string.
98
 */
99
function jetpack_get_future_removed_version( $version ) {
100
	/*
101
	 * Extract the version number from a deprecation notice.
102
	 * (let's only keep the first decimal, e.g. 8.8 and not 8.8.0)
103
	 */
104
	preg_match( '#(([0-9]+\.[0-9]+)(?:\.[0-9]+)*)#', $version, $matches );
105
106
	if ( ! empty( $matches[2] ) ) {
107
		// We'll remove the function from the code 6 months later, thus 6 major versions later.
108
		$removed_version = $matches[2] + 0.6;
109
110
		return (float) $removed_version;
111
	}
112
113
	return '';
114
}
115
116
/**
117
 * Set the admin language, based on user language.
118
 *
119
 * @since 4.5.0
120
 * @deprecated 6.6.0 Use Core function instead.
121
 *
122
 * @return string
123
 */
124
function jetpack_get_user_locale() {
125
	_deprecated_function( __FUNCTION__, 'jetpack-6.6.0', 'get_user_locale' );
126
	return get_user_locale();
127
}
128
129
/**
130
 * Determine if this site is an Atomic site or not looking first at the 'at_options' option.
131
 * As a fallback, check for presence of wpcomsh plugin to determine if a current site has undergone AT.
132
 *
133
 * @since 4.8.1
134
 *
135
 * @return bool
136
 */
137
function jetpack_is_atomic_site() {
138
	$at_options = get_option( 'at_options', array() );
139
	return ! empty( $at_options ) || defined( 'WPCOMSH__PLUGIN_FILE' );
140
}
141
142
/**
143
 * Register post type for migration.
144
 *
145
 * @since 5.2
146
 */
147
function jetpack_register_migration_post_type() {
148
	register_post_type(
149
		'jetpack_migration',
150
		array(
151
			'supports'     => array(),
152
			'taxonomies'   => array(),
153
			'hierarchical' => false,
154
			'public'       => false,
155
			'has_archive'  => false,
156
			'can_export'   => true,
157
		)
158
	);
159
}
160
161
/**
162
 * Stores migration data in the database.
163
 *
164
 * @since 5.2
165
 *
166
 * @param string $option_name  Option name.
167
 * @param bool   $option_value Option value.
168
 *
169
 * @return int|WP_Error
170
 */
171
function jetpack_store_migration_data( $option_name, $option_value ) {
172
	jetpack_register_migration_post_type();
173
174
	$insert = array(
175
		'post_title'            => $option_name,
176
		'post_content_filtered' => $option_value,
177
		'post_type'             => 'jetpack_migration',
178
		'post_date'             => gmdate( 'Y-m-d H:i:s', time() ),
179
	);
180
181
	$post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
182
183
	if ( null !== $post ) {
184
		$insert['ID'] = $post->ID;
185
	}
186
187
	return wp_insert_post( $insert, true );
188
}
189
190
/**
191
 * Retrieves legacy image widget data.
192
 *
193
 * @since 5.2
194
 *
195
 * @param string $option_name Option name.
196
 *
197
 * @return mixed|null
198
 */
199
function jetpack_get_migration_data( $option_name ) {
200
	$post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
201
202
	return null !== $post ? maybe_unserialize( $post->post_content_filtered ) : null;
203
}
204
205
/**
206
 * Prints a TOS blurb used throughout the connection prompts.
207
 *
208
 * @since 5.3
209
 *
210
 * @echo string
211
 */
212
function jetpack_render_tos_blurb() {
213
	printf(
214
		wp_kses(
215
			/* Translators: placeholders are links. */
216
			__( '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' ),
217
			array(
218
				'a'      => array(
219
					'href'   => array(),
220
					'target' => array(),
221
					'rel'    => array(),
222
				),
223
				'strong' => true,
224
			)
225
		),
226
		esc_url( Redirect::get_url( 'wpcom-tos' ) ),
227
		esc_url( Redirect::get_url( 'jetpack-support-what-data-does-jetpack-sync' ) )
228
	);
229
}
230
231
/**
232
 * Intervene upgrade process so Jetpack themes are downloaded with credentials.
233
 *
234
 * @since 5.3
235
 *
236
 * @param bool   $preempt Whether to preempt an HTTP request's return value. Default false.
237
 * @param array  $r       HTTP request arguments.
238
 * @param string $url     The request URL.
239
 *
240
 * @return array|bool|WP_Error
241
 */
242
function jetpack_theme_update( $preempt, $r, $url ) {
243
	if ( false !== stripos( $url, JETPACK__WPCOM_JSON_API_HOST . '/rest/v1/themes/download' ) ) {
244
		$file = $r['filename'];
245
		if ( ! $file ) {
246
			return new WP_Error( 'problem_creating_theme_file', esc_html__( 'Problem creating file for theme download', 'jetpack' ) );
247
		}
248
		$theme = pathinfo( wp_parse_url( $url, PHP_URL_PATH ), PATHINFO_FILENAME );
249
250
		// Remove filter to avoid endless loop since wpcom_json_api_request_as_blog uses this too.
251
		remove_filter( 'pre_http_request', 'jetpack_theme_update' );
252
		$result = Client::wpcom_json_api_request_as_blog(
253
			"themes/download/$theme.zip",
254
			'1.1',
255
			array(
256
				'stream'   => true,
257
				'filename' => $file,
258
			)
259
		);
260
261
		if ( 200 !== wp_remote_retrieve_response_code( $result ) ) {
262
			return new WP_Error( 'problem_fetching_theme', esc_html__( 'Problem downloading theme', 'jetpack' ) );
263
		}
264
		return $result;
265
	}
266
	return $preempt;
267
}
268
269
/**
270
 * Add the filter when a upgrade is going to be downloaded.
271
 *
272
 * @since 5.3
273
 *
274
 * @param bool $reply Whether to bail without returning the package. Default false.
275
 *
276
 * @return bool
277
 */
278
function jetpack_upgrader_pre_download( $reply ) {
279
	add_filter( 'pre_http_request', 'jetpack_theme_update', 10, 3 );
280
	return $reply;
281
}
282
283
add_filter( 'upgrader_pre_download', 'jetpack_upgrader_pre_download' );
284
285
286
/**
287
 * Wraps data in a way so that we can distinguish between objects and array and also prevent object recursion.
288
 *
289
 * @since 6.1.0
290
 *
291
 * @param array|obj $any        Source data to be cleaned up.
292
 * @param array     $seen_nodes Built array of nodes.
293
 *
294
 * @return array
295
 */
296 View Code Duplication
function jetpack_json_wrap( &$any, $seen_nodes = array() ) {
297
	if ( is_object( $any ) ) {
298
		$input        = get_object_vars( $any );
299
		$input['__o'] = 1;
300
	} else {
301
		$input = &$any;
302
	}
303
304
	if ( is_array( $input ) ) {
305
		$seen_nodes[] = &$any;
306
307
		$return = array();
308
309
		foreach ( $input as $k => &$v ) {
310
			if ( ( is_array( $v ) || is_object( $v ) ) ) {
311
				if ( in_array( $v, $seen_nodes, true ) ) {
312
					continue;
313
				}
314
				$return[ $k ] = jetpack_json_wrap( $v, $seen_nodes );
315
			} else {
316
				$return[ $k ] = $v;
317
			}
318
		}
319
320
		return $return;
321
	}
322
323
	return $any;
324
}
325
326
/**
327
 * Checks if the mime_content_type function is available and return it if so.
328
 *
329
 * The function mime_content_type is enabled by default in PHP, but can be disabled. We attempt to
330
 * enforce this via composer.json, but that won't be checked in majority of cases where
331
 * this would be happening.
332
 *
333
 * @since 7.8.0
334
 *
335
 * @param string $file File location.
336
 *
337
 * @return string|false MIME type or false if functionality is not available.
338
 */
339
function jetpack_mime_content_type( $file ) {
340
	if ( function_exists( 'mime_content_type' ) ) {
341
		return mime_content_type( $file );
342
	}
343
344
	return false;
345
}
346
347
/**
348
 * Checks that the mime type of the specified file is among those in a filterable list of mime types.
349
 *
350
 * @since 7.8.0
351
 *
352
 * @param string $file Path to file to get its mime type.
353
 *
354
 * @return bool
355
 */
356
function jetpack_is_file_supported_for_sideloading( $file ) {
357
	$type = jetpack_mime_content_type( $file );
358
359
	if ( ! $type ) {
360
		return false;
361
	}
362
363
	/**
364
	 * Filter the list of supported mime types for media sideloading.
365
	 *
366
	 * @since 4.0.0
367
	 *
368
	 * @module json-api
369
	 *
370
	 * @param array $supported_mime_types Array of the supported mime types for media sideloading.
371
	 */
372
	$supported_mime_types = apply_filters(
373
		'jetpack_supported_media_sideload_types',
374
		array(
375
			'image/png',
376
			'image/jpeg',
377
			'image/gif',
378
			'image/bmp',
379
			'video/quicktime',
380
			'video/mp4',
381
			'video/mpeg',
382
			'video/ogg',
383
			'video/3gpp',
384
			'video/3gpp2',
385
			'video/h261',
386
			'video/h262',
387
			'video/h264',
388
			'video/x-msvideo',
389
			'video/x-ms-wmv',
390
			'video/x-ms-asf',
391
		)
392
	);
393
394
	// If the type returned was not an array as expected, then we know we don't have a match.
395
	if ( ! is_array( $supported_mime_types ) ) {
396
		return false;
397
	}
398
399
	return in_array( $type, $supported_mime_types, true );
400
}
401
402
/**
403
 * Determine if the current User Agent matches the passed $kind
404
 *
405
 * @param string $kind Category of mobile device to check for.
406
 *                         Either: any, dumb, smart.
407
 * @param bool   $return_matched_agent Boolean indicating if the UA should be returned.
408
 *
409
 * @return bool|string Boolean indicating if current UA matches $kind. If
410
 *                              $return_matched_agent is true, returns the UA string
411
 */
412
function jetpack_is_mobile( $kind = 'any', $return_matched_agent = false ) {
413
414
	/**
415
	 * Filter the value of jetpack_is_mobile before it is calculated.
416
	 *
417
	 * Passing a truthy value to the filter will short-circuit determining the
418
	 * mobile type, returning the passed value instead.
419
	 *
420
	 * @since  4.2.0
421
	 *
422
	 * @param bool|string $matches Boolean if current UA matches $kind or not. If
423
	 *                             $return_matched_agent is true, should return the UA string
424
	 * @param string      $kind Category of mobile device being checked
425
	 * @param bool        $return_matched_agent Boolean indicating if the UA should be returned
426
	 */
427
	$pre = apply_filters( 'pre_jetpack_is_mobile', null, $kind, $return_matched_agent );
428
	if ( $pre ) {
429
		return $pre;
430
	}
431
432
	$return      = false;
433
	$device_info = Device_Detection::get_info();
434
435
	if ( 'any' === $kind ) {
436
		$return = $device_info['is_phone'];
437
	} elseif ( 'smart' === $kind ) {
438
		$return = $device_info['is_smartphone'];
439
	} elseif ( 'dumb' === $kind ) {
440
		$return = $device_info['is_phone'] && ! $device_info['is_smartphone'];
441
	}
442
443
	if ( $return_matched_agent && true === $return ) {
444
		$return = $device_info['is_phone_matched_ua'];
445
	}
446
447
	/**
448
	 * Filter the value of jetpack_is_mobile
449
	 *
450
	 * @since  4.2.0
451
	 *
452
	 * @param bool|string $matches Boolean if current UA matches $kind or not. If
453
	 *                             $return_matched_agent is true, should return the UA string
454
	 * @param string      $kind Category of mobile device being checked
455
	 * @param bool        $return_matched_agent Boolean indicating if the UA should be returned
456
	 */
457
	return apply_filters( 'jetpack_is_mobile', $return, $kind, $return_matched_agent );
458
}
459