Completed
Push — master ( 0991c5...1f821b )
by Mike
13s
created

CachedBuilder::getTypeClause()   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
        return $this->getWheres($wheres)
78
            ->reduce(function ($carry, $where) {
79
                if (in_array($where['type'], ['Exists', 'Nested', 'NotExists'])) {
80
                    return '_' . strtolower($where['type']) . $this->getWhereClauses($where['query']->wheres);
81
                }
82
83
                if ($where['type'] === 'Column') {
84
                    return "_{$where['boolean']}_{$where['first']}_{$where['operator']}_{$where['second']}";
85
                }
86
87
                if ($where['type'] === 'raw') {
88
                    return "_{$where['boolean']}_" . str_slug($where['sql']);
89
                }
90
91
                $value = array_get($where, 'value');
92
                $value .= $this->getTypeClause($where);
93
                $value .= $this->getValuesClause($where);
94
95
                return "{$carry}-{$where['column']}_{$value}";
96
            })
97
            . '';
98
    }
99
100
    protected function getWithModels() : string
101
    {
102
        $eagerLoads = collect($this->eagerLoad);
103
104
        if ($eagerLoads->isEmpty()) {
105
            return '';
106
        }
107
108
        return '-' . implode('-', $eagerLoads->keys()->toArray());
109
    }
110
111
	protected function getOrderByClauses(){
112
        $orders = collect($this->query->orders);
113
114
        return $orders->reduce(function($carry, $order){
115
            return $carry . '_orderBy_' . $order['column'] . '_' . $order['direction'];
116
        });
117
    }
118
119
    protected function getMethodKey(string $postfix = null) : string
120
    {
121
        return str_slug(get_class($this->model)) . $postfix;
122
    }
123
124
    protected function getModelTag() : array
125
    {
126
        return [str_slug(get_class($this->model))];
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
        return $this->cache($this->getModelTag())
156
            ->rememberForever($this->getMethodKey("-avg_{$column}"), function () use ($column) {
157
                return parent::avg($column);
158
            });
159
    }
160
161 View Code Duplication
    public function count($columns = ['*'])
162
    {
163
        return $this->cache($this->getModelTag())
164
            ->rememberForever($this->getMethodKey("-count"), function () use ($columns) {
165
                return parent::count($columns);
166
            });
167
    }
168
169
    public function cursor()
170
    {
171
        return $this->cache($this->getModelTag())
172
            ->rememberForever($this->getMethodKey("-cursor"), function () {
173
                return collect(parent::cursor());
174
            });
175
    }
176
177
    /**
178
     * @SuppressWarnings(PHPMD.ShortVariable)
179
     */
180 View Code Duplication
    public function find($id, $columns = ['*'])
181
    {
182
        return $this->cache($this->getCacheTags())
183
            ->rememberForever($this->getCacheKey($columns, $id), function () use ($id, $columns) {
184
                return parent::find($id, $columns);
185
            });
186
    }
187
188 View Code Duplication
    public function first($columns = ['*'])
189
    {
190
        return $this->cache($this->getCacheTags())
191
            ->rememberForever($this->getCacheKey($columns) . '-first', function () use ($columns) {
192
                return parent::first($columns);
193
            });
194
    }
195
196 View Code Duplication
    public function get($columns = ['*'])
197
    {
198
        return $this->cache($this->getCacheTags())
199
            ->rememberForever($this->getCacheKey($columns), function () use ($columns) {
200
                return parent::get($columns);
201
            });
202
    }
203
204 View Code Duplication
    public function max($column)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
205
    {
206
        return $this->cache($this->getModelTag())
207
            ->rememberForever($this->getMethodKey("-max_{$column}"), function () use ($column) {
208
                return parent::max($column);
209
            });
210
    }
211
212 View Code Duplication
    public function min($column)
213
    {
214
        return $this->cache($this->getModelTag())
215
            ->rememberForever($this->getMethodKey("-min_{$column}"), function () use ($column) {
216
                return parent::min($column);
217
            });
218
    }
219
220
    public function pluck($column, $key = null)
221
    {
222
        $cacheKey = $this->getCacheKey([$column]) . "-pluck_{$column}";
223
224
        if ($key) {
225
            $cacheKey .= "_{$key}";
226
        }
227
228
        return $this->cache($this->getCacheTags())
229
            ->rememberForever($cacheKey, function () use ($column, $key) {
230
                return parent::pluck($column, $key);
231
            });
232
    }
233
234 View Code Duplication
    public function sum($column)
235
    {
236
        return $this->cache($this->getModelTag())
237
            ->rememberForever($this->getMethodKey("-sum_{$column}"), function () use ($column) {
238
                return parent::sum($column);
239
            });
240
    }
241
242
    protected function getTypeClause($where)
243
    {
244
        return in_array($where['type'], ['In', 'Null', 'NotNull'])
245
            ? strtolower($where['type'])
246
            : '';
247
    }
248
249
    protected function getValuesClause($where)
250
    {
251
        return is_array(array_get($where, 'values'))
252
            ? '_' . implode('_', $where['values'])
253
            : '';
254
    }
255
256
    protected function getWheres(array $wheres) : Collection
257
    {
258
        $wheres = collect($wheres);
259
260
        if ($wheres->isEmpty()) {
261
            $wheres = collect($this->query->wheres);
262
        }
263
264
        return $wheres;
265
    }
266
}
267