Add subscriber backend

[PREMIUM-225]
This commit is contained in:
David Remer
2023-07-05 09:26:08 +03:00
committed by Aschepikov
parent 5841c09a31
commit a33422123a
6 changed files with 227 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ use MailPoet\Automation\Engine\WordPress;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\AutomationFlowEndpoint; use MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\AutomationFlowEndpoint;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\OrderEndpoint; use MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\OrderEndpoint;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\OverviewEndpoint; use MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\OverviewEndpoint;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\SubscriberEndpoint;
class Analytics { class Analytics {
@@ -25,6 +26,7 @@ class Analytics {
$api->registerGetRoute('automation/analytics/automation_flow', AutomationFlowEndpoint::class); $api->registerGetRoute('automation/analytics/automation_flow', AutomationFlowEndpoint::class);
$api->registerGetRoute('automation/analytics/overview', OverviewEndpoint::class); $api->registerGetRoute('automation/analytics/overview', OverviewEndpoint::class);
$api->registerGetRoute('automation/analytics/orders', OrderEndpoint::class); $api->registerGetRoute('automation/analytics/orders', OrderEndpoint::class);
$api->registerGetRoute('automation/analytics/subscribers', SubscriberEndpoint::class);
}); });
} }
} }

View File

@@ -0,0 +1,124 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\MailPoet\Analytics\Controller;
use MailPoet\Automation\Engine\Data\Automation;
use MailPoet\Automation\Engine\Data\AutomationRun;
use MailPoet\Automation\Engine\Data\Step;
use MailPoet\Automation\Engine\Registry;
use MailPoet\Automation\Engine\WordPress;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Entities\Query;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Subscribers\SubscribersRepository;
class FreeSubscriberController implements SubscriberController {
/** @var SubscribersRepository */
private $subscribersRepository;
/** @var WordPress */
private $wp;
/** @var Registry */
private $registry;
public function __construct(
SubscribersRepository $subscribersRepository,
WordPress $wp,
Registry $registry
) {
$this->subscribersRepository = $subscribersRepository;
$this->wp = $wp;
$this->registry = $registry;
}
public function getSubscribersForAutomation(Automation $automation, Query $query): array {
$items = [
$this->addItem($automation, $query),
$this->addItem($automation, $query),
$this->addItem($automation, $query),
$this->addItem($automation, $query),
];
return [
'results' => count($items),
'items' => $items,
];
}
private function addItem(Automation $automation, Query $query): array {
$subscriber = $this->getRandomSubscriber();
$step = $this->getRandomStep($automation);
return [
'date' => $this->findRandomDateBetween($query->getAfter(), $query->getBefore())->format(\DateTimeImmutable::W3C),
'subscriber' => [
'id' => $subscriber->getId(),
'email' => $subscriber->getEmail(),
'first_name' => $subscriber->getFirstName(),
'last_name' => $subscriber->getLastName(),
'avatar' => $this->wp->getAvatarUrl($subscriber->getEmail(), ['size' => 20]),
],
'run' => [
'automation_id' => $automation->getId(),
'status' => $this->getRandomStatus(),
'step' => $this->getRandomStep($automation),
],
];
}
private function getRandomStep(Automation $automation): array {
/** @var Step[] $steps */
$steps = array_values(
array_filter(
$automation->getSteps(),
function (Step $step) {
return $step->getType() === Step::TYPE_ACTION;
}
)
);
if (!$steps) {
return ['id' => '', 'name' => ''];
}
$step = $steps[array_rand($steps)];
$stepType = $this->registry->getStep($step->getKey());
return [
'id' => $step->getId(),
'name' => $stepType ? $stepType->getName() : __('Unknown', 'mailpoet'),
];
}
private function getRandomStatus(): string {
$statuses = [AutomationRun::STATUS_RUNNING, AutomationRun::STATUS_COMPLETE];
return $statuses[array_rand($statuses)];
}
private function getRandomSubscriber(): SubscriberEntity {
$subscribers = $this->subscribersRepository->findBy([], null, 100);
if (!$subscribers) {
/** @var string $email */
$email = $this->wp->getOption('admin_email');
$subscriber = new SubscriberEntity();
$subscriber->setFirstName('John');
$subscriber->setLastName('Doe');
$subscriber->setEmail($email);
return $subscriber;
}
return $subscribers[array_rand($subscribers)];
}
private function findRandomDateBetween(\DateTimeImmutable $start, \DateTimeImmutable $end): \DateTime {
$start = new \DateTime($start->format(\DateTime::W3C));
$start->setTimezone($this->wp->wpTimezone());
$end = new \DateTime($end->format(\DateTime::W3C));
$end->setTimezone($this->wp->wpTimezone());
$randomTimestamp = mt_rand($start->getTimestamp(), $end->getTimestamp());
$randomDate = new \DateTime();
$randomDate->setTimestamp($randomTimestamp);
$randomDate->setTimezone($this->wp->wpTimezone());
return $randomDate;
}
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\MailPoet\Analytics\Controller;
use MailPoet\Automation\Engine\Data\Automation;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Entities\Query;
interface SubscriberController {
public function getSubscribersForAutomation(Automation $automation, Query $query): array;
}

View File

@@ -0,0 +1,52 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints;
use MailPoet\API\REST\Request;
use MailPoet\API\REST\Response;
use MailPoet\Automation\Engine\API\Endpoint;
use MailPoet\Automation\Engine\Exceptions\NotFoundException;
use MailPoet\Automation\Engine\Storage\AutomationStorage;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Entities\Query;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Factories\SubscriberControllerFactory;
use MailPoet\Validator\Builder;
class SubscriberEndpoint extends Endpoint {
/** @var AutomationStorage */
private $automationStorage;
/** @var SubscriberControllerFactory */
private $subscriberControllerFactory;
public function __construct(
AutomationStorage $automationStorage,
SubscriberControllerFactory $subscriberControllerFactory
) {
$this->automationStorage = $automationStorage;
$this->subscriberControllerFactory = $subscriberControllerFactory;
}
public static function getRequestSchema(): array {
return [
'id' => Builder::integer()->required(),
'query' => Query::getRequestSchema(),
];
}
public function checkPermissions(): bool {
return true;
}
public function handle(Request $request): Response {
$automation = $this->automationStorage->getAutomation(absint($request->getParam('id')));
if (!$automation) {
throw new NotFoundException(__('Automation not found', 'mailpoet'));
}
$query = Query::fromRequest($request);
$controller = $this->subscriberControllerFactory->getSubscriberController();
$result = $controller->getSubscribersForAutomation($automation, $query);
return new Response($result);
}
}

View File

@@ -0,0 +1,35 @@
<?php declare(strict_types = 1);
namespace MailPoet\Automation\Integrations\MailPoet\Analytics\Factories;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Controller\FreeSubscriberController;
use MailPoet\Automation\Integrations\MailPoet\Analytics\Controller\SubscriberController;
use MailPoet\Premium\Automation\Integrations\MailPoetPremium\Analytics\Controller\PremiumSubscriberController;
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
class SubscriberControllerFactory {
/** @var SubscribersFeature */
private $subscribersFeature;
public function __construct(
SubscribersFeature $subscribersFeature
) {
$this->subscribersFeature = $subscribersFeature;
}
public function getSubscriberController(): SubscriberController {
$container = \MailPoet\DI\ContainerWrapper::getInstance();
return $this->isPremium() ?
$container->get(PremiumSubscriberController::class) : /* @phpstan-ignore-line */
$container->get(FreeSubscriberController::class);
}
private function isPremium(): bool {
return
class_exists(PremiumSubscriberController::class)
&& $this->subscribersFeature->hasValidApiKey()
&& !$this->subscribersFeature->check();
}
}

View File

@@ -205,6 +205,10 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Controller\FreeOrderController::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Controller\FreeOrderController::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Factories\OrderControllerFactory::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Factories\OrderControllerFactory::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\OrderEndpoint::class)->setPublic(true); $container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\OrderEndpoint::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Controller\FreeSubscriberController::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Factories\SubscriberControllerFactory::class)->setPublic(true);
$container->autowire(\MailPoet\Automation\Integrations\MailPoet\Analytics\Endpoints\SubscriberEndpoint::class)->setPublic(true);
// Config // Config
$container->autowire(\MailPoet\Config\AccessControl::class)->setPublic(true); $container->autowire(\MailPoet\Config\AccessControl::class)->setPublic(true);
$container->autowire(\MailPoet\Config\Activator::class)->setPublic(true); $container->autowire(\MailPoet\Config\Activator::class)->setPublic(true);