Completed
Pull Request — master (#6)
by Mike
02:34
created

CachedBuilder   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 233
Duplicated Lines 37.77 %

Importance

Changes 0
Metric Value
dl 88
loc 233
rs 9
c 0
b 0
f 0
wmc 35

20 Methods

Rating   Name   Duplication   Size   Complexity  
A cache() 0 9 2
A getCacheKey() 0 11 2
A getQueryColumns() 0 7 3
A getModelSlug() 0 3 1
A getLimitClause() 0 7 2
A getOffsetClause() 0 7 2
A min() 8 8 1
A pluck() 0 12 2
A getCacheTags() 0 22 3
A find() 8 8 1
A getWithModels() 0 9 2
B getWhereClauses() 0 18 5
A max() 8 8 1
A avg() 8 8 1
A getIdColumn() 0 4 2
A count() 8 8 1
A get() 8 8 1
A cursor() 8 8 1
A sum() 8 8 1
A first() 8 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
        // dump($this->query->wheres);
77
        return collect($this->query->wheres)->reduce(function ($carry, $where) {
78
            if (! $where['column'] ?? false) {
79
                return $carry . '';
80
            }
81
82
            $value = $where['value'] ?? '';
83
84
            if ($where['values'] ??  false) {
85
                $value .= 'in_' . implode('_', $where['values']);
86
            }
87
88
            $value = $where['type'] === 'Null' ? 'null' : $value;
89
90
            return "{$carry}-{$where['column']}_{$value}";
91
        }) ?: '';
92
    }
93
94
    protected function getWithModels() : string
95
    {
96
        $eagerLoads = collect($this->eagerLoad);
97
98
        if ($eagerLoads->isEmpty()) {
99
            return '';
100
        }
101
102
        return '-' . implode('-', $eagerLoads->keys()->toArray());
103
    }
104
105
    protected function getCacheTags() : array
106
    {
107
        return collect($this->eagerLoad)->keys()
108
            ->map(function ($relationName) {
109
                $relation = collect(explode('.', $relationName))
110
                    ->reduce(function ($carry, $name) {
111
                        if (! $carry) {
112
                            $carry = $this->model;
113
                        }
114
115
                        if ($carry instanceof Relation) {
116
                            $carry = $carry->getQuery()->model;
117
                        }
118
119
                        return $carry->{$name}();
120
                    });
121
122
                return str_slug(get_class($relation->getQuery()->model));
123
            })
124
            ->prepend(str_slug(get_class($this->model)))
125
            ->values()
126
            ->toArray();
127
    }
128
129 View Code Duplication
    public function avg($column)
130
    {
131
        $tags = [str_slug(get_class($this->model))];
132
        $key = str_slug(get_class($this->model)) ."-avg_{$column}";
133
134
        return $this->cache($tags)
135
            ->rememberForever($key, function () use ($column) {
136
                return parent::avg($column);
137
            });
138
    }
139
140 View Code Duplication
    public function count($columns = ['*'])
141
    {
142
        $tags = [str_slug(get_class($this->model))];
143
        $key = str_slug(get_class($this->model)) ."-count";
144
145
        return $this->cache($tags)
146
            ->rememberForever($key, function () use ($columns) {
147
                return parent::count($columns);
148
            });
149
    }
150
151 View Code Duplication
    public function cursor()
152
    {
153
        $tags = [str_slug(get_class($this->model))];
154
        $key = str_slug(get_class($this->model)) ."-cursor";
155
156
        return $this->cache($tags)
157
            ->rememberForever($key, function () {
158
                return collect(parent::cursor());
159
            });
160
    }
161
162
    /**
163
     * @SuppressWarnings(PHPMD.ShortVariable)
164
     */
165 View Code Duplication
    public function find($id, $columns = ['*'])
166
    {
167
        $tags = $this->getCacheTags();
168
        $key = $this->getCacheKey($columns, $id);
169
170
        return $this->cache($tags)
171
            ->rememberForever($key, function () use ($id, $columns) {
172
                return parent::find($id, $columns);
173
            });
174
    }
175
176 View Code Duplication
    public function first($columns = ['*'])
177
    {
178
        $tags = $this->getCacheTags();
179
        $key = $this->getCacheKey($columns) . '-first';
180
181
        return $this->cache($tags)
182
            ->rememberForever($key, function () use ($columns) {
183
                return parent::first($columns);
184
            });
185
    }
186
187 View Code Duplication
    public function get($columns = ['*'])
188
    {
189
        $tags = $this->getCacheTags();
190
        $key = $this->getCacheKey($columns);
191
192
        return $this->cache($tags)
193
            ->rememberForever($key, function () use ($columns) {
194
                return parent::get($columns);
195
            });
196
    }
197
198 View Code Duplication
    public function max($column)
199
    {
200
        $tags = [str_slug(get_class($this->model))];
201
        $key = str_slug(get_class($this->model)) ."-max_{$column}";
202
203
        return $this->cache($tags)
204
            ->rememberForever($key, function () use ($column) {
205
                return parent::max($column);
206
            });
207
    }
208
209 View Code Duplication
    public function min($column)
210
    {
211
        $tags = [str_slug(get_class($this->model))];
212
        $key = str_slug(get_class($this->model)) ."-min_{$column}";
213
214
        return $this->cache($tags)
215
            ->rememberForever($key, function () use ($column) {
216
                return parent::min($column);
217
            });
218
    }
219
220
    public function pluck($column, $key = null)
221
    {
222
        $tags = $this->getCacheTags();
223
        $cacheKey = $this->getCacheKey([$column]) . "-pluck_{$column}";
224
225
        if ($key) {
226
            $cacheKey .= "_{$key}";
227
        }
228
229
        return $this->cache($tags)
230
            ->rememberForever($cacheKey, function () use ($column, $key) {
231
                return parent::pluck($column, $key);
232
            });
233
    }
234
235 View Code Duplication
    public function sum($column)
236
    {
237
        $tags = [str_slug(get_class($this->model))];
238
        $key = str_slug(get_class($this->model)) ."-sum_{$column}";
239
240
        return $this->cache($tags)
241
            ->rememberForever($key, function () use ($column) {
242
                return parent::sum($column);
243
            });
244
    }
245
}
246