Passed
Pull Request — main (#69)
by
unknown
06:41 queued 03:15
created

PostService::trackView()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 2 Features 1
Metric Value
cc 3
eloc 18
c 5
b 2
f 1
nc 3
nop 3
dl 0
loc 33
rs 9.6666
1
<?php
2
3
namespace CSlant\Blog\Api\Services;
4
5
use CSlant\Blog\Api\Models\PostView;
6
use CSlant\Blog\Core\Http\Responses\Base\BaseHttpResponse;
7
use CSlant\Blog\Core\Models\Post;
8
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
9
use Illuminate\Database\Eloquent\Builder;
10
use Illuminate\Support\Arr;
11
12
/**
13
 * Class PostService
14
 *
15
 * @package CSlant\Blog\Api\Services
16
 *
17
 * @method BaseHttpResponse httpResponse()
18
 */
19
class PostService
20
{
21
    /**
22
     * Get posts by filters.
23
     *
24
     * @param  array<string, mixed>  $filters
25
     *
26
     * @return LengthAwarePaginator<Post>
27
     */
28
    public function getCustomFilters(array $filters): LengthAwarePaginator
29
    {
30
        $data = Post::query();
31
32
        if ($filters['categories'] !== null) {
33
            $categories = array_filter((array) $filters['categories']);
34
35
            $data = $data->whereHas('categories', function (Builder $query) use ($categories): void {
36
                $query->whereIn('categories.id', $categories);
37
            });
38
        }
39
40
        if ($filters['tags'] !== null) {
41
            $tags = array_filter((array) $filters['tags']);
42
43
            $data = $data->whereHas('tags', function (Builder $query) use ($tags): void {
44
                $query->whereIn('tags.id', $tags);
45
            });
46
        }
47
48
        $orderBy = Arr::get($filters, 'order_by', 'updated_at');
49
        $order = Arr::get($filters, 'order', 'desc');
50
51
        $data = $data
52
            ->wherePublished()
53
            ->orderBy($orderBy, $order);
54
55
        return $data->paginate((int) $filters['per_page']);
56
    }
57
58
    /**
59
     * Track a view for a post.
60
     *
61
     * @param int $postId The post ID
62
     * @param string $ipAddress The IP address
63
     * @param null|string $userAgent The user agent
64
     * @return void
65
     */
66
    public function trackView(int $postId, string $ipAddress, ?string $userAgent = null): void
67
    {
68
        /** @var null|\CSlant\Blog\Api\Models\PostView $existingView */
69
        $existingView = PostView::query()
70
            ->where('post_id', '=', $postId)
71
            ->where('ip_address', '=', $ipAddress)
72
            ->first();
73
74
        $timeCheck = now();
75
76
        if (!$existingView) {
77
            /** @var array<string, mixed> $attributes */
78
            $attributes = [
79
                'post_id' => $postId,
80
                'ip_address' => $ipAddress,
81
                'user_agent' => $userAgent,
82
                'time_check' => $timeCheck,
83
            ];
84
85
            PostView::query()->create($attributes);
86
87
            return;
88
        }
89
90
        // Only count as a new view if the last view was more than an hour ago
91
        if ($existingView->time_check->diffInHours(now()) >= 1) {
92
            /** @var array<string, mixed> $attributes */
93
            $attributes = [
94
                'time_check' => $timeCheck,
95
                'user_agent' => $userAgent,
96
            ];
97
98
            $existingView->update($attributes);
99
        }
100
    }
101
}
102