2222use Exception ;
2323use OpenApi \Attributes as OA ;
2424use phpMyFAQ \Comments ;
25- use phpMyFAQ \Controller \AbstractController ;
2625use phpMyFAQ \Entity \CommentType ;
2726use phpMyFAQ \Filter ;
2827use Symfony \Component \HttpFoundation \JsonResponse ;
2928use Symfony \Component \HttpFoundation \Request ;
3029use Symfony \Component \HttpFoundation \Response ;
31- use Symfony \Component \HttpKernel \Exception \UnauthorizedHttpException ;
3230
33- final class CommentController extends AbstractController
31+ final class CommentController extends AbstractApiController
3432{
35- public function __construct ()
36- {
37- parent ::__construct ();
38-
39- if (!$ this ->isApiEnabled ()) {
40- throw new UnauthorizedHttpException (challenge: 'API is not enabled ' );
41- }
42- }
43-
4433 /**
4534 * @throws Exception
46- */ #[OA \Get(
35+ */
36+ #[OA \Get(
4737 path: '/api/v3.2/comments/{faqId} ' ,
4838 operationId: 'getComments ' ,
49- description: 'Returns a list of comments for a given FAQ record ID. ' ,
39+ description: 'Returns a paginated list of comments for a given FAQ record ID. ' ,
5040 tags: ['Public Endpoints ' ],
5141 )]
5242 #[OA \Header(
@@ -61,34 +51,116 @@ public function __construct()
6151 required: true ,
6252 schema: new OA \Schema (type: 'integer ' ),
6353 )]
64- #[OA \Response(response: 200 , description: 'If the FAQ has at least one comment. ' , content: new OA \JsonContent (
65- example: '
66- [
67- {
68- "id": 2,
69- "recordId": 142,
70- "categoryId": null,
71- "type": "faq",
72- "username": "phpMyFAQ User",
73- 74- "comment": "Foo! Bar?",
75- "date": "2019-12-24T12:24:57+0100",
76- "helped": null
54+ #[OA \Parameter(
55+ name: 'page ' ,
56+ description: 'Page number for pagination (page-based) ' ,
57+ in: 'query ' ,
58+ required: false ,
59+ schema: new OA \Schema (type: 'integer ' , default: 1 ),
60+ )]
61+ #[OA \Parameter(
62+ name: 'per_page ' ,
63+ description: 'Items per page (page-based, max 100) ' ,
64+ in: 'query ' ,
65+ required: false ,
66+ schema: new OA \Schema (type: 'integer ' , default: 25 ),
67+ )]
68+ #[OA \Parameter(
69+ name: 'limit ' ,
70+ description: 'Number of items to return (offset-based, max 100) ' ,
71+ in: 'query ' ,
72+ required: false ,
73+ schema: new OA \Schema (type: 'integer ' , default: 25 ),
74+ )]
75+ #[OA \Parameter(
76+ name: 'offset ' ,
77+ description: 'Starting offset (offset-based) ' ,
78+ in: 'query ' ,
79+ required: false ,
80+ schema: new OA \Schema (type: 'integer ' , default: 0 ),
81+ )]
82+ #[OA \Parameter(name: 'sort ' , description: 'Field to sort by ' , in: 'query ' , required: false , schema: new OA \Schema (
83+ type: 'string ' ,
84+ default: 'id_comment ' ,
85+ enum: ['id_comment ' , 'id ' , 'usr ' , 'email ' , 'datum ' ],
86+ ))]
87+ #[OA \Parameter(
88+ name: 'order ' ,
89+ description: 'Sort direction ' ,
90+ in: 'query ' ,
91+ required: false ,
92+ schema: new OA \Schema (type: 'string ' , default: 'asc ' , enum: ['asc ' , 'desc ' ]),
93+ )]
94+ #[OA \Response(response: 200 , description: 'Returns paginated comments for the FAQ. ' , content: new OA \JsonContent (
95+ example: '{
96+ "success": true,
97+ "data": [
98+ {
99+ "id": 2,
100+ "recordId": 142,
101+ "categoryId": null,
102+ "type": "faq",
103+ "username": "phpMyFAQ User",
104+ 105+ "comment": "Foo! Bar?",
106+ "date": "2019-12-24T12:24:57+0100",
107+ "helped": null
108+ }
109+ ],
110+ "meta": {
111+ "pagination": {
112+ "total": 50,
113+ "count": 25,
114+ "per_page": 25,
115+ "current_page": 1,
116+ "total_pages": 2,
117+ "links": {
118+ "first": "/api/v3.2/comments/142?page=1&per_page=25",
119+ "last": "/api/v3.2/comments/142?page=2&per_page=25",
120+ "prev": null,
121+ "next": "/api/v3.2/comments/142?page=2&per_page=25"
122+ }
123+ },
124+ "sorting": {
125+ "field": "id_comment",
126+ "order": "asc"
127+ }
77128 }
78- ] ' ,
129+ } ' ,
79130 ))]
80- #[OA \Response(response: 404 , description: 'If the FAQ has no comments. ' , content: new OA \JsonContent (example: []))]
131+ #[OA \Response(
132+ response: 200 ,
133+ description: 'If no comments are found, returns empty data array. ' ,
134+ content: new OA \JsonContent (example: '{"success": true, "data": []} ' ),
135+ )]
81136 public function list (Request $ request ): JsonResponse
82137 {
83138 $ recordId = (int ) Filter::filterVar ($ request ->attributes ->get (key: 'recordId ' ), FILTER_VALIDATE_INT );
84139
85140 /** @var Comments $comments */
86141 $ comments = $ this ->container ->get (id: 'phpmyfaq.comments ' );
87- $ result = $ comments ->getCommentsData ($ recordId , CommentType::FAQ );
88- if ((is_countable ($ result ) ? count ($ result ) : 0 ) === 0 ) {
89- $ this ->json ($ result , Response::HTTP_NOT_FOUND );
90- }
91142
92- return $ this ->json ($ result , Response::HTTP_OK );
143+ // Get pagination and sorting parameters
144+ $ pagination = $ this ->getPaginationRequest ();
145+ $ sort = $ this ->getSortRequest (
146+ allowedFields: ['id_comment ' , 'id ' , 'usr ' , 'email ' , 'datum ' ],
147+ defaultField: 'id_comment ' ,
148+ defaultOrder: 'asc ' ,
149+ );
150+
151+ // Get paginated comments
152+ $ result = $ comments ->getCommentsDataPaginated (
153+ referenceId: $ recordId ,
154+ type: CommentType::FAQ ,
155+ limit: $ pagination ->limit ,
156+ offset: $ pagination ->offset ,
157+ sortField: $ sort ->getField () ?? 'id_comment ' ,
158+ sortOrder: $ sort ->getOrderSql (),
159+ );
160+
161+ // Get total count
162+ $ total = $ comments ->countComments ($ recordId , CommentType::FAQ );
163+
164+ return $ this ->paginatedResponse (data: $ result , total: $ total , pagination: $ pagination , sort: $ sort );
93165 }
94166}
0 commit comments