Add WooCommerce checkout opt-in functionality [MAILPOET-1483]
This commit is contained in:
@ -8,6 +8,7 @@ use MailPoet\Subscription\Comment;
|
||||
use MailPoet\Subscription\Form;
|
||||
use MailPoet\Subscription\Registration;
|
||||
use MailPoet\Segments\WooCommerce as WooCommerceSegment;
|
||||
use MailPoet\WooCommerce\Subscription as WooCommerceSubscription;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
class Hooks {
|
||||
@ -27,6 +28,9 @@ class Hooks {
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
/** @var WooCommerceSubscription */
|
||||
private $woocommerce_subscription;
|
||||
|
||||
/** @var WooCommerceSegment */
|
||||
private $woocommerce_segment;
|
||||
|
||||
@ -39,6 +43,7 @@ class Hooks {
|
||||
Registration $subscription_registration,
|
||||
SettingsController $settings,
|
||||
WPFunctions $wp,
|
||||
WooCommerceSubscription $woocommerce_subscription,
|
||||
WooCommerceSegment $woocommerce_segment,
|
||||
WooCommercePurchases $woocommerce_purchases
|
||||
) {
|
||||
@ -47,6 +52,7 @@ class Hooks {
|
||||
$this->subscription_registration = $subscription_registration;
|
||||
$this->settings = $settings;
|
||||
$this->wp = $wp;
|
||||
$this->woocommerce_subscription = $woocommerce_subscription;
|
||||
$this->woocommerce_segment = $woocommerce_segment;
|
||||
$this->woocommerce_purchases = $woocommerce_purchases;
|
||||
}
|
||||
@ -58,6 +64,7 @@ class Hooks {
|
||||
$this->setupImageSize();
|
||||
$this->setupListing();
|
||||
$this->setupSubscriptionEvents();
|
||||
$this->setupWooCommerceSubscriptionEvents();
|
||||
$this->setupPostNotifications();
|
||||
}
|
||||
|
||||
@ -149,6 +156,25 @@ class Hooks {
|
||||
);
|
||||
}
|
||||
|
||||
function setupWooCommerceSubscriptionEvents() {
|
||||
|
||||
$woocommerce = $this->settings->get('woocommerce', []);
|
||||
// WooCommerce: subscribe on checkout
|
||||
if (!empty($woocommerce['optin_on_checkout']['enabled'])) {
|
||||
$this->wp->addAction(
|
||||
'woocommerce_checkout_before_terms_and_conditions',
|
||||
[$this->woocommerce_subscription, 'extendWooCommerceCheckoutForm']
|
||||
);
|
||||
}
|
||||
|
||||
$this->wp->addAction(
|
||||
'woocommerce_checkout_update_order_meta',
|
||||
[$this->woocommerce_subscription, 'subscribeOnCheckout'],
|
||||
10, // this should execute after the WC sync call on the same hook
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
function setupWPUsers() {
|
||||
// WP Users synchronization
|
||||
$this->wp->addAction(
|
||||
|
@ -202,7 +202,7 @@ class Migrator {
|
||||
'updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'deleted_at timestamp NULL,',
|
||||
'unconfirmed_data longtext,',
|
||||
"source enum('form','imported','administrator','api','wordpress_user','woocommerce_user','unknown') DEFAULT 'unknown',",
|
||||
"source enum('form','imported','administrator','api','wordpress_user','woocommerce_user','woocommerce_checkout','unknown') DEFAULT 'unknown',",
|
||||
'count_confirmations int(11) unsigned NOT NULL DEFAULT 0,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY email (email),',
|
||||
|
@ -108,6 +108,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
$container->autowire(\MailPoet\Newsletter\AutomatedLatestContent::class)->setPublic(true);
|
||||
// WooCommerce
|
||||
$container->autowire(\MailPoet\WooCommerce\Helper::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\WooCommerce\Subscription::class)->setPublic(true);
|
||||
// WordPress
|
||||
$container->autowire(\MailPoet\WP\Functions::class)->setPublic(true);
|
||||
return $container;
|
||||
|
@ -4,6 +4,13 @@ namespace MailPoet\Models;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $subscriber_id
|
||||
* @property int $segment_id
|
||||
* @property string $status
|
||||
*/
|
||||
|
||||
class SubscriberSegment extends Model {
|
||||
public static $_table = MP_SUBSCRIBER_SEGMENT_TABLE;
|
||||
|
||||
|
@ -12,6 +12,7 @@ class Source {
|
||||
const API = 'api';
|
||||
const WORDPRESS_USER = 'wordpress_user';
|
||||
const WOOCOMMERCE_USER = 'woocommerce_user';
|
||||
const WOOCOMMERCE_CHECKOUT = 'woocommerce_checkout';
|
||||
const UNKNOWN = 'unknown';
|
||||
|
||||
private static $allowed_sources = array(
|
||||
@ -21,6 +22,7 @@ class Source {
|
||||
Source::API,
|
||||
Source::WORDPRESS_USER,
|
||||
Source::WOOCOMMERCE_USER,
|
||||
Source::WOOCOMMERCE_CHECKOUT,
|
||||
Source::UNKNOWN,
|
||||
);
|
||||
|
||||
|
112
lib/WooCommerce/Subscription.php
Normal file
112
lib/WooCommerce/Subscription.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
namespace MailPoet\WooCommerce;
|
||||
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Subscribers\Source;
|
||||
use MailPoet\Util\Helpers;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
class Subscription {
|
||||
const CHECKOUT_OPTIN_INPUT_NAME = 'mailpoet_woocommerce_checkout_optin';
|
||||
const OPTIN_ENABLED_SETTING_NAME = 'woocommerce.optin_on_checkout.enabled';
|
||||
const OPTIN_MESSAGE_SETTING_NAME = 'woocommerce.optin_on_checkout.message';
|
||||
|
||||
/** @var SettingsController */
|
||||
private $settings;
|
||||
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
function __construct(
|
||||
SettingsController $settings,
|
||||
WPFunctions $wp
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->wp = $wp;
|
||||
}
|
||||
|
||||
function extendWooCommerceCheckoutForm() {
|
||||
$input_name = self::CHECKOUT_OPTIN_INPUT_NAME;
|
||||
$checked = $this->isCurrentUserSubscribed();
|
||||
$label_string = $this->settings->get(self::OPTIN_MESSAGE_SETTING_NAME);
|
||||
$template = $this->wp->applyFilters(
|
||||
'mailpoet_woocommerce_checkout_optin_template',
|
||||
$this->getSubscriptionField($input_name, $checked, $label_string),
|
||||
$input_name,
|
||||
$checked,
|
||||
$label_string
|
||||
);
|
||||
echo $template;
|
||||
}
|
||||
|
||||
private function getSubscriptionField($input_name, $checked, $label_string) {
|
||||
return '<p class="form-row">
|
||||
<label class="woocommerce-form__label woocommerce-form__label-for-checkbox checkbox">
|
||||
<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" name="'.$this->wp->escAttr($input_name).'" id="'.$this->wp->escAttr($input_name).'" ' . ($checked ? 'checked' : '') . ' />
|
||||
<span class="woocommerce-terms-and-conditions-checkbox-text">' . $this->wp->escHtml($label_string) . '</label>
|
||||
</p>';
|
||||
}
|
||||
|
||||
private function isCurrentUserSubscribed() {
|
||||
$subscriber = Subscriber::getCurrentWPUser();
|
||||
if ($subscriber instanceof Subscriber) {
|
||||
$wc_segment = Segment::getWooCommerceSegment();
|
||||
$subscriber_segment = SubscriberSegment::where('subscriber_id', $subscriber->id)
|
||||
->where('segment_id', $wc_segment->id)
|
||||
->findOne();
|
||||
if ($subscriber_segment instanceof SubscriberSegment
|
||||
&& $subscriber_segment->status === Subscriber::STATUS_SUBSCRIBED
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function subscribeOnCheckout($order_id, $data) {
|
||||
if (empty($data['billing_email'])) {
|
||||
// no email in posted order data
|
||||
return null;
|
||||
}
|
||||
|
||||
$subscriber = Subscriber::where('email', $data['billing_email'])
|
||||
->where('is_woocommerce_user', 1)
|
||||
->findOne();
|
||||
if (!$subscriber) {
|
||||
// no subscriber: WooCommerce sync didn't work
|
||||
return null;
|
||||
}
|
||||
|
||||
$checkout_optin_enabled = (bool)$this->settings->get(self::OPTIN_ENABLED_SETTING_NAME);
|
||||
$wc_segment = Segment::getWooCommerceSegment();
|
||||
|
||||
if ($checkout_optin_enabled) {
|
||||
if (!empty($_POST[self::CHECKOUT_OPTIN_INPUT_NAME])) {
|
||||
// checkbox is checked
|
||||
$subscriber->source = Source::WOOCOMMERCE_CHECKOUT;
|
||||
$subscriber->status = Subscriber::STATUS_SUBSCRIBED;
|
||||
if (empty($subscriber->confirmed_ip) && empty($subscriber->confirmed_at)) {
|
||||
$subscriber->confirmed_ip = Helpers::getIP();
|
||||
$subscriber->setExpr('confirmed_at', 'NOW()');
|
||||
}
|
||||
$subscriber->save();
|
||||
|
||||
SubscriberSegment::subscribeToSegments(
|
||||
$subscriber,
|
||||
array($wc_segment->id)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Opt-in is disabled or checkbox is unchecked
|
||||
SubscriberSegment::unsubscribeFromSegments(
|
||||
$subscriber,
|
||||
array($wc_segment->id)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user