From dcc867dad7062596eaf23a0c294b394641d8084b Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Fri, 10 Dec 2021 02:38:04 +0000 Subject: [PATCH] [COMPONENT][Attachment] Delete related --- components/Attachment/Attachment.php | 13 +++++ .../Attachment/Entity/ActorToAttachment.php | 48 ++++++++++++++++++ components/Attachment/Entity/Attachment.php | 24 ++++++++- .../Attachment/Entity/AttachmentToLink.php | 48 ++++++++++++++++++ .../Attachment/Entity/AttachmentToNote.php | 49 +++++++++++++++++++ 5 files changed, 180 insertions(+), 2 deletions(-) diff --git a/components/Attachment/Attachment.php b/components/Attachment/Attachment.php index fa6ba0f34c..76e9e53f45 100644 --- a/components/Attachment/Attachment.php +++ b/components/Attachment/Attachment.php @@ -21,11 +21,14 @@ declare(strict_types = 1); namespace Component\Attachment; +use App\Core\Cache; use App\Core\Event; use App\Core\Modules\Component; use App\Core\Router\RouteLoader; +use App\Entity\Note; use Component\Attachment\Controller as C; use Component\Attachment\Entity as E; +use Component\Attachment\Entity\AttachmentToNote; class Attachment extends Component { @@ -48,4 +51,14 @@ class Attachment extends Component $out_hash = hash_file(E\Attachment::FILEHASH_ALGO, $filename); return Event::stop; } + + public function onNoteDeleteRelated(Note &$note): bool + { + Cache::delete("note-attachments-{$note->getId()}"); + E\AttachmentToNote::removeWhereNoteId($note->getId()); + foreach($note->getAttachments() as $attachment) { + $attachment->kill(); + } + return Event::next; + } } diff --git a/components/Attachment/Entity/ActorToAttachment.php b/components/Attachment/Entity/ActorToAttachment.php index 7c959b8f80..2a2c4630fd 100644 --- a/components/Attachment/Entity/ActorToAttachment.php +++ b/components/Attachment/Entity/ActorToAttachment.php @@ -19,6 +19,7 @@ namespace Component\Attachment\Entity; +use App\Core\DB\DB; use App\Core\Entity; use DateTimeInterface; @@ -76,6 +77,53 @@ class ActorToAttachment extends Entity // @codeCoverageIgnoreEnd // }}} Autocode + /** + * @param int $attachment_id + * @return mixed + */ + public static function removeWhereAttachmentId(int $attachment_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM actor_to_attachment ata + WHERE ata.attachment_id = :attachment_id + EOF, + ['attachment_id' => $attachment_id], + ); + } + + /** + * @param int $actor_id + * @param int $attachment_id + * @return mixed + */ + public static function removeWhere(int $attachment_id, int $actor_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM actor_to_attachment ata + WHERE (ata.attachment_id = :attachment_id + OR ata.actor_id = :actor_id) + EOF, + ['attachment_id' => $attachment_id, 'actor_id' => $actor_id], + ); + } + + /** + * @param int $actor_id + * @return mixed + */ + public static function removeWhereActorId(int $actor_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM actor_to_attachment ata + WHERE ata.actor_id = :actor_id + EOF, + ['actor_id' => $actor_id], + ); + } + public static function schemaDef(): array { return [ diff --git a/components/Attachment/Entity/Attachment.php b/components/Attachment/Entity/Attachment.php index 297f67b5d5..bbc4e60abb 100644 --- a/components/Attachment/Entity/Attachment.php +++ b/components/Attachment/Entity/Attachment.php @@ -248,24 +248,42 @@ class Attachment extends Entity /** * Attachment delete always removes dependencies, cleanups and flushes + * @see kill() It's more likely that you want to use that rather than call delete directly */ protected function delete(): bool { + // Friendly warning because the caller usually doesn't want to delete an attachment that is still referred elsewhere if ($this->getLives() > 0) { // @codeCoverageIgnoreStart - Log::warning("Deleting file {$this->getId()} with {$this->getLives()} lives. Why are you killing it so young?"); + Log::warning("Deleting file {$this->getId()} with {$this->getLives()} lives. Why are you killing it so old?"); // @codeCoverageIgnoreEnd } - // Delete related files from storage + + // Collect files starting with the one associated with this attachment $files = []; if (!is_null($filepath = $this->getPath())) { $files[] = $filepath; } + + // Collect thumbnail files and delete thumbnails foreach ($this->getThumbnails() as $at) { $files[] = $at->getPath(); $at->delete(flush: false); } + + // Delete eventual remaining relations with Actors + ActorToAttachment::removeWhereAttachmentId($this->getId()); + + // Delete eventual remaining relations with Notes + AttachmentToNote::removeWhereAttachmentId($this->getId()); + + // Delete eventual remaining relations with Links + AttachmentToLink::removeWhereAttachmentId($this->getId()); + + // Remove this attachment DB::remove($this); + + // Delete the files from disk foreach ($files as $f) { if (file_exists($f)) { if (@unlink($f) === false) { @@ -279,6 +297,8 @@ class Attachment extends Entity // @codeCoverageIgnoreEnd } } + + // Flush these changes as we have deleted the files from disk DB::flush(); return true; } diff --git a/components/Attachment/Entity/AttachmentToLink.php b/components/Attachment/Entity/AttachmentToLink.php index 576bb6e9a9..56b9c5f80c 100644 --- a/components/Attachment/Entity/AttachmentToLink.php +++ b/components/Attachment/Entity/AttachmentToLink.php @@ -19,6 +19,7 @@ namespace Component\Attachment\Entity; +use App\Core\DB\DB; use App\Core\Entity; use DateTimeInterface; @@ -76,6 +77,53 @@ class AttachmentToLink extends Entity // @codeCoverageIgnoreEnd // }}} Autocode + /** + * @param int $attachment_id + * @return mixed + */ + public static function removeWhereAttachmentId(int $attachment_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM attachment_to_link atl + WHERE atl.attachment_id = :attachment_id + EOF, + ['attachment_id' => $attachment_id], + ); + } + + /** + * @param int $link_id + * @param int $attachment_id + * @return mixed + */ + public static function removeWhere(int $link_id, int $attachment_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM attachment_to_link atl + WHERE (atl.link_id = :link_id + OR atl.attachment_id = :attachment_id) + EOF, + ['link_id' => $link_id, 'attachment_id' => $attachment_id], + ); + } + + /** + * @param int $link_id + * @return mixed + */ + public static function removeWhereLinkId(int $link_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM attachment_to_link atl + WHERE atl.link_id = :link_id + EOF, + ['link_id' => $link_id], + ); + } + public static function schemaDef(): array { return [ diff --git a/components/Attachment/Entity/AttachmentToNote.php b/components/Attachment/Entity/AttachmentToNote.php index 6d039098f1..a03fcaf39b 100644 --- a/components/Attachment/Entity/AttachmentToNote.php +++ b/components/Attachment/Entity/AttachmentToNote.php @@ -19,6 +19,8 @@ namespace Component\Attachment\Entity; +use App\Core\Cache; +use App\Core\DB\DB; use App\Core\Entity; use DateTimeInterface; @@ -92,6 +94,53 @@ class AttachmentToNote extends Entity // @codeCoverageIgnoreEnd // }}} Autocode + /** + * @param int $note_id + * @param int $attachment_id + * @return mixed + */ + public static function removeWhere(int $note_id, int $attachment_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM attachment_to_note atn + WHERE (atn.attachment_id = :attachment_id + OR atn.note_id = :note_id) + EOF, + ['note_id' => $note_id, 'attachment_id' => $attachment_id], + ); + } + + /** + * @param int $note_id + * @return mixed + */ + public static function removeWhereNoteId(int $note_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM attachment_to_note atn + WHERE atn.note_id = :note_id + EOF, + ['note_id' => $note_id], + ); + } + + /** + * @param int $attachment_id + * @return mixed + */ + public static function removeWhereAttachmentId(int $attachment_id): mixed + { + return DB::dql( + <<<'EOF' + DELETE FROM attachment_to_note atn + WHERE atn.attachment_id = :attachment_id + EOF, + ['attachment_id' => $attachment_id], + ); + } + public static function schemaDef(): array { return [