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

MappingHelper::setSimpleDatetimeFields()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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