Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
61.11% |
22 / 36 |
|
57.14% |
12 / 21 |
CRAP | |
0.00% |
0 / 1 |
| Environment | |
61.11% |
22 / 36 |
|
57.14% |
12 / 21 |
134.10 | |
0.00% |
0 / 1 |
| is_block_theme | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| is_simple_site | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| sharing_module_running | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| legacy_sharing_switched_off | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| legacy_sharing_supported | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
3 | |||
| settings_screen_supported | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| likes_supported | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
3 | |||
| is_connected | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| is_offline_mode | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| likes_module_running | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| legacy_likes_switched_off | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| comment_likes_module_running | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| comment_likes_enabled | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| comment_likes_follow_likes_settings | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| likes_settings_in_use | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| twitter_site_tag_used | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| module_active | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| sharing_block_registered | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| like_block_registered | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| single_template_editor_url | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
5.02 | |||
| block_is_registered | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Reads the site state that Settings > Sharing branches on. |
| 4 | * |
| 5 | * @package automattic/jetpack-sharing-likes |
| 6 | */ |
| 7 | |
| 8 | declare( strict_types = 1 ); |
| 9 | |
| 10 | namespace Automattic\Jetpack\Sharing_Likes\Settings; |
| 11 | |
| 12 | use Automattic\Jetpack\Connection\Manager as Connection_Manager; |
| 13 | use Automattic\Jetpack\Modules; |
| 14 | use Automattic\Jetpack\Status; |
| 15 | use Automattic\Jetpack\Status\Host; |
| 16 | |
| 17 | /** |
| 18 | * The facts Settings > Sharing branches on, read in one place so the sections |
| 19 | * and the state resolver stay free of environment lookups. |
| 20 | */ |
| 21 | final class Environment { |
| 22 | |
| 23 | /** |
| 24 | * Memoised Site Editor URL, since resolving the template hits the theme's files. |
| 25 | * |
| 26 | * @var string|null |
| 27 | */ |
| 28 | private static $single_template_editor_url = null; |
| 29 | |
| 30 | /** |
| 31 | * Whether the active theme is a block theme. |
| 32 | */ |
| 33 | public static function is_block_theme(): bool { |
| 34 | return wp_is_block_theme(); |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * Whether this is a WordPress.com Simple site. |
| 39 | */ |
| 40 | public static function is_simple_site(): bool { |
| 41 | return ( new Host() )->is_wpcom_simple(); |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * Whether sharing buttons can still produce output. |
| 46 | */ |
| 47 | public static function sharing_module_running(): bool { |
| 48 | return self::legacy_sharing_supported() && self::module_active( 'sharedaddy' ); |
| 49 | } |
| 50 | |
| 51 | /** |
| 52 | * Whether every sharing service has been removed, so sharedaddy renders nothing. |
| 53 | * |
| 54 | * An absent option is not that: `Sharing_Service::get_blog_services()` falls |
| 55 | * back to its default services when the option was never saved. |
| 56 | */ |
| 57 | public static function legacy_sharing_switched_off(): bool { |
| 58 | $services = get_option( 'sharing-services' ); |
| 59 | |
| 60 | if ( ! is_array( $services ) ) { |
| 61 | return false; |
| 62 | } |
| 63 | |
| 64 | return empty( $services['visible'] ) && empty( $services['hidden'] ); |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * Whether this site can have legacy sharing buttons at all. |
| 69 | * |
| 70 | * The module needs no connection, but `Jetpack::load_modules()` includes |
| 71 | * nothing on a site that is neither connected nor in offline mode, and |
| 72 | * `Modules::activate()` refuses there too: an active module renders no |
| 73 | * buttons, and offering to turn it on would do nothing. Simple loads |
| 74 | * sharedaddy from `post-flair.php` without either. |
| 75 | */ |
| 76 | public static function legacy_sharing_supported(): bool { |
| 77 | return self::is_simple_site() || self::is_connected() || self::is_offline_mode(); |
| 78 | } |
| 79 | |
| 80 | /** |
| 81 | * Whether Settings > Sharing has anything to offer this site. |
| 82 | * |
| 83 | * Neither the legacy features nor their blocks load on a site that is neither |
| 84 | * connected nor in offline mode. Checking sharing alone is enough: any site |
| 85 | * that can have Like buttons (connected, or Simple) passes that check too. |
| 86 | */ |
| 87 | public static function settings_screen_supported(): bool { |
| 88 | return self::legacy_sharing_supported(); |
| 89 | } |
| 90 | |
| 91 | /** |
| 92 | * Whether this site can have Like buttons at all. |
| 93 | * |
| 94 | * The Likes module declares `Requires Connection: Yes`, so without a |
| 95 | * WordPress.com connection it cannot be activated and its buttons cannot |
| 96 | * render: the widget is keyed on the blog ID a connection provides. |
| 97 | * Offline mode keeps a connected site's tokens, but `Jetpack::load_modules()` |
| 98 | * skips every module that requires a connection until it ends. |
| 99 | */ |
| 100 | public static function likes_supported(): bool { |
| 101 | return self::is_simple_site() || ( self::is_connected() && ! self::is_offline_mode() ); |
| 102 | } |
| 103 | |
| 104 | /** |
| 105 | * Whether the site holds a WordPress.com connection. |
| 106 | */ |
| 107 | private static function is_connected(): bool { |
| 108 | return ( new Connection_Manager( 'jetpack' ) )->is_connected(); |
| 109 | } |
| 110 | |
| 111 | /** |
| 112 | * Whether the site is in offline mode, where it cannot connect to WordPress.com either. |
| 113 | */ |
| 114 | public static function is_offline_mode(): bool { |
| 115 | return ( new Status() )->is_offline_mode(); |
| 116 | } |
| 117 | |
| 118 | /** |
| 119 | * Whether Like buttons can still produce output. |
| 120 | * |
| 121 | * The module can be left active in the options through a disconnect, |
| 122 | * which is why support is checked too. |
| 123 | */ |
| 124 | public static function likes_module_running(): bool { |
| 125 | return self::likes_supported() && self::module_active( 'likes' ); |
| 126 | } |
| 127 | |
| 128 | /** |
| 129 | * Whether Simple's posts show neither a Like nor a Reblog button, bar those that opted in individually. |
| 130 | * |
| 131 | * Both count because the legacy widget renders for either. Jetpack and Atomic never |
| 132 | * render Reblog, and switch to the block by turning the module off instead. |
| 133 | */ |
| 134 | public static function legacy_likes_switched_off(): bool { |
| 135 | return self::is_simple_site() |
| 136 | && ! Likes_Options::likes_enabled_sitewide() |
| 137 | && ! Likes_Options::reblogs_enabled_sitewide(); |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * Whether comments can still be liked. |
| 142 | * |
| 143 | * Comment Likes is its own module, but it reads the Likes settings: both |
| 144 | * `disabled_likes` and the shared placement gate `is_likes_visible()`. So a |
| 145 | * site running it without the Likes module still needs those controls. |
| 146 | */ |
| 147 | public static function comment_likes_module_running(): bool { |
| 148 | return self::likes_supported() && self::module_active( 'comment-likes' ); |
| 149 | } |
| 150 | |
| 151 | /** |
| 152 | * Whether Comment Likes are switched on for this site. |
| 153 | * |
| 154 | * - On WordPress.com Simple, which has no modules: the `jetpack_comment_likes_enabled` option. |
| 155 | * - On Atomic and self-hosted Jetpack sites: the Comment Likes module, which never reads that option. |
| 156 | */ |
| 157 | public static function comment_likes_enabled(): bool { |
| 158 | return self::is_simple_site() ? Likes_Options::comment_likes_enabled() : self::comment_likes_module_running(); |
| 159 | } |
| 160 | |
| 161 | /** |
| 162 | * Whether Comment Likes read the Likes settings: the sitewide default and placement. Simple's do not. |
| 163 | */ |
| 164 | public static function comment_likes_follow_likes_settings(): bool { |
| 165 | return ! self::is_simple_site() && self::comment_likes_module_running(); |
| 166 | } |
| 167 | |
| 168 | /** |
| 169 | * Whether anything on this site still reads the Likes settings. |
| 170 | * |
| 171 | * Both features are gated on `disabled_likes` and the shared placement, so |
| 172 | * either one running makes the Likes placement defaults the ones that apply. |
| 173 | */ |
| 174 | public static function likes_settings_in_use(): bool { |
| 175 | return self::likes_module_running() || self::comment_likes_module_running(); |
| 176 | } |
| 177 | |
| 178 | /** |
| 179 | * Whether anything on this site reads the Twitter Site Tag option. |
| 180 | * |
| 181 | * Twitter Cards read it, and through them the Sharing Buttons block's X `via`. |
| 182 | * Simple's Twitter Cards read `twitter_via`, which wpcom serves and saves this option from. |
| 183 | */ |
| 184 | public static function twitter_site_tag_used(): bool { |
| 185 | /** This filter is documented in projects/plugins/jetpack/class.jetpack.php */ |
| 186 | return ! apply_filters( 'jetpack_disable_twitter_cards', false ); |
| 187 | } |
| 188 | |
| 189 | /** |
| 190 | * Whether a module is active. |
| 191 | * |
| 192 | * Simple has no modules: wpcom loads both features on every request, so |
| 193 | * every module counts as active there whatever the option holds. |
| 194 | * |
| 195 | * @param string $slug Module slug. |
| 196 | */ |
| 197 | private static function module_active( string $slug ): bool { |
| 198 | return self::is_simple_site() || ( new Modules() )->is_active( $slug ); |
| 199 | } |
| 200 | |
| 201 | /** |
| 202 | * Whether the Sharing Buttons block is available to offer as an alternative. |
| 203 | */ |
| 204 | public static function sharing_block_registered(): bool { |
| 205 | return self::block_is_registered( 'jetpack/sharing-buttons' ); |
| 206 | } |
| 207 | |
| 208 | /** |
| 209 | * Whether the Like block is available to offer as an alternative. |
| 210 | */ |
| 211 | public static function like_block_registered(): bool { |
| 212 | return self::block_is_registered( 'jetpack/like' ); |
| 213 | } |
| 214 | |
| 215 | /** |
| 216 | * Site Editor URL for the active theme's single post template. |
| 217 | * |
| 218 | * Empty when the theme has no `single` template, which callers treat as |
| 219 | * "offer no Site Editor link" rather than linking somewhere that 404s: a |
| 220 | * block theme shipping only `index.html` is the case that hits this. |
| 221 | */ |
| 222 | public static function single_template_editor_url(): string { |
| 223 | if ( null !== self::$single_template_editor_url ) { |
| 224 | return self::$single_template_editor_url; |
| 225 | } |
| 226 | |
| 227 | $stylesheet = get_stylesheet(); |
| 228 | $template = $stylesheet ? $stylesheet . '//single' : ''; |
| 229 | |
| 230 | if ( ! $template || ! get_block_template( $template ) ) { |
| 231 | self::$single_template_editor_url = ''; |
| 232 | |
| 233 | return self::$single_template_editor_url; |
| 234 | } |
| 235 | |
| 236 | // `add_query_arg()` does not encode, and the Site Editor router wants `p` percent-encoded. |
| 237 | self::$single_template_editor_url = admin_url( |
| 238 | 'site-editor.php?p=' . rawurlencode( '/wp_template/' . $template ) . '&canvas=edit' |
| 239 | ); |
| 240 | |
| 241 | return self::$single_template_editor_url; |
| 242 | } |
| 243 | |
| 244 | /** |
| 245 | * Whether a block is registered, and so available to add to a template. |
| 246 | * |
| 247 | * Registration happens on `init`, well before this screen renders. |
| 248 | * |
| 249 | * @param string $name Fully qualified block name. |
| 250 | */ |
| 251 | private static function block_is_registered( string $name ): bool { |
| 252 | return \WP_Block_Type_Registry::get_instance()->is_registered( $name ); |
| 253 | } |
| 254 | } |