Passed
Push — main ( ca1b2d...8a3b62 )
by Tan
02:53
created

PostController::findBySlug()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 88
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 62
c 3
b 0
f 1
dl 0
loc 88
rs 8.829
cc 3
nc 3
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace CSlant\Blog\Api\Http\Controllers;
4
5
use Botble\Base\Http\Responses\BaseHttpResponse;
0 ignored issues
show
Bug introduced by
The type Botble\Base\Http\Responses\BaseHttpResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Botble\Blog\Repositories\Interfaces\PostInterface;
0 ignored issues
show
Bug introduced by
The type Botble\Blog\Repositories\Interfaces\PostInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use CSlant\Blog\Api\Enums\StatusEnum;
8
use CSlant\Blog\Api\Http\Resources\Post\ListPostResource;
9
use CSlant\Blog\Api\Http\Resources\Post\PostResource;
10
use CSlant\Blog\Api\OpenApi\Schemas\Resources\Post\PostListResourceSchema;
11
use CSlant\Blog\Api\OpenApi\Schemas\Resources\Post\PostModelResourceSchema;
12
use CSlant\Blog\Core\Facades\Base\SlugHelper;
13
use CSlant\Blog\Core\Http\Actions\Action;
14
use CSlant\Blog\Core\Models\Post;
15
use CSlant\Blog\Core\Models\Slug;
16
use CSlant\Blog\Core\Supports\Base\FilterPost;
17
use Illuminate\Http\JsonResponse;
18
use Illuminate\Http\RedirectResponse;
19
use Illuminate\Http\Request;
20
use Illuminate\Http\Resources\Json\JsonResource;
21
use OpenApi\Attributes\Get;
22
use OpenApi\Attributes\Items;
23
use OpenApi\Attributes\JsonContent;
24
use OpenApi\Attributes\Parameter;
25
use OpenApi\Attributes\Property;
26
use OpenApi\Attributes\Response;
27
use OpenApi\Attributes\Schema;
28
29
/**
30
 * Class PostController
31
 *
32
 * @package CSlant\Blog\Api\Http\Controllers
33
 *
34
 * @group Blog API
35
 *
36
 * @authenticated
37
 *
38
 * @method BaseHttpResponse httpResponse()
39
 * @method BaseHttpResponse setData(mixed $data)
40
 * @method BaseHttpResponse|JsonResource|JsonResponse|RedirectResponse toApiResponse()
41
 */
42
class PostController extends Action
43
{
44
    public function __construct(protected PostInterface $postRepository)
45
    {
46
        //
47
    }
48
49
    /**
50
     * @group Blog API
51
     *
52
     * @param  Request  $request
53
     *
54
     * @return BaseHttpResponse|JsonResource|JsonResponse|RedirectResponse
55
     */
56
    #[
57
        Get(
58
            path: "/posts",
59
            operationId: "postGetAllWithFilter",
60
            description: "Get all posts with pagination (10 items per page by default, page 1 by default)
61
62
    This API will get records from the database and return them as a paginated list. 
63
    The default number of items per page is 10 and the default page number is 1. You can change these values by passing the `per_page` and `page` query parameters.
64
            ",
65
            summary: "Get all posts with pagination",
66
            tags: ["Post"],
67
            parameters: [
68
                new Parameter(
69
                    name: 'per_page',
70
                    description: 'Number of items per page',
71
                    in: 'query',
72
                    required: false,
73
                    schema: new Schema(type: 'integer', default: 10)
74
                ),
75
                new Parameter(
76
                    name: 'page',
77
                    description: 'Page number',
78
                    in: 'query',
79
                    required: false,
80
                    schema: new Schema(type: 'integer', default: 1)
81
                ),
82
            ],
83
            responses: [
84
                new Response(
85
                    response: 200,
86
                    description: "Get posts successfully",
87
                    content: new JsonContent(
88
                        properties: [
89
                            new Property(
90
                                property: 'error',
91
                                description: 'Error status',
92
                                type: 'boolean',
93
                                default: false
94
                            ),
95
                            new Property(
96
                                property: "data",
97
                                description: "Data of model",
98
                                type: "array",
99
                                items: new Items(ref: PostListResourceSchema::class)
100
                            ),
101
                        ]
102
                    )
103
                ),
104
                new Response(
105
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\BadRequestResponseSchema::class,
106
                    response: 400,
107
                ),
108
                new Response(
109
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\ErrorNotFoundResponseSchema::class,
110
                    response: 404,
111
                ),
112
                new Response(
113
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\InternalServerResponseSchema::class,
114
                    response: 500,
115
                ),
116
            ]
117
        )
118
    ]
