123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- <?php
- declare(strict_types = 1);
- // {{{ License
- // This file is part of GNU social - https://www.gnu.org/software/social
- //
- // GNU social is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // GNU social is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with GNU social. If not, see <http://www.gnu.org/licenses/>.
- // }}}
- /**
- * Collections Controller for GNU social
- *
- * @package GNUsocial
- * @category Plugin
- *
- * @author Phablulo <phablulo@gmail.com>
- * @copyright 2018-2019, 2021 Free Software Foundation, Inc http://www.fsf.org
- * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
- */
- namespace Component\Collection\Util\Controller;
- use App\Core\DB\DB;
- use App\Core\Form;
- use function App\Core\I18n\_m;
- use App\Entity\LocalUser;
- use App\Util\Common;
- use App\Util\Exception\RedirectException;
- use Symfony\Component\Form\Extension\Core\Type\SubmitType;
- use Symfony\Component\Form\Extension\Core\Type\TextType;
- use Symfony\Component\HttpFoundation\Request;
- abstract class MetaCollectionController extends FeedController
- {
- protected string $slug = 'collectionsEntry';
- protected string $plural_slug = 'collectionsList';
- protected string $page_title = 'Collections';
- abstract public function getCollectionUrl(int $owner_id, string $owner_nickname, int $collection_id): string;
- abstract public function getCollectionItems(int $owner_id, $collection_id): array;
- abstract public function getCollectionsByActorId(int $owner_id): array;
- abstract public function getCollectionBy(int $owner_id, int $collection_id);
- abstract public function createCollection(int $owner_id, string $name);
- public function collectionsViewByActorNickname(Request $request, string $nickname): array
- {
- $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
- *
- * @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 = $this->getCollectionsByActorId($id);
- $create_title = _m('Create a ' . mb_strtolower(preg_replace('/([a-z0-9])([A-Z])/', '$1 $2', $this->slug)));
- $collections_title = _m('The ' . mb_strtolower(preg_replace('/([a-z0-9])([A-Z])/', '$1 $2', $this->plural_slug)));
- // create collection form
- $create = null;
- if (Common::user()?->getId() === $id) {
- $create = Form::create([
- ['name', TextType::class, [
- 'label' => $create_title,
- 'attr' => [
- 'placeholder' => _m('Name'),
- 'required' => 'required',
- ],
- 'data' => '',
- ]],
- ['add_collection', SubmitType::class, [
- 'label' => $create_title,
- 'attr' => [
- 'title' => $create_title,
- ],
- ]],
- ]);
- $create->handleRequest($request);
- if ($create->isSubmitted() && $create->isValid()) {
- $this->createCollection($id, $create->getData()['name']);
- DB::flush();
- throw new RedirectException();
- }
- }
- // We need to inject some functions in twig,
- // 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 that class to the template.
- // This is suggested at https://stackoverflow.com/a/50364502.
- $fn = new class($id, $nickname, $request, $this, $this->slug) {
- private $id;
- private $nick;
- private $request;
- private $parent;
- private $slug;
- public function __construct($id, $nickname, $request, $parent, $slug)
- {
- $this->id = $id;
- $this->nick = $nickname;
- $this->request = $request;
- $this->parent = $parent;
- $this->slug = $slug;
- }
- // there's already an 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)
- {
- return $this->parent->getCollectionUrl($this->id, $this->nick, $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()) {
- $this->parent->setCollectionName($this->id, $this->nick, $collection, $edit->getData()['name']);
- DB::flush();
- throw new RedirectException();
- }
- return $edit->createView();
- }
- // creating the remove form
- public function rmForm($collection)
- {
- $rm = Form::create([
- ['remove_' . $collection->getId(), SubmitType::class, [
- 'label' => _m('Delete ' . $this->slug),
- 'attr' => [
- 'title' => _m('Delete ' . $this->slug),
- 'class' => 'danger',
- ],
- ]],
- ]);
- $rm->handleRequest($this->request);
- if ($rm->isSubmitted()) {
- $this->parent->removeCollection($this->id, $this->nick, $collection);
- DB::flush();
- throw new RedirectException();
- }
- return $rm->createView();
- }
- };
- return [
- '_template' => 'collection/meta_collections.html.twig',
- 'page_title' => $this->page_title,
- 'list_title' => $collections_title,
- 'add_collection' => $create?->createView(),
- 'fn' => $fn,
- 'collections' => $collections,
- ];
- }
- public function collectionsEntryViewNotesByNickname(Request $request, string $nickname, int $cid): array
- {
- $user = DB::findOneBy(LocalUser::class, ['nickname' => $nickname]);
- return self::collectionsEntryViewNotesByActorId($request, $user->getId(), $cid);
- }
- public function collectionsEntryViewNotesByActorId(Request $request, int $id, int $cid): array
- {
- $collection = $this->getCollectionBy($id, $cid);
- $vars = $this->getCollectionItems($id, $cid);
- return array_merge([
- '_template' => 'collections/collection_entry_view.html.twig',
- 'page_title' => $collection->getName(),
- ], $vars);
- }
- }
|