Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.96% covered (warning)
86.96%
100 / 115
0.00% covered (danger)
0.00%
0 / 1
CRAP
n/a
0 / 0
wpcomsh_plan_notices
87.72% covered (warning)
87.72%
100 / 114
0.00% covered (danger)
0.00%
0 / 1
21.82
1<?php
2/**
3 * Plan notices file.
4 *
5 * @package wpcomsh
6 */
7
8/**
9 * This section controls expiration and autorenewal messaging in WP-Admin on Atomic sites. There are similar functions for WPCOM Simple Sites.
10 *
11 * Simple Site WP-Admin: fbhepr%2Skers%2Sgehax%2Sjc%2Qpbagrag%2Snqzva%2Qcyhtvaf%2Scyna%2Qerarj%2Qcebzcg.cuc%3Se%3Q225047%2320-og
12 * Simple Site Calypso: fbhepr%2Skers%2Sgehax%2Sjc%2Qpbagrag%2Syvo%2Subzr%2Sivrjf.cuc%3Se%3Q232480%23179-og
13 */
14function wpcomsh_plan_notices() {
15    /*
16     * This notice is being replaced by the expiry notices in jetpack-mu-wpcom,
17     * which are going out to a share of sites at a time. Stand down for the
18     * sites already on the new ones, and keep covering everyone else until the
19     * rollout reaches them.
20     *
21     * Tested here rather than on the `add_action` because the gate is defined
22     * in jetpack-mu-wpcom, which loads on `plugins_loaded` -- after this file
23     * is required. When it is missing the new notices are missing too, since
24     * they ship in the same file, so carrying on is the safe answer: it risks
25     * an old notice where a new one was due, never two notices at once.
26     */
27    if ( function_exists( 'wpcom_expiry_notices_is_enabled_for_site' )
28        && wpcom_expiry_notices_is_enabled_for_site() ) {
29        return;
30    }
31
32    // phpcs:ignore WordPress.WP.Capabilities.RoleFound
33    if ( ! current_user_can( 'editor' ) && ! current_user_can( 'administrator' ) ) {
34        return;
35    }
36
37    $persistent_data = new Atomic_Persistent_Data();
38
39    if ( ! $persistent_data->WPCOM_PURCHASES ) { // phpcs:ignore WordPress.NamingConventions
40        return;
41    }
42
43    $purchases = json_decode( $persistent_data->WPCOM_PURCHASES ); // phpcs:ignore WordPress.NamingConventions
44
45    if ( empty( $purchases ) ) {
46        return;
47    }
48
49    $atomic_supported_purchases = array_filter(
50        $purchases,
51        function ( $purchase ) {
52            return wpcom_purchase_has_feature( $purchase, WPCOM_Features::ATOMIC );
53        }
54    );
55
56    if ( empty( $atomic_supported_purchases ) ) {
57        return;
58    }
59
60    // For the off chance that there are more than one purchase, pick the one with the latest expiration.
61    usort(
62        $atomic_supported_purchases,
63        function ( $purchase1, $purchase2 ) {
64            if ( strtotime( $purchase1->expiry_date ) === strtotime( $purchase2->expiry_date ) ) {
65                return 0;
66            }
67            return ( strtotime( $purchase1->expiry_date ) > strtotime( $purchase2->expiry_date ) ) ? -1 : 1;
68        }
69    );
70    $atomic_supported_purchase = $atomic_supported_purchases[0];
71    $slug                      = $atomic_supported_purchase->product_slug;
72    $expiration                = strtotime( $atomic_supported_purchase->expiry_date );
73    $seconds_to_expiration     = $expiration - time();
74
75    if ( $seconds_to_expiration > 29 * DAY_IN_SECONDS ) {
76        return;
77    }
78
79    if ( strpos( $slug, 'personal' ) !== false ) {
80        $plan_level = 'personal';
81    } elseif ( strpos( $slug, 'value_bundle' ) !== false || 'bundle_pro' === $slug ) {
82        $plan_level = 'premium';
83    } elseif ( strpos( $slug, 'business' ) !== false ) {
84        $plan_level = 'business';
85    } elseif ( strpos( $slug, 'ecommerce' ) !== false ) {
86        $plan_level = 'ecommerce';
87    } elseif ( strpos( $slug, 'pro' ) !== false ) {
88        $plan_level = 'pro';
89    }
90
91    if ( empty( $plan_level ) ) {
92        return;
93    }
94
95    $domain      = preg_replace( '#^https?://#', '', network_site_url() );
96    $renewal_url = sprintf( 'https://wordpress.com/checkout/%1$s/%2$s', $slug, $domain );
97    // By default, display the notice 1 day after expiration
98    $notice_offset = -1 * DAY_IN_SECONDS;
99
100    // Pre-expiration message for non-monthly plans only.
101    if ( false === stripos( $slug, 'monthly' ) ) {
102        $notice_offset = 0;
103        $plan_messages = array(
104            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
105            'personal'  => __(
106                'The Personal plan for <strong>%3$s</strong> expires on %2$s. <a href="%1$s">Renew your plan</a> to retain Personal plan features such as 6 GB storage space, no WordPress.com ads, and Subscriber-only content.',
107                'wpcomsh'
108            ),
109            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
110            'premium'   => __(
111                'The Premium plan for <strong>%3$s</strong> expires on %2$s. <a href="%1$s">Renew your plan</a> to retain Premium plan features such as site monetization, VideoPress, and Google Analytics support.',
112                'wpcomsh'
113            ),
114            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
115            'business'  => __(
116                'The Business plan for <strong>%3$s</strong> expires on %2$s. <a href="%1$s">Renew your plan</a> to retain Business plan features such as custom plugins and themes, SFTP, and phpMyAdmin access.',
117                'wpcomsh'
118            ),
119            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
120            'ecommerce' => __(
121                'The Commerce plan for <strong>%3$s</strong> expires on %2$s. <a href="%1$s">Renew your plan</a> to retain Commerce plan features such as custom plugins and themes, SFTP, and phpMyAdmin access.',
122                'wpcomsh'
123            ),
124            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
125            'pro'       => __(
126                'The Pro plan for <strong>%3$s</strong> expires on %2$s. <a href="%1$s">Renew your plan</a> to retain Pro plan features such as custom plugins and themes, SFTP, and phpMyAdmin access.',
127                'wpcomsh'
128            ),
129        );
130    }
131
132    // Expired message for annual and monthly plans.
133    if ( $seconds_to_expiration < $notice_offset ) {
134        $plan_messages = array(
135            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
136            'personal'  => __(
137                'The Personal plan for <strong>%3$s</strong> expired on %2$s. <a href="%1$s">Reactivate your plan</a> to retain Personal plan features such as 6 GB storage space, no WordPress.com ads, and Subscriber-only content.',
138                'wpcomsh'
139            ),
140            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
141            'premium'   => __(
142                'The Premium plan for <strong>%3$s</strong> expired on %2$s. <a href="%1$s">Reactivate your plan</a> to retain Premium plan features such as site monetization, VideoPress, and Google Analytics support.',
143                'wpcomsh'
144            ),
145            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
146            'business'  => __(
147                'The Business plan for <strong>%3$s</strong> expired on %2$s. <a href="%1$s">Reactivate your plan</a> to retain Business plan features such as custom plugins and themes, SFTP, and phpMyAdmin access.',
148                'wpcomsh'
149            ),
150            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
151            'ecommerce' => __(
152                'The Commerce plan for <strong>%3$s</strong> expired on %2$s. <a href="%1$s">Reactivate your plan</a> to retain Commerce plan features such as custom plugins and themes, SFTP, and phpMyAdmin access.',
153                'wpcomsh'
154            ),
155            /* translators: %1$s is a link for plan renewal, %2$s human readable time e.g. January 1, 2021, %3$s site URL */
156            'pro'       => __(
157                'The Pro plan for <strong>%3$s</strong> expired on %2$s. <a href="%1$s">Reactivate your plan</a> to retain Pro plan features such as custom plugins and themes, SFTP, and phpMyAdmin access.',
158                'wpcomsh'
159            ),
160        );
161    }
162
163    if ( empty( $plan_messages[ $plan_level ] ) ) {
164        return;
165    }
166
167    wpcomsh_record_tracks_event(
168        'atomic_wpcomsh_renewal_notice',
169        array(
170            'plan_slug' => $plan_level,
171        )
172    );
173
174    $message = sprintf(
175        $plan_messages[ $plan_level ],
176        esc_url( $renewal_url ),
177        date_i18n( get_option( 'date_format' ), $expiration ),
178        $domain
179    );
180
181    printf(
182        '<div class="notice wpcomsh-notice">
183            <span class="notice__icon-wrapper notice__icon-wrapper-pink">
184                <span class="dashicons dashicons-info"></span>
185            </span>
186            <span class="notice__content">
187                <span class="notice__text">%s</span>
188            </span>
189        </div>',
190        wp_kses_post( $message )
191    );
192}
193add_action( 'admin_notices', 'wpcomsh_plan_notices' );