Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 3
CRAP
n/a
0 / 0
homepage_connection_banner
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
wpcom_add_pages_homepage_connection_banner
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
90
wpcom_dismiss_pages_homepage_connection_banner
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Banner connecting Pages screen to homepage editing.
4 *
5 * Displays a banner in the Pages admin list to help users navigate to homepage editing.
6 * This addresses user confusion about where to edit their homepage when it's controlled by theme settings.
7 *
8 * @package automattic/jetpack-mu-wpcom
9 */
10
11/**
12 * User meta key storing whether the current user has dismissed the homepage connection banner.
13 */
14const WPCOM_HOMEPAGE_CONNECTION_BANNER_DISMISSED_META = 'wpcom_pages_homepage_connection_banner_dismissed';
15
16/**
17 * Displays the homepage connection banner in the admin notices.
18 *
19 * The markup is rendered directly (rather than via wp_admin_notice()) because
20 * wp_admin_notice() passes its output through wp_kses_post(), which strips the
21 * data-nonce attribute the dismissal AJAX request relies on.
22 */
23function homepage_connection_banner() {
24    printf(
25        '<div id="edit-homepage-banner" class="notice notice-info is-dismissible" data-nonce="%s"><p>%s</p><a href="%s" class="button-primary">%s</a></div>',
26        esc_attr( wp_create_nonce( 'dismiss_homepage_connection_banner' ) ),
27        esc_html__( 'Looking to customize your homepage?', 'jetpack-mu-wpcom' ),
28        esc_url( admin_url( 'site-editor.php' ) ),
29        esc_html__( 'Edit homepage', 'jetpack-mu-wpcom' )
30    );
31}
32
33/**
34 * Adds a connection banner to the Pages screen linking to homepage editing.
35 */
36function wpcom_add_pages_homepage_connection_banner() {
37    $screen = get_current_screen();
38    if ( ! $screen || ! wp_is_block_theme() ) {
39        return;
40    }
41
42    $is_edit_page_screen = 'edit-page' === $screen->id;
43
44    if ( ! $is_edit_page_screen ) {
45        return;
46    }
47
48    // Don't show the banner if the current user has already dismissed it.
49    if ( get_user_meta( get_current_user_id(), WPCOM_HOMEPAGE_CONNECTION_BANNER_DISMISSED_META, true ) ) {
50        return;
51    }
52
53    $show_on_front  = get_option( 'show_on_front' );
54    $front_page_id  = (int) get_option( 'page_on_front' );
55    $posts_on_front = $show_on_front === 'posts' || ( $show_on_front === 'page' && ! $front_page_id );
56    $can_edit       = current_user_can( 'edit_theme_options' );
57
58    if ( ! $posts_on_front || ! $can_edit ) {
59        return;
60    }
61
62    add_action( 'admin_notices', 'homepage_connection_banner' );
63
64    wp_register_script_module(
65        'wpcom-tracks-module',
66        plugin_dir_url( __FILE__ ) . '../../common/tracks.js',
67        array(),
68        '20250604'
69    );
70
71    wp_enqueue_script_module(
72        'wpcom-pages-homepage-connection-banner',
73        plugin_dir_url( __FILE__ ) . 'js/pages-homepage-connection-banner.js',
74        array( 'wpcom-tracks-module', 'jquery' ),
75        '20250604'
76    );
77}
78
79add_action( 'current_screen', 'wpcom_add_pages_homepage_connection_banner' );
80
81/**
82 * AJAX handler to persist the dismissal of the homepage connection banner in user meta.
83 */
84function wpcom_dismiss_pages_homepage_connection_banner() {
85    check_ajax_referer( 'dismiss_homepage_connection_banner', 'nonce' );
86    update_user_meta( get_current_user_id(), WPCOM_HOMEPAGE_CONNECTION_BANNER_DISMISSED_META, '1' );
87    wp_send_json_success( null, 200, JSON_UNESCAPED_SLASHES );
88}
89add_action( 'wp_ajax_dismiss_homepage_connection_banner', 'wpcom_dismiss_pages_homepage_connection_banner' );