Passed
Pull Request — 4.3 (#142)
by Jean-Baptiste
04:20
created

BeanDescriptor::getDaoClassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Mouf\Database\TDBM\Utils;
4
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Schema\Index;
7
use Doctrine\DBAL\Schema\Schema;
8
use Doctrine\DBAL\Schema\Table;
9
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
10
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
11
use Mouf\Database\TDBM\TDBMException;
12
use Mouf\Database\TDBM\TDBMSchemaAnalyzer;
13
14
/**
15
 * This class represents a bean.
16
 */
17
class BeanDescriptor implements BeanDescriptorInterface
18
{
19
    /**
20
     * @var Table
21
     */
22
    private $table;
23
24
    /**
25
     * @var SchemaAnalyzer
26
     */
27
    private $schemaAnalyzer;
28
29
    /**
30
     * @var Schema
31
     */
32
    private $schema;
33
34
    /**
35
     * @var AbstractBeanPropertyDescriptor[]
36
     */
37
    private $beanPropertyDescriptors = [];
38
39
    /**
40
     * @var TDBMSchemaAnalyzer
41
     */
42
    private $tdbmSchemaAnalyzer;
43
44
    /**
45
     * @var NamingStrategyInterface
46
     */
47
    private $namingStrategy;
48
49
    /**
50
     * @param Table $table
51
     * @param SchemaAnalyzer $schemaAnalyzer
52
     * @param Schema $schema
53
     * @param TDBMSchemaAnalyzer $tdbmSchemaAnalyzer
54
     * @param NamingStrategyInterface $namingStrategy
55
     */
56
    public function __construct(Table $table, SchemaAnalyzer $schemaAnalyzer, Schema $schema, TDBMSchemaAnalyzer $tdbmSchemaAnalyzer, NamingStrategyInterface $namingStrategy)
57
    {
58
        $this->table = $table;
59
        $this->schemaAnalyzer = $schemaAnalyzer;
60
        $this->schema = $schema;
61
        $this->tdbmSchemaAnalyzer = $tdbmSchemaAnalyzer;
62
        $this->namingStrategy = $namingStrategy;
63
        $this->initBeanPropertyDescriptors();
64
    }
65
66
    private function initBeanPropertyDescriptors()
67
    {
68
        $this->beanPropertyDescriptors = $this->getProperties($this->table);
69
    }
70
71
    /**
72
     * Returns the foreign-key the column is part of, if any. null otherwise.
73
     *
74
     * @param Table  $table
75
     * @param Column $column
76
     *
77
     * @return ForeignKeyConstraint|null
78
     */
79
    private function isPartOfForeignKey(Table $table, Column $column)
80
    {
81
        $localColumnName = $column->getName();
82
        foreach ($table->getForeignKeys() as $foreignKey) {
83
            foreach ($foreignKey->getColumns() as $columnName) {
84
                if ($columnName === $localColumnName) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $columnName (integer) and $localColumnName (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
85
                    return $foreignKey;
86
                }
87
            }
88
        }
89
90
        return;
91
    }
92
93
    /**
94
     * @return AbstractBeanPropertyDescriptor[]
95
     */
96
    public function getBeanPropertyDescriptors()
97
    {
98
        return $this->beanPropertyDescriptors;
99
    }
100
101
    /**
102
     * Returns the list of columns that are not nullable and not autogenerated for a given table and its parent.
103
     *
104
     * @return AbstractBeanPropertyDescriptor[]
105
     */
106
    public function getConstructorProperties()
107
    {
108
        $constructorProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
109
            return $property->isCompulsory();
110
        });
111
112
        return $constructorProperties;
113
    }
114
115
    /**
116
     * Returns the list of columns that have default values for a given table.
117
     *
118
     * @return AbstractBeanPropertyDescriptor[]
119
     */
120
    public function getPropertiesWithDefault()
121
    {
122
        $properties = $this->getPropertiesForTable($this->table);
123
        $defaultProperties = array_filter($properties, function (AbstractBeanPropertyDescriptor $property) {
124
            return $property->hasDefault();
125
        });
126
127
        return $defaultProperties;
128
    }
129
130
    /**
131
     * Returns the list of properties exposed as getters and setters in this class.
132
     *
133
     * @return AbstractBeanPropertyDescriptor[]
134
     */
135
    public function getExposedProperties(): array
