From c3f8d07c92ff4c2777b1aaf4f47d0988c1a45bfb Mon Sep 17 00:00:00 2001 From: Martin Chaine Date: Tue, 3 Jun 2025 09:42:44 +0200 Subject: [PATCH] introduce the EntryDeletion entity --- migrations/Version20250530183653.php | 37 ++++++ src/Entity/EntryDeletion.php | 107 ++++++++++++++++++ .../Subscriber/EntryDeletionSubscriber.php | 36 ++++++ .../EntryDeletionSubscriberTest.php | 45 ++++++++ 4 files changed, 225 insertions(+) create mode 100644 migrations/Version20250530183653.php create mode 100644 src/Entity/EntryDeletion.php create mode 100644 src/Event/Subscriber/EntryDeletionSubscriber.php create mode 100644 tests/Event/Subscriber/EntryDeletionSubscriberTest.php diff --git a/migrations/Version20250530183653.php b/migrations/Version20250530183653.php new file mode 100644 index 000000000..4f8eb201c --- /dev/null +++ b/migrations/Version20250530183653.php @@ -0,0 +1,37 @@ +addSql(<<<'SQL' + CREATE TABLE "wallabag_entry_deletion" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user_id INTEGER DEFAULT NULL, entry_id INTEGER NOT NULL, deleted_at DATETIME NOT NULL, CONSTRAINT FK_D91765D5A76ED395 FOREIGN KEY (user_id) REFERENCES "wallabag_user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE) + SQL); + $this->addSql(<<<'SQL' + CREATE INDEX IDX_D91765D5A76ED395 ON "wallabag_entry_deletion" (user_id) + SQL); + $this->addSql(<<<'SQL' + CREATE INDEX IDX_D91765D54AF38FD1 ON "wallabag_entry_deletion" (deleted_at) + SQL); + $this->addSql(<<<'SQL' + CREATE INDEX IDX_D91765D5A76ED3954AF38FD1 ON "wallabag_entry_deletion" (user_id, deleted_at) + SQL); + } + + public function down(Schema $schema): void + { + $this->addSql(<<<'SQL' + DROP TABLE "wallabag_entry_deletion" + SQL); + } +} diff --git a/src/Entity/EntryDeletion.php b/src/Entity/EntryDeletion.php new file mode 100644 index 000000000..95f1d4c39 --- /dev/null +++ b/src/Entity/EntryDeletion.php @@ -0,0 +1,107 @@ +user = $user; + $this->entryId = $entryId; + $this->deletedAt = new \DateTime(); + } + + /** + * Get id. + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Get entryId. + * + * @return int + */ + public function getEntryId() + { + return $this->entryId; + } + + /** + * @return User + */ + public function getUser() + { + return $this->user; + } + + /** + * @return \DateTimeInterface + */ + public function getDeletedAt() + { + return $this->deletedAt; + } + + /** + * Set deleted_at. + * + * @return EntryDeletion + */ + public function setDeletedAt(\DateTimeInterface $deletedAt) + { + $this->deletedAt = $deletedAt; + + return $this; + } + + /** + * Create an EntryDeletion from an Entry that's being deleted. + */ + public static function createFromEntry(Entry $entry): self + { + return new self($entry->getUser(), $entry->getId()); + } +} diff --git a/src/Event/Subscriber/EntryDeletionSubscriber.php b/src/Event/Subscriber/EntryDeletionSubscriber.php new file mode 100644 index 000000000..e9252559e --- /dev/null +++ b/src/Event/Subscriber/EntryDeletionSubscriber.php @@ -0,0 +1,36 @@ + 'onEntryDeleted', + ]; + } + + /** + * Create a deletion event record for the entry. + */ + public function onEntryDeleted(EntryDeletedEvent $event): void + { + $entry = $event->getEntry(); + + $deletionEvent = EntryDeletion::createFromEntry($entry); + + $this->em->persist($deletionEvent); + $this->em->flush(); + } +} diff --git a/tests/Event/Subscriber/EntryDeletionSubscriberTest.php b/tests/Event/Subscriber/EntryDeletionSubscriberTest.php new file mode 100644 index 000000000..eb0eb2037 --- /dev/null +++ b/tests/Event/Subscriber/EntryDeletionSubscriberTest.php @@ -0,0 +1,45 @@ +getProperty('id'); + $property->setAccessible(true); + $property->setValue($entry, 123); + + $em = $this->createMock(EntityManagerInterface::class); + + // when the event is triggered, an EntryDeletion should be persisted and flushed + $em->expects($this->once()) + ->method('persist') + ->with($this->callback(function ($deletion) use ($entry) { + return $deletion instanceof EntryDeletion + && $deletion->getEntryId() === $entry->getId() + && $deletion->getUser() === $entry->getUser(); + })); + $em->expects($this->atLeastOnce()) + ->method('flush'); + + // trigger the event to run the mocked up persist and flush + /** @var EntityManagerInterface $em */ + $subscriber = new EntryDeletionSubscriber($em); + $event = new EntryDeletedEvent($entry); + $subscriber->onEntryDeleted($event); + } +}