Add tracking of WooCommerce oders after payment

[MAILPOET-1855]
This commit is contained in:
Jan Jakeš
2019-04-16 10:12:32 +02:00
committed by M. Shull
parent 97c4260697
commit 481f5b9344
5 changed files with 127 additions and 1 deletions

View File

@@ -3,6 +3,7 @@
namespace MailPoet\Config;
use MailPoet\Settings\SettingsController;
use MailPoet\Statistics\Track\WooCommerceOrders;
use MailPoet\Subscription\Comment;
use MailPoet\Subscription\Form;
use MailPoet\Subscription\Registration;
@@ -29,13 +30,17 @@ class Hooks {
/** @var WooCommerceSegment */
private $woocommerce_segment;
/** @var WooCommerceOrders */
private $woocommerce_orders;
function __construct(
Form $subscription_form,
Comment $subscription_comment,
Registration $subscription_registration,
SettingsController $settings,
WPFunctions $wp,
WooCommerceSegment $woocommerce_segment
WooCommerceSegment $woocommerce_segment,
WooCommerceOrders $woocommerce_orders
) {
$this->subscription_form = $subscription_form;
$this->subscription_comment = $subscription_comment;
@@ -43,11 +48,13 @@ class Hooks {
$this->settings = $settings;
$this->wp = $wp;
$this->woocommerce_segment = $woocommerce_segment;
$this->woocommerce_orders = $woocommerce_orders;
}
function init() {
$this->setupWPUsers();
$this->setupWooCommerceUsers();
$this->setupWooCommerceOrders();
$this->setupImageSize();
$this->setupListing();
$this->setupSubscriptionEvents();
@@ -206,6 +213,14 @@ class Hooks {
);
}
function setupWooCommerceOrders() {
$this->wp->addAction(
'woocommerce_payment_complete',
[$this->woocommerce_orders, 'trackPaidOrder']
);
}
function setupImageSize() {
$this->wp->addFilter(
'image_size_names_choose',

View File

@@ -82,6 +82,7 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\Router\Endpoints\Track::class)->setPublic(true);
$container->autowire(\MailPoet\Statistics\Track\Clicks::class);
$container->autowire(\MailPoet\Statistics\Track\Opens::class);
$container->autowire(\MailPoet\Statistics\Track\WooCommerceOrders::class)->setPublic(true);
$container->autowire(\MailPoet\Router\Router::class)
->setArgument('$container', new Reference(ContainerWrapper::class));
// Mailer

View File

@@ -1,6 +1,8 @@
<?php
namespace MailPoet\Models;
use DateTime;
if (!defined('ABSPATH')) exit;
/**
@@ -51,4 +53,31 @@ class StatisticsClicks extends Model {
->where('clicks.subscriber_id', $subscriber->id())
->orderByAsc('url');
}
static function findLatestPerNewsletterBySubscriber(Subscriber $subscriber, DateTime $before, $since_days_ago) {
// subquery to find latest click IDs for each newsletter
$table = self::$_table;
$latest_click_ids_per_newsletter_query = "
SELECT (
SELECT id
FROM $table
WHERE newsletter_id = c.newsletter_id
ORDER BY updated_at DESC
LIMIT 1
)
FROM $table c
WHERE c.subscriber_id = :subscriber_id
AND c.updated_at < :before
AND c.updated_at > DATE_SUB(NOW(), INTERVAL :since_days_ago DAY)
GROUP BY c.newsletter_id
";
return static::tableAlias('clicks')
->whereRaw("clicks.id IN ($latest_click_ids_per_newsletter_query)", [
'subscriber_id' => $subscriber->id,
'before' => $before->format('Y-m-d H:i:s'),
'since_days_ago' => $since_days_ago,
])
->findMany();
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace MailPoet\Models;
use WC_Order;
if (!defined('ABSPATH')) exit;
/**
* @property int $newsletter_id
* @property int $subscriber_id
* @property int $queue_id
* @property int $click_id
* @property int $order_id
* @property string $order_currency
* @property float $order_price_total
*/
class StatisticsWooCommerceOrders extends Model {
public static $_table = MP_STATISTICS_WOOCOMMERCE_ORDERS_TABLE;
static function createOrUpdateByClickAndOrder(StatisticsClicks $click, WC_Order $order) {
$statistics = self::where('click_id', $click->id)
->where('order_id', $order->get_id())
->findOne();
if (!$statistics) {
$statistics = self::create();
$statistics->newsletter_id = $click->newsletter_id;
$statistics->subscriber_id = $click->subscriber_id;
$statistics->queue_id = $click->queue_id;
$statistics->click_id = $click->id;
$statistics->order_id = $order->get_id();
}
$statistics->order_currency = $order->get_currency();
$statistics->order_price_total = (float)$order->get_total();
return $statistics->save();
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace MailPoet\Statistics\Track;
use MailPoet\Models\StatisticsClicks;
use MailPoet\Models\StatisticsWooCommerceOrders;
use MailPoet\Models\Subscriber;
use MailPoet\WooCommerce\Helper;
use WC_Order;
if (!defined('ABSPATH')) exit;
class WooCommerceOrders {
const USE_CLICKS_SINCE_DAYS_AGO = 14;
/** @var Helper */
private $woocommerce_helper;
function __construct(Helper $woocommerce_helper) {
$this->woocommerce_helper = $woocommerce_helper;
}
function trackPaidOrder($id) {
$order = $this->woocommerce_helper->wcGetOrder($id);
if (!$order instanceof WC_Order || floatval($order->get_total()) <= 0) {
return;
}
$subscriber = Subscriber::findOne($order->get_billing_email());
if (!$subscriber instanceof Subscriber) {
return;
}
$clicks = StatisticsClicks::findLatestPerNewsletterBySubscriber(
$subscriber,
$order->get_date_created(),
self::USE_CLICKS_SINCE_DAYS_AGO
);
foreach ($clicks as $click) {
StatisticsWooCommerceOrders::createOrUpdateByClickAndOrder($click, $order);
}
}
}