136
    {
137
        $exposedProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
138
            return $property->getTable()->getName() == $this->table->getName();
139
        });
140
141
        return $exposedProperties;
142
    }
143
144
    /**
145
     * Returns the list of properties for this table (including parent tables).
146
     *
147
     * @param Table $table
148
     *
149
     * @return AbstractBeanPropertyDescriptor[]
150
     */
151
    private function getProperties(Table $table)
152
    {
153
        $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
154
        if ($parentRelationship) {
155
            $parentTable = $this->schema->getTable($parentRelationship->getForeignTableName());
156
            $properties = $this->getProperties($parentTable);
157
            // we merge properties by overriding property names.
158
            $localProperties = $this->getPropertiesForTable($table);
159
            foreach ($localProperties as $name => $property) {
160
                // We do not override properties if this is a primary key!
161
                if ($property->isPrimaryKey()) {
162
                    continue;
163
                }
164
                $properties[$name] = $property;
165
            }
166
        } else {
167
            $properties = $this->getPropertiesForTable($table);
168
        }
169
170
        return $properties;
171
    }
172
173
    /**
174
     * Returns the list of properties for this table (ignoring parent tables).
175
     *
176
     * @param Table $table
177
     *
178
     * @return AbstractBeanPropertyDescriptor[]
179
     */
180
    private function getPropertiesForTable(Table $table)
181
    {
182
        $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
183
        if ($parentRelationship) {
184
            $ignoreColumns = $parentRelationship->getLocalColumns();
185
        } else {
186
            $ignoreColumns = [];
187
        }
188
189
        $beanPropertyDescriptors = [];
190
191
        foreach ($table->getColumns() as $column) {
192
            if (array_search($column->getName(), $ignoreColumns) !== false) {
193
                continue;
194
            }
195
196
            $fk = $this->isPartOfForeignKey($table, $column);
197
            if ($fk !== null) {
198
                // Check that previously added descriptors are not added on same FK (can happen with multi key FK).
199
                foreach ($beanPropertyDescriptors as $beanDescriptor) {
200
                    if ($beanDescriptor instanceof ObjectBeanPropertyDescriptor && $beanDescriptor->getForeignKey() === $fk) {
201
                        continue 2;
202
                    }
203
                }
204
                // Check that this property is not an inheritance relationship
205
                $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
206
                if ($parentRelationship === $fk) {
207
                    continue;
208
                }
209
210
                $beanPropertyDescriptors[] = new ObjectBeanPropertyDescriptor($table, $fk, $this->schemaAnalyzer, $this->namingStrategy);
211
            } else {
212
                $beanPropertyDescriptors[] = new ScalarBeanPropertyDescriptor($table, $column, $this->namingStrategy);
213
            }
214
        }
215
216
        // Now, let's get the name of all properties and let's check there is no duplicate.
217
        /** @var $names AbstractBeanPropertyDescriptor[] */
218
        $names = [];
219
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
220
            $name = $beanDescriptor->getUpperCamelCaseName();
221
            if (isset($names[$name])) {
222
                $names[$name]->useAlternativeName();
223
                $beanDescriptor->useAlternativeName();
224
            } else {
225
                $names[$name] = $beanDescriptor;
226
            }
227
        }
228
229
        // Final check (throw exceptions if problem arises)
230
        $names = [];
231
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
232
            $name = $beanDescriptor->getUpperCamelCaseName();
233
            if (isset($names[$name])) {
234
                throw new TDBMException('Unsolvable name conflict while generating method name');
235
            } else {
236
                $names[$name] = $beanDescriptor;
237
            }
238
        }
239
240
        // Last step, let's rebuild the list with a map:
241
        $beanPropertyDescriptorsMap = [];
242
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
243
            $beanPropertyDescriptorsMap[$beanDescriptor->getLowerCamelCaseName()] = $beanDescriptor;
244
        }
245
246
        return $beanPropertyDescriptorsMap;
247
    }
248
249
    private function generateBeanConstructor() : string
