Passed
Push — master ( a81fec...1f51b4 )
by Mike
02:20
created

CachedBuilder::delete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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