Passed
Push — master ( dd9af0...e8aa06 )
by Mike
02:35
created

CacheKey::getRawClauses()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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

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

198
    protected function getOtherClauses(array $where, /** @scrutinizer ignore-unused */ string $carry = null) : string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
199
    {
200
        if (in_array($where["type"], ["Exists", "Nested", "NotExists", "raw", "Column"])) {
201
            return "";
202
        }
203
204
        $value = $this->getTypeClause($where);
205
        $value .= $this->getValuesClause($where);
206
        $this->currentBinding++;
207
208
        return "{$where["column"]}_{$value}";
209
    }
210
211
    protected function getWheres(array $wheres) : Collection
212
    {
213
        $wheres = collect($wheres);
214
215
        if ($wheres->isEmpty()) {
216
            $wheres = collect($this->query->wheres);
217
        }
218
219
        return $wheres;
220
    }
221
222
    protected function getWithModels() : string
223
    {
224
        $eagerLoads = collect($this->eagerLoad);
225
226
        if ($eagerLoads->isEmpty()) {
227
            return "";
228
        }
229
230
        return "-" . implode("-", $eagerLoads->keys()->toArray());
231
    }
232
}
233