TDBMDaoGenerator::generateBean()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 48
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 22
c 3
b 0
f 0
dl 0
loc 48
rs 9.568
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TheCodingMachine\TDBM\Utils;
6
7
use Doctrine\DBAL\Types\Types;
8
use Doctrine\Inflector\Inflector;
9
use Doctrine\DBAL\Schema\Schema;
10
use Doctrine\DBAL\Schema\Table;
11
use Doctrine\DBAL\Types\Type;
12
use Doctrine\Inflector\InflectorFactory;
13
use Psr\Container\ContainerInterface;
14
use TheCodingMachine\TDBM\Schema\ForeignKeys;
15
use TheCodingMachine\TDBM\TDBMService;
16
use Laminas\Code\Generator\AbstractMemberGenerator;
17
use Laminas\Code\Generator\ClassGenerator;
18
use Laminas\Code\Generator\DocBlock\Tag\VarTag;
19
use Laminas\Code\Generator\DocBlockGenerator;
20
use Laminas\Code\Generator\FileGenerator;
21
use Laminas\Code\Generator\MethodGenerator;
22
use Laminas\Code\Generator\ParameterGenerator;
23
use Laminas\Code\Generator\PropertyGenerator;
24
use TheCodingMachine\TDBM\ConfigurationInterface;
25
use TheCodingMachine\TDBM\TDBMException;
26
use TheCodingMachine\TDBM\TDBMSchemaAnalyzer;
27
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
28
use Symfony\Component\Filesystem\Filesystem;
29
30
use function str_replace;
31
use function strpos;
32
use function substr;
33
use function var_export;
34
35
use const PHP_EOL;
36
37
/**
38
 * This class generates automatically DAOs and Beans for TDBM.
39
 */
