databaseId = $databaseId; $this->threadRootId = $threadRootId; } public static function fromRowData(int $id, string $subject, ?string $messageId, ?string $references, ?string $inReplyTo, ?string $threadRootId): self { $referencesForThreading = $references !== null ? json_decode($references, true) : []; if (!empty($inReplyTo)) { $referencesForThreading[] = $inReplyTo; } return new self( $id, $subject, $messageId, $referencesForThreading, $threadRootId ); } public function getDatabaseId(): int { return $this->databaseId; } public function getThreadRootId(): ?string { return $this->threadRootId; } public function setThreadRootId(?string $threadRootId): void { // Only update the thread ID if it has a value, is different and we haven't set one before if ($threadRootId !== null && $this->threadRootId !== $threadRootId && !$this->dirty) { $this->dirty = true; $this->threadRootId = $threadRootId; } } public function isDirty(): bool { return $this->dirty; } public function redact(callable $hash): DatabaseMessage { return new self( $this->databaseId, $this->hasReSubject() ? 'Re: ' . $hash($this->getSubject()) : $hash($this->getSubject()), $hash($this->getId()), array_map(static fn (string $ref) => $hash($ref), $this->getReferences()), $this->threadRootId === null ? null : $hash($this->threadRootId) ); } #[\Override] #[ReturnTypeWillChange] public function jsonSerialize() { return array_merge( parent::jsonSerialize(), [ 'databaseId' => $this->databaseId, 'threadRootId' => $this->getThreadRootId(), ] ); } }