. // }}} namespace Plugin\AttachmentCollections\Controller; use App\Core\DB\DB; use App\Core\Form; use function App\Core\I18n\_m; use App\Core\Router\Router; use App\Util\Common; 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; class Controller extends FeedController { public function collectionsByActorNickname(Request $request, string $nickname): array { $user = DB::findOneBy('local_user', ['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 * * @param int $id actor id * @param ?string $nickname actor nickname * * @return array twig template options */ 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], ); // create collection form $create = null; if (Common::user()?->getId() === $id) { $create = Form::create([ ['name', TextType::class, [ 'label' => _m('Create collection'), 'attr' => [ 'placeholder' => _m('Name'), 'required' => 'required', ], 'data' => '', ]], ['add_collection', SubmitType::class, [ 'label' => _m('Create collection'), 'attr' => [ 'title' => _m('Create collection'), ], ]], ]); $create->handleRequest($request); if ($create->isSubmitted() && $create->isValid()) { DB::persist(Collection::create([ 'name' => $create->getData()['name'], 'actor_id' => $id, ])); DB::flush(); } } // We need to inject some functions in twig, // but i don't want to create an enviroment 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. $fn = new class($id, $nickname, $request) { private $id; private $nick; private $request; public function __construct($id, $nickname, $request) { $this->id = $id; $this->nick = $nickname; $this->request = $request; } // there's already a injected function called path, // that maps to Router::url(name, args), but since // I want to preserve nicknames, I think it's better // to use that getUrl function public function getUrl($cid) { if (\is_null($this->nick)) { return Router::url( 'collection_notes_view_by_actor_id', ['id' => $this->id, 'cid' => $cid], ); } return Router::url( 'collection_notes_view_by_nickname', ['nickname' => $this->nick, 'cid' => $cid], ); } // There are many collections in this page and we need two // forms for each one of them: one form to edit the collection's // name and another to remove the collection. // creating the edit form public function editForm($collection) { $edit = Form::create([ ['name', TextType::class, [ 'attr' => [ 'placeholder' => 'New name', 'required' => 'required', ], 'data' => '', ]], ['update_' . $collection->getId(), SubmitType::class, [ 'label' => _m('Save'), 'attr' => [ 'title' => _m('Save'), ], ]], ]); $edit->handleRequest($this->request); if ($edit->isSubmitted() && $edit->isValid()) { $collection->setName($edit->getData()['name']); DB::persist($collection); DB::flush(); } return $edit->createView(); } // creating the remove form public function rmForm($collection) { $rm = Form::create([ ['remove_' . $collection->getId(), SubmitType::class, [ 'label' => _m('Delete collection'), 'attr' => [ 'title' => _m('Delete collection'), 'class' => 'danger', ], ]], ]); $rm->handleRequest($this->request); if ($rm->isSubmitted()) { DB::remove($collection); DB::flush(); } return $rm->createView(); } }; return [ '_template' => 'AttachmentCollections/collections.html.twig', 'page_title' => 'Attachment Collections list', 'add_collection' => $create?->createView(), 'fn' => $fn, 'collections' => $collections, ]; } public function collectionNotesByNickname(Request $request, string $nickname, int $cid): array { $user = DB::findOneBy('local_user', ['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', ['cid' => $cid], ); return [ '_template' => 'AttachmentCollections/collection.html.twig', 'page_title' => $collection->getName(), 'attachments' => $attchs, ]; } }