Completed
Push — update/switch-to-classic-edito... ( 0ac550 )
by
unknown
08:33
created

functions.global.php (4 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
16
/**
17
 * Disable direct access.
18
 */
19
if ( ! defined( 'ABSPATH' ) ) {
20
	exit;
21
}
22
23
/**
24
 * Set the admin language, based on user language.
25
 *
26
 * @since 4.5.0
27
 * @deprecated 6.6.0 Use Core function instead.
28
 *
29
 * @return string
30
 */
31
function jetpack_get_user_locale() {
32
	_deprecated_function( __FUNCTION__, 'jetpack-6.6.0', 'get_user_locale' );
33
	return get_user_locale();
34
}
35
36
/**
37
 * Determine if this site is an Atomic site or not looking first at the 'at_options' option.
38
 * As a fallback, check for presence of wpcomsh plugin to determine if a current site has undergone AT.
39
 *
40
 * @since 4.8.1
41
 *
42
 * @return bool
43
 */
44
function jetpack_is_atomic_site() {
45
	$at_options = get_option( 'at_options', array() );
46
	return ! empty( $at_options ) || defined( 'WPCOMSH__PLUGIN_FILE' );
47
}
48
49
/**
50
 * Register post type for migration.
51
 *
52
 * @since 5.2
53
 */
54
function jetpack_register_migration_post_type() {
55
	register_post_type(
56
		'jetpack_migration',
57
		array(
58
			'supports'     => array(),
59
			'taxonomies'   => array(),
60
			'hierarchical' => false,
61
			'public'       => false,
62
			'has_archive'  => false,
63
			'can_export'   => true,
64
		)
65
	);
66
}
67
68
/**
69
 * Stores migration data in the database.
70
 *
71
 * @since 5.2
72
 *
73
 * @param string $option_name  Option name.
74
 * @param bool   $option_value Option value.
75
 *
76
 * @return int|WP_Error
77
 */
78
function jetpack_store_migration_data( $option_name, $option_value ) {
79
	jetpack_register_migration_post_type();
80
81
	$insert = array(
82
		'post_title'            => $option_name,
83
		'post_content_filtered' => $option_value,
84
		'post_type'             => 'jetpack_migration',
85
		'post_date'             => gmdate( 'Y-m-d H:i:s', time() ),
86
	);
87
88
	$post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
89
90
	if ( null !== $post ) {
91
		$insert['ID'] = $post->ID;
92
	}
93
94
	return wp_insert_post( $insert, true );
95
}
96
97
/**
98
 * Retrieves legacy image widget data.
99
 *
100
 * @since 5.2
101
 *
102
 * @param string $option_name Option name.
103
 *
104
 * @return mixed|null
105
 */
106
function jetpack_get_migration_data( $option_name ) {
107
	$post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
108
109
	return null !== $post ? maybe_unserialize( $post->post_content_filtered ) : null;
110
}
111
112
/**
113
 * Prints a TOS blurb used throughout the connection prompts.
114
 *
115
 * @since 5.3
116
 *
117
 * @echo string
118
 */
119
function jetpack_render_tos_blurb() {
120
	printf(
121
		wp_kses(
122
			/* Translators: placeholders are links. */
123
			__( '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' ),
124
			array(
125
				'a'      => array(
126
					'href'   => array(),
127
					'target' => array(),
128
					'rel'    => array(),
129
				),
130
				'strong' => true,
131
			)
132
		),
133
		esc_url( Redirect::get_url( 'wpcom-tos' ) ),
134
		esc_url( Redirect::get_url( 'jetpack-support-what-data-does-jetpack-sync' ) )
135
	);
136
}
137
138
/**
139
 * Intervene upgrade process so Jetpack themes are downloaded with credentials.
140
 *
141
 * @since 5.3
142
 *
143
 * @param bool   $preempt Whether to preempt an HTTP request's return value. Default false.
144
 * @param array  $r       HTTP request arguments.
145
 * @param string $url     The request URL.
146
 *
147
 * @return array|bool|WP_Error
148
 */
149
function jetpack_theme_update( $preempt, $r, $url ) {
150
	if ( false !== stripos( $url, JETPACK__WPCOM_JSON_API_HOST . '/rest/v1/themes/download' ) ) {
151
		$file = $r['filename'];
152
		if ( ! $file ) {
153
			return new WP_Error( 'problem_creating_theme_file', esc_html__( 'Problem creating file for theme download', 'jetpack' ) );
0 ignored issues
show
The call to WP_Error::__construct() has too many arguments starting with 'problem_creating_theme_file'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
154
		}
155
		$theme = pathinfo( wp_parse_url( $url, PHP_URL_PATH ), PATHINFO_FILENAME );
0 ignored issues
show
The call to wp_parse_url() has too many arguments starting with PHP_URL_PATH.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
156
157
		// Remove filter to avoid endless loop since wpcom_json_api_request_as_blog uses this too.
158
		remove_filter( 'pre_http_request', 'jetpack_theme_update' );
159
		$result = Client::wpcom_json_api_request_as_blog(
160
			"themes/download/$theme.zip",
161
			'1.1',
162
			array(
163
				'stream'   => true,
164
				'filename' => $file,
165
			)
166
		);
167
168
		if ( 200 !== wp_remote_retrieve_response_code( $result ) ) {
169
			return new WP_Error( 'problem_fetching_theme', esc_html__( 'Problem downloading theme', 'jetpack' ) );
0 ignored issues
show
The call to WP_Error::__construct() has too many arguments starting with 'problem_fetching_theme'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
170
		}
171
		return $result;
172
	}
173
	return $preempt;
174
}
175
176
/**
177
 * Add the filter when a upgrade is going to be downloaded.
178
 *
179
 * @since 5.3
180
 *
181
 * @param bool $reply Whether to bail without returning the package. Default false.
182
 *
183
 * @return bool
184
 */
185
function jetpack_upgrader_pre_download( $reply ) {
186
	add_filter( 'pre_http_request', 'jetpack_theme_update', 10, 3 );
187
	return $reply;
188
}
189
190
add_filter( 'upgrader_pre_download', 'jetpack_upgrader_pre_download' );
191
192
193
/**
194
 * Wraps data in a way so that we can distinguish between objects and array and also prevent object recursion.
195
 *
196
 * @since 6.1.0
197
 *
198
 * @param array|obj $any        Source data to be cleaned up.
199
 * @param array     $seen_nodes Built array of nodes.
200
 *
201
 * @return array
202
 */
203 View Code Duplication
function jetpack_json_wrap( &$any, $seen_nodes = array() ) {
204
	if ( is_object( $any ) ) {
205
		$input        = get_object_vars( $any );
206
		$input['__o'] = 1;
207
	} else {
208
		$input = &$any;
209
	}
210
211
	if ( is_array( $input ) ) {
212
		$seen_nodes[] = &$any;
213
214
		$return = array();
215
216
		foreach ( $input as $k => &$v ) {
217
			if ( ( is_array( $v ) || is_object( $v ) ) ) {
218
				if ( in_array( $v, $seen_nodes, true ) ) {
219
					continue;
220
				}
221
				$return[ $k ] = jetpack_json_wrap( $v, $seen_nodes );
0 ignored issues
show
It seems like $v can also be of type object; however, jetpack_json_wrap() does only seem to accept array|object<obj>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
222
			} else {
223
				$return[ $k ] = $v;
224
			}
225
		}
226
227
		return $return;
228
	}
229
230
	return $any;
231
}
232
233
/**
234
 * Checks if the mime_content_type function is available and return it if so.
235
 *
236
 * The function mime_content_type is enabled by default in PHP, but can be disabled. We attempt to
237
 * enforce this via composer.json, but that won't be checked in majority of cases where
238
 * this would be happening.
239
 *
240
 * @since 7.8.0
241
 *
242
 * @param string $file File location.
243
 *
244
 * @return string|false MIME type or false if functionality is not available.
245
 */
246
function jetpack_mime_content_type( $file ) {
247
	if ( function_exists( 'mime_content_type' ) ) {
248
		return mime_content_type( $file );
249
	}
250
251
	return false;
252
}
253
254
/**
255
 * Checks that the mime type of the specified file is among those in a filterable list of mime types.
256
 *
257
 * @since 7.8.0
258
 *
259
 * @param string $file Path to file to get its mime type.
260
 *
261
 * @return bool
262
 */
263
function jetpack_is_file_supported_for_sideloading( $file ) {
264
	$type = jetpack_mime_content_type( $file );
265
266
	if ( ! $type ) {
267
		return false;
268
	}
269
270
	/**
271
	 * Filter the list of supported mime types for media sideloading.
272
	 *
273
	 * @since 4.0.0
274
	 *
275
	 * @module json-api
276
	 *
277
	 * @param array $supported_mime_types Array of the supported mime types for media sideloading.
278
	 */
279
	$supported_mime_types = apply_filters(
280
		'jetpack_supported_media_sideload_types',
281
		array(
282
			'image/png',
283
			'image/jpeg',
284
			'image/gif',
285
			'image/bmp',
286
			'video/quicktime',
287
			'video/mp4',
288
			'video/mpeg',
289
			'video/ogg',
290
			'video/3gpp',
291
			'video/3gpp2',
292
			'video/h261',
293
			'video/h262',
294
			'video/h264',
295
			'video/x-msvideo',
296
			'video/x-ms-wmv',
297
			'video/x-ms-asf',
298
		)
299
	);
300
301
	// If the type returned was not an array as expected, then we know we don't have a match.
302
	if ( ! is_array( $supported_mime_types ) ) {
303
		return false;
304
	}
305
306
	return in_array( $type, $supported_mime_types, true );
307
}
308