Completed
Pull Request — master (#18)
by Mike
03:29
created

CachedBuilder::max()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 8
Ratio 100 %

Importance

Changes 0
Metric Value
dl 8
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php namespace GeneaLabs\LaravelModelCaching;
2
3
use Closure;
4
use Illuminate\Cache\TaggableStore;
5
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
6
use Illuminate\Database\Eloquent\Relations\Pivot;
7
use Illuminate\Support\Collection;
8
use Illuminate\Database\Eloquent\Relations\Relation;
9
10
class CachedBuilder extends EloquentBuilder
11
{
12
    protected function cache(array $tags = [])
13
    {
14
        $cache = cache();
15
16
        if (is_subclass_of($cache->getStore(), TaggableStore::class)) {
17
            $cache = $cache->tags($tags);
18
        }
19
20
        return $cache;
21
    }
22
23
    protected function getCacheKey(array $columns = ['*'], $idColumn = null) : string
24
    {
25
        $key = $this->getModelSlug();
26
        $key .= $this->getIdColumn($idColumn ?: '');
27
        $key .= $this->getQueryColumns($columns);
28
        $key .= $this->getWhereClauses();
29
        $key .= $this->getWithModels();
30
        $key .= $this->getOrderByClauses();
31
        $key .= $this->getOffsetClause();
32
        $key .= $this->getLimitClause();
33
34
        return $key;
35
    }
36
37
    protected function getIdColumn(string $idColumn) : string
38
    {
39
40
        return $idColumn ? "_{$idColumn}" : '';
41
    }
42
43
    protected function getLimitClause() : string
44
    {
45
        if (! $this->query->limit) {
46
            return '';
47
        }
48
49
        return "-limit_{$this->query->limit}";
50
    }
51
52
    protected function getModelSlug() : string
53
    {
54
        return str_slug(get_class($this->model));
55
    }
56
57
    protected function getOffsetClause() : string
58
    {
59
        if (! $this->query->offset) {
60
            return '';
61
        }
62
63
        return "-offset_{$this->query->offset}";
64
    }
65
66
    protected function getQueryColumns(array $columns) : string
67
    {
68
        if ($columns === ['*'] || $columns === []) {
69
            return '';
70
        }
71
72
        return '_' . implode('_', $columns);
73
    }
74
75
    protected function getWhereClauses(array $wheres = []) : string
76
    {
77
        $wheres = collect($wheres);
78
79
        if ($wheres->isEmpty()) {
80
            $wheres = collect($this->query->wheres);
81
        }
82
83
        return $wheres->reduce(function ($carry, $where) {
84
            if (in_array($where['type'], ['Exists', 'Nested'])) {
85
                return $this->getWhereClauses($where['query']->wheres);
86
            }
87
88
            if ($where['type'] === 'Column') {
89
                return "_{$where['boolean']}_{$where['first']}_{$where['operator']}_{$where['second']}";
90
            }
91
92
            if ($where['type'] === 'raw') {
93
                return "_{$where['boolean']}_" . str_slug($where['sql']);
94
            }
95
96
            $value = array_get($where, 'value');
97
98
            if (in_array($where['type'], ['In', 'Null', 'NotNull'])) {
99
                $value = strtolower($where['type']);
100
            }
101
102
            if (is_array(array_get($where, 'values'))) {
103
                $value .= '_' . implode('_', $where['values']);
104
            }
105
106
            return "{$carry}-{$where['column']}_{$value}";
107
        }) ?: '';
108
    }
109
110
    protected function getWithModels() : string
111
    {
112
        $eagerLoads = collect($this->eagerLoad);
113
114
        if ($eagerLoads->isEmpty()) {
115
            return '';
116
        }
117
118
        return '-' . implode('-', $eagerLoads->keys()->toArray());
119
    }
120
121
	protected function getOrderByClauses(){
122
        $orders = collect($this->query->orders);
123
124
        return $orders->reduce(function($carry, $order){
125
            return $carry . '_orderBy_' . $order['column'] . '_' . $order['direction'];
126
        });
127
    }
128
129
    protected function getCacheTags() : array
130
    {
131
        return collect($this->eagerLoad)->keys()
132
            ->map(function ($relationName) {
133
                $relation = collect(explode('.', $relationName))
134
                    ->reduce(function ($carry, $name) {
135
                        if (! $carry) {
136
                            $carry = $this->model;
137
                        }
138
139
                        if ($carry instanceof Relation) {
140
                            $carry = $carry->getQuery()->model;
141
                        }
142
143
                        return $carry->{$name}();
144
                    });
145
146
                return str_slug(get_class($relation->getQuery()->model));
147
            })
148
            ->prepend(str_slug(get_class($this->model)))
149
            ->values()
150
            ->toArray();
151
    }
152
153 View Code Duplication
    public function avg($column)
154
    {
155
        $tags = [str_slug(get_class($this->model))];
156
        $key = str_slug(get_class($this->model)) ."-avg_{$column}";
157
158
        return $this->cache($tags)
159
            ->rememberForever($key, function () use ($column) {
160
                return parent::avg($column);
161
            });
162
    }
163
164 View Code Duplication
    public function count($columns = ['*'])
165
    {
166
        $tags = [str_slug(get_class($this->model))];
167
        $key = str_slug(get_class($this->model)) ."-count";
168
169
        return $this->cache($tags)
170
            ->rememberForever($key, function () use ($columns) {
171
                return parent::count($columns);
172
            });
173
    }
174
175 View Code Duplication
    public function cursor()
176
    {
177
        $tags = [str_slug(get_class($this->model))];
178
        $key = str_slug(get_class($this->model)) ."-cursor";
179
180
        return $this->cache($tags)
181
            ->rememberForever($key, function () {
182
                return collect(parent::cursor());
183
            });
184
    }
185
186
    /**
187
     * @SuppressWarnings(PHPMD.ShortVariable)
188
     */
189 View Code Duplication
    public function find($id, $columns = ['*'])
190
    {
191
        $tags = $this->getCacheTags();
192
        $key = $this->getCacheKey($columns, $id);
193
194
        return $this->cache($tags)
195
            ->rememberForever($key, function () use ($id, $columns) {
196
                return parent::find($id, $columns);
197
            });
198
    }
199
200 View Code Duplication
    public function first($columns = ['*'])
201
    {
202
        $tags = $this->getCacheTags();
203
        $key = $this->getCacheKey($columns) . '-first';
204
205
        return $this->cache($tags)
206
            ->rememberForever($key, function () use ($columns) {
207
                return parent::first($columns);
208
            });
209
    }
210
211 View Code Duplication
    public function get($columns = ['*'])
212
    {
213
        $tags = $this->getCacheTags();
214
        $key = $this->getCacheKey($columns);
215
216
        return $this->cache($tags)
217
            ->rememberForever($key, function () use ($columns) {
218
                return parent::get($columns);
219
            });
220
    }
221
222 View Code Duplication
    public function max($column)
223
    {
224
        $tags = [str_slug(get_class($this->model))];
225
        $key = str_slug(get_class($this->model)) ."-max_{$column}";
226
227
        return $this->cache($tags)
228
            ->rememberForever($key, function () use ($column) {
229
                return parent::max($column);
230
            });
231
    }
232
233 View Code Duplication
    public function min($column)
234
    {
235
        $tags = [str_slug(get_class($this->model))];
236
        $key = str_slug(get_class($this->model)) ."-min_{$column}";
237
238
        return $this->cache($tags)
239
            ->rememberForever($key, function () use ($column) {
240
                return parent::min($column);
241
            });
242
    }
243
244
    public function pluck($column, $key = null)
245
    {
246
        $tags = $this->getCacheTags();
247
        $cacheKey = $this->getCacheKey([$column]) . "-pluck_{$column}";
248
249
        if ($key) {
250
            $cacheKey .= "_{$key}";
251
        }
252
253
        return $this->cache($tags)
254
            ->rememberForever($cacheKey, function () use ($column, $key) {
255
                return parent::pluck($column, $key);
256
            });
257
    }
258
259 View Code Duplication
    public function sum($column)
260
    {
261
        $tags = [str_slug(get_class($this->model))];
262
        $key = str_slug(get_class($this->model)) ."-sum_{$column}";
263
264
        return $this->cache($tags)
265
            ->rememberForever($key, function () use ($column) {
266
                return parent::sum($column);
267
            });
268
    }
269
}
270