PostStoreViewCountAction   A
last analyzed

Complexity

Total Complexity 3

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 62
dl 0
loc 89
rs 10
c 1
b 0
f 0
wmc 3

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B __invoke() 0 80 2
1
<?php
2
3
namespace CSlant\Blog\Api\Http\Actions\Post;
4
5
use CSlant\Blog\Api\Http\Resources\Post\ViewCountResource;
6
use CSlant\Blog\Api\OpenApi\Schemas\Resources\Post\ViewCountResourceSchema;
7
use CSlant\Blog\Api\Services\VisitorLogsService;
8
use CSlant\Blog\Core\Http\Actions\Action;
9
use CSlant\Blog\Core\Http\Responses\Base\BaseHttpResponse;
10
use Illuminate\Http\JsonResponse;
11
use Illuminate\Http\RedirectResponse;
12
use Illuminate\Http\Request;
13
use Illuminate\Http\Resources\Json\JsonResource;
14
use Illuminate\Support\Facades\DB;
15
use OpenApi\Attributes\JsonContent;
16
use OpenApi\Attributes\Parameter;
17
use OpenApi\Attributes\Post;
18
use OpenApi\Attributes\Property;
19
use OpenApi\Attributes\Response;
20
use OpenApi\Attributes\Schema;
21
22
class PostStoreViewCountAction extends Action
23
{
24
    protected VisitorLogsService $visitorLogsService;
25
26
    public function __construct(VisitorLogsService $visitorLogsService)
27
    {
28
        $this->visitorLogsService = $visitorLogsService;
29
    }
30
31
    #[
32
        Post(
33
            path: "/posts/{id}/increment-views",
34
            operationId: "incrementViewCountPostById",
35
            description: "Increment views count of the post by ID. Only adds 1 view per IP within a time period specified in the environment configuration.",
36
            summary: "Increment views count of the post by ID",
37
            tags: ["Post"],
38
            parameters: [
39
                new Parameter(
40
                    name: 'id',
41
                    description: 'Post Id',
42
                    in: 'path',
43
                    required: true,
44
                    schema: new Schema(type: 'integer', example: 1)
45
                ),
46
            ],
47
            responses: [
48
                new Response(
49
                    response: 200,
50
                    description: "Success",
51
                    content: new JsonContent(
52
                        properties: [
53
                            new Property(
54
                                property: 'error',
55
                                description: 'Error status',
56
                                type: 'boolean',
57
                                default: false
58
                            ),
59
                            new Property(
60
                                property: "data",
61
                                ref: ViewCountResourceSchema::class,
62
                                description: "Updated view count data",
63
                                type: "object",
64
                            ),
65
                        ]
66
                    )
67
                ),
68
                new Response(
69
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\BadRequestResponseSchema::class,
70
                    response: 400,
71
                ),
72
                new Response(
73
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\ErrorNotFoundResponseSchema::class,
74
                    response: 404,
75
                ),
76
                new Response(
77
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\InternalServerResponseSchema::class,
78
                    response: 500,
79
                ),
80
                new Response(
81
                    ref: \CSlant\Blog\Api\OpenApi\Responses\Errors\TooManyRequestsResponseSchema::class,
82
                    response: 429,
83
                ),
84
            ]
85
        )
86
    ]
87
    public function __invoke(Request $request, int $id): BaseHttpResponse|JsonResponse|JsonResource|RedirectResponse
88
    {
89
        $ipAddress = $request->header('X-Forwarded-For') ?? $request->ip();
90
        $userAgent = $request->userAgent();
91
92
        DB::beginTransaction();
93
94
        try {
95
            $post = $this->visitorLogsService->trackPostView($id, $ipAddress, $userAgent);
0 ignored issues
show
Bug introduced by
It seems like $ipAddress can also be of type array; however, parameter $ipAddress of CSlant\Blog\Api\Services...ervice::trackPostView() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
            $post = $this->visitorLogsService->trackPostView($id, /** @scrutinizer ignore-type */ $ipAddress, $userAgent);
Loading history...
96
97
            DB::commit();
98
99
            return $this
100
                ->httpResponse()
101
                ->setData(new ViewCountResource($post))
102
                ->toApiResponse();
103
        } catch (\Exception $exception) {
104
            DB::rollBack();
105
106
            return $this
107
                ->httpResponse()
108
                ->setError()
109
                ->setStatusCode(500)
110
                ->setMessage($exception->getMessage());
111
        }
112
    }
113
}
114