diff --git a/src/Builder/CapsuleBuilder.php b/src/Builder/CapsuleBuilder.php index b219d3bcab024d36e363d369c50fbf8a9c5f7d95..d3eda494ea0ac71018c4327da6449714a47ebfdd 100755 --- a/src/Builder/CapsuleBuilder.php +++ b/src/Builder/CapsuleBuilder.php @@ -3,6 +3,7 @@ namespace App\Builder; use App\Entity\Capsule; +use App\Entity\Group; use App\Entity\User; use App\Helper\ContractHelper; @@ -90,6 +91,12 @@ class CapsuleBuilder return $this; } + public function withGroup(Group $group): CapsuleBuilder + { + $this->capsule->addGroup($group); + return $this; + } + public function createCapsule(): Capsule { $this->createEditionLink(); diff --git a/src/Controller/CapsuleController.php b/src/Controller/CapsuleController.php index 0bf9c029daa2fb2e7a0d1e3c6bc165d2e000d0a0..15fa5a497ef95b2de0768f4ae360dc0c5051197c 100755 --- a/src/Controller/CapsuleController.php +++ b/src/Controller/CapsuleController.php @@ -12,6 +12,9 @@ use App\Helper\StringHelper; use App\Repository\CapsuleRepository; use App\Builder\CapsuleBuilder; use App\Form\CreateCapsuleFormType; +use App\Repository\GroupRepository; +use ArrayObject; +use Doctrine\ORM\EntityManagerInterface; use Knp\Component\Pager\PaginatorInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Filesystem\Filesystem; @@ -26,13 +29,16 @@ class CapsuleController extends AbstractController { private CapsuleRepository $capsule_repository; private TranslatorInterface $translator; + private EntityManagerInterface $entity_manager; public function __construct( CapsuleRepository $capsule_repository, - TranslatorInterface $translator + TranslatorInterface $translator, + EntityManagerInterface $entity_manager ) { $this->capsule_repository = $capsule_repository; $this->translator = $translator; + $this->entity_manager = $entity_manager; } /** @@ -49,9 +55,9 @@ class CapsuleController extends AbstractController return $this->redirectToRoute('app_logout'); } - $all_capsules = $current_user->getCapsules(); - - $form = $this->createForm(FilterByGroupFormType::class, ['groups' => $current_user->getGroups()]); + // get all capsules without any filter + $all_capsules = $current_user->getCapsules()->toArray(); + $form = $this->createGroupFilterForm($current_user); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { @@ -61,7 +67,9 @@ class CapsuleController extends AbstractController throw new \Exception('Group not found'); } - $all_capsules = $current_user->getCapsulesFilteredByGroup($group); + if ($group->getId() !== Group::$ALL_GROUP_ID) { + $all_capsules = $group->getCapsulesIntersection($all_capsules); + } } $capsules = $paginator->paginate( @@ -175,8 +183,7 @@ class CapsuleController extends AbstractController return $this->redirectToRoute('app_logout'); } - $entityManager = $this->getDoctrine()->getManager(); - $capsule = $entityManager->getRepository(Capsule::class)->find($id); + $capsule = $this->capsule_repository->findOneBy(['id' => $id]); if (! $capsule) { throw $this->createNotFoundException( @@ -202,8 +209,8 @@ class CapsuleController extends AbstractController if ($form->isSubmitted() && $form->isValid()) { $current_user->removeCapsule($capsule); $capsule->removeEditor($current_user); - $entityManager->remove($capsule); - $entityManager->flush(); + $this->entity_manager->remove($capsule); + $this->entity_manager->flush(); $this->addFlash( 'success', @@ -240,8 +247,7 @@ class CapsuleController extends AbstractController return $this->redirectToRoute('app_logout'); } - $entityManager = $this->getDoctrine()->getManager(); - $parent_capsule = $entityManager->getRepository(Capsule::class)->find($id); + $parent_capsule = $this->capsule_repository->findOneBy(['id' => $id]); if (! $parent_capsule instanceof Capsule) { throw new \Exception('The retrieved capsule is not an instance of Capsule.'); @@ -301,7 +307,6 @@ class CapsuleController extends AbstractController $password = StringHelper::generateRandomHashedString(); $preview_link = Uuid::v4(); - $entityManager = $this->getDoctrine()->getManager(); $capsule_builder = new CapsuleBuilder(); $capsule = $capsule_builder ->withName($capsule_name) @@ -312,9 +317,30 @@ class CapsuleController extends AbstractController ->withPassword($password) ->createCapsule(); - $entityManager->persist($capsule); - $entityManager->flush(); + $this->entity_manager->persist($capsule); + $this->entity_manager->flush(); return $capsule; } + + private function getDefaultGroup(): Group + { + $noGroup = new Group(); + + // TODO : to be translated + $noGroup->setName($this->translator->trans('groups.filter.no_filter')); + $noGroup->setId(Group::$ALL_GROUP_ID); + + return $noGroup; + } + + private function createGroupFilterForm(User $current_user): FormInterface + { + $groups = new ArrayObject($current_user->getGroups()); + $groups = $groups->getArrayCopy(); + array_unshift($groups, self::getDefaultGroup()); + + + return $this->createForm(FilterByGroupFormType::class, ['groups' => $groups]); + } } diff --git a/src/DataFixtures/GroupFixtures.php b/src/DataFixtures/GroupFixtures.php new file mode 100644 index 0000000000000000000000000000000000000000..82cb6670ce1bb648173cccdbe8d83f4ebed27235 --- /dev/null +++ b/src/DataFixtures/GroupFixtures.php @@ -0,0 +1,26 @@ +<?php + +namespace App\DataFixtures; + +use App\Entity\Group; +use Doctrine\Bundle\FixturesBundle\Fixture; +use Doctrine\Persistence\ObjectManager; + +class GroupFixtures extends Fixture +{ + public function load(ObjectManager $manager): void + { + $group_all = new Group(); + $group_all->setName("All"); + $manager->persist($group_all); + $manager->flush(); + } + + /** @phpstan-ignore-next-line */ + public function getDependencies(): array + { + return [ + CapsuleFixtures::class, + ]; + } +} diff --git a/src/Entity/Group.php b/src/Entity/Group.php index dae2d533ec24b6a139b42ab7cf018ddde2aafdfe..af8ad780d8377e498ee1a03db3115e2636657e6e 100755 --- a/src/Entity/Group.php +++ b/src/Entity/Group.php @@ -15,6 +15,7 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; */ class Group { + public static int $ALL_GROUP_ID = -1; /** * @ORM\Id * @ORM\GeneratedValue @@ -43,6 +44,11 @@ class Group return $this->id; } + public function setId(int $id): void + { + $this->id = $id; + } + public function getName(): string { return $this->name; @@ -67,6 +73,19 @@ class Group { if (!$this->capsules->contains($capsule)) { $this->capsules[] = $capsule; + $capsule->addGroup($this); + } + + return $this; + } + + /** + * @param array<Capsule> $capsules + */ + public function addCapsules(array $capsules): self + { + foreach ($capsules as $capsule) { + $this->addCapsule($capsule); } return $this; @@ -78,4 +97,19 @@ class Group return $this; } + + /** + * @param array<Capsule> $capsules + * @return array<Capsule> + */ + public function getCapsulesIntersection(array $capsules): array + { + return array_uintersect( + $capsules, + $this->getCapsules()->toArray(), + function ($obj_a, $obj_b) { + return $obj_a->getId() - $obj_b->getId(); + } + ); + } } diff --git a/src/Entity/User.php b/src/Entity/User.php index 4d527cfd46202d01562cb7a7974a20fe87b6c1a4..21bcad23af3a2c2aeb5e0e49c129a8bb663deeca 100755 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -316,18 +316,4 @@ class User implements UserInterface, LegacyPasswordAuthenticatedUserInterface return $existing_groups_for_current_editor; } - - /** - * @return array<Capsule> - */ - public function getCapsulesFilteredByGroup(Group $group): array - { - return array_uintersect( - $this->getCapsules()->toArray(), - $group->getCapsules()->toArray(), - function ($obj_a, $obj_b) { - return $obj_a->getId() - $obj_b->getId(); - } - ); - } } diff --git a/templates/capsule/groups/edit.html.twig b/templates/capsule/groups/edit.html.twig index 35070f4628cbfe50b1d83abf81983d8c7424ab7b..6248ac5e488e16f7b67378628dea051165909003 100644 --- a/templates/capsule/groups/edit.html.twig +++ b/templates/capsule/groups/edit.html.twig @@ -38,13 +38,15 @@ </h5> <ul class="ps-0"> {% for group in groups %} - <li class="text-capitalize text-secondary list-unstyled p-1"> - {{ group.getName() }} - - - <a href="/capsule/{{ capsule.getId() }}/groups/{{ group.getId() }}/remove" class="remove-link"> - {{ 'groups.remove.link'|trans }} - </a> - </li> + {% if group.getName() != 'All' %} + <li class="text-capitalize text-secondary list-unstyled p-1"> + {{ group.getName() }} + - + <a href="/capsule/{{ capsule.getId() }}/groups/{{ group.getId() }}/remove" class="remove-link"> + {{ 'groups.remove.link'|trans }} + </a> + </li> + {% endif %} {% endfor %} </ul> </div> diff --git a/templates/capsule/index.html.twig b/templates/capsule/index.html.twig index f0bf7f272038c1c49ecc4b1d4e01ae16f591f38e..b5413a1606ac2ddfe3760a07bc9cebd8b2ddb280 100644 --- a/templates/capsule/index.html.twig +++ b/templates/capsule/index.html.twig @@ -13,13 +13,14 @@ {{ 'capsule.title'|trans }} </h2> - <div class="mb-3 mb-sm-0"> - {{ form_start(filterByGroupForm, {'attr': {novalidate: 'novalidate', 'class': 'd-flex flex-column flex-sm-row mb-0 align-items-center pt-3'}}) }} - {{ form_row(filterByGroupForm.name, {'attr': {'class': ''}}) }} - {{ form_row(filterByGroupForm.filter, {'attr': {'class': 'ms-2'}}) }} - {{ form_end(filterByGroupForm) }} - </div> - + {% if app.request.query.get('page')|default(1) == 1 %} + <div class="mb-3 mb-sm-0"> + {{ form_start(filterByGroupForm, {'attr': {novalidate: 'novalidate', 'class': 'd-flex flex-column flex-sm-row mb-0 align-items-center pt-3'}}) }} + {{ form_row(filterByGroupForm.name, {'attr': {'class': ''}}) }} + {{ form_row(filterByGroupForm.filter, {'attr': {'class': 'ms-2'}}) }} + {{ form_end(filterByGroupForm) }} + </div> + {% endif %} <form class="d-flex mb-4 mb-lg-0"> <button id="btn-orange" formaction="/create"> diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 58e65a0609fdf62242e707e7d53bb60e3f66e9c6..0ca87ae5989f26eb7d394eef75ec64335afba1e0 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -181,4 +181,5 @@ groups: title: Remove group success: Group group_name removed successfully filter: - button: Filter by group \ No newline at end of file + button: Apply group filter + no_filter: Show all \ No newline at end of file diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml index 63d83b0278e2fc16a01bd02a31089ba9ed6ee1aa..258d7cec2ef3119f597bbb3e46dd80276a28b0d5 100644 --- a/translations/messages.fr.yaml +++ b/translations/messages.fr.yaml @@ -180,4 +180,5 @@ groups: title: Supprimer le groupe success: Le groupe group_name a bien été supprimé filter: - button: Filtrer par groupe \ No newline at end of file + button: Filtrer par groupe + no_filter: Tout afficher \ No newline at end of file