Passed
Push — develop ( 23d850...73e75c )
by Kenneth
01:44
created

MySQLBindings::bDate()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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