262 lines
8.1 KiB
PHP
262 lines
8.1 KiB
PHP
<?php declare(strict_types = 1);
|
|
|
|
namespace MailPoet\Automation\Integrations\MailPoet\Templates;
|
|
|
|
if (!defined('ABSPATH')) exit;
|
|
|
|
|
|
use MailPoet\Automation\Engine\Data\Automation;
|
|
use MailPoet\Automation\Engine\Exceptions\NotFoundException;
|
|
use MailPoet\Automation\Engine\WordPress;
|
|
use MailPoet\Config\Env;
|
|
use MailPoet\Entities\NewsletterEntity;
|
|
use MailPoet\Entities\NewsletterOptionEntity;
|
|
use MailPoet\Entities\NewsletterOptionFieldEntity;
|
|
use MailPoet\Newsletter\NewslettersRepository;
|
|
use MailPoet\Newsletter\Options\NewsletterOptionFieldsRepository;
|
|
use MailPoet\Newsletter\Options\NewsletterOptionsRepository;
|
|
use MailPoet\Settings\SettingsController;
|
|
use MailPoet\Util\Security;
|
|
|
|
class EmailFactory {
|
|
/** @var NewslettersRepository */
|
|
private $newslettersRepository;
|
|
|
|
/** @var SettingsController */
|
|
private $settings;
|
|
|
|
/** @var string|null */
|
|
protected $templatesDirectory;
|
|
|
|
/** @var WordPress */
|
|
private $wp;
|
|
|
|
/** @var NewsletterOptionsRepository */
|
|
private $newsletterOptionsRepository;
|
|
|
|
/** @var NewsletterOptionFieldsRepository */
|
|
private $newsletterOptionFieldsRepository;
|
|
|
|
public function __construct(
|
|
NewslettersRepository $newslettersRepository,
|
|
SettingsController $settings,
|
|
WordPress $wp,
|
|
NewsletterOptionsRepository $newsletterOptionsRepository,
|
|
NewsletterOptionFieldsRepository $newsletterOptionFieldsRepository
|
|
) {
|
|
$this->newslettersRepository = $newslettersRepository;
|
|
$this->settings = $settings;
|
|
$this->wp = $wp;
|
|
$this->newsletterOptionsRepository = $newsletterOptionsRepository;
|
|
$this->newsletterOptionFieldsRepository = $newsletterOptionFieldsRepository;
|
|
}
|
|
|
|
/**
|
|
* Create an email from a template and store it in the database
|
|
*
|
|
* @param array $data Email data including subject, preheader, etc.
|
|
* @return int|null The ID of the created email or null if the email couldn't be created
|
|
*/
|
|
public function createEmail(array $data = []): ?int {
|
|
// Create a new newsletter entity
|
|
$newsletter = new NewsletterEntity();
|
|
$newsletter->setType(NewsletterEntity::TYPE_AUTOMATION);
|
|
$newsletter->setStatus(NewsletterEntity::STATUS_ACTIVE);
|
|
$newsletter->setSubject($data['subject'] ?? '');
|
|
$newsletter->setPreheader($data['preheader'] ?? '');
|
|
$newsletter->setSenderName($data['sender_name'] ?? $this->getDefaultSenderName());
|
|
$newsletter->setSenderAddress($data['sender_address'] ?? $this->getDefaultSenderAddress());
|
|
$newsletter->setHash(Security::generateHash());
|
|
|
|
// Set content if provided
|
|
if (isset($data['content'])) {
|
|
$newsletter->setBody($data['content']);
|
|
} elseif (isset($data['template'])) {
|
|
$template = $this->loadTemplate($data['template']);
|
|
if ($template) {
|
|
$newsletter->setBody($template);
|
|
}
|
|
}
|
|
|
|
// Save the newsletter to the database
|
|
$this->newslettersRepository->persist($newsletter);
|
|
$this->newslettersRepository->flush();
|
|
|
|
// Return the newsletter ID
|
|
return $newsletter->getId();
|
|
}
|
|
|
|
/**
|
|
* Sets automation and step ID for all email steps in an automation
|
|
*
|
|
* @param Automation $automation The automation object
|
|
* @return void
|
|
*/
|
|
public function setAutomationIdForEmails(Automation $automation): void {
|
|
// Skip if automation ID is not set
|
|
try {
|
|
$automationId = $automation->getId();
|
|
} catch (\Exception $e) {
|
|
return;
|
|
}
|
|
|
|
$steps = $automation->getSteps();
|
|
$emailSteps = array_filter($steps, function($step) {
|
|
return $step->getKey() === 'mailpoet:send-email';
|
|
});
|
|
|
|
foreach ($emailSteps as $step) {
|
|
$args = $step->getArgs();
|
|
$emailId = $args['email_id'] ?? null;
|
|
|
|
if ($emailId) {
|
|
$newsletter = $this->newslettersRepository->findOneById($emailId);
|
|
if (!$newsletter) {
|
|
continue;
|
|
}
|
|
|
|
$existingAutomationId = $newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AUTOMATION_ID);
|
|
$existingStepId = $newsletter->getOptionValue(NewsletterOptionFieldEntity::NAME_AUTOMATION_STEP_ID);
|
|
|
|
if ($existingAutomationId === (string)$automationId && $existingStepId === $step->getId()) {
|
|
continue;
|
|
}
|
|
|
|
$this->storeNewsletterOption(
|
|
$newsletter,
|
|
NewsletterOptionFieldEntity::NAME_AUTOMATION_ID,
|
|
(string)$automationId
|
|
);
|
|
|
|
$this->storeNewsletterOption(
|
|
$newsletter,
|
|
NewsletterOptionFieldEntity::NAME_AUTOMATION_STEP_ID,
|
|
$step->getId()
|
|
);
|
|
|
|
$this->newslettersRepository->flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stores a newsletter option
|
|
*
|
|
* @param NewsletterEntity $newsletter The newsletter entity
|
|
* @param string $optionName The name of the option
|
|
* @param string|null $optionValue The value of the option
|
|
* @return void
|
|
*/
|
|
private function storeNewsletterOption(NewsletterEntity $newsletter, string $optionName, ?string $optionValue = null): void {
|
|
if (!$optionValue || !$this->newsletterOptionsRepository || !$this->newsletterOptionFieldsRepository) {
|
|
return;
|
|
}
|
|
|
|
$existingOption = $newsletter->getOption($optionName);
|
|
if ($existingOption && $existingOption->getValue() === $optionValue) {
|
|
return; // Skip if option already exists with the same value
|
|
}
|
|
|
|
$field = $this->newsletterOptionFieldsRepository->findOneBy([
|
|
'name' => $optionName,
|
|
'newsletterType' => $newsletter->getType(),
|
|
]);
|
|
|
|
if (!$field) {
|
|
return;
|
|
}
|
|
|
|
// If option exists but with different value, update it
|
|
if ($existingOption) {
|
|
$existingOption->setValue($optionValue);
|
|
return;
|
|
}
|
|
|
|
// Otherwise create a new option
|
|
$option = new NewsletterOptionEntity($newsletter, $field);
|
|
$option->setValue($optionValue);
|
|
$this->newsletterOptionsRepository->persist($option);
|
|
$newsletter->getOptions()->add($option);
|
|
}
|
|
|
|
/**
|
|
* Get the default sender name from settings
|
|
*/
|
|
private function getDefaultSenderName(): string {
|
|
return $this->settings->get('sender.name', '');
|
|
}
|
|
|
|
/**
|
|
* Get the default sender address from settings
|
|
*/
|
|
private function getDefaultSenderAddress(): string {
|
|
return $this->settings->get('sender.address', '');
|
|
}
|
|
|
|
/**
|
|
* Load a template from a file
|
|
*
|
|
* @param string $templateName The name of the template file (without .json extension)
|
|
* @return array|null The template body or null if the template doesn't exist
|
|
*/
|
|
public function loadTemplate(string $templateName): ?array {
|
|
$templatePath = $this->getTemplatePath($templateName);
|
|
|
|
if (!file_exists($templatePath)) {
|
|
throw new NotFoundException('Template not found: ' . $templateName);
|
|
}
|
|
return $this->fetchEmailTemplate($templatePath);
|
|
}
|
|
|
|
/**
|
|
* Get the path to a template file
|
|
*
|
|
* @param string $templateName The name of the template file (without .json extension)
|
|
* @return string The full path to the template file
|
|
*/
|
|
protected function getTemplatePath(string $templateName): string {
|
|
$sanitizedTemplateName = $this->wp->sanitizeFileName($templateName);
|
|
return $this->getTemplatesDirectory() . '/' . $sanitizedTemplateName . '.json';
|
|
}
|
|
|
|
/**
|
|
* Fetch email template from a file
|
|
*
|
|
* @param string $templatePath The path to the template file
|
|
* @return array|null The template body or null if the template couldn't be loaded
|
|
*/
|
|
private function fetchEmailTemplate(string $templatePath): ?array {
|
|
$templateString = file_get_contents($templatePath);
|
|
if ($templateString === false) {
|
|
return null;
|
|
}
|
|
|
|
$templateArr = json_decode((string)$templateString, true);
|
|
if (!is_array($templateArr) || !isset($templateArr['body'])) {
|
|
return null;
|
|
}
|
|
|
|
return $templateArr['body'];
|
|
}
|
|
|
|
/**
|
|
* Set the templates directory
|
|
*
|
|
* @param string|null $directory The directory where templates are stored
|
|
* @return self
|
|
*/
|
|
public function setTemplatesDirectory(?string $directory): self {
|
|
$this->templatesDirectory = $directory;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get the templates directory
|
|
*
|
|
* @return string The directory where templates are stored
|
|
*/
|
|
public function getTemplatesDirectory(): string {
|
|
return $this->templatesDirectory
|
|
?: Env::$libPath . '/Automation/Integrations/MailPoet/Templates/EmailTemplates';
|
|
}
|
|
}
|