init
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
|
||||
|
||||
namespace MailPoet\Subscribers\Statistics;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Newsletter\Statistics\WooCommerceRevenue;
|
||||
|
||||
class SubscriberStatistics {
|
||||
|
||||
/** @var int */
|
||||
private $clickCount;
|
||||
|
||||
/** @var int */
|
||||
private $openCount;
|
||||
|
||||
/** @var int */
|
||||
private $machineOpenCount;
|
||||
|
||||
/** @var int */
|
||||
private $totalSentCount;
|
||||
|
||||
/** @var WooCommerceRevenue|null */
|
||||
private $wooCommerceRevenue;
|
||||
|
||||
public function __construct(
|
||||
$clickCount,
|
||||
$openCount,
|
||||
$machineOpenCount,
|
||||
$totalSentCount,
|
||||
$wooCommerceRevenue = null
|
||||
) {
|
||||
$this->clickCount = $clickCount;
|
||||
$this->openCount = $openCount;
|
||||
$this->machineOpenCount = $machineOpenCount;
|
||||
$this->totalSentCount = $totalSentCount;
|
||||
$this->wooCommerceRevenue = $wooCommerceRevenue;
|
||||
}
|
||||
|
||||
public function getClickCount(): int {
|
||||
return $this->clickCount;
|
||||
}
|
||||
|
||||
public function getOpenCount(): int {
|
||||
return $this->openCount;
|
||||
}
|
||||
|
||||
public function getMachineOpenCount(): int {
|
||||
return $this->machineOpenCount;
|
||||
}
|
||||
|
||||
public function getTotalSentCount(): int {
|
||||
return $this->totalSentCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WooCommerceRevenue|null
|
||||
*/
|
||||
public function getWooCommerceRevenue() {
|
||||
return $this->wooCommerceRevenue;
|
||||
}
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
|
||||
|
||||
namespace MailPoet\Subscribers\Statistics;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Doctrine\Repository;
|
||||
use MailPoet\Entities\StatisticsClickEntity;
|
||||
use MailPoet\Entities\StatisticsNewsletterEntity;
|
||||
use MailPoet\Entities\StatisticsOpenEntity;
|
||||
use MailPoet\Entities\StatisticsWooCommercePurchaseEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\Entities\UserAgentEntity;
|
||||
use MailPoet\Newsletter\Statistics\WooCommerceRevenue;
|
||||
use MailPoet\Settings\TrackingConfig;
|
||||
use MailPoet\WooCommerce\Helper as WCHelper;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||
use MailPoetVendor\Doctrine\ORM\QueryBuilder;
|
||||
|
||||
/**
|
||||
* @extends Repository<SubscriberEntity>
|
||||
*/
|
||||
class SubscriberStatisticsRepository extends Repository {
|
||||
|
||||
/** @var WCHelper */
|
||||
private $wcHelper;
|
||||
|
||||
/** @var TrackingConfig */
|
||||
private $trackingConfig;
|
||||
|
||||
public function __construct(
|
||||
EntityManager $entityManager,
|
||||
WCHelper $wcHelper,
|
||||
TrackingConfig $trackingConfig
|
||||
) {
|
||||
parent::__construct($entityManager);
|
||||
$this->wcHelper = $wcHelper;
|
||||
$this->trackingConfig = $trackingConfig;
|
||||
}
|
||||
|
||||
protected function getEntityClassName() {
|
||||
return SubscriberEntity::class;
|
||||
}
|
||||
|
||||
public function getStatistics(SubscriberEntity $subscriber, ?Carbon $startTime = null) {
|
||||
return new SubscriberStatistics(
|
||||
$this->getStatisticsClickCount($subscriber, $startTime),
|
||||
$this->getStatisticsOpenCount($subscriber, $startTime),
|
||||
$this->getStatisticsMachineOpenCount($subscriber, $startTime),
|
||||
$this->getTotalSentCount($subscriber, $startTime),
|
||||
$this->getWooCommerceRevenue($subscriber, $startTime)
|
||||
);
|
||||
}
|
||||
|
||||
public function getStatisticsClickCount(SubscriberEntity $subscriber, ?Carbon $startTime = null): int {
|
||||
$queryBuilder = $this->getStatisticsCountQuery(StatisticsClickEntity::class, $subscriber);
|
||||
if ($startTime) {
|
||||
$this->applyDateConstraint($queryBuilder, $startTime);
|
||||
}
|
||||
return (int)$queryBuilder
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function getStatisticsOpenCountQuery(SubscriberEntity $subscriber, ?Carbon $startTime = null): QueryBuilder {
|
||||
$queryBuilder = $this->getStatisticsCountQuery(StatisticsOpenEntity::class, $subscriber);
|
||||
if ($startTime) {
|
||||
$this->applyDateConstraint($queryBuilder, $startTime);
|
||||
}
|
||||
return $queryBuilder;
|
||||
}
|
||||
|
||||
public function getStatisticsOpenCount(SubscriberEntity $subscriber, ?Carbon $startTime = null): int {
|
||||
$queryBuilder = $this->getStatisticsOpenCountQuery($subscriber, $startTime);
|
||||
if ($this->trackingConfig->areOpensSeparated()) {
|
||||
$queryBuilder
|
||||
->andWhere('(stats.userAgentType = :userAgentType)')
|
||||
->setParameter('userAgentType', UserAgentEntity::USER_AGENT_TYPE_HUMAN);
|
||||
}
|
||||
return (int)$queryBuilder
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function getStatisticsMachineOpenCount(SubscriberEntity $subscriber, ?Carbon $startTime = null): int {
|
||||
return (int)$this->getStatisticsOpenCountQuery($subscriber, $startTime)
|
||||
->andWhere('(stats.userAgentType = :userAgentType)')
|
||||
->setParameter('userAgentType', UserAgentEntity::USER_AGENT_TYPE_MACHINE)
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function getTotalSentCount(SubscriberEntity $subscriber, ?Carbon $startTime = null): int {
|
||||
$queryBuilder = $this->getStatisticsCountQuery(StatisticsNewsletterEntity::class, $subscriber);
|
||||
if ($startTime) {
|
||||
$queryBuilder
|
||||
->andWhere('stats.sentAt >= :dateTime')
|
||||
->setParameter('dateTime', $startTime);
|
||||
}
|
||||
return (int)$queryBuilder
|
||||
->getQuery()
|
||||
->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function getStatisticsCountQuery(string $entityName, SubscriberEntity $subscriber): QueryBuilder {
|
||||
return $this->entityManager->createQueryBuilder()
|
||||
->select('COUNT(DISTINCT stats.newsletter) as cnt')
|
||||
->from($entityName, 'stats')
|
||||
->where('stats.subscriber = :subscriber')
|
||||
->setParameter('subscriber', $subscriber);
|
||||
}
|
||||
|
||||
public function getWooCommerceRevenue(SubscriberEntity $subscriber, ?Carbon $startTime = null): ?WooCommerceRevenue {
|
||||
if (!$this->wcHelper->isWooCommerceActive()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$revenueStatus = $this->wcHelper->getPurchaseStates();
|
||||
$currency = $this->wcHelper->getWoocommerceCurrency();
|
||||
$queryBuilder = $this->entityManager->createQueryBuilder()
|
||||
->select('stats.orderPriceTotal')
|
||||
->from(StatisticsWooCommercePurchaseEntity::class, 'stats')
|
||||
->where('stats.subscriber = :subscriber')
|
||||
->andWhere('stats.orderCurrency = :currency')
|
||||
->setParameter('subscriber', $subscriber)
|
||||
->setParameter('currency', $currency)
|
||||
->andWhere('stats.status IN (:revenue_status)')
|
||||
->setParameter('subscriber', $subscriber)
|
||||
->setParameter('currency', $currency)
|
||||
->setParameter('revenue_status', $revenueStatus)
|
||||
->groupBy('stats.orderId, stats.orderPriceTotal');
|
||||
if ($startTime) {
|
||||
$queryBuilder
|
||||
->andWhere('stats.createdAt >= :dateTime')
|
||||
->setParameter('dateTime', $startTime);
|
||||
}
|
||||
$purchases =
|
||||
$queryBuilder->getQuery()
|
||||
->getResult();
|
||||
$sum = array_sum(array_column($purchases, 'orderPriceTotal'));
|
||||
return new WooCommerceRevenue(
|
||||
$currency,
|
||||
(float)$sum,
|
||||
count($purchases),
|
||||
$this->wcHelper
|
||||
);
|
||||
}
|
||||
|
||||
private function applyDateConstraint(QueryBuilder $queryBuilder, Carbon $startTime): QueryBuilder {
|
||||
$queryBuilder->join(StatisticsNewsletterEntity::class, 'sent_stats', 'WITH', 'stats.newsletter = sent_stats.newsletter AND stats.subscriber = sent_stats.subscriber AND sent_stats.sentAt >= :dateTime')
|
||||
->setParameter('dateTime', $startTime);
|
||||
|
||||
return $queryBuilder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
Reference in New Issue
Block a user