Completed
Push — master ( 5a2551...16ba6c )
by Agel_Nash
03:05
created

SupportTrait::checkFields()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 11
nc 10
nop 3
dl 0
loc 19
ccs 11
cts 11
cp 1
crap 7
rs 8.2222
c 0
b 0
f 0
1
<?php namespace AgelxNash\Modx\Evo\Database\Traits;
2
3
use AgelxNash\Modx\Evo\Database\Exceptions;
4
5
trait SupportTrait
6
{
7
    abstract public function getConfig();
8
9
    /**
10
     * @param string $table
11
     * @return string
12
     * @throws Exceptions\TableNotDefinedException
13
     */
14
    public function getFullTableName(string $table) : string
15
    {
16
        if (empty($table)) {
17
            throw new Exceptions\TableNotDefinedException($table);
18
        }
19
20
        return implode('.', [
21
            '`' . $this->getConfig('base') . '`',
0 ignored issues
show
Unused Code introduced by
The call to AgelxNash\Modx\Evo\Datab...pportTrait::getConfig() has too many arguments starting with 'base'. ( Ignorable by Annotation )

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

21
            '`' . $this->/** @scrutinizer ignore-call */ getConfig('base') . '`',

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
22
            '`' . $this->getConfig('prefix') . $table . '`'
23
        ]);
24
    }
25
26
    /**
27
     * @param int $timestamp
28
     * @param string $fieldType
29
     * @return bool|false|string
30
     * @deprecated
31
     */
32
    public function prepareDate(int $timestamp, string $fieldType = 'DATETIME')
33
    {
34
        $date = false;
35
        if (! empty($timestamp) && $timestamp > 0) {
36
            switch ($fieldType) {
37
                case 'DATE':
38
                    $date = date('Y-m-d', $timestamp);
39
                    break;
40
                case 'TIME':
41
                    $date = date('H:i:s', $timestamp);
42
                    break;
43
                case 'YEAR':
44
                    $date = date('Y', $timestamp);
45
                    break;
46
                case 'DATETIME':
47
                default:
48
                    $date = date('Y-m-d H:i:s', $timestamp);
49
                    break;
50
            }
51
        }
52
53
        return $date;
54
    }
55
56
    /**
57
     * @param string|array $data
58
     * @return string
59
     */
60
    protected function prepareFields($data) : string
61
    {
62
        if (\is_array($data)) {
63
            $tmp = [];
64
            foreach ($data as $alias => $field) {
65
                $tmp[] = ($alias !== $field && ! \is_int($alias)) ? ($field . ' as `' . $alias . '`') : $field;
66
            }
67
68
            $data = implode(',', $tmp);
69
        }
70
        if (empty($data)) {
71
            $data = '*';
72
        }
73
74
        return $data;
75
    }
76
77
    /**
78
     * @param string|null $value
79
     * @return string
80
     */
81 2
    protected function prepareNull($value) : string
82
    {
83
        switch (true) {
84 2
            case ($value === null || (\is_scalar($value) && strtolower($value) === 'null')):
85 2
                $value = 'NULL';
86 2
                break;
87 2
            case \is_scalar($value):
88 2
                $value = "'" . $value . "'";
89 2
                break;
90
            default:
91
                throw (new Exceptions\InvaludFieldException('NULL'))
92
                    ->setData($value);
93
        }
94
95 2
        return $value;
96
    }
97
98
    /**
99
     * @param string|array $data
100
     * @param int $level
101
     * @param bool $skipFieldNames
102
     * @return array|string
103
     * @throws Exceptions\TooManyLoopsException
104
     */
105 1
    public function prepareValues($data, $level = 1, $skipFieldNames = false)
106
    {
107 1
        $fields = [];
108 1
        $values = [];
109 1
        $maxLevel = $level;
110 1
        $wrap = false;
111
112 1
        if (\is_array($data)) {
113 1
            foreach ($data as $key => $value) {
114 1
                if (\is_array($value)) {
115 1
                    if ($level > 2) {
116
                        throw new Exceptions\TooManyLoopsException();
117
                    }
118 1
                    $maxLevel++;
119 1
                    $out = $this->prepareValues($value, $level + 1);
120 1
                    if (empty($fields)) {
121 1
                        $fields = $out['fields'];
122 1
                    } elseif ($fields !== $out['fields'] && $skipFieldNames === false) {
123
                        throw (new Exceptions\InvaludFieldException("Don't match field names"))
124
                            ->setData($data);
125
                    }
126 1
                    $wrap = true;
127 1
                    $values[] = $out['values'];
128
                } else {
129 1
                    $fields[] = $key;
130 1
                    $values[] = $this->prepareNull($value);
131
                }
132
            }
133 1
            if (\is_array($values)) {
134 1
                $values = implode(', ', $values);
135
            }
136 1
            if ($wrap === false) {
137 1
                $values = '(' . $values . ')';
138
            }
139
        }
140
141 1
        if (! \is_scalar($values)) {
142
            throw (new Exceptions\InvaludFieldException('values'))
143
                ->setData($values);
144
        }
145
146 1
        if (($fields = $this->checkFields($fields, $maxLevel, $skipFieldNames))=== false) {
147
            throw (new Exceptions\InvaludFieldException('fields name'))
148
                ->setData($data);
149
        }
150
151 1
        if ($level === 2) {
152 1
            return compact('fields', 'values');
153
        }
154
155 1
        return (empty($fields) ? '' : $fields . ' VALUES ') . $values;
1 ignored issue
show
Bug introduced by
Are you sure $fields of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

155
        return (empty($fields) ? '' : /** @scrutinizer ignore-type */ $fields . ' VALUES ') . $values;
Loading history...
156
    }
157
158
    /**
159
     * @param mixed $fields
160
     * @param int $level
161
     * @param bool $skipFieldNames
162
     * @return bool|string
163
     */
164 1
    private function checkFields($fields, $level, bool $skipFieldNames = false)
165
    {
166 1
        if (\is_array($fields) && $skipFieldNames === false) {
167 1
            $onlyNumbers = true;
168 1
            foreach ($fields as $name) {
169 1
                if (! \is_int($name)) {
170 1
                    $onlyNumbers = false;
171 1
                    break;
172
                }
173
            }
174
175 1
            if ($onlyNumbers === true) {
176 1
                $fields = ($level === 2) ? false : '';
177
            } else {
178 1
                $fields = '(`' . implode('`, `', $fields) . '`)';
179
            }
180
        }
181
182 1
        return $fields;
183
    }
184
185
    /**
186
     * @param string|array $data
187
     * @return string
188
     */
189 1
    protected function prepareValuesSet($data) : string
190
    {
191 1
        if (\is_array($data)) {
192 1
            foreach ($data as $key => $value) {
193 1
                $data[$key] = $this->prepareNull($value);
194
            }
195
196 1
            foreach ($data as $key => $value) {
197 1
                $data[$key] = "`{$key}` = " . $value;
198
            }
199 1
            $data = implode(', ', $data);
200
        }
201
202 1
        return $data;
203
    }
204
205
    /**
206
     * @param string|array $data
207
     * @param bool $hasArray
208
     * @return string
209
     * @throws Exceptions\TableNotDefinedException
210
     */
211
    protected function prepareFrom($data, bool $hasArray = false) : string
212
    {
213
        if (\is_array($data) && $hasArray === true) {
214
            $tmp = [];
215
            foreach ($data as $table) {
216
                $tmp[] = $table;
217
            }
218
            $data = implode(' ', $tmp);
219
        }
220
        if (! is_scalar($data) || empty($data)) {
221
            throw new Exceptions\TableNotDefinedException($data);
222
        }
223
224
        return $data;
225
    }
226
227
    /**
228
     * @param array|string $data
229
     * @return string
230
     */
231
    protected function prepareWhere($data) : string
232
    {
233
        if (\is_array($data)) {
234
            $data = implode(' ', $data);
235
        }
236
        $data = trim($data);
237
        if (! empty($data) && stripos($data, 'WHERE') !== 0) {
238
            $data = "WHERE {$data}";
239
        }
240
241
        return $data;
242
    }
243
244
    /**
245
     * @param string $data
246
     * @return string
247
     */
248
    protected function prepareOrder($data) : string
249
    {
250
        $data = trim($data);
251
        if (! empty($data) && stripos($data, 'ORDER') !== 0) {
252
            $data = "ORDER BY {$data}";
253
        }
254
255
        return $data;
256
    }
257
258
    /**
259
     * @param string $data
260
     * @return string
261
     */
262
    protected function prepareLimit($data) : string
263
    {
264
        $data = trim($data);
265
        if (! empty($data) && stripos($data, 'LIMIT') !== 0) {
266
            $data = "LIMIT {$data}";
267
        }
268
269
        return $data;
270
    }
271
}
272