Completed
Push — master ( b71a5d...fa70a6 )
by Mike
07:35
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
        return $idColumn ? "_{$idColumn}" : '';
39
    }
40
41
    protected function getLimitClause() : string
42
    {
43
        if (! $this->query->limit) {
44
            return '';
45
        }
46
47
        return "-limit_{$this->query->limit}";
48
    }
49
50
    protected function getModelSlug() : string
51
    {
52
        return str_slug(get_class($this->model));
53
    }
54
55
    protected function getOffsetClause() : string
56
    {
57
        if (! $this->query->offset) {
58
            return '';
59
        }
60
61
        return "-offset_{$this->query->offset}";
62
    }
63
64
    protected function getQueryColumns(array $columns) : string
65
    {
66
        if ($columns === ['*'] || $columns === []) {
67
            return '';
68
        }
69
70
        return '_' . implode('_', $columns);
71
    }
72
73
    protected function getWhereClauses() : string
74
    {
75
        return collect($this->query->wheres)->reduce(function ($carry, $where) {
76
            $value = $where['value'] ?? implode('_', ($where['values'] ?? []));
77
78
            return "{$carry}-{$where['column']}_{$value}";
79
        }) ?: '';
80
    }
81
82
    protected function getWithModels() : string
83
    {
84
        $eagerLoads = collect($this->eagerLoad);
85
86
        if ($eagerLoads->isEmpty()) {
87
            return '';
88
        }
89
90
        return '-' . implode('-', $eagerLoads->keys()->toArray());
91
    }
92
93
    protected function getCacheTags() : array
94
    {
95
        return collect($this->eagerLoad)->keys()
96
            ->map(function ($relationName) {
97
                $relation = collect(explode('.', $relationName))
98
                    ->reduce(function ($carry, $name) {
99
                        if (! $carry) {
100
                            $carry = $this->model;
101
                        }
102
103
                        if ($carry instanceof Relation) {
104
                            $carry = $carry->getQuery()->model;
1 ignored issue
show
Bug introduced by
The property model does not seem to exist on Illuminate\Database\Query\Builder.
Loading history...
105
                        }
106
107
                        return $carry->{$name}();
108
                    });
109
110
                return str_slug(get_class($relation->getQuery()->model));
111
            })
112
            ->prepend(str_slug(get_class($this->model)))
113
            ->values()
114
            ->toArray();
115
    }
116
117 View Code Duplication
    public function avg($column)
118
    {
119
        $tags = [str_slug(get_class($this->model))];
120
        $key = str_slug(get_class($this->model)) ."-avg_{$column}";
121
122
        return $this->cache($tags)
123
            ->rememberForever($key, function () use ($column) {
124
                return parent::avg($column);
1 ignored issue
show
Bug introduced by
The method avg() does not exist on Illuminate\Database\Eloquent\Builder. It seems like you code against a sub-type of Illuminate\Database\Eloquent\Builder such as GeneaLabs\LaravelModelCaching\CachedBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

124
                return parent::/** @scrutinizer ignore-call */ avg($column);
Loading history...
125
            });
126
    }
127
128 View Code Duplication
    public function count($columns = ['*'])
129
    {
130
        $tags = [str_slug(get_class($this->model))];
131
        $key = str_slug(get_class($this->model)) ."-count";
132
133
        return $this->cache($tags)
134
            ->rememberForever($key, function () use ($columns) {
135
                return parent::count($columns);
1 ignored issue
show
Bug introduced by
The method count() does not exist on Illuminate\Database\Eloquent\Builder. It seems like you code against a sub-type of Illuminate\Database\Eloquent\Builder such as GeneaLabs\LaravelModelCaching\CachedBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

135
                return parent::/** @scrutinizer ignore-call */ count($columns);
Loading history...
136
            });
137
    }
138
139 View Code Duplication
    public function cursor()
