RecentlyViewed::clearPersist()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 10
1
<?php
2
3
namespace RecentlyViewed;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Support\Facades\Auth;
7
use Illuminate\Support\Facades\Session;
8
use RecentlyViewed\Exceptions\ShouldBeViewableException;
9
use RecentlyViewed\Models\Contracts\Viewable;
10
use RecentlyViewed\Models\Contracts\Viewer;
11
12
class RecentlyViewed
13
{
14
    protected string $sessionPrefix;
15
16 10
    public function __construct()
17
    {
18 10
        $this->sessionPrefix = config('recently-viewed.session_prefix');
19
    }
20
21 9
    public function add(Viewable $viewable): static
22
    {
23 9
        if (method_exists($viewable, 'getKey')) {
24 9
            $keys = Session::get("{$this->sessionPrefix}.".get_class($viewable));
25 9
            if (!is_array($keys)) {
26 9
                $keys = [];
27
            }
28 9
            array_unshift($keys, $viewable->getKey());
29 9
            $keys = array_slice(array_unique($keys), 0, $viewable->getRecentlyViewsLimit());
30 9
            Session::put("{$this->sessionPrefix}.".get_class($viewable), $keys);
31
32 9
            if (PersistManager::isEnabled()) {
33 6
                $this->persist($viewable, $keys);
34
            }
35
        }
36
37 9
        return $this;
38
    }
39
40
    /**
41
     * @return Collection Eloquent collection of items.
42
     * @throws ShouldBeViewableException
43
     */
44 1
    public function get(Viewable|string $viewable, ?int $limit = null): Collection
45
    {
46 1
        throw_if(
47 1
            !is_a($viewable, Viewable::class, true),
48 1
            new ShouldBeViewableException('Entity should implement Viewable interface.')
49 1
        );
50
51 1
        if (is_string($viewable)) {
52 1
            $viewable = app()->make($viewable);
53
        }
54
55 1
        $keys = Session::get("{$this->sessionPrefix}.".get_class($viewable));
56
57 1
        if (!is_array($keys)) {
58 1
            $keys = [];
59
        }
60
61 1
        return $viewable
62 1
                   ->whereRecentlyViewedIn($keys)
63 1
                   ?->take($limit ?? $viewable->getRecentlyViewsLimit())
64 1
                   ->get()
65 1
                   ->sortBy(fn ($model) => array_search($model->getKey(), $keys)) ?? collect([]);
0 ignored issues
show
Bug introduced by
array() of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

65
                   ->sortBy(fn ($model) => array_search($model->getKey(), $keys)) ?? collect(/** @scrutinizer ignore-type */ []);
Loading history...
66
    }
67
68
    /**
69
     * @throws ShouldBeViewableException
70
     */
71 3
    public function clear(Viewable|string $viewable): static
72
    {
73 3
        throw_if(
74 3
            !is_a($viewable, Viewable::class, true),
75 3
            new ShouldBeViewableException('Entity should implement Viewable interface.')
76 3
        );
77
78 3
        if (is_string($viewable)) {
79 2
            $viewable = app()->make($viewable);
80
        }
81
82 3
        Session::forget("{$this->sessionPrefix}.".get_class($viewable));
83
84 3
        if (PersistManager::isEnabled()) {
85 2
            $this->clearPersist($viewable);
86
        }
87
88 3
        return $this;
89
    }
90
91 2
    public function clearAll(): static
92
    {
93 2
        Session::forget(config('recently-viewed.session_prefix'));
94
95 2
        if (PersistManager::isEnabled()) {
96 1
            $this->clearPersistAll();
97
        }
98
99 2
        return $this;
100
    }
101
102 6
    public function persist(Viewable $viewable, array $data): static
103
    {
104 6
        if ($viewer = $this->getViewer()) {
105 6
            $viewer->syncRecentViews(get_class($viewable), $data);
106
        }
107
108 6
        return $this;
109
    }
110
111 2
    public function clearPersist(Viewable $viewable): static
112
    {
113 2
        if ($viewer = $this->getViewer()) {
114 2
            $viewer->deleteRecentViews([get_class($viewable)]);
115
        }
116
117 2
        return $this;
118
    }
119
120 1
    public function clearPersistAll(): static
121
    {
122 1
        $this->getViewer()?->deleteRecentViews();
123
124 1
        return $this;
125
    }
126
127 7
    protected function getViewer(): ?Viewer
128
    {
129
        if (
130 7
            ($user = Auth::guard(config('recently-viewed.auth_guard'))->user()) &&
131 7
            ($user instanceof Viewer)
132
        ) {
133 7
            return $user;
134
        }
135
136 3
        return null;
137
    }
138
139 1
    public function mergePersistToCurrentSession(): static
140
    {
141 1
        if (!($viewer = $this->getViewer())) {
142 1
            return $this;
143
        }
144
145 1
        $persist = $viewer->getRecentViews()->toArray();
146 1
        $session = Session::get($this->sessionPrefix);
147
148 1
        $merged = [];
149 1
        if (is_array($session)) {
150 1
            foreach ($session as $type => $keys) {
151 1
                if (!class_exists($type)) {
152
                    continue;
153
                }
154 1
                $obj = new $type();
155 1
                if ($obj instanceof Viewable) {
156 1
                    $limit = $obj->getRecentlyViewsLimit();
157 1
                    if (count($keys) >= $limit) {
158
                        $keys = array_slice($keys, 0, $limit);
159
                    } else {
160 1
                        if (isset($persist[$type])) {
161 1
                            $keys = array_slice(array_merge($keys, $persist[$type]), 0, $limit);
162
                        }
163
                    }
164 1
                    $keys = array_unique($keys);
165 1
                    if (count($keys)) {
166 1
                        $merged[$type] = array_unique($keys);
167
                    }
168
                }
169 1
                if (isset($persist[$type])) {
170 1
                    unset($persist[$type]);
171
                }
172
            }
173
        }
174
175 1
        if (is_array($persist)) {
176 1
            foreach ($persist as $type => $keys) {
177 1
                if (!class_exists($type)) {
178
                    continue;
179
                }
180 1
                $obj = new $type();
181 1
                if ($obj instanceof Viewable) {
182 1
                    $limit = $obj->getRecentlyViewsLimit();
183 1
                    if (count($keys)) {
184 1
                        $merged[$type] = array_slice($keys, 0, $limit);
185
                    }
186
                }
187
            }
188
        }
189
190 1
        Session::put($this->sessionPrefix, $merged);
191 1
        $viewer->deleteRecentViews();
192 1
        foreach ($merged as $type => $keys) {
193 1
            $viewer->syncRecentViews($type, $keys);
194
        }
195
196 1
        return $this;
197
    }
198
}
199