119
    public function index(Request $request): BaseHttpResponse|JsonResponse|JsonResource|RedirectResponse
120
    {
121
        $data = $this
122
            ->postRepository
123
            ->advancedGet([
124
                'with' => ['tags', 'categories', 'author', 'slugable'],
125
                'condition' => ['status' => StatusEnum::PUBLISHED->value],
126
                'paginate' => [
127
                    'per_page' => $request->integer('per_page', 10),
128
                    'current_paged' => $request->integer('page', 1),
129
                ],
130
            ]);
131
132
        return $this
133
            ->httpResponse()
134
            ->setData(ListPostResource::collection($data))
135
            ->toApiResponse();
136
    }
137
138
    /**
139
     * @param  string  $slug
140
     *
141
     * @group Blog
142
     * @queryParam slug Find by slug of post.
143
     * @return BaseHttpResponse|JsonResource|JsonResponse|RedirectResponse
144
     */
145
    #[
146
        Get(
147
            path: "/posts/{slug}",
148
            operationId: "postFilterBySlug",
149
            description: "Get the post by slug
150
            
151
    This API will get records from the database and return the post by slug.
152
            ",
153
            summary: "Get post by slug",
154
            tags: ["Post"],
155
            parameters: [
156
                new Parameter(
157
                    name: 'slug',
158
                    description: 'Post slug',
159
                    in: 'path',
160
                    required: true,
161
                    schema: new Schema(type: 'string', example: 'php')
162
                ),
163
            ],
164
            responses: [
165
                new Response(
166
                    response: 200,
167
                    description: "Get post successfully",
168
                    content: new JsonContent(
169
                        properties: [
170
                            new Property(
171
                                property: 'error',
172
                                description: 'Error status',
173
                                type: 'boolean',
174
                                default: false
175
                            ),
176
                            new Property(
177
                                property: "data",
178
                                ref: PostModelResourceSchema::class,
179
                                description: "Data of model",
180
                                type: "object",
181
                            ),
182
                        ]
183
                    )
184
                ),
185
                new Response(
186
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\BadRequestResponseSchema::class,
187
                    response: 400,
188
                ),
189
                new Response(
190
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\ErrorNotFoundResponseSchema::class,
191
                    response: 404,
192
                ),
193
                new Response(
194
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\InternalServerResponseSchema::class,
195
                    response: 500,
196
                ),
197
            ]
198
        )
199
    ]
200
    public function findBySlug(string $slug): BaseHttpResponse|JsonResponse|JsonResource|RedirectResponse
201
    {
202
        /** @var Slug $slug */
203
        $slug = SlugHelper::getSlug($slug, SlugHelper::getPrefix(Post::getBaseModel()));
204
205
        if (!$slug) {
0 ignored issues
show
introduced by
$slug is of type CSlant\Blog\Core\Models\Slug, thus it always evaluated to true.
Loading history...
206
            return $this
207
                ->httpResponse()
208
                ->setError()
209
                ->setCode(404)
210
                ->setMessage('Not found');
211
        }
212
213
        $post = Post::query()
214
            ->with(['tags', 'categories', 'author'])
215
            ->where([
216
                'id' => $slug->reference_id,
217
                'status' => StatusEnum::PUBLISHED,
218
            ])
219
            ->first();
220
221
        if (!$post) {
222
            return $this
223
                ->httpResponse()
224
                ->setError()
225
                ->setCode(404)
226
                ->setMessage('Not found');
227
        }
228
229
        return $this
230
            ->httpResponse()
231
            ->setData(new PostResource($post))
232
            ->toApiResponse();
233
    }
234
235
    /**
236
     * @param  Request  $request
237
     *
238
     * @return BaseHttpResponse|JsonResource|JsonResponse|RedirectResponse
239
     */
240
    #[
