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
Pull Request — master (#58)
by joseph
28:39
created

MappingHelper::getTableNameForEntityFqn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.0054

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
ccs 8
cts 9
cp 0.8889
cc 2
eloc 8
nc 2
nop 1
crap 2.0054
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 25
                ->length(Database::MAX_VARCHAR_LENGTH)
259 25
                ->build();
260
        }
261 25
    }
262
263
    /**
264
     * Set bog standard text fields quickly in bulk
265
     *
266
     * @param array                $fields
267
     * @param ClassMetadataBuilder $builder
268
     * @param mixed                $default
269
     * In this case the boolean argument is simply data
270
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
271
     */
272 15
    public static function setSimpleTextFields(
273
        array $fields,
274
        ClassMetadataBuilder $builder,
275
        $default = null
276
    ): void {
277 15
        if (null !== $default && !\is_string($default)) {
278 1
            throw new \InvalidArgumentException(
279 1
                'Invalid default value '.$default
280 1
                .' with type '.self::getType($default)
281
            );
282
        }
283 14
        foreach ($fields as $field) {
284 14
            $fieldBuilder = new FieldBuilder(
285 14
                $builder,
286
                [
287 14
                    'fieldName' => $field,
288 14
                    'type'      => Type::TEXT,
289 14
                    'default'   => $default,
290
                ]
291
            );
292 14
            $fieldBuilder->columnName(self::getColumnNameForField($field))
293 14
                         ->nullable(null === $default)
294 14
                         ->build();
295
        }
296 14
    }
297
298
299
    /**
300
     * Set bog standard float fields quickly in bulk
301
     *
302
     * @param array                $fields
303
     * @param ClassMetadataBuilder $builder
304
     * @param mixed                $default
305
     * In this case the boolean argument is simply data
306
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
307
     */
308 15
    public static function setSimpleFloatFields(
309
        array $fields,
310
        ClassMetadataBuilder $builder,
311
        $default = null
312
    ): void {
313 15
        if (null !== $default && !\is_float($default)) {
314 1
            throw new \InvalidArgumentException(
315 1
                'Invalid default value '.$default
316 1
                .' with type '.self::getType($default)
317
            );
318
        }
319 14
        foreach ($fields as $field) {
320 14
            $fieldBuilder = new FieldBuilder(
321 14
                $builder,
322
                [
323 14
                    'fieldName' => $field,
324 14
                    'type'      => Type::FLOAT,
325 14
                    'default'   => $default,
326
                ]
327
            );
328
            $fieldBuilder
329 14
                ->columnName(self::getColumnNameForField($field))
330 14
                ->nullable(null === $default)
331 14
                ->build();
332
        }
333 14
    }
334
335
    /**
336
     * Set bog standard decimal fields quickly in bulk
337
     *
338
     * @param array                $fields
339
     * @param ClassMetadataBuilder $builder
340
     * @param mixed                $default
341
     * In this case the boolean argument is simply data
342
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
343
     */
344 15
    public static function setSimpleDecimalFields(
345
        array $fields,
346
        ClassMetadataBuilder $builder,
347
        $default = null
348
    ): void {
349 15
        if (null !== $default && !\is_string($default)) {
350
            throw new \InvalidArgumentException(
351
                'Invalid default value '.$default
352
                .' with type '.self::getType($default)
353
            );
354
        }
355 15
        if (null !== $default && !is_numeric($default)) {
356 1
            throw new \InvalidArgumentException(
357 1
                'Invalid default value '.$default
358 1
                .', even though it is a string, it must be numeric '
359
            );
360
        }
361 14
        foreach ($fields as $field) {
362 14
            $fieldBuilder = new FieldBuilder(
363 14
                $builder,
364
                [
365 14
                    'fieldName' => $field,
366 14
                    'type'      => Type::DECIMAL,
367 14
                    'default'   => (string)(float)$default,
368
                ]
369
            );
370
            $fieldBuilder
371 14
                ->columnName(self::getColumnNameForField($field))
372 14
                ->nullable(null === $default)
373 14
                ->precision(Database::MAX_DECIMAL_PRECISION)
374 14
                ->scale(Database::MAX_DECIMAL_SCALE)
375 14
                ->build();
376
        }
377 14
    }
378
379
    /**
380
     * Set bog standard dateTime fields quickly in bulk
381
     *
382
     * @param array                $fields
383
     * @param ClassMetadataBuilder $builder
384
     * @param mixed                $default
385
     * In this case the boolean argument is simply data
386
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
387
     */
