| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- <?php
- namespace MailPoet\Entities;
- if (!defined('ABSPATH')) exit;
- use DateTimeInterface;
- use MailPoet\Doctrine\EntityTraits\AutoincrementedIdTrait;
- use MailPoet\Doctrine\EntityTraits\CreatedAtTrait;
- use MailPoet\Doctrine\EntityTraits\DeletedAtTrait;
- use MailPoet\Doctrine\EntityTraits\SafeToOneAssociationLoadTrait;
- use MailPoet\Doctrine\EntityTraits\UpdatedAtTrait;
- use MailPoet\Util\Helpers;
- use MailPoetVendor\Carbon\Carbon;
- use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection;
- use MailPoetVendor\Doctrine\Common\Collections\Collection;
- use MailPoetVendor\Doctrine\Common\Collections\Criteria;
- use MailPoetVendor\Doctrine\ORM\Mapping as ORM;
- use MailPoetVendor\Symfony\Component\Validator\Constraints as Assert;
- /**
- * @ORM\Entity()
- * @ORM\Table(name="newsletters")
- */
- class NewsletterEntity {
- // types
- const TYPE_AUTOMATIC = 'automatic';
- const TYPE_STANDARD = 'standard';
- const TYPE_WELCOME = 'welcome';
- const TYPE_NOTIFICATION = 'notification';
- const TYPE_NOTIFICATION_HISTORY = 'notification_history';
- const TYPE_WC_TRANSACTIONAL_EMAIL = 'wc_transactional';
- const TYPE_RE_ENGAGEMENT = 're_engagement';
- // standard newsletters
- const STATUS_DRAFT = 'draft';
- const STATUS_SCHEDULED = 'scheduled';
- const STATUS_SENDING = 'sending';
- const STATUS_SENT = 'sent';
- // automatic newsletters status
- const STATUS_ACTIVE = 'active';
- use AutoincrementedIdTrait;
- use CreatedAtTrait;
- use UpdatedAtTrait;
- use DeletedAtTrait;
- use SafeToOneAssociationLoadTrait;
- /**
- * @ORM\Column(type="string", nullable=true)
- * @var string|null
- */
- private $hash;
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $subject;
- /**
- * @ORM\Column(type="string")
- * @Assert\NotBlank()
- * @var string
- */
- private $type;
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $senderAddress = '';
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $senderName = '';
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $status = self::STATUS_DRAFT;
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $replyToAddress = '';
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $replyToName = '';
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $preheader = '';
- /**
- * @ORM\Column(type="json", nullable=true)
- * @var array|null
- */
- private $body;
- /**
- * @ORM\Column(type="datetimetz", nullable=true)
- * @var DateTimeInterface|null
- */
- private $sentAt;
- /**
- * @ORM\Column(type="string", nullable=true)
- * @var string|null
- */
- private $unsubscribeToken;
- /**
- * @ORM\Column(type="string")
- * @var string
- */
- private $gaCampaign = '';
- /**
- * @ORM\ManyToOne(targetEntity="MailPoet\Entities\NewsletterEntity")
- * @var NewsletterEntity|null
- */
- private $parent;
- /**
- * @ORM\OneToMany(targetEntity="MailPoet\Entities\NewsletterEntity", mappedBy="parent")
- * @var ArrayCollection<int, NewsletterEntity>
- */
- private $children;
- /**
- * @ORM\OneToMany(targetEntity="MailPoet\Entities\NewsletterSegmentEntity", mappedBy="newsletter", orphanRemoval=true)
- * @var ArrayCollection<int, NewsletterSegmentEntity>
- */
- private $newsletterSegments;
- /**
- * @ORM\OneToMany(targetEntity="MailPoet\Entities\NewsletterOptionEntity", mappedBy="newsletter", orphanRemoval=true)
- * @var ArrayCollection<int, NewsletterOptionEntity>
- */
- private $options;
- /**
- * @ORM\OneToMany(targetEntity="MailPoet\Entities\SendingQueueEntity", mappedBy="newsletter")
- * @var ArrayCollection<int, SendingQueueEntity>
- */
- private $queues;
- public function __construct() {
- $this->children = new ArrayCollection();
- $this->newsletterSegments = new ArrayCollection();
- $this->options = new ArrayCollection();
- $this->queues = new ArrayCollection();
- }
- /**
- * @deprecated This is here only for backward compatibility with custom shortcodes https://kb.mailpoet.com/article/160-create-a-custom-shortcode
- * This can be removed after 2021-08-01
- */
- public function __get($key) {
- $getterName = 'get' . Helpers::underscoreToCamelCase($key, $capitaliseFirstChar = true);
- $callable = [$this, $getterName];
- if (is_callable($callable)) {
- return call_user_func($callable);
- }
- }
- public function __clone() {
- // reset ID
- $this->id = null;
- }
- /**
- * @return string|null
- */
- public function getHash() {
- return $this->hash;
- }
- /**
- * @param string|null $hash
- */
- public function setHash($hash) {
- $this->hash = $hash;
- }
- /**
- * @return string
- */
- public function getSubject() {
- return $this->subject;
- }
- /**
- * @param string $subject
- */
- public function setSubject($subject) {
- $this->subject = $subject;
- }
- /**
- * @return string
- */
- public function getType() {
- return $this->type;
- }
- /**
- * @param string $type
- */
- public function setType($type) {
- $this->type = $type;
- }
- /**
- * @return string
- */
- public function getSenderAddress() {
- return $this->senderAddress;
- }
- /**
- * @param string $senderAddress
- */
- public function setSenderAddress($senderAddress) {
- $this->senderAddress = $senderAddress;
- }
- /**
- * @return string
- */
- public function getSenderName() {
- return $this->senderName;
- }
- /**
- * @param string $senderName
- */
- public function setSenderName($senderName) {
- $this->senderName = $senderName;
- }
- /**
- * @return string
- */
- public function getStatus() {
- return $this->status;
- }
- /**
- * @param string $status
- */
- public function setStatus($status) {
- $this->status = $status;
- // activate/deactivate unfinished tasks
- $newTaskStatus = null;
- $typesWithActivation = [self::TYPE_NOTIFICATION, self::TYPE_WELCOME, self::TYPE_AUTOMATIC];
- if (($status === self::STATUS_DRAFT) && in_array($this->type, $typesWithActivation)) {
- $newTaskStatus = ScheduledTaskEntity::STATUS_PAUSED;
- }
- if (($status === self::STATUS_ACTIVE) && in_array($this->type, $typesWithActivation)) {
- $newTaskStatus = ScheduledTaskEntity::STATUS_SCHEDULED;
- }
- if (!$newTaskStatus) return;
- $queues = $this->getUnfinishedQueues();
- foreach ($queues as $queue) {
- /** @var SendingQueueEntity $queue */
- $task = $queue->getTask();
- if ($task === null) continue;
- $scheduled = new Carbon($task->getScheduledAt());
- if ($scheduled < (new Carbon())->subDays(30)) continue;
- if (($status === self::STATUS_DRAFT) && ($task->getStatus() !== ScheduledTaskEntity::STATUS_SCHEDULED)) continue;
- if (($status === self::STATUS_ACTIVE) && ($task->getStatus() !== ScheduledTaskEntity::STATUS_PAUSED)) continue;
- $task->setStatus($newTaskStatus);
- }
- }
- /**
- * @return string
- */
- public function getReplyToAddress() {
- return $this->replyToAddress;
- }
- /**
- * @param string $replyToAddress
- */
- public function setReplyToAddress($replyToAddress) {
- $this->replyToAddress = $replyToAddress;
- }
- /**
- * @return string
- */
- public function getReplyToName() {
- return $this->replyToName;
- }
- /**
- * @param string $replyToName
- */
- public function setReplyToName($replyToName) {
- $this->replyToName = $replyToName;
- }
- /**
- * @return string
- */
- public function getPreheader() {
- return $this->preheader;
- }
- /**
- * @param string $preheader
- */
- public function setPreheader($preheader) {
- $this->preheader = $preheader;
- }
- /**
- * @return array|null
- */
- public function getBody() {
- return $this->body;
- }
- /**
- * @param array|null $body
- */
- public function setBody($body) {
- $this->body = $body;
- }
- /**
- * @return DateTimeInterface|null
- */
- public function getSentAt() {
- return $this->sentAt;
- }
- /**
- * @param DateTimeInterface|null $sentAt
- */
- public function setSentAt($sentAt) {
- $this->sentAt = $sentAt;
- }
- /**
- * @return string|null
- */
- public function getUnsubscribeToken() {
- return $this->unsubscribeToken;
- }
- /**
- * @return string
- */
- public function getGaCampaign() {
- return $this->gaCampaign;
- }
- /**
- * @param string $gaCampaign
- */
- public function setGaCampaign($gaCampaign) {
- $this->gaCampaign = $gaCampaign;
- }
- /**
- * @param string|null $unsubscribeToken
- */
- public function setUnsubscribeToken($unsubscribeToken) {
- $this->unsubscribeToken = $unsubscribeToken;
- }
- /**
- * @return NewsletterEntity|null
- */
- public function getParent() {
- $this->safelyLoadToOneAssociation('parent');
- return $this->parent;
- }
- /**
- * @param NewsletterEntity|null $parent
- */
- public function setParent($parent) {
- $this->parent = $parent;
- }
- /**
- * @return ArrayCollection<int, NewsletterEntity>
- */
- public function getChildren() {
- return $this->children;
- }
- /**
- * @return ArrayCollection<int, NewsletterSegmentEntity>
- */
- public function getNewsletterSegments() {
- return $this->newsletterSegments;
- }
- /**
- * @return ArrayCollection<int, NewsletterOptionEntity>
- */
- public function getOptions() {
- return $this->options;
- }
- public function getOption(string $name): ?NewsletterOptionEntity {
- $option = $this->options->filter(function (NewsletterOptionEntity $option) use ($name): bool {
- return ($field = $option->getOptionField()) ? $field->getName() === $name : false;
- })->first();
- return $option ?: null;
- }
- public function getOptionValue(string $name) {
- $option = $this->getOption($name);
- return $option ? $option->getValue() : null;
- }
- /**
- * @return ArrayCollection<int, SendingQueueEntity>
- */
- public function getQueues() {
- return $this->queues;
- }
- /**
- * @return SendingQueueEntity|null
- */
- public function getLatestQueue() {
- $criteria = new Criteria();
- $criteria->orderBy(['id' => Criteria::DESC]);
- $criteria->setMaxResults(1);
- return $this->queues->matching($criteria)->first() ?: null;
- }
- /**
- * @return Collection<int, SendingQueueEntity>
- */
- private function getUnfinishedQueues(): Collection {
- $criteria = new Criteria();
- $expr = Criteria::expr();
- $criteria->where($expr->neq('countToProcess', 0));
- return $this->queues->matching($criteria);
- }
- public function getGlobalStyle(string $category, string $style): ?string {
- $body = $this->getBody();
- if ($body === null) {
- return null;
- }
- return $body['globalStyles'][$category][$style] ?? null;
- }
- public function getProcessedAt(): ?DateTimeInterface {
- $processedAt = null;
- $queue = $this->getLatestQueue();
- if ($queue instanceof SendingQueueEntity) {
- $task = $queue->getTask();
- if ($task instanceof ScheduledTaskEntity) {
- $processedAt = $task->getProcessedAt();
- }
- }
- return $processedAt;
- }
- }
|