40
class TDBMDaoGenerator
41
{
42
    /**
43
     * @var TDBMSchemaAnalyzer
44
     */
45
    private $tdbmSchemaAnalyzer;
46
47
    /**
48
     * @var GeneratorListenerInterface
49
     */
50
    private $eventDispatcher;
51
52
    /**
53
     * @var NamingStrategyInterface
54
     */
55
    private $namingStrategy;
56
    /**
57
     * @var ConfigurationInterface
58
     */
59
    private $configuration;
60
    /**
61
     * @var Inflector
62
     */
63
    private static $inflector;
64
65
    /**
66
     * Constructor.
67
     *
68
     * @param ConfigurationInterface $configuration
69
     * @param TDBMSchemaAnalyzer $tdbmSchemaAnalyzer
70
     */
71
    public function __construct(ConfigurationInterface $configuration, TDBMSchemaAnalyzer $tdbmSchemaAnalyzer)
72
    {
73
        $this->configuration = $configuration;
74
        $this->tdbmSchemaAnalyzer = $tdbmSchemaAnalyzer;
75
        $this->namingStrategy = $configuration->getNamingStrategy();
76
        $this->eventDispatcher = $configuration->getGeneratorEventDispatcher();
77
    }
78
79
    /**
80
     * Generates all the daos and beans.
81
     *
82
     * @throws TDBMException
83
     */
84
    public function generateAllDaosAndBeans(bool $fromLock = false): void
85
    {
86
        if (!$fromLock) {
87
            $this->tdbmSchemaAnalyzer->generateLockFile();
0 ignored issues
show
Deprecated Code introduced by
The function TheCodingMachine\TDBM\TD...zer::generateLockFile() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

87
            /** @scrutinizer ignore-deprecated */ $this->tdbmSchemaAnalyzer->generateLockFile();
Loading history...
88
        }
89
        $schema = $this->tdbmSchemaAnalyzer->getSchema();
0 ignored issues
show
Deprecated Code introduced by
The function TheCodingMachine\TDBM\TD...maAnalyzer::getSchema() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

89
        $schema = /** @scrutinizer ignore-deprecated */ $this->tdbmSchemaAnalyzer->getSchema();
Loading history...
90
91
        // TODO: check that no class name ends with "Base". Otherwise, there will be name clash.
92
        $tableList = $schema->getTables();
93
94
        // Remove all beans and daos from junction tables
95
        $junctionTables = $this->configuration->getSchemaAnalyzer()->detectJunctionTables(true);
96
        $junctionTableNames = array_map(function (Table $table) {
97
            return $table->getName();
98
        }, $junctionTables);
99
100
        $tableList = array_filter($tableList, function (Table $table) use ($junctionTableNames) {
101
            return !in_array($table->getName(), $junctionTableNames, true);
102
        });
103
104
        $this->cleanUpGenerated();
105
106
        $beanDescriptors = [];
107
108
        $beanRegistry = new BeanRegistry($this->configuration, $schema, $this->tdbmSchemaAnalyzer, $this->namingStrategy);
109
        foreach ($tableList as $table) {
110
            $beanDescriptors[] = $beanRegistry->addBeanForTable($table);
111
        }
112
        foreach ($beanDescriptors as $beanDescriptor) {
113
            $beanDescriptor->initBeanPropertyDescriptors();
114
        }
115
        foreach ($beanDescriptors as $beanDescriptor) {
116
            $this->generateBean($beanDescriptor);
117
            $this->generateDao($beanDescriptor);
118
            $this->generateResultIterator($beanDescriptor);
119
        }
120
121
        $this->generateFactory($beanDescriptors);
122
123
        // Let's call the list of listeners
124
        $this->eventDispatcher->onGenerate($this->configuration, $beanDescriptors);
125
    }
126
127
    /**
128
     * Removes all files from the Generated folders.
129
     * This is a way to ensure that when a table is deleted, the matching bean/dao are deleted.
130
     * Note: only abstract generated classes are deleted. We do not delete the code that might have been customized
131
     * by the user. The user will need to delete this code him/herself
132
     */
133
    private function cleanUpGenerated(): void
134
    {
135
        $generatedBeanDir = $this->configuration->getPathFinder()->getPath($this->configuration->getBeanNamespace().'\\Generated\\Xxx')->getPath();
136
        $this->deleteAllPhpFiles($generatedBeanDir);
137
138
        $generatedDaoDir = $this->configuration->getPathFinder()->getPath($this->configuration->getDaoNamespace().'\\Generated\\Xxx')->getPath();
139
        $this->deleteAllPhpFiles($generatedDaoDir);
140
141
        $generatedResultIteratorDir = $this->configuration->getPathFinder()->getPath($this->configuration->getResultIteratorNamespace().'\\Generated\\Xxx')->getPath();
142
        $this->deleteAllPhpFiles($generatedResultIteratorDir);
143
    }
144
145
    private function deleteAllPhpFiles(string $directory): void
146
    {
147
        $files = glob($directory.'/*.php', GLOB_NOSORT);
148
        if ($files === false) {
149
            return;
150
        }
151
        $fileSystem = new Filesystem();
152
        $fileSystem->remove($files);
153
    }
154
155
    /**
156
     * Writes the PHP bean file with all getters and setters from the table passed in parameter.
157
     *
158
     * @param BeanDescriptor  $beanDescriptor
159
     *
160
     * @throws TDBMException
161
     */
162
    public function generateBean(BeanDescriptor $beanDescriptor): void
163
    {
164
        $className = $beanDescriptor->getBeanClassName();
165
        $baseClassName = $beanDescriptor->getBaseBeanClassName();
166
        $table = $beanDescriptor->getTable();
167
        $beannamespace = $this->configuration->getBeanNamespace();
168
        $file = $beanDescriptor->generatePhpCode();
169
        if ($file === null) {
170
            return;
171
        }
172
173
        $possibleBaseFileName = $this->configuration->getPathFinder()->getPath($beannamespace.'\\Generated\\'.$baseClassName)->getPathname();
174
175
        $fileContent = $file->generate();
176
177
        // Hard code PSR-2 fix
178
        $fileContent = $this->psr2Fix($fileContent);
179
        // Add the declare strict-types directive
180
        $commentEnd = strpos($fileContent, ' */') + 3;
181
        $fileContent = substr($fileContent, 0, $commentEnd) . "\n\ndeclare(strict_types=1);" . substr($fileContent, $commentEnd + 1);
182
183
        $this->dumpFile($possibleBaseFileName, $fileContent);
184
185
        $possibleFileName = $this->configuration->getPathFinder()->getPath($beannamespace.'\\'.$className)->getPathname();
186
187
        if (!file_exists($possibleFileName)) {
188
            $tableName = $table->getName();
189
            $str = "<?php
190
/*
191
 * This file has been automatically generated by TDBM.
192
 * You can edit this file as it will not be overwritten.
193
 */
194
195
declare(strict_types=1);
196
197
namespace {$beannamespace};
198
199
use {$beannamespace}\\Generated\\{$baseClassName};
200
201
/**
202
 * The $className class maps the '$tableName' table in database.
203
 */
204
class $className extends $baseClassName
205
{
206
}
207
";
208
209
            $this->dumpFile($possibleFileName, $str);
210
        }
211
    }
212
213
    /**
214
     * Writes the PHP bean DAO with simple functions to create/get/save objects.
215
     *
216
     * @param BeanDescriptor  $beanDescriptor
217
     *
218
     * @throws TDBMException
219
     */
220
    private function generateDao(BeanDescriptor $beanDescriptor): void
221
    {
222
        $className = $beanDescriptor->getDaoClassName();
223
        $baseClassName = $beanDescriptor->getBaseDaoClassName();
224
        $beanClassName = $beanDescriptor->getBeanClassName();
225
        $table = $beanDescriptor->getTable();
226
        $file = $beanDescriptor->generateDaoPhpCode();
227
        if ($file === null) {
228
            return;
229
        }
230
        $daonamespace = $this->configuration->getDaoNamespace();
231
        $tableName = $table->getName();
232
233
        $beanClassWithoutNameSpace = $beanClassName;
234
235
        $possibleBaseFileName = $this->configuration->getPathFinder()->getPath($daonamespace.'\\Generated\\'.$baseClassName)->getPathname();
236
237
        $fileContent = $file->generate();
238
239
        // Hard code PSR-2 fix
240
        $fileContent = $this->psr2Fix($fileContent);
241
        // Add the declare strict-types directive
242
        $commentEnd = strpos($fileContent, ' */') + 3;
243
        $fileContent = substr($fileContent, 0, $commentEnd) . "\n\ndeclare(strict_types=1);" . substr($fileContent, $commentEnd + 1);
244
245
        $this->dumpFile($possibleBaseFileName, $fileContent);
246
247
248
        $possibleFileName = $this->configuration->getPathFinder()->getPath($daonamespace.'\\'.$className)->getPathname();
249
250
        // Now, let's generate the "editable" class
251
        if (!file_exists($possibleFileName)) {
252
            $str = "<?php
253
/*
254
 * This file has been automatically generated by TDBM.
255
 * You can edit this file as it will not be overwritten.
256
 */
257
258
declare(strict_types=1);
259
260
namespace {$daonamespace};
261
262
use {$daonamespace}\\Generated\\{$baseClassName};
263
264
/**
265
 * The $className class will maintain the persistence of $beanClassWithoutNameSpace class into the $tableName table.
266
 */
267
class $className extends $baseClassName
268
{
269
}
270
";
271
            $this->dumpFile($possibleFileName, $str);
272
        }
273
    }
274
275
    /**
276
     * Fixes PSR-2 for files generated by Zend-Code
277
     */
278
    private function psr2Fix(string $content): string
279
    {
280
        // Removes the extra blank line at the end (before: `\n\n`, after: `\n`)
281
        return rtrim($content, PHP_EOL) . PHP_EOL;
282
    }
283
284
    /**
285
     * Writes the PHP ResultIterator file with typed accessors.
286
     */
287
    private function generateResultIterator(BeanDescriptor $beanDescriptor): void
288
    {
289
        $resultIteratorClassName = $beanDescriptor->getResultIteratorClassName();
290
        $resultIteratorBaseClassName = $beanDescriptor->getBaseResultIteratorClassName();
291
        $resultIteratorNamespace = $this->configuration->getResultIteratorNamespace();
292
        $resultIteratorBaseNamespace = $resultIteratorNamespace . '\\Generated';
293
        $beanClassWithoutNameSpace = $beanDescriptor->getBeanClassName();
294
        $file = $beanDescriptor->generateResultIteratorPhpCode();
295
        if ($file === null) {
296
            return;
297
        }
298
299
        $fileContent = $this->psr2Fix($file->generate());
300
        $commentEnd = strpos($fileContent, ' */') + 3;
301
        $fileContent = substr($fileContent, 0, $commentEnd) . "\n\ndeclare(strict_types=1);" . substr($fileContent, $commentEnd + 1);
302
303
        $baseResultIteratorFilePath = $this->configuration->getPathFinder()->getPath($resultIteratorBaseNamespace.'\\'.$resultIteratorBaseClassName)->getPathname();
304
        $this->dumpFile($baseResultIteratorFilePath, $fileContent);
305
306
        $resultIteratorFilePath = $this->configuration->getPathFinder()->getPath($resultIteratorNamespace.'\\'.$resultIteratorClassName)->getPathname();
307
        // Now, let's generate the "editable" class
308
        if (!file_exists($resultIteratorFilePath)) {
309
            $str = "<?php
310
/*
311
 * This file has been automatically generated by TDBM.
312
 * You can edit this file as it will not be overwritten.
313
 */
314
315
declare(strict_types=1);
316
317
namespace {$resultIteratorNamespace};
318
319
use {$resultIteratorBaseNamespace}\\{$resultIteratorBaseClassName};
320
321
/**
322
 * The $resultIteratorClassName class will iterate over results of $beanClassWithoutNameSpace class.
323
 */
324
class $resultIteratorClassName extends $resultIteratorBaseClassName
325
{
326
}
327
";
328
            $this->dumpFile($resultIteratorFilePath, $str);
329
        }
330
    }
331
332
    /**
333
     * Generates the factory bean.
334
     *
335
     * @param BeanDescriptor[] $beanDescriptors
336
     * @throws TDBMException
337
     */
338
    private function generateFactory(array $beanDescriptors): void
339
    {
340
        $daoNamespace = $this->configuration->getDaoNamespace();
341
        $daoFactoryClassName = $this->namingStrategy->getDaoFactoryClassName();
342
343
        $file = new FileGenerator();
344
        $file->setDocBlock(
345
            new DocBlockGenerator(
346
                <<<DOC
347
This file has been automatically generated by TDBM.
348
DO NOT edit this file, as it might be overwritten.
349
DOC
350
            )
351
        );
352
        $class = new ClassGenerator();
353
        $file->setClass($class);
354
        $class->setName($daoFactoryClassName);
355
        $file->setNamespace($daoNamespace.'\\Generated');
356
357
        $class->setDocBlock(new DocBlockGenerator("The $daoFactoryClassName provides an easy access to all DAOs generated by TDBM."));
358
359
        $containerProperty = new PropertyGenerator('container');
360
        $containerProperty->setVisibility(AbstractMemberGenerator::VISIBILITY_PRIVATE);
361
        $containerProperty->setDocBlock(new DocBlockGenerator(null, null, [new VarTag(null, ['\\'.ContainerInterface::class])]));
362
        $class->addPropertyFromGenerator($containerProperty);
363
364
        $constructorMethod = new MethodGenerator(
365
            '__construct',
366
            [ new ParameterGenerator('container', ContainerInterface::class) ],
367
            MethodGenerator::FLAG_PUBLIC,
368
            '$this->container = $container;'
369
        );
370
        $constructorMethod = $this->configuration->getCodeGeneratorListener()->onDaoFactoryConstructorGenerated($constructorMethod, $beanDescriptors, $this->configuration, $class);
371
        if ($constructorMethod !== null) {
372
            $class->addMethodFromGenerator($constructorMethod);
373
        }
374
375
        // For each table, let's write a property.
376
        foreach ($beanDescriptors as $beanDescriptor) {
377
            $daoClassName = $beanDescriptor->getDaoClassName();
378
            $daoInstanceName = self::toVariableName($daoClassName);
379
380
            $daoInstanceProperty = new PropertyGenerator($daoInstanceName);
381
            $daoInstanceProperty->setVisibility(AbstractMemberGenerator::VISIBILITY_PRIVATE);
382
            $daoInstanceProperty->setDocBlock(new DocBlockGenerator(null, null, [new VarTag(null, ['\\' . $daoNamespace . '\\' . $daoClassName, 'null'])]));
383
            $class->addPropertyFromGenerator($daoInstanceProperty);
384
385
            $fullClassNameVarExport = var_export($daoNamespace.'\\'.$daoClassName, true);
386
            $getterBody = <<<BODY
387
if (!\$this->$daoInstanceName) {
388
    \$this->$daoInstanceName = \$this->container->get($fullClassNameVarExport);
389
}
390
391
return \$this->$daoInstanceName;
392
BODY;
393
394
            $getterMethod = new MethodGenerator(
395
                'get' . $daoClassName,
396
                [],
397
                MethodGenerator::FLAG_PUBLIC,
398
                $getterBody
399
            );
400
            $getterMethod->setReturnType($daoNamespace.'\\'.$daoClassName);
401
            $getterMethod = $this->configuration->getCodeGeneratorListener()->onDaoFactoryGetterGenerated($getterMethod, $beanDescriptor, $this->configuration, $class);
402
            if ($getterMethod !== null) {
403
                $class->addMethodFromGenerator($getterMethod);
404
            }
405
406
            $setterMethod = new MethodGenerator(
407
                'set' . $daoClassName,
408
                [new ParameterGenerator($daoInstanceName, '\\' . $daoNamespace . '\\' . $daoClassName)],
409
                MethodGenerator::FLAG_PUBLIC,
410
                '$this->' . $daoInstanceName . ' = $' . $daoInstanceName . ';'
411
            );
412
            $setterMethod->setReturnType('void');
413
            $setterMethod = $this->configuration->getCodeGeneratorListener()->onDaoFactorySetterGenerated($setterMethod, $beanDescriptor, $this->configuration, $class);
414
            if ($setterMethod !== null) {
415
                $class->addMethodFromGenerator($setterMethod);
416
            }
417
        }
418
419
        $file = $this->configuration->getCodeGeneratorListener()->onDaoFactoryGenerated($file, $beanDescriptors, $this->configuration);
420
421
        if ($file !== null) {
422
            $possibleFileName = $this->configuration->getPathFinder()->getPath($daoNamespace.'\\Generated\\'.$daoFactoryClassName)->getPathname();
423
424
            $fileContent = $file->generate();
425
426
            // Hard code PSR-2 fix
427
            $fileContent = $this->psr2Fix($fileContent);
428
            // Add the declare strict-types directive
429
            $commentEnd = strpos($fileContent, ' */') + 3;
430
            $fileContent = substr($fileContent, 0, $commentEnd) . "\n\ndeclare(strict_types=1);" . substr($fileContent, $commentEnd + 1);
431
432
            $this->dumpFile($possibleFileName, $fileContent);
433
        }
434
    }
435
436
    /**
437
     * Transforms a string to camelCase (except the first letter will be uppercase too).
438
     * Underscores and spaces are removed and the first letter after the underscore is uppercased.
439
     * Quoting is removed if present.
440
     *
441
     * @param string $str
442
     *
443
     * @return string
444
     */
445
    public static function toCamelCase(string $str): string
446
    {
447
        $str = str_replace(array('`', '"', '[', ']'), '', $str);
448
449
        $str = strtoupper(substr($str, 0, 1)).substr($str, 1);
450
        while (true) {
451
            $pos = strpos($str, '_');
452
            if ($pos === false) {
453
                $pos = strpos($str, ' ');
454
                if ($pos === false) {
455
                    break;
456
                }
457
            }
458
459
            $before = substr($str, 0, $pos);
460
            $after = substr($str, $pos + 1);
461
            $str = $before.strtoupper(substr($after, 0, 1)).substr($after, 1);
462
        }
463
464
        return $str;
465
    }
466
467
    /**
468
     * Tries to put string to the singular form (if it is plural).
469
     * We assume the table names are in english.
470
     *
471
     * @param string $str
472
     *
473
     * @return string
474
     */
475
    public static function toSingular(string $str): string
476
    {
477
        if (self::$inflector === null) {
478
            self::$inflector = InflectorFactory::create()->build();
479
        }
480
481
        return self::$inflector->singularize($str);
482
    }
483
484
    /**
485
     * Tries to put string to the plural form (if it is singular).
486
     * We assume the string is in english.
487
     */
488
    public static function toPlural(string $str): string
489
    {
490
        if (self::$inflector === null) {
491
            self::$inflector = InflectorFactory::create()->build();
492
        }
493
494
        return self::$inflector->pluralize($str);
495
    }
496
497
    /**
498
     * Put the first letter of the string in lower case.
499
     * Very useful to transform a class name into a variable name.
500
     *
501
     * @param string $str
502
     *
503
     * @return string
504
     */
505
    public static function toVariableName(string $str): string
506
    {
507
        return strtolower(substr($str, 0, 1)).substr($str, 1);
508
    }
509
510
    /**
511
     * Ensures the file passed in parameter can be written in its directory.
512
     *
513
     * @param string $fileName
514
     *
515
     * @throws TDBMException
516
     */
517
    private function ensureDirectoryExist(string $fileName): void
518
    {
519
        $dirName = dirname($fileName);
520
        if (!file_exists($dirName)) {
521
            $old = umask(0);
522
            $result = mkdir($dirName, 0775, true);
523
            umask($old);
524
            if ($result === false) {
525
                throw new TDBMException("Unable to create directory: '".$dirName."'.");
526
            }
527
        }
528
    }
529
530
    private function dumpFile(string $fileName, string $content): void
531
    {
532
        $this->ensureDirectoryExist($fileName);
533
        $fileSystem = new Filesystem();
534
        $fileSystem->dumpFile($fileName, $content);
535
        @chmod($fileName, 0664);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

535
        /** @scrutinizer ignore-unhandled */ @chmod($fileName, 0664);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
536
    }
537
538
    /**
539
     * Transforms a DBAL type into a PHP type (for PHPDoc purpose).
540
     *
541
     * @param Type $type The DBAL type
542
     *
543
     * @return string The PHP type
544
     */
545
    public static function dbalTypeToPhpType(Type $type): string
546
    {
547
        $map = [
548
            Types::ARRAY => 'array',
0 ignored issues
show
Deprecated Code introduced by
The constant Doctrine\DBAL\Types\Types::ARRAY has been deprecated: Use {@link Types::JSON} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

548
            /** @scrutinizer ignore-deprecated */ Types::ARRAY => 'array',

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
549
            Types::SIMPLE_ARRAY => 'array',
550
            Types::JSON => 'array',
551
            Types::BIGINT => 'string',
552
            Types::BOOLEAN => 'bool',
553
            Types::DATETIME_IMMUTABLE => '\DateTimeImmutable',
554
            Types::DATETIMETZ_IMMUTABLE => '\DateTimeImmutable',
555
            Types::DATE_IMMUTABLE => '\DateTimeImmutable',
556
            Types::TIME_IMMUTABLE => '\DateTimeImmutable',
557
            Types::DECIMAL => 'string',
558
            Types::INTEGER => 'int',
559
            Types::OBJECT => 'string',
0 ignored issues
show
Deprecated Code introduced by
The constant Doctrine\DBAL\Types\Types::OBJECT has been deprecated: Use {@link Types::JSON} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

559
            /** @scrutinizer ignore-deprecated */ Types::OBJECT => 'string',

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
560
            Types::SMALLINT => 'int',
561
            Types::STRING => 'string',
562
            Types::TEXT => 'string',
563
            Types::BINARY => 'resource',
564
            Types::BLOB => 'resource',
565
            Types::FLOAT => 'float',
566
            Types::GUID => 'string',
567
        ];
568
569
        return $map[$type->getName()] ?? $type->getName();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Types\Type::getName() has been deprecated: this method will be removed in Doctrine DBAL 4.0, use {@see TypeRegistry::lookupName()} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

569
        return $map[/** @scrutinizer ignore-deprecated */ $type->getName()] ?? $type->getName();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
570
    }
571
572
    /**
573
     * @param Table $table
574
     * @return string[]
575
     * @throws TDBMException
576
     */
577
    public static function getPrimaryKeyColumnsOrFail(Table $table): array
578
    {
579
        if ($table->getPrimaryKey() === null) {
580
            // Security check: a table MUST have a primary key
581
            throw new TDBMException(sprintf('Table "%s" does not have any primary key', $table->getName()));
582
        }
583
        return $table->getPrimaryKey()->getUnquotedColumns();
584
    }
585
}
586