GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#58)
by joseph
17:08
created

MappingHelper::setSimpleJsonFields()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.1574

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.6845
c 0
b 0
f 0
ccs 11
cts 14
cp 0.7856
cc 4
eloc 14
nc 3
nop 3
crap 4.1574
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta;
4
5
use Doctrine\Common\Util\Inflector;
6
use Doctrine\DBAL\Types\Type;
7
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
8
use Doctrine\ORM\Mapping\Builder\FieldBuilder;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\TypeHelper;
11
use EdmondsCommerce\DoctrineStaticMeta\Schema\Database;
12
13
/**
14
 * Class MappingHelper
15
 *
16
 * Helper functions to assist with setting up Doctrine mapping meta data
17
 *
18
 * @package EdmondsCommerce\DoctrineStaticMeta
19
 *
20
 * @SuppressWarnings(PHPMD.StaticAccess)
21
 */
22
class MappingHelper
23
{
24
25
    /**
26
     * @see https://stackoverflow.com/a/34275878
27
     */
28
    public const DATETIME_DEFAULT_CURRENT_TIME_STAMP = 0;
29
30
    /**
31
     * Quick accessors for common types that are supported by methods in this helper
32
     *
33
     * Note this is not all of the types supported by Doctrine
34
     */
35
    public const TYPE_STRING   = Type::STRING;
36
    public const TYPE_DATETIME = Type::DATETIME;
37
    public const TYPE_FLOAT    = Type::FLOAT;
38
    public const TYPE_DECIMAL  = Type::DECIMAL;
39
    public const TYPE_INTEGER  = Type::INTEGER;
40
    public const TYPE_TEXT     = Type::TEXT;
41
    public const TYPE_BOOLEAN  = Type::BOOLEAN;
42
    public const TYPE_JSON     = Type::JSON;
43
44
    /**
45
     * This is the list of common types, listed above
46
     */
47
    public const COMMON_TYPES = [
48
        self::TYPE_STRING,
49
        self::TYPE_DATETIME,
50
        self::TYPE_FLOAT,
51
        self::TYPE_DECIMAL,
52
        self::TYPE_INTEGER,
53
        self::TYPE_TEXT,
54
        self::TYPE_BOOLEAN,
55
        self::TYPE_JSON,
56
    ];
57
58
    /**
59
     * Which types do we support marking as unique
60
     */
61
    public const UNIQUEABLE_TYPES = [
62
        self::TYPE_STRING,
63
        self::TYPE_INTEGER,
64
    ];
65
66
    public const PHP_TYPE_STRING   = 'string';
67
    public const PHP_TYPE_DATETIME = '\\'.\DateTime::class;
68
    public const PHP_TYPE_FLOAT    = 'float';
69
    public const PHP_TYPE_INTEGER  = 'int';
70
    public const PHP_TYPE_TEXT     = 'string';
71
    public const PHP_TYPE_BOOLEAN  = 'bool';
72
73
    public const PHP_TYPES = [
74
        self::PHP_TYPE_STRING,
75
        self::PHP_TYPE_DATETIME,
76
        self::PHP_TYPE_FLOAT,
77
        self::PHP_TYPE_INTEGER,
78
        self::PHP_TYPE_TEXT,
79
        self::PHP_TYPE_BOOLEAN,
80
    ];
81
82
    /**
83
     * The PHP type associated with the mapping type
84
     */
85
    public const COMMON_TYPES_TO_PHP_TYPES = [
86
        self::TYPE_STRING   => self::PHP_TYPE_STRING,
87
        self::TYPE_DATETIME => self::PHP_TYPE_DATETIME,
88
        self::TYPE_FLOAT    => self::PHP_TYPE_FLOAT,
89
        self::TYPE_DECIMAL  => self::PHP_TYPE_STRING,
90
        self::TYPE_INTEGER  => self::PHP_TYPE_INTEGER,
91
        self::TYPE_TEXT     => self::PHP_TYPE_TEXT,
92
        self::TYPE_BOOLEAN  => self::PHP_TYPE_BOOLEAN,
93
        self::TYPE_JSON     => self::PHP_TYPE_STRING,
94
    ];
95
96
    /**
97
     * This is the full list of mapping types
98
     *
99
     * @see \Doctrine\DBAL\Types\Type
100
     */
101
    public const ALL_DBAL_TYPES = [
102
        Type::TARRAY,
103
        Type::SIMPLE_ARRAY,
104
        Type::JSON,
105
        Type::BIGINT,
106
        Type::BOOLEAN,
107
        Type::DATETIME,
108
        Type::DATETIME_IMMUTABLE,
109
        Type::DATETIMETZ,
110
        Type::DATETIMETZ_IMMUTABLE,
111
        Type::DATE,
112
        Type::DATE_IMMUTABLE,
113
        Type::TIME,
114
        Type::TIME_IMMUTABLE,
115
        Type::DECIMAL,
116
        Type::INTEGER,
117
        Type::OBJECT,
118
        Type::SMALLINT,
119
        Type::STRING,
120
        Type::TEXT,
121
        Type::BINARY,
122
        Type::BLOB,
123
        Type::FLOAT,
124
        Type::GUID,
125
        Type::DATEINTERVAL,
126
    ];
127
128
    public const MIXED_TYPES = [
129
        // Doctrine hydrates decimal values as strings.
130
        // However, setting these using an int or float is also valid.
131
        Type::DECIMAL,
132
    ];
133
134
    /**
135
     * @param string $entityFqn
136
     *
137
     * @return string
138
     */
139 112
    public static function getPluralForFqn(string $entityFqn): string
140
    {
141 112
        $singular = self::getSingularForFqn($entityFqn);
142
143 112
        return Inflector::pluralize($singular);
144
    }
145
146
    /**
147
     * @param string $entityFqn
148
     *
149
     * @return string
150
     */
151 112
    public static function getSingularForFqn(string $entityFqn): string
152
    {
153 112
        $shortName = self::getShortNameForFqn($entityFqn);
154
155 112
        return lcfirst(Inflector::singularize($shortName));
156
    }
157
158
    /**
159
     * @param string $entityFqn
160
     *
161
     * @return string
162
     */
163 112
    public static function getShortNameForFqn(string $entityFqn): string
164
    {
165 112
        return substr($entityFqn, strrpos($entityFqn, '\\') + 1);
166
    }
167
168
    /**
169
     * Get the properly backticked and formatted column name for a field
170
     *
171
     * @param string $field
172
     *
173
     * @return string
174
     */
175 34
    public static function getColumnNameForField(string $field): string
176
    {
177 34
        return self::backticks(Inflector::tableize($field));
178
    }
179
180
    /**
181
     * @param string $entityFqn
182
     *
183
     * @return string
184
     */
185 43
    public static function getTableNameForEntityFqn(
186
        string $entityFqn
187
    ): string {
188 43
        $namespaceHelper = new NamespaceHelper();
189 43
        $subFqn          = $namespaceHelper->getEntitySubNamespace(
190 43
            $entityFqn
191
        );
192 43
        $tableName       = \str_replace('\\', '', $subFqn);
193 43
        $tableName       = self::backticks(Inflector::tableize($tableName));
194 43
        if (\strlen($tableName) > Database::MAX_IDENTIFIER_LENGTH) {
195
            $tableName = substr($tableName, -Database::MAX_IDENTIFIER_LENGTH);
196
        }
197
198 43
        return $tableName;
199
    }
200
201
    /**
202
     * Wrap the name in backticks
203
     *
204
     * @param string $name
205
     *
206
     * @return string
207
     */
208 44
    public static function backticks(string $name): string
209
    {
210 44
        return '`'.$name.'`';
211
    }
212
213 5
    private static function getType($var): string
214
    {
215 5
        static $typeHelper;
216 5
        if (null === $typeHelper) {
217 1
            $typeHelper = new TypeHelper();
218
        }
219
220 5
        return $typeHelper->getType($var);
221
    }
222
223
    /**
224
     * Set bog standard string fields quickly in bulk
225
     *
226
     * @param array                $fields
227
     * @param ClassMetadataBuilder $builder
228
     * @param mixed                $default
229
     * @param bool                 $isUnique
230
     * In this case the boolean argument is simply data
231
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
232
     */
233 26
    public static function setSimpleStringFields(
234
        array $fields,
235
        ClassMetadataBuilder $builder,
236
        $default = null,
237
        bool $isUnique = false
238
    ): void {
239 26
        if (null !== $default && !\is_string($default)) {
240 1
            throw new \InvalidArgumentException(
241 1
                'Invalid default value '.$default
242 1
                .' with type '.self::getType($default)
243
            );
244
        }
245 25
        foreach ($fields as $field) {
246 25
            $fieldBuilder = new FieldBuilder(
247 25
                $builder,
248
                [
249 25
                    'fieldName' => $field,
250 25
                    'type'      => Type::STRING,
251 25
                    'default'   => $default,
252
                ]
253
            );
254
            $fieldBuilder
255 25
                ->columnName(self::getColumnNameForField($field))
256 25
                ->nullable(null === $default)
257 25
                ->unique($isUnique)
258
                // see https://github.com/symfony/symfony-docs/issues/639
259
                // basically, if we are using utf8mb4 then the max col
260
                // length on strings is no longer 255.
261 25
                ->length(190)
262 25
                ->build();
263
        }
264 25
    }
265
266
    /**
267
     * Set bog standard text fields quickly in bulk
268
     *
269
     * @param array                $fields
270
     * @param ClassMetadataBuilder $builder
271
     * @param mixed                $default
272
     * In this case the boolean argument is simply data
273
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
274
     */
275 15
    public static function setSimpleTextFields(
276
        array $fields,
277
        ClassMetadataBuilder $builder,
278
        $default = null
279
    ): void {
280 15
        if (null !== $default && !\is_string($default)) {
281 1
            throw new \InvalidArgumentException(
282 1
                'Invalid default value '.$default
283 1
                .' with type '.self::getType($default)
284
            );
285
        }
286 14
        foreach ($fields as $field) {
287 14
            $fieldBuilder = new FieldBuilder(
288 14
                $builder,
289
                [
290 14
                    'fieldName' => $field,
291 14
                    'type'      => Type::TEXT,
292 14
                    'default'   => $default,
293
                ]
294
            );
295 14
            $fieldBuilder->columnName(self::getColumnNameForField($field))
296 14
                         ->nullable(null === $default)
297 14
                         ->build();
298
        }
299 14
    }
300
301
302
    /**
303
     * Set bog standard float fields quickly in bulk
304
     *
305
     * @param array                $fields
306
     * @param ClassMetadataBuilder $builder
307
     * @param mixed                $default
308
     * In this case the boolean argument is simply data
309
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
310
     */
311 15
    public static function setSimpleFloatFields(
312
        array $fields,
313
        ClassMetadataBuilder $builder,
314
        $default = null
315
    ): void {
316 15
        if (null !== $default && !\is_float($default)) {
317 1
            throw new \InvalidArgumentException(
318 1
                'Invalid default value '.$default
319 1
                .' with type '.self::getType($default)
320
            );
321
        }
322 14
        foreach ($fields as $field) {
323 14
            $fieldBuilder = new FieldBuilder(
324 14
                $builder,
325
                [
326 14
                    'fieldName' => $field,
327 14
                    'type'      => Type::FLOAT,
328 14
                    'default'   => $default,
329
                ]
330
            );
331
            $fieldBuilder
332 14
                ->columnName(self::getColumnNameForField($field))
333 14
                ->nullable(null === $default)
334 14
                ->build();
335
        }
336 14
    }
337
338
    /**
339
     * Set bog standard decimal fields quickly in bulk
340
     *
341
     * @param array                $fields
342
     * @param ClassMetadataBuilder $builder
343
     * @param mixed                $default
344
     * In this case the boolean argument is simply data
345
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
346
     */
347 15
    public static function setSimpleDecimalFields(
348
        array $fields,
349
        ClassMetadataBuilder $builder,
350
        $default = null
351
    ): void {
352 15
        if (null !== $default && !\is_string($default)) {
353
            throw new \InvalidArgumentException(
354
                'Invalid default value '.$default
355
                .' with type '.self::getType($default)
356
            );
357
        }
358 15
        if (null !== $default && !is_numeric($default)) {
359 1
            throw new \InvalidArgumentException(
360 1
                'Invalid default value '.$default
361 1
                .', even though it is a string, it must be numeric '
362
            );
363
        }
364 14
        foreach ($fields as $field) {
365 14
            $fieldBuilder = new FieldBuilder(
366 14
                $builder,
367
                [
368 14
                    'fieldName' => $field,
369 14
                    'type'      => Type::DECIMAL,
370 14
                    'default'   => (string)(float)$default,
371
                ]
372
            );
373
            $fieldBuilder
374 14
                ->columnName(self::getColumnNameForField($field))
375 14
                ->nullable(null === $default)
376 14
                ->precision(Database::MAX_DECIMAL_PRECISION)
377 14
                ->scale(Database::MAX_DECIMAL_SCALE)
378 14
                ->build();
379
        }
380 14
    }
381
382
    /**
383
     * Set bog standard dateTime fields quickly in bulk
384
     *
385
     * @param array                $fields
386
     * @param ClassMetadataBuilder $builder
387
     * @param mixed                $default
388
     * In this case the boolean argument is simply data
389
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
390
     */
391 20
    public static function setSimpleDatetimeFields(
392
        array $fields,
393
        ClassMetadataBuilder $builder,
394
        $default = null
395
    ): void {
396 20
        if (null !== $default
397 20
            && self::DATETIME_DEFAULT_CURRENT_TIME_STAMP !== $default
398
        ) {
399 1
            throw new \InvalidArgumentException(
400 1
                'Invalid default '.$default
401 1
                .' This must be one of:'
402 1
                ."\n - null"
403 1
                ."\n - \EdmondsCommerce\DoctrineStaticMeta\MappingHelper::DATETIME_DEFAULT_CURRENT_TIME_STAMP"
404
            );
405
        }
406 19
        foreach ($fields as $field) {
407 19
            $fieldBuilder = new FieldBuilder(
408 19
                $builder,
409
                [
410 19
                    'fieldName' => $field,
411 19
                    'type'      => Type::DATETIME,
412 19
                    'default'   => $default,
413
                ]
414
            );
415
            $fieldBuilder
416 19
                ->columnName(self::getColumnNameForField($field))
417 19
                ->nullable(null === $default)
418 19
                ->build();
419
        }
420 19
    }
421
422
    /**
423
     * Set bog standard integer fields quickly in bulk
424
     *
425
     * @param array                $fields
426
     * @param ClassMetadataBuilder $builder
427
     * @param mixed                $default
428
     * @param bool                 $isUnique
429
     * In this case the boolean argument is simply data
430
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
431
     */
432 16
    public static function setSimpleIntegerFields(
433
        array $fields,
434
        ClassMetadataBuilder $builder,
435
        $default = null,
436
        bool $isUnique = false
437
    ): void {
438 16
        if (null !== $default && !\is_int($default)) {
439 1
            throw new \InvalidArgumentException(
440 1
                'Invalid default value '.$default
441 1
                .' with type '.self::getType($default)
442
            );
443
        }
444 15
        foreach ($fields as $field) {
445 15
            $fieldBuilder = new FieldBuilder(
446 15
                $builder,
447
                [
448 15
                    'fieldName' => $field,
449 15
                    'type'      => Type::INTEGER,
450 15
                    'default'   => $default,
451
                ]
452
            );
453
            $fieldBuilder
454 15
                ->columnName(self::getColumnNameForField($field))
455 15
                ->nullable(null === $default)
456 15
                ->unique($isUnique)
457 15
                ->build();
458
        }
459 15
    }
460
461
    /**
462
     * Set bog standard boolean fields quickly in bulk
463
     *
464
     * @param array                $fields
465
     * @param ClassMetadataBuilder $builder
466
     * @param mixed                $default
467
     * In this case the boolean argument is simply data
468
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
469
     */
470 15
    public static function setSimpleBooleanFields(
471
        array $fields,
472
        ClassMetadataBuilder $builder,
473
        $default = null
474
    ): void {
475 15
        if (null !== $default && !\is_bool($default)) {
476 1
            throw new \InvalidArgumentException(
477 1
                'Invalid default value '.$default
478 1
                .' with type '.self::getType($default)
479
            );
480
        }
481 14
        foreach ($fields as $field) {
482 14
            $fieldBuilder = new FieldBuilder(
483 14
                $builder,
484
                [
485 14
                    'fieldName' => $field,
486 14
                    'type'      => Type::BOOLEAN,
487 14
                    'default'   => $default,
488
                ]
489
            );
490
            $fieldBuilder
491 14
                ->columnName(self::getColumnNameForField($field))
492 14
                ->nullable(null === $default)
493 14
                ->build();
494
        }
495 14
    }
496
497
    /**
498
     * Create JSON fields
499
     *
500
     * Will use real JSON in the DB engine if it is supported
501
     *
502
     * This should be used for any structured data, arrays, lists, simple objects
503
     *
504
     * @param array                $fields
505
     * @param ClassMetadataBuilder $builder
506
     * @param null                 $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
507
     */
508 15
    public static function setSimpleJsonFields(
509
        array $fields,
510
        ClassMetadataBuilder $builder,
511
        $default = null
512
    ) {
513 15
        if (null !== $default && !\is_string($default)) {
514
            throw new \InvalidArgumentException(
515
                'Invalid default value '.$default
516
                .' with type '.self::getType($default)
517
            );
518
        }
519 15
        foreach ($fields as $field) {
520 15
            $fieldBuilder = new FieldBuilder(
521 15
                $builder,
522
                [
523 15
                    'fieldName' => $field,
524 15
                    'type'      => Type::JSON,
525 15
                    'default'   => $default,
526
                ]
527
            );
528
            $fieldBuilder
529 15
                ->columnName(self::getColumnNameForField($field))
530 15
                ->nullable(null === $default)
531 15
                ->build();
532
        }
533 15
    }
534
535
    /**
536
     * Bulk create multiple fields of different simple types
537
     *
538
     * Always creates nullable fields, if you want to set a default, you must call the type based method
539
     *
540
     * @param array                $fieldToType [
541
     *                                          'fieldName'=>'fieldSimpleType'
542
     *                                          ]
543
     * @param ClassMetadataBuilder $builder
544
     */
545 3
    public static function setSimpleFields(
546
        array $fieldToType,
547
        ClassMetadataBuilder $builder
548
    ): void {
549 3
        foreach ($fieldToType as $field => $type) {
550 3
            $method = "setSimple$type".'fields';
551 3
            static::$method([$field], $builder);
552
        }
553 3
    }
554
}
555