RecentlyViewed::mergePersistToCurrentSession()   C
last analyzed

Complexity

Conditions 16
Paths 9

Size

Total Lines 58
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 16.1479

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 16
eloc 36
c 1
b 0
f 1
nc 9
nop 0
dl 0
loc 58
ccs 33
cts 36
cp 0.9167
crap 16.1479
rs 5.5666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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