Passed
Pull Request — master (#7)
by Mike
02:40
created

CachedBuilder::count()   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->getOffsetClause();
31
        $key .= $this->getLimitClause();
32
33
        return $key;
34
    }
35
36
    protected function getIdColumn(string $idColumn) : string
37
    {
38
39
        return $idColumn ? "_{$idColumn}" : '';
40
    }
41
42
    protected function getLimitClause() : string
43
    {
44
        if (! $this->query->limit) {
45
            return '';
46
        }
47
48
        return "-limit_{$this->query->limit}";
49
    }
50
51
    protected function getModelSlug() : string
52
    {
53
        return str_slug(get_class($this->model));
54
    }
55
56
    protected function getOffsetClause() : string
57
    {
58
        if (! $this->query->offset) {
59
            return '';
60
        }
61
62
        return "-offset_{$this->query->offset}";
63
    }
64
65
    protected function getQueryColumns(array $columns) : string
66
    {
67
        if ($columns === ['*'] || $columns === []) {
68
            return '';
69
        }
70
71
        return '_' . implode('_', $columns);
72
    }
73
74
    protected function getWhereClauses() : string
75
    {
76
        return collect($this->query->wheres)->reduce(function ($carry, $where) {
77
            $value = array_get($where, 'value');
78
79
            if (in_array($where['type'], ['In', 'Null', 'NotNull'])) {
80
                $value = strtolower($where['type']);
81
            }
82
83
            if (is_array(array_get($where, 'values'))) {
84
                $value .= '_' . implode('_', $where['values']);
85
            }
86
87
            return "{$carry}-{$where['column']}_{$value}";
88
        }) ?: '';
89
    }
90
91
    protected function getWithModels() : string
92
    {
93
        $eagerLoads = collect($this->eagerLoad);
94
95
        if ($eagerLoads->isEmpty()) {
96
            return '';
97
        }
98
99
        return '-' . implode('-', $eagerLoads->keys()->toArray());
100
    }
101
102
    protected function getCacheTags() : array
103
    {
104
        return collect($this->eagerLoad)->keys()
105
            ->map(function ($relationName) {
106
                $relation = collect(explode('.', $relationName))
107
                    ->reduce(function ($carry, $name) {
108
                        if (! $carry) {
109
                            $carry = $this->model;
110
                        }
111
112
                        if ($carry instanceof Relation) {
113
                            $carry = $carry->getQuery()->model;
114
                        }
115
116
                        return $carry->{$name}();
117
                    });
118
119
                return str_slug(get_class($relation->getQuery()->model));
120
            })
121
            ->prepend(str_slug(get_class($this->model)))
122
            ->values()
123
            ->toArray();
124
    }
125
126 View Code Duplication
    public function avg($column)
127
    {
128
        $tags = [str_slug(get_class($this->model))];
129
        $key = str_slug(get_class($this->model)) ."-avg_{$column}";
130
131
        return $this->cache($tags)
132
            ->rememberForever($key, function () use ($column) {
133
                return parent::avg($column);
134
            });
135
    }
136
137 View Code Duplication
    public function count($columns = ['*'])
138
    {
139
        $tags = [str_slug(get_class($this->model))];
140
        $key = str_slug(get_class($this->model)) ."-count";
141
142
        return $this->cache($tags)
143
            ->rememberForever($key, function () use ($columns) {
144
                return parent::count($columns);
145
            });
146
    }
147
148 View Code Duplication
    public function cursor()
149
    {
150
        $tags = [str_slug(get_class($this->model))];
151
        $key = str_slug(get_class($this->model)) ."-cursor";
152
153
        return $this->cache($tags)
154
            ->rememberForever($key, function () {
155
                return collect(parent::cursor());
156
            });
157
    }
158
159
    /**
160
     * @SuppressWarnings(PHPMD.ShortVariable)
161
     */
162 View Code Duplication
    public function find($id, $columns = ['*'])
163
    {
164
        $tags = $this->getCacheTags();
165
        $key = $this->getCacheKey($columns, $id);
166
167
        return $this->cache($tags)
168
            ->rememberForever($key, function () use ($id, $columns) {
169
                return parent::find($id, $columns);
170
            });
171
    }
172
173 View Code Duplication
    public function first($columns = ['*'])
174
    {
175
        $tags = $this->getCacheTags();
176
        $key = $this->getCacheKey($columns) . '-first';
177
178
        return $this->cache($tags)
179
            ->rememberForever($key, function () use ($columns) {
180
                return parent::first($columns);
181
            });
182
    }
183
184 View Code Duplication
    public function get($columns = ['*'])
185
    {
186
        $tags = $this->getCacheTags();
187
        $key = $this->getCacheKey($columns);
188
189
        return $this->cache($tags)
190
            ->rememberForever($key, function () use ($columns) {
191
                return parent::get($columns);
192
            });
193
    }
194
195 View Code Duplication
    public function max($column)
196
    {
197
        $tags = [str_slug(get_class($this->model))];
198
        $key = str_slug(get_class($this->model)) ."-max_{$column}";
199
200
        return $this->cache($tags)
201
            ->rememberForever($key, function () use ($column) {
202
                return parent::max($column);
203
            });
204
    }
205
206 View Code Duplication
    public function min($column)
207
    {
208
        $tags = [str_slug(get_class($this->model))];
209
        $key = str_slug(get_class($this->model)) ."-min_{$column}";
210
211
        return $this->cache($tags)
212
            ->rememberForever($key, function () use ($column) {
213
                return parent::min($column);
214
            });
215
    }
216
217
    public function pluck($column, $key = null)
218
    {
219
        $tags = $this->getCacheTags();
220
        $cacheKey = $this->getCacheKey([$column]) . "-pluck_{$column}";
221
222
        if ($key) {
223
            $cacheKey .= "_{$key}";
224
        }
225
226
        return $this->cache($tags)
227
            ->rememberForever($cacheKey, function () use ($column, $key) {
228
                return parent::pluck($column, $key);
229
            });
230
    }
231
232 View Code Duplication
    public function sum($column)
233
    {
234
        $tags = [str_slug(get_class($this->model))];
235
        $key = str_slug(get_class($this->model)) ."-sum_{$column}";
236
237
        return $this->cache($tags)
238
            ->rememberForever($key, function () use ($column) {
239
                return parent::sum($column);
240
            });
241
    }
242
}
243