Test Setup Failed
Push — master ( 6592af...c06444 )
by Chauncey
08:19
created

PropertyField::snakeize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 14
Ratio 100 %

Importance

Changes 0
Metric Value
dl 14
loc 14
rs 9.7998
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Charcoal\Property;
4
5
use PDO;
6
use InvalidArgumentException;
7
8
/**
9
 *
10
 */
11
class PropertyField
12
{
13
    /**
14
     * @var string
15
     */
16
    private $ident;
17
18
    /**
19
     * @var string
20
     */
21
    private $label;
22
23
    /**
24
     * @var string
25
     */
26
    private $sqlType;
27
28
    /**
29
     * @var integer
30
     */
31
    private $sqlPdoType;
32
33
    /**
34
     * @var string
35
     */
36
    private $sqlEncoding;
37
38
    /**
39
     * @var string
40
     */
41
    private $extra;
42
43
    /**
44
     * @var mixed
45
     */
46
    private $val;
47
48
    /**
49
     * @var mixed
50
     */
51
    private $defaultVal;
52
53
    /**
54
     * @var boolean
55
     */
56
    private $allowNull;
57
58
    /**
59
     * Holds a list of all snake_case strings.
60
     *
61
     * @var string[]
62
     */
63
    protected static $snakeCache = [];
64
65
    /**
66
     * @param  array $data The field data.
67
     * @return PropertyField Chainable
68
     */
69
    public function setData(array $data)
70
    {
71
        if (isset($data['ident'])) {
72
            $this->setIdent($data['ident']);
73
        }
74
        if (isset($data['label'])) {
75
            $this->setLabel($data['label']);
76
        }
77
        if (isset($data['sqlType'])) {
78
            $this->setSqlType($data['sqlType']);
79
        }
80
        if (isset($data['sqlPdoType'])) {
81
            $this->setSqlPdoType($data['sqlPdoType']);
82
        }
83
        if (isset($data['sqlEncoding'])) {
84
            $this->setSqlEncoding($data['sqlEncoding']);
85
        }
86
        if (isset($data['extra'])) {
87
            $this->setExtra($data['extra']);
88
        }
89
        if (isset($data['val'])) {
90
            $this->setVal($data['val']);
91
        }
92
        if (isset($data['defaultVal'])) {
93
            $this->setDefaultVal($data['defaultVal']);
94
        }
95
        if (isset($data['allowNull'])) {
96
            $this->setAllowNull($data['allowNull']);
97
        }
98
99
        return $this;
100
    }
101
102
    /**
103
     * @param  string $ident The field identifier.
104
     * @throws InvalidArgumentException If the identifier is not a string.
105
     * @return PropertyField Chainable
106
     */
107
    public function setIdent($ident)
108
    {
109
        if (!is_string($ident)) {
110
            throw new InvalidArgumentException(
111
                'Identifier must be a string'
112
            );
113
        }
114
        $this->ident = $this->snakeize($ident);
115
        return $this;
116
    }
117
118
    /**
119
     * @return string|null
120
     */
121
    public function ident()
122
    {
123
        return $this->ident;
124
    }
125
126
    /**
127
     * @param  string $label The field label.
128
     * @throws InvalidArgumentException If the label is not a string.
129
     * @return PropertyField Chainable
130
     */
131 View Code Duplication
    public function setLabel($label)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
    {
133
        if (!is_string($label) && $label !== null) {
134
            throw new InvalidArgumentException(
135
                'Label must be a string'
136
            );
137
        }
138
        $this->label = $label;
139
        return $this;
140
    }
141
142
    /**
143
     * @return string|null
144
     */
145
    public function label()
146
    {
147
        return $this->label;
148
    }
149
150
    /**
151
     * @param  string $sqlType The field SQL column type.
152
     * @throws InvalidArgumentException If the SQL type is not a string.
153
     * @return PropertyField Chainable
154
     */
155
    public function setSqlType($sqlType)
156
    {
157
        if (!is_string($sqlType) && $sqlType !== null) {
158
            throw new InvalidArgumentException(
159
                'SQL Type must be a string'
160
            );
161
        }
162
        $this->sqlType = $sqlType;
163
        return $this;
164
    }
165
166
    /**
167
     * @return string
168
     */
169
    public function sqlType()
170
    {
171
        return $this->sqlType;
172
    }
173
174
    /**
175
     * @param  integer $sqlPdoType The field PDO type.
176
     * @throws InvalidArgumentException If the PDO type is not an integer.
177
     * @return PropertyField Chainable
178
     */
179
    public function setSqlPdoType($sqlPdoType)
180
    {
181
        if (!is_integer($sqlPdoType)) {
182
            throw new InvalidArgumentException(
183
                'PDO Type must be an integer'
184
            );
185
        }
186
        $this->sqlPdoType = $sqlPdoType;
187
        return $this;
188
    }
189
190
    /**
191
     * @return integer
192
     */
193
    public function sqlPdoType()
194
    {
195
        if ($this->val() === null) {
196
            return PDO::PARAM_NULL;
197
        }
198
199
        return $this->sqlPdoType;
200
    }
201
202
    /**
203
     * @param  string|null $extra The extra.
204
     * @throws InvalidArgumentException If the extra is not a string.
205
     * @return PropertyField Chainable
206
     */
207 View Code Duplication
    public function setExtra($extra)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
    {
209
        if (!is_string($extra) && $extra !== null) {
210
            throw new InvalidArgumentException(
211
                'Extra must be a string'
212
            );
213
        }
214
        $this->extra = $extra;
215
        return $this;
216
    }
217
218
    /**
219
     * @return string|null
220
     */
221
    public function extra()
222
    {
223
        return $this->extra;
224
    }
225
226
    /**
227
     * @param  string $encoding The encoding and collation.
228
     * @throws InvalidArgumentException If the encoding is not a string.
229
     * @return PropertyField Chainable
230
     */
231
    public function setSqlEncoding($encoding)
232
    {
233
        if (!is_string($encoding) && $encoding !== null) {
234
            throw new InvalidArgumentException(
235
                'Encoding must be a string'
236
            );
237
        }
238
        $this->sqlEncoding = $encoding;
239
        return $this;
240
    }
241
242
    /**
243
     * @return string|null
244
     */
245
    public function sqlEncoding()
246
    {
247
        return $this->sqlEncoding;
248
    }
249
250
    /**
251
     * @param  mixed $val The field value.
252
     * @return PropertyField Chainable
253
     */
254
    public function setVal($val)
255
    {
256
        $this->val = $val;
257
        return $this;
258
    }
259
260
    /**
261
     * @return mixed
262
     */
263
    public function val()
264
    {
265
        return $this->val;
266
    }
267
268
    /**
269
     * @param  mixed $defaultVal The default field value.
270
     * @return PropertyField Chainable
271
     */
272
    public function setDefaultVal($defaultVal)
273
    {
274
        $this->defaultVal = $defaultVal;
275
        return $this;
276
    }
277
278
    /**
279
     * @return mixed
280
     */
281
    public function defaultVal()
282
    {
283
        return $this->defaultVal;
284
    }
285
286
    /**
287
     * @param  boolean $allowNull The field allow null flag.
288
     * @return PropertyField Chainable
289
     */
290
    public function setAllowNull($allowNull)
291
    {
292
        $this->allowNull = !!$allowNull;
293
        return $this;
294
    }
295
296
    /**
297
     * @return boolean
298
     */
299
    public function allowNull()
300
    {
301
        return $this->allowNull;
302
    }
303
304
    /**
305
     * Generates the SQL table column.
306
     *
307
     * @return string|null
308
     */
309
    public function sql()
310
    {
311
        $ident = $this->ident();
312
        if (!$ident) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ident of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
313
            return null;
314
        }
315
316
        $dataType = $this->sqlType();
317
        if (!$dataType) {
318
            return null;
319
        }
320
321
        $parts = [
322
            sprintf('`%s`', $ident),
323
            $dataType
324
        ];
325
326
        if ($this->allowNull() === false) {
327
            $parts[] = 'NOT NULL';
328
        }
329
330
        $extra = $this->extra();
331
        if ($extra) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extra of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
332
            $parts[] = $extra;
333
        }
334
335
        $encoding = $this->sqlEncoding();
336
        if ($encoding) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $encoding of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
337
            $parts[] = $encoding;
338
        }
339
340
        $default = $this->defaultVal();
341
        if ($default) {
342
            $parts[] = sprintf('DEFAULT \'%s\'', addslashes($default));
343
        }
344
345
        $comment = $this->label();
346
        if ($comment) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $comment of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
347
            $parts[] = sprintf('COMMENT \'%s\'', addslashes($comment));
348
        }
349
350
        return implode(' ', $parts);
351
    }
352
353
    /**
354
     * Transform a string from "camelCase" to "snake_case".
355
     *
356
     * @param  string $value The string to snakeize.
357
     * @return string The snake_case string.
358
     */
359 View Code Duplication
    protected function snakeize($value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
    {
361
        $key = $value;
362
363
        if (isset(static::$snakeCache[$key])) {
364
            return static::$snakeCache[$key];
365
        }
366
367
        $value = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $value));
368
369
        static::$snakeCache[$key] = $value;
370
371
        return static::$snakeCache[$key];
372
    }
373
}
374