src/Kbin/Magazine/DTO/MagazineLogResponseDto.php
<?php
// SPDX-FileCopyrightText: 2023 /kbin contributors <https://kbin.pub/>
//
// SPDX-License-Identifier: AGPL-3.0-only
declare(strict_types=1);
namespace App\Kbin\Magazine\DTO;
use App\Entity\Entry;
use App\Entity\EntryComment;
use App\Entity\Post;
use App\Entity\PostComment;
use App\Kbin\Entry\DTO\EntryResponseDto;
use App\Kbin\Entry\Factory\EntryFactory;
use App\Kbin\EntryComment\DTO\EntryCommentResponseDto;
use App\Kbin\EntryComment\Factory\EntryCommentFactory;
use App\Kbin\Post\DTO\PostResponseDto;
use App\Kbin\Post\Factory\PostFactory;
use App\Kbin\PostComment\DTO\PostCommentResponseDto;
use App\Kbin\PostComment\Factory\PostCommentFactory;
use App\Kbin\User\DTO\UserSmallResponseDto;
use Nelmio\ApiDocBundle\Annotation\Model;
use OpenApi\Attributes as OA;
use Symfony\Component\Serializer\Annotation\Ignore;
#[OA\Schema()]
class MagazineLogResponseDto implements \JsonSerializable
{
public const LOG_TYPES = [
'log_entry_deleted',
'log_entry_restored',
'log_entry_comment_deleted',
'log_entry_comment_restored',
'log_post_deleted',
'log_post_restored',
'log_post_comment_deleted',
'log_post_comment_restored',
'log_ban',
'log_unban',
];
#[OA\Property(enum: self::LOG_TYPES)]
public ?string $type = null;
public ?\DateTimeImmutable $createdAt = null;
public ?MagazineSmallResponseDto $magazine = null;
public ?UserSmallResponseDto $moderator = null;
#[OA\Property(
'subject',
anyOf: [
new OA\Schema(ref: new Model(type: EntryResponseDto::class)),
new OA\Schema(ref: new Model(type: EntryCommentResponseDto::class)),
new OA\Schema(ref: new Model(type: PostResponseDto::class)),
new OA\Schema(ref: new Model(type: PostCommentResponseDto::class)),
new OA\Schema(ref: new Model(type: MagazineBanResponseDto::class)),
],
)]
public ?\JsonSerializable $subject = null;
public static function create(
MagazineSmallResponseDto $magazine,
UserSmallResponseDto $moderator,
\DateTimeImmutable $createdAt,
string $type,
MagazineBanResponseDto $subject = null,
): self {
$dto = new MagazineLogResponseDto();
$dto->magazine = $magazine;
$dto->moderator = $moderator;
$dto->createdAt = $createdAt;
$dto->type = $type;
if ('log_ban' === $type || 'log_unban' === $type) {
$dto->subject = $subject;
}
return $dto;
}
#[Ignore]
public function setSubject(
Entry|EntryComment|Post|PostComment|null $subject,
EntryFactory $entryFactory,
EntryCommentFactory $entryCommentFactory,
PostFactory $postFactory,
PostCommentFactory $postCommentFactory,
): void {
switch ($this->type) {
case 'log_entry_deleted':
case 'log_entry_restored':
\assert($subject instanceof Entry);
$this->subject = $entryFactory->createResponseDto($subject);
break;
case 'log_entry_comment_deleted':
case 'log_entry_comment_restored':
\assert($subject instanceof EntryComment);
$this->subject = $entryCommentFactory->createResponseDto($subject);
break;
case 'log_post_deleted':
case 'log_post_restored':
\assert($subject instanceof Post);
$this->subject = $postFactory->createResponseDto($subject);
break;
case 'log_post_comment_deleted':
case 'log_post_comment_restored':
\assert($subject instanceof PostComment);
$this->subject = $postCommentFactory->createResponseDto($subject);
break;
default:
break;
}
}
public function jsonSerialize(): mixed
{
return [
'type' => $this->type,
'createdAt' => $this->createdAt->format(\DateTimeInterface::ATOM),
'magazine' => $this->magazine,
'moderator' => $this->moderator,
'subject' => $this->subject,
];
}
}