Passed
Push — master ( 2ecf44...c26111 )
by Kenneth
03:39 queued 02:05
created

MySQLBindings   F

Complexity

Total Complexity 62

Size/Duplication

Total Lines 308
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 84
c 4
b 0
f 0
dl 0
loc 308
rs 3.44
wmc 62

11 Methods

Rating   Name   Duplication   Size   Complexity  
A bIntArray() 0 19 4
B bJSON() 0 26 8
A bFloat() 0 19 6
A bInt() 0 18 6
A bStrArr() 0 6 2
A bRaw() 0 3 1
B bLike() 0 15 7
B bDate() 0 19 7
A bStr() 0 11 5
B bDateTime() 0 30 9
B bBool() 0 16 7

How to fix   Complexity   

Complex Class

Complex classes like MySQLBindings often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MySQLBindings, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace GeekLab\GLPDO2\Bindings;
4
5
use \DomainException;
6
use \Exception;
7
use \JsonException;
8
use GeekLab\GLPDO2\Constants;
9
use PDO;
10
11
class MySQLBindings implements BindingsInterface, Constants
12
{
13
    /**
14
     * Bind a boolean value as bool, with NULL option or with integer option.
15
     *
16
     * @param string|int|bool|null $value
17
     * @param bool $null
18
     * @param bool $int
19
     *
20
     * @return array
21
     * @throws Exception
22
     */
23
    public function bBool($value = null, bool $null = false, bool $int = false): array
24
    {
25
        // use NULL
26
        if ($value === null && $null) {
27
            return $this->bStr(null, true);
28
        }
29
30
        if ($value === null && $null === false) {
31
            throw new DomainException('Can not bind NULL in boolean spot.');
32
        }
33
34
        $value = (bool) $value;
35
        $value = $int ? (int) $value : $value;
36
        $type = $int ? PDO::PARAM_INT : PDO::PARAM_BOOL;
37
38
        return [$value, $type];
39
    }
40
41
    /**
42
     * Bind a date value as date or optional NULL.
43
     * YYYY-MM-DD is the proper date format.
44
     *
45
     * @param string|null $value
46
     * @param bool $null
47
     *
48
     * @return array
49
     * @throws Exception
50
     */
51
    public function bDate($value = null, bool $null = false): array
52
    {
53
        if ($value === null && !$null) {
54
            throw new DomainException('Can not bind NULL in date spot.');
55
        }
56
57
        $d = null;
58
59
        if ($value !== null) {
60
            $value = trim($value);
61
            $d = preg_match(self::DATE_REGEX, $value);
62
        }
63
64
        // Use NULL?
65
        if ($d === null && $null) {
66
            return $this->bStr(null, true);
67
        }
68
69
        return $this->bStr($d ? $value : '1970-01-01');
70
    }
71
72
    /**
73
     * Bind a date value as date time or optional NULL.
74
     * YYYY-MM-DD HH:MM:SS is the proper date format.
75
     *
76
     * @param string|null $value
77
     * @param bool $null
78
     *
79
     * @return array
80
     * @throws Exception
81
     */
82
    public function bDateTime($value = null, bool $null = false): array
83
    {
84
        if ($value === null && !$null) {
85
            throw new DomainException('Can not bind NULL in date time spot.');
86
        }
87
88
        $dt = 0;
89
90
        if ($value !== null) {
91
            // Trim $value and see if it matches full date time string format.
92
            $dt = preg_match(self::DATE_TIME_REGEX, trim($value));
93
        }
94
95
        // Use NULL?
96
        if ($dt === 0 && $null) {
97
            return $this->bStr(null, true);
98
        }
99
100
        if ($dt === 0 && $value !== null) {
101
            if (preg_match(self::DATE_REGEX, $value) === 0) {
102
                // $value is not a valid date string, set to earliest date time available (GMT).
103
                $value = '1970-01-01 00:00:00';
104
            } else {
105
                // $value is a valid date string, add midnight time.
106
                $value .= ' 00:00:00';
107
            }
108
        }
109
110
        // DateTimes are really strings.
111
        return $this->bStr($value);
112
    }
113
114
    /**
115
     * Bind a float.
116
     *
117
     * @param string|int|float|null $value
118
     * @param int $decimals
119
     * @param bool $null
120
     *
121
     * @return array
122
     * @throws Exception
123
     */
124
    public function bFloat($value = null, $decimals = 3, $null = false): array
125
    {
126
        // Use NULL?
127
        if ($value === null && $null) {
128
            return $this->bRaw('NULL');
129
        }
130
131
        if ($value === null && !$null) {
132
            throw new DomainException('Can not bind NULL in float spot.');
133
        }
134
135
        if (!is_numeric($value)) {
136
            throw new DomainException('Can not bind "' . $value . '" in float spot.');
137
        }
138
139
        $format = sprintf('%%0.%df', $decimals);
140
141
        // Apparently using PDO::PARAM_STR makes this fail!
142
        return $this->bRaw(sprintf($format, $value));
143
    }
144
145
    /**
146
     * Bind an integer with optional NULL.
147
     *
148
     * @param string|int|float|bool|null $value
149
     * @param bool $null
150
     *
151
     * @return array
152
     * @throws Exception
153
     */
154
    public function bInt($value = null, bool $null = false): array
155
    {
156
        // Use NULL?
157
        if ($value === null && $null) {
158
            return $this->bStr(null, true);
159
        }
160
161
        if ($value === null && !$null) {
162
            throw new DomainException('Can not bind NULL in integer spot.');
163
        }
164
165
        if (!is_numeric($value)) {
166
            throw new DomainException('Can not bind "' . $value . '" in integer spot.');
167
        }
168
169
        $value = sprintf('%u', $value);
170
171
        return [(int) $value, PDO::PARAM_INT];
172
    }
173
174
    /**
175
     * Convert array of integers to comma separated values. Uses %%
176
     * Great for IN() statements.
177
     *
178
     * @param array $data
179
     * @param int $default
180
     *
181
     * @return array
182
     * @throws Exception
183
     */
184
    public function bIntArray(array $data, int $default = 0): array
185
    {
186
        if (empty($data)) {
187
            throw new DomainException('Can not bind an empty array.');
188
        }
189
190
        // Make unique integer array
191
        $numbers = array();
192
193
        foreach ($data as $value) {
194
            $numbers[(int) $value] = true;
195
        }
196
197
        $numbers = array_keys($numbers);
198
199
        // turn into a string
200
        $result = implode(', ', $numbers);
201
202
        return $this->bRaw($result ?: $default);
203
    }
204
205
    /**
206
     * Bind a object or JSON string to a string
207
     *
208
     * @param string|object|null $value
209
     * @param bool $null
210
     *
211
     * @return array
212
     * @throws \JsonException
213
     */
214
    public function bJSON($value, bool $null = false): array
215
    {
216
        // Use NULL?
217
        if ($value === null && $null) {
218
            return $this->bStr(null, true);
219
        }
220
221
        if ($value === null && !$null) {
222
            throw new DomainException('Can not bind NULL in JSON spot.');
223
        }
224
225
        if (is_object($value)) {
226
            $value = json_encode($value);
227
        } elseif (is_string($value)) {
228
            $JSON = json_decode($value, false, 255);
229
230
            if (json_last_error()) {
231
                throw new JsonException('Can not bind invalid JSON in JSON spot. (' . json_last_error_msg() . ')');
232
            }
233
234
            $value = json_encode($JSON);
235
        } else {
236
            throw new JsonException('Can not bind invalid JSON in JSON spot. (' . $value . ')');
237
        }
238
239
        return $this->bStr($value);
240
    }
241
242
    /**
243
     * Create and bind string for LIKE() statements.
244
     *
245
     * @param string $value
246
     * @param bool $ends Ends with?
247
     * @param bool $starts Starts with?
248
     *
249
     * @return array
250
     */
251
    public function bLike(string $value, bool $ends = false, bool $starts = false): array
252
    {
253
254
        if ($starts && !$ends) {
255
            // Starts with.
256
            $value .= '%';
257
        } elseif (!$starts && $ends) {
258
            // Ends with.
259
            $value = '%' . $value;
260
        } elseif (!$starts && !$ends) {
261
            // Is somewhere...
262
            $value = '%' . $value . '%';
263
        }
264
265
        return [$value];
266
    }
267
268
    /**
269
     * !!!DANGER!!!
270
     * Bind a raw value.
271
     *
272
     * @param string|int|float|bool $value
273
     *
274
     * @return array
275
     */
276
    public function bRaw($value): array
277
    {
278
        return [$value];
279
    }
280
281
    /**
282
     * Bind a string value.
283
     *
284
     * @param string|int|float|bool|null $value
285
     * @param bool $null
286
     * @param int $type
287
     *
288
     * @return array
289
     * @throws Exception
290
     */
291
    public function bStr($value, bool $null = false, int $type = PDO::PARAM_STR): array
292
    {
293
        //$name = $this->getNextName();
294
295
        if ($value === null && $null) {
296
            $type = PDO::PARAM_NULL;
297
        } elseif ($value === null && !$null) {
298
            throw new DomainException('Can not bind NULL in string spot.');
299
        }
300
301
        return [(string) $value, $type];
302
    }
303
304
    /**
305
     * Convert an array into a string and bind it.
306
     * Great for IN() statements.
307
     *
308
     * @param array $values
309
     * @param string|int|float|bool $default
310
     *
311
     * @return array
312
     */
313
    public function bStrArr(array $values, $default = ''): array
314
    {
315
        //  No array elements?
316
        $aStr = empty($values) ? $default : '\'' . implode("', '", $values) . '\'';
317
318
        return $this->bRaw($aStr);
319
    }
320
}
321