Passed
Pull Request — main (#69)
by Tan
03:05
created

VisitorLogsService::trackPostView()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 10
Bugs 3 Features 0
Metric Value
cc 6
eloc 16
c 10
b 3
f 0
nc 5
nop 3
dl 0
loc 33
rs 9.1111
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\Model;
10
11
class VisitorLogsService
12
{
13
    /**
14
     * @param  int  $postId
15
     * @param  string|null  $ipAddress
16
     * @param  string|null  $userAgent
17
     *
18
     * @return Model|null
19
     */
20
    public function trackPostView(
21
        int $postId,
22
        ?string $ipAddress,
23
        ?string $userAgent = null
24
    ): Model|null {
25
        $now = Carbon::now();
26
27
        /** @var Post $post */
28
        $post = Post::query()->lockForUpdate()->findOrFail($postId);
29
30
        if (!$post instanceof Post && $post->status !== StatusEnum::PUBLISHED->value) {
0 ignored issues
show
introduced by
$post is always a sub-type of CSlant\Blog\Core\Models\Post.
Loading history...
31
            return null;
32
        }
33
34
        $visitorLog = VisitorLog::query()->firstOrNew([
35
            'viewable_id' => $post->getKey(),
36
            'viewable_type' => Post::class,
37
            'ip_address' => $ipAddress ?: '',
38
        ]);
39
40
        $shouldCountView = !$visitorLog->exists || $now->isAfter($visitorLog->expired_at);
41
42
        if ($shouldCountView) {
43
            $visitorLog->fill([
44
                'user_agent' => $userAgent,
45
                'expired_at' => $now->copy()->addMinutes((int) config('blog-core.view_throttle_minutes')),
46
            ]);
47
            $visitorLog->save();
48
49
            Post::where('id', $postId)->increment('views');
50
        }
51
52
        return $post->refresh();
53
    }
54
}
55