Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
53.85% |
14 / 26 |
|
40.00% |
2 / 5 |
CRAP | |
0.00% |
0 / 1 |
| Jetpack_Script_Data | |
53.85% |
14 / 26 |
|
40.00% |
2 / 5 |
29.62 | |
0.00% |
0 / 1 |
| configure | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| set_admin_script_data | |
72.73% |
8 / 11 |
|
0.00% |
0 / 1 |
3.18 | |||
| theme_supports_infinite_scroll | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
30 | |||
| is_settings_consolidation_enabled | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| should_skip_photon_domain | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Jetpack_Script_Data. |
| 4 | * |
| 5 | * Adds Jetpack-plugin-specific data to the consolidated JetpackScriptData object. |
| 6 | * |
| 7 | * @package automattic/jetpack |
| 8 | */ |
| 9 | |
| 10 | namespace Automattic\Jetpack\Plugin; |
| 11 | |
| 12 | use Automattic\Jetpack\Current_Plan as Jetpack_Plan; |
| 13 | use Automattic\Jetpack\My_Jetpack\Initializer as My_Jetpack_Initializer; |
| 14 | |
| 15 | /** |
| 16 | * Jetpack_Script_Data class. |
| 17 | */ |
| 18 | class Jetpack_Script_Data { |
| 19 | |
| 20 | /** |
| 21 | * Configure script data. |
| 22 | */ |
| 23 | public static function configure() { |
| 24 | add_filter( 'jetpack_admin_js_script_data', array( __CLASS__, 'set_admin_script_data' ), 10, 1 ); |
| 25 | } |
| 26 | |
| 27 | /** |
| 28 | * Add Jetpack-plugin-specific data to the consolidated JetpackScriptData object. |
| 29 | * |
| 30 | * @since 15.6 |
| 31 | * |
| 32 | * @param array $data The script data. |
| 33 | * @return array |
| 34 | */ |
| 35 | public static function set_admin_script_data( $data ) { |
| 36 | /** |
| 37 | * Whether to show the Jetpack branding in editor panels (e.g., SEO, AI Assistant). |
| 38 | * |
| 39 | * @since 15.6 |
| 40 | * |
| 41 | * @param bool $show Whether to show the Jetpack editor panel branding. Defaults to true. |
| 42 | */ |
| 43 | $data['jetpack'] = array( |
| 44 | 'flags' => array( |
| 45 | 'showJetpackBranding' => (bool) apply_filters( 'jetpack_show_editor_panel_branding', true ), |
| 46 | 'skipPhotonDomain' => self::should_skip_photon_domain( $data ), |
| 47 | ), |
| 48 | ); |
| 49 | |
| 50 | // Only the settings panel in My Jetpack reads it, so skip the theme folder scan elsewhere. |
| 51 | // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only selects which data to print. |
| 52 | if ( 'my-jetpack' === sanitize_key( wp_unslash( $_GET['page'] ?? '' ) ) && self::is_settings_consolidation_enabled() ) { |
| 53 | $data['jetpack']['themeSupports'] = array( |
| 54 | 'infiniteScroll' => self::theme_supports_infinite_scroll(), |
| 55 | ); |
| 56 | } |
| 57 | |
| 58 | return $data; |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * Whether the current theme supports Infinite Scroll, by itself or through a file Jetpack ships for it. |
| 63 | * |
| 64 | * @since $$next-version$$ |
| 65 | * |
| 66 | * @return bool |
| 67 | */ |
| 68 | public static function theme_supports_infinite_scroll() { |
| 69 | if ( current_theme_supports( 'infinite-scroll' ) ) { |
| 70 | return true; |
| 71 | } |
| 72 | |
| 73 | $stylesheet = wp_get_theme()->get_stylesheet(); |
| 74 | foreach ( \Jetpack::glob_php( JETPACK__PLUGIN_DIR . 'modules/infinite-scroll/themes' ) as $path ) { |
| 75 | if ( basename( $path, '.php' ) === $stylesheet && is_readable( $path ) ) { |
| 76 | return true; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | return false; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Whether settings move to My Jetpack. False with a My Jetpack too old to know the flag. |
| 85 | * |
| 86 | * @return bool |
| 87 | */ |
| 88 | private static function is_settings_consolidation_enabled() { |
| 89 | return method_exists( My_Jetpack_Initializer::class, 'is_settings_consolidation_enabled' ) |
| 90 | && My_Jetpack_Initializer::is_settings_consolidation_enabled(); |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Whether image-serving blocks should skip the external Photon domain (i0.wp.com) and build |
| 95 | * URLs on the site's own Photon-like host instead. |
| 96 | * |
| 97 | * VIP sites serve images from a host of their own, and images routed through the public Photon |
| 98 | * domain are not reachable there. |
| 99 | * |
| 100 | * This is read by the Tiled Gallery block's skipPhotonDomain(), which runs inside the block's |
| 101 | * save() output — including when the editor regenerates that output to validate saved content. |
| 102 | * That regeneration happens while the post is being parsed, before any editor store holds |
| 103 | * settings, so the value has to travel in the script data rather than in editor settings. |
| 104 | * |
| 105 | * The signal is the plan slug rather than Host::is_vip_site(): it is what the block's previous |
| 106 | * isVIP() check used, and switching to the WPCOM_IS_VIP_ENV constant would change which sites get |
| 107 | * site-host URLs — and so which existing galleries need a deprecation to stay valid. |
| 108 | * |
| 109 | * @since 16.2 |
| 110 | * |
| 111 | * @param array $data The script data, which may already carry the site plan. |
| 112 | * @return bool |
| 113 | */ |
| 114 | private static function should_skip_photon_domain( $data ) { |
| 115 | // Another package may have put the plan in the payload already (see Publicize_Script_Data); |
| 116 | // only look it up when it hasn't. |
| 117 | $product_slug = $data['site']['plan']['product_slug'] ?? ''; |
| 118 | if ( '' === $product_slug ) { |
| 119 | $jetpack_plan = Jetpack_Plan::get(); |
| 120 | $product_slug = $jetpack_plan['product_slug']; |
| 121 | } |
| 122 | |
| 123 | /** |
| 124 | * Filter whether the Tiled Gallery and Image Compare blocks should skip the external |
| 125 | * Photon (i0.wp.com) domain and build image URLs on the site's own host instead. |
| 126 | * |
| 127 | * Defaults to true on VIP sites only, and false everywhere else. |
| 128 | * |
| 129 | * Changing this changes the markup Tiled Gallery saves, because it bakes the image URLs into its |
| 130 | * save() output. Galleries saved under the previous value stay valid — the block ships a |
| 131 | * deprecation for each image host, so flipping this either way is safe — and they are |
| 132 | * re-serialized with the new URLs the next time they are saved. |
| 133 | * |
| 134 | * Image Compare only uses this for its editor previews; its save() writes the attachment URLs |
| 135 | * through untouched, so its saved markup does not depend on this value. |
| 136 | * |
| 137 | * @module tiled-gallery |
| 138 | * |
| 139 | * @since 16.2 |
| 140 | * |
| 141 | * @param bool $skip_photon_domain Whether to skip the external Photon domain. |
| 142 | */ |
| 143 | return (bool) apply_filters( 'jetpack_skip_photon_domain', 'vip' === $product_slug ); |
| 144 | } |
| 145 | } |