388 20
    public static function setSimpleDatetimeFields(
389
        array $fields,
390
        ClassMetadataBuilder $builder,
391
        $default = null
392
    ): void {
393 20
        if (null !== $default
394 20
            && self::DATETIME_DEFAULT_CURRENT_TIME_STAMP !== $default
395
        ) {
396 1
            throw new \InvalidArgumentException(
397 1
                'Invalid default '.$default
398 1
                .' This must be one of:'
399 1
                ."\n - null"
400 1
                ."\n - \EdmondsCommerce\DoctrineStaticMeta\MappingHelper::DATETIME_DEFAULT_CURRENT_TIME_STAMP"
401
            );
402
        }
403 19
        foreach ($fields as $field) {
404 19
            $fieldBuilder = new FieldBuilder(
405 19
                $builder,
406
                [
407 19
                    'fieldName' => $field,
408 19
                    'type'      => Type::DATETIME,
409 19
                    'default'   => $default,
410
                ]
411
            );
412
            $fieldBuilder
413 19
                ->columnName(self::getColumnNameForField($field))
414 19
                ->nullable(null === $default)
415 19
                ->build();
416
        }
417 19
    }
418
419
    /**
420
     * Set bog standard integer fields quickly in bulk
421
     *
422
     * @param array                $fields
423
     * @param ClassMetadataBuilder $builder
424
     * @param mixed                $default
425
     * @param bool                 $isUnique
426
     * In this case the boolean argument is simply data
427
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
428
     */
429 16
    public static function setSimpleIntegerFields(
430
        array $fields,
431
        ClassMetadataBuilder $builder,
432
        $default = null,
433
        bool $isUnique = false
434
    ): void {
435 16
        if (null !== $default && !\is_int($default)) {
436 1
            throw new \InvalidArgumentException(
437 1
                'Invalid default value '.$default
438 1
                .' with type '.self::getType($default)
439
            );
440
        }
441 15
        foreach ($fields as $field) {
442 15
            $fieldBuilder = new FieldBuilder(
443 15
                $builder,
444
                [
445 15
                    'fieldName' => $field,
446 15
                    'type'      => Type::INTEGER,
447 15
                    'default'   => $default,
448
                ]
449
            );
450
            $fieldBuilder
451 15
                ->columnName(self::getColumnNameForField($field))
452 15
                ->nullable(null === $default)
453 15
                ->unique($isUnique)
454 15
                ->build();
455
        }
456 15
    }
457
458
    /**
459
     * Set bog standard boolean fields quickly in bulk
460
     *
461
     * @param array                $fields
462
     * @param ClassMetadataBuilder $builder
463
     * @param mixed                $default
464
     * In this case the boolean argument is simply data
465
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
466
     */
467 15
    public static function setSimpleBooleanFields(
468
        array $fields,
469
        ClassMetadataBuilder $builder,
470
        $default = null
471
    ): void {
472 15
        if (null !== $default && !\is_bool($default)) {
473 1
            throw new \InvalidArgumentException(
474 1
                'Invalid default value '.$default
475 1
                .' with type '.self::getType($default)
476
            );
477
        }
478 14
        foreach ($fields as $field) {
479 14
            $fieldBuilder = new FieldBuilder(
480 14
                $builder,
481
                [
482 14
                    'fieldName' => $field,
483 14
                    'type'      => Type::BOOLEAN,
484 14
                    'default'   => $default,
485
                ]
486
            );
487
            $fieldBuilder
488 14
                ->columnName(self::getColumnNameForField($field))
489 14
                ->nullable(null === $default)
490 14
                ->build();
491
        }
492 14
    }
493
494
    /**
495
     * Create JSON fields
496
     *
497
     * Will use real JSON in the DB engine if it is supported
498
     *
499
     * This should be used for any structured data, arrays, lists, simple objects
500
     *
501
     * @param array                $fields
502
     * @param ClassMetadataBuilder $builder
503
     * @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...
504
     */
505 15
    public static function setSimpleJsonFields(
506
        array $fields,
507
        ClassMetadataBuilder $builder,
508
        $default = null
509
    ) {
510 15
        if (null !== $default && !\is_string($default)) {
511
            throw new \InvalidArgumentException(
512
                'Invalid default value '.$default
513
                .' with type '.self::getType($default)
514
            );
515
        }
516 15
        foreach ($fields as $field) {
517 15
            $fieldBuilder = new FieldBuilder(
518 15
                $builder,
519
                [
520 15
                    'fieldName' => $field,
521 15
                    'type'      => Type::JSON,
522 15
                    'default'   => $default,
523
                ]
524
            );
525
            $fieldBuilder
526 15
                ->columnName(self::getColumnNameForField($field))
527 15
                ->nullable(null === $default)
528 15
                ->build();
529
        }
530 15
    }
531
532
    /**
533
     * Bulk create multiple fields of different simple types
534
     *
535
     * Always creates nullable fields, if you want to set a default, you must call the type based method
536
     *
537
     * @param array                $fieldToType [
538
     *                                          'fieldName'=>'fieldSimpleType'
539
     *                                          ]
540
     * @param ClassMetadataBuilder $builder
541
     */
542 3
    public static function setSimpleFields(
543
        array $fieldToType,
544
        ClassMetadataBuilder $builder
545
    ): void {
546 3
        foreach ($fieldToType as $field => $type) {
547 3
            $method = "setSimple$type".'fields';
548 3
            static::$method([$field], $builder);
549
        }
550 3
    }
551
}
552