Passed
Push — master ( d182c1...749c7a )
by Mike
02:50
created

CachedBuilder::count()   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 value($column)
148
    {
149
        if (! $this->isCachable()) {
150
            return parent::value($column);
151
        }
152
153
        $cacheKey = $this->makeCacheKey(["*"], null, "-value_{$column}");
154
155
        return $this->cachedValue(func_get_args(), $cacheKey);
156
    }
157
158
    public function cachedValue(array $arguments, string $cacheKey)
159
    {
160
        $method = debug_backtrace()[1]['function'];
161
        $cacheTags = $this->makeCacheTags();
162
        $hashedCacheKey = sha1($cacheKey);
163
        $result = $this->retrieveCachedValue(
164
            $arguments,
165
            $cacheKey,
166
            $cacheTags,
167
            $hashedCacheKey,
168
            $method
169
        );
170
171
        return $this->preventHashCollision(
172
            $result,
173
            $arguments,
174
            $cacheKey,
175
            $cacheTags,
176
            $hashedCacheKey,
177
            $method
178
        );
179
    }
180
181
    protected function preventHashCollision(
182
        array $result,
183
        array $arguments,
184
        string $cacheKey,
185
        array $cacheTags,
186
        string $hashedCacheKey,
187
        string $method
188
    ) {
189
        if ($result["key"] === $cacheKey) {
190
            return $result["value"];
191
        }
192
193
        $this->cache()
194
            ->tags($cacheTags)
195
            ->forget($hashedCacheKey);
196
197
        return $this->retrieveCachedValue(
198
            $arguments,
199
            $cacheKey,
200
            $cacheTags,
201
            $hashedCacheKey,
202
            $method
203
        );
204
    }
205
206
    protected function retrieveCachedValue(
207
        array $arguments,
208
        string $cacheKey,
209
        array $cacheTags,
210
        string $hashedCacheKey,
211
        string $method
212
    ) {
213
        $this->checkCooldownAndRemoveIfExpired($this->model);
214
215
        return $this->cache($cacheTags)
216
            ->rememberForever(
217
                $hashedCacheKey,
218
                function () use ($arguments, $cacheKey, $method) {
219
                    return [
220
                        "key" => $cacheKey,
221
                        "value" => parent::{$method}(...$arguments),
222
                    ];
223
                }
224
            );
225
    }
226
}
227