Passed
Push — master ( 110a1c...9a7d28 )
by Mike
03:05
created

CachedBuilder::inRandomOrder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php namespace GeneaLabs\LaravelModelCaching;
2
3
use GeneaLabs\LaravelModelCaching\Traits\BuilderCaching;
4
use GeneaLabs\LaravelModelCaching\Traits\Caching;
5
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
6
use Illuminate\Support\Collection;
7
8
/**
9
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
10
 */
11
class CachedBuilder extends EloquentBuilder
12
{
13
    use BuilderCaching;
14
    use Caching;
15
16
    public function avg($column)
17
    {
18
        if (! $this->isCachable()) {
19
            return parent::avg($column);
20
        }
21
22
        $cacheKey = $this->makeCacheKey(["*"], null, "-avg_{$column}");
23
24
        return $this->cachedValue(func_get_args(), $cacheKey);
25
    }
26
27
    public function count($columns = "*")
28
    {
29
        if (! $this->isCachable()) {
30
            return parent::count($columns);
31
        }
32
33
        $cacheKey = $this->makeCacheKey([$columns], null, "-count");
34
35
        return $this->cachedValue(func_get_args(), $cacheKey);
36
    }
37
38
    public function delete()
39
    {
40
        $this->cache($this->makeCacheTags())
41
            ->flush();
42
43
        return parent::delete();
44
    }
45
46
    /**
47
     * @SuppressWarnings(PHPMD.ShortVariable)
48
     */
49
    public function find($id, $columns = ["*"])
50
    {
51
        if (! $this->isCachable()) {
52
            return parent::find($id, $columns);
53
        }
54
55
        $cacheKey = $this->makeCacheKey($columns, null, "-find_{$id}");
56
57
        return $this->cachedValue(func_get_args(), $cacheKey);
58
    }
59
60
    public function first($columns = ["*"])
61
    {
62
        if (! $this->isCachable()) {
63
            return parent::first($columns);
64
        }
65
66
        $cacheKey = $this->makeCacheKey($columns, null, "-first");
67
68
        return $this->cachedValue(func_get_args(), $cacheKey);
69
    }
70
71
    public function get($columns = ["*"])
72
    {
73
        if (! $this->isCachable()) {
74
            return parent::get($columns);
75
        }
76
77
        $cacheKey = $this->makeCacheKey($columns);
78
79
        return $this->cachedValue(func_get_args(), $cacheKey);
80
    }
81
82
    public function inRandomOrder($seed = '')
83
    {
84
        $this->isCachable = false;
85
86
        return parent::inRandomOrder($seed);
1 ignored issue
show
introduced by
The method inRandomOrder() does not exist on Illuminate\Database\Eloquent\Builder. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

86
        return parent::/** @scrutinizer ignore-call */ inRandomOrder($seed);
Loading history...
87
    }
88
89
    public function insert(array $values)
90
    {
91
        $this->checkCooldownAndFlushAfterPersiting($this->model);
92
93
        return parent::insert($values);
94
    }
95
96
    public function max($column)
97
    {
98
        if (! $this->isCachable()) {
99
            return parent::max($column);
100
        }
101
102
        $cacheKey = $this->makeCacheKey(["*"], null, "-max_{$column}");
103
104
        return $this->cachedValue(func_get_args(), $cacheKey);
105
    }
106
107
    public function min($column)
108
    {
109
        if (! $this->isCachable()) {
110
            return parent::min($column);
111
        }
112
113
        $cacheKey = $this->makeCacheKey(["*"], null, "-min_{$column}");
114
115
        return $this->cachedValue(func_get_args(), $cacheKey);
116
    }
117
118
    public function paginate(
119
        $perPage = null,
120
        $columns = ["*"],
121
        $pageName = "page",
122
        $page = null
123
    ) {
124
        if (! $this->isCachable()) {
125
            return parent::paginate($perPage, $columns, $pageName, $page);
126
        }
127
128
        $page = request("page", $page ?: 1);
129
        $cacheKey = $this->makeCacheKey($columns, null, "-paginate_by_{$perPage}_{$pageName}_{$page}");
130
131
        return $this->cachedValue(func_get_args(), $cacheKey);
132
    }
133
134
    public function pluck($column, $key = null)
135
    {
136
        if (! $this->isCachable()) {
137
            return parent::pluck($column, $key);
138
        }
139
140
        $keyDifferentiator = "-pluck_{$column}" . ($key ? "_{$key}" : "");
141
        $cacheKey = $this->makeCacheKey([$column], null, $keyDifferentiator);
142
143
        return $this->cachedValue(func_get_args(), $cacheKey);
144
    }
145
146
    public function sum($column)
147
    {
148
        if (! $this->isCachable()) {
149
            return parent::sum($column);
150
        }
151
152
        $cacheKey = $this->makeCacheKey(["*"], null, "-sum_{$column}");
153
154
        return $this->cachedValue(func_get_args(), $cacheKey);
155
    }
156
157
    public function update(array $values)
158
    {
159
        $this->checkCooldownAndFlushAfterPersiting($this->model);
160
161
        return parent::update($values);
162
    }
163
164
    public function value($column)
165
    {
166
        if (! $this->isCachable()) {
167
            return parent::value($column);
168
        }
169
170
        $cacheKey = $this->makeCacheKey(["*"], null, "-value_{$column}");
171
172
        return $this->cachedValue(func_get_args(), $cacheKey);
173
    }
174
175
    public function cachedValue(array $arguments, string $cacheKey)
176
    {
177
        $method = debug_backtrace()[1]['function'];
178
        $cacheTags = $this->makeCacheTags();
179
        $hashedCacheKey = sha1($cacheKey);
180
        $result = $this->retrieveCachedValue(
181
            $arguments,
182
            $cacheKey,
183
            $cacheTags,
184
            $hashedCacheKey,
185
            $method
186
        );
187
188
        return $this->preventHashCollision(
189
            $result,
190
            $arguments,
191
            $cacheKey,
192
            $cacheTags,
193
            $hashedCacheKey,
194
            $method
195
        );
196
    }
197
198
    protected function preventHashCollision(
199
        array $result,
200
        array $arguments,
201
        string $cacheKey,
202
        array $cacheTags,
203
        string $hashedCacheKey,
204
        string $method
205
    ) {
206
        if ($result["key"] === $cacheKey) {
207
            return $result["value"];
208
        }
209
210
        $this->cache()
211
            ->tags($cacheTags)
212
            ->forget($hashedCacheKey);
213
214
        return $this->retrieveCachedValue(
215
            $arguments,
216
            $cacheKey,
217
            $cacheTags,
218
            $hashedCacheKey,
219
            $method
220
        );
221
    }
222
223
    protected function retrieveCachedValue(
224
        array $arguments,
225
        string $cacheKey,
226
        array $cacheTags,
227
        string $hashedCacheKey,
228
        string $method
229
    ) {
230
        $this->checkCooldownAndRemoveIfExpired($this->model);
231
232
        return $this->cache($cacheTags)
233
            ->rememberForever(
234
                $hashedCacheKey,
235
                function () use ($arguments, $cacheKey, $method) {
236
                    return [
237
                        "key" => $cacheKey,
238
                        "value" => parent::{$method}(...$arguments),
239
                    ];
240
                }
241
            );
242
    }
243
}
244