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.
Completed
Push — master ( 0b4676...ecfcbd )
by joseph
17s queued 14s
created

MappingHelper::setSimpleDatetimeFields()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3.0052

Importance

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