Completed
Push — update/date-time ( 50c4ab )
by
unknown
06:46
created

functions.global.php ➔ wp_timezone()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
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
15
/**
16
 * Disable direct access.
17
 */
18
if ( ! defined( 'ABSPATH' ) ) {
19
	exit;
20
}
21
22
if ( ! function_exists( wp_timezone ) ) {
23
	/**
24
	 * Shim for WordPress 5.3's wp_timezone() function.
25
	 *
26
	 * This is a mix of wp_timezone(), which calls wp_timezone_string().
27
	 * We don't need both in Jetpack, so providing only one function.
28
	 *
29
	 * @since 7.9.0
30
	 * @todo Remove when WP 5.3 is Jetpack's minimum
31
	 *
32
	 * @return DateTimeZone Site's DateTimeZone
33
	 */
34
	function wp_timezone() {
35
		$timezone_string = get_option( 'timezone_string' );
36
37
		if ( $timezone_string ) {
38
			return new DateTimeZone( $timezone_string );
39
		}
40
41
		$offset  = (float) get_option( 'gmt_offset' );
42
		$hours   = (int) $offset;
43
		$minutes = ( $offset - $hours );
44
45
		$sign      = ( $offset < 0 ) ? '-' : '+';
46
		$abs_hour  = abs( $hours );
47
		$abs_mins  = abs( $minutes * 60 );
48
		$tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
49
50
		return new DateTimeZone( $tz_offset );
51
	}
52
}
53
54
/**
55
 * Set the admin language, based on user language.
56
 *
57
 * @since 4.5.0
58
 * @deprecated 6.6.0 Use Core function instead.
59
 *
60
 * @return string
61
 */
62
function jetpack_get_user_locale() {
63
	_deprecated_function( __FUNCTION__, 'jetpack-6.6.0', 'get_user_locale' );
64
	return get_user_locale();
65
}
66
67
/**
68
 * Determine if this site is an Atomic site or not looking first at the 'at_options' option.
69
 * As a fallback, check for presence of wpcomsh plugin to determine if a current site has undergone AT.
70
 *
71
 * @since 4.8.1
72
 *
73
 * @return bool
74
 */
75
function jetpack_is_atomic_site() {
76
	$at_options = get_option( 'at_options', array() );
77
	return ! empty( $at_options ) || defined( 'WPCOMSH__PLUGIN_FILE' );
78
}
79
80
/**
81
 * Register post type for migration.
82
 *
83
 * @since 5.2
84
 */
85
function jetpack_register_migration_post_type() {
86
	register_post_type(
87
		'jetpack_migration',
88
		array(
89
			'supports'     => array(),
90
			'taxonomies'   => array(),
91
			'hierarchical' => false,
92
			'public'       => false,
93
			'has_archive'  => false,
94
			'can_export'   => true,
95
		)
96
	);
97
}
98
99
/**
100
 * Stores migration data in the database.
101
 *
102
 * @since 5.2
103
 *
104
 * @param string $option_name  Option name.
105
 * @param bool   $option_value Option value.
106
 *
107
 * @return int|WP_Error
108
 */
109
function jetpack_store_migration_data( $option_name, $option_value ) {
110
	jetpack_register_migration_post_type();
111
112
	$insert = array(
113
		'post_title'            => $option_name,
114
		'post_content_filtered' => $option_value,
115
		'post_type'             => 'jetpack_migration',
116
		'post_date'             => date( 'Y-m-d H:i:s', time() ),
117
	);
118
119
	$post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
120
121
	if ( null !== $post ) {
122
		$insert['ID'] = $post->ID;
123
	}
124
125
	return wp_insert_post( $insert, true );
126
}
127
128
/**
129
 * Retrieves legacy image widget data.
130
 *
131
 * @since 5.2
132
 *
133
 * @param string $option_name Option name.
134
 *
135
 * @return mixed|null
136
 */
137
function jetpack_get_migration_data( $option_name ) {
138
	$post = get_page_by_title( $option_name, 'OBJECT', 'jetpack_migration' );
139
140
	return null !== $post ? maybe_unserialize( $post->post_content_filtered ) : null;
141
}
142
143
/**
144
 * Prints a TOS blurb used throughout the connection prompts.
145
 *
146
 * @since 5.3
147
 *
148
 * @echo string
149
 */
150
function jetpack_render_tos_blurb() {
151
	printf(
152
		wp_kses(
153
			/* Translators: placeholders are links. */
154
			__( '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' ),
155
			array(
156
				'a'      => array(
157
					'href'   => array(),
158
					'target' => array(),
159
					'rel'    => array(),
160
				),
161
				'strong' => true,
162
			)
163
		),
164
		'https://wordpress.com/tos',
165
		'https://jetpack.com/support/what-data-does-jetpack-sync'
166
	);
167
}
168
169
/**
170
 * Intervene upgrade process so Jetpack themes are downloaded with credentials.
171
 *
172
 * @since 5.3
173
 *
174
 * @param bool   $preempt Whether to preempt an HTTP request's return value. Default false.
175
 * @param array  $r       HTTP request arguments.
176
 * @param string $url     The request URL.
177
 *
178
 * @return array|bool|WP_Error
179
 */
