diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f17df61b..351ac54e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: main: name: phpList on PHP ${{ matrix.php-versions }} [Build, Test] - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: DB_DATABASE: phplist DB_USERNAME: root diff --git a/.github/workflows/core-docs.yml b/.github/workflows/core-docs.yml index a88fa4fe..dc3a5bdf 100644 --- a/.github/workflows/core-docs.yml +++ b/.github/workflows/core-docs.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: make-restapi-docs: name: Checkout phpList core and generate docs using `phpDocumentor` - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v3 @@ -41,7 +41,7 @@ jobs: path: phpdocumentor.zip deploy-docs: name: Deploy Core Docs - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: make-restapi-docs steps: - name: Checkout phplist/core-docs diff --git a/config/repositories.yml b/config/repositories.yml index 47cdbd07..2373b0dc 100644 --- a/config/repositories.yml +++ b/config/repositories.yml @@ -11,10 +11,10 @@ services: arguments: - PhpList\Core\Domain\Model\Identity\AdministratorToken - PhpList\Core\Domain\Repository\Messaging\SubscriberListRepository: + PhpList\Core\Domain\Repository\Subscription\SubscriberListRepository: parent: PhpList\Core\Domain\Repository arguments: - - PhpList\Core\Domain\Model\Messaging\SubscriberList + - PhpList\Core\Domain\Model\Subscription\SubscriberList PhpList\Core\Domain\Repository\Subscription\SubscriberRepository: parent: PhpList\Core\Domain\Repository @@ -25,3 +25,18 @@ services: parent: PhpList\Core\Domain\Repository arguments: - PhpList\Core\Domain\Model\Subscription\Subscription + + PhpList\Core\Domain\Repository\Messaging\MessageRepository: + parent: PhpList\Core\Domain\Repository + arguments: + - PhpList\Core\Domain\Model\Messaging\Message + + PhpList\Core\Domain\Repository\Messaging\TemplateRepository: + parent: PhpList\Core\Domain\Repository + arguments: + - PhpList\Core\Domain\Model\Messaging\Template + + PhpList\Core\Domain\Repository\Messaging\TemplateImageRepository: + parent: PhpList\Core\Domain\Repository + arguments: + - PhpList\Core\Domain\Model\Messaging\TemplateImage diff --git a/src/Domain/Filter/FilterRequestInterface.php b/src/Domain/Filter/FilterRequestInterface.php new file mode 100644 index 00000000..cfe3710a --- /dev/null +++ b/src/Domain/Filter/FilterRequestInterface.php @@ -0,0 +1,10 @@ +owner; + } + + public function setOwner(?Administrator $admin): self + { + $this->owner = $admin; + return $this; + } +} diff --git a/src/Domain/Filter/SubscriberFilter.php b/src/Domain/Filter/SubscriberFilter.php new file mode 100644 index 00000000..7fae293b --- /dev/null +++ b/src/Domain/Filter/SubscriberFilter.php @@ -0,0 +1,21 @@ +listId = $listId; + return $this; + } + + public function getListId(): ?int + { + return $this->listId; + } +} diff --git a/src/Domain/Model/Analytics/LinkTrackForward.php b/src/Domain/Model/Analytics/LinkTrackForward.php index 2b42bc93..213ff342 100644 --- a/src/Domain/Model/Analytics/LinkTrackForward.php +++ b/src/Domain/Model/Analytics/LinkTrackForward.php @@ -7,7 +7,6 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; use PhpList\Core\Domain\Repository\Analytics\LinkTrackForwardRepository; #[ORM\Entity(repositoryClass: LinkTrackForwardRepository::class)] @@ -17,7 +16,10 @@ #[ORM\Index(name: 'uuididx', columns: ['uuid'])] class LinkTrackForward implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(type: 'string', length: 2083, nullable: true)] private ?string $url = null; @@ -31,6 +33,11 @@ class LinkTrackForward implements DomainModel, Identity #[ORM\Column(type: 'boolean', nullable: true, options: ['default' => 0])] private bool $personalise = false; + public function getId(): ?int + { + return $this->id; + } + public function getUrl(): ?string { return $this->url; diff --git a/src/Domain/Model/Analytics/LinkTrackUmlClick.php b/src/Domain/Model/Analytics/LinkTrackUmlClick.php index 964a8c99..8cff6c1b 100644 --- a/src/Domain/Model/Analytics/LinkTrackUmlClick.php +++ b/src/Domain/Model/Analytics/LinkTrackUmlClick.php @@ -8,7 +8,6 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; use PhpList\Core\Domain\Repository\Analytics\LinkTrackUmlClickRepository; #[ORM\Entity(repositoryClass: LinkTrackUmlClickRepository::class)] @@ -19,7 +18,10 @@ #[ORM\Index(name: 'uidindex', columns: ['userid'])] class LinkTrackUmlClick implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'messageid', type: 'integer')] private int $messageId; @@ -45,6 +47,11 @@ class LinkTrackUmlClick implements DomainModel, Identity #[ORM\Column(name: 'textclicked', type: 'integer', nullable: true, options: ['default' => 0])] private ?int $textClicked = 0; + public function getId(): ?int + { + return $this->id; + } + public function getMessageId(): int { return $this->messageId; diff --git a/src/Domain/Model/Analytics/UserMessageView.php b/src/Domain/Model/Analytics/UserMessageView.php index 19a6bbc1..d933e545 100644 --- a/src/Domain/Model/Analytics/UserMessageView.php +++ b/src/Domain/Model/Analytics/UserMessageView.php @@ -8,16 +8,19 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Analytics\UserMessageViewRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UserMessageViewRepository::class)] #[ORM\Table(name: 'phplist_user_message_view')] #[ORM\Index(name: 'msgidx', columns: ['messageid'])] #[ORM\Index(name: 'useridx', columns: ['userid'])] #[ORM\Index(name: 'usermsgidx', columns: ['userid', 'messageid'])] class UserMessageView implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'messageid', type: 'integer')] private int $messageId; @@ -34,6 +37,11 @@ class UserMessageView implements DomainModel, Identity #[ORM\Column(name: 'data', type: 'text', nullable: true)] private ?string $data = null; + public function getId(): ?int + { + return $this->id; + } + public function getMessageId(): int { return $this->messageId; diff --git a/src/Domain/Model/Analytics/UserStats.php b/src/Domain/Model/Analytics/UserStats.php index 838b942e..4907bb52 100644 --- a/src/Domain/Model/Analytics/UserStats.php +++ b/src/Domain/Model/Analytics/UserStats.php @@ -7,9 +7,9 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Analytics\UserStatsRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UserStatsRepository::class)] #[ORM\Table(name: 'phplist_userstats')] #[ORM\UniqueConstraint(name: 'entry', columns: ['unixdate', 'item', 'listid'])] #[ORM\Index(name: 'dateindex', columns: ['unixdate'])] @@ -18,7 +18,10 @@ #[ORM\Index(name: 'listindex', columns: ['listid'])] class UserStats implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'unixdate', type: 'integer', nullable: true)] private ?int $unixDate = null; @@ -32,6 +35,11 @@ class UserStats implements DomainModel, Identity #[ORM\Column(name: 'value', type: 'integer', options: ['default' => 0])] private int $value = 0; + public function getId(): ?int + { + return $this->id; + } + public function getUnixDate(): ?int { return $this->unixDate; diff --git a/src/Domain/Model/Configuration/EventLog.php b/src/Domain/Model/Configuration/EventLog.php index d26ae733..426cbb80 100644 --- a/src/Domain/Model/Configuration/EventLog.php +++ b/src/Domain/Model/Configuration/EventLog.php @@ -8,7 +8,6 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; use PhpList\Core\Domain\Repository\Configuration\EventLogRepository; #[ORM\Entity(repositoryClass: EventLogRepository::class)] @@ -17,7 +16,10 @@ #[ORM\Index(name: 'pageidx', columns: ['page'])] class EventLog implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(type: 'datetime', nullable: true)] private ?DateTimeInterface $entered = null; @@ -28,7 +30,7 @@ class EventLog implements DomainModel, Identity #[ORM\Column(type: 'text', nullable: true)] private ?string $entry = null; - public function getId(): int + public function getId(): ?int { return $this->id; } diff --git a/src/Domain/Model/Configuration/UrlCache.php b/src/Domain/Model/Configuration/UrlCache.php index 5ea2f9eb..a53b68b6 100644 --- a/src/Domain/Model/Configuration/UrlCache.php +++ b/src/Domain/Model/Configuration/UrlCache.php @@ -8,14 +8,17 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Configuration\UrlCacheRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UrlCacheRepository::class)] #[ORM\Table(name: 'phplist_urlcache')] #[ORM\Index(name: 'urlindex', columns: ['url'])] class UrlCache implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'url', type: 'string', length: 2083)] private string $url; @@ -29,6 +32,11 @@ class UrlCache implements DomainModel, Identity #[ORM\Column(name: 'content', type: 'blob', nullable: true)] private ?string $content = null; + public function getId(): ?int + { + return $this->id; + } + public function getUrl(): string { return $this->url; diff --git a/src/Domain/Model/Identity/AdminAttribute.php b/src/Domain/Model/Identity/AdminAttribute.php index a3696bdb..be740895 100644 --- a/src/Domain/Model/Identity/AdminAttribute.php +++ b/src/Domain/Model/Identity/AdminAttribute.php @@ -7,7 +7,6 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; use PhpList\Core\Domain\Repository\Identity\AdminAttributeRepository; #[ORM\Entity(repositoryClass: AdminAttributeRepository::class)] @@ -15,7 +14,10 @@ #[ORM\HasLifecycleCallbacks] class AdminAttribute implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'name', type: 'string', length: 255)] private string $name; @@ -51,7 +53,7 @@ public function __construct( $this->tableName = $tableName; } - public function getId(): int + public function getId(): ?int { return $this->id; } @@ -86,33 +88,45 @@ public function getTableName(): ?string return $this->tableName; } - public function setName(string $name): void + public function setName(string $name): self { $this->name = $name; + + return $this; } - public function setType(?string $type): void + public function setType(?string $type): self { $this->type = $type; + + return $this; } - public function setListOrder(?int $listOrder): void + public function setListOrder(?int $listOrder): self { $this->listOrder = $listOrder; + + return $this; } - public function setDefaultValue(?string $defaultValue): void + public function setDefaultValue(?string $defaultValue): self { $this->defaultValue = $defaultValue; + + return $this; } - public function setRequired(?bool $required): void + public function setRequired(?bool $required): self { $this->required = $required; + + return $this; } - public function setTableName(?string $tableName): void + public function setTableName(?string $tableName): self { $this->tableName = $tableName; + + return $this; } } diff --git a/src/Domain/Model/Identity/AdminAttributeRelation.php b/src/Domain/Model/Identity/AdminAttributeRelation.php index 526156fe..454e8800 100644 --- a/src/Domain/Model/Identity/AdminAttributeRelation.php +++ b/src/Domain/Model/Identity/AdminAttributeRelation.php @@ -46,8 +46,10 @@ public function getValue(): ?string return $this->value; } - public function setValue(?string $value): void + public function setValue(?string $value): self { $this->value = $value; + + return $this; } } diff --git a/src/Domain/Model/Identity/AdminLogin.php b/src/Domain/Model/Identity/AdminLogin.php index d16bff16..a5afaebb 100644 --- a/src/Domain/Model/Identity/AdminLogin.php +++ b/src/Domain/Model/Identity/AdminLogin.php @@ -4,10 +4,11 @@ namespace PhpList\Core\Domain\Model\Identity; +use DateTimeImmutable; +use DateTimeInterface; use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; use PhpList\Core\Domain\Repository\Identity\AdminLoginRepository; #[ORM\Entity(repositoryClass: AdminLoginRepository::class)] @@ -15,10 +16,14 @@ #[ORM\HasLifecycleCallbacks] class AdminLogin implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; - #[ORM\Column(name: 'adminid', type: 'integer', options: ['unsigned' => true])] - private int $adminId; + #[ORM\ManyToOne(targetEntity: Administrator::class)] + #[ORM\JoinColumn(name: 'adminid', referencedColumnName: 'id', nullable: false)] + private Administrator $administrator; #[ORM\Column(name: 'moment', type: 'bigint')] private int $moment; @@ -26,43 +31,53 @@ class AdminLogin implements DomainModel, Identity #[ORM\Column(name: 'remote_ip4', type: 'string', length: 32)] private string $remoteIp4; - #[ORM\Column(name: 'remote_ip6', type: 'string', length:50)] + #[ORM\Column(name: 'remote_ip6', type: 'string', length: 50)] private string $remoteIp6; - #[ORM\Column(name: 'sessionid', type: 'string', length:50)] + #[ORM\Column(name: 'sessionid', type: 'string', length: 50)] private string $sessionId; #[ORM\Column(name: 'active', type: 'boolean')] private bool $active = false; public function __construct( - int $adminId, - int $moment, + Administrator $administrator, + DateTimeInterface $createdAt, string $remoteIp4, string $remoteIp6, string $sessionId, ) { - $this->adminId = $adminId; - $this->moment = $moment; + $this->administrator = $administrator; + $this->moment = $createdAt->getTimestamp(); $this->remoteIp4 = $remoteIp4; $this->remoteIp6 = $remoteIp6; $this->sessionId = $sessionId; } + public function getId(): ?int + { + return $this->id; + } + + public function isActive(): bool + { + return $this->active; + } + public function setActive(bool $active): self { $this->active = $active; - return $this; } - public function getAdminId(): int + + public function getAdministrator(): Administrator { - return $this->adminId; + return $this->administrator; } - public function getMoment(): int + public function getCreatedAt(): DateTimeInterface { - return $this->moment; + return (new DateTimeImmutable())->setTimestamp($this->moment); } public function getRemoteIp4(): string @@ -79,9 +94,4 @@ public function getSessionId(): string { return $this->sessionId; } - - public function isActive(): bool - { - return $this->active; - } } diff --git a/src/Domain/Model/Identity/AdminPasswordRequest.php b/src/Domain/Model/Identity/AdminPasswordRequest.php index 990b75d2..b2ae7bcb 100644 --- a/src/Domain/Model/Identity/AdminPasswordRequest.php +++ b/src/Domain/Model/Identity/AdminPasswordRequest.php @@ -23,16 +23,17 @@ class AdminPasswordRequest implements DomainModel, Identity #[ORM\Column(name: 'date', type: 'datetime', nullable: true)] private ?DateTime $date; - #[ORM\Column(name: 'admin', type: 'integer', nullable: true, options: ['unsigned' => true])] - private ?int $adminId; + #[ORM\ManyToOne(targetEntity: Administrator::class)] + #[ORM\JoinColumn(name: 'admin', referencedColumnName: 'id', nullable: true)] + private Administrator $administrator; #[ORM\Column(name: 'key_value', type: 'string', length: 32)] private string $keyValue; - public function __construct(?DateTime $date, ?int $adminId, string $keyValue) + public function __construct(?DateTime $date, Administrator $admin, string $keyValue) { $this->date = $date; - $this->adminId = $adminId; + $this->administrator = $admin; $this->keyValue = $keyValue; } @@ -46,9 +47,9 @@ public function getDate(): DateTime return $this->date; } - public function getAdminId(): int + public function getAdmin(): Administrator { - return $this->adminId; + return $this->administrator; } public function getKeyValue(): string diff --git a/src/Domain/Model/Identity/Administrator.php b/src/Domain/Model/Identity/Administrator.php index 8c56c367..9509269d 100644 --- a/src/Domain/Model/Identity/Administrator.php +++ b/src/Domain/Model/Identity/Administrator.php @@ -10,9 +10,6 @@ use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; use PhpList\Core\Domain\Model\Interfaces\ModificationDate; -use PhpList\Core\Domain\Model\Traits\CreationDateTrait; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; -use PhpList\Core\Domain\Model\Traits\ModificationDateTrait; use PhpList\Core\Domain\Repository\Identity\AdministratorRepository; /** @@ -20,15 +17,23 @@ * selected lists (as the owner), send campaigns to these lists and edit subscribers. * * @author Oliver Klee + * @author Tatevik Grigoryan */ #[ORM\Entity(repositoryClass: AdministratorRepository::class)] #[ORM\Table(name: 'phplist_admin')] #[ORM\HasLifecycleCallbacks] class Administrator implements DomainModel, Identity, CreationDate, ModificationDate { - use IdentityTrait; - use CreationDateTrait; - use ModificationDateTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; + + #[ORM\Column(name: 'created', type: 'datetime')] + protected DateTime $createdAt; + + #[ORM\Column(name: 'modified', type: 'datetime')] + private ?DateTime $updatedAt; #[ORM\Column(name: 'loginname')] private string $loginName; @@ -37,13 +42,10 @@ class Administrator implements DomainModel, Identity, CreationDate, Modification private string $namelc; #[ORM\Column(name: 'email')] - private string $emailAddress; - - #[ORM\Column(name: 'created', type: 'datetime')] - protected ?DateTime $creationDate = null; + private string $email; #[ORM\Column(name: 'modifiedby', type: 'string', length: 66, nullable: true)] - protected ?string $modifiedBy; + private ?string $modifiedBy; #[ORM\Column(name: 'password')] private string $passwordHash; @@ -67,8 +69,9 @@ public function __construct() $this->passwordChangeDate = null; $this->loginName = ''; $this->passwordHash = ''; - $this->modificationDate = null; - $this->emailAddress = ''; + $this->createdAt = new DateTime(); + $this->updatedAt = null; + $this->email = ''; } public function getLoginName(): string @@ -76,19 +79,23 @@ public function getLoginName(): string return $this->loginName; } - public function setLoginName(string $loginName): void + public function setLoginName(string $loginName): self { $this->loginName = $loginName; + + return $this; } - public function getEmailAddress(): string + public function getEmail(): string { - return $this->emailAddress; + return $this->email; } - public function setEmailAddress(string $emailAddress): void + public function setEmail(string $email): self { - $this->emailAddress = $emailAddress; + $this->email = $email; + + return $this; } public function getPasswordHash(): string @@ -96,10 +103,12 @@ public function getPasswordHash(): string return $this->passwordHash; } - public function setPasswordHash(string $passwordHash): void + public function setPasswordHash(string $passwordHash): self { $this->passwordHash = $passwordHash; - $this->setPasswordChangeDate(new DateTime()); + $this->passwordChangeDate = new DateTime(); + + return $this; } public function getPasswordChangeDate(): ?DateTime @@ -107,19 +116,16 @@ public function getPasswordChangeDate(): ?DateTime return $this->passwordChangeDate; } - private function setPasswordChangeDate(DateTime $changeDate): void - { - $this->passwordChangeDate = $changeDate; - } - public function isDisabled(): bool { return $this->disabled; } - public function setDisabled(bool $disabled): void + public function setDisabled(bool $disabled): self { $this->disabled = $disabled; + + return $this; } public function isSuperUser(): bool @@ -127,14 +133,18 @@ public function isSuperUser(): bool return $this->superUser; } - public function setSuperUser(bool $superUser): void + public function setSuperUser(bool $superUser): self { $this->superUser = $superUser; + + return $this; } - public function setNameLc(string $nameLc): void + public function setNameLc(string $nameLc): self { $this->namelc = $nameLc; + + return $this; } public function getNameLc(): string @@ -142,13 +152,50 @@ public function getNameLc(): string return $this->namelc; } - public function setPrivileges(string $privileges): void + public function setPrivileges(string $privileges): self { $this->privileges = $privileges; + + return $this; } public function getPrivileges(): string { return $this->privileges; } + + public function getCreatedAt(): ?DateTime + { + return $this->createdAt; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getUpdatedAt(): ?DateTime + { + return $this->updatedAt; + } + + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateUpdatedAt(): DomainModel + { + $this->updatedAt = new DateTime(); + + return $this; + } + + public function setModifiedBy(?string $modifiedBy): self + { + $this->modifiedBy = $modifiedBy; + return $this; + } + + public function getModifiedBy(): ?string + { + return $this->modifiedBy; + } } diff --git a/src/Domain/Model/Identity/AdministratorToken.php b/src/Domain/Model/Identity/AdministratorToken.php index 43c57bbd..abac6261 100644 --- a/src/Domain/Model/Identity/AdministratorToken.php +++ b/src/Domain/Model/Identity/AdministratorToken.php @@ -9,29 +9,30 @@ use Doctrine\ORM\Mapping as ORM; use Doctrine\Persistence\Proxy; use PhpList\Core\Domain\Repository\Identity\AdministratorTokenRepository; -use Symfony\Component\Serializer\Annotation\Ignore; use Symfony\Component\Serializer\Annotation\SerializedName; use PhpList\Core\Domain\Model\Interfaces\CreationDate; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; /** * This class represents an API authentication token for an administrator. * @author Oliver Klee + * @author Tateik Grigoryan */ #[ORM\Entity(repositoryClass: AdministratorTokenRepository::class)] #[ORM\Table(name: 'phplist_admintoken')] #[ORM\HasLifecycleCallbacks] class AdministratorToken implements DomainModel, Identity, CreationDate { - use IdentityTrait; - public const DEFAULT_EXPIRY = '+1 hour'; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; + #[ORM\Column(name: 'entered', type: 'integer')] - #[Ignore] - protected int $creationDate = 0; + protected int $createdAt = 0; #[ORM\Column(name: 'expires', type: 'datetime')] #[SerializedName('expiry_date')] @@ -43,7 +44,6 @@ class AdministratorToken implements DomainModel, Identity, CreationDate #[ORM\ManyToOne(targetEntity: Administrator::class)] #[ORM\JoinColumn(name: 'adminid')] - #[Ignore] private ?Administrator $administrator = null; public function __construct() @@ -51,27 +51,28 @@ public function __construct() $this->setExpiry(new DateTime()); } - public function getCreationDate(): ?DateTime + public function getId(): ?int + { + return $this->id; + } + + public function getCreatedAt(): ?DateTime { - if ($this->creationDate === 0) { + if ($this->createdAt === 0) { return null; } $date = new DateTime(); - $date->setTimestamp($this->creationDate); + $date->setTimestamp($this->createdAt); $date->setTimezone(new DateTimeZone('UTC')); return $date; } - private function setCreationDate(DateTime $creationDate): void - { - $this->creationDate = $creationDate->getTimestamp(); - } - #[ORM\PrePersist] - public function updateCreationDate(): void + public function updateCreatedAt(): DomainModel { - $this->setCreationDate(new DateTime()); + $this->createdAt = (new DateTime())->getTimestamp(); + return $this; } public function getExpiry(): DateTime @@ -84,9 +85,11 @@ private function setExpiry(DateTime $expiry): void $this->expiry = $expiry; } - public function generateExpiry(): void + public function generateExpiry(): self { $this->setExpiry(new DateTime(static::DEFAULT_EXPIRY)); + + return $this; } public function getKey(): string @@ -94,15 +97,19 @@ public function getKey(): string return $this->key; } - public function setKey(string $key): void + public function setKey(string $key): self { $this->key = $key; + + return $this; } - public function generateKey(): void + public function generateKey(): self { $key = md5(random_bytes(256)); $this->setKey($key); + + return $this; } public function getAdministrator(): Administrator|Proxy|null @@ -110,8 +117,9 @@ public function getAdministrator(): Administrator|Proxy|null return $this->administrator; } - public function setAdministrator(Administrator $administrator): void + public function setAdministrator(Administrator $administrator): self { $this->administrator = $administrator; + return $this; } } diff --git a/src/Domain/Model/Identity/UserBlacklist.php b/src/Domain/Model/Identity/UserBlacklist.php index 3c352aa4..b0b60e9d 100644 --- a/src/Domain/Model/Identity/UserBlacklist.php +++ b/src/Domain/Model/Identity/UserBlacklist.php @@ -7,8 +7,9 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; +use PhpList\Core\Domain\Repository\Identity\UserBlacklistRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UserBlacklistRepository::class)] #[ORM\Table(name: 'phplist_user_blacklist')] #[ORM\Index(name: 'emailidx', columns: ['email'])] class UserBlacklist implements DomainModel diff --git a/src/Domain/Model/Identity/UserBlacklistData.php b/src/Domain/Model/Identity/UserBlacklistData.php index 76e1ca61..bfb2e1e9 100644 --- a/src/Domain/Model/Identity/UserBlacklistData.php +++ b/src/Domain/Model/Identity/UserBlacklistData.php @@ -6,8 +6,9 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; +use PhpList\Core\Domain\Repository\Identity\UserBlacklistDataRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UserBlacklistDataRepository::class)] #[ORM\Table(name: 'phplist_user_blacklist_data')] #[ORM\Index(name: 'emailidx', columns: ['email'])] #[ORM\Index(name: 'emailnameidx', columns: ['email', 'name'])] diff --git a/src/Domain/Model/Interfaces/CreationDate.php b/src/Domain/Model/Interfaces/CreationDate.php index 41a6f9ad..813970f1 100644 --- a/src/Domain/Model/Interfaces/CreationDate.php +++ b/src/Domain/Model/Interfaces/CreationDate.php @@ -13,20 +13,12 @@ * The CreationDateTrait is the default implementation. * * @author Oliver Klee + * @author Tatevik Grigoryan */ interface CreationDate { /** * @return DateTime|null */ - public function getCreationDate(): ?DateTime; - - /** - * Updates the creation date to now. - * - * @PrePersist - * - * @return void - */ - public function updateCreationDate(): void; + public function getCreatedAt(): ?DateTime; } diff --git a/src/Domain/Model/Interfaces/EmbeddableInterface.php b/src/Domain/Model/Interfaces/EmbeddableInterface.php new file mode 100644 index 00000000..92524b7a --- /dev/null +++ b/src/Domain/Model/Interfaces/EmbeddableInterface.php @@ -0,0 +1,10 @@ +size = $size; } + public function getId(): ?int + { + return $this->id; + } + public function getFilename(): ?string { return $this->filename; } - public function setFilename(?string $filename): void + public function setFilename(?string $filename): self { $this->filename = $filename; + return $this; } public function getRemoteFile(): ?string @@ -60,9 +68,10 @@ public function getRemoteFile(): ?string return $this->remoteFile; } - public function setRemoteFile(?string $remoteFile): void + public function setRemoteFile(?string $remoteFile): self { $this->remoteFile = $remoteFile; + return $this; } public function getMimeType(): ?string @@ -70,9 +79,10 @@ public function getMimeType(): ?string return $this->mimeType; } - public function setMimeType(?string $mimeType): void + public function setMimeType(?string $mimeType): self { $this->mimeType = $mimeType; + return $this; } public function getDescription(): ?string @@ -80,9 +90,10 @@ public function getDescription(): ?string return $this->description; } - public function setDescription(?string $description): void + public function setDescription(?string $description): self { $this->description = $description; + return $this; } public function getSize(): ?int @@ -90,8 +101,9 @@ public function getSize(): ?int return $this->size; } - public function setSize(?int $size): void + public function setSize(?int $size): self { $this->size = $size; + return $this; } } diff --git a/src/Domain/Model/Messaging/Bounce.php b/src/Domain/Model/Messaging/Bounce.php index 3a4c0668..5611f9b5 100644 --- a/src/Domain/Model/Messaging/Bounce.php +++ b/src/Domain/Model/Messaging/Bounce.php @@ -8,7 +8,6 @@ use DateTime; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; use PhpList\Core\Domain\Repository\Messaging\BounceRepository; #[ORM\Entity(repositoryClass: BounceRepository::class)] @@ -17,7 +16,10 @@ #[ORM\Index(name: 'statusidx', columns: ['status'])] class Bounce implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(type: 'datetime', nullable: true)] private ?DateTime $date; @@ -48,7 +50,7 @@ public function __construct( $this->comment = $comment; } - public function getId(): int + public function getId(): ?int { return $this->id; } @@ -58,9 +60,10 @@ public function getDate(): ?DateTime return $this->date; } - public function setDate(?DateTime $date): void + public function setDate(?DateTime $date): self { $this->date = $date; + return $this; } public function getHeader(): ?string @@ -68,9 +71,10 @@ public function getHeader(): ?string return $this->header; } - public function setHeader(?string $header): void + public function setHeader(?string $header): self { $this->header = $header; + return $this; } public function getData(): ?string @@ -78,9 +82,10 @@ public function getData(): ?string return $this->data; } - public function setData(?string $data): void + public function setData(?string $data): self { $this->data = $data; + return $this; } public function getStatus(): ?string @@ -88,9 +93,10 @@ public function getStatus(): ?string return $this->status; } - public function setStatus(?string $status): void + public function setStatus(?string $status): self { $this->status = $status; + return $this; } public function getComment(): ?string @@ -98,8 +104,9 @@ public function getComment(): ?string return $this->comment; } - public function setComment(?string $comment): void + public function setComment(?string $comment): self { $this->comment = $comment; + return $this; } } diff --git a/src/Domain/Model/Messaging/BounceRegex.php b/src/Domain/Model/Messaging/BounceRegex.php index d5179b99..88da280b 100644 --- a/src/Domain/Model/Messaging/BounceRegex.php +++ b/src/Domain/Model/Messaging/BounceRegex.php @@ -7,7 +7,6 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; use PhpList\Core\Domain\Repository\Messaging\BounceRegexRepository; #[ORM\Entity(repositoryClass: BounceRegexRepository::class)] @@ -15,7 +14,10 @@ #[ORM\UniqueConstraint(name: 'regex', columns: ['regexhash'])] class BounceRegex implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(type: 'string', length: 2083, nullable: true)] private ?string $regex; @@ -61,7 +63,7 @@ public function __construct( $this->count = $count; } - public function getId(): int + public function getId(): ?int { return $this->id; } @@ -71,9 +73,10 @@ public function getRegex(): ?string return $this->regex; } - public function setRegex(?string $regex): void + public function setRegex(?string $regex): self { $this->regex = $regex; + return $this; } public function getRegexHash(): ?string @@ -81,9 +84,10 @@ public function getRegexHash(): ?string return $this->regexHash; } - public function setRegexHash(?string $regexHash): void + public function setRegexHash(?string $regexHash): self { $this->regexHash = $regexHash; + return $this; } public function getAction(): ?string @@ -91,9 +95,10 @@ public function getAction(): ?string return $this->action; } - public function setAction(?string $action): void + public function setAction(?string $action): self { $this->action = $action; + return $this; } public function getListOrder(): ?int @@ -101,9 +106,10 @@ public function getListOrder(): ?int return $this->listOrder; } - public function setListOrder(?int $listOrder): void + public function setListOrder(?int $listOrder): self { $this->listOrder = $listOrder; + return $this; } public function getAdmin(): ?int @@ -111,9 +117,10 @@ public function getAdmin(): ?int return $this->admin; } - public function setAdmin(?int $admin): void + public function setAdmin(?int $admin): self { $this->admin = $admin; + return $this; } public function getComment(): ?string @@ -121,9 +128,10 @@ public function getComment(): ?string return $this->comment; } - public function setComment(?string $comment): void + public function setComment(?string $comment): self { $this->comment = $comment; + return $this; } public function getStatus(): ?string @@ -131,9 +139,10 @@ public function getStatus(): ?string return $this->status; } - public function setStatus(?string $status): void + public function setStatus(?string $status): self { $this->status = $status; + return $this; } public function getCount(): ?int @@ -141,8 +150,9 @@ public function getCount(): ?int return $this->count; } - public function setCount(?int $count): void + public function setCount(?int $count): self { $this->count = $count; + return $this; } } diff --git a/src/Domain/Model/Messaging/BounceRegexBounce.php b/src/Domain/Model/Messaging/BounceRegexBounce.php index 76967704..f36a9f31 100644 --- a/src/Domain/Model/Messaging/BounceRegexBounce.php +++ b/src/Domain/Model/Messaging/BounceRegexBounce.php @@ -6,9 +6,9 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; -use PhpList\Core\Domain\Repository\Messaging\BounceRepository; +use PhpList\Core\Domain\Repository\Messaging\BounceRegexBounceRepository; -#[ORM\Entity(repositoryClass: BounceRepository::class)] +#[ORM\Entity(repositoryClass: BounceRegexBounceRepository::class)] #[ORM\Table(name: 'phplist_bounceregex_bounce')] class BounceRegexBounce implements DomainModel { @@ -31,9 +31,10 @@ public function getRegex(): int return $this->regex; } - public function setRegex(int $regex): void + public function setRegex(int $regex): self { $this->regex = $regex; + return $this; } public function getBounce(): int @@ -41,8 +42,9 @@ public function getBounce(): int return $this->bounce; } - public function setBounce(int $bounce): void + public function setBounce(int $bounce): self { $this->bounce = $bounce; + return $this; } } diff --git a/src/Domain/Model/Messaging/ListMessage.php b/src/Domain/Model/Messaging/ListMessage.php index b587d8b3..52a4dff0 100644 --- a/src/Domain/Model/Messaging/ListMessage.php +++ b/src/Domain/Model/Messaging/ListMessage.php @@ -10,8 +10,6 @@ use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; use PhpList\Core\Domain\Model\Interfaces\ModificationDate; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; -use PhpList\Core\Domain\Model\Traits\ModificationDateTrait; use PhpList\Core\Domain\Repository\Messaging\ListMessageRepository; #[ORM\Entity(repositoryClass: ListMessageRepository::class)] @@ -21,8 +19,10 @@ #[ORM\HasLifecycleCallbacks] class ListMessage implements DomainModel, Identity, ModificationDate { - use IdentityTrait; - use ModificationDateTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'messageid', type: 'integer')] private int $messageId; @@ -30,9 +30,17 @@ class ListMessage implements DomainModel, Identity, ModificationDate #[ORM\Column(name: 'listid', type: 'integer')] private int $listId; - #[ORM\Column(type: 'datetime', nullable: true)] + #[ORM\Column(name: 'entered', type: 'datetime', nullable: true)] private ?DateTimeInterface $entered = null; + #[ORM\Column(name: 'modified', type: 'datetime')] + private ?DateTime $updatedAt = null; + + public function getId(): ?int + { + return $this->id; + } + public function getMessageId(): int { return $this->messageId; @@ -65,4 +73,18 @@ public function setEntered(?DateTimeInterface $entered): self $this->entered = $entered; return $this; } + + public function getUpdatedAt(): ?DateTime + { + return $this->updatedAt; + } + + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateUpdatedAt(): DomainModel + { + $this->updatedAt = new DateTime(); + + return $this; + } } diff --git a/src/Domain/Model/Messaging/Message.php b/src/Domain/Model/Messaging/Message.php new file mode 100644 index 00000000..278b2f6e --- /dev/null +++ b/src/Domain/Model/Messaging/Message.php @@ -0,0 +1,179 @@ + ''])] + private ?string $uuid = ''; + + #[ORM\ManyToOne(targetEntity: Administrator::class)] + #[ORM\JoinColumn(name: 'owner', referencedColumnName: 'id', nullable: true)] + private ?Administrator $owner; + + #[ORM\ManyToOne(targetEntity: Template::class)] + #[ORM\JoinColumn(name: 'template', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')] + private ?Template $template = null; + + public function __construct( + MessageFormat $format, + MessageSchedule $schedule, + MessageMetadata $metadata, + MessageContent $content, + MessageOptions $options, + ?Administrator $owner, + ?Template $template = null, + ) { + $this->format = $format; + $this->schedule = $schedule; + $this->metadata = $metadata; + $this->content = $content; + $this->options = $options; + $this->uuid = bin2hex(random_bytes(18)); + $this->owner = $owner; + $this->template = $template; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getUpdatedAt(): ?DateTime + { + return $this->updatedAt; + } + + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateUpdatedAt(): DomainModel + { + $this->updatedAt = new DateTime(); + + return $this; + } + + public function getFormat(): MessageFormat + { + return $this->format; + } + + public function getSchedule(): MessageSchedule + { + return $this->schedule; + } + + public function getMetadata(): MessageMetadata + { + return $this->metadata; + } + + public function getContent(): MessageContent + { + return $this->content; + } + + public function getOptions(): MessageOptions + { + return $this->options; + } + + public function getUuid(): ?string + { + return $this->uuid; + } + + public function getOwner(): ?Administrator + { + return $this->owner; + } + + public function setOwner(?Administrator $owner): self + { + $this->owner = $owner; + return $this; + } + + public function getTemplate(): ?Template + { + return $this->template; + } + + public function setTemplate(?Template $template): self + { + $this->template = $template; + return $this; + } + + public function setFormat(MessageFormat $format): self + { + $this->format = $format; + return $this; + } + + public function setSchedule(MessageSchedule $schedule): self + { + $this->schedule = $schedule; + return $this; + } + + public function setMetadata(MessageMetadata $metadata): self + { + $this->metadata = $metadata; + return $this; + } + + public function setContent(MessageContent $content): self + { + $this->content = $content; + return $this; + } + + public function setOptions(MessageOptions $options): self + { + $this->options = $options; + return $this; + } +} diff --git a/src/Domain/Model/Messaging/Message/Message.php b/src/Domain/Model/Messaging/Message/Message.php deleted file mode 100644 index a2285dab..00000000 --- a/src/Domain/Model/Messaging/Message/Message.php +++ /dev/null @@ -1,87 +0,0 @@ - ''])] - private ?string $uuid = ''; - - public function __construct( - MessageFormat $format, - MessageSchedule $schedule, - MessageMetadata $metadata, - MessageContent $content, - MessageOptions $options - ) { - $this->format = $format; - $this->schedule = $schedule; - $this->metadata = $metadata; - $this->content = $content; - $this->options = $options; - $this->uuid = bin2hex(random_bytes(18)); - } - - public function getFormat(): MessageFormat - { - return $this->format; - } - - public function getSchedule(): MessageSchedule - { - return $this->schedule; - } - - public function getMetadata(): MessageMetadata - { - return $this->metadata; - } - - public function getContent(): MessageContent - { - return $this->content; - } - - public function getOptions(): MessageOptions - { - return $this->options; - } - - public function getUuid(): ?string - { - return $this->uuid; - } -} diff --git a/src/Domain/Model/Messaging/Message/MessageContent.php b/src/Domain/Model/Messaging/Message/MessageContent.php index 6474c4ec..b80580a6 100644 --- a/src/Domain/Model/Messaging/Message/MessageContent.php +++ b/src/Domain/Model/Messaging/Message/MessageContent.php @@ -5,14 +5,15 @@ namespace PhpList\Core\Domain\Model\Messaging\Message; use Doctrine\ORM\Mapping as ORM; +use PhpList\Core\Domain\Model\Interfaces\EmbeddableInterface; #[ORM\Embeddable] -class MessageContent +class MessageContent implements EmbeddableInterface { #[ORM\Column(type: 'string', length: 255, nullable: false, options: ['default' => '(no subject)'])] private string $subject; - #[ORM\Column(type: 'text', nullable: true)] + #[ORM\Column(name:'message', type: 'text', nullable: true)] private ?string $text = null; #[ORM\Column(name: 'textmessage', type: 'text', nullable: true)] @@ -60,8 +61,20 @@ public function getTextMessage(): ?string return $this->textMessage; } + public function setTextMessage(?string $textMessage): self + { + $this->textMessage = $textMessage; + return $this; + } + public function getFooter(): ?string { return $this->footer; } + + public function setFooter(?string $footer): self + { + $this->footer = $footer; + return $this; + } } diff --git a/src/Domain/Model/Messaging/Message/MessageFormat.php b/src/Domain/Model/Messaging/Message/MessageFormat.php index e4de42c4..90fc56f0 100644 --- a/src/Domain/Model/Messaging/Message/MessageFormat.php +++ b/src/Domain/Model/Messaging/Message/MessageFormat.php @@ -5,35 +5,46 @@ namespace PhpList\Core\Domain\Model\Messaging\Message; use Doctrine\ORM\Mapping as ORM; +use InvalidArgumentException; +use PhpList\Core\Domain\Model\Interfaces\EmbeddableInterface; #[ORM\Embeddable] -class MessageFormat +class MessageFormat implements EmbeddableInterface { - #[ORM\Column(type: 'boolean', options: ['default' => false])] + #[ORM\Column(name: 'htmlformatted', type: 'boolean', options: ['default' => false])] private bool $htmlFormatted = false; #[ORM\Column(name: 'sendformat', type: 'string', length: 20, nullable: true)] private ?string $sendFormat = null; #[ORM\Column(name: 'astext', type: 'integer', options: ['default' => 0])] - private int $asText = 0; + private bool $asText = false; #[ORM\Column(name: 'ashtml', type: 'integer', options: ['default' => 0])] - private int $asHtml = 0; - - #[ORM\Column(name: 'astextandhtml', type: 'integer', options: ['default' => 0])] - private int $asTextAndHtml = 0; + private bool $asHtml = false; #[ORM\Column(name: 'aspdf', type: 'integer', options: ['default' => 0])] - private int $asPdf = 0; + private bool $asPdf = false; + + #[ORM\Column(name: 'astextandhtml', type: 'integer', options: ['default' => 0])] + private bool $asTextAndHtml = false; #[ORM\Column(name: 'astextandpdf', type: 'integer', options: ['default' => 0])] - private int $asTextAndPdf = 0; + private bool $asTextAndPdf = false; - public function __construct(bool $htmlFormatted, ?string $sendFormat) - { + public const FORMAT_TEXT = 'text'; + public const FORMAT_HTML = 'html'; + public const FORMAT_PDF = 'pdf'; + + public function __construct( + bool $htmlFormatted, + ?string $sendFormat, + array $formatOptions = [] + ) { $this->htmlFormatted = $htmlFormatted; $this->sendFormat = $sendFormat; + + $this->setFormatOptions($formatOptions); } public function isHtmlFormatted(): bool @@ -41,39 +52,71 @@ public function isHtmlFormatted(): bool return $this->htmlFormatted; } + public function setHtmlFormatted(bool $htmlFormatted): self + { + $this->htmlFormatted = $htmlFormatted; + return $this; + } + public function getSendFormat(): ?string { return $this->sendFormat; } - public function getAsText(): int + public function setSendFormat(?string $sendFormat): self + { + $this->sendFormat = $sendFormat; + return $this; + } + + public function isAsText(): bool { return $this->asText; } - public function getAsHtml(): int + public function isAsHtml(): bool { return $this->asHtml; } - public function getAsTextAndHtml(): int + public function isAsTextAndHtml(): bool { return $this->asTextAndHtml; } - public function getAsPdf(): int + public function isAsPdf(): bool { return $this->asPdf; } - public function getAsTextAndPdf(): int + public function isAsTextAndPdf(): bool { return $this->asTextAndPdf; } - public function setSendFormat(?string $sendFormat): self + public function getFormatOptions(): array { - $this->sendFormat = $sendFormat; + return array_values(array_filter([ + $this->asText ? self::FORMAT_TEXT : null, + $this->asHtml ? self::FORMAT_HTML : null, + $this->asPdf ? self::FORMAT_PDF : null, + ])); + } + + public function setFormatOptions(array $formatOptions): self + { + foreach ($formatOptions as $option) { + match ($option) { + self::FORMAT_TEXT => $this->asText = true, + self::FORMAT_HTML => $this->asHtml = true, + self::FORMAT_PDF => $this->asPdf = true, + default => throw new InvalidArgumentException('Invalid format option: ' . $option) + }; + } + + $this->asTextAndHtml = $this->asText && $this->asHtml; + $this->asTextAndPdf = $this->asText && $this->asPdf; + return $this; } } diff --git a/src/Domain/Model/Messaging/Message/MessageMetadata.php b/src/Domain/Model/Messaging/Message/MessageMetadata.php index 6e2a52e0..3e4452a1 100644 --- a/src/Domain/Model/Messaging/Message/MessageMetadata.php +++ b/src/Domain/Model/Messaging/Message/MessageMetadata.php @@ -6,18 +6,19 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; +use PhpList\Core\Domain\Model\Interfaces\EmbeddableInterface; #[ORM\Embeddable] -class MessageMetadata +class MessageMetadata implements EmbeddableInterface { #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $status = null; - #[ORM\Column(type: 'integer', options: ['unsigned' => true, 'default' => 0])] - private int $processed; + #[ORM\Column(type: 'boolean', options: ['unsigned' => true, 'default' => false])] + private bool $processed; #[ORM\Column(type: 'integer', options: ['default' => 0])] - private int $viewed; + private int $viewed = 0; #[ORM\Column(name: 'bouncecount', type: 'integer', options: ['default' => 0])] private int $bounceCount; @@ -28,20 +29,23 @@ class MessageMetadata #[ORM\Column(type: 'datetime', nullable: true)] private ?DateTime $sent; + #[ORM\Column(name: 'sendstart', type: 'datetime', nullable: true)] + private ?DateTime $sendStart; + public function __construct( ?string $status = null, - int $processed = 0, - int $viewed = 0, int $bounceCount = 0, ?DateTime $entered = null, ?DateTime $sent = null, + ?DateTime $sendStart = null, ) { $this->status = $status; - $this->processed = $processed; - $this->viewed = $viewed; + $this->processed = false; + $this->viewed = 0; $this->bounceCount = $bounceCount; $this->entered = $entered ?? new DateTime(); $this->sent = $sent; + $this->sendStart = $sendStart; } public function getStatus(): ?string @@ -49,18 +53,30 @@ public function getStatus(): ?string return $this->status; } - public function getProcessed(): int + public function setStatus(string $status): self + { + $this->status = $status; + return $this; + } + + public function isProcessed(): bool { return $this->processed; } - public function setProcessed(int $processed): self + public function setProcessed(bool $processed): self { $this->processed = $processed; return $this; } - public function getViewed(): int + public function setViews(int $viewed): self + { + $this->viewed = $viewed; + return $this; + } + + public function getViews(): int { return $this->viewed; } @@ -79,4 +95,33 @@ public function getSent(): ?DateTime { return $this->sent; } + + public function setBounceCount(int $bounceCount): self + { + $this->bounceCount = $bounceCount; + return $this; + } + + public function setEntered(?DateTime $entered): self + { + $this->entered = $entered; + return $this; + } + + public function setSent(?DateTime $sent): self + { + $this->sent = $sent; + return $this; + } + + public function getSendStart(): ?DateTime + { + return $this->sendStart; + } + + public function setSendStart(?DateTime $sendStart): self + { + $this->sendStart = $sendStart; + return $this; + } } diff --git a/src/Domain/Model/Messaging/Message/MessageOptions.php b/src/Domain/Model/Messaging/Message/MessageOptions.php index 0c885528..002d3c9a 100644 --- a/src/Domain/Model/Messaging/Message/MessageOptions.php +++ b/src/Domain/Model/Messaging/Message/MessageOptions.php @@ -5,10 +5,10 @@ namespace PhpList\Core\Domain\Model\Messaging\Message; use Doctrine\ORM\Mapping as ORM; -use DateTime; +use PhpList\Core\Domain\Model\Interfaces\EmbeddableInterface; #[ORM\Embeddable] -class MessageOptions +class MessageOptions implements EmbeddableInterface { #[ORM\Column(name: 'fromfield', type: 'string', length: 255, nullable: false, options: ['default' => ''])] private string $fromField; @@ -19,44 +19,24 @@ class MessageOptions #[ORM\Column(name: 'replyto', type: 'string', length: 255, nullable: false, options: ['default' => ''])] private string $replyTo; - #[ORM\Column(type: 'datetime', nullable: true)] - private ?DateTime $embargo; - #[ORM\Column(name: 'userselection', type: 'text', nullable: true)] private ?string $userSelection; - #[ORM\Column(type: 'integer', nullable: true)] - private ?int $template; - - #[ORM\Column(name: 'sendstart', type: 'datetime', nullable: true)] - private ?DateTime $sendStart; - #[ORM\Column(name: 'rsstemplate', type: 'string', length: 100, nullable: true)] private ?string $rssTemplate; - #[ORM\Column(type: 'integer', nullable: true)] - private ?int $owner; - public function __construct( string $fromField = '', string $toField = '', string $replyTo = '', - ?DateTime $embargo = null, ?string $userSelection = null, - ?int $template = null, - ?DateTime $sendStart = null, - ?string $rssTemplate = null, - ?int $owner = null + ?string $rssTemplate = null ) { $this->fromField = $fromField; $this->toField = $toField; $this->replyTo = $replyTo; - $this->embargo = $embargo; $this->userSelection = $userSelection; - $this->template = $template; - $this->sendStart = $sendStart; $this->rssTemplate = $rssTemplate; - $this->owner = $owner; } public function getFromField(): string @@ -69,38 +49,48 @@ public function getToField(): string return $this->toField; } - public function getReplyToO(): string + public function getReplyTo(): string { return $this->replyTo; } - public function getEmbargo(): ?DateTime + public function getUserSelection(): ?string { - return $this->embargo; + return $this->userSelection; } - public function getUserSelection(): ?string + public function getRssTemplate(): ?string { - return $this->userSelection; + return $this->rssTemplate; } - public function getTemplate(): ?int + public function setFromField(string $fromField): self { - return $this->template; + $this->fromField = $fromField; + return $this; } - public function getSendStart(): ?DateTime + public function setToField(string $toField): self { - return $this->sendStart; + $this->toField = $toField; + return $this; } - public function getRssTemplate(): ?string + public function setReplyTo(string $replyTo): self { - return $this->rssTemplate; + $this->replyTo = $replyTo; + return $this; } - public function getOwner(): ?int + public function setUserSelection(?string $userSelection): self { - return $this->owner; + $this->userSelection = $userSelection; + return $this; + } + + public function setRssTemplate(?string $rssTemplate): self + { + $this->rssTemplate = $rssTemplate; + return $this; } } diff --git a/src/Domain/Model/Messaging/Message/MessageSchedule.php b/src/Domain/Model/Messaging/Message/MessageSchedule.php index 28b82c41..3448f8d1 100644 --- a/src/Domain/Model/Messaging/Message/MessageSchedule.php +++ b/src/Domain/Model/Messaging/Message/MessageSchedule.php @@ -6,9 +6,10 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; +use PhpList\Core\Domain\Model\Interfaces\EmbeddableInterface; #[ORM\Embeddable] -class MessageSchedule +class MessageSchedule implements EmbeddableInterface { #[ORM\Column(name: 'repeatinterval', type: 'integer', nullable: true, options: ['default' => 0])] private ?int $repeatInterval; @@ -22,16 +23,21 @@ class MessageSchedule #[ORM\Column(name: 'requeueuntil', type: 'datetime', nullable: true)] private ?DateTime $requeueUntil; + #[ORM\Column(type: 'datetime', nullable: true)] + private ?DateTime $embargo; + public function __construct( ?int $repeatInterval, ?DateTime $repeatUntil, ?int $requeueInterval, - ?DateTime $requeueUntil + ?DateTime $requeueUntil, + ?DateTime $embargo ) { $this->repeatInterval = $repeatInterval; $this->repeatUntil = $repeatUntil; $this->requeueInterval = $requeueInterval; $this->requeueUntil = $requeueUntil; + $this->embargo = $embargo; } public function getRepeatInterval(): ?int @@ -53,4 +59,39 @@ public function getRequeueUntil(): ?DateTime { return $this->requeueUntil; } + + public function getEmbargo(): ?DateTime + { + return $this->embargo; + } + + public function setRepeatInterval(?int $repeatInterval): self + { + $this->repeatInterval = $repeatInterval; + return $this; + } + + public function setRepeatUntil(?DateTime $repeatUntil): self + { + $this->repeatUntil = $repeatUntil; + return $this; + } + + public function setRequeueInterval(?int $requeueInterval): self + { + $this->requeueInterval = $requeueInterval; + return $this; + } + + public function setRequeueUntil(?DateTime $requeueUntil): self + { + $this->requeueUntil = $requeueUntil; + return $this; + } + + public function setEmbargo(?DateTime $embargo): self + { + $this->embargo = $embargo; + return $this; + } } diff --git a/src/Domain/Model/Messaging/MessageAttachment.php b/src/Domain/Model/Messaging/MessageAttachment.php index a4baaf84..1f65656e 100644 --- a/src/Domain/Model/Messaging/MessageAttachment.php +++ b/src/Domain/Model/Messaging/MessageAttachment.php @@ -6,15 +6,18 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Messaging\MessageAttachmentRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: MessageAttachmentRepository::class)] #[ORM\Table(name: 'phplist_message_attachment')] #[ORM\Index(name: 'messageattidx', columns: ['messageid', 'attachmentid'])] #[ORM\Index(name: 'messageidx', columns: ['messageid'])] class MessageAttachment implements Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'messageid', type: 'integer')] private int $messageId; @@ -22,6 +25,11 @@ class MessageAttachment implements Identity #[ORM\Column(name: 'attachmentid', type: 'integer')] private int $attachmentId; + public function getId(): ?int + { + return $this->id; + } + public function getMessageId(): int { return $this->messageId; diff --git a/src/Domain/Model/Messaging/MessageData.php b/src/Domain/Model/Messaging/MessageData.php index 8daedeb7..686436f4 100644 --- a/src/Domain/Model/Messaging/MessageData.php +++ b/src/Domain/Model/Messaging/MessageData.php @@ -6,8 +6,9 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; +use PhpList\Core\Domain\Repository\Messaging\MessageDataRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: MessageDataRepository::class)] #[ORM\Table(name: 'phplist_messagedata')] class MessageData implements DomainModel { diff --git a/src/Domain/Model/Messaging/SendProcess.php b/src/Domain/Model/Messaging/SendProcess.php index 1db36238..0c86b941 100644 --- a/src/Domain/Model/Messaging/SendProcess.php +++ b/src/Domain/Model/Messaging/SendProcess.php @@ -9,16 +9,20 @@ use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; use PhpList\Core\Domain\Model\Interfaces\ModificationDate; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; -use PhpList\Core\Domain\Model\Traits\ModificationDateTrait; +use PhpList\Core\Domain\Repository\Messaging\SendProcessRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: SendProcessRepository::class)] #[ORM\Table(name: 'phplist_sendprocess')] #[ORM\HasLifecycleCallbacks] class SendProcess implements DomainModel, Identity, ModificationDate { - use IdentityTrait; - use ModificationDateTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; + + #[ORM\Column(name: 'modified', type: 'datetime')] + private ?DateTime $updatedAt = null; #[ORM\Column(name: 'started', type: 'datetime', nullable: true)] private ?DateTime $started = null; @@ -32,6 +36,25 @@ class SendProcess implements DomainModel, Identity, ModificationDate #[ORM\Column(name: 'page', type: 'string', length: 100, nullable: true)] private ?string $page = null; + public function getId(): ?int + { + return $this->id; + } + + public function getUpdatedAt(): ?DateTime + { + return $this->updatedAt; + } + + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateUpdatedAt(): DomainModel + { + $this->updatedAt = new DateTime(); + + return $this; + } + public function getStartedDate(): ?DateTime { return $this->started; diff --git a/src/Domain/Model/Messaging/Template.php b/src/Domain/Model/Messaging/Template.php index 3236f64c..420ba9bc 100644 --- a/src/Domain/Model/Messaging/Template.php +++ b/src/Domain/Model/Messaging/Template.php @@ -9,23 +9,26 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Messaging\TemplateRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: TemplateRepository::class)] #[ORM\Table(name: 'phplist_template')] #[ORM\UniqueConstraint(name: 'title', columns: ['title'])] class Template implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'title', type: 'string', length: 255, unique: true)] private string $title; #[ORM\Column(name: 'template', type: 'blob', nullable: true)] - private ?string $template = null; + private mixed $content; #[ORM\Column(name: 'template_text', type: 'blob', nullable: true)] - private ?string $templateText = null; + private mixed $text; #[ORM\Column(name: 'listorder', type: 'integer', nullable: true)] private ?int $listOrder = null; @@ -38,24 +41,40 @@ class Template implements DomainModel, Identity )] private Collection $images; - public function __construct() + public function __construct(string $title) { + $this->title = $title; $this->images = new ArrayCollection(); } + public function getId(): ?int + { + return $this->id; + } + public function getTitle(): string { return $this->title; } - public function getTemplate(): ?string + public function getContent(): ?string { - return $this->template; + if (is_resource($this->content)) { + rewind($this->content); + return stream_get_contents($this->content); + } + + return $this->content; } - public function getTemplateText(): ?string + public function getText(): ?string { - return $this->templateText; + if (is_resource($this->text)) { + rewind($this->text); + return stream_get_contents($this->text); + } + + return $this->text; } public function getListOrder(): ?int @@ -74,15 +93,16 @@ public function setTitle(string $title): self return $this; } - public function setTemplate(?string $template): self + public function setContent(?string $content): self { - $this->template = $template; + $this->content = $content !== null ? fopen('data://text/plain,' . $content, 'r') : null; return $this; } - public function setTemplateText(?string $templateText): self + + public function setText(?string $text): self { - $this->templateText = $templateText; + $this->text = $text !== null ? fopen('data://text/plain,' . $text, 'r') : null; return $this; } diff --git a/src/Domain/Model/Messaging/TemplateImage.php b/src/Domain/Model/Messaging/TemplateImage.php index dd95f89d..09ff6b2e 100644 --- a/src/Domain/Model/Messaging/TemplateImage.php +++ b/src/Domain/Model/Messaging/TemplateImage.php @@ -7,14 +7,18 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Messaging\TemplateImageRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: TemplateImageRepository::class)] #[ORM\Table(name: 'phplist_templateimage')] #[ORM\Index(name: 'templateidx', columns: ['template'])] class TemplateImage implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; + #[ORM\ManyToOne(targetEntity: Template::class)] #[ORM\JoinColumn(name: 'template', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] private Template $template; @@ -26,7 +30,7 @@ class TemplateImage implements DomainModel, Identity private ?string $filename = null; #[ORM\Column(name: 'data', type: 'blob', nullable: true)] - private ?string $data = null; + private mixed $data = null; #[ORM\Column(name: 'width', type: 'integer', nullable: true)] private ?int $width = null; @@ -34,6 +38,11 @@ class TemplateImage implements DomainModel, Identity #[ORM\Column(name: 'height', type: 'integer', nullable: true)] private ?int $height = null; + public function getId(): ?int + { + return $this->id; + } + public function getTemplate(): ?Template { return $this->template; @@ -51,6 +60,11 @@ public function getFilename(): ?string public function getData(): ?string { + if (is_resource($this->data)) { + rewind($this->data); + return stream_get_contents($this->data); + } + return $this->data; } @@ -84,7 +98,7 @@ public function setFilename(?string $filename): self public function setData(?string $data): self { - $this->data = $data; + $this->data = $data !== null ? fopen('data://text/plain,' . $data, 'r') : null; return $this; } diff --git a/src/Domain/Model/Messaging/UserMessage.php b/src/Domain/Model/Messaging/UserMessage.php index f62dca24..fbe606fe 100644 --- a/src/Domain/Model/Messaging/UserMessage.php +++ b/src/Domain/Model/Messaging/UserMessage.php @@ -7,10 +7,10 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; -use PhpList\Core\Domain\Model\Messaging\Message\Message; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Repository\Messaging\UserMessageRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UserMessageRepository::class)] #[ORM\Table(name: 'phplist_usermessage')] #[ORM\Index(name: 'enteredindex', columns: ['entered'])] #[ORM\Index(name: 'messageidindex', columns: ['messageid'])] @@ -30,7 +30,7 @@ class UserMessage implements DomainModel private Message $message; #[ORM\Column(name: 'entered', type: 'datetime')] - private DateTime $entered; + private DateTime $createdAt; #[ORM\Column(name: 'viewed', type: 'datetime', nullable: true)] private ?DateTime $viewed = null; @@ -38,6 +38,13 @@ class UserMessage implements DomainModel #[ORM\Column(name: 'status', type: 'string', length: 255, nullable: true)] private ?string $status = null; + public function __construct(Subscriber $user, Message $message) + { + $this->user = $user; + $this->message = $message; + $this->createdAt = new DateTime(); + } + public function getUser(): Subscriber { return $this->user; @@ -48,9 +55,9 @@ public function getMessage(): Message return $this->message; } - public function getEntered(): DateTime + public function getCreatedAt(): DateTime { - return $this->entered; + return $this->createdAt; } public function getViewed(): ?DateTime @@ -63,24 +70,6 @@ public function getStatus(): ?string return $this->status; } - public function setUser(Subscriber $user): self - { - $this->user = $user; - return $this; - } - - public function setMessage(Message $message): self - { - $this->message = $message; - return $this; - } - - public function setEntered(DateTime $entered): self - { - $this->entered = $entered; - return $this; - } - public function setViewed(?DateTime $viewed): self { $this->viewed = $viewed; diff --git a/src/Domain/Model/Messaging/UserMessageBounce.php b/src/Domain/Model/Messaging/UserMessageBounce.php index 280c2d8f..7d9ce4c4 100644 --- a/src/Domain/Model/Messaging/UserMessageBounce.php +++ b/src/Domain/Model/Messaging/UserMessageBounce.php @@ -8,9 +8,9 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Messaging\UserMessageBounceRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UserMessageBounceRepository::class)] #[ORM\Table(name: 'phplist_user_message_bounce')] #[ORM\Index(name: 'bounceidx', columns: ['bounce'])] #[ORM\Index(name: 'msgidx', columns: ['message'])] @@ -19,7 +19,10 @@ #[ORM\HasLifecycleCallbacks] class UserMessageBounce implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'user', type: 'integer')] private int $user; @@ -31,11 +34,16 @@ class UserMessageBounce implements DomainModel, Identity private int $bounce; #[ORM\Column(name: 'time', type: 'datetime', options: ['default' => 'CURRENT_TIMESTAMP'])] - private DateTime $time; + private DateTime $createdAt; public function __construct() { - $this->time = new DateTime(); + $this->createdAt = new DateTime(); + } + + public function getId(): ?int + { + return $this->id; } public function getUser(): int @@ -53,9 +61,9 @@ public function getBounce(): int return $this->bounce; } - public function getTime(): DateTime + public function getCreatedAt(): DateTime { - return $this->time; + return $this->createdAt; } public function setUser(int $user): self diff --git a/src/Domain/Model/Messaging/UserMessageForward.php b/src/Domain/Model/Messaging/UserMessageForward.php index ac79f4d6..1f69da23 100644 --- a/src/Domain/Model/Messaging/UserMessageForward.php +++ b/src/Domain/Model/Messaging/UserMessageForward.php @@ -8,16 +8,19 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Messaging\UserMessageForwardRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: UserMessageForwardRepository::class)] #[ORM\Table(name: 'phplist_user_message_forward')] #[ORM\Index(name: 'messageidx', columns: ['message'])] #[ORM\Index(name: 'useridx', columns: ['user'])] #[ORM\Index(name: 'usermessageidx', columns: ['user', 'message'])] class UserMessageForward implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'user', type: 'integer')] private int $user; @@ -32,7 +35,17 @@ class UserMessageForward implements DomainModel, Identity private ?string $status = null; #[ORM\Column(name: 'time', type: 'datetime', options: ['default' => 'CURRENT_TIMESTAMP'])] - private DateTime $time; + private DateTime $createdAt; + + public function __construct() + { + $this->createdAt = new DateTime(); + } + + public function getId(): ?int + { + return $this->id; + } public function getUser(): int { @@ -54,9 +67,9 @@ public function getStatus(): ?string return $this->status; } - public function getTime(): DateTime + public function getCreatedAt(): DateTime { - return $this->time; + return $this->createdAt; } public function setUser(int $user): self @@ -82,10 +95,4 @@ public function setStatus(?string $status): self $this->status = $status; return $this; } - - public function setTime(DateTime $time): self - { - $this->time = $time; - return $this; - } } diff --git a/src/Domain/Model/Subscription/SubscribePage.php b/src/Domain/Model/Subscription/SubscribePage.php index 75f2b151..bd2d29cf 100644 --- a/src/Domain/Model/Subscription/SubscribePage.php +++ b/src/Domain/Model/Subscription/SubscribePage.php @@ -7,13 +7,16 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Subscription\SubscriberPageRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: SubscriberPageRepository::class)] #[ORM\Table(name: 'phplist_subscribepage')] class SubscribePage implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'title', type: 'string', length: 255)] private string $title; @@ -24,6 +27,11 @@ class SubscribePage implements DomainModel, Identity #[ORM\Column(name: 'owner', type: 'integer', nullable: true)] private ?int $owner = null; + public function getId(): ?int + { + return $this->id; + } + public function getTitle(): string { return $this->title; diff --git a/src/Domain/Model/Subscription/SubscribePageData.php b/src/Domain/Model/Subscription/SubscribePageData.php index ecc6d615..7c99db46 100644 --- a/src/Domain/Model/Subscription/SubscribePageData.php +++ b/src/Domain/Model/Subscription/SubscribePageData.php @@ -6,8 +6,9 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; +use PhpList\Core\Domain\Repository\Subscription\SubscriberPageDataRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: SubscriberPageDataRepository::class)] #[ORM\Table(name: 'phplist_subscribepage_data')] class SubscribePageData implements DomainModel { diff --git a/src/Domain/Model/Subscription/Subscriber.php b/src/Domain/Model/Subscription/Subscriber.php index ce1fec51..f06972ec 100644 --- a/src/Domain/Model/Subscription/Subscriber.php +++ b/src/Domain/Model/Subscription/Subscriber.php @@ -9,21 +9,16 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Repository\Subscription\SubscriberRepository; -use Symfony\Component\Serializer\Annotation\Ignore; -use Symfony\Component\Serializer\Annotation\SerializedName; use PhpList\Core\Domain\Model\Interfaces\CreationDate; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; use PhpList\Core\Domain\Model\Interfaces\ModificationDate; -use PhpList\Core\Domain\Model\Traits\CreationDateTrait; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; -use PhpList\Core\Domain\Model\Traits\ModificationDateTrait; -use Symfony\Component\Serializer\Attribute\Groups; /** * This class represents subscriber who can subscribe to multiple subscriber lists and can receive email messages from * campaigns for those subscriber lists. * @author Oliver Klee + * @author Tatevik Grigoryan */ #[ORM\Entity(repositoryClass: SubscriberRepository::class)] #[ORM\Table(name: 'phplist_user_user')] @@ -34,66 +29,90 @@ #[ORM\HasLifecycleCallbacks] class Subscriber implements DomainModel, Identity, CreationDate, ModificationDate { - use IdentityTrait; - use CreationDateTrait; - use ModificationDateTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'entered', type: 'datetime', nullable: true)] - #[SerializedName('creation_date')] - #[Groups(['SubscriberListMembers'])] - protected ?DateTime $creationDate = null; + protected ?DateTime $createdAt = null; + + #[ORM\Column(name: 'modified', type: 'datetime')] + private ?DateTime $updatedAt = null; #[ORM\Column(unique: true)] - #[SerializedName('email')] - #[Groups(['SubscriberListMembers'])] private string $email = ''; #[ORM\Column(type: 'boolean')] - #[SerializedName('confirmed')] - #[Groups(['SubscriberListMembers'])] private bool $confirmed = false; #[ORM\Column(type: 'boolean')] - #[SerializedName('blacklisted')] - #[Groups(['SubscriberListMembers'])] private bool $blacklisted = false; #[ORM\Column(name: 'bouncecount', type: 'integer')] - #[SerializedName('bounce_count')] - #[Groups(['SubscriberListMembers'])] private int $bounceCount = 0; #[ORM\Column(name: 'uniqid', unique: true)] - #[SerializedName('unique_id')] - #[Groups(['SubscriberListMembers'])] private string $uniqueId = ''; #[ORM\Column(name: 'htmlemail', type: 'boolean')] - #[SerializedName('html_email')] - #[Groups(['SubscriberListMembers'])] private bool $htmlEmail = false; #[ORM\Column(type: 'boolean')] - #[SerializedName('disabled')] - #[Groups(['SubscriberListMembers'])] private bool $disabled = false; #[ORM\Column(name: 'extradata', type: 'text')] - #[SerializedName('extra_data')] private ?string $extraData; #[ORM\OneToMany( - targetEntity: 'PhpList\Core\Domain\Model\Subscription\Subscription', + targetEntity: Subscription::class, mappedBy: 'subscriber', cascade: ['remove'], orphanRemoval: true, )] private Collection $subscriptions; + /** + * @var Collection + */ + #[ORM\OneToMany( + targetEntity: SubscriberAttribute::class, + mappedBy: 'subscriber', + cascade: ['persist', 'remove'], + orphanRemoval: true + )] + private Collection $attributes; + public function __construct() { $this->subscriptions = new ArrayCollection(); + $this->attributes = new ArrayCollection(); $this->extraData = ''; + $this->createdAt = new DateTime(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getCreatedAt(): ?DateTime + { + return $this->createdAt; + } + + public function getUpdatedAt(): ?DateTime + { + return $this->updatedAt; + } + + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateUpdatedAt(): DomainModel + { + $this->updatedAt = new DateTime(); + + return $this; } public function isConfirmed(): bool @@ -101,9 +120,11 @@ public function isConfirmed(): bool return $this->confirmed; } - public function setConfirmed(bool $confirmed): void + public function setConfirmed(bool $confirmed): self { $this->confirmed = $confirmed; + + return $this; } public function isBlacklisted(): bool @@ -111,9 +132,11 @@ public function isBlacklisted(): bool return $this->blacklisted; } - public function setBlacklisted(bool $blacklisted): void + public function setBlacklisted(bool $blacklisted): self { $this->blacklisted = $blacklisted; + + return $this; } public function getBounceCount(): int @@ -121,14 +144,18 @@ public function getBounceCount(): int return $this->bounceCount; } - public function setBounceCount(int $bounceCount): void + public function setBounceCount(int $bounceCount): self { $this->bounceCount = $bounceCount; + + return $this; } - public function addToBounceCount(int $delta): void + public function addToBounceCount(int $delta): self { $this->setBounceCount($this->getBounceCount() + $delta); + + return $this; } public function getUniqueId(): string @@ -136,15 +163,18 @@ public function getUniqueId(): string return $this->uniqueId; } - public function setUniqueId(string $uniqueId): void + public function setUniqueId(string $uniqueId): self { $this->uniqueId = $uniqueId; + + return $this; } #[ORM\PrePersist] - public function generateUniqueId(): void + public function generateUniqueId(): self { $this->setUniqueId(bin2hex(random_bytes(16))); + return $this; } public function getEmail(): string @@ -152,9 +182,11 @@ public function getEmail(): string return $this->email; } - public function setEmail(string $email): void + public function setEmail(string $email): self { $this->email = $email; + + return $this; } public function hasHtmlEmail(): bool @@ -162,9 +194,11 @@ public function hasHtmlEmail(): bool return $this->htmlEmail; } - public function setHtmlEmail(bool $htmlEmail): void + public function setHtmlEmail(bool $htmlEmail): self { $this->htmlEmail = $htmlEmail; + + return $this; } public function isDisabled(): bool @@ -172,9 +206,11 @@ public function isDisabled(): bool return $this->disabled; } - public function setDisabled(bool $disabled): void + public function setDisabled(bool $disabled): self { $this->disabled = $disabled; + + return $this; } public function getExtraData(): string @@ -182,9 +218,11 @@ public function getExtraData(): string return $this->extraData; } - public function setExtraData(string $extraData): void + public function setExtraData(string $extraData): self { $this->extraData = $extraData; + + return $this; } /** @@ -223,4 +261,24 @@ public function getSubscribedLists(): Collection return $result; } + + public function getAttributes(): Collection + { + return $this->attributes; + } + + public function addAttribute(SubscriberAttribute $attribute): self + { + if (!$this->attributes->contains($attribute)) { + $this->attributes[] = $attribute; + } + + return $this; + } + + public function removeAttribute(SubscriberAttribute $attribute): self + { + $this->attributes->removeElement($attribute); + return $this; + } } diff --git a/src/Domain/Model/Subscription/SubscriberAttribute.php b/src/Domain/Model/Subscription/SubscriberAttribute.php index 4bdc44fc..8484ff1d 100644 --- a/src/Domain/Model/Subscription/SubscriberAttribute.php +++ b/src/Domain/Model/Subscription/SubscriberAttribute.php @@ -6,8 +6,9 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; +use PhpList\Core\Domain\Repository\Subscription\SubscriberAttributeRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: SubscriberAttributeRepository::class)] #[ORM\Table(name: 'phplist_user_user_attribute')] #[ORM\Index(name: 'attindex', columns: ['attributeid'])] #[ORM\Index(name: 'attuserid', columns: ['userid', 'attributeid'])] @@ -15,8 +16,9 @@ class SubscriberAttribute implements DomainModel { #[ORM\Id] - #[ORM\Column(name: 'attributeid', type: 'integer', nullable: false)] - private int $id; + #[ORM\ManyToOne(targetEntity: SubscriberAttributeDefinition::class)] + #[ORM\JoinColumn(name: 'attributeid', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] + private SubscriberAttributeDefinition $attributeDefinition; #[ORM\Id] #[ORM\ManyToOne(targetEntity: Subscriber::class)] @@ -26,15 +28,15 @@ class SubscriberAttribute implements DomainModel #[ORM\Column(name: 'value', type: 'text', nullable: true)] private ?string $value = null; - public function __construct(int $id, Subscriber $subscriber) + public function __construct(SubscriberAttributeDefinition $attributeDefinition, Subscriber $subscriber) { - $this->id = $id; + $this->attributeDefinition = $attributeDefinition; $this->subscriber = $subscriber; } - public function getId(): int + public function getAttributeDefinition(): SubscriberAttributeDefinition { - return $this->id; + return $this->attributeDefinition; } public function getSubscriber(): Subscriber diff --git a/src/Domain/Model/Identity/UserAttribute.php b/src/Domain/Model/Subscription/SubscriberAttributeDefinition.php similarity index 83% rename from src/Domain/Model/Identity/UserAttribute.php rename to src/Domain/Model/Subscription/SubscriberAttributeDefinition.php index 81e4c8c2..9c9f51b4 100644 --- a/src/Domain/Model/Identity/UserAttribute.php +++ b/src/Domain/Model/Subscription/SubscriberAttributeDefinition.php @@ -2,20 +2,23 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Model\Identity; +namespace PhpList\Core\Domain\Model\Subscription; use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Subscription\SubscriberAttributeDefinitionRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: SubscriberAttributeDefinitionRepository::class)] #[ORM\Table(name: 'phplist_user_attribute')] #[ORM\Index(name: 'idnameindex', columns: ['id', 'name'])] #[ORM\Index(name: 'nameindex', columns: ['name'])] -class UserAttribute implements DomainModel, Identity +class SubscriberAttributeDefinition implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column(name: 'name', type: 'string', length: 255)] private string $name; @@ -35,6 +38,11 @@ class UserAttribute implements DomainModel, Identity #[ORM\Column(name: 'tablename', type: 'string', length: 255, nullable: true)] private ?string $tableName = null; + public function getId(): ?int + { + return $this->id; + } + public function getName(): string { return $this->name; diff --git a/src/Domain/Model/Subscription/SubscriberHistory.php b/src/Domain/Model/Subscription/SubscriberHistory.php index ace918c7..5761a96a 100644 --- a/src/Domain/Model/Subscription/SubscriberHistory.php +++ b/src/Domain/Model/Subscription/SubscriberHistory.php @@ -8,15 +8,18 @@ use Doctrine\ORM\Mapping as ORM; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; +use PhpList\Core\Domain\Repository\Subscription\SubscriberHistoryRepository; -#[ORM\Entity] +#[ORM\Entity(repositoryClass: SubscriberHistoryRepository::class)] #[ORM\Table(name: 'phplist_user_user_history')] #[ORM\Index(name: 'dateidx', columns: ['date'])] #[ORM\Index(name: 'userididx', columns: ['userid'])] class SubscriberHistory implements DomainModel, Identity { - use IdentityTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\ManyToOne(targetEntity: Subscriber::class)] #[ORM\JoinColumn(name: 'userid', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')] @@ -26,7 +29,7 @@ class SubscriberHistory implements DomainModel, Identity private ?string $ip = null; #[ORM\Column(name: 'date', type: 'datetime', nullable: true)] - private ?DateTime $date = null; + private ?DateTime $createdAt = null; #[ORM\Column(name: 'summary', type: 'string', length: 255, nullable: true)] private ?string $summary = null; @@ -37,6 +40,17 @@ class SubscriberHistory implements DomainModel, Identity #[ORM\Column(name: 'systeminfo', type: 'text', nullable: true)] private ?string $systemInfo = null; + public function __construct(Subscriber $subscriber) + { + $this->subscriber = $subscriber; + $this->createdAt = new DateTime(); + } + + public function getId(): ?int + { + return $this->id; + } + public function getSubscriber(): Subscriber { return $this->subscriber; @@ -47,9 +61,9 @@ public function getIp(): ?string return $this->ip; } - public function getDate(): ?DateTime + public function getCreatedAt(): ?DateTime { - return $this->date; + return $this->createdAt; } public function getSummary(): ?string @@ -79,12 +93,6 @@ public function setIp(?string $ip): self return $this; } - public function setDate(?DateTime $date): self - { - $this->date = $date; - return $this; - } - public function setSummary(?string $summary): self { $this->summary = $summary; diff --git a/src/Domain/Model/Messaging/SubscriberList.php b/src/Domain/Model/Subscription/SubscriberList.php similarity index 69% rename from src/Domain/Model/Messaging/SubscriberList.php rename to src/Domain/Model/Subscription/SubscriberList.php index 4340ef17..1b58875e 100644 --- a/src/Domain/Model/Messaging/SubscriberList.php +++ b/src/Domain/Model/Subscription/SubscriberList.php @@ -2,31 +2,25 @@ declare(strict_types=1); -namespace PhpList\Core\Domain\Model\Messaging; +namespace PhpList\Core\Domain\Model\Subscription; use DateTime; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -use PhpList\Core\Domain\Model\Subscription\Subscription; -use PhpList\Core\Domain\Repository\Messaging\SubscriberListRepository; -use Symfony\Component\Serializer\Annotation\Ignore; -use Symfony\Component\Serializer\Annotation\SerializedName; use PhpList\Core\Domain\Model\Identity\Administrator; use PhpList\Core\Domain\Model\Interfaces\CreationDate; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\Identity; use PhpList\Core\Domain\Model\Interfaces\ModificationDate; -use PhpList\Core\Domain\Model\Traits\CreationDateTrait; -use PhpList\Core\Domain\Model\Traits\IdentityTrait; -use PhpList\Core\Domain\Model\Traits\ModificationDateTrait; -use Symfony\Component\Serializer\Attribute\Groups; +use PhpList\Core\Domain\Repository\Subscription\SubscriberListRepository; use Symfony\Component\Serializer\Attribute\MaxDepth; /** * This class represents an administrator who can log to the system, is allowed to administer * selected lists (as the owner), send campaigns to these lists and edit subscribers. * @author Oliver Klee + * @author Tatevik Grigoryan */ #[ORM\Entity(repositoryClass: SubscriberListRepository::class)] #[ORM\Table(name: 'phplist_list')] @@ -35,52 +29,41 @@ #[ORM\HasLifecycleCallbacks] class SubscriberList implements DomainModel, Identity, CreationDate, ModificationDate { - use IdentityTrait; - use CreationDateTrait; - use ModificationDateTrait; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + private ?int $id = null; #[ORM\Column] - #[SerializedName('name')] - #[Groups(['SubscriberList'])] private string $name = ''; #[ORM\Column] - #[SerializedName('description')] - #[Groups(['SubscriberList'])] private string $description = ''; #[ORM\Column(name: 'entered', type: 'datetime', nullable: true)] - #[SerializedName('creation_date')] - #[Groups(['SubscriberList'])] - protected ?DateTime $creationDate = null; + protected ?DateTime $createdAt = null; + + #[ORM\Column(name: 'modified', type: 'datetime')] + private ?DateTime $updatedAt = null; #[ORM\Column(name: 'listorder', type: 'integer', nullable: true)] - #[SerializedName('list_position')] - #[Groups(['SubscriberList'])] private ?int $listPosition; #[ORM\Column(name: 'prefix')] - #[SerializedName('subject_prefix')] - #[Groups(['SubscriberList'])] private ?string $subjectPrefix; #[ORM\Column(name: 'active', type: 'boolean')] - #[SerializedName('public')] - #[Groups(['SubscriberList'])] private bool $public; #[ORM\Column] - #[SerializedName('category')] - #[Groups(['SubscriberList'])] private string $category; - #[ORM\ManyToOne(targetEntity: 'PhpList\Core\Domain\Model\Identity\Administrator')] + #[ORM\ManyToOne(targetEntity: Administrator::class)] #[ORM\JoinColumn(name: 'owner')] - #[Ignore] private ?Administrator $owner = null; #[ORM\OneToMany( - targetEntity: 'PhpList\Core\Domain\Model\Subscription\Subscription', + targetEntity: Subscription::class, mappedBy: 'subscriberList', cascade: ['remove'], orphanRemoval: true, @@ -91,20 +74,28 @@ class SubscriberList implements DomainModel, Identity, CreationDate, Modificatio public function __construct() { $this->subscriptions = new ArrayCollection(); + $this->createdAt = new DateTime(); $this->listPosition = 0; $this->subjectPrefix = ''; $this->category = ''; $this->public = false; } + public function getId(): ?int + { + return $this->id; + } + public function getName(): string { return $this->name; } - public function setName(string $name): void + public function setName(string $name): self { $this->name = $name; + + return $this; } public function getDescription(): string @@ -112,9 +103,11 @@ public function getDescription(): string return $this->description; } - public function setDescription(string $description): void + public function setDescription(string $description): self { $this->description = $description; + + return $this; } public function getListPosition(): ?int @@ -122,9 +115,10 @@ public function getListPosition(): ?int return $this->listPosition; } - public function setListPosition(int $listPosition): void + public function setListPosition(int $listPosition): self { $this->listPosition = $listPosition; + return $this; } public function getSubjectPrefix(): ?string @@ -132,9 +126,11 @@ public function getSubjectPrefix(): ?string return $this->subjectPrefix; } - public function setSubjectPrefix(string $subjectPrefix): void + public function setSubjectPrefix(string $subjectPrefix): self { $this->subjectPrefix = $subjectPrefix; + + return $this; } public function isPublic(): bool @@ -142,9 +138,11 @@ public function isPublic(): bool return $this->public ?? false; } - public function setPublic(bool $public): void + public function setPublic(bool $public): self { $this->public = $public; + + return $this; } public function getCategory(): string @@ -152,9 +150,11 @@ public function getCategory(): string return $this->category; } - public function setCategory(string $category): void + public function setCategory(string $category): self { $this->category = $category; + + return $this; } public function getOwner(): ?Administrator @@ -162,9 +162,11 @@ public function getOwner(): ?Administrator return $this->owner; } - public function setOwner(Administrator $owner): void + public function setOwner(Administrator $owner): self { $this->owner = $owner; + + return $this; } public function getSubscriptions(): Collection @@ -200,4 +202,23 @@ public function getSubscribers(): Collection return $result; } + + public function getCreatedAt(): ?DateTime + { + return $this->createdAt; + } + + public function getUpdatedAt(): ?DateTime + { + return $this->updatedAt; + } + + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateUpdatedAt(): DomainModel + { + $this->updatedAt = new DateTime(); + + return $this; + } } diff --git a/src/Domain/Model/Subscription/Subscription.php b/src/Domain/Model/Subscription/Subscription.php index fa736940..ba1ade79 100644 --- a/src/Domain/Model/Subscription/Subscription.php +++ b/src/Domain/Model/Subscription/Subscription.php @@ -7,22 +7,21 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; use Doctrine\Persistence\Proxy; -use Symfony\Component\Serializer\Annotation\Ignore; -use Symfony\Component\Serializer\Annotation\SerializedName; use PhpList\Core\Domain\Model\Interfaces\CreationDate; use PhpList\Core\Domain\Model\Interfaces\DomainModel; use PhpList\Core\Domain\Model\Interfaces\ModificationDate; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; -use PhpList\Core\Domain\Model\Traits\CreationDateTrait; -use PhpList\Core\Domain\Model\Traits\ModificationDateTrait; +use PhpList\Core\Domain\Repository\Subscription\SubscriptionRepository; +use Symfony\Component\Serializer\Annotation\Ignore; +use Symfony\Component\Serializer\Annotation\SerializedName; use Symfony\Component\Serializer\Attribute\Groups; /** * This class represents subscriber who can subscribe to multiple subscriber lists and can receive email messages from * campaigns for those subscriber lists. * @author Oliver Klee + * @author Tatevik Grigoryan */ -#[ORM\Entity(repositoryClass: 'PhpList\Core\Domain\Repository\Subscription\SubscriptionRepository')] +#[ORM\Entity(repositoryClass: SubscriptionRepository::class)] #[ORM\Table(name: 'phplist_listuser')] #[ORM\Index(name: 'userenteredidx', columns: ['userid', 'entered'])] #[ORM\Index(name: 'userlistenteredidx', columns: ['userid', 'entered', 'listid'])] @@ -31,16 +30,16 @@ #[ORM\HasLifecycleCallbacks] class Subscription implements DomainModel, CreationDate, ModificationDate { - use CreationDateTrait; - use ModificationDateTrait; - #[ORM\Column(name: 'entered', type: 'datetime', nullable: true)] #[SerializedName('creation_date')] - protected ?DateTime $creationDate = null; + protected ?DateTime $createdAt = null; + + #[ORM\Column(name: 'modified', type: 'datetime')] + private ?DateTime $updatedAt = null; #[ORM\Id] #[ORM\ManyToOne( - targetEntity: 'PhpList\Core\Domain\Model\Subscription\Subscriber', + targetEntity: Subscriber::class, inversedBy: 'subscriptions' )] #[ORM\JoinColumn(name: 'userid')] @@ -49,7 +48,7 @@ class Subscription implements DomainModel, CreationDate, ModificationDate #[ORM\Id] #[ORM\ManyToOne( - targetEntity: 'PhpList\Core\Domain\Model\Messaging\SubscriberList', + targetEntity: SubscriberList::class, inversedBy: 'subscriptions' )] #[ORM\JoinColumn(name: 'listid', onDelete: 'CASCADE')] @@ -57,14 +56,20 @@ class Subscription implements DomainModel, CreationDate, ModificationDate #[Groups(['SubscriberListMembers'])] private ?SubscriberList $subscriberList = null; + public function __construct() + { + $this->createdAt = new DateTime(); + } + public function getSubscriber(): Subscriber|Proxy|null { return $this->subscriber; } - public function setSubscriber(?Subscriber $subscriber): void + public function setSubscriber(?Subscriber $subscriber): self { $this->subscriber = $subscriber; + return $this; } public function getSubscriberList(): ?SubscriberList @@ -72,8 +77,28 @@ public function getSubscriberList(): ?SubscriberList return $this->subscriberList; } - public function setSubscriberList(?SubscriberList $subscriberList): void + public function setSubscriberList(?SubscriberList $subscriberList): self { $this->subscriberList = $subscriberList; + return $this; + } + + public function getCreatedAt(): ?DateTime + { + return $this->createdAt; + } + + public function getUpdatedAt(): ?DateTime + { + return $this->updatedAt; + } + + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateUpdatedAt(): DomainModel + { + $this->updatedAt = new DateTime(); + + return $this; } } diff --git a/src/Domain/Model/Traits/CreationDateTrait.php b/src/Domain/Model/Traits/CreationDateTrait.php deleted file mode 100644 index 51b6fd25..00000000 --- a/src/Domain/Model/Traits/CreationDateTrait.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -trait CreationDateTrait -{ - /** - * @return DateTime|null - */ - public function getCreationDate(): ?DateTime - { - return $this->creationDate; - } - - /** - * @param DateTime $creationDate - * - * @return void - */ - private function setCreationDate(DateTime $creationDate): void - { - $this->creationDate = $creationDate; - } - - #[ORM\PrePersist] - public function updateCreationDate(): void - { - $this->setCreationDate(new DateTime()); - } -} diff --git a/src/Domain/Model/Traits/IdentityTrait.php b/src/Domain/Model/Traits/IdentityTrait.php deleted file mode 100644 index 4445ea26..00000000 --- a/src/Domain/Model/Traits/IdentityTrait.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ -trait IdentityTrait -{ - #[ORM\Id] - #[ORM\Column(type: 'integer')] - #[ORM\GeneratedValue] - #[SerializedName('id')] - #[Groups(['SubscriberList', 'SubscriberListMembers'])] - private int $id; - - public function getId(): int - { - return $this->id; - } -} diff --git a/src/Domain/Model/Traits/ModificationDateTrait.php b/src/Domain/Model/Traits/ModificationDateTrait.php deleted file mode 100644 index ab03e769..00000000 --- a/src/Domain/Model/Traits/ModificationDateTrait.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ -trait ModificationDateTrait -{ - #[ORM\Column(name: 'modified', type: 'datetime')] - private ?DateTime $modificationDate = null; - - public function getModificationDate(): ?DateTime - { - return $this->modificationDate; - } - - private function setModificationDate(DateTime $modificationDate): void - { - $this->modificationDate = $modificationDate; - } - - #[ORM\PrePersist] - #[ORM\PreUpdate] - public function updateModificationDate(): void - { - $this->setModificationDate(new DateTime()); - } -} diff --git a/src/Domain/Repository/AbstractRepository.php b/src/Domain/Repository/AbstractRepository.php index b5d56385..9fff90b7 100644 --- a/src/Domain/Repository/AbstractRepository.php +++ b/src/Domain/Repository/AbstractRepository.php @@ -5,6 +5,7 @@ namespace PhpList\Core\Domain\Repository; use Doctrine\ORM\EntityRepository; +use LogicException; use PhpList\Core\Domain\Model\Interfaces\DomainModel; /** @@ -15,6 +16,8 @@ */ abstract class AbstractRepository extends EntityRepository { + protected ?string $alias = null; + /** * Persists $model and flushes the entity manager change list. * @@ -46,4 +49,13 @@ public function remove(DomainModel $model): void $this->getEntityManager()->remove($model); $this->getEntityManager()->flush(); } + + public function getAlias(): string + { + if (!$this->alias) { + throw new LogicException('Alias not set in repository: ' . static::class); + } + + return $this->alias; + } } diff --git a/src/Domain/Repository/Analytics/LinkTrackForwardRepository.php b/src/Domain/Repository/Analytics/LinkTrackForwardRepository.php index c5e21bc0..ff0b3c8d 100644 --- a/src/Domain/Repository/Analytics/LinkTrackForwardRepository.php +++ b/src/Domain/Repository/Analytics/LinkTrackForwardRepository.php @@ -5,7 +5,10 @@ namespace PhpList\Core\Domain\Repository\Analytics; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; -class LinkTrackForwardRepository extends AbstractRepository +class LinkTrackForwardRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; } diff --git a/src/Domain/Repository/Analytics/LinkTrackRepository.php b/src/Domain/Repository/Analytics/LinkTrackRepository.php index 44465ae0..acc63431 100644 --- a/src/Domain/Repository/Analytics/LinkTrackRepository.php +++ b/src/Domain/Repository/Analytics/LinkTrackRepository.php @@ -5,7 +5,10 @@ namespace PhpList\Core\Domain\Repository\Analytics; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; -class LinkTrackRepository extends AbstractRepository +class LinkTrackRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; } diff --git a/src/Domain/Repository/Analytics/LinkTrackUmlClickRepository.php b/src/Domain/Repository/Analytics/LinkTrackUmlClickRepository.php index 08163303..dc0d4511 100644 --- a/src/Domain/Repository/Analytics/LinkTrackUmlClickRepository.php +++ b/src/Domain/Repository/Analytics/LinkTrackUmlClickRepository.php @@ -5,7 +5,10 @@ namespace PhpList\Core\Domain\Repository\Analytics; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; -class LinkTrackUmlClickRepository extends AbstractRepository +class LinkTrackUmlClickRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; } diff --git a/src/Domain/Repository/Analytics/UserMessageViewRepository.php b/src/Domain/Repository/Analytics/UserMessageViewRepository.php new file mode 100644 index 00000000..da6f3c09 --- /dev/null +++ b/src/Domain/Repository/Analytics/UserMessageViewRepository.php @@ -0,0 +1,14 @@ +createQueryBuilder('e') + ->andWhere('e.id > :lastId') + ->setParameter('lastId', $lastId) + ->orderBy('e.id', 'ASC') + ->setMaxResults($limit) + ->getQuery() + ->getResult(); + } + + /** + * Get filtered + paginated messages for a given owner and status. + * + * @return DomainModel[] + * @throws RuntimeException + */ + public function getFilteredAfterId(int $lastId, int $limit, ?FilterRequestInterface $filter = null): array + { + if ($filter === null) { + return $this->getAfterId($lastId, $limit); + } + + throw new RuntimeException('Filter method not implemented'); + } +} diff --git a/src/Domain/Repository/Identity/AdminAttributeRepository.php b/src/Domain/Repository/Identity/AdminAttributeRepository.php index 52d34cd3..c47797ba 100644 --- a/src/Domain/Repository/Identity/AdminAttributeRepository.php +++ b/src/Domain/Repository/Identity/AdminAttributeRepository.php @@ -5,7 +5,10 @@ namespace PhpList\Core\Domain\Repository\Identity; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; -class AdminAttributeRepository extends AbstractRepository +class AdminAttributeRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; } diff --git a/src/Domain/Repository/Identity/AdminLoginRepository.php b/src/Domain/Repository/Identity/AdminLoginRepository.php index 50289e72..850ce208 100644 --- a/src/Domain/Repository/Identity/AdminLoginRepository.php +++ b/src/Domain/Repository/Identity/AdminLoginRepository.php @@ -5,7 +5,10 @@ namespace PhpList\Core\Domain\Repository\Identity; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; -class AdminLoginRepository extends AbstractRepository +class AdminLoginRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; } diff --git a/src/Domain/Repository/Identity/AdminPasswordRequestRepository.php b/src/Domain/Repository/Identity/AdminPasswordRequestRepository.php index 75371c92..46edcba3 100644 --- a/src/Domain/Repository/Identity/AdminPasswordRequestRepository.php +++ b/src/Domain/Repository/Identity/AdminPasswordRequestRepository.php @@ -5,7 +5,10 @@ namespace PhpList\Core\Domain\Repository\Identity; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; -class AdminPasswordRequestRepository extends AbstractRepository +class AdminPasswordRequestRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; } diff --git a/src/Domain/Repository/Identity/AdministratorRepository.php b/src/Domain/Repository/Identity/AdministratorRepository.php index d98324b0..5081578d 100644 --- a/src/Domain/Repository/Identity/AdministratorRepository.php +++ b/src/Domain/Repository/Identity/AdministratorRepository.php @@ -8,6 +8,8 @@ use Doctrine\ORM\Mapping\ClassMetadata; use PhpList\Core\Domain\Model\Identity\Administrator; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; use PhpList\Core\Security\HashGenerator; /** @@ -15,8 +17,10 @@ * * @author Oliver Klee */ -class AdministratorRepository extends AbstractRepository +class AdministratorRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; + private HashGenerator $hashGenerator; public function __construct( diff --git a/src/Domain/Repository/Identity/AdministratorTokenRepository.php b/src/Domain/Repository/Identity/AdministratorTokenRepository.php index 818b6bd0..4e7c2d65 100644 --- a/src/Domain/Repository/Identity/AdministratorTokenRepository.php +++ b/src/Domain/Repository/Identity/AdministratorTokenRepository.php @@ -10,14 +10,19 @@ use Doctrine\Common\Collections\Criteria; use PhpList\Core\Domain\Model\Identity\AdministratorToken; use PhpList\Core\Domain\Repository\AbstractRepository; +use PhpList\Core\Domain\Repository\CursorPaginationTrait; +use PhpList\Core\Domain\Repository\Interfaces\PaginatableRepositoryInterface; /** * Repository for AdministratorToken models. * * @author Oliver Klee + * @author Tatevik Grigoryan */ -class AdministratorTokenRepository extends AbstractRepository +class AdministratorTokenRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; + /** * Finds one unexpired token by the given key. Returns null if there is no match. * diff --git a/src/Domain/Repository/Identity/UserBlacklistDataRepository.php b/src/Domain/Repository/Identity/UserBlacklistDataRepository.php new file mode 100644 index 00000000..cfdde439 --- /dev/null +++ b/src/Domain/Repository/Identity/UserBlacklistDataRepository.php @@ -0,0 +1,11 @@ +createQueryBuilder('m') + ->where('IDENTITY(m.owner) = :ownerId') + ->setParameter('ownerId', $ownerId) + ->getQuery() + ->getResult(); + } + + /** @return Message[] */ + public function getFilteredAfterId(int $lastId, int $limit, ?FilterRequestInterface $filter = null): array + { + $queryBuilder = $this->createQueryBuilder($this->getAlias()); + + if ($filter instanceof MessageFilter && $filter->getOwner() !== null) { + $queryBuilder->andWhere('IDENTITY(m.owner) = :ownerId') + ->setParameter('ownerId', $filter->getOwner()->getId()); + } + + return $queryBuilder->andWhere('m.id > :lastId') + ->setParameter('lastId', $lastId) + ->orderBy('m.id', 'ASC') + ->setMaxResults($limit) + ->getQuery() + ->getResult(); + } } diff --git a/src/Domain/Repository/Messaging/SendProcessRepository.php b/src/Domain/Repository/Messaging/SendProcessRepository.php new file mode 100644 index 00000000..59d20674 --- /dev/null +++ b/src/Domain/Repository/Messaging/SendProcessRepository.php @@ -0,0 +1,14 @@ + + * @author Tatevik Grigoryan */ -class SubscriberListRepository extends AbstractRepository +class SubscriberListRepository extends AbstractRepository implements PaginatableRepositoryInterface { + use CursorPaginationTrait; + public function findWithSubscription($id) { return $this->createQueryBuilder('sl') diff --git a/src/Domain/Repository/Subscription/SubscriberPageDataRepository.php b/src/Domain/Repository/Subscription/SubscriberPageDataRepository.php new file mode 100644 index 00000000..b8e4ab2b --- /dev/null +++ b/src/Domain/Repository/Subscription/SubscriberPageDataRepository.php @@ -0,0 +1,14 @@ + + * @author Tatevik Grigoryan */ -class SubscriberRepository extends AbstractRepository +class SubscriberRepository extends AbstractRepository implements PaginatableRepositoryInterface { public function findSubscribersBySubscribedList(int $listId): ?Subscriber { @@ -39,6 +44,33 @@ public function getSubscribersBySubscribedListId(int $listId): array ->getResult(); } + /** + * @return Subscriber[] + * @throws InvalidArgumentException + */ + public function getFilteredAfterId(int $lastId, int $limit, ?FilterRequestInterface $filter = null): array + { + if (!$filter instanceof SubscriberFilter) { + throw new InvalidArgumentException('Expected SubscriberFilterRequest.'); + } + + $queryBuilder = $this->createQueryBuilder('s') + ->innerJoin('s.subscriptions', 'subscription') + ->innerJoin('subscription.subscriberList', 'list'); + + if ($filter->getListId() !== null) { + $queryBuilder->where('list.id = :listId') + ->setParameter('listId', $filter->getListId()); + } + + return $queryBuilder->andWhere('s.id > :lastId') + ->setParameter('lastId', $lastId) + ->orderBy('s.id', 'ASC') + ->setMaxResults($limit) + ->getQuery() + ->getResult(); + } + public function findSubscriberWithSubscriptions(int $id): ?Subscriber { return $this->createQueryBuilder('s') diff --git a/src/Domain/Repository/Subscription/SubscriptionRepository.php b/src/Domain/Repository/Subscription/SubscriptionRepository.php index eb79f023..e1e97827 100644 --- a/src/Domain/Repository/Subscription/SubscriptionRepository.php +++ b/src/Domain/Repository/Subscription/SubscriptionRepository.php @@ -4,8 +4,8 @@ namespace PhpList\Core\Domain\Repository\Subscription; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscription; use PhpList\Core\Domain\Repository\AbstractRepository; @@ -16,15 +16,10 @@ * @method Subscription[] findBySubscriberList(SubscriberList $list) * * @author Oliver Klee + * @author Tatevik Grigoryan */ class SubscriptionRepository extends AbstractRepository { - /** - * @param SubscriberList $list - * @param Subscriber $subscriber - * - * @return Subscription|null - */ public function findOneBySubscriberListAndSubscriber(SubscriberList $list, Subscriber $subscriber): ?Subscription { return $this->findOneBy( @@ -34,4 +29,17 @@ public function findOneBySubscriberListAndSubscriber(SubscriberList $list, Subsc ] ); } + + public function findOneBySubscriberEmailAndListId(int $listId, string $email): ?Subscription + { + return $this->createQueryBuilder('subscription') + ->join('subscription.subscriber', 'subscriber') + ->join('subscription.subscriberList', 'list') + ->where('subscriber.email = :email') + ->andWhere('list.id = :listId') + ->setParameter('email', $email) + ->setParameter('listId', $listId) + ->getQuery() + ->getOneOrNullResult(); + } } diff --git a/tests/Integration/Domain/Repository/Fixtures/Administrator.csv b/tests/Integration/Domain/Repository/Fixtures/Identity/Administrator.csv similarity index 100% rename from tests/Integration/Domain/Repository/Fixtures/Administrator.csv rename to tests/Integration/Domain/Repository/Fixtures/Identity/Administrator.csv diff --git a/tests/Integration/Domain/Repository/Fixtures/AdministratorFixture.php b/tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorFixture.php similarity index 91% rename from tests/Integration/Domain/Repository/Fixtures/AdministratorFixture.php rename to tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorFixture.php index 30905f29..963d7648 100644 --- a/tests/Integration/Domain/Repository/Fixtures/AdministratorFixture.php +++ b/tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorFixture.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures; +namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity; use DateTime; use Doctrine\Bundle\FixturesBundle\Fixture; @@ -39,13 +39,13 @@ public function load(ObjectManager $manager): void $admin = new Administrator(); $this->setSubjectId($admin, (int)$row['id']); $admin->setLoginName($row['loginname']); - $admin->setEmailAddress($row['email']); + $admin->setEmail($row['email']); $admin->setPasswordHash($row['password']); $admin->setDisabled((bool) $row['disabled']); $admin->setSuperUser((bool) $row['superuser']); $manager->persist($admin); - $this->setSubjectProperty($admin, 'creationDate', new DateTime($row['created'])); + $this->setSubjectProperty($admin, 'createdAt', new DateTime($row['created'])); $this->setSubjectProperty($admin, 'passwordChangeDate', new DateTime($row['passwordchanged'])); } while (true); diff --git a/tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministrator.csv b/tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorTokenWithAdministrator.csv similarity index 100% rename from tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministrator.csv rename to tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorTokenWithAdministrator.csv diff --git a/tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministratorFixture.php b/tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorTokenWithAdministratorFixture.php similarity index 94% rename from tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministratorFixture.php rename to tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorTokenWithAdministratorFixture.php index 1d1ac74c..9805caea 100644 --- a/tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministratorFixture.php +++ b/tests/Integration/Domain/Repository/Fixtures/Identity/AdministratorTokenWithAdministratorFixture.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures; +namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity; use DateTime; use Doctrine\Bundle\FixturesBundle\Fixture; @@ -49,7 +49,7 @@ public function load(ObjectManager $manager): void $this->setSubjectId($adminToken, (int)$row['id']); $adminToken->setKey($row['value']); $this->setSubjectProperty($adminToken, 'expiry', new DateTime($row['expires'])); - $this->setSubjectProperty($adminToken, 'creationDate', (bool) $row['entered']); + $this->setSubjectProperty($adminToken, 'createdAt', (bool) $row['entered']); $adminToken->setAdministrator($admin); $manager->persist($adminToken); } while (true); diff --git a/tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokenFixture.php b/tests/Integration/Domain/Repository/Fixtures/Identity/DetachedAdministratorTokenFixture.php similarity index 93% rename from tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokenFixture.php rename to tests/Integration/Domain/Repository/Fixtures/Identity/DetachedAdministratorTokenFixture.php index 15f5d2a7..cd4bc687 100644 --- a/tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokenFixture.php +++ b/tests/Integration/Domain/Repository/Fixtures/Identity/DetachedAdministratorTokenFixture.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures; +namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity; use DateTime; use Doctrine\Bundle\FixturesBundle\Fixture; @@ -43,7 +43,7 @@ public function load(ObjectManager $manager): void $manager->persist($adminToken); $this->setSubjectProperty($adminToken, 'expiry', new DateTime($row['expires'])); - $this->setSubjectProperty($adminToken, 'creationDate', $row['entered']); + $this->setSubjectProperty($adminToken, 'createdAt', $row['entered']); } while (true); fclose($handle); diff --git a/tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokens.csv b/tests/Integration/Domain/Repository/Fixtures/Identity/DetachedAdministratorTokens.csv similarity index 100% rename from tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokens.csv rename to tests/Integration/Domain/Repository/Fixtures/Identity/DetachedAdministratorTokens.csv diff --git a/tests/Integration/Domain/Repository/Fixtures/Messaging/Message.csv b/tests/Integration/Domain/Repository/Fixtures/Messaging/Message.csv new file mode 100644 index 00000000..c2e52a79 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/Messaging/Message.csv @@ -0,0 +1,21 @@ +id,uuid,subject,fromfield,tofield,replyto,message,textmessage,footer,entered,modified,embargo,repeatinterval,repeatuntil,requeueinterval,requeueuntil,status,userselection,sent,htmlformatted,sendformat,template,processed,astext,ashtml,astextandhtml,aspdf,astextandpdf,viewed,bouncecount,sendstart,rsstemplate,owner +1,2df6b147-8470-45ed-8e4e-86aa01af400d,Do you want to continue receiving our messages?, My Name ,"","","

