Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 179 |
|
0.00% |
0 / 12 |
CRAP | n/a |
0 / 0 |
|
| wpcom_normalize_site_logo_id | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
30 | |||
| wpcom_site_logo_edit_link | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
42 | |||
| wpcom_site_logo_edit_description | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
12 | |||
| wpcom_fiverr_logo | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
| wpcom_fiverr_cta_button | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
| wpcom_fiverr_cta | |
0.00% |
0 / 45 |
|
0.00% |
0 / 1 |
42 | |||
| wpcom_fiverr | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| wpcom_site_management_panel_link | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| wpcom_site_management_panel | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| wpcom_options_general_get_site_domains | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
132 | |||
| wpcom_options_general_get_primary_domain_candidates | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
156 | |||
| wpcom_enqueue_options_general_assets | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Override /wp-admin/options-general.php |
| 4 | * |
| 5 | * @package automattic/jetpack-mu-wpcom |
| 6 | */ |
| 7 | |
| 8 | use Automattic\Jetpack\Connection\Client; |
| 9 | use Automattic\Jetpack\Constants; |
| 10 | use Automattic\Jetpack\Jetpack_Mu_Wpcom; |
| 11 | |
| 12 | /** |
| 13 | * Normalize a site logo value to a positive attachment ID. |
| 14 | * |
| 15 | * The value may hold an attachment ID, a legacy `array( 'id' => ... )`, or a WP_Error, |
| 16 | * so anything that is not a positive scalar resolves to 0. |
| 17 | * |
| 18 | * @param mixed $value The raw site_logo option or custom_logo theme mod value. |
| 19 | * @return int A positive attachment ID, or 0 when none is usable. |
| 20 | */ |
| 21 | function wpcom_normalize_site_logo_id( $value ) { |
| 22 | if ( is_array( $value ) && isset( $value['id'] ) ) { |
| 23 | $value = $value['id']; |
| 24 | } |
| 25 | return ( is_scalar( $value ) && (int) $value > 0 ) ? (int) $value : 0; |
| 26 | } |
| 27 | |
| 28 | /** |
| 29 | * Resolve the URL for editing the current site logo. |
| 30 | * |
| 31 | * Block themes use the Site Editor's Identity screen; classic themes use the |
| 32 | * Customizer control matching their logo support (mirroring the logo-tool feature). |
| 33 | * The URL is empty when no reliable destination exists, so callers can omit the link. |
| 34 | * |
| 35 | * @return array{url:string, is_block:bool} The edit URL and block-theme flag. |
| 36 | */ |
| 37 | function wpcom_site_logo_edit_link() { |
| 38 | if ( wp_is_block_theme() ) { |
| 39 | // The Identity screen shipped in Gutenberg 22.8 / WordPress 7.1; omit the |
| 40 | // link when it is unavailable. |
| 41 | $has_identity = defined( 'GUTENBERG_VERSION' ) |
| 42 | ? version_compare( GUTENBERG_VERSION, '22.8', '>=' ) |
| 43 | : version_compare( get_bloginfo( 'version' ), '7.1', '>=' ); |
| 44 | |
| 45 | return array( |
| 46 | 'url' => $has_identity ? admin_url( 'site-editor.php?p=%2Fidentity' ) : '', |
| 47 | 'is_block' => true, |
| 48 | ); |
| 49 | } |
| 50 | |
| 51 | if ( current_theme_supports( 'custom-logo' ) ) { |
| 52 | $url = admin_url( 'customize.php?autofocus[control]=custom_logo' ); |
| 53 | } elseif ( current_theme_supports( 'site-logo' ) ) { |
| 54 | $url = admin_url( 'customize.php?autofocus[control]=site_logo' ); |
| 55 | } else { |
| 56 | $url = ''; |
| 57 | } |
| 58 | |
| 59 | return array( |
| 60 | 'url' => $url, |
| 61 | 'is_block' => false, |
| 62 | ); |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * The description pointing at where the site logo can be set. |
| 67 | * |
| 68 | * Rendered whether or not a logo exists, so the empty state still offers a way |
| 69 | * to upload one. That is the case where someone is most likely looking for it. |
| 70 | * The wording says "set" so it reads correctly for both adding and replacing. |
| 71 | */ |
| 72 | function wpcom_site_logo_edit_description() { |
| 73 | $logo_edit_link = wpcom_site_logo_edit_link(); |
| 74 | |
| 75 | // Only promise an edit path when a known destination exists. |
| 76 | if ( ! $logo_edit_link['url'] ) { |
| 77 | return; |
| 78 | } |
| 79 | ?> |
| 80 | <p class="description wpcom-site-logo-description"> |
| 81 | <?php |
| 82 | if ( $logo_edit_link['is_block'] ) { |
| 83 | printf( |
| 84 | /* translators: %1$s: opening link tag to the Site Editor, %2$s: closing link tag. */ |
| 85 | esc_html__( 'Displays in your site\'s layout via the Site Logo block. %1$sYou can set your site logo in the site editor%2$s.', 'jetpack-mu-wpcom' ), |
| 86 | '<a href="' . esc_url( $logo_edit_link['url'] ) . '">', |
| 87 | '</a>' |
| 88 | ); |
| 89 | } else { |
| 90 | printf( |
| 91 | /* translators: %1$s: opening link tag to the Customizer, %2$s: closing link tag. */ |
| 92 | esc_html__( '%1$sYou can set your site logo in the Customizer%2$s.', 'jetpack-mu-wpcom' ), |
| 93 | '<a href="' . esc_url( $logo_edit_link['url'] ) . '">', |
| 94 | '</a>' |
| 95 | ); |
| 96 | } |
| 97 | ?> |
| 98 | </p> |
| 99 | <?php |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * The Fiverr logo mark. |
| 104 | * |
| 105 | * Decorative in every current use, since the adjacent text always names Fiverr. |
| 106 | */ |
| 107 | function wpcom_fiverr_logo() { |
| 108 | ?> |
| 109 | <svg class="wpcom-fiverr-cta-logo" width="20" height="20" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"> |
| 110 | <circle cx="250" cy="250" r="177" fill="white"/> |
| 111 | <path d="M500 250C500 111.93 388.07 0 250 0C111.93 0 0 111.93 0 250C0 388.07 111.93 500 250 500C388.07 500 500 388.07 500 250ZM360.42 382.5H294.77V237.2H231.94V382.5H165.9V237.2H128.45V183.45H165.9V167.13C165.9 124.54 198.12 95.48 246.05 95.48H294.78V149.22H256.93C241.62 149.22 231.95 157.58 231.95 171.12V183.45H360.43V382.5H360.42Z" fill="#1DBF73"/> |
| 112 | </svg> |
| 113 | <?php |
| 114 | } |
| 115 | |
| 116 | /** |
| 117 | * The Fiverr logo-maker CTA button's DOM. |
| 118 | */ |
| 119 | function wpcom_fiverr_cta_button() { |
| 120 | ?> |
| 121 | <button class="wpcom-fiverr-cta-button button" type="button"> |
| 122 | <?php wpcom_fiverr_logo(); ?> |
| 123 | <?php esc_html_e( 'Try Fiverr Logo Maker', 'jetpack-mu-wpcom' ); ?> |
| 124 | </button> |
| 125 | <?php |
| 126 | } |
| 127 | |
| 128 | /** |
| 129 | * The fiverr cta's DOM. |
| 130 | */ |
| 131 | function wpcom_fiverr_cta() { |
| 132 | // Core keeps the site_logo option and custom_logo theme mod in sync; read either. |
| 133 | $logo_id = wpcom_normalize_site_logo_id( get_option( 'site_logo' ) ); |
| 134 | if ( ! $logo_id ) { |
| 135 | $logo_id = wpcom_normalize_site_logo_id( get_theme_mod( 'custom_logo' ) ); |
| 136 | } |
| 137 | |
| 138 | $logo_img = ''; |
| 139 | if ( $logo_id ) { |
| 140 | // Fall back to the site title when the logo has no alt text, so the preview |
| 141 | // is still announced to assistive technology. |
| 142 | $logo_alt = trim( wp_strip_all_tags( (string) get_post_meta( $logo_id, '_wp_attachment_image_alt', true ) ) ); |
| 143 | if ( '' === $logo_alt ) { |
| 144 | $site_name = get_bloginfo( 'name' ); |
| 145 | $logo_alt = $site_name |
| 146 | /* translators: %s: The site title. */ |
| 147 | ? sprintf( __( 'Current site logo for %s', 'jetpack-mu-wpcom' ), $site_name ) |
| 148 | : __( 'Current site logo', 'jetpack-mu-wpcom' ); |
| 149 | } |
| 150 | // Request a proportional size, not a square, so wide logos aren't shown as a |
| 151 | // center-cropped thumbnail; CSS caps the dimensions. |
| 152 | $logo_img = wp_get_attachment_image( |
| 153 | $logo_id, |
| 154 | 'medium', |
| 155 | false, |
| 156 | array( |
| 157 | 'class' => 'wpcom-site-logo-preview-image', |
| 158 | 'alt' => $logo_alt, |
| 159 | ) |
| 160 | ); |
| 161 | } |
| 162 | ?> |
| 163 | <div id="wpcom-fiverr-cta"> |
| 164 | <?php if ( $logo_img ) : ?> |
| 165 | <div class="wpcom-site-logo"> |
| 166 | <div class="wpcom-site-logo-preview"> |
| 167 | <?php echo $logo_img; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_get_attachment_image() returns escaped markup. ?> |
| 168 | </div> |
| 169 | <?php wpcom_fiverr_cta_button(); ?> |
| 170 | </div> |
| 171 | <?php else : ?> |
| 172 | <div class="wpcom-fiverr-cta-box"> |
| 173 | <?php wpcom_fiverr_logo(); ?> |
| 174 | <div class="wpcom-fiverr-cta-description"> |
| 175 | <p> |
| 176 | <?php |
| 177 | printf( |
| 178 | /* translators: %1$s: opening link tag to the Fiverr logo maker, %2$s: closing link tag. */ |
| 179 | esc_html__( 'No logo yet? Make one in minutes with %1$sFiverr Logo Maker%2$s.', 'jetpack-mu-wpcom' ), |
| 180 | '<a class="wpcom-fiverr-cta-link" href="' . esc_url( 'https://wp.me/logo-maker/?utm_campaign=general_settings' ) . '" target="_blank" rel="noopener noreferrer">', |
| 181 | '</a>' |
| 182 | ); |
| 183 | ?> |
| 184 | </p> |
| 185 | <p><?php esc_html_e( 'Pre-designed by top talent. Just add your touch.', 'jetpack-mu-wpcom' ); ?></p> |
| 186 | </div> |
| 187 | </div> |
| 188 | <?php endif; ?> |
| 189 | </div> |
| 190 | <?php |
| 191 | // Sits outside the Fiverr CTA: it describes the Site Logo setting itself, |
| 192 | // not the upsell. |
| 193 | wpcom_site_logo_edit_description(); |
| 194 | } |
| 195 | |
| 196 | /** |
| 197 | * Add the fiverr cta to the general settings page. |
| 198 | */ |
| 199 | function wpcom_fiverr() { |
| 200 | add_settings_field( 'wpcom_fiverr_cta', __( 'Site Logo', 'jetpack-mu-wpcom' ), 'wpcom_fiverr_cta', 'general', 'default' ); |
| 201 | } |
| 202 | add_action( 'load-options-general.php', 'wpcom_fiverr' ); |
| 203 | |
| 204 | /** |
| 205 | * DOM for the link to the Site Management Panel on WordPress.com. |
| 206 | */ |
| 207 | function wpcom_site_management_panel_link() { |
| 208 | ?> |
| 209 | <a href="https://my.wordpress.com/sites/<?php echo esc_attr( wpcom_get_site_slug() ); ?>"> |
| 210 | <?php esc_html_e( 'Manage site ownership and other site tools on WordPress.com ↗', 'jetpack-mu-wpcom' ); ?> |
| 211 | </a> |
| 212 | <?php |
| 213 | } |
| 214 | |
| 215 | /** |
| 216 | * Add the link to the Site Management Panel on WordPress.com to the general settings page. |
| 217 | */ |
| 218 | function wpcom_site_management_panel() { |
| 219 | $current_screen = wpcom_admin_get_current_screen(); |
| 220 | if ( in_array( $current_screen, WPCOM_DUPLICATED_VIEW, true ) ) { |
| 221 | add_settings_field( 'wpcom_site_management_panel_link', __( 'WordPress.com Site Settings', 'jetpack-mu-wpcom' ), 'wpcom_site_management_panel_link', 'general' ); |
| 222 | } |
| 223 | } |
| 224 | add_action( 'load-options-general.php', 'wpcom_site_management_panel' ); |
| 225 | |
| 226 | /** |
| 227 | * Get the site's domains, from the domains table on Simple and from the WordPress.com API on Atomic. |
| 228 | * |
| 229 | * @return array<int,object>|null Domain objects shaped like /sites/{id}/domains, or null if the lookup failed. |
| 230 | */ |
| 231 | function wpcom_options_general_get_site_domains() { |
| 232 | if ( Constants::is_true( 'IS_WPCOM' ) ) { |
| 233 | if ( ! class_exists( 'Domain_Management' ) && file_exists( WP_CONTENT_DIR . '/admin-plugins/domains/management.php' ) ) { |
| 234 | require_once WP_CONTENT_DIR . '/admin-plugins/domains/management.php'; |
| 235 | } |
| 236 | if ( ! class_exists( 'Domain_Management' ) ) { |
| 237 | return null; |
| 238 | } |
| 239 | return \Domain_Management::get_domains_for_current_blog_light_load(); |
| 240 | } |
| 241 | |
| 242 | $site_id = \Jetpack_Options::get_option( 'id' ); |
| 243 | if ( ! $site_id ) { |
| 244 | return null; |
| 245 | } |
| 246 | |
| 247 | $response = Client::wpcom_json_api_request_as_blog( |
| 248 | sprintf( '/sites/%d/domains', (int) $site_id ), |
| 249 | '1.2', |
| 250 | array( |
| 251 | 'method' => 'GET', |
| 252 | // A slow answer must not become a slow settings page. |
| 253 | 'timeout' => 5, |
| 254 | ), |
| 255 | null, |
| 256 | 'rest' |
| 257 | ); |
| 258 | if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { |
| 259 | return null; |
| 260 | } |
| 261 | |
| 262 | $body = json_decode( wp_remote_retrieve_body( $response ) ); |
| 263 | if ( ! is_object( $body ) || ! isset( $body->domains ) || ! is_array( $body->domains ) ) { |
| 264 | return null; |
| 265 | } |
| 266 | |
| 267 | return $body->domains; |
| 268 | } |
| 269 | |
| 270 | /** |
| 271 | * Get the custom domains that could become the site address of a site still on its WordPress.com address. |
| 272 | * |
| 273 | * Covers a domain bought during setup that never became primary. A site that already |
| 274 | * uses a custom domain gets an empty list, so it keeps the "Add custom address" button. |
| 275 | * |
| 276 | * @return string[] Domain names. |
| 277 | */ |
| 278 | function wpcom_options_general_get_primary_domain_candidates() { |
| 279 | $domains = wpcom_options_general_get_site_domains(); |
| 280 | if ( ! is_array( $domains ) ) { |
| 281 | return array(); |
| 282 | } |
| 283 | |
| 284 | $candidates = array(); |
| 285 | foreach ( $domains as $domain ) { |
| 286 | if ( empty( $domain->domain ) || ! is_string( $domain->domain ) ) { |
| 287 | continue; |
| 288 | } |
| 289 | |
| 290 | $is_wpcom_provided = ! empty( $domain->wpcom_domain ) || ! empty( $domain->is_wpcom_staging_domain ); |
| 291 | |
| 292 | if ( ! empty( $domain->primary_domain ) ) { |
| 293 | if ( ! $is_wpcom_provided ) { |
| 294 | return array(); |
| 295 | } |
| 296 | continue; |
| 297 | } |
| 298 | |
| 299 | if ( |
| 300 | $is_wpcom_provided || |
| 301 | empty( $domain->can_set_as_primary ) || |
| 302 | ! empty( $domain->expired ) || |
| 303 | ! empty( $domain->set_primary_domain_pending ) |
| 304 | ) { |
| 305 | continue; |
| 306 | } |
| 307 | |
| 308 | $candidates[] = $domain->domain; |
| 309 | } |
| 310 | |
| 311 | return $candidates; |
| 312 | } |
| 313 | |
| 314 | /** |
| 315 | * Display the site URL in General Settings on Simple Classic sites. |
| 316 | * |
| 317 | * @param string $hook_suffix The current admin page. |
| 318 | */ |
| 319 | function wpcom_enqueue_options_general_assets( $hook_suffix = '' ) { |
| 320 | $asset_file = include Jetpack_Mu_Wpcom::BASE_DIR . 'build/wpcom-options-general/wpcom-options-general.asset.php'; |
| 321 | |
| 322 | wp_enqueue_style( |
| 323 | 'wpcom-options-general', |
| 324 | plugins_url( 'build/wpcom-options-general/wpcom-options-general.css', Jetpack_Mu_Wpcom::BASE_FILE ), |
| 325 | array(), |
| 326 | $asset_file['version'] ?? filemtime( Jetpack_Mu_Wpcom::BASE_DIR . 'build/wpcom-options-general/wpcom-options-general.css' ) |
| 327 | ); |
| 328 | |
| 329 | wp_enqueue_script( |
| 330 | 'wpcom-options-general', |
| 331 | plugins_url( 'build/wpcom-options-general/wpcom-options-general.js', Jetpack_Mu_Wpcom::BASE_FILE ), |
| 332 | $asset_file['dependencies'] ?? array(), |
| 333 | $asset_file['version'] ?? filemtime( Jetpack_Mu_Wpcom::BASE_DIR . 'build/wpcom-options-general/wpcom-options-general.js' ), |
| 334 | true |
| 335 | ); |
| 336 | wp_set_script_translations( 'wpcom-options-general', 'jetpack-mu-wpcom' ); |
| 337 | $site_slug = wpcom_get_site_slug(); |
| 338 | $options_general_url = admin_url( 'options-general.php' ); |
| 339 | wp_add_inline_script( |
| 340 | 'wpcom-options-general', |
| 341 | 'window.wpcomSiteUrl = ' . wp_json_encode( |
| 342 | array( |
| 343 | 'siteUrl' => get_site_url(), |
| 344 | 'homeUrl' => home_url(), |
| 345 | 'siteSlug' => $site_slug, |
| 346 | 'optionsGeneralUrl' => $options_general_url, |
| 347 | // Only looked up on Settings > General, the one page that uses it. |
| 348 | 'primaryDomainCandidates' => 'options-general.php' === $hook_suffix ? wpcom_options_general_get_primary_domain_candidates() : array(), |
| 349 | ), |
| 350 | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP |
| 351 | ) . ';', |
| 352 | 'before' |
| 353 | ); |
| 354 | } |
| 355 | add_action( 'admin_enqueue_scripts', 'wpcom_enqueue_options_general_assets' ); |