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 ( a48bd8...83d092 )
by joseph
16:18 queued 18s
created

src/MappingHelper.php (1 issue)

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