Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions migrations/Version20260225095315.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20260225095315 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add magazine log columns for the purged classes';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE magazine_log ADD author_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE magazine_log ADD title VARCHAR(255) DEFAULT NULL');
$this->addSql('ALTER TABLE magazine_log ADD CONSTRAINT FK_87D3D4C5F675F31B FOREIGN KEY (author_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please name the constraint and index with a meaningful name

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the doctrine generated ones. Afaik if I rename them to something else, doctrine will try to regenerate them in every diff... I can try if that it true

$this->addSql('CREATE INDEX IDX_87D3D4C5F675F31B ON magazine_log (author_id)');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE magazine_log DROP CONSTRAINT FK_87D3D4C5F675F31B');
$this->addSql('DROP INDEX IDX_87D3D4C5F675F31B');
$this->addSql('ALTER TABLE magazine_log DROP author_id');
$this->addSql('ALTER TABLE magazine_log DROP title');
$this->addSql('ALTER TABLE magazine_log DROP short_body');
}
}
2 changes: 1 addition & 1 deletion src/Controller/ModlogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function instance(Request $request): Response
{
$dto = new ModlogFilterDto();
$dto->magazine = null;
$form = $this->createForm(ModlogFilterType::class, $dto, ['method' => 'GET']);
$form = $this->createForm(ModlogFilterType::class, $dto, ['method' => 'GET', 'csrf_protection' => false]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var ModlogFilterDto $dto */
Expand Down
17 changes: 14 additions & 3 deletions src/DTO/MagazineLogResponseDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@
#[OA\Schema()]
class MagazineLogResponseDto implements \JsonSerializable
{
public const LOG_TYPES = [
public const array LOG_TYPES = [
'log_entry_deleted',
'log_entry_restored',
'log_entry_purged',
'log_entry_comment_deleted',
'log_entry_comment_restored',
'log_entry_comment_purged',
'log_post_deleted',
'log_post_restored',
'log_post_purged',
'log_post_comment_deleted',
'log_post_comment_restored',
'log_post_comment_purged',
'log_ban',
'log_unban',
'log_entry_pinned',
Expand All @@ -48,11 +52,17 @@ class MagazineLogResponseDto implements \JsonSerializable
* - PostCommentResponseDto when type is 'log_post_comment_deleted' or 'log_post_comment_restored'
* - MagazineBanResponseDto when type is 'log_ban' or 'log_unban'
* - UserSmallResponseDto when type is 'log_moderator_add' or 'log_moderator_remove'
* - string when type is 'log_entry_purged', 'log_entry_comment_purged', 'log_post_purged' or 'log_post_comment_purged'
*/
#[OA\Property('subject')]
// If this property is named 'subject' the api doc generator will not pick it up.
// It is still serialized as 'subject', see the jsonSerialize method.
public EntryResponseDto|EntryCommentResponseDto|PostResponseDto|PostCommentResponseDto|MagazineBanResponseDto|UserSmallResponseDto|null $subject2 = null;
public EntryResponseDto|EntryCommentResponseDto|PostResponseDto|PostCommentResponseDto|MagazineBanResponseDto|UserSmallResponseDto|string|null $subject2 = null;

/**
* Only set if the subject is a string, otherwise the author information is contained within the subject.
*/
public ?UserSmallResponseDto $subjectAuthor = null;

public static function create(
MagazineSmallResponseDto $magazine,
Expand Down Expand Up @@ -139,7 +149,8 @@ public function jsonSerialize(): mixed
'createdAt' => $this->createdAt->format(\DateTimeInterface::ATOM),
'magazine' => $this->magazine,
'moderator' => $this->moderator,
'subject' => $this->subject2?->jsonSerialize(),
'subject' => \is_string($this->subject2) ? $this->subject2 : $this->subject2?->jsonSerialize(),
'subjectAuthor' => $this->subjectAuthor?->jsonSerialize(),
];
}
}
12 changes: 10 additions & 2 deletions src/Entity/MagazineLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,21 @@ abstract class MagazineLog
CreatedAtTrait::__construct as createdAtTraitConstruct;
}

public const DISCRIMINATOR_MAP = [
public const array DISCRIMINATOR_MAP = [
'entry_deleted' => MagazineLogEntryDeleted::class,
'entry_restored' => MagazineLogEntryRestored::class,
'entry_purged' => MagazineLogEntryPurged::class,
'entry_comment_deleted' => MagazineLogEntryCommentDeleted::class,
'entry_comment_restored' => MagazineLogEntryCommentRestored::class,
'entry_comment_purged' => MagazineLogEntryCommentPurged::class,
'entry_pinned' => MagazineLogEntryPinned::class,
'entry_unpinned' => MagazineLogEntryUnpinned::class,
'post_deleted' => MagazineLogPostDeleted::class,
'post_restored' => MagazineLogPostRestored::class,
'post_purged' => MagazineLogPostPurged::class,
'post_comment_deleted' => MagazineLogPostCommentDeleted::class,
'post_comment_restored' => MagazineLogPostCommentRestored::class,
'post_comment_purged' => MagazineLogPostCommentPurged::class,
'ban' => MagazineLogBan::class,
'moderator_add' => MagazineLogModeratorAdd::class,
'moderator_remove' => MagazineLogModeratorRemove::class,
Expand All @@ -47,17 +51,21 @@ abstract class MagazineLog
'post_unlocked' => MagazineLogPostUnlocked::class,
];

public const CHOICES = [
public const array CHOICES = [
'entry_deleted',
'entry_restored',
'entry_purged',
'entry_comment_deleted',
'entry_comment_restored',
'entry_comment_purged',
'entry_pinned',
'entry_unpinned',
'post_deleted',
'post_restored',
'post_purged',
'post_comment_deleted',
'post_comment_restored',
'post_comment_purged',
'ban',
'moderator_add',
'moderator_remove',
Expand Down
44 changes: 44 additions & 0 deletions src/Entity/MagazineLogEntryCommentPurged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace App\Entity;

use App\Entity\Contracts\ContentInterface;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;

#[Entity]
class MagazineLogEntryCommentPurged extends MagazineLog
{
#[Column(type: 'string', length: Entry::MAX_TITLE_LENGTH)]
public string $title;

#[JoinColumn(onDelete: 'CASCADE')]
#[ManyToOne(targetEntity: User::class)]
public User $author;

public function __construct(Magazine $magazine, User $user, string $title, User $author)
{
parent::__construct($magazine, $user);
$this->title = $title;
$this->author = $author;
}

public function getSubject(): ?ContentInterface
{
return null;
}

public function clearSubject(): MagazineLog
{
return $this;
}

public function getType(): string
{
return 'log_entry_comment_purged';
}
}
44 changes: 44 additions & 0 deletions src/Entity/MagazineLogEntryPurged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace App\Entity;

use App\Entity\Contracts\ContentInterface;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;

#[Entity]
class MagazineLogEntryPurged extends MagazineLog
{
#[Column(type: 'string', length: Entry::MAX_TITLE_LENGTH)]
public string $title;

#[JoinColumn(onDelete: 'CASCADE')]
#[ManyToOne(targetEntity: User::class)]
public User $author;

public function __construct(Magazine $magazine, User $user, string $title, User $author)
{
parent::__construct($magazine, $user);
$this->title = $title;
$this->author = $author;
}

public function getSubject(): ?ContentInterface
{
return null;
}

public function clearSubject(): MagazineLog
{
return $this;
}

public function getType(): string
{
return 'log_entry_purged';
}
}
44 changes: 44 additions & 0 deletions src/Entity/MagazineLogPostCommentPurged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace App\Entity;

use App\Entity\Contracts\ContentInterface;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;

#[Entity]
class MagazineLogPostCommentPurged extends MagazineLog
{
#[Column(type: 'string', length: Entry::MAX_TITLE_LENGTH)]
public string $title;

#[JoinColumn(onDelete: 'CASCADE')]
#[ManyToOne(targetEntity: User::class)]
public User $author;

public function __construct(Magazine $magazine, User $user, string $title, User $author)
{
parent::__construct($magazine, $user);
$this->title = $title;
$this->author = $author;
}

public function getSubject(): ?ContentInterface
{
return null;
}

public function clearSubject(): MagazineLog
{
return $this;
}

public function getType(): string
{
return 'log_post_comment_purged';
}
}
44 changes: 44 additions & 0 deletions src/Entity/MagazineLogPostPurged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace App\Entity;

use App\Entity\Contracts\ContentInterface;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;

#[Entity]
class MagazineLogPostPurged extends MagazineLog
{
#[Column(type: 'string', length: Entry::MAX_TITLE_LENGTH)]
public string $title;

#[JoinColumn(onDelete: 'CASCADE')]
#[ManyToOne(targetEntity: User::class)]
public User $author;

public function __construct(Magazine $magazine, User $user, string $title, User $author)
{
parent::__construct($magazine, $user);
$this->title = $title;
$this->author = $author;
}

public function getSubject(): ?ContentInterface
{
return null;
}

public function clearSubject(): MagazineLog
{
return $this;
}

public function getType(): string
{
return 'log_post_purged';
}
}
Loading
Loading