Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
19.61% |
20 / 102 |
|
9.09% |
1 / 11 |
CRAP | |
0.00% |
0 / 1 |
| Gifting_Banner | |
20.41% |
20 / 98 |
|
9.09% |
1 / 11 |
515.54 | |
0.00% |
0 / 1 |
| init | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
20 | |||
| register_gifting_banner | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| should_display_expiring_plan_notice | |
93.75% |
15 / 16 |
|
0.00% |
0 / 1 |
10.02 | |||
| get_checkout_link | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| get_days_to_dismiss_banner | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
6 | |||
| get_more_info_link | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| inject_gifting_banner_wpcom | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
| inject_gifting_banner_wpcomsh | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
2 | |||
| get_plan_purchase | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| get_title_texts | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
6 | |||
| get_subtitle_texts | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
20 | |||
| 1 | <?php // phpcs:ignore WordPress.File.FileName.InvalidClassFileName |
| 2 | /** |
| 3 | * Show the gifting banner on Simple & Atomic sites. |
| 4 | * This file is duplicated in WPCOM and WPCOMSH. |
| 5 | * WPCOM: public_html/wp-content/blog-plugins/gifting-banner.php |
| 6 | * WPCOMSH: wpcomsh/frontend-notices/gifting-banner/gifting-banner.php |
| 7 | * See: p9Jlb4-5v7-p2 |
| 8 | * |
| 9 | * @package gifting-banner |
| 10 | */ |
| 11 | |
| 12 | /** |
| 13 | * Class Gifting_Banner |
| 14 | */ |
| 15 | class Gifting_Banner { |
| 16 | |
| 17 | /** |
| 18 | * The current purchased plan of the blog. |
| 19 | * Used to pass data between methods. |
| 20 | * |
| 21 | * @var object|null |
| 22 | */ |
| 23 | public $current_plan; |
| 24 | |
| 25 | /** |
| 26 | * Maybe show the gifting banner for the current site. |
| 27 | */ |
| 28 | public function init() { |
| 29 | // Inject the gifting banner after the launch banner. |
| 30 | if ( defined( 'IS_ATOMIC' ) && IS_ATOMIC ) { |
| 31 | if ( ! $this->should_display_expiring_plan_notice() ) { |
| 32 | return; |
| 33 | } |
| 34 | |
| 35 | add_action( 'wp_head', array( $this, 'inject_gifting_banner_wpcomsh' ), 1103 ); |
| 36 | } else { |
| 37 | add_action( 'wp_head', array( $this, 'inject_gifting_banner_wpcom' ), 1103 ); |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | /** |
| 42 | * Resolves if the gifting banner should be displayed and adds it to the banner list in necessary. |
| 43 | * |
| 44 | * @param array $banners Banners. |
| 45 | * |
| 46 | * @return array |
| 47 | */ |
| 48 | public function register_gifting_banner( $banners ) { |
| 49 | // If the banner shouldn't display, don't inject it. |
| 50 | if ( ! $this->should_display_expiring_plan_notice() ) { |
| 51 | return $banners; |
| 52 | } |
| 53 | |
| 54 | return array_merge( $banners, array( 'wpcom_gifting_banner' => array( $this, 'init' ) ) ); |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * Determines if the plan expiring notice should display. |
| 59 | * |
| 60 | * @return bool |
| 61 | */ |
| 62 | public function should_display_expiring_plan_notice() { |
| 63 | if ( function_exists( 'is_automattic' ) && is_automattic() ) { |
| 64 | return false; |
| 65 | } |
| 66 | |
| 67 | $this->current_plan = static::get_plan_purchase(); |
| 68 | |
| 69 | // If site doesn't have valid plan -> don't show the banner. |
| 70 | if ( ! $this->current_plan ) { |
| 71 | return false; |
| 72 | } |
| 73 | |
| 74 | // If wpcom_gifting_subscription option exists, we show/hide the banner based on it. |
| 75 | if ( 'option-not-exists' !== get_option( 'wpcom_gifting_subscription', 'option-not-exists' ) ) { |
| 76 | return (bool) get_option( 'wpcom_gifting_subscription' ); |
| 77 | } |
| 78 | |
| 79 | // Create parity between WPCOM and WPCOMSH for auto_renew. |
| 80 | if ( defined( 'IS_ATOMIC' ) && IS_ATOMIC ) { |
| 81 | $this->current_plan->user_allows_auto_renew = $this->current_plan->auto_renew; |
| 82 | } |
| 83 | |
| 84 | // Test if gifting is enabled - We default to the inverse of auto-renew but configured options take precedence. |
| 85 | if ( ! get_option( 'wpcom_gifting_subscription', ! $this->current_plan->user_allows_auto_renew ) ) { |
| 86 | return false; |
| 87 | } |
| 88 | |
| 89 | /* |
| 90 | * We will display the banner: |
| 91 | * - 54 days before the annual plan expiration. |
| 92 | * - 5 days before the monthly plan expiration. |
| 93 | */ |
| 94 | $days_of_warning = false !== strpos( $this->current_plan->product_slug, 'monthly' ) ? 5 : 54; |
| 95 | $seconds_until_expiration = strtotime( $this->current_plan->expiry_date ) - time(); |
| 96 | |
| 97 | if ( $seconds_until_expiration < $days_of_warning * DAY_IN_SECONDS ) { |
| 98 | // Show the banner. |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | return false; |
| 103 | } |
| 104 | |
| 105 | /** |
| 106 | * Get checkout link. |
| 107 | */ |
| 108 | public function get_checkout_link() { |
| 109 | return 'https://wordpress.com/checkout/' . $this->current_plan->product_slug . '/gift/' . $this->current_plan->subscription_id . '?cancel_to=/home'; |
| 110 | } |
| 111 | |
| 112 | /** |
| 113 | * Get how many days the banner should be dismissed based on plan type (30 days for monthly, 1 year for yearly) |
| 114 | */ |
| 115 | public function get_days_to_dismiss_banner() { |
| 116 | return false !== strpos( $this->current_plan->product_slug, 'monthly' ) ? 30 : 365; |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Get more info link. |
| 121 | */ |
| 122 | public function get_more_info_link() { |
| 123 | return 'https://wordpress.com/support/gift-a-wordpress-com-subscription/'; |
| 124 | } |
| 125 | |
| 126 | /** |
| 127 | * Inject the gifting banner on WPCOM. |
| 128 | */ |
| 129 | public function inject_gifting_banner_wpcom() { |
| 130 | $days_to_expire = ceil( ( strtotime( $this->current_plan->expiry_date ) - time() ) / DAY_IN_SECONDS ); |
| 131 | $data = array(); |
| 132 | $data['dismiss_days_count'] = $this->get_days_to_dismiss_banner(); |
| 133 | $data['checkout_link'] = $this->get_checkout_link(); |
| 134 | $data['more_info_link'] = localized_wpcom_url( $this->get_more_info_link() ); |
| 135 | $data['i18n'] = array( |
| 136 | 'title' => $this->get_title_texts( $days_to_expire ), |
| 137 | 'subtitle' => $this->get_subtitle_texts( $this->current_plan, $days_to_expire ), |
| 138 | 'button_text' => _x( 'Gift', 'verb', 'wpcomsh' ), |
| 139 | ); |
| 140 | // Change the version if associated files are updated, current: 20230103. |
| 141 | wp_enqueue_style( 'gifting-banner', plugins_url( 'gifting-banner/css/gifting-banner.css', __FILE__ ), array(), '20230103' ); |
| 142 | wp_enqueue_script( 'gifting-banner', plugins_url( 'gifting-banner/js/gifting-banner.js', __FILE__ ), array(), '20230103', true ); |
| 143 | wp_localize_script( 'gifting-banner', 'gifting_banner', $data ); |
| 144 | wp_set_script_translations( 'gifting-banner', 'wpcomsh' ); |
| 145 | } |
| 146 | |
| 147 | /** |
| 148 | * Inject the gifting banner on WPCOMSH. |
| 149 | */ |
| 150 | public function inject_gifting_banner_wpcomsh() { |
| 151 | $days_to_expire = ceil( ( strtotime( $this->current_plan->expiry_date ) - time() ) / DAY_IN_SECONDS ); |
| 152 | $data = array(); |
| 153 | $data['dismiss_days_count'] = $this->get_days_to_dismiss_banner(); |
| 154 | $data['checkout_link'] = $this->get_checkout_link(); |
| 155 | $data['more_info_link'] = $this->get_more_info_link(); |
| 156 | $data['i18n'] = array( |
| 157 | 'title' => static::get_title_texts( $days_to_expire ), |
| 158 | 'subtitle' => static::get_subtitle_texts( $this->current_plan, $days_to_expire ), |
| 159 | 'button_text' => _x( |
| 160 | 'Gift', |
| 161 | 'verb', |
| 162 | 'wpcomsh' |
| 163 | ), |
| 164 | ); |
| 165 | |
| 166 | wp_enqueue_style( 'gifting-banner', plugins_url( 'css/gifting-banner.css', __FILE__ ), array(), WPCOMSH_VERSION ); |
| 167 | wp_enqueue_script( 'gifting-banner', plugins_url( 'js/gifting-banner.js', __FILE__ ), array(), WPCOMSH_VERSION, true ); |
| 168 | wp_localize_script( 'gifting-banner', 'gifting_banner', $data ); |
| 169 | wp_set_script_translations( 'gifting-banner', 'wpcomsh' ); |
| 170 | } |
| 171 | |
| 172 | /** |
| 173 | * Get hosting plan purchase from the current site. |
| 174 | * See: https://github.com/Automattic/wpcomsh/pull/1118 |
| 175 | * |
| 176 | * @return object|null |
| 177 | */ |
| 178 | private static function get_plan_purchase() { |
| 179 | $purchases = wpcom_get_site_purchases(); |
| 180 | |
| 181 | foreach ( $purchases as $purchase ) { |
| 182 | if ( wpcom_purchase_has_feature( $purchase, WPCOM_Features::SUBSCRIPTION_GIFTING ) ) { |
| 183 | return $purchase; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | return null; |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * Get title based on days. |
| 192 | * |
| 193 | * @param int $days_to_expire Days to expire. |
| 194 | * @return string |
| 195 | */ |
| 196 | private function get_title_texts( $days_to_expire ) { |
| 197 | |
| 198 | if ( $days_to_expire < 1 ) { |
| 199 | return __( |
| 200 | 'This site\'s plan has expired.', |
| 201 | 'wpcomsh' |
| 202 | ); |
| 203 | } |
| 204 | |
| 205 | return __( |
| 206 | 'Enjoy this site?', |
| 207 | 'wpcomsh' |
| 208 | ); |
| 209 | } |
| 210 | |
| 211 | /** |
| 212 | * Get subtitle based on days & type of plan. |
| 213 | * - Plan expired |
| 214 | * - Annual Plan < 2 weeks before expiration |
| 215 | * - Monthly Plan or Annual plan > 2 weeks before expiration |
| 216 | * |
| 217 | * @param object $current_plan Current Plan. |
| 218 | * @param int $days_to_expire Days to expire. |
| 219 | * @return string |
| 220 | */ |
| 221 | private function get_subtitle_texts( $current_plan, $days_to_expire ) { |
| 222 | |
| 223 | if ( $days_to_expire < 1 ) { |
| 224 | return sprintf( |
| 225 | /* translators: Banner to show the visitor the site gifting option on expired sites. */ |
| 226 | __( |
| 227 | 'Gift the author a WordPress.com upgrade.', |
| 228 | 'wpcomsh' |
| 229 | ), |
| 230 | $days_to_expire |
| 231 | ); |
| 232 | } |
| 233 | |
| 234 | if ( ! strpos( $current_plan->product_slug, 'monthly' ) && $days_to_expire < 15 ) { |
| 235 | return sprintf( |
| 236 | /* translators: Banner to show the visitor the site gifting option on days before expires. */ |
| 237 | _n( |
| 238 | 'Gift the author a WordPress.com plan before it expires in %d day.', |
| 239 | 'Gift the author a WordPress.com plan before it expires in %d days.', |
| 240 | $days_to_expire, |
| 241 | 'wpcomsh' |
| 242 | ), |
| 243 | $days_to_expire |
| 244 | ); |
| 245 | } |
| 246 | |
| 247 | return sprintf( |
| 248 | /* translators: Banner to show the visitor the site gifting option, no days shown. */ |
| 249 | __( |
| 250 | 'Gift the author a WordPress.com plan.', |
| 251 | 'wpcomsh' |
| 252 | ), |
| 253 | $days_to_expire |
| 254 | ); |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | /** |
| 259 | * Load the Gifting Banner. |
| 260 | */ |
| 261 | $gifting_banner = new Gifting_Banner(); |
| 262 | |
| 263 | // On Atomic sites we don't have a banner resolver, so we apply the filter directly. |
| 264 | if ( defined( 'IS_ATOMIC' ) && IS_ATOMIC ) { |
| 265 | add_action( 'init', array( $gifting_banner, 'init' ) ); |
| 266 | } else { |
| 267 | add_filter( 'wpcom_register_banners', array( $gifting_banner, 'register_gifting_banner' ) ); |
| 268 | } |