Passed
Pull Request — main (#69)
by
unknown
05:47 queued 02:53
created

VisitorLogsService::trackPostView()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 11
Bugs 4 Features 0
Metric Value
cc 5
eloc 17
c 11
b 4
f 0
nc 5
nop 3
dl 0
loc 34
rs 9.3888
1
<?php
2
3
namespace CSlant\Blog\Api\Services;
4
5
use Carbon\Carbon;
6
use CSlant\Blog\Api\Enums\StatusEnum;
7
use CSlant\Blog\Api\Models\VisitorLog;
8
use CSlant\Blog\Core\Models\Post;
9
use Illuminate\Database\Eloquent\ModelNotFoundException;
10
11
class VisitorLogsService
12
{
13
    /**
14
     * @param  int  $postId
15
     * @param  null|string  $ipAddress
16
     * @param  null|string  $userAgent
17
     *
18
     * @return Post
19
     * @throws ModelNotFoundException
20
     */
21
    public function trackPostView(
22
        int $postId,
23
        ?string $ipAddress,
24
        ?string $userAgent = null
25
    ): Post {
26
        $now = Carbon::now();
27
28
        /** @var Post $post */
29
        $post = Post::query()->lockForUpdate()->findOrFail($postId);
30
31
        if ($post->status !== StatusEnum::PUBLISHED->value) {
32
            return $post;
33
        }
34
35
        $visitorLog = VisitorLog::query()->firstOrNew([
36
            'viewable_id' => $post->getKey(),
37
            'viewable_type' => Post::class,
38
            'ip_address' => $ipAddress ?: '',
39
        ]);
40
41
        $shouldCountView = !$visitorLog->exists || $now->isAfter($visitorLog->expired_at ?? $now->copy()->subMinute());
42
43
        if ($shouldCountView) {
44
            $visitorLog->fill([
45
                'user_agent' => $userAgent,
46
                'expired_at' => $now->copy()->addMinutes((int) config('blog-core.view_throttle_minutes')),
47
            ]);
48
            $visitorLog->save();
49
50
            Post::where('id', $postId)->increment('views');
51
            $post->refresh();
52
        }
53
54
        return $post;
55
    }
56
}
57