250
    {
251
        $constructorProperties = $this->getConstructorProperties();
252
253
        $constructorCode = '    /**
254
     * The constructor takes all compulsory arguments.
255
     *
256
%s
257
     */
258
    public function __construct(%s)
259
    {
260
%s%s    }
261
    ';
262
263
        $paramAnnotations = [];
264
        $arguments = [];
265
        $assigns = [];
266
        $parentConstructorArguments = [];
267
268
        foreach ($constructorProperties as $property) {
269
            $className = $property->getClassName();
270
            if ($className) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $className of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
271
                $arguments[] = $className.' '.$property->getVariableName();
272
            } else {
273
                $arguments[] = $property->getVariableName();
274
            }
275
            $paramAnnotations[] = $property->getParamAnnotation();
276
            if ($property->getTable()->getName() === $this->table->getName()) {
277
                $assigns[] = $property->getConstructorAssignCode()."\n";
278
            } else {
279
                $parentConstructorArguments[] = $property->getVariableName();
280
            }
281
        }
282
283
        $parentConstructorCode = sprintf("        parent::__construct(%s);\n", implode(', ', $parentConstructorArguments));
284
285
        foreach ($this->getPropertiesWithDefault() as $property) {
286
            $assigns[] = $property->assignToDefaultCode()."\n";
287
        }
288
289
        return sprintf($constructorCode, implode("\n", $paramAnnotations), implode(', ', $arguments), $parentConstructorCode, implode('', $assigns));
290
    }
291
292
    public function getDirectForeignKeysDescriptors(): array
293
    {
294
        $fks = $this->tdbmSchemaAnalyzer->getIncomingForeignKeys($this->table->getName());
295
296
        $descriptors = [];
297
298
        foreach ($fks as $fk) {
299
            $descriptors[] = new DirectForeignKeyMethodDescriptor($fk, $this->table, $this->namingStrategy);
300
        }
301
302
        return $descriptors;
303
    }
304
305
    private function getPivotTableDescriptors(): array
306
    {
307
        $descs = [];
308
        foreach ($this->schemaAnalyzer->detectJunctionTables(true) as $table) {
309
            // There are exactly 2 FKs since this is a pivot table.
310
            $fks = array_values($table->getForeignKeys());
311
312
            if ($fks[0]->getForeignTableName() === $this->table->getName()) {
313
                list($localFk, $remoteFk) = $fks;
314
            } elseif ($fks[1]->getForeignTableName() === $this->table->getName()) {
315
                list($remoteFk, $localFk) = $fks;
316
            } else {
317
                continue;
318
            }
319
320
            $descs[] = new PivotTableMethodsDescriptor($table, $localFk, $remoteFk, $this->namingStrategy);
321
        }
322
323
        return $descs;
324
    }
325
326
    /**
327
     * Returns the list of method descriptors (and applies the alternative name if needed).
328
     *
329
     * @return MethodDescriptorInterface[]
330
     */
331
    private function getMethodDescriptors(): array
332
    {
333
        $directForeignKeyDescriptors = $this->getDirectForeignKeysDescriptors();
334
        $pivotTableDescriptors = $this->getPivotTableDescriptors();
335
336
        $descriptors = array_merge($directForeignKeyDescriptors, $pivotTableDescriptors);
337
338
        // Descriptors by method names
339
        $descriptorsByMethodName = [];
340
341
        foreach ($descriptors as $descriptor) {
342
            $descriptorsByMethodName[$descriptor->getName()][] = $descriptor;
343
        }
344
345
        foreach ($descriptorsByMethodName as $descriptorsForMethodName) {
346
            if (count($descriptorsForMethodName) > 1) {
347
                foreach ($descriptorsForMethodName as $descriptor) {
348
                    $descriptor->useAlternativeName();
349
                }
350
            }
351
        }
352
353
        return $descriptors;
354
    }
355
356
    public function generateJsonSerialize(): string
357
    {
358
        $tableName = $this->table->getName();
359
        $parentFk = $this->schemaAnalyzer->getParentRelationship($tableName);
360
        if ($parentFk !== null) {
361
            $initializer = '$array = parent::jsonSerialize($stopRecursion);';
362
        } else {
363
            $initializer = '$array = [];';
364
        }
365
366
        $str = '
367
    /**
368
     * Serializes the object for JSON encoding.
369
     *
370
     * @param bool $stopRecursion Parameter used internally by TDBM to stop embedded objects from embedding other objects.
371
     * @return array
372
     */
373
    public function jsonSerialize($stopRecursion = false)
374
    {
375
        %s
376
%s
377
%s
378
        return $array;
379
    }
380
';
381
382
        $propertiesCode = '';
383
        foreach ($this->beanPropertyDescriptors as $beanPropertyDescriptor) {
384
            $propertiesCode .= $beanPropertyDescriptor->getJsonSerializeCode();
385
        }
386
387
        // Many2many relationships
388
        $methodsCode = '';
389
        foreach ($this->getMethodDescriptors() as $methodDescriptor) {
390
            $methodsCode .= $methodDescriptor->getJsonSerializeCode();
391
        }
392
393
        return sprintf($str, $initializer, $propertiesCode, $methodsCode);
394
    }
