These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Class Jetpack_Constants |
||
5 | * This class is not meant to be used directly |
||
6 | * but the Jetpack class inherits from it for clarity's sanitize_key |
||
7 | * |
||
8 | * If you need to use any of the methods here just use them likes |
||
9 | * Jetpack::method_name() for using it statically. |
||
10 | * Jetpack::init()->method_name() for using it from an instance. |
||
11 | */ |
||
12 | abstract class Jetpack_Functions { |
||
13 | |||
14 | /** |
||
15 | * Determine whether the active plan supports a particular feature |
||
16 | * |
||
17 | * @uses Jetpack::get_active_plan() |
||
18 | * |
||
19 | * @access public |
||
20 | * @static |
||
21 | * |
||
22 | * @return bool True if plan supports feature, false if not |
||
23 | */ |
||
24 | public static function active_plan_supports( $feature ) { |
||
25 | $plan = Jetpack::get_active_plan(); |
||
26 | |||
27 | // Manually mapping WordPress.com features to Jetpack module slugs |
||
28 | foreach ( $plan['features']['active'] as $wpcom_feature ) { |
||
29 | switch ( $wpcom_feature ) { |
||
30 | case 'wordads-jetpack'; |
||
31 | |||
32 | // WordAds are supported for this site |
||
33 | if ( 'wordads' === $feature ) { |
||
34 | return true; |
||
35 | } |
||
36 | break; |
||
37 | } |
||
38 | } |
||
39 | |||
40 | if ( |
||
41 | in_array( $feature, $plan['supports'] ) |
||
42 | || in_array( $feature, $plan['features']['active'] ) |
||
43 | ) { |
||
44 | return true; |
||
45 | } |
||
46 | |||
47 | return false; |
||
48 | } |
||
49 | |||
50 | public static function admin_url( $args = null ) { |
||
51 | $args = wp_parse_args( $args, array( 'page' => 'jetpack' ) ); |
||
52 | $url = add_query_arg( $args, admin_url( 'admin.php' ) ); |
||
53 | return $url; |
||
54 | } |
||
55 | |||
56 | /** |
||
57 | * Converts any url in a stylesheet, to the correct absolute url. |
||
58 | * |
||
59 | * Considerations: |
||
60 | * - Normal, relative URLs `feh.png` |
||
61 | * - Data URLs `data:image/gif;base64,eh129ehiuehjdhsa==` |
||
62 | * - Schema-agnostic URLs `//domain.com/feh.png` |
||
63 | * - Absolute URLs `http://domain.com/feh.png` |
||
64 | * - Domain root relative URLs `/feh.png` |
||
65 | * |
||
66 | * @param $css string: The raw CSS -- should be read in directly from the file. |
||
67 | * @param $css_file_url : The URL that the file can be accessed at, for calculating paths from. |
||
68 | * |
||
69 | * @return mixed|string |
||
70 | */ |
||
71 | public static function absolutize_css_urls( $css, $css_file_url ) { |
||
72 | $pattern = '#url\((?P<path>[^)]*)\)#i'; |
||
73 | $css_dir = dirname( $css_file_url ); |
||
74 | $p = parse_url( $css_dir ); |
||
75 | $domain = sprintf( |
||
76 | '%1$s//%2$s%3$s%4$s', |
||
77 | isset( $p['scheme'] ) ? "{$p['scheme']}:" : '', |
||
78 | isset( $p['user'], $p['pass'] ) ? "{$p['user']}:{$p['pass']}@" : '', |
||
79 | $p['host'], |
||
80 | isset( $p['port'] ) ? ":{$p['port']}" : '' |
||
81 | ); |
||
82 | |||
83 | if ( preg_match_all( $pattern, $css, $matches, PREG_SET_ORDER ) ) { |
||
84 | $find = $replace = array(); |
||
85 | foreach ( $matches as $match ) { |
||
86 | $url = trim( $match['path'], "'\" \t" ); |
||
87 | |||
88 | // If this is a data url, we don't want to mess with it. |
||
89 | if ( 'data:' === substr( $url, 0, 5 ) ) { |
||
90 | continue; |
||
91 | } |
||
92 | |||
93 | // If this is an absolute or protocol-agnostic url, |
||
94 | // we don't want to mess with it. |
||
95 | if ( preg_match( '#^(https?:)?//#i', $url ) ) { |
||
96 | continue; |
||
97 | } |
||
98 | |||
99 | switch ( substr( $url, 0, 1 ) ) { |
||
100 | case '/': |
||
101 | $absolute = $domain . $url; |
||
102 | break; |
||
103 | default: |
||
104 | $absolute = $css_dir . '/' . $url; |
||
105 | } |
||
106 | |||
107 | $find[] = $match[0]; |
||
108 | $replace[] = sprintf( 'url("%s")', $absolute ); |
||
109 | } |
||
110 | $css = str_replace( $find, $replace, $css ); |
||
111 | } |
||
112 | |||
113 | return $css; |
||
114 | } |
||
115 | |||
116 | /* |
||
117 | * Strip http:// or https:// from a url, replaces forward slash with ::, |
||
118 | * so we can bring them directly to their site in calypso. |
||
119 | * |
||
120 | * @param string | url |
||
121 | * @return string | url without the guff |
||
122 | */ |
||
123 | public static function build_raw_urls( $url ) { |
||
124 | $strip_http = '/.*?:\/\//i'; |
||
125 | $url = preg_replace( $strip_http, '', $url ); |
||
126 | $url = str_replace( '/', '::', $url ); |
||
127 | return $url; |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * Checks if the site is currently in an identity crisis. |
||
132 | * |
||
133 | * @return array|bool Array of options that are in a crisis, or false if everything is OK. |
||
134 | */ |
||
135 | public static function check_identity_crisis() { |
||
136 | if ( ! Jetpack::is_active() || Jetpack::is_development_mode() || ! Jetpack::validate_sync_error_idc_option() ) { |
||
137 | return false; |
||
138 | } |
||
139 | |||
140 | return Jetpack_Options::get_option( 'sync_error_idc' ); |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Gets current user IP address. |
||
145 | * |
||
146 | * @param bool $check_all_headers Check all headers? Default is `false`. |
||
147 | * |
||
148 | * @return string Current user IP address. |
||
149 | */ |
||
150 | public static function current_user_ip( $check_all_headers = false ) { |
||
151 | if ( $check_all_headers ) { |
||
152 | foreach ( array( |
||
153 | 'HTTP_CF_CONNECTING_IP', |
||
154 | 'HTTP_CLIENT_IP', |
||
155 | 'HTTP_X_FORWARDED_FOR', |
||
156 | 'HTTP_X_FORWARDED', |
||
157 | 'HTTP_X_CLUSTER_CLIENT_IP', |
||
158 | 'HTTP_FORWARDED_FOR', |
||
159 | 'HTTP_FORWARDED', |
||
160 | 'HTTP_VIA', |
||
161 | ) as $key ) { |
||
162 | if ( ! empty( $_SERVER[ $key ] ) ) { |
||
163 | return $_SERVER[ $key ]; |
||
164 | } |
||
165 | } |
||
166 | } |
||
167 | |||
168 | return ! empty( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : ''; |
||
169 | } |
||
170 | |||
171 | function current_user_is_connection_owner() { |
||
172 | $user_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER ); |
||
173 | return $user_token && is_object( $user_token ) && isset( $user_token->external_user_id ) && get_current_user_id() === $user_token->external_user_id; |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * Determines whether the current theme supports featured images or not. |
||
178 | * @return string ( '1' | '0' ) |
||
179 | */ |
||
180 | public static function featured_images_enabled() { |
||
181 | _deprecated_function( __METHOD__, 'jetpack-4.2' ); |
||
182 | return current_theme_supports( 'post-thumbnails' ) ? '1' : '0'; |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * Returns true if the site has file write access false otherwise. |
||
187 | * @return string ( '1' | '0' ) |
||
188 | **/ |
||
189 | public static function file_system_write_access() { |
||
190 | if ( ! function_exists( 'get_filesystem_method' ) ) { |
||
191 | require_once( ABSPATH . 'wp-admin/includes/file.php' ); |
||
192 | } |
||
193 | |||
194 | require_once( ABSPATH . 'wp-admin/includes/template.php' ); |
||
195 | |||
196 | $filesystem_method = get_filesystem_method(); |
||
197 | if ( $filesystem_method === 'direct' ) { |
||
198 | return 1; |
||
199 | } |
||
200 | |||
201 | ob_start(); |
||
202 | $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() ); |
||
203 | ob_end_clean(); |
||
204 | if ( $filesystem_credentials_are_stored ) { |
||
205 | return 1; |
||
206 | } |
||
207 | return 0; |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Get a list of activated modules as an array of module slugs. |
||
212 | */ |
||
213 | public static function get_active_modules() { |
||
214 | $active = Jetpack_Options::get_option( 'active_modules' ); |
||
215 | |||
216 | if ( ! is_array( $active ) ) { |
||
217 | $active = array(); |
||
218 | } |
||
219 | |||
220 | if ( class_exists( 'VaultPress' ) || function_exists( 'vaultpress_contact_service' ) ) { |
||
221 | $active[] = 'vaultpress'; |
||
222 | } else { |
||
223 | $active = array_diff( $active, array( 'vaultpress' ) ); |
||
224 | } |
||
225 | |||
226 | //If protect is active on the main site of a multisite, it should be active on all sites. |
||
227 | if ( ! in_array( 'protect', $active ) && is_multisite() && get_site_option( 'jetpack_protect_active' ) ) { |
||
228 | $active[] = 'protect'; |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Allow filtering of the active modules. |
||
233 | * |
||
234 | * Gives theme and plugin developers the power to alter the modules that |
||
235 | * are activated on the fly. |
||
236 | * |
||
237 | * @since 5.8.0 |
||
238 | * |
||
239 | * @param array $active Array of active module slugs. |
||
240 | */ |
||
241 | $active = apply_filters( 'jetpack_active_modules', $active ); |
||
242 | |||
243 | return array_unique( $active ); |
||
244 | } |
||
245 | |||
246 | /** |
||
247 | * Get the plan that this Jetpack site is currently using |
||
248 | * |
||
249 | * @uses get_option() |
||
250 | * |
||
251 | * @access public |
||
252 | * @static |
||
253 | * |
||
254 | * @return array Active Jetpack plan details |
||
255 | */ |
||
256 | public static function get_active_plan() { |
||
257 | global $active_plan_cache; |
||
258 | |||
259 | // this can be expensive to compute so we cache for the duration of a request |
||
260 | if ( is_array( $active_plan_cache ) && ! empty( $active_plan_cache ) ) { |
||
261 | return $active_plan_cache; |
||
262 | } |
||
263 | |||
264 | $plan = get_option( 'jetpack_active_plan', array() ); |
||
265 | |||
266 | // Set the default options |
||
267 | $plan = wp_parse_args( $plan, array( |
||
268 | 'product_slug' => 'jetpack_free', |
||
269 | 'class' => 'free', |
||
270 | 'features' => array( |
||
271 | 'active' => array() |
||
272 | ), |
||
273 | ) ); |
||
274 | |||
275 | $supports = array(); |
||
276 | |||
277 | // Define what paid modules are supported by personal plans |
||
278 | $personal_plans = array( |
||
279 | 'jetpack_personal', |
||
280 | 'jetpack_personal_monthly', |
||
281 | 'personal-bundle', |
||
282 | ); |
||
283 | |||
284 | if ( in_array( $plan['product_slug'], $personal_plans ) ) { |
||
285 | // special support value, not a module but a separate plugin |
||
286 | $supports[] = 'akismet'; |
||
287 | $plan['class'] = 'personal'; |
||
288 | } |
||
289 | |||
290 | // Define what paid modules are supported by premium plans |
||
291 | $premium_plans = array( |
||
292 | 'jetpack_premium', |
||
293 | 'jetpack_premium_monthly', |
||
294 | 'value_bundle', |
||
295 | ); |
||
296 | |||
297 | View Code Duplication | if ( in_array( $plan['product_slug'], $premium_plans ) ) { |
|
298 | $supports[] = 'akismet'; |
||
299 | $supports[] = 'vaultpress'; |
||
300 | $plan['class'] = 'premium'; |
||
301 | } |
||
302 | |||
303 | // Define what paid modules are supported by professional plans |
||
304 | $business_plans = array( |
||
305 | 'jetpack_business', |
||
306 | 'jetpack_business_monthly', |
||
307 | 'business-bundle', |
||
308 | 'vip', |
||
309 | ); |
||
310 | |||
311 | View Code Duplication | if ( in_array( $plan['product_slug'], $business_plans ) ) { |
|
312 | $supports[] = 'akismet'; |
||
313 | $supports[] = 'vaultpress'; |
||
314 | $plan['class'] = 'business'; |
||
315 | } |
||
316 | |||
317 | // get available features |
||
318 | foreach ( Jetpack::get_available_modules() as $module_slug ) { |
||
319 | $module = Jetpack::get_module( $module_slug ); |
||
320 | if ( ! isset( $module ) || ! is_array( $module ) ) { |
||
321 | continue; |
||
322 | } |
||
323 | if ( in_array( 'free', $module['plan_classes'] ) || in_array( $plan['class'], $module['plan_classes'] ) ) { |
||
324 | $supports[] = $module_slug; |
||
325 | } |
||
326 | } |
||
327 | |||
328 | $plan['supports'] = $supports; |
||
329 | |||
330 | $active_plan_cache = $plan; |
||
331 | |||
332 | return $plan; |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * Gets all plugins currently active in values, regardless of whether they're |
||
337 | * traditionally activated or network activated. |
||
338 | * |
||
339 | * @todo Store the result in core's object cache maybe? |
||
340 | */ |
||
341 | public static function get_active_plugins() { |
||
342 | $active_plugins = (array) get_option( 'active_plugins', array() ); |
||
343 | |||
344 | if ( is_multisite() ) { |
||
345 | // Due to legacy code, active_sitewide_plugins stores them in the keys, |
||
346 | // whereas active_plugins stores them in the values. |
||
347 | $network_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); |
||
348 | if ( $network_plugins ) { |
||
349 | $active_plugins = array_merge( $active_plugins, $network_plugins ); |
||
350 | } |
||
351 | } |
||
352 | |||
353 | sort( $active_plugins ); |
||
354 | |||
355 | return array_unique( $active_plugins ); |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Wrapper for core's get_avatar_url(). This one is deprecated. |
||
360 | * |
||
361 | * @deprecated 4.7 use get_avatar_url instead. |
||
362 | * @param int|string|object $id_or_email A user ID, email address, or comment object |
||
363 | * @param int $size Size of the avatar image |
||
364 | * @param string $default URL to a default image to use if no avatar is available |
||
365 | * @param bool $force_display Whether to force it to return an avatar even if show_avatars is disabled |
||
366 | * |
||
367 | * @return array |
||
368 | */ |
||
369 | public static function get_avatar_url( $id_or_email, $size = 96, $default = '', $force_display = false ) { |
||
370 | _deprecated_function( __METHOD__, 'jetpack-4.7', 'get_avatar_url' ); |
||
371 | return get_avatar_url( $id_or_email, array( |
||
372 | 'size' => $size, |
||
373 | 'default' => $default, |
||
374 | 'force_default' => $force_display, |
||
375 | ) ); |
||
376 | } |
||
377 | |||
378 | /** |
||
379 | * Get the wpcom user data of the current|specified connected user. |
||
380 | */ |
||
381 | public static function get_connected_user_data( $user_id = null ) { |
||
382 | if ( ! $user_id ) { |
||
383 | $user_id = get_current_user_id(); |
||
384 | } |
||
385 | |||
386 | $transient_key = "jetpack_connected_user_data_$user_id"; |
||
387 | |||
388 | if ( $cached_user_data = get_transient( $transient_key ) ) { |
||
389 | return $cached_user_data; |
||
390 | } |
||
391 | |||
392 | Jetpack::load_xml_rpc_client(); |
||
393 | $xml = new Jetpack_IXR_Client( array( |
||
394 | 'user_id' => $user_id, |
||
395 | ) ); |
||
396 | $xml->query( 'wpcom.getUser' ); |
||
397 | if ( ! $xml->isError() ) { |
||
398 | $user_data = $xml->getResponse(); |
||
399 | set_transient( $transient_key, $xml->getResponse(), DAY_IN_SECONDS ); |
||
400 | return $user_data; |
||
401 | } |
||
402 | |||
403 | return false; |
||
404 | } |
||
405 | |||
406 | /** |
||
407 | * Get the wpcom email of the current|specified connected user. |
||
408 | */ |
||
409 | View Code Duplication | public static function get_connected_user_email( $user_id = null ) { |
|
410 | if ( ! $user_id ) { |
||
411 | $user_id = get_current_user_id(); |
||
412 | } |
||
413 | Jetpack::load_xml_rpc_client(); |
||
414 | $xml = new Jetpack_IXR_Client( array( |
||
415 | 'user_id' => $user_id, |
||
416 | ) ); |
||
417 | $xml->query( 'wpcom.getUserEmail' ); |
||
418 | if ( ! $xml->isError() ) { |
||
419 | return $xml->getResponse(); |
||
420 | } |
||
421 | return false; |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * Get $content_width, but with a <s>twist</s> filter. |
||
426 | */ |
||
427 | public static function get_content_width() { |
||
428 | $content_width = isset( $GLOBALS['content_width'] ) ? $GLOBALS['content_width'] : false; |
||
429 | /** |
||
430 | * Filter the Content Width value. |
||
431 | * |
||
432 | * @since 2.2.3 |
||
433 | * |
||
434 | * @param string $content_width Content Width value. |
||
435 | */ |
||
436 | return apply_filters( 'jetpack_content_width', $content_width ); |
||
437 | } |
||
438 | |||
439 | |||
440 | /** |
||
441 | * Like core's get_file_data implementation, but caches the result. |
||
442 | */ |
||
443 | public static function get_file_data( $file, $headers ) { |
||
444 | //Get just the filename from $file (i.e. exclude full path) so that a consistent hash is generated |
||
445 | $file_name = basename( $file ); |
||
446 | |||
447 | $cache_key = 'jetpack_file_data_' . JETPACK__VERSION; |
||
448 | |||
449 | $file_data_option = get_transient( $cache_key ); |
||
450 | |||
451 | if ( false === $file_data_option ) { |
||
452 | $file_data_option = array(); |
||
453 | } |
||
454 | |||
455 | $key = md5( $file_name . serialize( $headers ) ); |
||
456 | $refresh_cache = is_admin() && isset( $_GET['page'] ) && 'jetpack' === substr( $_GET['page'], 0, 7 ); |
||
457 | |||
458 | // If we don't need to refresh the cache, and already have the value, short-circuit! |
||
459 | if ( ! $refresh_cache && isset( $file_data_option[ $key ] ) ) { |
||
460 | return $file_data_option[ $key ]; |
||
461 | } |
||
462 | |||
463 | $data = get_file_data( $file, $headers ); |
||
464 | |||
465 | $file_data_option[ $key ] = $data; |
||
466 | |||
467 | set_transient( $cache_key, $file_data_option, 29 * DAY_IN_SECONDS ); |
||
468 | |||
469 | return $data; |
||
470 | } |
||
471 | |||
472 | /** |
||
473 | * Given a minified path, and a non-minified path, will return |
||
474 | * a minified or non-minified file URL based on whether SCRIPT_DEBUG is set and truthy. |
||
475 | * |
||
476 | * Both `$min_base` and `$non_min_base` are expected to be relative to the |
||
477 | * root Jetpack directory. |
||
478 | * |
||
479 | * @since 5.6.0 |
||
480 | * |
||
481 | * @param string $min_path |
||
482 | * @param string $non_min_path |
||
483 | * @return string The URL to the file |
||
484 | */ |
||
485 | public static function get_file_url_for_environment( $min_path, $non_min_path ) { |
||
486 | $path = ( Jetpack_Constants::is_defined( 'SCRIPT_DEBUG' ) && Jetpack_Constants::get_constant( 'SCRIPT_DEBUG' ) ) |
||
487 | ? $non_min_path |
||
488 | : $min_path; |
||
489 | |||
490 | return plugins_url( $path, JETPACK__PLUGIN_FILE ); |
||
491 | } |
||
492 | |||
493 | /** |
||
494 | * Return string containing the Jetpack logo. |
||
495 | * |
||
496 | * @since 3.9.0 |
||
497 | * |
||
498 | * @return string |
||
499 | */ |
||
500 | public static function get_jp_emblem() { |
||
501 | return '<svg id="jetpack-logo__icon" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 32 32"><path fill="#00BE28" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16c8.8,0,16-7.2,16-16S24.8,0,16,0z M15.2,18.7h-8l8-15.5V18.7z M16.8,28.8 V13.3h8L16.8,28.8z"/></svg>'; |
||
502 | } |
||
503 | |||
504 | /* |
||
505 | * This method is used to organize all options that can be reset |
||
506 | * without disconnecting Jetpack. |
||
507 | * |
||
508 | * It is used in class.jetpack-cli.php to reset options |
||
509 | * |
||
510 | * @since 5.4.0 Logic moved to Jetpack_Options class. Method left in Jetpack class for backwards compat. |
||
511 | * |
||
512 | * @return array of options to delete. |
||
513 | */ |
||
514 | public static function get_jetpack_options_for_reset() { |
||
515 | return Jetpack_Options::get_options_for_reset(); |
||
516 | } |
||
517 | |||
518 | /** |
||
519 | * Get the locale. |
||
520 | * |
||
521 | * @return string|bool |
||
522 | */ |
||
523 | function get_locale() { |
||
524 | $locale = $this->guess_locale_from_lang( get_locale() ); |
||
525 | |||
526 | if ( ! $locale ) { |
||
527 | $locale = 'en_US'; |
||
528 | } |
||
529 | |||
530 | return $locale; |
||
531 | } |
||
532 | |||
533 | /** |
||
534 | * Get the wpcom email of the master user. |
||
535 | */ |
||
536 | public static function get_master_user_email() { |
||
537 | $master_user_id = Jetpack_Options::get_option( 'master_user' ); |
||
538 | if ( $master_user_id ) { |
||
539 | return Jetpack::get_connected_user_email( $master_user_id ); |
||
540 | } |
||
541 | return ''; |
||
542 | } |
||
543 | |||
544 | /** |
||
545 | * Builds the timeout limit for queries talking with the wpcom servers. |
||
546 | * |
||
547 | * Based on local php max_execution_time in php.ini |
||
548 | * |
||
549 | * @since 5.4 |
||
550 | * @return int |
||
551 | **/ |
||
552 | public static function get_max_execution_time() { |
||
553 | $timeout = (int) ini_get( 'max_execution_time' ); |
||
554 | |||
555 | // Ensure exec time set in php.ini |
||
556 | if ( ! $timeout ) { |
||
557 | $timeout = 30; |
||
558 | } |
||
559 | return $timeout; |
||
560 | } |
||
561 | |||
562 | /** |
||
563 | * Extract a module's slug from its full path. |
||
564 | */ |
||
565 | public static function get_module_slug( $file ) { |
||
566 | return str_replace( '.php', '', basename( $file ) ); |
||
567 | } |
||
568 | |||
569 | /** |
||
570 | * Generate a module's path from its slug. |
||
571 | */ |
||
572 | public static function get_module_path( $slug ) { |
||
573 | return JETPACK__PLUGIN_DIR . "modules/$slug.php"; |
||
574 | } |
||
575 | |||
576 | /** |
||
577 | * Load module data from module file. Headers differ from WordPress |
||
578 | * plugin headers to avoid them being identified as standalone |
||
579 | * plugins on the WordPress plugins page. |
||
580 | */ |
||
581 | public static function get_module( $module ) { |
||
582 | $headers = array( |
||
583 | 'name' => 'Module Name', |
||
584 | 'description' => 'Module Description', |
||
585 | 'jumpstart_desc' => 'Jumpstart Description', |
||
586 | 'sort' => 'Sort Order', |
||
587 | 'recommendation_order' => 'Recommendation Order', |
||
588 | 'introduced' => 'First Introduced', |
||
589 | 'changed' => 'Major Changes In', |
||
590 | 'deactivate' => 'Deactivate', |
||
591 | 'free' => 'Free', |
||
592 | 'requires_connection' => 'Requires Connection', |
||
593 | 'auto_activate' => 'Auto Activate', |
||
594 | 'module_tags' => 'Module Tags', |
||
595 | 'feature' => 'Feature', |
||
596 | 'additional_search_queries' => 'Additional Search Queries', |
||
597 | 'plan_classes' => 'Plans', |
||
598 | ); |
||
599 | |||
600 | $file = Jetpack::get_module_path( Jetpack::get_module_slug( $module ) ); |
||
601 | |||
602 | $mod = Jetpack::get_file_data( $file, $headers ); |
||
603 | if ( empty( $mod['name'] ) ) { |
||
604 | return false; |
||
605 | } |
||
606 | |||
607 | $mod['sort'] = empty( $mod['sort'] ) ? 10 : (int) $mod['sort']; |
||
608 | $mod['recommendation_order'] = empty( $mod['recommendation_order'] ) ? 20 : (int) $mod['recommendation_order']; |
||
609 | $mod['deactivate'] = empty( $mod['deactivate'] ); |
||
610 | $mod['free'] = empty( $mod['free'] ); |
||
611 | $mod['requires_connection'] = ( ! empty( $mod['requires_connection'] ) && 'No' == $mod['requires_connection'] ) ? false : true; |
||
612 | |||
613 | if ( empty( $mod['auto_activate'] ) || ! in_array( strtolower( $mod['auto_activate'] ), array( 'yes', 'no', 'public' ) ) ) { |
||
614 | $mod['auto_activate'] = 'No'; |
||
615 | } else { |
||
616 | $mod['auto_activate'] = (string) $mod['auto_activate']; |
||
617 | } |
||
618 | |||
619 | if ( $mod['module_tags'] ) { |
||
620 | $mod['module_tags'] = explode( ',', $mod['module_tags'] ); |
||
621 | $mod['module_tags'] = array_map( 'trim', $mod['module_tags'] ); |
||
622 | $mod['module_tags'] = array_map( array( 'Jetpack', 'translate_module_tag' ), $mod['module_tags'] ); |
||
623 | } else { |
||
624 | $mod['module_tags'] = array( Jetpack::translate_module_tag( 'Other' ) ); |
||
625 | } |
||
626 | |||
627 | if ( $mod['plan_classes'] ) { |
||
628 | $mod['plan_classes'] = explode( ',', $mod['plan_classes'] ); |
||
629 | $mod['plan_classes'] = array_map( 'strtolower', array_map( 'trim', $mod['plan_classes'] ) ); |
||
630 | } else { |
||
631 | $mod['plan_classes'] = array( 'free' ); |
||
632 | } |
||
633 | |||
634 | if ( $mod['feature'] ) { |
||
635 | $mod['feature'] = explode( ',', $mod['feature'] ); |
||
636 | $mod['feature'] = array_map( 'trim', $mod['feature'] ); |
||
637 | } else { |
||
638 | $mod['feature'] = array( Jetpack::translate_module_tag( 'Other' ) ); |
||
639 | } |
||
640 | |||
641 | /** |
||
642 | * Filters the feature array on a module. |
||
643 | * |
||
644 | * This filter allows you to control where each module is filtered: Recommended, |
||
645 | * Jumpstart, and the default "Other" listing. |
||
646 | * |
||
647 | * @since 3.5.0 |
||
648 | * |
||
649 | * @param array $mod['feature'] The areas to feature this module: |
||
650 | * 'Jumpstart' adds to the "Jumpstart" option to activate many modules at once. |
||
651 | * 'Recommended' shows on the main Jetpack admin screen. |
||
652 | * 'Other' should be the default if no other value is in the array. |
||
653 | * @param string $module The slug of the module, e.g. sharedaddy. |
||
654 | * @param array $mod All the currently assembled module data. |
||
655 | */ |
||
656 | $mod['feature'] = apply_filters( 'jetpack_module_feature', $mod['feature'], $module, $mod ); |
||
657 | |||
658 | /** |
||
659 | * Filter the returned data about a module. |
||
660 | * |
||
661 | * This filter allows overriding any info about Jetpack modules. It is dangerous, |
||
662 | * so please be careful. |
||
663 | * |
||
664 | * @since 3.6.0 |
||
665 | * |
||
666 | * @param array $mod The details of the requested module. |
||
667 | * @param string $module The slug of the module, e.g. sharedaddy |
||
668 | * @param string $file The path to the module source file. |
||
669 | */ |
||
670 | return apply_filters( 'jetpack_get_module', $mod, $module, $file ); |
||
671 | } |
||
672 | |||
673 | /** |
||
674 | * Gets and parses additional plugin data to send with the heartbeat data |
||
675 | * |
||
676 | * @since 3.8.1 |
||
677 | * |
||
678 | * @return array Array of plugin data |
||
679 | */ |
||
680 | public static function get_parsed_plugin_data() { |
||
681 | if ( ! function_exists( 'get_plugins' ) ) { |
||
682 | require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); |
||
683 | } |
||
684 | /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */ |
||
685 | $all_plugins = apply_filters( 'all_plugins', get_plugins() ); |
||
686 | $active_plugins = Jetpack::get_active_plugins(); |
||
687 | |||
688 | $plugins = array(); |
||
689 | foreach ( $all_plugins as $path => $plugin_data ) { |
||
690 | $plugins[ $path ] = array( |
||
691 | 'is_active' => in_array( $path, $active_plugins ), |
||
692 | 'file' => $path, |
||
693 | 'name' => $plugin_data['Name'], |
||
694 | 'version' => $plugin_data['Version'], |
||
695 | 'author' => $plugin_data['Author'], |
||
696 | ); |
||
697 | } |
||
698 | |||
699 | return $plugins; |
||
700 | } |
||
701 | |||
702 | /** |
||
703 | * Gets and parses theme data to send with the heartbeat data |
||
704 | * |
||
705 | * @since 3.8.1 |
||
706 | * |
||
707 | * @return array Array of theme data |
||
708 | */ |
||
709 | public static function get_parsed_theme_data() { |
||
710 | $all_themes = wp_get_themes( array( 'allowed' => true ) ); |
||
711 | $header_keys = array( 'Name', 'Author', 'Version', 'ThemeURI', 'AuthorURI', 'Status', 'Tags' ); |
||
712 | |||
713 | $themes = array(); |
||
714 | foreach ( $all_themes as $slug => $theme_data ) { |
||
715 | $theme_headers = array(); |
||
716 | foreach ( $header_keys as $header_key ) { |
||
717 | $theme_headers[ $header_key ] = $theme_data->get( $header_key ); |
||
718 | } |
||
719 | |||
720 | $themes[ $slug ] = array( |
||
721 | 'is_active_theme' => $slug == wp_get_theme()->get_template(), |
||
722 | 'slug' => $slug, |
||
723 | 'theme_root' => $theme_data->get_theme_root_uri(), |
||
724 | 'parent' => $theme_data->parent(), |
||
725 | 'headers' => $theme_headers |
||
726 | ); |
||
727 | } |
||
728 | |||
729 | return $themes; |
||
730 | } |
||
731 | |||
732 | /** |
||
733 | * Guess locale from language code. |
||
734 | * |
||
735 | * @param string $lang Language code. |
||
736 | * @return string|bool |
||
737 | */ |
||
738 | View Code Duplication | function guess_locale_from_lang( $lang ) { |
|
739 | if ( 'en' === $lang || 'en_US' === $lang || ! $lang ) { |
||
740 | return 'en_US'; |
||
741 | } |
||
742 | |||
743 | if ( ! class_exists( 'GP_Locales' ) ) { |
||
744 | if ( ! defined( 'JETPACK__GLOTPRESS_LOCALES_PATH' ) || ! file_exists( JETPACK__GLOTPRESS_LOCALES_PATH ) ) { |
||
745 | return false; |
||
746 | } |
||
747 | |||
748 | require JETPACK__GLOTPRESS_LOCALES_PATH; |
||
749 | } |
||
750 | |||
751 | if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { |
||
752 | // WP.com: get_locale() returns 'it' |
||
753 | $locale = GP_Locales::by_slug( $lang ); |
||
754 | } else { |
||
755 | // Jetpack: get_locale() returns 'it_IT'; |
||
756 | $locale = GP_Locales::by_field( 'facebook_locale', $lang ); |
||
757 | } |
||
758 | |||
759 | if ( ! $locale ) { |
||
760 | return false; |
||
761 | } |
||
762 | |||
763 | if ( empty( $locale->facebook_locale ) ) { |
||
764 | if ( empty( $locale->wp_locale ) ) { |
||
765 | return false; |
||
766 | } else { |
||
767 | // Facebook SDK is smart enough to fall back to en_US if a |
||
768 | // locale isn't supported. Since supported Facebook locales |
||
769 | // can fall out of sync, we'll attempt to use the known |
||
770 | // wp_locale value and rely on said fallback. |
||
771 | return $locale->wp_locale; |
||
772 | } |
||
773 | } |
||
774 | |||
775 | return $locale->facebook_locale; |
||
776 | } |
||
777 | |||
778 | private static function get_site_user_count() { |
||
779 | global $wpdb; |
||
780 | |||
781 | if ( function_exists( 'wp_is_large_network' ) ) { |
||
782 | if ( wp_is_large_network( 'users' ) ) { |
||
783 | return -1; // Not a real value but should tell us that we are dealing with a large network. |
||
784 | } |
||
785 | } |
||
786 | View Code Duplication | if ( false === ( $user_count = get_transient( 'jetpack_site_user_count' ) ) ) { |
|
787 | // It wasn't there, so regenerate the data and save the transient |
||
788 | $user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$wpdb->prefix}capabilities'" ); |
||
789 | set_transient( 'jetpack_site_user_count', $user_count, DAY_IN_SECONDS ); |
||
790 | } |
||
791 | return $user_count; |
||
792 | } |
||
793 | |||
794 | /** |
||
795 | * Returns an array of all PHP files in the specified absolute path. |
||
796 | * Equivalent to glob( "$absolute_path/*.php" ). |
||
797 | * |
||
798 | * @param string $absolute_path The absolute path of the directory to search. |
||
799 | * @return array Array of absolute paths to the PHP files. |
||
800 | */ |
||
801 | public static function glob_php( $absolute_path ) { |
||
802 | if ( function_exists( 'glob' ) ) { |
||
803 | return glob( "$absolute_path/*.php" ); |
||
804 | } |
||
805 | |||
806 | $absolute_path = untrailingslashit( $absolute_path ); |
||
807 | $files = array(); |
||
808 | if ( ! $dir = @opendir( $absolute_path ) ) { |
||
809 | return $files; |
||
810 | } |
||
811 | |||
812 | while ( false !== $file = readdir( $dir ) ) { |
||
813 | if ( '.' == substr( $file, 0, 1 ) || '.php' != substr( $file, -4 ) ) { |
||
814 | continue; |
||
815 | } |
||
816 | |||
817 | $file = "$absolute_path/$file"; |
||
818 | |||
819 | if ( ! is_file( $file ) ) { |
||
820 | continue; |
||
821 | } |
||
822 | |||
823 | $files[] = $file; |
||
824 | } |
||
825 | |||
826 | closedir( $dir ); |
||
827 | |||
828 | return $files; |
||
829 | } |
||
830 | |||
831 | /** |
||
832 | * Checks if Akismet is active and working. |
||
833 | * |
||
834 | * We dropped support for Akismet 3.0 with Jetpack 6.1.1 while introducing a check for an Akismet valid key |
||
835 | * that implied usage of methods present since more recent version. |
||
836 | * See https://github.com/Automattic/jetpack/pull/9585 |
||
837 | * |
||
838 | * @since 5.1.0 |
||
839 | * |
||
840 | * @return bool True = Akismet available. False = Aksimet not available. |
||
841 | */ |
||
842 | public static function is_akismet_active() { |
||
843 | if ( method_exists( 'Akismet' , 'http_post' ) ) { |
||
844 | $akismet_key = Akismet::get_api_key(); |
||
845 | if ( ! $akismet_key ) { |
||
846 | return false; |
||
847 | } |
||
848 | $akismet_key_state = Akismet::verify_key( $akismet_key ); |
||
849 | if ( 'invalid' === $akismet_key_state || 'failed' === $akismet_key_state ) { |
||
850 | return false; |
||
851 | } |
||
852 | return true; |
||
853 | } |
||
854 | return false; |
||
855 | } |
||
856 | |||
857 | /** |
||
858 | * Is Jetpack in development (offline) mode? |
||
859 | */ |
||
860 | public static function is_development_mode() { |
||
861 | $development_mode = false; |
||
862 | |||
863 | if ( defined( 'JETPACK_DEV_DEBUG' ) ) { |
||
864 | $development_mode = JETPACK_DEV_DEBUG; |
||
865 | } elseif ( $site_url = site_url() ) { |
||
866 | $development_mode = false === strpos( $site_url, '.' ); |
||
867 | } |
||
868 | |||
869 | /** |
||
870 | * Filters Jetpack's development mode. |
||
871 | * |
||
872 | * @see https://jetpack.com/support/development-mode/ |
||
873 | * |
||
874 | * @since 2.2.1 |
||
875 | * |
||
876 | * @param bool $development_mode Is Jetpack's development mode active. |
||
877 | */ |
||
878 | $development_mode = ( bool ) apply_filters( 'jetpack_development_mode', $development_mode ); |
||
879 | return $development_mode; |
||
880 | } |
||
881 | |||
882 | /** |
||
883 | * Whether Jetpack's version maps to a public release, or a development version. |
||
884 | */ |
||
885 | public static function is_development_version() { |
||
886 | /** |
||
887 | * Allows filtering whether this is a development version of Jetpack. |
||
888 | * |
||
889 | * This filter is especially useful for tests. |
||
890 | * |
||
891 | * @since 4.3.0 |
||
892 | * |
||
893 | * @param bool $development_version Is this a develoment version of Jetpack? |
||
894 | */ |
||
895 | return (bool) apply_filters( |
||
896 | 'jetpack_development_version', |
||
897 | ! preg_match( '/^\d+(\.\d+)+$/', Jetpack_Constants::get_constant( 'JETPACK__VERSION' ) ) |
||
898 | ); |
||
899 | } |
||
900 | |||
901 | /** |
||
902 | * Check whether or not a Jetpack module is active. |
||
903 | * |
||
904 | * @param string $module The slug of a Jetpack module. |
||
905 | * @return bool |
||
906 | * |
||
907 | * @static |
||
908 | */ |
||
909 | public static function is_module_active( $module ) { |
||
910 | return in_array( $module, Jetpack::get_active_modules() ); |
||
911 | } |
||
912 | |||
913 | public static function is_module( $module ) { |
||
914 | return ! empty( $module ) && ! validate_file( $module, Jetpack::get_available_modules() ); |
||
915 | } |
||
916 | |||
917 | /** |
||
918 | * Implemented since there is no core is multi network function |
||
919 | * Right now there is no way to tell if we which network is the dominant network on the system |
||
920 | * |
||
921 | * @since 3.3 |
||
922 | * @return boolean |
||
923 | */ |
||
924 | public static function is_multi_network() { |
||
925 | global $wpdb; |
||
926 | |||
927 | // if we don't have a multi site setup no need to do any more |
||
928 | if ( ! is_multisite() ) { |
||
929 | return false; |
||
930 | } |
||
931 | |||
932 | $num_sites = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->site}" ); |
||
933 | if ( $num_sites > 1 ) { |
||
934 | return true; |
||
935 | } else { |
||
936 | return false; |
||
937 | } |
||
938 | } |
||
939 | |||
940 | /** |
||
941 | * Return true if we are with multi-site or multi-network false if we are dealing with single site. |
||
942 | * |
||
943 | * @param string $option |
||
944 | * @return boolean |
||
945 | */ |
||
946 | public function is_multisite( $option ) { |
||
947 | return (string) (bool) is_multisite(); |
||
948 | } |
||
949 | |||
950 | /** |
||
951 | * Whether the site is currently onboarding or not. |
||
952 | * A site is considered as being onboarded if it currently has an onboarding token. |
||
953 | * |
||
954 | * @since 5.8 |
||
955 | * |
||
956 | * @access public |
||
957 | * @static |
||
958 | * |
||
959 | * @return bool True if the site is currently onboarding, false otherwise |
||
960 | */ |
||
961 | public static function is_onboarding() { |
||
962 | return Jetpack_Options::get_option( 'onboarding' ) !== false; |
||
963 | } |
||
964 | |||
965 | /** |
||
966 | * Checks whether a specific plugin is active. |
||
967 | * |
||
968 | * We don't want to store these in a static variable, in case |
||
969 | * there are switch_to_blog() calls involved. |
||
970 | */ |
||
971 | public static function is_plugin_active( $plugin = 'jetpack/jetpack.php' ) { |
||
972 | return in_array( $plugin, Jetpack::get_active_plugins() ); |
||
973 | } |
||
974 | |||
975 | /** |
||
976 | * Checks for whether Jetpack Rewind is enabled. |
||
977 | * Will return true if the state of Rewind is anything except "unavailable". |
||
978 | * @return bool|int|mixed |
||
979 | */ |
||
980 | public static function is_rewind_enabled() { |
||
981 | if ( ! Jetpack::is_active() ) { |
||
982 | return false; |
||
983 | } |
||
984 | |||
985 | $rewind_enabled = get_transient( 'jetpack_rewind_enabled' ); |
||
986 | if ( false === $rewind_enabled ) { |
||
987 | jetpack_require_lib( 'class.core-rest-api-endpoints' ); |
||
988 | $rewind_data = (array) Jetpack_Core_Json_Api_Endpoints::rewind_data(); |
||
989 | $rewind_enabled = ( ! is_wp_error( $rewind_data ) |
||
990 | && ! empty( $rewind_data['state'] ) |
||
991 | && 'active' === $rewind_data['state'] ) |
||
992 | ? 1 |
||
993 | : 0; |
||
994 | |||
995 | set_transient( 'jetpack_rewind_enabled', $rewind_enabled, 10 * MINUTE_IN_SECONDS ); |
||
996 | } |
||
997 | return $rewind_enabled; |
||
998 | } |
||
999 | |||
1000 | /** |
||
1001 | * Get back if the current site is single user site. |
||
1002 | * |
||
1003 | * @return bool |
||
1004 | */ |
||
1005 | public static function is_single_user_site() { |
||
1006 | global $wpdb; |
||
1007 | |||
1008 | View Code Duplication | if ( false === ( $some_users = get_transient( 'jetpack_is_single_user' ) ) ) { |
|
1009 | $some_users = $wpdb->get_var( "SELECT COUNT(*) FROM (SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '{$wpdb->prefix}capabilities' LIMIT 2) AS someusers" ); |
||
1010 | set_transient( 'jetpack_is_single_user', (int) $some_users, 12 * HOUR_IN_SECONDS ); |
||
1011 | } |
||
1012 | return 1 === (int) $some_users; |
||
1013 | } |
||
1014 | |||
1015 | /** |
||
1016 | * Checks whether the home and siteurl specifically are whitelisted |
||
1017 | * Written so that we don't have re-check $key and $value params every time |
||
1018 | * we want to check if this site is whitelisted, for example in footer.php |
||
1019 | * |
||
1020 | * @since 3.8.0 |
||
1021 | * @return bool True = already whitelisted False = not whitelisted |
||
1022 | */ |
||
1023 | public static function is_staging_site() { |
||
1024 | $is_staging = false; |
||
1025 | |||
1026 | $known_staging = array( |
||
1027 | 'urls' => array( |
||
1028 | '#\.staging\.wpengine\.com$#i', // WP Engine |
||
1029 | '#\.staging\.kinsta\.com$#i', // Kinsta.com |
||
1030 | ), |
||
1031 | 'constants' => array( |
||
1032 | 'IS_WPE_SNAPSHOT', // WP Engine |
||
1033 | 'KINSTA_DEV_ENV', // Kinsta.com |
||
1034 | 'WPSTAGECOACH_STAGING', // WP Stagecoach |
||
1035 | 'JETPACK_STAGING_MODE', // Generic |
||
1036 | ) |
||
1037 | ); |
||
1038 | /** |
||
1039 | * Filters the flags of known staging sites. |
||
1040 | * |
||
1041 | * @since 3.9.0 |
||
1042 | * |
||
1043 | * @param array $known_staging { |
||
1044 | * An array of arrays that each are used to check if the current site is staging. |
||
1045 | * @type array $urls URLs of staging sites in regex to check against site_url. |
||
1046 | * @type array $constants PHP constants of known staging/developement environments. |
||
1047 | * } |
||
1048 | */ |
||
1049 | $known_staging = apply_filters( 'jetpack_known_staging', $known_staging ); |
||
1050 | |||
1051 | if ( isset( $known_staging['urls'] ) ) { |
||
1052 | foreach ( $known_staging['urls'] as $url ){ |
||
1053 | if ( preg_match( $url, site_url() ) ) { |
||
1054 | $is_staging = true; |
||
1055 | break; |
||
1056 | } |
||
1057 | } |
||
1058 | } |
||
1059 | |||
1060 | if ( isset( $known_staging['constants'] ) ) { |
||
1061 | foreach ( $known_staging['constants'] as $constant ) { |
||
1062 | if ( defined( $constant ) && constant( $constant ) ) { |
||
1063 | $is_staging = true; |
||
1064 | } |
||
1065 | } |
||
1066 | } |
||
1067 | |||
1068 | // Last, let's check if sync is erroring due to an IDC. If so, set the site to staging mode. |
||
1069 | if ( ! $is_staging && Jetpack::validate_sync_error_idc_option() ) { |
||
1070 | $is_staging = true; |
||
1071 | } |
||
1072 | |||
1073 | /** |
||
1074 | * Filters is_staging_site check. |
||
1075 | * |
||
1076 | * @since 3.9.0 |
||
1077 | * |
||
1078 | * @param bool $is_staging If the current site is a staging site. |
||
1079 | */ |
||
1080 | return apply_filters( 'jetpack_is_staging_site', $is_staging ); |
||
1081 | } |
||
1082 | |||
1083 | /** |
||
1084 | * Is a given user (or the current user if none is specified) linked to a WordPress.com user? |
||
1085 | */ |
||
1086 | public static function is_user_connected( $user_id = false ) { |
||
1087 | $user_id = false === $user_id ? get_current_user_id() : absint( $user_id ); |
||
1088 | if ( ! $user_id ) { |
||
1089 | return false; |
||
1090 | } |
||
1091 | |||
1092 | return (bool) Jetpack_Data::get_access_token( $user_id ); |
||
1093 | } |
||
1094 | |||
1095 | /** |
||
1096 | * Finds out if a site is using a version control system. |
||
1097 | * @return string ( '1' | '0' ) |
||
1098 | **/ |
||
1099 | public static function is_version_controlled() { |
||
1100 | _deprecated_function( __METHOD__, 'jetpack-4.2', 'Jetpack_Sync_Functions::is_version_controlled' ); |
||
1101 | return (string) (int) Jetpack_Sync_Functions::is_version_controlled(); |
||
1102 | } |
||
1103 | |||
1104 | /** |
||
1105 | * Return the network_site_url so that .com knows what network this site is a part of. |
||
1106 | * @param bool $option |
||
1107 | * @return string |
||
1108 | */ |
||
1109 | public function jetpack_main_network_site_option( $option ) { |
||
1110 | return network_site_url(); |
||
1111 | } |
||
1112 | |||
1113 | /** |
||
1114 | * Checks whether or not TOS has been agreed upon. |
||
1115 | * Will return true if a user has clicked to register, or is already connected. |
||
1116 | */ |
||
1117 | public static function jetpack_tos_agreed() { |
||
1118 | return Jetpack_Options::get_option( 'tos_agreed' ) || Jetpack::is_active(); |
||
1119 | } |
||
1120 | |||
1121 | /** |
||
1122 | * Loads a view file from the views |
||
1123 | * |
||
1124 | * Data passed in with the $data parameter will be available in the |
||
1125 | * template file as $data['value'] |
||
1126 | * |
||
1127 | * @param string $template - Template file to load |
||
1128 | * @param array $data - Any data to pass along to the template |
||
1129 | * @return boolean - If template file was found |
||
1130 | **/ |
||
1131 | public function load_view( $template, $data = array() ) { |
||
1132 | $views_dir = JETPACK__PLUGIN_DIR . 'views/'; |
||
1133 | |||
1134 | if( file_exists( $views_dir . $template ) ) { |
||
1135 | require_once( $views_dir . $template ); |
||
1136 | return true; |
||
1137 | } |
||
1138 | |||
1139 | error_log( "Jetpack: Unable to find view file $views_dir$template" ); |
||
1140 | return false; |
||
1141 | } |
||
1142 | |||
1143 | /** |
||
1144 | * Network Name. |
||
1145 | */ |
||
1146 | static function network_name( $option = null ) { |
||
1147 | global $current_site; |
||
1148 | return $current_site->site_name; |
||
1149 | } |
||
1150 | /** |
||
1151 | * Does the network allow new user and site registrations. |
||
1152 | * @return string |
||
1153 | */ |
||
1154 | static function network_allow_new_registrations( $option = null ) { |
||
1155 | return ( in_array( get_site_option( 'registration' ), array('none', 'user', 'blog', 'all' ) ) ? get_site_option( 'registration') : 'none' ); |
||
1156 | } |
||
1157 | /** |
||
1158 | * Does the network allow admins to add new users. |
||
1159 | * @return boolian |
||
1160 | */ |
||
1161 | static function network_add_new_users( $option = null ) { |
||
1162 | return (bool) get_site_option( 'add_new_users' ); |
||
1163 | } |
||
1164 | /** |
||
1165 | * File upload psace left per site in MB. |
||
1166 | * -1 means NO LIMIT. |
||
1167 | * @return number |
||
1168 | */ |
||
1169 | static function network_site_upload_space( $option = null ) { |
||
1170 | // value in MB |
||
1171 | return ( get_site_option( 'upload_space_check_disabled' ) ? -1 : get_space_allowed() ); |
||
1172 | } |
||
1173 | |||
1174 | /** |
||
1175 | * Network allowed file types. |
||
1176 | * @return string |
||
1177 | */ |
||
1178 | static function network_upload_file_types( $option = null ) { |
||
1179 | return get_site_option( 'upload_filetypes', 'jpg jpeg png gif' ); |
||
1180 | } |
||
1181 | |||
1182 | /** |
||
1183 | * Maximum file upload size set by the network. |
||
1184 | * @return number |
||
1185 | */ |
||
1186 | static function network_max_upload_file_size( $option = null ) { |
||
1187 | // value in KB |
||
1188 | return get_site_option( 'fileupload_maxk', 300 ); |
||
1189 | } |
||
1190 | |||
1191 | /** |
||
1192 | * Lets us know if a site allows admins to manage the network. |
||
1193 | * @return array |
||
1194 | */ |
||
1195 | static function network_enable_administration_menus( $option = null ) { |
||
1196 | return get_site_option( 'menu_items' ); |
||
1197 | } |
||
1198 | |||
1199 | /** |
||
1200 | * Normalizes a url by doing three things: |
||
1201 | * - Strips protocol |
||
1202 | * - Strips www |
||
1203 | * - Adds a trailing slash |
||
1204 | * |
||
1205 | * @since 4.4.0 |
||
1206 | * @param string $url |
||
1207 | * @return WP_Error|string |
||
1208 | */ |
||
1209 | public static function normalize_url_protocol_agnostic( $url ) { |
||
1210 | $parsed_url = wp_parse_url( trailingslashit( esc_url_raw( $url ) ) ); |
||
1211 | if ( ! $parsed_url || empty( $parsed_url['host'] ) || empty( $parsed_url['path'] ) ) { |
||
1212 | return new WP_Error( 'cannot_parse_url', sprintf( esc_html__( 'Cannot parse URL %s', 'jetpack' ), $url ) ); |
||
1213 | } |
||
1214 | |||
1215 | // Strip www and protocols |
||
1216 | $url = preg_replace( '/^www\./i', '', $parsed_url['host'] . $parsed_url['path'] ); |
||
1217 | return $url; |
||
1218 | } |
||
1219 | |||
1220 | /** |
||
1221 | * Sets a minimum request timeout, and returns the current timeout |
||
1222 | * |
||
1223 | * @since 5.4 |
||
1224 | **/ |
||
1225 | public static function set_min_time_limit( $min_timeout ) { |
||
1226 | $timeout = Jetpack::get_max_execution_time(); |
||
1227 | if ( $timeout < $min_timeout ) { |
||
1228 | $timeout = $min_timeout; |
||
1229 | set_time_limit( $timeout ); |
||
1230 | } |
||
1231 | return $timeout; |
||
1232 | } |
||
1233 | |||
1234 | public static function staticize_subdomain( $url ) { |
||
1235 | |||
1236 | // Extract hostname from URL |
||
1237 | $host = parse_url( $url, PHP_URL_HOST ); |
||
1238 | |||
1239 | // Explode hostname on '.' |
||
1240 | $exploded_host = explode( '.', $host ); |
||
1241 | |||
1242 | // Retrieve the name and TLD |
||
1243 | if ( count( $exploded_host ) > 1 ) { |
||
1244 | $name = $exploded_host[ count( $exploded_host ) - 2 ]; |
||
1245 | $tld = $exploded_host[ count( $exploded_host ) - 1 ]; |
||
1246 | // Rebuild domain excluding subdomains |
||
1247 | $domain = $name . '.' . $tld; |
||
1248 | } else { |
||
1249 | $domain = $host; |
||
1250 | } |
||
1251 | // Array of Automattic domains |
||
1252 | $domain_whitelist = array( 'wordpress.com', 'wp.com' ); |
||
1253 | |||
1254 | // Return $url if not an Automattic domain |
||
1255 | if ( ! in_array( $domain, $domain_whitelist ) ) { |
||
1256 | return $url; |
||
1257 | } |
||
1258 | |||
1259 | if ( is_ssl() ) { |
||
1260 | return preg_replace( '|https?://[^/]++/|', 'https://s-ssl.wordpress.com/', $url ); |
||
1261 | } |
||
1262 | |||
1263 | srand( crc32( basename( $url ) ) ); |
||
1264 | $static_counter = rand( 0, 2 ); |
||
1265 | srand(); // this resets everything that relies on this, like array_rand() and shuffle() |
||
1266 | |||
1267 | return preg_replace( '|://[^/]+?/|', "://s$static_counter.wp.com/", $url ); |
||
1268 | } |
||
1269 | |||
1270 | static function translate_current_user_to_role() { |
||
1271 | foreach ( Jetpack::$capability_translations as $role => $cap ) { |
||
0 ignored issues
–
show
|
|||
1272 | if ( current_user_can( $role ) || current_user_can( $cap ) ) { |
||
1273 | return $role; |
||
1274 | } |
||
1275 | } |
||
1276 | |||
1277 | return false; |
||
1278 | } |
||
1279 | |||
1280 | static function translate_user_to_role( $user ) { |
||
1281 | foreach ( Jetpack::$capability_translations as $role => $cap ) { |
||
0 ignored issues
–
show
The property
capability_translations cannot be accessed from this context as it is declared private in class Jetpack .
This check looks for access to properties that are not accessible from the current context. If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class. ![]() |
|||
1282 | if ( user_can( $user, $role ) || user_can( $user, $cap ) ) { |
||
1283 | return $role; |
||
1284 | } |
||
1285 | } |
||
1286 | |||
1287 | return false; |
||
1288 | } |
||
1289 | |||
1290 | static function translate_role_to_cap( $role ) { |
||
1291 | if ( ! isset( Jetpack::$capability_translations[$role] ) ) { |
||
0 ignored issues
–
show
The property
capability_translations cannot be accessed from this context as it is declared private in class Jetpack .
This check looks for access to properties that are not accessible from the current context. If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class. ![]() |
|||
1292 | return false; |
||
1293 | } |
||
1294 | |||
1295 | return Jetpack::$capability_translations[$role]; |
||
0 ignored issues
–
show
The property
capability_translations cannot be accessed from this context as it is declared private in class Jetpack .
This check looks for access to properties that are not accessible from the current context. If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class. ![]() |
|||
1296 | } |
||
1297 | |||
1298 | /** |
||
1299 | * Returns the Jetpack XML-RPC API |
||
1300 | * |
||
1301 | * @return string |
||
1302 | */ |
||
1303 | public static function xmlrpc_api_url() { |
||
1304 | $base = preg_replace( '#(https?://[^?/]+)(/?.*)?$#', '\\1', JETPACK__API_BASE ); |
||
1305 | return untrailingslashit( $base ) . '/xmlrpc.php'; |
||
1306 | } |
||
1307 | } |
||
1308 |
This check looks for access to properties that are not accessible from the current context.
If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.