Passed
Pull Request — master (#27)
by Mike
02:20
created

CachedBuilder::getValuesClause()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
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', 'NotExists'])) {
85
                return '_' . strtolower($where['type']) . $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
            $value .= $this->getTypeClause($where);
98
            $value .= $this->getValuesClause($where);
99
100
            return "{$carry}-{$where['column']}_{$value}";
101
        }) . '';
102
    }
103
104
    protected function getWithModels() : string
105
    {
106
        $eagerLoads = collect($this->eagerLoad);
107
108
        if ($eagerLoads->isEmpty()) {
109
            return '';
110
        }
111
112
        return '-' . implode('-', $eagerLoads->keys()->toArray());
113
    }
114
115
	protected function getOrderByClauses(){
116
        $orders = collect($this->query->orders);
117
118
        return $orders->reduce(function($carry, $order){
119
            return $carry . '_orderBy_' . $order['column'] . '_' . $order['direction'];
120
        });
121
    }
122
123
    protected function getMethodKey(string $postfix = null) : string
124
    {
125
        return str_slug(get_class($this->model)) . $postfix;
126
    }
127
128
    protected function getModelTag() : array
129
    {
130
        return [str_slug(get_class($this->model))];
131
    }
132
133
    protected function getCacheTags() : array
134
    {
135
        return collect($this->eagerLoad)->keys()
136
            ->map(function ($relationName) {
137
                $relation = collect(explode('.', $relationName))
138
                    ->reduce(function ($carry, $name) {
139
                        if (! $carry) {
140
                            $carry = $this->model;
141
                        }
142
143
                        if ($carry instanceof Relation) {
144
                            $carry = $carry->getQuery()->model;
145
                        }
146
147
                        return $carry->{$name}();
148
                    });
149
150
                return str_slug(get_class($relation->getQuery()->model));
151
            })
152
            ->prepend(str_slug(get_class($this->model)))
153
            ->values()
154
            ->toArray();
155
    }
156
157 View Code Duplication
    public function avg($column)
158
    {
159
        return $this->cache($this->getModelTag())
160
            ->rememberForever($this->getMethodKey("-avg_{$column}"), function () use ($column) {
161
                return parent::avg($column);
162
            });
163
    }
164
165 View Code Duplication
    public function count($columns = ['*'])
166
    {
167
        return $this->cache($this->getModelTag())
168
            ->rememberForever($this->getMethodKey("-count"), function () use ($columns) {
169
                return parent::count($columns);
170
            });
171
    }
172
173
    public function cursor()
174
    {
175
        return $this->cache($this->getModelTag())
176
            ->rememberForever($this->getMethodKey("-cursor"), function () {
177
                return collect(parent::cursor());
178
            });
179
    }
180
181
    /**
182
     * @SuppressWarnings(PHPMD.ShortVariable)
183
     */
184 View Code Duplication
    public function find($id, $columns = ['*'])
185
    {
186
        return $this->cache($this->getCacheTags())
187
            ->rememberForever($this->getCacheKey($columns, $id), function () use ($id, $columns) {
188
                return parent::find($id, $columns);
189
            });
190
    }
191
192 View Code Duplication
    public function first($columns = ['*'])
193
    {
194
        return $this->cache($this->getCacheTags())
195
            ->rememberForever($this->getCacheKey($columns) . '-first', function () use ($columns) {
196
                return parent::first($columns);
197
            });
198
    }
199
200 View Code Duplication
    public function get($columns = ['*'])
201
    {
202
        return $this->cache($this->getCacheTags())
203
            ->rememberForever($this->getCacheKey($columns), function () use ($columns) {
204
                return parent::get($columns);
205
            });
206
    }
207
208 View Code Duplication
    public function max($column)
209
    {
210
        return $this->cache($this->getModelTag())
211
            ->rememberForever($this->getMethodKey("-max_{$column}"), function () use ($column) {
212
                return parent::max($column);
213
            });
214
    }
215
216 View Code Duplication
    public function min($column)
217
    {
218
        return $this->cache($this->getModelTag())
219
            ->rememberForever($this->getMethodKey("-min_{$column}"), function () use ($column) {
220
                return parent::min($column);
221
            });
222
    }
223
224
    public function pluck($column, $key = null)
225
    {
226
        $cacheKey = $this->getCacheKey([$column]) . "-pluck_{$column}";
227
228
        if ($key) {
229
            $cacheKey .= "_{$key}";
230
        }
231
232
        return $this->cache($this->getCacheTags())
233
            ->rememberForever($cacheKey, function () use ($column, $key) {
234
                return parent::pluck($column, $key);
235
            });
236
    }
237
238 View Code Duplication
    public function sum($column)
239
    {
240
        return $this->cache($this->getModelTag())
241
            ->rememberForever($this->getMethodKey("-sum_{$column}"), function () use ($column) {
242
                return parent::sum($column);
243
            });
244
    }
245
246
    protected function getTypeClause($where)
247
    {
248
        return in_array($where['type'], ['In', 'Null', 'NotNull'])
249
            ? strtolower($where['type'])
250
            : '';
251
    }
252
253
    protected function getValuesClause($where)
254
    {
255
        return is_array(array_get($where, 'values'))
256
            ? '_' . implode('_', $where['values'])
257
            : '';
258
    }
259
}
260