Passed
Pull Request — main (#69)
by
unknown
02:49
created

PostService::search()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 6
eloc 16
c 1
b 0
f 1
nc 3
nop 2
dl 0
loc 24
rs 9.1111
1
<?php
2
3
namespace CSlant\Blog\Api\Services;
4
5
use CSlant\Blog\Api\Models\PostView;
0 ignored issues
show
Bug introduced by
The type CSlant\Blog\Api\Models\PostView 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 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['tags'] !== null) {
33
            $tags = array_filter((array) $filters['tags']);
34
35
            $data = $data->whereHas('tags', function (Builder $query) use ($tags): void {
36
                $query->whereIn('tags.id', $tags);
37
            });
38
        }
39
40
        if ($filters['categories'] !== null) {
41
            $categories = array_filter((array) $filters['categories']);
42
43
            $data = $data->whereHas('categories', function (Builder $query) use ($categories): void {
44
                $query->whereIn('categories.id', $categories);
45
            });
46
        }
47
48
        if ($filters['categories_exclude'] !== null) {
49
            $data = $data
50
                ->whereHas('categories', function (Builder $query) use ($filters): void {
51
                    $query->whereNotIn('categories.id', array_filter((array) $filters['categories_exclude']));
52
                });
53
        }
54
55
        if ($filters['exclude'] !== null) {
56
            $data = $data->whereNotIn('id', array_filter((array) $filters['exclude']));
57
        }
58
59
        if ($filters['include'] !== null) {
60
            $data = $data->whereNotIn('id', array_filter((array) $filters['include']));
61
        }
62
63
        if ($filters['author'] !== null) {
64
            $data = $data->whereIn('author_id', array_filter((array) $filters['author']));
65
        }
66
67
        if ($filters['author_exclude'] !== null) {
68
            $data = $data->whereNotIn('author_id', array_filter((array) $filters['author_exclude']));
69
        }
70
71
        if ($filters['featured'] !== null) {
72
            $data = $data->where('is_featured', $filters['featured']);
73
        }
74
75
        if ($filters['search'] !== null) {
76
            $keyword = isset($filters['search']) ? (string) $filters['search'] : null;
77
            $data = $this->search($data, $keyword);
0 ignored issues
show
Bug introduced by
The method search() does not exist on CSlant\Blog\Api\Services\PostService. ( Ignorable by Annotation )

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

77
            /** @scrutinizer ignore-call */ 
78
            $data = $this->search($data, $keyword);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
78
        }
79
80
        $orderBy = Arr::get($filters, 'order_by', 'updated_at');
81
        $order = Arr::get($filters, 'order', 'desc');
82
83
        $data = $data
84
            ->wherePublished()
85
            ->orderBy($orderBy, $order);
86
87
        return $data->paginate((int) $filters['per_page']);
88
    }
89
90
    /**
91
     * Track a view for a post.
92
     *
93
     * @param int $postId The post ID
94
     * @param string $ipAddress The IP address
95
     * @param null|string $userAgent The user agent
96
     * @return void
97
     */
98
    public function trackView(int $postId, string $ipAddress, ?string $userAgent = null): void
99
    {
100
        /** @var null|\CSlant\Blog\Api\Models\PostView $existingView */
101
        $existingView = PostView::query()
102
            ->where('post_id', '=', $postId)
103
            ->where('ip_address', '=', $ipAddress)
104
            ->first();
105
106
        $timeCheck = now();
107
108
        if (!$existingView) {
109
            /** @var array<string, mixed> $attributes */
110
            $attributes = [
111
                'post_id' => $postId,
112
                'ip_address' => $ipAddress,
113
                'user_agent' => $userAgent,
114
                'time_check' => $timeCheck,
115
            ];
116
117
            PostView::query()->create($attributes);
118
119
            return;
120
        }
121
122
        // Only count as a new view if the last view was more than an hour ago
123
        if ($existingView->time_check->diffInHours(now()) >= 1) {
124
            /** @var array<string, mixed> $attributes */
125
            $attributes = [
126
                'time_check' => $timeCheck,
127
                'user_agent' => $userAgent,
128
            ];
129
130
            $existingView->update($attributes);
131
        }
132
    }
133
}
134