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 (#63)
by joseph
03:18
created

MappingHelper::getShortNameForFqn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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