Agentic
4 months ago
BlockTemplates
4 weeks ago
EmailImprovements
1 year ago
EmailPreview
4 weeks ago
Emails
1 year ago
ImportExport
1 year ago
Logging
1 year ago
Marketing
2 years ago
Notes
4 weeks ago
Onboarding
5 months ago
Orders
4 weeks ago
ProductForm
2 years ago
ProductReviews
4 weeks ago
RemoteFreeExtensions
4 weeks ago
Schedulers
4 weeks ago
Settings
5 days ago
Suggestions
4 weeks ago
WCPayPromotion
10 months ago
ActivityPanels.php
3 years ago
Analytics.php
4 weeks ago
CategoryLookup.php
4 years ago
Coupons.php
1 year ago
CouponsMovedTrait.php
5 months ago
CustomerEffortScoreTracks.php
7 months ago
Events.php
2 months ago
FeaturePlugin.php
4 months ago
Homescreen.php
1 month ago
Loader.php
4 weeks ago
Marketing.php
1 year ago
Marketplace.php
5 months ago
MobileAppBanner.php
4 years ago
OrderMilestoneEasterEgg.php
4 weeks ago
RemoteInboxNotifications.php
3 years ago
Settings.php
5 days ago
ShippingLabelBanner.php
1 year ago
ShippingLabelBannerDisplayRules.php
1 year ago
SiteHealth.php
3 years ago
Survey.php
4 years ago
SystemStatusReport.php
1 year ago
Translations.php
1 year ago
WCAdminAssets.php
5 days ago
WCAdminSharedSettings.php
1 year ago
WCAdminUser.php
9 months ago
WcPayWelcomePage.php
1 year ago
ShippingLabelBannerDisplayRules.php
141 lines
| 1 | <?php |
| 2 | /** |
| 3 | * WooCommerce Shipping Label Banner Display Rules. |
| 4 | */ |
| 5 | |
| 6 | namespace Automattic\WooCommerce\Internal\Admin; |
| 7 | |
| 8 | /** |
| 9 | * Determines whether the Shipping Label Banner should be displayed |
| 10 | */ |
| 11 | class ShippingLabelBannerDisplayRules { |
| 12 | |
| 13 | /** |
| 14 | * Whether the site is connected to wordpress.com. |
| 15 | * |
| 16 | * @var bool |
| 17 | */ |
| 18 | private $dotcom_connected; |
| 19 | |
| 20 | /** |
| 21 | * Whether installed plugins are incompatible with the banner. |
| 22 | * |
| 23 | * @var bool |
| 24 | */ |
| 25 | private $no_incompatible_plugins_installed; |
| 26 | |
| 27 | /** |
| 28 | * Holds the installed WooCommerce Shipping & Tax version. |
| 29 | * |
| 30 | * @var string |
| 31 | */ |
| 32 | private $wcs_version; |
| 33 | |
| 34 | /** |
| 35 | * Supported countries by USPS, see: https://webpmt.usps.gov/pmt010.cfm |
| 36 | * |
| 37 | * @var array |
| 38 | */ |
| 39 | private $supported_countries = array( 'US', 'AS', 'PR', 'VI', 'GU', 'MP', 'UM', 'FM', 'MH' ); |
| 40 | |
| 41 | /** |
| 42 | * Array of supported currency codes. |
| 43 | * |
| 44 | * @var array |
| 45 | */ |
| 46 | private $supported_currencies = array( 'USD' ); |
| 47 | |
| 48 | |
| 49 | /** |
| 50 | * Constructor. |
| 51 | * |
| 52 | * @param bool $dotcom_connected Is site connected to wordpress.com?. |
| 53 | * @param string|null $wcs_version Installed WooCommerce Shipping version to check, null if not installed. |
| 54 | * @param bool $incompatible_plugins_installed Are there any incompatible plugins installed?. |
| 55 | */ |
| 56 | public function __construct( $dotcom_connected, $wcs_version, $incompatible_plugins_installed ) { |
| 57 | $this->dotcom_connected = $dotcom_connected; |
| 58 | $this->wcs_version = $wcs_version; |
| 59 | $this->no_incompatible_plugins_installed = ! $incompatible_plugins_installed; |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Determines whether banner is eligible for display (does not include a/b logic). |
| 64 | */ |
| 65 | public function should_display_banner() { |
| 66 | return $this->banner_not_dismissed() && |
| 67 | $this->dotcom_connected && |
| 68 | $this->no_incompatible_plugins_installed && |
| 69 | $this->order_has_shippable_products() && |
| 70 | $this->store_in_us_and_usd() && |
| 71 | $this->wcs_not_installed(); |
| 72 | } |
| 73 | |
| 74 | /** |
| 75 | * Checks if the banner was not dismissed by the user. |
| 76 | * |
| 77 | * @return bool |
| 78 | */ |
| 79 | private function banner_not_dismissed() { |
| 80 | $dismissed_timestamp_ms = get_option( 'woocommerce_shipping_dismissed_timestamp' ); |
| 81 | |
| 82 | if ( ! is_numeric( $dismissed_timestamp_ms ) ) { |
| 83 | return true; |
| 84 | } |
| 85 | $dismissed_timestamp_ms = intval( $dismissed_timestamp_ms ); |
| 86 | $dismissed_timestamp = intval( round( $dismissed_timestamp_ms / 1000 ) ); |
| 87 | $expired_timestamp = $dismissed_timestamp + 24 * 60 * 60; // 24 hours from click time |
| 88 | |
| 89 | $dismissed_for_good = -1 === $dismissed_timestamp_ms; |
| 90 | $dismissed_24h = time() < $expired_timestamp; |
| 91 | |
| 92 | return ! $dismissed_for_good && ! $dismissed_24h; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Checks if there's a shippable product in the current order. |
| 97 | * |
| 98 | * @return bool |
| 99 | */ |
| 100 | private function order_has_shippable_products() { |
| 101 | $order = wc_get_order(); |
| 102 | |
| 103 | if ( ! $order ) { |
| 104 | return false; |
| 105 | } |
| 106 | // At this point (no packaging data), only show if there's at least one existing and shippable product. |
| 107 | foreach ( $order->get_items() as $item ) { |
| 108 | if ( $item instanceof \WC_Order_Item_Product ) { |
| 109 | $product = $item->get_product(); |
| 110 | |
| 111 | if ( $product && $product->needs_shipping() ) { |
| 112 | return true; |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | return false; |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | * Checks if the store is in the US and has its default currency set to USD. |
| 122 | * |
| 123 | * @return bool |
| 124 | */ |
| 125 | private function store_in_us_and_usd() { |
| 126 | $base_currency = get_woocommerce_currency(); |
| 127 | $base_location = wc_get_base_location(); |
| 128 | |
| 129 | return in_array( $base_currency, $this->supported_currencies, true ) && in_array( $base_location['country'], $this->supported_countries, true ); |
| 130 | } |
| 131 | |
| 132 | /** |
| 133 | * Checks if WooCommerce Shipping & Tax is not installed. |
| 134 | * |
| 135 | * @return bool |
| 136 | */ |
| 137 | private function wcs_not_installed() { |
| 138 | return ! $this->wcs_version; |
| 139 | } |
| 140 | } |
| 141 |