[COMPONENT][Attachment] Delete related

This commit is contained in:
Diogo Peralta Cordeiro 2021-12-10 02:38:04 +00:00
parent 5f167517ad
commit dcc867dad7
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0
5 changed files with 180 additions and 2 deletions

View File

@ -21,11 +21,14 @@ declare(strict_types = 1);
namespace Component\Attachment; namespace Component\Attachment;
use App\Core\Cache;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Core\Router\RouteLoader; use App\Core\Router\RouteLoader;
use App\Entity\Note;
use Component\Attachment\Controller as C; use Component\Attachment\Controller as C;
use Component\Attachment\Entity as E; use Component\Attachment\Entity as E;
use Component\Attachment\Entity\AttachmentToNote;
class Attachment extends Component class Attachment extends Component
{ {
@ -48,4 +51,14 @@ class Attachment extends Component
$out_hash = hash_file(E\Attachment::FILEHASH_ALGO, $filename); $out_hash = hash_file(E\Attachment::FILEHASH_ALGO, $filename);
return Event::stop; 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;
}
} }

View File

@ -19,6 +19,7 @@
namespace Component\Attachment\Entity; namespace Component\Attachment\Entity;
use App\Core\DB\DB;
use App\Core\Entity; use App\Core\Entity;
use DateTimeInterface; use DateTimeInterface;
@ -76,6 +77,53 @@ class ActorToAttachment extends Entity
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
// }}} Autocode // }}} 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 public static function schemaDef(): array
{ {
return [ return [

View File

@ -248,24 +248,42 @@ class Attachment extends Entity
/** /**
* Attachment delete always removes dependencies, cleanups and flushes * 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 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) { if ($this->getLives() > 0) {
// @codeCoverageIgnoreStart // @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 // @codeCoverageIgnoreEnd
} }
// Delete related files from storage
// Collect files starting with the one associated with this attachment
$files = []; $files = [];
if (!is_null($filepath = $this->getPath())) { if (!is_null($filepath = $this->getPath())) {
$files[] = $filepath; $files[] = $filepath;
} }
// Collect thumbnail files and delete thumbnails
foreach ($this->getThumbnails() as $at) { foreach ($this->getThumbnails() as $at) {
$files[] = $at->getPath(); $files[] = $at->getPath();
$at->delete(flush: false); $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); DB::remove($this);
// Delete the files from disk
foreach ($files as $f) { foreach ($files as $f) {
if (file_exists($f)) { if (file_exists($f)) {
if (@unlink($f) === false) { if (@unlink($f) === false) {
@ -279,6 +297,8 @@ class Attachment extends Entity
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
} }
} }
// Flush these changes as we have deleted the files from disk
DB::flush(); DB::flush();
return true; return true;
} }

View File

@ -19,6 +19,7 @@
namespace Component\Attachment\Entity; namespace Component\Attachment\Entity;
use App\Core\DB\DB;
use App\Core\Entity; use App\Core\Entity;
use DateTimeInterface; use DateTimeInterface;
@ -76,6 +77,53 @@ class AttachmentToLink extends Entity
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
// }}} Autocode // }}} 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 public static function schemaDef(): array
{ {
return [ return [

View File

@ -19,6 +19,8 @@
namespace Component\Attachment\Entity; namespace Component\Attachment\Entity;
use App\Core\Cache;
use App\Core\DB\DB;
use App\Core\Entity; use App\Core\Entity;
use DateTimeInterface; use DateTimeInterface;
@ -92,6 +94,53 @@ class AttachmentToNote extends Entity
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
// }}} Autocode // }}} 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 public static function schemaDef(): array
{ {
return [ return [