180
function jetpack_theme_update( $preempt, $r, $url ) {
181
	if ( false !== stripos( $url, JETPACK__WPCOM_JSON_API_HOST . '/rest/v1/themes/download' ) ) {
182
		$file = $r['filename'];
183
		if ( ! $file ) {
184
			return new WP_Error( 'problem_creating_theme_file', esc_html__( 'Problem creating file for theme download', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
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...
185
		}
186
		$theme = pathinfo( wp_parse_url( $url, PHP_URL_PATH ), PATHINFO_FILENAME );
187
188
		// Remove filter to avoid endless loop since wpcom_json_api_request_as_blog uses this too.
189
		remove_filter( 'pre_http_request', 'jetpack_theme_update' );
190
		$result = Client::wpcom_json_api_request_as_blog(
191
			"themes/download/$theme.zip",
192
			'1.1',
193
			array(
194
				'stream'   => true,
195
				'filename' => $file,
196
			)
197
		);
198
199
		if ( 200 !== wp_remote_retrieve_response_code( $result ) ) {
200
			return new WP_Error( 'problem_fetching_theme', esc_html__( 'Problem downloading theme', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
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...
201
		}
202
		return $result;
203
	}
204
	return $preempt;
205
}
206
207
/**
208
 * Add the filter when a upgrade is going to be downloaded.
209
 *
210
 * @since 5.3
211
 *
212
 * @param bool $reply Whether to bail without returning the package. Default false.
213
 *
214
 * @return bool
215
 */
216
function jetpack_upgrader_pre_download( $reply ) {
217
	add_filter( 'pre_http_request', 'jetpack_theme_update', 10, 3 );
218
	return $reply;
219
}
220
221
add_filter( 'upgrader_pre_download', 'jetpack_upgrader_pre_download' );
222
223
224
/**
225
 * Wraps data in a way so that we can distinguish between objects and array and also prevent object recursion.
226
 *
227
 * @since 6.1.0
228
 *
229
 * @param array|obj $any        Source data to be cleaned up.
230
 * @param array     $seen_nodes Built array of nodes.
231
 *
232
 * @return array
233
 */
234 View Code Duplication
function jetpack_json_wrap( &$any, $seen_nodes = array() ) {
0 ignored issues
show
Duplication introduced by
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...
235
	if ( is_object( $any ) ) {
236
		$input        = get_object_vars( $any );
237
		$input['__o'] = 1;
238
	} else {
239
		$input = &$any;
240
	}
241
242
	if ( is_array( $input ) ) {
243
		$seen_nodes[] = &$any;
244
245
		$return = array();
246
247
		foreach ( $input as $k => &$v ) {
248
			if ( ( is_array( $v ) || is_object( $v ) ) ) {
249
				if ( in_array( $v, $seen_nodes, true ) ) {
250
					continue;
251
				}
252
				$return[ $k ] = jetpack_json_wrap( $v, $seen_nodes );
0 ignored issues
show
Bug introduced by
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...
253
			} else {
254
				$return[ $k ] = $v;
255
			}
256
		}
257
258
		return $return;
259
	}
260
261
	return $any;
262
}
263
264
/**
265
 * Checks if the mime_content_type function is available and return it if so.
266
 *
267
 * The function mime_content_type is enabled by default in PHP, but can be disabled. We attempt to
268
 * enforce this via composer.json, but that won't be checked in majority of cases where
269
 * this would be happening.
270
 *
271
 * @since 7.8.0
272
 *
273
 * @param string $file File location.
274
 *
275
 * @return string|false MIME type or false if functionality is not available.
276
 */
277
function jetpack_mime_content_type( $file ) {
278
	if ( function_exists( 'mime_content_type' ) ) {
279
		return mime_content_type( $file );
280
	}
281
282
	return false;
283
}
284
285
/**
286
 * Checks that the mime type of the specified file is among those in a filterable list of mime types.
287
 *
288
 * @since 7.8.0
289
 *
290
 * @param string $file Path to file to get its mime type.
291
 *
292
 * @return bool
293
 */
294
function jetpack_is_file_supported_for_sideloading( $file ) {
295
	$type = jetpack_mime_content_type( $file );
296
297
	if ( ! $type ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $type of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
298
		return false;
299
	}
300
301
	/**
302
	 * Filter the list of supported mime types for media sideloading.
303
	 *
304
	 * @since 4.0.0
305
	 *
306
	 * @module json-api
307
	 *
308
	 * @param array $supported_mime_types Array of the supported mime types for media sideloading.
309
	 */
310
	$supported_mime_types = apply_filters(
311
		'jetpack_supported_media_sideload_types',
312
		array(
313
			'image/png',
314
			'image/jpeg',
315
			'image/gif',
316
			'image/bmp',
317
			'video/quicktime',
318
			'video/mp4',
319
			'video/mpeg',
320
			'video/ogg',
321
			'video/3gpp',
322
			'video/3gpp2',
323
			'video/h261',
324
			'video/h262',
325
			'video/h264',
326
			'video/x-msvideo',
327
			'video/x-ms-wmv',
328
			'video/x-ms-asf',
329
		)
330
	);
331
332
	// If the type returned was not an array as expected, then we know we don't have a match.
333
	if ( ! is_array( $supported_mime_types ) ) {
334
		return false;
335
	}
336
337
	return in_array( $type, $supported_mime_types, true );
338
}
339