| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- <?php
- namespace MailPoet\AutomaticEmails\WooCommerce\Events;
- if (!defined('ABSPATH')) exit;
- use MailPoet\AutomaticEmails\WooCommerce\WooCommerce;
- use MailPoet\DI\ContainerWrapper;
- use MailPoet\Logging\LoggerFactory;
- use MailPoet\Models\Newsletter;
- use MailPoet\Models\SendingQueue;
- use MailPoet\Models\Subscriber;
- use MailPoet\Newsletter\AutomaticEmailsRepository;
- use MailPoet\Newsletter\Scheduler\AutomaticEmailScheduler;
- use MailPoet\WooCommerce\Helper as WCHelper;
- use MailPoet\WP\Functions as WPFunctions;
- class FirstPurchase {
- const SLUG = 'woocommerce_first_purchase';
- const ORDER_TOTAL_SHORTCODE = '[woocommerce:order_total]';
- const ORDER_DATE_SHORTCODE = '[woocommerce:order_date]';
- /**
- * @var \MailPoet\WooCommerce\Helper
- */
- private $helper;
- /** @var AutomaticEmailScheduler */
- private $scheduler;
- /** @var LoggerFactory */
- private $loggerFactory;
- /** @var AutomaticEmailsRepository */
- private $repository;
- public function __construct(
- WCHelper $helper = null
- ) {
- if ($helper === null) {
- $helper = new WCHelper();
- }
- $this->helper = $helper;
- $this->scheduler = new AutomaticEmailScheduler();
- $this->loggerFactory = LoggerFactory::getInstance();
- $this->repository = ContainerWrapper::getInstance()->get(AutomaticEmailsRepository::class);
- }
- public function init() {
- WPFunctions::get()->addFilter('mailpoet_newsletter_shortcode', [
- $this,
- 'handleOrderTotalShortcode',
- ], 10, 4);
- WPFunctions::get()->addFilter('mailpoet_newsletter_shortcode', [
- $this,
- 'handleOrderDateShortcode',
- ], 10, 4);
- // We have to use a set of states because an order state after checkout differs for different payment methods
- $acceptedOrderStates = WPFunctions::get()->applyFilters('mailpoet_first_purchase_order_states', ['completed', 'processing']);
- foreach ($acceptedOrderStates as $state) {
- WPFunctions::get()->addAction('woocommerce_order_status_' . $state, [
- $this,
- 'scheduleEmailWhenOrderIsPlaced',
- ], 10, 1);
- }
- }
- public function getEventDetails() {
- return [
- 'slug' => self::SLUG,
- 'title' => WPFunctions::get()->__('First Purchase', 'mailpoet'),
- 'description' => WPFunctions::get()->__('Let MailPoet send an email to customers who make their first purchase.', 'mailpoet'),
- 'listingScheduleDisplayText' => WPFunctions::get()->__('Email sent when a customer makes their first purchase.', 'mailpoet'),
- 'badge' => [
- 'text' => WPFunctions::get()->__('Must-have', 'mailpoet'),
- 'style' => 'red',
- ],
- 'shortcodes' => [
- [
- 'text' => WPFunctions::get()->__('Order amount', 'mailpoet'),
- 'shortcode' => self::ORDER_TOTAL_SHORTCODE,
- ],
- [
- 'text' => WPFunctions::get()->__('Order date', 'mailpoet'),
- 'shortcode' => self::ORDER_DATE_SHORTCODE,
- ],
- ],
- ];
- }
- public function handleOrderDateShortcode($shortcode, $newsletter, $subscriber, $queue) {
- $result = $shortcode;
- if ($shortcode === self::ORDER_DATE_SHORTCODE) {
- $defaultValue = WPFunctions::get()->dateI18n(get_option('date_format'));
- if (!$queue) {
- $result = $defaultValue;
- } else {
- $meta = $queue->getMeta();
- $result = (!empty($meta['order_date'])) ? WPFunctions::get()->dateI18n(get_option('date_format'), $meta['order_date']) : $defaultValue;
- }
- }
- $this->loggerFactory->getLogger(self::SLUG)->addInfo(
- 'handleOrderDateShortcode called', [
- 'newsletter_id' => ($newsletter instanceof Newsletter) ? $newsletter->id : null,
- 'subscriber_id' => ($subscriber instanceof Subscriber) ? $subscriber->id : null,
- 'task_id' => ($queue instanceof SendingQueue) ? $queue->taskId : null,
- 'shortcode' => $shortcode,
- 'result' => $result,
- ]
- );
- return $result;
- }
- public function handleOrderTotalShortcode($shortcode, $newsletter, $subscriber, $queue) {
- $result = $shortcode;
- if ($shortcode === self::ORDER_TOTAL_SHORTCODE) {
- $defaultValue = $this->helper->wcPrice(0);
- if (!$queue) {
- $result = $defaultValue;
- } else {
- $meta = $queue->getMeta();
- $result = (!empty($meta['order_amount'])) ? $this->helper->wcPrice($meta['order_amount']) : $defaultValue;
- }
- }
- $this->loggerFactory->getLogger(self::SLUG)->addInfo(
- 'handleOrderTotalShortcode called', [
- 'newsletter_id' => ($newsletter instanceof Newsletter) ? $newsletter->id : null,
- 'subscriber_id' => ($subscriber instanceof Subscriber) ? $subscriber->id : null,
- 'task_id' => ($queue instanceof SendingQueue) ? $queue->taskId : null,
- 'shortcode' => $shortcode,
- 'result' => $result,
- ]
- );
- return $result;
- }
- public function scheduleEmailWhenOrderIsPlaced($orderId) {
- $orderDetails = $this->helper->wcGetOrder($orderId);
- if (!$orderDetails || !$orderDetails->get_billing_email()) {
- $this->loggerFactory->getLogger(self::SLUG)->addInfo(
- 'Email not scheduled because the order customer was not found',
- ['order_id' => $orderId]
- );
- return;
- }
- $customerEmail = $orderDetails->get_billing_email();
- $customerOrderCount = $this->getCustomerOrderCount($customerEmail);
- if ($customerOrderCount > 1) {
- $this->loggerFactory->getLogger(self::SLUG)->addInfo(
- 'Email not scheduled because this is not the first order of the customer', [
- 'order_id' => $orderId,
- 'customer_email' => $customerEmail,
- 'order_count' => $customerOrderCount,
- ]
- );
- return;
- }
- $meta = [
- 'order_amount' => $orderDetails->get_total(),
- 'order_date' => $orderDetails->get_date_created()->getTimestamp(),
- 'order_id' => $orderDetails->get_id(),
- ];
- $subscriber = Subscriber::getWooCommerceSegmentSubscriber($customerEmail);
- if (!$subscriber instanceof Subscriber) {
- $this->loggerFactory->getLogger(self::SLUG)->addInfo(
- 'Email not scheduled because the customer was not found as WooCommerce list subscriber',
- ['order_id' => $orderId, 'customer_email' => $customerEmail]
- );
- return;
- }
- $checkEmailWasNotScheduled = function (Newsletter $newsletter) use ($subscriber) {
- return !$this->repository->wasScheduledForSubscriber($newsletter->id, $subscriber->id);
- };
- $this->loggerFactory->getLogger(self::SLUG)->addInfo(
- 'Email scheduled', [
- 'order_id' => $orderId,
- 'customer_email' => $customerEmail,
- 'subscriber_id' => $subscriber->id,
- ]
- );
- $this->scheduler->scheduleAutomaticEmail(WooCommerce::SLUG, self::SLUG, $checkEmailWasNotScheduled, $subscriber->id, $meta);
- }
- public function getCustomerOrderCount($customerEmail) {
- // registered user
- $user = WPFunctions::get()->getUserBy('email', $customerEmail);
- if ($user) {
- return $this->helper->wcGetCustomerOrderCount($user->ID);
- }
- // guest user
- return $this->getGuestCustomerOrderCountByEmail($customerEmail);
- }
- private function getGuestCustomerOrderCountByEmail($customerEmail) {
- global $wpdb;
- $count = $wpdb->get_var( "SELECT COUNT(*)
- FROM $wpdb->posts as posts
- LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
- WHERE meta.meta_key = '_billing_email'
- AND posts.post_type = 'shop_order'
- AND meta_value = '" . WPFunctions::get()->escSql($customerEmail) . "'
- " );
- return (int)$count;
- }
- }
|