Files
Lesstime/src/Module/Mail/Domain/Entity/MailMessage.php
T
Matthieu 25d3a693f9 feat(mail) : migrate Mail integration into module (back)
LST-67 (2.5) backend. Behaviour-preserving move of the IMAP mail integration
into src/Module/Mail/. All /api/mail/* routes, securities (ROLE_CLIENT still
excluded via MailAccessChecker) and the async sync are unchanged.

- 4 entities + 4 repositories (Domain interfaces + Doctrine impls, bound).
  TaskMailLink.task now references TaskInterface (contract) instead of the
  concrete PM Task. Link/unlink/list-mails controllers load tasks via
  TaskRepositoryInterface; MailCreateTaskController keeps the concrete Task
  (instantiation) — documented Mail->PM coupling.
- Domain (MailProviderInterface, exception), Application (5 DTOs, MailSyncService,
  MailSyncRequested message + handler), Infrastructure (ImapMailProvider +
  MimeHeaderDecoder, MailAccessChecker, 2 console commands, 12 controllers,
  ApiPlatform state + MailSettings resource). TokenEncryptor stays shared.
- doctrine mapping Mail; messenger routing repointed; services.yaml repo +
  provider bindings; MailModule registered (id mail, mail.access/configure).
- #[Auditable] + Timestampable on MailConfiguration only (additive migration);
  IMAP data entities keep their own sync timestamps.

163 tests green, mapping valid, no route regression, cs-fixer clean.
2026-06-20 19:44:19 +02:00

240 lines
5.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Module\Mail\Domain\Entity;
use App\Module\Mail\Infrastructure\Doctrine\DoctrineMailMessageRepository;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: DoctrineMailMessageRepository::class)]
#[ORM\Table(name: 'mail_message')]
#[ORM\UniqueConstraint(name: 'uq_mail_message_folder_uid', columns: ['folder_id', 'uid'])]
#[ORM\Index(columns: ['sent_at'], name: 'idx_mail_message_sent_at')]
#[ORM\Index(columns: ['is_read'], name: 'idx_mail_message_is_read')]
#[ORM\Index(columns: ['message_id'], name: 'idx_mail_message_message_id')]
class MailMessage
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 500)]
private string $messageId;
#[ORM\ManyToOne(targetEntity: MailFolder::class)]
#[ORM\JoinColumn(name: 'folder_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
private MailFolder $folder;
#[ORM\Column]
private int $uid;
#[ORM\Column(length: 500, nullable: true)]
private ?string $subject = null;
#[ORM\Column(length: 255)]
private string $fromAddress;
#[ORM\Column(length: 255, nullable: true)]
private ?string $fromName = null;
#[ORM\Column(type: 'json')]
private array $toAddresses = [];
#[ORM\Column(type: 'json', nullable: true)]
private ?array $ccAddresses = null;
#[ORM\Column(type: 'datetimetz_immutable')]
private DateTimeImmutable $sentAt;
#[ORM\Column(type: 'boolean')]
private bool $isRead = false;
#[ORM\Column(type: 'boolean')]
private bool $isFlagged = false;
#[ORM\Column(type: 'boolean')]
private bool $hasAttachments = false;
#[ORM\Column(type: 'text', nullable: true)]
private ?string $snippet = null;
#[ORM\Column(type: 'datetimetz_immutable')]
private DateTimeImmutable $syncedAt;
public function getId(): ?int
{
return $this->id;
}
public function getMessageId(): string
{
return $this->messageId;
}
public function setMessageId(string $messageId): static
{
$this->messageId = $messageId;
return $this;
}
public function getFolder(): MailFolder
{
return $this->folder;
}
public function setFolder(MailFolder $folder): static
{
$this->folder = $folder;
return $this;
}
public function getUid(): int
{
return $this->uid;
}
public function setUid(int $uid): static
{
$this->uid = $uid;
return $this;
}
public function getSubject(): ?string
{
return $this->subject;
}
public function setSubject(?string $subject): static
{
$this->subject = $subject;
return $this;
}
public function getFromAddress(): string
{
return $this->fromAddress;
}
public function setFromAddress(string $fromAddress): static
{
$this->fromAddress = $fromAddress;
return $this;
}
public function getFromName(): ?string
{
return $this->fromName;
}
public function setFromName(?string $fromName): static
{
$this->fromName = $fromName;
return $this;
}
public function getToAddresses(): array
{
return $this->toAddresses;
}
public function setToAddresses(array $toAddresses): static
{
$this->toAddresses = $toAddresses;
return $this;
}
public function getCcAddresses(): ?array
{
return $this->ccAddresses;
}
public function setCcAddresses(?array $ccAddresses): static
{
$this->ccAddresses = $ccAddresses;
return $this;
}
public function getSentAt(): DateTimeImmutable
{
return $this->sentAt;
}
public function setSentAt(DateTimeImmutable $sentAt): static
{
$this->sentAt = $sentAt;
return $this;
}
public function isRead(): bool
{
return $this->isRead;
}
public function setIsRead(bool $isRead): static
{
$this->isRead = $isRead;
return $this;
}
public function isFlagged(): bool
{
return $this->isFlagged;
}
public function setIsFlagged(bool $isFlagged): static
{
$this->isFlagged = $isFlagged;
return $this;
}
public function hasAttachments(): bool
{
return $this->hasAttachments;
}
public function setHasAttachments(bool $hasAttachments): static
{
$this->hasAttachments = $hasAttachments;
return $this;
}
public function getSnippet(): ?string
{
return $this->snippet;
}
public function setSnippet(?string $snippet): static
{
$this->snippet = $snippet;
return $this;
}
public function getSyncedAt(): DateTimeImmutable
{
return $this->syncedAt;
}
public function setSyncedAt(DateTimeImmutable $syncedAt): static
{
$this->syncedAt = $syncedAt;
return $this;
}
}