settings = $settings; $this->newslettersRepository = $newslettersRepository; $this->scheduledTasksRepository = $scheduledTasksRepository; $this->subscriberSegmentRepository = $subscriberSegmentRepository; $this->automationEmailScheduler = $automationEmailScheduler; } public function getKey(): string { return 'mailpoet:send-email'; } public function getName(): string { return __('Send email', 'mailpoet'); } public function getArgsSchema(): ObjectSchema { return Builder::object([ 'subject' => Builder::string()->default(__('Subject', 'mailpoet')), 'preheader' => Builder::string(), 'sender_name' => Builder::string()->default($this->settings->get('sender.name')), 'sender_address' => Builder::string()->default($this->settings->get('sender.address')), 'reply_to_name' => Builder::string()->default($this->settings->get('reply_to.name')), 'reply_to_address' => Builder::string()->default($this->settings->get('reply_to.address')), 'ga_campaign' => Builder::string(), 'name' => Builder::string()->default(__('Send email', 'mailpoet')), ]); } public function isValid(array $subjects, Step $step, Workflow $workflow): bool { try { $this->getEmailForStep($step); } catch (InvalidStateException $exception) { return false; } $segmentSubjects = array_filter($subjects, function (Subject $subject) { return $subject->getKey() === SegmentSubject::KEY; }); $subscriberSubjects = array_filter($subjects, function (Subject $subject) { return $subject->getKey() === SubscriberSubject::KEY; }); return count($segmentSubjects) === 1 && count($subscriberSubjects) === 1; } public function run(Workflow $workflow, WorkflowRun $workflowRun, Step $step): void { $newsletter = $this->getEmailForStep($step); $subscriberSubject = $workflowRun->requireSingleSubject(SubscriberSubject::class); $subscriber = $subscriberSubject->getSubscriber(); if ($subscriber->getStatus() !== SubscriberEntity::STATUS_SUBSCRIBED) { throw InvalidStateException::create()->withMessage(sprintf("Cannot schedule a newsletter for subscriber ID '%s' because their status is '%s'.", $subscriber->getId(), $subscriber->getStatus())); } $segmentSubject = $workflowRun->requireSingleSubject(SegmentSubject::class); $segmentId = $segmentSubject->getSegment()->getId(); $subscriberSegment = $this->subscriberSegmentRepository->findOneBy([ 'subscriber' => $subscriber, 'segment' => $segmentId, 'status' => SubscriberEntity::STATUS_SUBSCRIBED, ]); if ($subscriberSegment === null) { throw InvalidStateException::create()->withMessage(sprintf("Subscriber ID '%s' is not subscribed to segment ID '%s'.", $subscriber->getId(), $segmentId)); } $previouslyScheduledNotification = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($newsletter, (int)$subscriber->getId()); if (!empty($previouslyScheduledNotification)) { throw InvalidStateException::create()->withMessage(sprintf("Subscriber ID '%s' was already scheduled to receive newsletter ID '%s'.", $subscriber->getId(), $newsletter->getId())); } try { $this->automationEmailScheduler->createSendingTask($newsletter, $subscriber); } catch (Throwable $e) { throw InvalidStateException::create()->withMessage('Could not create sending task.'); } } public function saveEmailSettings(Step $step): void { $args = $step->getArgs(); if (!isset($args['email_id'])) { return; } $email = $this->getEmailForStep($step); $email->setSubject($args['subject'] ?? ''); $email->setPreheader($args['preheader'] ?? ''); $email->setSenderName($args['sender_name'] ?? ''); $email->setSenderAddress($args['sender_address'] ?? ''); $email->setReplyToName($args['reply_to_name'] ?? ''); $email->setReplyToAddress($args['reply_to_address'] ?? ''); $email->setGaCampaign($args['ga_campaign'] ?? ''); $this->newslettersRepository->flush(); } private function getEmailForStep(Step $step): NewsletterEntity { $emailId = $step->getArgs()['email_id'] ?? null; if (!$emailId) { throw InvalidStateException::create(); } $email = $this->newslettersRepository->findOneBy([ 'id' => $emailId, 'type' => NewsletterEntity::TYPE_AUTOMATION, ]); if (!$email) { throw InvalidStateException::create()->withMessage(sprintf("Automation email with ID '%s' not found.", $emailId)); } return $email; } }