140
    {
141
        $tags = [str_slug(get_class($this->model))];
142
        $key = str_slug(get_class($this->model)) ."-cursor";
143
144
        return $this->cache($tags)
145
            ->rememberForever($key, function () {
146
                return collect(parent::cursor());
147
            });
148
    }
149
150
    /**
151
     * @SuppressWarnings(PHPMD.ShortVariable)
152
     */
153 View Code Duplication
    public function find($id, $columns = ['*'])
154
    {
155
        $tags = $this->getCacheTags();
156
        $key = $this->getCacheKey($columns, $id);
157
158
        return $this->cache($tags)
159
            ->rememberForever($key, function () use ($id, $columns) {
160
                return parent::find($id, $columns);
161
            });
162
    }
163
164 View Code Duplication
    public function first($columns = ['*'])
165
    {
166
        $tags = $this->getCacheTags();
167
        $key = $this->getCacheKey($columns) . '-first';
168
169
        return $this->cache($tags)
170
            ->rememberForever($key, function () use ($columns) {
171
                return parent::first($columns);
172
            });
173
    }
174
175 View Code Duplication
    public function get($columns = ['*'])
176
    {
177
        $tags = $this->getCacheTags();
178
        $key = $this->getCacheKey($columns);
179
180
        return $this->cache($tags)
181
            ->rememberForever($key, function () use ($columns) {
182
                return parent::get($columns);
183
            });
184
    }
185
186 View Code Duplication
    public function max($column)
187
    {
188
        $tags = [str_slug(get_class($this->model))];
189
        $key = str_slug(get_class($this->model)) ."-max_{$column}";
190
191
        return $this->cache($tags)
192
            ->rememberForever($key, function () use ($column) {
193
                return parent::max($column);
1 ignored issue
show
Bug introduced by
The method max() does not exist on Illuminate\Database\Eloquent\Builder. It seems like you code against a sub-type of Illuminate\Database\Eloquent\Builder such as GeneaLabs\LaravelModelCaching\CachedBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
                return parent::/** @scrutinizer ignore-call */ max($column);
Loading history...
194
            });
195
    }
196
197 View Code Duplication
    public function min($column)
198
    {
199
        $tags = [str_slug(get_class($this->model))];
200
        $key = str_slug(get_class($this->model)) ."-min_{$column}";
201
202
        return $this->cache($tags)
203
            ->rememberForever($key, function () use ($column) {
204
                return parent::min($column);
1 ignored issue
show
Bug introduced by
The method min() does not exist on Illuminate\Database\Eloquent\Builder. It seems like you code against a sub-type of Illuminate\Database\Eloquent\Builder such as GeneaLabs\LaravelModelCaching\CachedBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

204
                return parent::/** @scrutinizer ignore-call */ min($column);
Loading history...
205
            });
206
    }
207
208
    public function pluck($column, $key = null)
209
    {
210
        $tags = $this->getCacheTags();
211
        $cacheKey = $this->getCacheKey([$column]) . "-pluck_{$column}";
212
213
        if ($key) {
214
            $cacheKey .= "_{$key}";
215
        }
216
217
        return $this->cache($tags)
218
            ->rememberForever($cacheKey, function () use ($column, $key) {
219
                return parent::pluck($column, $key);
220
            });
221
    }
222
223 View Code Duplication
    public function sum($column)
224
    {
225
        $tags = [str_slug(get_class($this->model))];
226
        $key = str_slug(get_class($this->model)) ."-sum_{$column}";
227
228
        return $this->cache($tags)
229
            ->rememberForever($key, function () use ($column) {
230
                return parent::sum($column);
1 ignored issue
show
Bug introduced by
The method sum() does not exist on Illuminate\Database\Eloquent\Builder. It seems like you code against a sub-type of Illuminate\Database\Eloquent\Builder such as GeneaLabs\LaravelModelCaching\CachedBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

230
                return parent::/** @scrutinizer ignore-call */ sum($column);
Loading history...
231
            });
232
    }
233
}
234