wallabag/src/Wallabag/ApiBundle/Controller/TagRestController.php
Jeremy Benoist 6aca334d53
Move to controller as a service
Mostly using autowiring to inject deps.
The only tricky part was for import because all producer use the same class and have a different alias. So we must write them down in the service definition, autowiring doesn't work in that case.

Usually:
- if a controller has a constructor, it means injected services are at least re-used once in actions
- otherwise, service are injected per action
2022-12-19 10:38:08 +01:00

200 lines
5.8 KiB
PHP

<?php
namespace Wallabag\ApiBundle\Controller;
use Nelmio\ApiDocBundle\Annotation\Operation;
use Swagger\Annotations as SWG;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\Tag;
use Wallabag\CoreBundle\Repository\EntryRepository;
use Wallabag\CoreBundle\Repository\TagRepository;
class TagRestController extends WallabagRestController
{
/**
* Retrieve all tags.
*
* @Operation(
* tags={"Tags"},
* summary="Retrieve all tags.",
* @SWG\Response(
* response="200",
* description="Returned when successful"
* )
* )
*
* @Route("/api/tags.{_format}", methods={"GET"}, name="api_get_tags", defaults={"_format": "json"})
*
* @return JsonResponse
*/
public function getTagsAction(TagRepository $tagRepository)
{
$this->validateAuthentication();
$tags = $tagRepository->findAllFlatTagsWithNbEntries($this->getUser()->getId());
$json = $this->serializer->serialize($tags, 'json');
return (new JsonResponse())->setJson($json);
}
/**
* Permanently remove one tag from **every** entry by passing the Tag label.
*
* @Operation(
* tags={"Tags"},
* summary="Permanently remove one tag from every entry by passing the Tag label.",
* @SWG\Parameter(
* name="tag",
* in="body",
* description="Tag as a string",
* required=true,
* pattern="\w+",
* @SWG\Schema(type="string")
* ),
* @SWG\Response(
* response="200",
* description="Returned when successful"
* )
* )
*
* @Route("/api/tag/label.{_format}", methods={"DELETE"}, name="api_delete_tag_label", defaults={"_format": "json"})
*
* @return JsonResponse
*/
public function deleteTagLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
{
$this->validateAuthentication();
$label = $request->get('tag', '');
$tags = $tagRepository->findByLabelsAndUser([$label], $this->getUser()->getId());
if (empty($tags)) {
throw $this->createNotFoundException('Tag not found');
}
$tag = $tags[0];
$entryRepository->removeTag($this->getUser()->getId(), $tag);
$this->cleanOrphanTag($tag);
$json = $this->serializer->serialize($tag, 'json');
return (new JsonResponse())->setJson($json);
}
/**
* Permanently remove some tags from **every** entry.
*
* @Operation(
* tags={"Tags"},
* summary="Permanently remove some tags from every entry.",
* @SWG\Parameter(
* name="tags",
* in="body",
* description="Tags as strings (comma splitted)",
* required=true,
* @SWG\Schema(
* type="string",
* example="tag1,tag2",
* )
* ),
* @SWG\Response(
* response="200",
* description="Returned when successful"
* )
* )
*
* @Route("/api/tags/label.{_format}", methods={"DELETE"}, name="api_delete_tags_label", defaults={"_format": "json"})
*
* @return JsonResponse
*/
public function deleteTagsLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
{
$this->validateAuthentication();
$tagsLabels = $request->get('tags', '');
$tags = $tagRepository->findByLabelsAndUser(explode(',', $tagsLabels), $this->getUser()->getId());
if (empty($tags)) {
throw $this->createNotFoundException('Tags not found');
}
$entryRepository->removeTags($this->getUser()->getId(), $tags);
$this->cleanOrphanTag($tags);
$json = $this->serializer->serialize($tags, 'json');
return (new JsonResponse())->setJson($json);
}
/**
* Permanently remove one tag from **every** entry by passing the Tag ID.
*
* @Operation(
* tags={"Tags"},
* summary="Permanently remove one tag from every entry by passing the Tag ID.",
* @SWG\Parameter(
* name="tag",
* in="body",
* description="The tag",
* required=true,
* pattern="\w+",
* @SWG\Schema(type="integer")
* ),
* @SWG\Response(
* response="200",
* description="Returned when successful"
* )
* )
*
* @Route("/api/tags/{tag}.{_format}", methods={"DELETE"}, name="api_delete_tag", defaults={"_format": "json"})
*
* @return JsonResponse
*/
public function deleteTagAction(Tag $tag, TagRepository $tagRepository, EntryRepository $entryRepository)
{
$this->validateAuthentication();
$tagFromDb = $tagRepository->findByLabelsAndUser([$tag->getLabel()], $this->getUser()->getId());
if (empty($tagFromDb)) {
throw $this->createNotFoundException('Tag not found');
}
$entryRepository->removeTag($this->getUser()->getId(), $tag);
$this->cleanOrphanTag($tag);
$json = $this->serializer->serialize($tag, 'json');
return (new JsonResponse())->setJson($json);
}
/**
* Remove orphan tag in case no entries are associated to it.
*
* @param Tag|array $tags
*/
private function cleanOrphanTag($tags)
{
if (!\is_array($tags)) {
$tags = [$tags];
}
foreach ($tags as $tag) {
if (0 === \count($tag->getEntries())) {
$this->entityManager->remove($tag);
}
}
$this->entityManager->flush();
}
}