Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 8687c56

Browse files
authored
Add inbox notification to surface cart and checkout blocks to select merchants (#4518)
* Add InboxNotifications class This will be used to handle displaying the inbox notification to select merchants * Show inbox notifications on load * Update copy in inbox notification * Update URL and percent chance for a user to be chosen * Add apostrophe to notification content * Only register notifications when woocommerce_init is done * Wait for admin to load before adding note * Add further disallowed plugins * Allow notification to be shown when using WC Points and Rewards * Remove timestamp and content data from the note This isn't necessary and was only added for testing. * Check for existence of note based on name instead of content_data * Create delete note function We'll be deleting notes in the case that an ineligible plugin becomes active. * Reorder the eligible plugin and % targeting check This will let us target a truer % of users, and also will let us delete the note if a user activates an ineligible plugin. * Remove code which was added for testing purposes The code to return if the feature plugin was active was enabled, woocommerce-gutenberg-products-block was added as an ineligible plugin.
1 parent 72c7c21 commit 8687c56

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

src/Domain/Bootstrap.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi;
66
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
77
use Automattic\WooCommerce\Blocks\BlockTypesController;
8+
use Automattic\WooCommerce\Blocks\InboxNotifications;
89
use Automattic\WooCommerce\Blocks\Installer;
910
use Automattic\WooCommerce\Blocks\Registry\Container;
1011
use Automattic\WooCommerce\Blocks\RestApi;
@@ -74,6 +75,15 @@ protected function init() {
7475
$this->register_dependencies();
7576
$this->register_payment_methods();
7677

78+
add_action(
79+
'admin_init',
80+
function() {
81+
InboxNotifications::create_surface_cart_checkout_blocks_notification();
82+
},
83+
10,
84+
0
85+
);
86+
7787
$is_rest = wc()->is_rest_api_request();
7888

7989
// Load assets in admin and on the frontend.

src/InboxNotifications.php

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<?php
2+
namespace Automattic\WooCommerce\Blocks;
3+
4+
use Automattic\WooCommerce\Admin\Notes\Note;
5+
use Automattic\WooCommerce\Admin\Notes\Notes;
6+
7+
/**
8+
* A class used to display inbox messages to merchants in the WooCommerce Admin dashboard.
9+
*
10+
* @package Automattic\WooCommerce\Blocks
11+
* @since x.x.x
12+
*/
13+
class InboxNotifications {
14+
15+
const SURFACE_CART_CHECKOUT_NOTE_NAME = 'surface_cart_checkout';
16+
const SURFACE_CART_CHECKOUT_PROBABILITY_OPTION = 'wc_blocks_surface_cart_checkout_probability';
17+
const PERCENT_USERS_TO_TARGET = 10;
18+
const INELIGIBLE_EXTENSIONS = [
19+
'automatewoo',
20+
'mailchimp-for-woocommerce',
21+
'mailpoet',
22+
'klarna-payments-for-woocommerce',
23+
'klarna-checkout-for-woocommerce',
24+
'woocommerce-gutenberg-products-block', // Disallow the notification if the store is using the feature plugin already.
25+
'woocommerce-all-products-for-subscriptions',
26+
'woocommerce-bookings',
27+
'woocommerce-box-office',
28+
'woocommerce-cart-add-ons',
29+
'woocommerce-checkout-add-ons',
30+
'woocommerce-checkout-field-editor',
31+
'woocommerce-conditional-shipping-and-payments',
32+
'woocommerce-dynamic-pricing',
33+
'woocommerce-eu-vat-number',
34+
'woocommerce-follow-up-emails',
35+
'woocommerce-gateway-amazon-payments-advanced',
36+
'woocommerce-gateway-authorize-net-cim',
37+
'woocommerce-google-analytics-pro',
38+
'woocommerce-memberships',
39+
'woocommerce-paypal-payments',
40+
'woocommerce-pre-orders',
41+
'woocommerce-product-bundles',
42+
'woocommerce-shipping-fedex',
43+
'woocommerce-smart-coupons',
44+
];
45+
const ELIGIBLE_COUNTRIES = [
46+
'GB',
47+
'US',
48+
];
49+
50+
51+
/**
52+
* Deletes the note.
53+
*/
54+
public static function delete_surface_cart_checkout_blocks_notification() {
55+
Notes::delete_notes_with_name( self::SURFACE_CART_CHECKOUT_NOTE_NAME );
56+
}
57+
58+
/**
59+
* Creates a notification letting merchants know about the Cart and Checkout Blocks.
60+
*/
61+
public static function create_surface_cart_checkout_blocks_notification() {
62+
63+
// If this is the feature plugin, then we don't need to do this. This should only show when Blocks is bundled
64+
// with WooCommerce Core.
65+
if ( Package::feature()->is_feature_plugin_build() ) {
66+
return;
67+
}
68+
69+
if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\WC_Admin_Notes' ) ) {
70+
return;
71+
}
72+
73+
if ( ! class_exists( 'WC_Data_Store' ) ) {
74+
return;
75+
}
76+
77+
$data_store = \WC_Data_Store::load( 'admin-note' );
78+
$note_ids = $data_store->get_notes_with_name( self::SURFACE_CART_CHECKOUT_NOTE_NAME );
79+
80+
// Calculate store's eligibility to be shown the notice, starting with whether they have any plugins we know to
81+
// be incompatible with Blocks. This check is done before checking if the note exists already because we want to
82+
// delete the note if the merchant activates an ineligible plugin.
83+
foreach ( self::INELIGIBLE_EXTENSIONS as $extension ) {
84+
if ( is_plugin_active( $extension . '/' . $extension . '.php' ) ) {
85+
86+
// Delete the notification here, we shouldn't show it if it's not going to work with the merchant's site.
87+
self::delete_surface_cart_checkout_blocks_notification();
88+
return;
89+
}
90+
}
91+
92+
foreach ( (array) $note_ids as $note_id ) {
93+
$note = Notes::get_note( $note_id );
94+
95+
// Return now because the note already exists.
96+
if ( $note->get_name() === self::SURFACE_CART_CHECKOUT_NOTE_NAME ) {
97+
return;
98+
}
99+
}
100+
101+
// Next check the store is located in one of the eligible countries.
102+
$raw_country = get_option( 'woocommerce_default_country' );
103+
$country = explode( ':', $raw_country )[0];
104+
if ( ! in_array( $country, self::ELIGIBLE_COUNTRIES, true ) ) {
105+
return;
106+
}
107+
108+
// Pick a random number between 1 and 100 and add this to the wp_options table. This can then be used to target
109+
// a percentage of users. We do this here so we target a truer percentage of eligible users than if we did it
110+
// before checking plugins/country.
111+
$existing_probability = get_option( self::SURFACE_CART_CHECKOUT_PROBABILITY_OPTION );
112+
if ( false === $existing_probability ) {
113+
$existing_probability = wp_rand( 0, 100 );
114+
add_option( self::SURFACE_CART_CHECKOUT_PROBABILITY_OPTION, $existing_probability );
115+
}
116+
117+
// Finally, check if the store's generated % chance is below the % of users we want to surface this to.
118+
if ( $existing_probability > self::PERCENT_USERS_TO_TARGET ) {
119+
return;
120+
}
121+
122+
// At this point, the store meets all the criteria to be shown the notice! Woo!
123+
$note = new Note();
124+
$note->set_title(
125+
__(
126+
'Introducing the Cart and Checkout blocks!',
127+
'woo-gutenberg-products-block'
128+
)
129+
);
130+
$note->set_content(
131+
__(
132+
"Increase your store's revenue with the conversion optimized Cart & Checkout WooCommerce blocks available in the WooCommerce Blocks extension.",
133+
'woo-gutenberg-products-block'
134+
)
135+
);
136+
$note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
137+
$note->set_source( 'woo-gutenberg-products-block' );
138+
$note->set_name( self::SURFACE_CART_CHECKOUT_NOTE_NAME );
139+
$note->add_action(
140+
'learn_more',
141+
'Learn More',
142+
'https://woocommerce.com/checkout-blocks/'
143+
);
144+
$note->save();
145+
146+
}
147+
}

0 commit comments

Comments
 (0)