395
396
    /**
397
     * Returns as an array the class we need to extend from and the list of use statements.
398
     *
399
     * @param ForeignKeyConstraint|null $parentFk
400
     * @return array
401
     */
402
    private function generateExtendsAndUseStatements(ForeignKeyConstraint $parentFk = null): array
403
    {
404
        $classes = [];
405
        if ($parentFk !== null) {
406
            $extends = $this->namingStrategy->getBeanClassName($parentFk->getForeignTableName());
407
            $classes[] = $extends;
408
        }
409
410
        foreach ($this->getBeanPropertyDescriptors() as $beanPropertyDescriptor) {
411
            $className = $beanPropertyDescriptor->getClassName();
412
            if (null !== $className) {
413
                $classes[] = $beanPropertyDescriptor->getClassName();
414
            }
415
        }
416
417
        foreach ($this->getMethodDescriptors() as $descriptor) {
418
            $classes = array_merge($classes, $descriptor->getUsedClasses());
419
        }
420
421
        $classes = array_unique($classes);
422
423
        return $classes;
424
    }
425
426
    /**
427
     * Writes the PHP bean file with all getters and setters from the table passed in parameter.
428
     *
429
     * @param string $beannamespace The namespace of the bean
430
     * @return string
431
     */
432
    public function generatePhpCode($beannamespace): string
