From 334a37a9d01f9c98dd300eac96b1304332a6f7c5 Mon Sep 17 00:00:00 2001 From: d-buchmann Date: Thu, 22 May 2025 14:43:05 +0200 Subject: [PATCH 1/4] Preparations for bulk editing of tags Made "target" parameter of handleAction in parts table a string Sanitize input for exisitng action which expect an int Add tag (dummy) to SelectAPI Add tag option to twig template --- src/Controller/PartListsController.php | 2 +- src/Controller/SelectAPIController.php | 15 +++++++++++++ .../Parts/PartsTableActionHandler.php | 21 ++++++++++++++++++- .../components/datatables.macro.html.twig | 4 ++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Controller/PartListsController.php b/src/Controller/PartListsController.php index 48995228..171d1999 100644 --- a/src/Controller/PartListsController.php +++ b/src/Controller/PartListsController.php @@ -78,7 +78,7 @@ public function tableAction(Request $request, PartsTableActionHandler $actionHan $errors = []; $parts = $actionHandler->idStringToArray($ids); - $redirectResponse = $actionHandler->handleAction($action, $parts, $target ? (int) $target : null, $redirect, $errors); + $redirectResponse = $actionHandler->handleAction($action, $parts, $target ? $target : null, $redirect, $errors); //Save changes $this->entityManager->flush(); diff --git a/src/Controller/SelectAPIController.php b/src/Controller/SelectAPIController.php index c1e682c8..03224634 100644 --- a/src/Controller/SelectAPIController.php +++ b/src/Controller/SelectAPIController.php @@ -33,6 +33,7 @@ use App\Entity\ProjectSystem\Project; use App\Form\Type\Helper\StructuralEntityChoiceHelper; use App\Services\Trees\NodesListBuilder; +use App\ApiPlatform\Filter\TagFilter; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -49,6 +50,20 @@ public function __construct(private readonly NodesListBuilder $nodesListBuilder, { } + #[Route(path: '/tag', name: 'select_tag')] + public function tag(): Response + { + $tags = [ + 'text' => 'test', + 'value' => 'test', + ]; + $this->addEmptyNode($tags); + // pseudocode: + // for each part in selection + // use TagFilter to find tags + // dedupe + return $this->json($tags); + #[Route(path: '/category', name: 'select_category')] public function category(): Response { diff --git a/src/Services/Parts/PartsTableActionHandler.php b/src/Services/Parts/PartsTableActionHandler.php index 616df229..affaa06b 100644 --- a/src/Services/Parts/PartsTableActionHandler.php +++ b/src/Services/Parts/PartsTableActionHandler.php @@ -67,8 +67,15 @@ public function idStringToArray(string $ids): array * @return RedirectResponse|null Returns a redirect response if the user should be redirected to another page, otherwise null * //@param-out list|array $errors */ - public function handleAction(string $action, array $selected_parts, ?int $target_id, ?string $redirect_url = null, array &$errors = []): ?RedirectResponse + public function handleAction(string $action, array $selected_parts, ?string $target_id, ?string $redirect_url = null, array &$errors = []): ?RedirectResponse { + // sanitize target_id + if (!str_contains($action, 'tag') && $target_id !== null) + { + if (!is_numeric($target_id) + throw new InvalidArgumentException('$target_id must be an integer for action'. $action.'!'); + } + if ($action === 'add_to_project') { return new RedirectResponse( $this->urlGenerator->generate('project_add_parts', [ @@ -130,6 +137,18 @@ public function handleAction(string $action, array $selected_parts, ?int $target $this->denyAccessUnlessGranted('edit', $part); switch ($action) { + case "add_tag": + $this->denyAccessUnlessGranted('edit', $part); + $tags = $part->getTags(); + $part->setTags($tags . ',' . $target_id); // simple append + break; + case "remove_tag": + $this->denyAccessUnlessGranted('edit', $part); + $tags = $part->getTags(); + $tags = str_replace($target_id, '', $tags); + // sanitize $tags (remove leading, trailing and double commas) + $part->setTags($tags); + break; case 'favorite': $this->denyAccessUnlessGranted('change_favorite', $part); $part->setFavorite(true); diff --git a/templates/components/datatables.macro.html.twig b/templates/components/datatables.macro.html.twig index 5ce0f23f..d790ffe5 100644 --- a/templates/components/datatables.macro.html.twig +++ b/templates/components/datatables.macro.html.twig @@ -41,6 +41,10 @@