Configured swagger-php for documentation at /docs, probably needs a refactor lol; paginated searchAlbums to fix limit bug with null filters.
This commit is contained in:
1 parent
56dea097d6
commit
c1b1c2f372
19 files changed
+840
-273
No files matched your search
@@ -9,6 +9,7 @@ use App\Repository\AlbumRepository;
|
||||
use App\Repository\ReviewRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use FOS\RestBundle\Controller\AbstractFOSRestController;
|
||||
use OpenApi\Attributes as OA;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
@@ -25,6 +26,18 @@ class ReviewApiController extends AbstractFOSRestController
|
||||
}
|
||||
|
||||
#[Route('', name: 'api_v1_review_index', methods: ['GET'])]
|
||||
#[OA\Get(
|
||||
path: '/api/v1/reviews',
|
||||
operationId: 'api_v1_review_index',
|
||||
summary: 'List latest reviews',
|
||||
tags: ['Reviews'],
|
||||
parameters: [
|
||||
new OA\Parameter(name: 'limit', in: 'query', required: false, schema: new OA\Schema(type: 'integer', default: 50)),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(response: 200, description: 'Review list', content: new OA\JsonContent(type: 'object')),
|
||||
]
|
||||
)]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$limit = max(1, min(100, (int) $request->query->get('limit', 50)));
|
||||
@@ -36,6 +49,18 @@ class ReviewApiController extends AbstractFOSRestController
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'api_v1_review_show', requirements: ['id' => '\\d+'], methods: ['GET'])]
|
||||
#[OA\Get(
|
||||
path: '/api/v1/reviews/{id}',
|
||||
operationId: 'api_v1_review_show',
|
||||
summary: 'Get a review by ID',
|
||||
tags: ['Reviews'],
|
||||
parameters: [
|
||||
new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer')),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(response: 200, description: 'Review details', content: new OA\JsonContent(type: 'object')),
|
||||
]
|
||||
)]
|
||||
public function show(Review $review): Response
|
||||
{
|
||||
return $this->handleView($this->view(['data' => $this->serializeReview($review)], Response::HTTP_OK));
|
||||
@@ -43,6 +68,31 @@ class ReviewApiController extends AbstractFOSRestController
|
||||
|
||||
#[Route('', name: 'api_v1_review_create', methods: ['POST'])]
|
||||
#[IsGranted('ROLE_USER')]
|
||||
#[OA\Post(
|
||||
path: '/api/v1/reviews',
|
||||
operationId: 'api_v1_review_create',
|
||||
summary: 'Create a review',
|
||||
tags: ['Reviews'],
|
||||
security: [['bearerAuth' => []]],
|
||||
requestBody: new OA\RequestBody(
|
||||
required: true,
|
||||
content: new OA\JsonContent(
|
||||
required: ['album_id', 'title', 'content', 'rating'],
|
||||
properties: [
|
||||
new OA\Property(property: 'album_id', type: 'string'),
|
||||
new OA\Property(property: 'title', type: 'string'),
|
||||
new OA\Property(property: 'content', type: 'string'),
|
||||
new OA\Property(property: 'rating', type: 'integer', minimum: 1, maximum: 10),
|
||||
]
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(response: 201, description: 'Review created', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 400, description: 'Validation failed', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 401, description: 'JWT required', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 404, description: 'Album not found', content: new OA\JsonContent(type: 'object')),
|
||||
]
|
||||
)]
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
$payload = $this->readJsonPayload($request);
|
||||
@@ -88,6 +138,58 @@ class ReviewApiController extends AbstractFOSRestController
|
||||
|
||||
#[Route('/{id}', name: 'api_v1_review_update', requirements: ['id' => '\\d+'], methods: ['PUT', 'PATCH'])]
|
||||
#[IsGranted('ROLE_USER')]
|
||||
#[OA\Put(
|
||||
path: '/api/v1/reviews/{id}',
|
||||
operationId: 'api_v1_review_update_put',
|
||||
summary: 'Replace a review',
|
||||
tags: ['Reviews'],
|
||||
security: [['bearerAuth' => []]],
|
||||
parameters: [
|
||||
new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer')),
|
||||
],
|
||||
requestBody: new OA\RequestBody(
|
||||
required: true,
|
||||
content: new OA\JsonContent(
|
||||
properties: [
|
||||
new OA\Property(property: 'title', type: 'string'),
|
||||
new OA\Property(property: 'content', type: 'string'),
|
||||
new OA\Property(property: 'rating', type: 'integer', minimum: 1, maximum: 10),
|
||||
]
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(response: 200, description: 'Review updated', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 400, description: 'Validation failed', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 401, description: 'JWT required', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 403, description: 'Forbidden', content: new OA\JsonContent(type: 'object')),
|
||||
]
|
||||
)]
|
||||
#[OA\Patch(
|
||||
path: '/api/v1/reviews/{id}',
|
||||
operationId: 'api_v1_review_update_patch',
|
||||
summary: 'Partially update a review',
|
||||
tags: ['Reviews'],
|
||||
security: [['bearerAuth' => []]],
|
||||
parameters: [
|
||||
new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer')),
|
||||
],
|
||||
requestBody: new OA\RequestBody(
|
||||
required: true,
|
||||
content: new OA\JsonContent(
|
||||
properties: [
|
||||
new OA\Property(property: 'title', type: 'string'),
|
||||
new OA\Property(property: 'content', type: 'string'),
|
||||
new OA\Property(property: 'rating', type: 'integer', minimum: 1, maximum: 10),
|
||||
]
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(response: 200, description: 'Review updated', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 400, description: 'Validation failed', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 401, description: 'JWT required', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 403, description: 'Forbidden', content: new OA\JsonContent(type: 'object')),
|
||||
]
|
||||
)]
|
||||
public function update(Review $review, Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('REVIEW_EDIT', $review);
|
||||
@@ -131,6 +233,21 @@ class ReviewApiController extends AbstractFOSRestController
|
||||
|
||||
#[Route('/{id}', name: 'api_v1_review_delete', requirements: ['id' => '\\d+'], methods: ['DELETE'])]
|
||||
#[IsGranted('ROLE_USER')]
|
||||
#[OA\Delete(
|
||||
path: '/api/v1/reviews/{id}',
|
||||
operationId: 'api_v1_review_delete',
|
||||
summary: 'Delete a review',
|
||||
tags: ['Reviews'],
|
||||
security: [['bearerAuth' => []]],
|
||||
parameters: [
|
||||
new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer')),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(response: 204, description: 'Review deleted'),
|
||||
new OA\Response(response: 401, description: 'JWT required', content: new OA\JsonContent(type: 'object')),
|
||||
new OA\Response(response: 403, description: 'Forbidden', content: new OA\JsonContent(type: 'object')),
|
||||
]
|
||||
)]
|
||||
public function delete(Review $review): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('REVIEW_DELETE', $review);
|
||||
@@ -161,7 +278,7 @@ class ReviewApiController extends AbstractFOSRestController
|
||||
'display_name' => $review->getAuthor()?->getDisplayName(),
|
||||
],
|
||||
'album' => [
|
||||
'id' => $album?->getSource() === 'user' ? $album?->getLocalId() : $album?->getExternalId(),
|
||||
'id' => $album?->getExternalId(),
|
||||
'name' => $album?->getName(),
|
||||
'source' => $album?->getSource(),
|
||||
],
|
||||
@@ -174,11 +291,6 @@ class ReviewApiController extends AbstractFOSRestController
|
||||
return null;
|
||||
}
|
||||
|
||||
$local = $this->albumRepository->findOneByLocalId($albumId);
|
||||
if ($local instanceof Album) {
|
||||
return $local;
|
||||
}
|
||||
|
||||
return $this->albumRepository->findOneByExternalId($albumId);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user