Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.62% covered (warning)
84.62%
33 / 39
60.00% covered (warning)
60.00%
3 / 5
CRAP
n/a
0 / 0
wpcom_expiry_notices_frontend_banner_data
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
4
wpcom_expiry_notices_enqueue_frontend_banner_assets
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
2.00
wpcom_expiry_notices_frontend_banner_body_class
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
wpcom_expiry_notices_render_frontend_banner
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
5
wpcom_expiry_notices_render_frontend_banner_fallback
50.00% covered (danger)
50.00%
1 / 2
0.00% covered (danger)
0.00%
0 / 1
2.50
1<?php
2/**
3 * Front-end banner for plans in their final week, in grace, or post-grace.
4 * Admins only; visitors never see it.
5 *
6 * @package automattic/jetpack-mu-wpcom
7 */
8
9use Automattic\Jetpack\Jetpack_Mu_Wpcom\Expiry_Notices\Expiry_Notice_Dismiss;
10
11/**
12 * What the banner renders from, or null if it shouldn't show.
13 *
14 * Feeds and embeds render markup of their own the bar would corrupt, and the
15 * Customizer preview is not the site.
16 *
17 * @return array<string,mixed>|null
18 */
19function wpcom_expiry_notices_frontend_banner_data(): ?array {
20    if ( is_feed() || is_embed() || is_customize_preview() ) {
21        return null;
22    }
23    return wpcom_expiry_notices_banner_data();
24}
25
26/**
27 * Enqueue the banner's JS/CSS on wp_enqueue_scripts.
28 */
29function wpcom_expiry_notices_enqueue_frontend_banner_assets() {
30    $data = wpcom_expiry_notices_frontend_banner_data();
31    if ( null === $data ) {
32        return;
33    }
34    wpcom_expiry_notices_enqueue_surface(
35        'expiry-notices-banner',
36        'wpcomExpiryBanner',
37        array(
38            'metaKey'    => Expiry_Notice_Dismiss::banner_meta_key(),
39            'trackProps' => wpcom_expiry_notices_track_props( $data['state'], $data['is_owner'], 'frontend' ),
40        ),
41        'expiry-notices-frontend-banner'
42    );
43}
44add_action( 'wp_enqueue_scripts', 'wpcom_expiry_notices_enqueue_frontend_banner_assets' );
45
46/**
47 * Body class the stylesheet keys theme offsets on.
48 *
49 * @param string[]|mixed $classes Body classes; a theme filter may have returned a non-array.
50 * @return string[]|mixed
51 */
52function wpcom_expiry_notices_frontend_banner_body_class( $classes ) {
53    if ( is_array( $classes ) && null !== wpcom_expiry_notices_frontend_banner_data() ) {
54        $classes[] = 'has-wpcom-expiry-banner';
55    }
56    return $classes;
57}
58add_filter( 'body_class', 'wpcom_expiry_notices_frontend_banner_body_class' );
59
60/**
61 * Render the banner at the top of <body>, so the absolute positioning used on
62 * small screens anchors to the page and not to a theme wrapper.
63 */
64function wpcom_expiry_notices_render_frontend_banner() {
65    $data = wpcom_expiry_notices_frontend_banner_data();
66    if ( null === $data ) {
67        return;
68    }
69
70    $urls           = $data['urls'];
71    $is_dismissible = $data['is_dismissible'];
72    ?>
73    <div id="wpcom-expiry-frontend-banner" class="wpcom-expiry-frontend-banner<?php echo $is_dismissible ? ' wpcom-expiry-frontend-banner--dismissible' : ''; ?>" role="region" aria-label="<?php esc_attr_e( 'Plan expiry notice', 'jetpack-mu-wpcom' ); ?>" data-wpcom-expiry-banner>
74        <div class="wpcom-expiry-frontend-banner__content">
75            <span class="wpcom-expiry-frontend-banner__text"><?php echo esc_html( wpcom_expiry_notices_banner_sentence( $data['state'], $data['is_owner'] ) ); ?></span>
76            <?php if ( null !== $urls ) : ?>
77                <?php wpcom_expiry_notices_render_cta_link( $urls['primary'], 'primary', 'wpcom-expiry-frontend-banner__cta' ); ?>
78            <?php endif; ?>
79        </div>
80        <?php if ( $is_dismissible ) : ?>
81            <button type="button" class="wpcom-expiry-frontend-banner__dismiss" data-wpcom-expiry-dismiss aria-label="<?php esc_attr_e( 'Dismiss', 'jetpack-mu-wpcom' ); ?>">
82                <svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path fill="currentColor" d="m13.06 12 6.47-6.47-1.06-1.06L12 10.94 5.53 4.47 4.47 5.53 10.94 12l-6.47 6.47 1.06 1.06L12 13.06l6.47 6.47 1.06-1.06L13.06 12Z"/></svg>
83            </button>
84        <?php endif; ?>
85    </div>
86    <?php
87}
88add_action( 'wp_body_open', 'wpcom_expiry_notices_render_frontend_banner' );
89
90/**
91 * Themes that never call wp_body_open get the banner from the footer; the
92 * script then moves it to the top of <body>.
93 */
94function wpcom_expiry_notices_render_frontend_banner_fallback() {
95    if ( ! did_action( 'wp_body_open' ) ) {
96        wpcom_expiry_notices_render_frontend_banner();
97    }
98}
99add_action( 'wp_footer', 'wpcom_expiry_notices_render_frontend_banner_fallback' );