Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 136 |
|
0.00% |
0 / 8 |
CRAP | n/a |
0 / 0 |
|
| is_jetpack_connected | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
6 | |||
| wp_ajax_wpcom_generate_site_preview_link | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
6 | |||
| wp_ajax_wpcom_delete_site_preview_link | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
12 | |||
| wpcom_get_site_preview_link | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
| replace_site_visibility_load_assets | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
110 | |||
| replace_site_visibility | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
30 | |||
| allowed_options_remove_site_visibility | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
| load_options_update_site_visibility | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
156 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Replaces the 'Site Visibility' privacy options selector with a Calypso link. |
| 4 | * |
| 5 | * @package automattic/jetpack-mu-wpcom |
| 6 | */ |
| 7 | |
| 8 | use Automattic\Jetpack\Connection\Client; |
| 9 | use Automattic\Jetpack\Status\Host; |
| 10 | |
| 11 | /** |
| 12 | * Load dependencies. |
| 13 | */ |
| 14 | require_once __DIR__ . '/../../utils.php'; |
| 15 | |
| 16 | /** |
| 17 | * Whether the current site is connected to Jetpack. |
| 18 | * |
| 19 | * @return bool |
| 20 | */ |
| 21 | function is_jetpack_connected() { |
| 22 | // @phan-suppress-next-line PhanUndeclaredClassMethod |
| 23 | return class_exists( 'Jetpack' ) && Jetpack::is_connection_ready(); |
| 24 | } |
| 25 | |
| 26 | /** |
| 27 | * Generate the links for sharing the site. |
| 28 | */ |
| 29 | function wp_ajax_wpcom_generate_site_preview_link() { |
| 30 | check_ajax_referer( 'wpcom_site_visibility_site_preview_link' ); |
| 31 | |
| 32 | $blog_id = get_wpcom_blog_id(); |
| 33 | $body = Client::wpcom_json_api_request_as_user( |
| 34 | "/sites/$blog_id/preview-links", |
| 35 | '2', |
| 36 | array( |
| 37 | 'method' => 'POST', |
| 38 | ) |
| 39 | ); |
| 40 | |
| 41 | if ( is_wp_error( $body ) ) { |
| 42 | // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- It takes null, but its phpdoc only says int. |
| 43 | wp_send_json_error( $body, null, JSON_UNESCAPED_SLASHES ); |
| 44 | return; |
| 45 | } |
| 46 | |
| 47 | $response = json_decode( wp_remote_retrieve_body( $body ) ); |
| 48 | // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- It takes null, but its phpdoc only says int. |
| 49 | wp_send_json( $response[0] ?? $response, null, JSON_UNESCAPED_SLASHES ); |
| 50 | } |
| 51 | add_action( 'wp_ajax_wpcom_generate_site_preview_link', 'wp_ajax_wpcom_generate_site_preview_link' ); |
| 52 | |
| 53 | /** |
| 54 | * Delete the links for sharing the site. |
| 55 | */ |
| 56 | function wp_ajax_wpcom_delete_site_preview_link() { |
| 57 | check_ajax_referer( 'wpcom_site_visibility_site_preview_link' ); |
| 58 | |
| 59 | if ( ! isset( $_POST['code'] ) ) { |
| 60 | wp_send_json_error( |
| 61 | array( |
| 62 | 'error' => 'Missing code', |
| 63 | ), |
| 64 | null, // @phan-suppress-current-line PhanTypeMismatchArgumentProbablyReal -- It takes null, but its phpdoc only says int. |
| 65 | JSON_UNESCAPED_SLASHES |
| 66 | ); |
| 67 | return; |
| 68 | } |
| 69 | |
| 70 | $code = sanitize_text_field( wp_unslash( $_POST['code'] ) ); |
| 71 | $blog_id = get_wpcom_blog_id(); |
| 72 | $body = Client::wpcom_json_api_request_as_user( |
| 73 | "/sites/$blog_id/preview-links/$code", |
| 74 | '2', |
| 75 | array( |
| 76 | 'method' => 'DELETE', |
| 77 | ) |
| 78 | ); |
| 79 | |
| 80 | if ( is_wp_error( $body ) ) { |
| 81 | return $body; |
| 82 | } |
| 83 | |
| 84 | $response = json_decode( wp_remote_retrieve_body( $body ) ); |
| 85 | return rest_ensure_response( $response ); |
| 86 | } |
| 87 | add_action( 'wp_ajax_wpcom_delete_site_preview_link', 'wp_ajax_wpcom_delete_site_preview_link' ); |
| 88 | |
| 89 | /** |
| 90 | * Get the links for sharing the site. |
| 91 | */ |
| 92 | function wpcom_get_site_preview_link() { |
| 93 | $blog_id = get_wpcom_blog_id(); |
| 94 | $body = Client::wpcom_json_api_request_as_user( |
| 95 | "/sites/$blog_id/preview-links" |
| 96 | ); |
| 97 | |
| 98 | if ( is_wp_error( $body ) ) { |
| 99 | return $body; |
| 100 | } |
| 101 | |
| 102 | $response = json_decode( wp_remote_retrieve_body( $body ) ); |
| 103 | if ( ! is_array( $response ) ) { |
| 104 | return $response; |
| 105 | } |
| 106 | return $response[0]; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Load assets |
| 111 | */ |
| 112 | function replace_site_visibility_load_assets() { |
| 113 | $handle = jetpack_mu_wpcom_enqueue_assets( 'wpcom-replace-site-visibility', array( 'js', 'css' ) ); |
| 114 | |
| 115 | $bundles = wp_list_filter( wpcom_get_site_purchases(), array( 'product_type' => 'bundle' ) ); |
| 116 | $current_plan = array_pop( $bundles ); |
| 117 | |
| 118 | $data = array( |
| 119 | 'blogId' => get_current_blog_id(), |
| 120 | 'homeUrl' => home_url( '/' ), |
| 121 | 'siteTitle' => get_bloginfo( 'name' ), |
| 122 | 'isWpcomStagingSite' => (bool) get_option( 'wpcom_is_staging_site' ), |
| 123 | 'isUnlaunchedSite' => get_option( 'launch-status' ) === 'unlaunched', |
| 124 | 'hasSitePreviewLink' => function_exists( 'wpcom_site_has_feature' ) && wpcom_site_has_feature( \WPCOM_Features::SITE_PREVIEW_LINKS ), |
| 125 | 'sitePreviewLink' => wpcom_get_site_preview_link(), |
| 126 | 'sitePreviewLinkNonce' => wp_create_nonce( 'wpcom_site_visibility_site_preview_link' ), |
| 127 | 'blogPublic' => get_option( 'blog_public' ), |
| 128 | 'wpcomComingSoon' => get_option( 'wpcom_coming_soon' ), |
| 129 | 'wpcomPublicComingSoon' => get_option( 'wpcom_public_coming_soon' ), |
| 130 | 'wpcomDataSharingOptOut' => (bool) get_option( 'wpcom_data_sharing_opt_out' ), |
| 131 | 'siteDomain' => wp_parse_url( home_url(), PHP_URL_HOST ), |
| 132 | 'sitePlan' => $current_plan, |
| 133 | 'hasCustomDomain' => function_exists( 'wpcom_site_has_feature' ) && wpcom_site_has_feature( 'custom-domain' ), |
| 134 | ); |
| 135 | |
| 136 | // If the site is launched, replace the option value with the actual site visibility. |
| 137 | if ( ( new Host() )->is_woa_site() && function_exists( '\Private_Site\site_is_private' ) |
| 138 | && ! $data['isUnlaunchedSite'] && ! $data['wpcomPublicComingSoon'] && ! $data['wpcomComingSoon'] && (string) $data['blogPublic'] !== '0' |
| 139 | ) { |
| 140 | // @phan-suppress-next-line PhanUndeclaredFunction |
| 141 | $data['blogPublic'] = \Private_Site\site_is_private() ? '-1' : '1'; |
| 142 | } |
| 143 | |
| 144 | $encoded_data = wp_json_encode( $data, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); |
| 145 | wp_add_inline_script( |
| 146 | $handle, |
| 147 | "var JETPACK_MU_WPCOM_SITE_VISIBILITY = $encoded_data;", |
| 148 | 'before' |
| 149 | ); |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * Replaces the 'Site Visibility' privacy options selector with a Calypso link. |
| 154 | */ |
| 155 | function replace_site_visibility() { |
| 156 | // We are not either in Simple or Atomic. |
| 157 | if ( ! class_exists( 'Automattic\Jetpack\Status' ) ) { |
| 158 | return; |
| 159 | } |
| 160 | |
| 161 | $jetpack_status = new Automattic\Jetpack\Status(); |
| 162 | |
| 163 | if ( ! is_jetpack_connected() && $jetpack_status->is_private_site() ) { |
| 164 | $settings_url = esc_url_raw( sprintf( '/wp-admin/admin.php?page=jetpack' ) ); |
| 165 | $manage_label = __( 'Jetpack is disconnected & site is private. Reconnect Jetpack to manage site visibility settings.', 'jetpack-mu-wpcom' ); |
| 166 | $escaped_content = '<a href="' . esc_url( $settings_url ) . '">' . esc_html( $manage_label ) . '</a>'; |
| 167 | } elseif ( ! is_jetpack_connected() ) { |
| 168 | return; |
| 169 | } else { |
| 170 | $escaped_content = <<<'HTML' |
| 171 | <fieldset id="wpcom-site-visibility"> |
| 172 | <img src="images/loading.gif" alt="Loading..." width="16" height="16"> |
| 173 | </fieldset> |
| 174 | HTML; |
| 175 | |
| 176 | replace_site_visibility_load_assets(); |
| 177 | } |
| 178 | |
| 179 | ?> |
| 180 | <noscript> |
| 181 | <p><?php echo wp_json_encode( $escaped_content, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?></p> |
| 182 | </noscript> |
| 183 | <script> |
| 184 | ( function() { |
| 185 | var widgetArea = document.querySelector( '.option-site-visibility td' ); |
| 186 | if ( ! widgetArea ) { |
| 187 | return; |
| 188 | } |
| 189 | widgetArea.innerHTML = <?php echo wp_json_encode( $escaped_content, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?>; |
| 190 | } )() |
| 191 | </script> |
| 192 | <?php |
| 193 | } |
| 194 | add_action( 'blog_privacy_selector', 'replace_site_visibility' ); |
| 195 | |
| 196 | /** |
| 197 | * Filter out the settings related to the site visibility. |
| 198 | * |
| 199 | * @param array $allowed_options The allowed options list. |
| 200 | * @return array |
| 201 | */ |
| 202 | function allowed_options_remove_site_visibility( $allowed_options ) { |
| 203 | $del_options = array( |
| 204 | 'reading' => array( 'blog_public' ), |
| 205 | ); |
| 206 | |
| 207 | $allowed_options = remove_allowed_options( $del_options, $allowed_options ); |
| 208 | |
| 209 | return $allowed_options; |
| 210 | } |
| 211 | |
| 212 | /** |
| 213 | * Update the site options that are related to the site visibility. |
| 214 | */ |
| 215 | function load_options_update_site_visibility() { |
| 216 | $action = ! empty( $_REQUEST['action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) : ''; |
| 217 | $option_page = ! empty( $_REQUEST['option_page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['option_page'] ) ) : ''; |
| 218 | if ( $action !== 'update' || $option_page !== 'reading' || ! current_user_can( 'manage_options' ) ) { |
| 219 | return; |
| 220 | } |
| 221 | |
| 222 | check_admin_referer( 'reading-options' ); |
| 223 | |
| 224 | $data = array(); |
| 225 | |
| 226 | $allowed_options = array( |
| 227 | 'blog_public', |
| 228 | 'wpcom_coming_soon', |
| 229 | 'wpcom_public_coming_soon', |
| 230 | 'wpcom_data_sharing_opt_out', |
| 231 | ); |
| 232 | |
| 233 | foreach ( $allowed_options as $option ) { |
| 234 | if ( isset( $_POST[ $option ] ) ) { |
| 235 | $data[ $option ] = sanitize_text_field( wp_unslash( $_POST[ $option ] ) ); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | if ( empty( $data ) ) { |
| 240 | add_filter( 'allowed_options', 'allowed_options_remove_site_visibility' ); |
| 241 | return; |
| 242 | } |
| 243 | |
| 244 | $blog_id = get_wpcom_blog_id(); |
| 245 | |
| 246 | // wpcom_json_api_request_as_user does not support internal requests. |
| 247 | $request = defined( 'IS_WPCOM' ) && IS_WPCOM ? 'wpcom_json_api_request_as_blog' : 'wpcom_json_api_request_as_user'; |
| 248 | $response = Client::$request( |
| 249 | "/sites/$blog_id/site-visibility", |
| 250 | 'v2', |
| 251 | array( |
| 252 | 'method' => 'POST', |
| 253 | 'headers' => array( |
| 254 | 'content-type' => 'application/json', |
| 255 | ), |
| 256 | ), |
| 257 | wp_json_encode( $data, JSON_UNESCAPED_SLASHES ), |
| 258 | 'wpcom' |
| 259 | ); |
| 260 | |
| 261 | if ( wp_remote_retrieve_response_code( $response ) !== 200 ) { |
| 262 | add_settings_error( 'general', 'settings_updated', __( 'Settings save failed.', 'jetpack-mu-wpcom' ), 'error' ); |
| 263 | } |
| 264 | } |
| 265 | add_action( 'load-options.php', 'load_options_update_site_visibility' ); |