Hi [FIRST NAME%%there], remember us? You first signed up for our email newsletter on [ENTERED] – please click here to confirm you're happy to continue receiving our messages:

+ +

Continue receiving messages  (If you do not confirm using this link, then you won't hear from us again)

+ +

While you're at it, you can also update your preferences, including your email address or other details, by clicking here:

+ +

Update preferences

+ +

By confirming your membership and keeping your details up to date, you're helping us to manage and protect your data in accordance with best practices.

+ +

Thank you!

","","-- + +
+

This message was sent to [EMAIL] by [FROMEMAIL].

+

To forward this message, please do not use the forward button of your email application, because this message was made specifically for you only. Instead use the forward page in our newsletter system.
+ To change your details and to choose which lists to be subscribed to, visit your personal preferences page.
+ Or you can opt-out completely from all future mailings.

+
+ + ",2024-11-10 16:57:46,2024-11-14 08:32:15,2024-11-14 08:32:00,0,2024-11-14 08:32:00,0,2024-11-14 08:32:00,sent,,2024-11-14 08:32:15,1,invite,0,0,0,0,0,0,0,0,0,2024-11-14 08:32:15,,1 diff --git a/tests/Integration/Domain/Repository/Fixtures/Messaging/MessageFixture.php b/tests/Integration/Domain/Repository/Fixtures/Messaging/MessageFixture.php new file mode 100644 index 00000000..b65e66c2 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/Messaging/MessageFixture.php @@ -0,0 +1,109 @@ +getRepository(Administrator::class); + $templateRepository = $manager->getRepository(Template::class); + + do { + $data = fgetcsv($handle); + if ($data === false) { + break; + } + $row = array_combine($headers, $data); + $admin = $adminRepository->find($row['owner']); + $template = $templateRepository->find($row['template']); + + $format = new MessageFormat( + (bool)$row['htmlformatted'], + $row['sendformat'], + array_keys(array_filter([ + MessageFormat::FORMAT_TEXT => $row['astext'], + MessageFormat::FORMAT_HTML => $row['ashtml'], + MessageFormat::FORMAT_PDF => $row['aspdf'], + ])) + ); + + $schedule = new MessageSchedule( + (int)$row['repeatinterval'], + new DateTime($row['repeatuntil']), + (int)$row['requeueinterval'], + new DateTime($row['requeueuntil']), + new DateTime($row['embargo']), + ); + $metadata = new MessageMetadata( + $row['status'], + (int)$row['bouncecount'], + new DateTime($row['entered']), + new DateTime($row['sent']), + new DateTime($row['sendstart']), + ); + $metadata->setProcessed((bool) $row['processed']); + $metadata->setViews($row['viewed']); + $content = new MessageContent( + $row['subject'], + $row['message'], + $row['textmessage'], + $row['footer'] + ); + $options = new MessageOptions( + $row['fromfield'], + $row['tofield'], + $row['replyto'], + $row['userselection'], + $row['rsstemplate'], + ); + + $message = new Message( + $format, + $schedule, + $metadata, + $content, + $options, + $admin, + $template, + ); + $this->setSubjectId($message, (int)$row['id']); + $this->setSubjectProperty($message, 'uuid', $row['uuid']); + + $manager->persist($message); + $this->setSubjectProperty($message, 'updatedAt', new DateTime($row['modified'])); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Fixtures/Messaging/Template.csv b/tests/Integration/Domain/Repository/Fixtures/Messaging/Template.csv new file mode 100644 index 00000000..65872d62 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/Messaging/Template.csv @@ -0,0 +1,2 @@ +id,title,template,template_text,listorder +1,Newsletter Template,

Welcome

,,1 diff --git a/tests/Integration/Domain/Repository/Fixtures/Messaging/TemplateFixture.php b/tests/Integration/Domain/Repository/Fixtures/Messaging/TemplateFixture.php new file mode 100644 index 00000000..e5222290 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/Messaging/TemplateFixture.php @@ -0,0 +1,50 @@ +setContent($row['template']); + $template->setText($row['template_text']); + $template->setListOrder((int)$row['listorder']); + + $this->setSubjectId($template, (int)$row['id']); + $manager->persist($template); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Fixtures/Subscriber.csv b/tests/Integration/Domain/Repository/Fixtures/Subscription/Subscriber.csv similarity index 100% rename from tests/Integration/Domain/Repository/Fixtures/Subscriber.csv rename to tests/Integration/Domain/Repository/Fixtures/Subscription/Subscriber.csv diff --git a/tests/Integration/Domain/Repository/Fixtures/SubscriberFixture.php b/tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberFixture.php similarity index 89% rename from tests/Integration/Domain/Repository/Fixtures/SubscriberFixture.php rename to tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberFixture.php index 9a4ce782..a9fc5867 100644 --- a/tests/Integration/Domain/Repository/Fixtures/SubscriberFixture.php +++ b/tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberFixture.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures; +namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription; use DateTime; use Doctrine\Bundle\FixturesBundle\Fixture; @@ -51,8 +51,8 @@ public function load(ObjectManager $manager): void $manager->persist($subscriber); // avoid pre-persist $subscriber->setUniqueId($row['uniqueid']); - $this->setSubjectProperty($subscriber, 'creationDate', new DateTime($row['entered'])); - $this->setSubjectProperty($subscriber, 'modificationDate', new DateTime($row['modified'])); + $this->setSubjectProperty($subscriber, 'createdAt', new DateTime($row['entered'])); + $this->setSubjectProperty($subscriber, 'updatedAt', new DateTime($row['modified'])); } while (true); fclose($handle); diff --git a/tests/Integration/Domain/Repository/Fixtures/SubscriberList.csv b/tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberList.csv similarity index 100% rename from tests/Integration/Domain/Repository/Fixtures/SubscriberList.csv rename to tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberList.csv diff --git a/tests/Integration/Domain/Repository/Fixtures/SubscriberListFixture.php b/tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberListFixture.php similarity index 87% rename from tests/Integration/Domain/Repository/Fixtures/SubscriberListFixture.php rename to tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberListFixture.php index 0b8aff88..954c3c0e 100644 --- a/tests/Integration/Domain/Repository/Fixtures/SubscriberListFixture.php +++ b/tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriberListFixture.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures; +namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription; use DateTime; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; use PhpList\Core\Domain\Model\Identity\Administrator; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\TestingSupport\Traits\ModelTestTrait; use RuntimeException; @@ -50,8 +50,6 @@ public function load(ObjectManager $manager): void $this->setSubjectId($subscriberList, (int)$row['id']); $subscriberList->setName($row['name']); $subscriberList->setDescription($row['description']); - $this->setSubjectProperty($subscriberList, 'creationDate', new DateTime($row['entered'])); - $this->setSubjectProperty($subscriberList, 'modificationDate', new DateTime($row['modified'])); $subscriberList->setListPosition((int)$row['listorder']); $subscriberList->setSubjectPrefix($row['prefix']); $subscriberList->setPublic((bool) $row['active']); @@ -59,6 +57,9 @@ public function load(ObjectManager $manager): void $subscriberList->setOwner($admin); $manager->persist($subscriberList); + + $this->setSubjectProperty($subscriberList, 'createdAt', new DateTime($row['entered'])); + $this->setSubjectProperty($subscriberList, 'updatedAt', new DateTime($row['modified'])); } while (true); fclose($handle); diff --git a/tests/Integration/Domain/Repository/Fixtures/Subscription.csv b/tests/Integration/Domain/Repository/Fixtures/Subscription/Subscription.csv similarity index 100% rename from tests/Integration/Domain/Repository/Fixtures/Subscription.csv rename to tests/Integration/Domain/Repository/Fixtures/Subscription/Subscription.csv diff --git a/tests/Integration/Domain/Repository/Fixtures/SubscriptionFixture.php b/tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriptionFixture.php similarity index 86% rename from tests/Integration/Domain/Repository/Fixtures/SubscriptionFixture.php rename to tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriptionFixture.php index 35cd792b..df1741c5 100644 --- a/tests/Integration/Domain/Repository/Fixtures/SubscriptionFixture.php +++ b/tests/Integration/Domain/Repository/Fixtures/Subscription/SubscriptionFixture.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures; +namespace PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription; use DateTime; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscription; use PhpList\Core\TestingSupport\Traits\ModelTestTrait; use RuntimeException; @@ -51,8 +51,8 @@ public function load(ObjectManager $manager): void $manager->persist($subscription); - $this->setSubjectProperty($subscription, 'creationDate', new DateTime($row['entered'])); - $this->setSubjectProperty($subscription, 'modificationDate', new DateTime($row['modified'])); + $this->setSubjectProperty($subscription, 'createdAt', new DateTime($row['entered'])); + $this->setSubjectProperty($subscription, 'updatedAt', new DateTime($row['modified'])); } while (true); fclose($handle); diff --git a/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php b/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php index 2f74bcf3..05d0b83c 100644 --- a/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php @@ -10,7 +10,7 @@ use PhpList\Core\Domain\Repository\Identity\AdministratorRepository; use PhpList\Core\TestingSupport\Traits\DatabaseTestTrait; use PhpList\Core\TestingSupport\Traits\ModelTestTrait; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\AdministratorFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity\AdministratorFixture; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** @@ -51,34 +51,36 @@ public function testFindReadsModelFromDatabase(): void $this->assertSame($actual->getLoginName(), $actual->getLoginName()); $this->assertEqualsWithDelta( (new DateTime())->getTimestamp(), - $actual->getModificationDate()->getTimestamp(), + $actual->getUpdatedAt()->getTimestamp(), 1 ); - $this->assertSame('john@example.com', $actual->getEmailAddress()); + $this->assertSame('john@example.com', $actual->getEmail()); $this->assertSame( '1491a3c7e7b23b9a6393323babbb095dee0d7d81b2199617b487bd0fb5236f3c', $actual->getPasswordHash() ); - $this->assertEquals(new DateTime('2017-06-22 15:01:17'), $actual->getCreationDate()); + $this->assertEquals(new DateTime('2017-06-22 15:01:17'), $actual->getCreatedat()); $this->assertEquals(new DateTime('2017-06-28'), $actual->getPasswordChangeDate()); } public function testCreationDateOfExistingModelStaysUnchangedOnUpdate(): void { $id = 1; + /** @var Administrator $model */ $model = $this->repository->find($id); $this->assertNotNull($model); - $originalCreationDate = $model->getCreationDate(); + $originalCreationDate = $model->getCreatedAt(); $model->setLoginName('mel'); $this->entityManager->flush(); - $this->assertSame($originalCreationDate, $model->getCreationDate()); + $this->assertSame($originalCreationDate, $model->getCreatedAt()); } public function testModificationDateOfExistingModelGetsUpdatedOnUpdate(): void { $id = 1; + /** @var Administrator $model */ $model = $this->repository->find($id); $this->assertNotNull($model); @@ -86,7 +88,7 @@ public function testModificationDateOfExistingModelGetsUpdatedOnUpdate(): void $this->entityManager->flush(); $expectedModificationDate = new DateTime(); - $this->assertEqualsWithDelta($expectedModificationDate, $model->getModificationDate(), 5); + $this->assertEqualsWithDelta($expectedModificationDate, $model->getUpdatedAt(), 5); } public function testCreationDateOfNewModelIsSetToNowOnPersist() @@ -97,7 +99,7 @@ public function testCreationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->flush(); $expectedCreationDate = new DateTime(); - $this->assertEqualsWithDelta($expectedCreationDate, $model->getCreationDate(), 1); + $this->assertEqualsWithDelta($expectedCreationDate, $model->getCreatedAt(), 1); } public function testModificationDateOfNewModelIsSetToNowOnPersist() @@ -108,7 +110,7 @@ public function testModificationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->flush(); $expectedCreationDate = new DateTime(); - $this->assertEqualsWithDelta($expectedCreationDate, $model->getModificationDate(), 1); + $this->assertEqualsWithDelta($expectedCreationDate, $model->getUpdatedAt(), 1); } /** diff --git a/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php b/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php index e6b9ba35..b37d4e79 100644 --- a/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php @@ -12,10 +12,8 @@ use PhpList\Core\Domain\Repository\Identity\AdministratorTokenRepository; use PhpList\Core\TestingSupport\Traits\DatabaseTestTrait; use PhpList\Core\TestingSupport\Traits\SimilarDatesAssertionTrait; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\AdministratorFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\AdministratorTokenWithAdministratorFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\DetachedAdministratorTokenFixture; -use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity\AdministratorFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity\DetachedAdministratorTokenFixture; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; /** @@ -58,7 +56,7 @@ public function testFindReadsModelFromDatabase() self::assertInstanceOf(AdministratorToken::class, $model); self::assertSame($id, $model->getId()); - self::assertEqualsWithDelta($creationDate, $model->getCreationDate(), 1); + self::assertEqualsWithDelta($creationDate, $model->getCreatedAt(), 1); self::assertEquals($expiry, $model->getExpiry()); self::assertSame($key, $model->getKey()); } @@ -70,12 +68,12 @@ public function testCreationDateOfExistingModelStaysUnchangedOnUpdate() $id = 1; /** @var AdministratorToken $model */ $model = $this->repository->find($id); - $creationDate = $model->getCreationDate(); + $creationDate = $model->getCreatedAt(); $model->setKey('asdfasd'); $this->entityManager->flush(); - self::assertEquals($creationDate, $model->getCreationDate()); + self::assertEquals($creationDate, $model->getCreatedAt()); } public function testCreationDateOfNewModelIsSetToNowOnPersist() @@ -85,7 +83,7 @@ public function testCreationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->persist($model); - self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreatedAt()); } public function testFindOneUnexpiredByKeyFindsUnexpiredTokenWithMatchingKey() diff --git a/tests/Integration/Domain/Repository/Messaging/MessageRepositoryTest.php b/tests/Integration/Domain/Repository/Messaging/MessageRepositoryTest.php new file mode 100644 index 00000000..fc16a416 --- /dev/null +++ b/tests/Integration/Domain/Repository/Messaging/MessageRepositoryTest.php @@ -0,0 +1,133 @@ +loadSchema(); + + $this->messageRepository = self::getContainer()->get(MessageRepository::class); + } + + protected function tearDown(): void + { + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); + } + + public function testMessageIsPersistedAndFetchedCorrectly(): void + { + $admin = new Administrator(); + $this->entityManager->persist($admin); + + $message = new Message( + new MessageFormat(true, 'text'), + new MessageSchedule(1, null, 3, null, null), + new MessageMetadata('done'), + new MessageContent('Hello world!'), + new MessageOptions(), + $admin + ); + + $this->entityManager->persist($message); + $this->entityManager->flush(); + $this->entityManager->clear(); + + $foundMessages = $this->messageRepository->getByOwnerId($admin->getId()); + + self::assertCount(1, $foundMessages); + self::assertInstanceOf(Message::class, $foundMessages[0]); + self::assertSame('done', $foundMessages[0]->getMetadata()->getStatus()); + self::assertSame('Hello world!', $foundMessages[0]->getContent()->getSubject()); + } + + public function testGetByOwnerIdReturnsOnlyOwnedMessages(): void + { + $admin1 = new Administrator(); + $admin2 = new Administrator(); + + $this->entityManager->persist($admin1); + $this->entityManager->persist($admin2); + + $msg1 = new Message( + new MessageFormat(true, MessageFormat::FORMAT_TEXT), + new MessageSchedule(1, null, 3, null, null), + new MessageMetadata('done'), + new MessageContent('Owned by Admin 1!'), + new MessageOptions(), + $admin1 + ); + + $msg2 = new Message( + new MessageFormat(true, MessageFormat::FORMAT_TEXT), + new MessageSchedule(1, null, 3, null, null), + new MessageMetadata(null), + new MessageContent('Owned by Admin 2!'), + new MessageOptions(), + $admin2 + ); + + $msg3 = new Message( + new MessageFormat(true, MessageFormat::FORMAT_TEXT), + new MessageSchedule(1, null, 3, null, null), + new MessageMetadata(null), + new MessageContent('Hello world!'), + new MessageOptions(), + null + ); + + $this->entityManager->persist($msg1); + $this->entityManager->persist($msg2); + $this->entityManager->persist($msg3); + $this->entityManager->flush(); + $this->entityManager->clear(); + + $results = $this->messageRepository->getByOwnerId($admin1->getId()); + + self::assertCount(1, $results); + self::assertSame('Owned by Admin 1!', $results[0]->getContent()->getSubject()); + } + + public function testMessageTimestampsAreSetOnPersist(): void + { + $expectedDate = new DateTime(); + + $message = new Message( + new MessageFormat(true, MessageFormat::FORMAT_TEXT), + new MessageSchedule(1, null, 3, null, null), + new MessageMetadata(null), + new MessageContent('Hello world!'), + new MessageOptions(), + null + ); + + $this->entityManager->persist($message); + + self::assertSimilarDates($expectedDate, $message->getUpdatedAt()); + } +} diff --git a/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php b/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php index e53d725b..c721cb57 100644 --- a/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php @@ -6,20 +6,19 @@ use DateTime; use Doctrine\ORM\Tools\SchemaTool; -use PhpList\Core\Domain\Model\Identity\Administrator; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscription; use PhpList\Core\Domain\Repository\Identity\AdministratorRepository; -use PhpList\Core\Domain\Repository\Messaging\SubscriberListRepository; +use PhpList\Core\Domain\Repository\Subscription\SubscriberListRepository; use PhpList\Core\Domain\Repository\Subscription\SubscriberRepository; use PhpList\Core\Domain\Repository\Subscription\SubscriptionRepository; use PhpList\Core\TestingSupport\Traits\DatabaseTestTrait; use PhpList\Core\TestingSupport\Traits\SimilarDatesAssertionTrait; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\AdministratorFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriberFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriberListFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriptionFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity\AdministratorFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriberFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriberListFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriptionFixture; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** @@ -60,8 +59,8 @@ public function testFindReadsModelFromDatabase() $this->loadFixtures([SubscriberListFixture::class]); $id = 1; - $creationDate = new DateTime(); - $modificationDate = new DateTime(); + $creationDate = new DateTime('2016-06-22 15:01:17'); + $modificationDate = new DateTime('2016-06-23 19:50:43'); $name = 'News'; $description = 'News (and some fun stuff)'; $listPosition = 12; @@ -72,8 +71,8 @@ public function testFindReadsModelFromDatabase() $model = $this->subscriberListRepository->find($id); self::assertSame($id, $model->getId()); - self::assertSimilarDates($creationDate, $model->getCreationDate()); - self::assertSimilarDates($modificationDate, $model->getModificationDate()); + self::assertSimilarDates($creationDate, $model->getCreatedAt()); + self::assertSimilarDates($modificationDate, $model->getUpdatedAt()); self::assertSame($name, $model->getName()); self::assertSame($description, $model->getDescription()); self::assertSame($listPosition, $model->getListPosition()); @@ -89,7 +88,7 @@ public function testCreationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->persist($model); - self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreatedAt()); } public function testModificationDateOfNewModelIsSetToNowOnPersist() @@ -99,7 +98,7 @@ public function testModificationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->persist($model); - self::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + self::assertSimilarDates($expectedModificationDate, $model->getUpdatedAt()); } public function testSavePersistsAndFlushesModel() diff --git a/tests/Integration/Domain/Repository/Messaging/TemplateRepositoryTest.php b/tests/Integration/Domain/Repository/Messaging/TemplateRepositoryTest.php new file mode 100644 index 00000000..2d49df1e --- /dev/null +++ b/tests/Integration/Domain/Repository/Messaging/TemplateRepositoryTest.php @@ -0,0 +1,73 @@ +loadSchema(); + + $this->templateRepository = self::getContainer()->get(TemplateRepository::class); + } + + protected function tearDown(): void + { + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); + } + + public function testGetAllTemplatesReturnsCorrectResults(): void + { + $template1 = new Template('Template 1'); + $template2 = new Template('Template 2'); + + $this->entityManager->persist($template1); + $this->entityManager->persist($template2); + $this->entityManager->flush(); + $this->entityManager->clear(); + + $allTemplates = $this->templateRepository->findAll(); + + self::assertCount(2, $allTemplates); + self::assertContainsOnlyInstancesOf(Template::class, $allTemplates); + } + + public function testTemplateIsPersistedAndFetchedCorrectly(): void + { + $this->loadFixtures([TemplateFixture::class]); + + $fetched = $this->templateRepository->findOneBy(['title' => 'Newsletter Template']); + + self::assertInstanceOf(Template::class, $fetched); + self::assertSame('Newsletter Template', $fetched->getTitle()); + self::assertSame('

Welcome

', $fetched->getContent()); + self::assertSame('', $fetched->getText()); + self::assertSame(1, $fetched->getListOrder()); + } + + public function testGetAllTemplatesReturnsCorrectType(): void + { + $this->loadFixtures([TemplateFixture::class]); + + $allTemplates = $this->templateRepository->findAll(); + + self::assertNotEmpty($allTemplates); + self::assertContainsOnlyInstancesOf(Template::class, $allTemplates); + } +} diff --git a/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php b/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php index fc7b50f4..7c779bfd 100644 --- a/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php @@ -6,21 +6,19 @@ use DateTime; use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use Doctrine\ORM\Tools\SchemaTool; -use PhpList\Core\Domain\Model\Identity\Administrator; use PhpList\Core\Domain\Model\Subscription\Subscriber; use PhpList\Core\Domain\Model\Subscription\Subscription; -use PhpList\Core\Domain\Repository\Messaging\SubscriberListRepository; +use PhpList\Core\Domain\Repository\Subscription\SubscriberListRepository; use PhpList\Core\Domain\Repository\Subscription\SubscriberRepository; use PhpList\Core\Domain\Repository\Subscription\SubscriptionRepository; use PhpList\Core\TestingSupport\Traits\DatabaseTestTrait; use PhpList\Core\TestingSupport\Traits\SimilarDatesAssertionTrait; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\AdministratorFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriberFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriberListFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriptionFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity\AdministratorFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriberFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriberListFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriptionFixture; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** @@ -67,8 +65,8 @@ public function testFindReadsModelFromDatabase() $model = $this->subscriberRepository->find($id); self::assertSame($id, $model->getId()); - self::assertSimilarDates($creationDate, $model->getCreationDate()); - self::assertSimilarDates($modificationDate, $model->getModificationDate()); + self::assertSimilarDates($creationDate, $model->getCreatedAt()); + self::assertSimilarDates($modificationDate, $model->getUpdatedAt()); self::assertEquals('oliver@example.com', $model->getEmail()); self::assertTrue($model->isConfirmed()); self::assertTrue($model->isBlacklisted()); @@ -87,7 +85,7 @@ public function testCreationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->persist($model); - self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreatedAt()); } public function testModificationDateOfNewModelIsSetToNowOnPersist() @@ -98,7 +96,7 @@ public function testModificationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->persist($model); - self::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + self::assertSimilarDates($expectedModificationDate, $model->getUpdatedAt()); } public function testSavePersistsAndFlushesModel() diff --git a/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php b/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php index 280c7dcc..e394a3ff 100644 --- a/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php @@ -6,17 +6,17 @@ use DateTime; use Doctrine\ORM\Tools\SchemaTool; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscription; -use PhpList\Core\Domain\Repository\Messaging\SubscriberListRepository; +use PhpList\Core\Domain\Repository\Subscription\SubscriberListRepository; use PhpList\Core\Domain\Repository\Subscription\SubscriberRepository; use PhpList\Core\Domain\Repository\Subscription\SubscriptionRepository; use PhpList\Core\TestingSupport\Traits\DatabaseTestTrait; use PhpList\Core\TestingSupport\Traits\SimilarDatesAssertionTrait; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriberFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriberListFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\SubscriptionFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriberFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriberListFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Subscription\SubscriptionFixture; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; /** @@ -64,8 +64,8 @@ public function testFindAllReadsModelsFromDatabase() $model = $result[0]; self::assertInstanceOf(Subscription::class, $model); - self::assertEquals($creationDate, $model->getCreationDate()); - self::assertEquals($modificationDate, $model->getModificationDate()); + self::assertEquals($creationDate, $model->getCreatedAt()); + self::assertEquals($modificationDate, $model->getUpdatedAt()); } public function testCreationDateOfNewModelIsSetToNowOnPersist() @@ -83,7 +83,7 @@ public function testCreationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->persist($model); - self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreatedAt()); } public function testModificationDateOfNewModelIsSetToNowOnPersist() @@ -101,7 +101,7 @@ public function testModificationDateOfNewModelIsSetToNowOnPersist() $this->entityManager->persist($model); - self::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + self::assertSimilarDates($expectedModificationDate, $model->getUpdatedAt()); } public function testFindBySubscriberFindsSubscriptionOnlyWithTheGivenSubscriber() @@ -212,4 +212,26 @@ public function testFindOneBySubscriberListAndSubscriberForBothMatchingReturnsMa self::assertSame($subscriberList, $result->getSubscriberList()); self::assertSame($subscriber, $result->getSubscriber()); } + + public function testFindOneByListIdAndSubscriberEmailForNeitherMatchingReturnsNull() + { + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); + + $result = $this->subscriptionRepository->findOneBySubscriberEmailAndListId(3, 'some@random.mail'); + + self::assertNull($result); + } + + public function testFindOneByListIdAndSubscriberEmailForBothMatchingReturnsMatch() + { + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); + + $subscriberList = $this->subscriberListRepository->find(2); + $subscriber = $this->subscriberRepository->find(1); + $result = $this->subscriptionRepository->findOneBySubscriberEmailAndListId(2, $subscriber->getEmail()); + + self::assertInstanceOf(Subscription::class, $result); + self::assertSame($subscriberList, $result->getSubscriberList()); + self::assertSame($subscriber, $result->getSubscriber()); + } } diff --git a/tests/Integration/Security/AuthenticationTest.php b/tests/Integration/Security/AuthenticationTest.php index dfb55089..a46a6d93 100644 --- a/tests/Integration/Security/AuthenticationTest.php +++ b/tests/Integration/Security/AuthenticationTest.php @@ -8,8 +8,8 @@ use PhpList\Core\Domain\Model\Identity\Administrator; use PhpList\Core\Security\Authentication; use PhpList\Core\TestingSupport\Traits\DatabaseTestTrait; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\AdministratorFixture; -use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\AdministratorTokenWithAdministratorFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity\AdministratorFixture; +use PhpList\Core\Tests\Integration\Domain\Repository\Fixtures\Identity\AdministratorTokenWithAdministratorFixture; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\HttpFoundation\Request; diff --git a/tests/Unit/Domain/Model/Identity/AdministratorTest.php b/tests/Unit/Domain/Model/Identity/AdministratorTest.php index 4bdca7dc..e5565c64 100644 --- a/tests/Unit/Domain/Model/Identity/AdministratorTest.php +++ b/tests/Unit/Domain/Model/Identity/AdministratorTest.php @@ -55,39 +55,27 @@ public function testSetLoginNameSetsLoginName(): void public function testGetEmailAddressInitiallyReturnsEmptyString(): void { - self::assertSame('', $this->subject->getEmailAddress()); + self::assertSame('', $this->subject->getEmail()); } public function testSetEmailAddressSetsEmailAddress(): void { $value = 'oliver@example.com'; - $this->subject->setEmailAddress($value); + $this->subject->setEmail($value); - self::assertSame($value, $this->subject->getEmailAddress()); + self::assertSame($value, $this->subject->getEmail()); } - public function testGetCreationDateInitiallyReturnsNull(): void + public function testGetUpdatedAtInitiallyReturnsNull(): void { - self::assertNull($this->subject->getCreationDate()); - } - - public function testUpdateCreationDateSetsCreationDateToNow(): void - { - $this->subject->updateCreationDate(); - - self::assertSimilarDates(new \DateTime(), $this->subject->getCreationDate()); - } - - public function testGetModificationDateInitiallyReturnsNull(): void - { - self::assertNull($this->subject->getModificationDate()); + self::assertNull($this->subject->getUpdatedAt()); } public function testUpdateModificationDateSetsModificationDateToNow(): void { - $this->subject->updateModificationDate(); + $this->subject->updateUpdatedAt(); - self::assertSimilarDates(new \DateTime(), $this->subject->getModificationDate()); + self::assertSimilarDates(new \DateTime(), $this->subject->getUpdatedAt()); } public function testGetPasswordHashInitiallyReturnsEmptyString(): void diff --git a/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php b/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php index f28a2d70..5318782f 100644 --- a/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php +++ b/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php @@ -42,16 +42,16 @@ public function testGetIdReturnsId(): void self::assertSame($id, $this->subject->getId()); } - public function testGetCreationDateInitiallyReturnsNull(): void + public function testgetCreatedAtInitiallyReturnsNull(): void { - self::assertNull($this->subject->getCreationDate()); + self::assertNull($this->subject->getCreatedAt()); } public function testUpdateCreationDateSetsCreationDateToNow(): void { - $this->subject->updateCreationDate(); + $this->subject->updateCreatedAt(); - self::assertSimilarDates(new DateTime(), $this->subject->getCreationDate()); + self::assertSimilarDates(new DateTime(), $this->subject->getCreatedAt()); } public function testGetKeyInitiallyReturnsEmptyString(): void diff --git a/tests/Unit/Domain/Model/Messaging/MessageTest.php b/tests/Unit/Domain/Model/Messaging/MessageTest.php new file mode 100644 index 00000000..92ec6245 --- /dev/null +++ b/tests/Unit/Domain/Model/Messaging/MessageTest.php @@ -0,0 +1,106 @@ +format = new MessageFormat(true, MessageFormat::FORMAT_TEXT); + $this->schedule = new MessageSchedule(1, new DateTime(), 2, new DateTime(), null); + $this->metadata = new MessageMetadata(); + $this->content = new MessageContent('This is the body'); + $this->options = new MessageOptions(); + $this->owner = new Administrator(); + + $this->message = new Message( + $this->format, + $this->schedule, + $this->metadata, + $this->content, + $this->options, + $this->owner + ); + } + + public function testIsDomainModel(): void + { + self::assertInstanceOf(DomainModel::class, $this->message); + self::assertInstanceOf(Identity::class, $this->message); + self::assertInstanceOf(ModificationDate::class, $this->message); + } + + public function testUuidIsGenerated(): void + { + $uuid = $this->message->getUuid(); + self::assertNotEmpty($uuid); + self::assertMatchesRegularExpression('/^[a-f0-9]{36}$/', $uuid); + } + + public function testGetFormat(): void + { + self::assertSame($this->format, $this->message->getFormat()); + } + + public function testGetSchedule(): void + { + self::assertSame($this->schedule, $this->message->getSchedule()); + } + + public function testGetMetadata(): void + { + self::assertSame($this->metadata, $this->message->getMetadata()); + } + + public function testGetContent(): void + { + self::assertSame($this->content, $this->message->getContent()); + } + + public function testGetOptions(): void + { + self::assertSame($this->options, $this->message->getOptions()); + } + + public function testGetOwner(): void + { + self::assertSame($this->owner, $this->message->getOwner()); + } + + public function testGetOwnerInitiallyNull(): void + { + $message = new Message( + $this->format, + $this->schedule, + $this->metadata, + $this->content, + $this->options, + null + ); + + self::assertNull($message->getOwner()); + } +} diff --git a/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php b/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php index eb8209c5..8b7afa5b 100644 --- a/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php +++ b/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php @@ -5,12 +5,11 @@ namespace PhpList\Core\Tests\Unit\Domain\Model\Messaging; use DateTime; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use PhpList\Core\Domain\Model\Identity\Administrator; use PhpList\Core\Domain\Model\Interfaces\DomainModel; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscription; use PhpList\Core\TestingSupport\Traits\ModelTestTrait; use PhpList\Core\TestingSupport\Traits\SimilarDatesAssertionTrait; @@ -46,28 +45,23 @@ public function testGetIdReturnsId(): void self::assertSame($id, $this->subscriberList->getId()); } - public function testGetCreationDateInitiallyReturnsNull(): void - { - self::assertNull($this->subscriberList->getCreationDate()); - } - public function testUpdateCreationDateSetsCreationDateToNow(): void { - $this->subscriberList->updateCreationDate(); + $this->subscriberList->setCategory('test'); - self::assertSimilarDates(new DateTime(), $this->subscriberList->getCreationDate()); + self::assertSimilarDates(new DateTime(), $this->subscriberList->getCreatedAt()); } - public function testGetModificationDateInitiallyReturnsNull(): void + public function testgetUpdatedAtInitiallyReturnsNull(): void { - self::assertNull($this->subscriberList->getModificationDate()); + self::assertNull($this->subscriberList->getUpdatedAt()); } public function testUpdateModificationDateSetsModificationDateToNow(): void { - $this->subscriberList->updateModificationDate(); + $this->subscriberList->updateUpdatedAt(); - self::assertSimilarDates(new DateTime(), $this->subscriberList->getModificationDate()); + self::assertSimilarDates(new DateTime(), $this->subscriberList->getUpdatedAt()); } public function testGetNameInitiallyReturnsEmptyString(): void diff --git a/tests/Unit/Domain/Model/Subscription/SubscriberTest.php b/tests/Unit/Domain/Model/Subscription/SubscriberTest.php index edac5790..f61c3192 100644 --- a/tests/Unit/Domain/Model/Subscription/SubscriberTest.php +++ b/tests/Unit/Domain/Model/Subscription/SubscriberTest.php @@ -7,8 +7,8 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use PhpList\Core\Domain\Model\Interfaces\DomainModel; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscription; use PhpList\Core\TestingSupport\Traits\ModelTestTrait; use PhpList\Core\TestingSupport\Traits\SimilarDatesAssertionTrait; @@ -44,28 +44,28 @@ public function testGetIdReturnsId(): void self::assertSame($id, $this->subscriber->getId()); } - public function testGetCreationDateInitiallyReturnsNull(): void + public function testGetCreatedAtInitiallyReturnsNull(): void { - self::assertNull($this->subscriber->getCreationDate()); + self::assertSimilarDates(new \DateTime(), $this->subscriber->getCreatedAt()); } public function testUpdateCreationDateSetsCreationDateToNow(): void { - $this->subscriber->updateCreationDate(); + $this->subscriber->updateUpdatedAt(); - self::assertSimilarDates(new \DateTime(), $this->subscriber->getCreationDate()); + self::assertSimilarDates(new \DateTime(), $this->subscriber->getCreatedAt()); } - public function testGetModificationDateInitiallyReturnsNull(): void + public function testgetUpdatedAtInitiallyReturnsNull(): void { - self::assertNull($this->subscriber->getModificationDate()); + self::assertNull($this->subscriber->getUpdatedAt()); } public function testUpdateModificationDateSetsModificationDateToNow(): void { - $this->subscriber->updateModificationDate(); + $this->subscriber->updateUpdatedAt(); - self::assertSimilarDates(new \DateTime(), $this->subscriber->getModificationDate()); + self::assertSimilarDates(new \DateTime(), $this->subscriber->getUpdatedAt()); } public function testGetEmailInitiallyReturnsEmptyString(): void diff --git a/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php b/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php index af1aff86..5cdf3c03 100644 --- a/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php +++ b/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php @@ -6,8 +6,8 @@ use DateTime; use PhpList\Core\Domain\Model\Interfaces\DomainModel; -use PhpList\Core\Domain\Model\Messaging\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscriber; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; use PhpList\Core\Domain\Model\Subscription\Subscription; use PhpList\Core\TestingSupport\Traits\ModelTestTrait; use PhpList\Core\TestingSupport\Traits\SimilarDatesAssertionTrait; @@ -61,27 +61,20 @@ public function testSetSubscriberListSetsSubscriberList(): void self::assertSame($model, $this->subject->getSubscriberList()); } - public function testGetCreationDateInitiallyReturnsNull(): void + public function testGetCreatedAtInitiallyReturnsCurrentTime(): void { - self::assertNull($this->subject->getCreationDate()); + self::assertSimilarDates(new DateTime(), $this->subject->getCreatedAt()); } - public function testUpdateCreationDateSetsCreationDateToNow(): void + public function testGetUpdatedAtInitiallyReturnsNull(): void { - $this->subject->updateCreationDate(); - - self::assertSimilarDates(new DateTime(), $this->subject->getCreationDate()); - } - - public function testGetModificationDateInitiallyReturnsNull(): void - { - self::assertNull($this->subject->getModificationDate()); + self::assertNull($this->subject->getUpdatedAt()); } public function testUpdateModificationDateSetsModificationDateToNow(): void { - $this->subject->updateModificationDate(); + $this->subject->updateUpdatedAt(); - self::assertSimilarDates(new DateTime(), $this->subject->getModificationDate()); + self::assertSimilarDates(new DateTime(), $this->subject->getUpdatedAt()); } } diff --git a/tests/Unit/Domain/Repository/CursorPaginationTraitTest.php b/tests/Unit/Domain/Repository/CursorPaginationTraitTest.php new file mode 100644 index 00000000..1639b633 --- /dev/null +++ b/tests/Unit/Domain/Repository/CursorPaginationTraitTest.php @@ -0,0 +1,67 @@ +qb = $this->createMock(QueryBuilder::class); + $this->query = $this->createMock(Query::class); + + $this->qb->method('andWhere')->willReturnSelf(); + $this->qb->method('setParameter')->willReturnSelf(); + $this->qb->method('orderBy')->willReturnSelf(); + $this->qb->method('setMaxResults')->willReturnSelf(); + $this->qb->method('getQuery')->willReturn($this->query); + + $this->repo = new DummyRepository($this->qb); + } + + public function testGetAfterIdReturnsResults(): void + { + $expected = ['foo', 'bar']; + $this->query + ->expects(self::once()) + ->method('getResult') + ->willReturn($expected); + + $result = $this->repo->getAfterId(10, 2); + + self::assertSame($expected, $result); + } + + public function testGetFilteredAfterIdWithNullFilterDelegates(): void + { + $expected = ['cursor', 'pagination']; + // same expectations as previous test + $this->query->method('getResult')->willReturn($expected); + + $result = $this->repo->getFilteredAfterId(10, 2, null); + + self::assertSame($expected, $result); + } + + public function testGetFilteredAfterIdWithFilterThrows(): void + { + $dummyFilter = $this->createMock(FilterRequestInterface::class); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Filter method not implemented'); + + $this->repo->getFilteredAfterId(0, 10, $dummyFilter); + } +} diff --git a/tests/Unit/Domain/Repository/DummyRepository.php b/tests/Unit/Domain/Repository/DummyRepository.php new file mode 100644 index 00000000..b9b2bfbe --- /dev/null +++ b/tests/Unit/Domain/Repository/DummyRepository.php @@ -0,0 +1,31 @@ +createQueryBuilder(). */ + protected function createQueryBuilder(string $alias): QueryBuilder + { + return $this->queryBuilder; + } +} diff --git a/tests/Unit/Domain/Repository/Messaging/MessageRepositoryTest.php b/tests/Unit/Domain/Repository/Messaging/MessageRepositoryTest.php new file mode 100644 index 00000000..067ecb73 --- /dev/null +++ b/tests/Unit/Domain/Repository/Messaging/MessageRepositoryTest.php @@ -0,0 +1,36 @@ + + */ +class MessageRepositoryTest extends TestCase +{ + private MessageRepository $subject; + + protected function setUp(): void + { + $entityManager = $this->createMock(EntityManager::class); + + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->name = MessageRepository::class; + + $this->subject = new MessageRepository($entityManager, $classMetadata); + } + + public function testClassIsEntityRepository(): void + { + self::assertInstanceOf(EntityRepository::class, $this->subject); + } +} diff --git a/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php b/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php index e4cf7c19..f1f6a56b 100644 --- a/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php +++ b/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php @@ -7,7 +7,8 @@ use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadata; -use PhpList\Core\Domain\Repository\Messaging\SubscriberListRepository; +use PhpList\Core\Domain\Model\Subscription\SubscriberList; +use PhpList\Core\Domain\Repository\Subscription\SubscriberListRepository; use PHPUnit\Framework\TestCase; /** @@ -24,7 +25,7 @@ protected function setUp(): void $entityManager = $this->createMock(EntityManager::class); $classMetadata = $this->createMock(ClassMetadata::class); - $classMetadata->name = 'PhpList\Core\Domain\Model\Messaging\SubscriberList'; + $classMetadata->name = SubscriberList::class; $this->subject = new SubscriberListRepository($entityManager, $classMetadata); }