Passed
Pull Request — master (#246)
by
unknown
03:05
created

CacheBelongsToMany::value()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
namespace GeneaLabs\LaravelModelCaching;
3
4
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
5
use GeneaLabs\LaravelModelCaching\Traits\BuilderCaching;
6
use GeneaLabs\LaravelModelCaching\Traits\Caching;
7
use Fico7489\Laravel\Pivot\Traits\FiresPivotEventsTrait;
8
9
class CacheBelongsToMany extends BelongsToMany
10
{
11
    use BuilderCaching,
0 ignored issues
show
introduced by
The trait GeneaLabs\LaravelModelCaching\Traits\Caching requires some properties which are not provided by GeneaLabs\LaravelModelCaching\CacheBelongsToMany: $cacheCooldownSeconds, $model, $eagerLoad
Loading history...
Bug introduced by
The trait GeneaLabs\LaravelModelCa...g\Traits\BuilderCaching requires the property $model which is not provided by GeneaLabs\LaravelModelCaching\CacheBelongsToMany.
Loading history...
12
        Caching,
13
        FiresPivotEventsTrait;
14
15
    protected function makeCacheKey(
16
        array $columns = ['*'],
17
        $idColumn = null,
18
        string $keyDifferentiator = ''
19
    ) : string {
20
        $eagerLoad = $this->eagerLoad ?? [];
0 ignored issues
show
Bug Best Practice introduced by
The property eagerLoad does not exist on GeneaLabs\LaravelModelCaching\CacheBelongsToMany. Did you maybe forget to declare it?
Loading history...
21
        $model = $this->model ?? $this;
0 ignored issues
show
Bug Best Practice introduced by
The property model does not exist on GeneaLabs\LaravelModelCaching\CacheBelongsToMany. Did you maybe forget to declare it?
Loading history...
22
        $query = $this->query->getQuery() ?? app('db')->query();
23
24
        return (new CacheKey($eagerLoad, $model, $query))
25
            ->make($columns, $idColumn, $keyDifferentiator);
26
    }
27
28
    public function avg($column)
29
    {
30
        if (! $this->isCachable()) {
31
            return parent::avg($column);
0 ignored issues
show
introduced by
The method avg() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

31
            return parent::/** @scrutinizer ignore-call */ avg($column);
Loading history...
32
        }
33
34
        $cacheKey = $this->makeCacheKey(["*"], null, "-avg_{$column}");
35
36
        return $this->cachedValue(func_get_args(), $cacheKey);
37
    }
38
39
    public function count($columns = "*")
40
    {
41
        if (! $this->isCachable()) {
42
            return parent::count($columns);
0 ignored issues
show
introduced by
The method count() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

42
            return parent::/** @scrutinizer ignore-call */ count($columns);
Loading history...
43
        }
44
45
        $cacheKey = $this->makeCacheKey([$columns], null, "-count");
46
47
        return $this->cachedValue(func_get_args(), $cacheKey);
48
    }
49
50
    public function decrement($column, $amount = 1, array $extra = [])
51
    {
52
        $this->cache($this->makeCacheTags())
53
            ->flush();
54
55
        return parent::decrement($column, $amount, $extra);
0 ignored issues
show
introduced by
The method decrement() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

55
        return parent::/** @scrutinizer ignore-call */ decrement($column, $amount, $extra);
Loading history...
56
    }
57
58
    public function delete()
59
    {
60
        $this->cache($this->makeCacheTags())
61
            ->flush();
62
63
        return parent::delete();
0 ignored issues
show
introduced by
The method delete() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

63
        return parent::/** @scrutinizer ignore-call */ delete();
Loading history...
64
    }
65
66
    /**
67
     * @SuppressWarnings(PHPMD.ShortVariable)
68
     */
69
    public function find($id, $columns = ["*"])
70
    {
71
        if (! $this->isCachable()) {
72
            return parent::find($id, $columns);
73
        }
74
75
        $idKey = collect($id)
76
            ->implode('_');
77
        $preStr = is_array($id)
78
            ? 'find_list'
79
            : 'find';
80
        $cacheKey = $this->makeCacheKey($columns, null, "-{$preStr}_{$idKey}");
81
82
        return $this->cachedValue(func_get_args(), $cacheKey);
83
    }
84
85
    public function first($columns = ["*"])
86
    {
87
        if (! $this->isCachable()) {
88
            return parent::first($columns);
89
        }
90
91
        if (! is_array($columns)) {
92
            $columns = [$columns];
93
        }
94
95
        $cacheKey = $this->makeCacheKey($columns, null, "-first");
96
97
        return $this->cachedValue(func_get_args(), $cacheKey);
98
    }
99
100
    public function forceDelete()
101
    {
102
        $this->cache($this->makeCacheTags())
103
            ->flush();
104
105
        return parent::forceDelete();
0 ignored issues
show
introduced by
The method forceDelete() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

105
        return parent::/** @scrutinizer ignore-call */ forceDelete();
Loading history...
106
    }
107
108
    public function get($columns = ["*"])
109
    {
110
        if (! $this->isCachable()) {
111
            return parent::get($columns);
112
        }
113
114
        $cacheKey = $this->makeCacheKey($columns);
115
116
        return $this->cachedValue(func_get_args(), $cacheKey);
117
    }
118
119
    public function increment($column, $amount = 1, array $extra = [])
120
    {
121
        $this->cache($this->makeCacheTags())
122
            ->flush();
123
124
        return parent::increment($column, $amount, $extra);
0 ignored issues
show
introduced by
The method increment() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

124
        return parent::/** @scrutinizer ignore-call */ increment($column, $amount, $extra);
Loading history...
125
    }
126
127
    public function inRandomOrder($seed = '')
128
    {
129
        $this->isCachable = false;
130
131
        return parent::inRandomOrder($seed);
0 ignored issues
show
introduced by
The method inRandomOrder() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

131
        return parent::/** @scrutinizer ignore-call */ inRandomOrder($seed);
Loading history...
132
    }
133
134
    public function insert(array $values)
135
    {
136
        $this->checkCooldownAndFlushAfterPersisting($this->model);
0 ignored issues
show
Bug Best Practice introduced by
The property model does not exist on GeneaLabs\LaravelModelCaching\CacheBelongsToMany. Did you maybe forget to declare it?
Loading history...
137
138
        return parent::insert($values);
0 ignored issues
show
introduced by
The method insert() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

138
        return parent::/** @scrutinizer ignore-call */ insert($values);
Loading history...
139
    }
140
141
    public function max($column)
142
    {
143
        if (! $this->isCachable()) {
144
            return parent::max($column);
0 ignored issues
show
introduced by
The method max() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

144
            return parent::/** @scrutinizer ignore-call */ max($column);
Loading history...
145
        }
146
147
        $cacheKey = $this->makeCacheKey(["*"], null, "-max_{$column}");
148
149
        return $this->cachedValue(func_get_args(), $cacheKey);
150
    }
151
152
    public function min($column)
153
    {
154
        if (! $this->isCachable()) {
155
            return parent::min($column);
0 ignored issues
show
introduced by
The method min() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

155
            return parent::/** @scrutinizer ignore-call */ min($column);
Loading history...
156
        }
157
158
        $cacheKey = $this->makeCacheKey(["*"], null, "-min_{$column}");
159
160
        return $this->cachedValue(func_get_args(), $cacheKey);
161
    }
162
163
    public function paginate(
164
        $perPage = null,
165
        $columns = ["*"],
166
        $pageName = "page",
167
        $page = null
168
    ) {
169
        if (! $this->isCachable()) {
170
            return parent::paginate($perPage, $columns, $pageName, $page);
171
        }
172
173
        $page = app('request')->input($pageName)
174
            ?: $page
175
            ?: 1;
176
177
        if (is_array($page)) {
178
            $page = $this->recursiveImplodeWithKey($page);
179
        }
180
        $cacheKey = $this->makeCacheKey($columns, null, "-paginate_by_{$perPage}_{$pageName}_{$page}");
181
182
        return $this->cachedValue(func_get_args(), $cacheKey);
183
    }
184
185
    public function getRelation($name)
186
    {
187
        $relation = parent::getRelation($name);
0 ignored issues
show
Bug introduced by
The method getRelation() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. Did you maybe mean getRelationCountHash()? ( Ignorable by Annotation )

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

187
        /** @scrutinizer ignore-call */ 
188
        $relation = parent::getRelation($name);

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...
188
189
        if (! $this->isCachable()
190
            && is_a($relation->getQuery(), self::class)
191
        ) {
192
            $relation->getQuery()->disableModelCaching();
193
        }
194
195
        return $relation;
196
    }
197
198
    protected function recursiveImplodeWithKey(array $items, string $glue = "_") : string
199
    {
200
        $result = "";
201
202
        foreach ($items as $key => $value) {
203
            if (is_array($value)) {
204
                $result .= $key . $glue . $this->recursiveImplodeWithKey($value, $glue);
205
206
                continue;
207
            }
208
209
            $result .= $glue . $key . $glue . $value;
210
        }
211
212
        return $result;
213
    }
214
215
    public function pluck($column, $key = null)
216
    {
217
        if (! $this->isCachable()) {
218
            return parent::pluck($column, $key);
0 ignored issues
show
introduced by
The method pluck() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

218
            return parent::/** @scrutinizer ignore-call */ pluck($column, $key);
Loading history...
219
        }
220
221
        $keyDifferentiator = "-pluck_{$column}" . ($key ? "_{$key}" : "");
222
        $cacheKey = $this->makeCacheKey([$column], null, $keyDifferentiator);
223
224
        return $this->cachedValue(func_get_args(), $cacheKey);
225
    }
226
227
    public function sum($column)
228
    {
229
        if (! $this->isCachable()) {
230
            return parent::sum($column);
0 ignored issues
show
introduced by
The method sum() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

230
            return parent::/** @scrutinizer ignore-call */ sum($column);
Loading history...
231
        }
232
233
        $cacheKey = $this->makeCacheKey(["*"], null, "-sum_{$column}");
234
235
        return $this->cachedValue(func_get_args(), $cacheKey);
236
    }
237
238
    public function update(array $values)
239
    {
240
        $this->checkCooldownAndFlushAfterPersisting($this->model);
0 ignored issues
show
Bug Best Practice introduced by
The property model does not exist on GeneaLabs\LaravelModelCaching\CacheBelongsToMany. Did you maybe forget to declare it?
Loading history...
241
242
        return parent::update($values);
0 ignored issues
show
Bug introduced by
The method update() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. Did you maybe mean updatedAt()? ( Ignorable by Annotation )

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

242
        return parent::/** @scrutinizer ignore-call */ update($values);

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...
243
    }
244
245
    public function value($column)
246
    {
247
        if (! $this->isCachable()) {
248
            return parent::value($column);
0 ignored issues
show
introduced by
The method value() does not exist on Illuminate\Database\Eloq...Relations\BelongsToMany. 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

248
            return parent::/** @scrutinizer ignore-call */ value($column);
Loading history...
249
        }
250
251
        $cacheKey = $this->makeCacheKey(["*"], null, "-value_{$column}");
252
253
        return $this->cachedValue(func_get_args(), $cacheKey);
254
    }
255
256
    public function cachedValue(array $arguments, string $cacheKey)
257
    {
258
        $method = debug_backtrace()[1]['function'];
259
        $cacheTags = $this->makeCacheTags();
260
        $hashedCacheKey = sha1($cacheKey);
261
        $result = $this->retrieveCachedValue(
262
            $arguments,
263
            $cacheKey,
264
            $cacheTags,
265
            $hashedCacheKey,
266
            $method
267
        );
268
269
        return $this->preventHashCollision(
270
            $result,
271
            $arguments,
272
            $cacheKey,
273
            $cacheTags,
274
            $hashedCacheKey,
275
            $method
276
        );
277
    }
278
279
    protected function preventHashCollision(
280
        array $result,
281
        array $arguments,
282
        string $cacheKey,
283
        array $cacheTags,
284
        string $hashedCacheKey,
285
        string $method
286
    ) {
287
        if ($result["key"] === $cacheKey) {
288
            return $result["value"];
289
        }
290
291
        $this->cache()
292
            ->tags($cacheTags)
293
            ->forget($hashedCacheKey);
294
295
        return $this->retrieveCachedValue(
296
            $arguments,
297
            $cacheKey,
298
            $cacheTags,
299
            $hashedCacheKey,
300
            $method
301
        );
302
    }
303
304
    protected function retrieveCachedValue(
305
        array $arguments,
306
        string $cacheKey,
307
        array $cacheTags,
308
        string $hashedCacheKey,
309
        string $method
310
    ) {
311
        $this->checkCooldownAndRemoveIfExpired($this->getModel());
0 ignored issues
show
Bug introduced by
The method getModel() does not exist on GeneaLabs\LaravelModelCaching\CacheBelongsToMany. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

311
        $this->checkCooldownAndRemoveIfExpired($this->/** @scrutinizer ignore-call */ getModel());
Loading history...
312
313
        return $this->cache($cacheTags)
314
            ->rememberForever(
315
                $hashedCacheKey,
316
                function () use ($arguments, $cacheKey, $method) {
317
                    return [
318
                        "key" => $cacheKey,
319
                        "value" => parent::{$method}(...$arguments),
320
                    ];
321
                }
322
            );
323
    }
324
}
325