Passed
Push — master ( 9b8fdb...e88b61 )
by Mike
02:53
created

CacheKey::getValuesFromBindings()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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