241
        Get(
242
            path: "/posts/filters",
243
            operationId: "postGetWithFilter",
244
            description: "Get all posts with pagination (10 items per page by default, page 1 by default)
245
            
246
    This API will get records from the database and return them as a paginated list. 
247
    The default number of items per page is 10 and the default page number is 1. You can change these values by passing the `per_page` and `page` query parameters.
248
            ",
249
            summary: "Get posts by filter with pagination",
250
            tags: ["Post"],
251
            parameters: [
252
                new Parameter(
253
                    name: 'categories',
254
                    description: 'Filter posts by categories IDs',
255
                    in: 'query',
256
                    required: false,
257
                    schema: new Schema(
258
                        type: 'array',
259
                        items: new Items(description: 'Input the category ID', type: 'integer'),
260
                        default: null,
261
                    )
262
                ),
263
                new Parameter(
264
                    name: 'categories_exclude',
265
                    description: 'Filter posts by excluding specific category IDs.',
266
                    in: 'query',
267
                    required: false,
268
                    schema: new Schema(
269
                        type: 'array',
270
                        items: new Items(description: 'Input the exclude category ID', type: 'integer'),
271
                        default: null
272
                    )
273
                ),
274
                new Parameter(
275
                    name: 'exclude',
276
                    description: 'Filter posts by excluding specific post IDs.',
277
                    in: 'query',
278
                    required: false,
279
                    schema: new Schema(
280
                        type: 'array',
281
                        items: new Items(description: 'Input the exclude post ID', type: 'integer'),
282
                        default: null
283
                    )
284
                ),
285
                new Parameter(
286
                    name: 'author',
287
                    description: 'Filter posts by author IDs',
288
                    in: 'query',
289
                    required: false,
290
                    schema: new Schema(
291
                        type: 'array',
292
                        items: new Items(description: 'Input the author ID', type: 'integer'),
293
                        default: null
294
                    )
295
                ),
296
                new Parameter(
297
                    name: 'author_exclude',
298
                    description: 'Filter posts by excluding specific author IDs.',
299
                    in: 'query',
300
                    required: false,
301
                    schema: new Schema(
302
                        type: 'array',
303
                        items: new Items(description: 'Input the exclude author ID', type: 'integer'),
304
                        default: null
305
                    )
306
                ),
307
                new Parameter(
308
                    name: 'featured',
309
                    description: 'Filter posts by featured status. Accepts values:
310
                        1 for featured posts
311
                        0 for non-featured posts.',
312
                    in: 'query',
313
                    required: false,
314
                    schema: new Schema(
315
                        type: 'integer',
316
                        default: null,
317
                        enum: [0, 1],
318
                        nullable: true
319
                    )
320
                ),
321
                new Parameter(
322
                    name: 'search',
323
                    description: 'Search for posts where the given keyword appears in either the name or description fields.',
324
                    in: 'query',
325
                    required: false,
326
                    schema: new Schema(type: 'string', default: null)
327
                ),
328
                new Parameter(
329
                    name: 'per_page',
330
                    description: 'Number of items per page',
331
                    in: 'query',
332
                    required: false,
333
                    schema: new Schema(type: 'integer', default: 10)
334
                ),
335
                new Parameter(
336
                    name: 'page',
337
                    description: 'Page number',
338
                    in: 'query',
339
                    required: false,
340
                    schema: new Schema(type: 'integer', default: 1)
341
                ),
342
            ],
343
            responses: [
344
                new Response(
345
                    response: 200,
346
                    description: "Get posts successfully",
347
                    content: new JsonContent(
348
                        properties: [
349
                            new Property(
350
                                property: 'error',
351
                                description: 'Error status',
352
                                type: 'boolean',
353
                                default: false
354
                            ),
355
                            new Property(
356
                                property: "data",
357
                                description: "Data of model",
358
                                type: "array",
359
                                items: new Items(ref: PostListResourceSchema::class)
360
                            ),
361
                        ]
362
                    )
363
                ),
364
                new Response(
365
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\BadRequestResponseSchema::class,
366
                    response: 400,
367
                ),
368
                new Response(
369
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\ErrorNotFoundResponseSchema::class,
370
                    response: 404,
371
                ),
372
                new Response(
373
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\InternalServerResponseSchema::class,
374
                    response: 500,
375
                ),
376
            ]
377
        )
378
    ]
379
    public function getFilters(Request $request): BaseHttpResponse|JsonResponse|JsonResource|RedirectResponse
380
    {
381
        $filters = FilterPost::setFilters($request->input());
382
383
        $data = $this->postRepository->getFilters((array) $filters);
384
385
        return $this
386
            ->httpResponse()
387
            ->setData(ListPostResource::collection($data))
388
            ->toApiResponse();
389
    }
390
}
391