433
    {
434
        $tableName = $this->table->getName();
435
        $baseClassName = $this->namingStrategy->getBaseBeanClassName($tableName);
436
        $className = $this->namingStrategy->getBeanClassName($tableName);
437
        $parentFk = $this->schemaAnalyzer->getParentRelationship($this->table->getName());
438
439
        $classes = $this->generateExtendsAndUseStatements($parentFk);
440
441
        $uses = array_map(function ($className) use ($beannamespace) {
442
            return 'use '.$beannamespace.'\\'.$className.";\n";
443
        }, $classes);
444
        $use = implode('', $uses);
445
446
        $extends = $this->getExtendedBeanClassName();
447
        if ($extends === null) {
448
            $extends = 'AbstractTDBMObject';
449
            $use .= "use Mouf\\Database\\TDBM\\AbstractTDBMObject;\n";
450
        }
451
452
        $str = "<?php
453
namespace {$beannamespace}\\Generated;
454
455
use Mouf\\Database\\TDBM\\ResultIterator;
456
use Mouf\\Database\\TDBM\\ResultArray;
457
use Mouf\\Database\\TDBM\\AlterableResultIterator;
458
$use
459
/*
460
 * This file has been automatically generated by TDBM.
461
 * DO NOT edit this file, as it might be overwritten.
462
 * If you need to perform changes, edit the $className class instead!
463
 */
464
465
/**
466
 * The $baseClassName class maps the '$tableName' table in database.
467
 */
468
abstract class $baseClassName extends $extends implements \\JsonSerializable
469
{
470
";
471
472
        $str .= $this->generateBeanConstructor();
473
474
        foreach ($this->getExposedProperties() as $property) {
475
            $str .= $property->getGetterSetterCode();
476
        }
477
478
        foreach ($this->getMethodDescriptors() as $methodDescriptor) {
479
            $str .= $methodDescriptor->getCode();
480
        }
481
        $str .= $this->generateJsonSerialize();
482
483
        $str .= $this->generateGetUsedTablesCode();
484
485
        $str .= $this->generateOnDeleteCode();
486
487
        $str .= '}
488
';
489
490
        return $str;
491
    }
492
493
    /**
494
     * @param string $beanNamespace
495
     * @param string $beanClassName
496
     *
497
     * @return array first element: list of used beans, second item: PHP code as a string
498
     */
499
    public function generateFindByDaoCode($beanNamespace, $beanClassName)
500
    {
501
        $code = '';
502
        $usedBeans = [];
503
        foreach ($this->table->getIndexes() as $index) {
504
            if (!$index->isPrimary()) {
505
                list($usedBeansForIndex, $codeForIndex) = $this->generateFindByDaoCodeForIndex($index, $beanNamespace, $beanClassName);
506
                $code .= $codeForIndex;
507
                $usedBeans = array_merge($usedBeans, $usedBeansForIndex);
508
            }
509
        }
510
511
        return [$usedBeans, $code];
512
    }
513
514
    /**
515
     * @param Index  $index
516
     * @param string $beanNamespace
517
     * @param string $beanClassName
518
     *
519
     * @return array first element: list of used beans, second item: PHP code as a string
520
     */
521
    private function generateFindByDaoCodeForIndex(Index $index, $beanNamespace, $beanClassName)
522
    {
523
        $columns = $index->getColumns();
524
        $usedBeans = [];
525
526
        /*
527
         * The list of elements building this index (expressed as columns or foreign keys)
528
         * @var AbstractBeanPropertyDescriptor[]
529
         */
530
        $elements = [];
531
532
        foreach ($columns as $column) {
533
            $fk = $this->isPartOfForeignKey($this->table, $this->table->getColumn($column));
534
            if ($fk !== null) {
535
                if (!in_array($fk, $elements)) {
536
                    $elements[] = new ObjectBeanPropertyDescriptor($this->table, $fk, $this->schemaAnalyzer, $this->namingStrategy);
537
                }
538
            } else {
539
                $elements[] = new ScalarBeanPropertyDescriptor($this->table, $this->table->getColumn($column), $this->namingStrategy);
540
            }
541
        }
542
543
        // If the index is actually only a foreign key, let's bypass it entirely.
544
        if (count($elements) === 1 && $elements[0] instanceof ObjectBeanPropertyDescriptor) {
545
            return [[], ''];
546
        }
547
548
        $methodNameComponent = [];
549
        $functionParameters = [];
550
        $first = true;
551
        foreach ($elements as $element) {
552
            $methodNameComponent[] = $element->getUpperCamelCaseName();
553
            $functionParameter = $element->getClassName();
554
            if ($functionParameter) {
555
                $usedBeans[] = $beanNamespace.'\\'.$functionParameter;
556
                $functionParameter .= ' ';
557
            }
558
            $functionParameter .= $element->getVariableName();
559
            if ($first) {
560
                $first = false;
561
            } else {
562
                $functionParameter .= ' = null';
563
            }
564
            $functionParameters[] = $functionParameter;
565
        }
566
567
        $functionParametersString = implode(', ', $functionParameters);
568
569
        $count = 0;
570
571
        $params = [];
572
        $filterArrayCode = '';
573
        $commentArguments = [];
574
        foreach ($elements as $element) {
575
            $params[] = $element->getParamAnnotation();
576
            if ($element instanceof ScalarBeanPropertyDescriptor) {
577
                $filterArrayCode .= '            '.var_export($element->getColumnName(), true).' => '.$element->getVariableName().",\n";
578
            } else {
579
                ++$count;
580
                $filterArrayCode .= '            '.$count.' => '.$element->getVariableName().",\n";
581
            }
582
            $commentArguments[] = substr($element->getVariableName(), 1);
583
        }
584
        $paramsString = implode("\n", $params);
585
586
        if ($index->isUnique()) {
587
            $methodName = 'findOneBy'.implode('And', $methodNameComponent);
588
            $returnType = "{$beanClassName}";
589
590
            $code = "
591
    /**
592
     * Get a $beanClassName filtered by ".implode(', ', $commentArguments).".
593
     *
594
$paramsString
595
     * @param array \$additionalTablesFetch A list of additional tables to fetch (for performance improvement)
596
     * @return $returnType
597
     */
598
    public function $methodName($functionParametersString, array \$additionalTablesFetch = array()) : $returnType
599
    {
600
        \$filter = [
601
".$filterArrayCode."        ];
602
        return \$this->findOne(\$filter, [], \$additionalTablesFetch);
603
    }
604
";
605
        } else {
606
            $methodName = 'findBy'.implode('And', $methodNameComponent);
607
            $returnType = "{$beanClassName}[]|ResultIterator|ResultArray";
608
609
            $code = "
610
    /**
611
     * Get a list of $beanClassName filtered by ".implode(', ', $commentArguments).".
612
     *
613
$paramsString
614
     * @param mixed \$orderBy The order string
615
     * @param array \$additionalTablesFetch A list of additional tables to fetch (for performance improvement)
616
     * @param string \$mode Either TDBMService::MODE_ARRAY or TDBMService::MODE_CURSOR (for large datasets). Defaults to TDBMService::MODE_ARRAY.
617
     * @return $returnType
618
     */
619
    public function $methodName($functionParametersString, \$orderBy = null, array \$additionalTablesFetch = array(), \$mode = null) : iterable
620
    {
621
        \$filter = [
622
".$filterArrayCode."        ];
623
        return \$this->find(\$filter, [], \$orderBy, \$additionalTablesFetch, \$mode);
624
    }
625
";
626
        }
627
628
        return [$usedBeans, $code];
629
    }
630
631
    /**
632
     * Generates the code for the getUsedTable protected method.
633
     *
634
     * @return string
635
     */
636
    private function generateGetUsedTablesCode()
637
    {
638
        $hasParentRelationship = $this->schemaAnalyzer->getParentRelationship($this->table->getName()) !== null;
639
        if ($hasParentRelationship) {
640
            $code = sprintf('        $tables = parent::getUsedTables();
641
        $tables[] = %s;
642
643
        return $tables;', var_export($this->table->getName(), true));
644
        } else {
645
            $code = sprintf('        return [ %s ];', var_export($this->table->getName(), true));
646
        }
647
648
        return sprintf('
649
    /**
650
     * Returns an array of used tables by this bean (from parent to child relationship).
651
     *
652
     * @return string[]
653
     */
654
    protected function getUsedTables() : array
655
    {
656
%s
657
    }
658
', $code);
659
    }
660
661
    private function generateOnDeleteCode()
662
    {
663
        $code = '';
664
        $relationships = $this->getPropertiesForTable($this->table);
665
        foreach ($relationships as $relationship) {
666
            if ($relationship instanceof ObjectBeanPropertyDescriptor) {
667
                $code .= sprintf('        $this->setRef('.var_export($relationship->getForeignKey()->getName(), true).', null, '.var_export($this->table->getName(), true).");\n");
668
            }
669
        }
670
671
        if ($code) {
672
            return sprintf('
673
    /**
674
     * Method called when the bean is removed from database.
675
     *
676
     */
677
    protected function onDelete() : void
678
    {
679
        parent::onDelete();
680
%s    }
681
', $code);
682
        }
683
684
        return '';
685
    }
686
687
    /**
688
     * Returns the bean class name (without the namespace).
689
     *
690
     * @return string
691
     */
692
    public function getBeanClassName() : string
693
    {
694
        return $this->namingStrategy->getBeanClassName($this->table->getName());
695
    }
696
697
    /**
698
     * Returns the base bean class name (without the namespace).
699
     *
700
     * @return string
701
     */
702
    public function getBaseBeanClassName() : string
703
    {
704
        return $this->namingStrategy->getBaseBeanClassName($this->table->getName());
705
    }
706
707
    /**
708
     * Returns the DAO class name (without the namespace).
709
     *
710
     * @return string
711
     */
712
    public function getDaoClassName() : string
713
    {
714
        return $this->namingStrategy->getDaoClassName($this->table->getName());
715
    }
716
717
    /**
718
     * Returns the base DAO class name (without the namespace).
719
     *
720
     * @return string
721
     */
722
    public function getBaseDaoClassName() : string
723
    {
724
        return $this->namingStrategy->getBaseDaoClassName($this->table->getName());
725
    }
726
727
    /**
728
     * Returns the table used to build this bean.
729
     *
730
     * @return Table
731
     */
732
    public function getTable(): Table
733
    {
734
        return $this->table;
735
    }
736
737
    /**
738
     * Returns the extended bean class name (without the namespace), or null if the bean is not extended.
739
     *
740
     * @return string
741
     */
742
    public function getExtendedBeanClassName(): ?string
743
    {
744
        $parentFk = $this->schemaAnalyzer->getParentRelationship($this->table->getName());
745
        if ($parentFk !== null) {
746
            return $this->namingStrategy->getBeanClassName($parentFk->getForeignTableName());
747
        } else {
748
            return null;
749
        }
750
    }
751
}
752