From bb4149e092cb4cb004aa06fbf95850bcc3814aa6 Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Tue, 28 Dec 2021 04:39:09 +0000 Subject: [PATCH] [PLUGIN][AttachmentCollections] Restore functionality Some minor corrections --- .../Attachment/Controller/Attachment.php | 2 +- components/Collection/Collection.php | 11 ++++ .../Collection}/Entity/Collection.php | 15 ++--- .../AttachmentCollections.php | 62 ++++++++++--------- .../Controller/Controller.php | 46 ++++++++------ ...ntry.php => AttachmentCollectionEntry.php} | 19 +++++- .../collection.html.twig | 7 ++- .../collections.html.twig | 34 +++++----- .../AttachmentCollections/widget.html.twig | 3 +- 9 files changed, 118 insertions(+), 81 deletions(-) create mode 100644 components/Collection/Collection.php rename {plugins/AttachmentCollections => components/Collection}/Entity/Collection.php (80%) rename plugins/AttachmentCollections/Entity/{CollectionEntry.php => AttachmentCollectionEntry.php} (70%) diff --git a/components/Attachment/Controller/Attachment.php b/components/Attachment/Controller/Attachment.php index 934388d26f..3e363bc9b8 100644 --- a/components/Attachment/Controller/Attachment.php +++ b/components/Attachment/Controller/Attachment.php @@ -94,7 +94,7 @@ class Attachment extends Controller 'title' => $res['title'], 'attachment' => $res['attachment'], 'note' => $res['note'], - 'right_panel_vars' => ['attachment_id' => $attachment_id], + 'right_panel_vars' => ['attachment_id' => $attachment_id, 'note_id' => $note_id], ]; }); } catch (NotFoundException) { diff --git a/components/Collection/Collection.php b/components/Collection/Collection.php new file mode 100644 index 0000000000..e642fb6872 --- /dev/null +++ b/components/Collection/Collection.php @@ -0,0 +1,11 @@ +id; } - public function setName(?string $name): self + public function setName(string $name): self { - $this->name = \is_null($name) ? null : mb_substr($name, 0, 255); + $this->name = mb_substr($name, 0, 255); return $this; } - public function getName(): ?string + public function getName(): string { return $this->name; } @@ -54,10 +55,10 @@ class Collection extends Entity public static function schemaDef() { return [ - 'name' => 'attachment_collection', + 'name' => 'collection', 'fields' => [ 'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'], - 'name' => ['type' => 'varchar', 'length' => 255, 'description' => 'collection\'s name'], + 'name' => ['type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'collection\'s name'], 'actor_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Actor.id', 'multiplicity' => 'one to many', 'not null' => true, 'description' => 'foreign key to actor table'], ], 'primary key' => ['id'], diff --git a/plugins/AttachmentCollections/AttachmentCollections.php b/plugins/AttachmentCollections/AttachmentCollections.php index 4da2a08e95..90bc656909 100644 --- a/plugins/AttachmentCollections/AttachmentCollections.php +++ b/plugins/AttachmentCollections/AttachmentCollections.php @@ -33,7 +33,6 @@ namespace Plugin\AttachmentCollections; use App\Core\DB\DB; use App\Core\Event; -use App\Util\Exception\RedirectException; use App\Core\Form; use function App\Core\I18n\_m; use App\Core\Modules\Plugin; @@ -42,11 +41,12 @@ use App\Core\Router\Router; use App\Entity\Feed; use App\Entity\LocalUser; use App\Util\Common; +use App\Util\Exception\RedirectException; use App\Util\Formatting; use App\Util\Nickname; +use Component\Collection\Entity\Collection; use Plugin\AttachmentCollections\Controller as C; -use Plugin\AttachmentCollections\Entity\Collection; -use Plugin\AttachmentCollections\Entity\CollectionEntry; +use Plugin\AttachmentCollections\Entity\AttachmentCollectionEntry; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -80,6 +80,7 @@ class AttachmentCollections extends Plugin ); return Event::next; } + public function onCreateDefaultFeeds(int $actor_id, LocalUser $user, int &$ordering) { DB::persist(Feed::create([ @@ -91,6 +92,7 @@ class AttachmentCollections extends Plugin ])); return Event::next; } + /** * Append Attachment Collections widget to the right panel. * It's compose of two forms: one to select collections to add @@ -106,23 +108,23 @@ class AttachmentCollections extends Plugin return Event::next; } - $colls = DB::dql( - 'select coll from Plugin\AttachmentCollections\Entity\Collection coll where coll.actor_id = :id', - ['id' => $user->getId()], - ); + $collections = DB::findBy(Collection::class, ['actor_id' => $user->getId()]); // add to collection form $attachment_id = $vars['vars']['attachment_id']; + $note_id = $vars['vars']['note_id']; $choices = []; - foreach ($colls as $col) { + foreach ($collections as $col) { $choices[$col->getName()] = $col->getId(); } $already_selected = DB::dql( - 'select entry.collection_id from attachment_album_entry entry ' - . 'inner join attachment_collection collection ' - . 'with collection.id = entry.collection_id ' - . 'where entry.attachment_id = :aid and collection.actor_id = :id', - ['aid' => $attachment_id, 'id' => $user->getId()], + <<<'EOF' + SELECT entry.collection_id FROM \Plugin\AttachmentCollections\Entity\AttachmentCollectionEntry AS entry + INNER JOIN \Component\Collection\Entity\Collection AS attachment_collection + WITH attachment_collection.id = entry.collection_id + WHERE entry.attachment_id = :attach_id AND entry.note_id = :note_id AND attachment_collection.actor_id = :id + EOF, + ['attach_id' => $attachment_id, 'note_id' => $note_id, 'id' => $user->getId()], ); $already_selected = array_map(fn ($x) => $x['collection_id'], $already_selected); $add_form = Form::create([ @@ -150,24 +152,23 @@ class AttachmentCollections extends Plugin $collections = $add_form->getData()['collections']; $removed = array_filter($already_selected, fn ($x) => !\in_array($x, $collections)); $added = array_filter($collections, fn ($x) => !\in_array($x, $already_selected)); - if (\count($removed)) { - DB::dql( - 'delete from Plugin\AttachmentCollections\Entity\CollectionEntry entry ' - . 'where entry.attachment_id = :aid and entry.collection_id in (' - . 'select collection.id from Plugin\AttachmentCollections\Entity\Collection collection ' - . 'where collection.id in (:ids) ' - // prevent user from deleting something (s)he doesn't own: - . 'and collection.actor_id = :id' - . ')', - ['aid' => $attachment_id, 'id' => $user->getId(), 'ids' => $removed], - ); + if (\count($removed) > 0) { + DB::dql(<<<'EOF' + DELETE FROM \Plugin\AttachmentCollections\Entity\AttachmentCollectionEntry AS entry + WHERE entry.attachment_id = :attach_id AND entry.note_id = :note_id + AND entry.collection_id IN ( + SELECT album.id FROM \Component\Collection\Entity\Collection AS album + WHERE album.actor_id = :user_id + AND album.id IN (:ids) + ) + EOF, ['attach_id' => $attachment_id, 'note_id' => $note_id, 'user_id' => $user->getId(), 'ids' => $removed]); } - $collection_ids = array_map(fn ($x) => $x->getId(), $colls); foreach ($added as $cid) { // prevent user from putting something in a collection (s)he doesn't own: - if (\in_array($cid, $collection_ids)) { - DB::persist(CollectionEntry::create([ + if (\in_array($cid, $collections)) { + DB::persist(AttachmentCollectionEntry::create([ 'attachment_id' => $attachment_id, + 'note_id' => $note_id, 'collection_id' => $cid, ])); } @@ -200,9 +201,9 @@ class AttachmentCollections extends Plugin 'actor_id' => $user->getId(), ]); DB::persist($coll); - DB::flush(); - DB::persist(CollectionEntry::create([ + DB::persist(AttachmentCollectionEntry::create([ 'attachment_id' => $attachment_id, + 'note_id' => $note_id, 'collection_id' => $coll->getId(), ])); DB::flush(); @@ -212,13 +213,14 @@ class AttachmentCollections extends Plugin $res[] = Formatting::twigRenderFile( 'AttachmentCollections/widget.html.twig', [ - 'has_collections' => $colls, + 'has_collections' => $collections, 'add_form' => $add_form->createView(), 'create_form' => $create_form->createView(), ], ); return Event::next; } + /** * Output our dedicated stylesheet * diff --git a/plugins/AttachmentCollections/Controller/Controller.php b/plugins/AttachmentCollections/Controller/Controller.php index dda50f40f4..573b642604 100644 --- a/plugins/AttachmentCollections/Controller/Controller.php +++ b/plugins/AttachmentCollections/Controller/Controller.php @@ -24,13 +24,14 @@ declare(strict_types = 1); namespace Plugin\AttachmentCollections\Controller; use App\Core\DB\DB; -use App\Util\Exception\RedirectException; use App\Core\Form; use function App\Core\I18n\_m; use App\Core\Router\Router; +use App\Entity\LocalUser; use App\Util\Common; +use App\Util\Exception\RedirectException; +use Component\Collection\Entity\Collection; use Component\Feed\Util\FeedController; -use Plugin\AttachmentCollections\Entity\Collection; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\Request; @@ -39,13 +40,15 @@ class Controller extends FeedController { public function collectionsByActorNickname(Request $request, string $nickname): array { - $user = DB::findOneBy('local_user', ['nickname' => $nickname]); + $user = DB::findOneBy(LocalUser::class, ['nickname' => $nickname]); return self::collectionsView($request, $user->getId(), $nickname); } + public function collectionsViewByActorId(Request $request, int $id): array { return self::collectionsView($request, $id, null); } + /** * Generate Collections page * @@ -56,11 +59,8 @@ class Controller extends FeedController */ public function collectionsView(Request $request, int $id, ?string $nickname): array { - $collections = DB::dql( - 'select collection from Plugin\AttachmentCollections\Entity\Collection collection ' - . 'where collection.actor_id = :id', - ['id' => $id], - ); + $collections = DB::findBy(Collection::class, ['actor_id' => $id]); + // create collection form $create = null; if (Common::user()?->getId() === $id) { @@ -92,16 +92,17 @@ class Controller extends FeedController } // We need to inject some functions in twig, - // but i don't want to create an enviroment for this + // but I don't want to create an environment for this // as twig docs suggest in https://twig.symfony.com/doc/2.x/advanced.html#functions. // // Instead, I'm using an anonymous class to encapsulate - // the functions and passing how the class to the template. - // It's suggested at https://stackoverflow.com/a/50364502. + // the functions and passing that class to the template. + // This is suggested at https://stackoverflow.com/a/50364502. $fn = new class($id, $nickname, $request) { private $id; private $nick; private $request; + public function __construct($id, $nickname, $request) { $this->id = $id; @@ -156,6 +157,7 @@ class Controller extends FeedController } return $edit->createView(); } + // creating the remove form public function rmForm($collection) { @@ -189,23 +191,29 @@ class Controller extends FeedController public function collectionNotesByNickname(Request $request, string $nickname, int $cid): array { - $user = DB::findOneBy('local_user', ['nickname' => $nickname]); + $user = DB::findOneBy(LocalUser::class, ['nickname' => $nickname]); return self::collectionNotesByActorId($request, $user->getId(), $cid); } + public function collectionNotesByActorId(Request $request, int $id, int $cid): array { - $collection = DB::findOneBy('attachment_collection', ['id' => $cid]); - $attchs = DB::dql( - 'select attch from attachment_album_entry entry ' - . 'left join Component\Attachment\Entity\Attachment attch ' - . 'with entry.attachment_id = attch.id ' - . 'where entry.collection_id = :cid', + $collection = DB::findOneBy(Collection::class, ['id' => $cid]); + [$attachs, $notes] = DB::dql( + <<<'EOF' + SELECT attach, notice FROM \Plugin\AttachmentCollections\Entity\AttachmentCollectionEntry AS entry + LEFT JOIN \Component\Attachment\Entity\Attachment AS attach + WITH entry.attachment_id = attach.id + LEFT JOIN \App\Entity\Note AS notice + WITH entry.note_id = notice.id + WHERE entry.collection_id = :cid + EOF, ['cid' => $cid], ); return [ '_template' => 'AttachmentCollections/collection.html.twig', 'page_title' => $collection->getName(), - 'attachments' => $attchs, + 'attachments' => array_values($attachs), + 'bare_notes' => array_values($notes), ]; } } diff --git a/plugins/AttachmentCollections/Entity/CollectionEntry.php b/plugins/AttachmentCollections/Entity/AttachmentCollectionEntry.php similarity index 70% rename from plugins/AttachmentCollections/Entity/CollectionEntry.php rename to plugins/AttachmentCollections/Entity/AttachmentCollectionEntry.php index 0bee92d6e5..1a75e626ba 100644 --- a/plugins/AttachmentCollections/Entity/CollectionEntry.php +++ b/plugins/AttachmentCollections/Entity/AttachmentCollectionEntry.php @@ -6,12 +6,13 @@ namespace Plugin\AttachmentCollections\Entity; use App\Core\Entity; -class CollectionEntry extends Entity +class AttachmentCollectionEntry extends Entity { // These tags are meant to be literally included and will be populated with the appropriate fields, setters and getters by `bin/generate_entity_fields` // {{{ Autocode // @codeCoverageIgnoreStart private int $id; + private int $note_id; private int $attachment_id; private int $collection_id; @@ -26,6 +27,17 @@ class CollectionEntry extends Entity return $this->id; } + public function setNoteId(int $note_id): self + { + $this->note_id = $note_id; + return $this; + } + + public function getNoteId(): int + { + return $this->note_id; + } + public function setAttachmentId(int $attachment_id): self { $this->attachment_id = $attachment_id; @@ -54,11 +66,12 @@ class CollectionEntry extends Entity public static function schemaDef() { return [ - 'name' => 'attachment_album_entry', + 'name' => 'attachment_collection_entry', 'fields' => [ 'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'], + 'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to note table'], 'attachment_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Attachment.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to attachment table'], - 'collection_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'AttachmentCollection.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to attachment_collection table'], + 'collection_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Collection.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to collection table'], ], 'primary key' => ['id'], ]; diff --git a/plugins/AttachmentCollections/templates/AttachmentCollections/collection.html.twig b/plugins/AttachmentCollections/templates/AttachmentCollections/collection.html.twig index 6c55c0ecba..1e8ac4d579 100644 --- a/plugins/AttachmentCollections/templates/AttachmentCollections/collection.html.twig +++ b/plugins/AttachmentCollections/templates/AttachmentCollections/collection.html.twig @@ -13,10 +13,11 @@ {# Backwards compatibility with hAtom 0.1 #}
- {% for attachment in attachments %} + {% for key, attachment in attachments %}
- {% include '/cards/attachments/view.html.twig' with {'attachment': attachment, 'note': null} only%} - {{ 'Download link' | trans }} + {% include '/cards/attachments/view.html.twig' with {'attachment': attachment, 'note': bare_notes[key], 'title': attachment.getBestTitle(bare_notes[key])} only %} + {{ 'Download link' | trans }}
{% else %}

{% trans %}No attachments here.{% endtrans %}

diff --git a/plugins/AttachmentCollections/templates/AttachmentCollections/collections.html.twig b/plugins/AttachmentCollections/templates/AttachmentCollections/collections.html.twig index 27b303feae..edf42966df 100644 --- a/plugins/AttachmentCollections/templates/AttachmentCollections/collections.html.twig +++ b/plugins/AttachmentCollections/templates/AttachmentCollections/collections.html.twig @@ -20,23 +20,23 @@ {% endif %}

{{ 'Your collections' | trans }}

- {% for col in collections %} -
- {{ col.name }} -
- -
{{ icon('edit') | raw }}
-
- {{ form(fn.editForm(col)) }} -
-
- -
{{ icon('delete') | raw }}
-
- {{ form(fn.rmForm(col)) }} -
-
- {% endfor %} + {% for col in collections %} +
+ {{ col.name }} +
+ +
{{ icon('edit') | raw }}
+
+ {{ form(fn.editForm(col)) }} +
+
+ +
{{ icon('delete') | raw }}
+
+ {{ form(fn.rmForm(col)) }} +
+
+ {% endfor %}
diff --git a/plugins/AttachmentCollections/templates/AttachmentCollections/widget.html.twig b/plugins/AttachmentCollections/templates/AttachmentCollections/widget.html.twig index ae32110f9d..25fd7f9693 100644 --- a/plugins/AttachmentCollections/templates/AttachmentCollections/widget.html.twig +++ b/plugins/AttachmentCollections/templates/AttachmentCollections/widget.html.twig @@ -9,7 +9,8 @@ {{ form(add_form) }} -
+
{% trans %}Other options{% endtrans %} {{ icon('arrow-down', 'icon icon-details-close') | raw }}