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'; } }