Passed
Push — master ( 749c7a...45c010 )
by Mike
03:40
created

CachedBuilder::value()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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

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