PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.2
MailPoet – Newsletters, Email Marketing, and Automation v5.34.2
5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib / Statistics / StatisticsWooCommercePurchasesRepository.php
mailpoet / lib / Statistics Last commit date
Track 4 days ago GATracking.php 6 months ago StatisticsBouncesRepository.php 3 years ago StatisticsClicksRepository.php 2 years ago StatisticsFormsRepository.php 3 years ago StatisticsNewslettersRepository.php 1 year ago StatisticsOpensRepository.php 3 days ago StatisticsUnsubscribesRepository.php 2 months ago StatisticsWooCommercePurchasesRepository.php 1 year ago UnsubscribeReasonTracker.php 2 months ago UserAgentsRepository.php 1 year ago index.php 3 years ago
StatisticsWooCommercePurchasesRepository.php
137 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Statistics;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Doctrine\Repository;
9 use MailPoet\Entities\NewsletterEntity;
10 use MailPoet\Entities\SendingQueueEntity;
11 use MailPoet\Entities\StatisticsClickEntity;
12 use MailPoet\Entities\StatisticsWooCommercePurchaseEntity;
13 use MailPoet\WooCommerce\Helper;
14 use MailPoetVendor\Doctrine\DBAL\ArrayParameterType;
15 use MailPoetVendor\Doctrine\DBAL\ParameterType;
16 use MailPoetVendor\Doctrine\ORM\EntityManager;
17
18 /**
19 * @extends Repository<StatisticsWooCommercePurchaseEntity>
20 */
21 class StatisticsWooCommercePurchasesRepository extends Repository {
22
23 /** @var Helper */
24 private $wooCommerceHelper;
25
26 public function __construct(
27 EntityManager $entityManager,
28 Helper $wooCommerceHelper
29 ) {
30 parent::__construct($entityManager);
31 $this->wooCommerceHelper = $wooCommerceHelper;
32 }
33
34 protected function getEntityClassName() {
35 return StatisticsWooCommercePurchaseEntity::class;
36 }
37
38 public function createOrUpdateByClickDataAndOrder(StatisticsClickEntity $click, \WC_Order $order) {
39 // search by subscriber and newsletter IDs (instead of click itself) to avoid duplicities
40 // when a new click from the subscriber appeared since last tracking for given newsletter
41 // (this will keep the originally tracked click - likely the click that led to the order)
42 $statistics = $this->findOneBy([
43 'orderId' => $order->get_id(),
44 'subscriber' => $click->getSubscriber(),
45 'newsletter' => $click->getNewsletter(),
46 ]);
47
48 if (!$statistics instanceof StatisticsWooCommercePurchaseEntity) {
49 $newsletter = $click->getNewsletter();
50 $queue = $click->getQueue();
51 if ((!$newsletter instanceof NewsletterEntity) || (!$queue instanceof SendingQueueEntity)) return;
52 $statistics = new StatisticsWooCommercePurchaseEntity(
53 $newsletter,
54 $queue,
55 $click,
56 $order->get_id(),
57 $order->get_currency(),
58 (float)$order->get_remaining_refund_amount(),
59 $order->get_status()
60 );
61 $this->persist($statistics);
62 } else {
63 $statistics->setOrderCurrency($order->get_currency());
64 $statistics->setOrderPriceTotal((float)$order->get_remaining_refund_amount());
65 $statistics->setStatus($order->get_status());
66 }
67 $statistics->setSubscriber($click->getSubscriber());
68 $this->flush();
69 }
70
71 public function getRevenuesByCampaigns(string $currency): array {
72 $revenueStatus = $this->wooCommerceHelper->getPurchaseStates();
73 $revenueStatsTable = $this->entityManager->getClassMetadata(StatisticsWooCommercePurchaseEntity::class)->getTableName();
74 $newsletterTable = $this->entityManager->getClassMetadata(NewsletterEntity::class)->getTableName();
75
76 // The "SELECT MIN(click_id)..." sub-query is used to count each purchase only once.
77 // In the data we track a purchase to multiple newsletters if clicks from multiple newsletters occurred.
78 /** @var array<int, array{revenue: float|int, campaign_id:int, orders_count:int}> $data */
79 $data = $this->entityManager->getConnection()->executeQuery('
80 SELECT
81 SUM(swp.order_price_total) AS revenue,
82 COALESCE(n.parent_id, swp.newsletter_id) AS campaign_id,
83 (
84 CASE
85 WHEN n.type IS NULL THEN \'unknown\'
86 WHEN n.type = :notification_history_type THEN :notification_type
87 ELSE n.type
88 END
89 ) AS campaign_type,
90 COUNT(order_id) as orders_count
91 FROM ' . $revenueStatsTable . ' swp
92 LEFT JOIN ' . $newsletterTable . ' n ON
93 n.id = swp.newsletter_id
94 WHERE
95 swp.order_currency = :currency
96 AND swp.status IN (:revenue_status)
97 AND swp.click_id IN (SELECT MIN(click_id) FROM ' . $revenueStatsTable . ' ss GROUP BY order_id)
98 GROUP BY campaign_id, n.type;
99 ', [
100 'notification_history_type' => NewsletterEntity::TYPE_NOTIFICATION_HISTORY,
101 'notification_type' => NewsletterEntity::TYPE_NOTIFICATION,
102 'currency' => $currency,
103 'revenue_status' => $revenueStatus,
104 ], [
105 'notification_history_type' => ParameterType::STRING,
106 'notification_type' => ParameterType::STRING,
107 'currency' => ParameterType::STRING,
108 'revenue_status' => ArrayParameterType::STRING,
109 ])->fetchAllAssociative();
110
111 $data = array_map(function($row) {
112 $row['revenue'] = round(floatval($row['revenue']), 2);
113 $row['orders_count'] = intval($row['orders_count']);
114 return $row;
115 }, $data);
116 return $data;
117 }
118
119 /** @param int[] $ids */
120 public function removeNewsletterDataByNewsletterIds(array $ids): void {
121 $this->entityManager->createQueryBuilder()
122 ->update(StatisticsWooCommercePurchaseEntity::class, 'swp')
123 ->set('swp.newsletter', ':newsletter')
124 ->where('swp.newsletter IN (:ids)')
125 ->setParameter('newsletter', null)
126 ->setParameter('ids', $ids)
127 ->getQuery()
128 ->execute();
129
130 // update was done via DQL, make sure the entities are also refreshed in the entity manager
131 $this->refreshAll(function (StatisticsWooCommercePurchaseEntity $entity) use ($ids) {
132 $newsletter = $entity->getNewsletter();
133 return $newsletter && in_array($newsletter->getId(), $ids, true);
134 });
135 }
136 }
137