Passed
Push — master ( 3b95d3...c47628 )
by Mike
03:03
created

CacheKey::getTypeClause()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php namespace GeneaLabs\LaravelModelCaching;
2
3
use Illuminate\Database\Eloquent\Model;
4
use Illuminate\Database\Query\Builder;
5
use Illuminate\Support\Collection;
6
7
class CacheKey
8
{
9
    protected $eagerLoad;
10
    protected $model;
11
    protected $query;
12
13
    protected function getCachePrefix() : string
14
    {
15
        return "genealabs:laravel-model-caching:"
16
            . (config('genealabs:laravel-model-caching', '')
17
                ? config('genealabs:laravel-model-caching', '') . ":"
18
                : "");
19
    }
20
21
    public function __construct(
22
        array $eagerLoad,
23
        Model $model,
24
        Builder $query
25
    ) {
26
        $this->eagerLoad = $eagerLoad;
27
        $this->model = $model;
28
        $this->query = $query;
29
    }
30
31
    public function make(
32
        array $columns = ['*'],
33
        $idColumn = null,
34
        string $keyDifferentiator = ''
35
    ) : string {
36
        $key = $this->getCachePrefix();
37
        $key .= $this->getModelSlug();
38
        $key .= $this->getIdColumn($idColumn ?: '');
39
        $key .= $this->getQueryColumns($columns);
40
        $key .= $this->getWhereClauses();
41
        $key .= $this->getWithModels();
42
        $key .= $this->getOrderByClauses();
43
        $key .= $this->getOffsetClause();
44
        $key .= $this->getLimitClause();
45
        $key .= $keyDifferentiator;
46
47
        return $key;
48
    }
49
50
    protected function getIdColumn(string $idColumn) : string
51
    {
52
        return $idColumn ? "_{$idColumn}" : '';
53
    }
54
55
    protected function getLimitClause() : string
56
    {
57
        if (! $this->query->limit) {
58
            return '';
59
        }
60
61
        return "-limit_{$this->query->limit}";
62
    }
63
64
    protected function getModelSlug() : string
65
    {
66
        return str_slug(get_class($this->model));
67
    }
68
69
    protected function getOffsetClause() : string
70
    {
71
        if (! $this->query->offset) {
72
            return '';
73
        }
74
75
        return "-offset_{$this->query->offset}";
76
    }
77
78
    protected function getOrderByClauses() : string
79
    {
80
        $orders = collect($this->query->orders);
81
82
        return $orders
83
            ->reduce(function ($carry, $order) {
84
                if (($order['type'] ?? '') === 'Raw') {
85
                    return $carry . '_orderByRaw_' . str_slug($order['sql']);
86
                }
87
88
                return $carry . '_orderBy_' . $order['column'] . '_' . $order['direction'];
89
            })
90
            ?: '';
91
    }
92
93
    protected function getQueryColumns(array $columns) : string
94
    {
95
        if ($columns === ['*'] || $columns === []) {
96
            return '';
97
        }
98
99
        return '_' . implode('_', $columns);
100
    }
101
102
    protected function getTypeClause($where) : string
103
    {
104
        $type =in_array($where['type'], ['In', 'NotIn', 'Null', 'NotNull', 'between'])
105
            ? strtolower($where['type'])
106
            : strtolower($where['operator']);
107
108
        return str_replace(' ', '_', $type);
109
    }
110
111
    protected function getValuesClause(array $where = null) : string
112
    {
113
        if (in_array($where['type'], ['NotNull'])) {
114
            return '';
115
        }
116
117
        $values = is_array(array_get($where, 'values'))
118
            ? implode('_', $where['values'])
119
            : '';
120
121
        if (! $values && $this->query->bindings['where'] ?? false) {
122
            $values = implode('_', $this->query->bindings['where']);
123
        }
124
125
        return '_' . $values;
126
    }
127
128
    protected function getWhereClauses(array $wheres = []) : string
129
    {
130
        return $this->getWheres($wheres)
131
            ->reduce(function ($carry, $where) {
132
                $value = $this->getNestedClauses($where);
133
                $value .= $this->getColumnClauses($where);
134
                $value .= $this->getRawClauses($where);
135
                $value .= $this->getOtherClauses($where, $carry);
136
137
                return $value;
138
            })
139
            . '';
140
    }
141
142
    protected function getNestedClauses(array $where) : string
143
    {
144
        if (! in_array($where['type'], ['Exists', 'Nested', 'NotExists'])) {
145
            return '';
146
        }
147
148
        return '_' . strtolower($where['type']) . $this->getWhereClauses($where['query']->wheres);
149
    }
150
151
    protected function getColumnClauses(array $where) : string
152
    {
153
        if ($where['type'] !== 'Column') {
154
            return '';
155
        }
156
157
        return "_{$where['boolean']}_{$where['first']}_{$where['operator']}_{$where['second']}";
158
    }
159
160
    protected function getRawClauses(array $where) : string
161
    {
162
        if ($where['type'] !== 'raw') {
163
            return '';
164
        }
165
166
        return "_{$where['boolean']}_" . str_slug($where['sql']);
167
    }
168
169
    protected function getOtherClauses(array $where, string $carry = null) : string
170
    {
171
        if (in_array($where['type'], ['Exists', 'Nested', 'NotExists', 'raw', 'Column'])) {
172
            return '';
173
        }
174
175
        $value = $this->getTypeClause($where);
176
        $value .= $this->getValuesClause($where);
177
178
        return "{$carry}-{$where['column']}_{$value}";
179
    }
180
181
    protected function getWheres(array $wheres) : Collection
182
    {
183
        $wheres = collect($wheres);
184
185
        if ($wheres->isEmpty()) {
186
            $wheres = collect($this->query->wheres);
187
        }
188
189
        return $wheres;
190
    }
191
192
    protected function getWithModels() : string
193
    {
194
        $eagerLoads = collect($this->eagerLoad);
195
196
        if ($eagerLoads->isEmpty()) {
197
            return '';
198
        }
199
200
        return '-' . implode('-', $eagerLoads->keys()->toArray());
201
    }
202
}
203