Passed
Push — master ( 5f3c58...4c28db )
by David
01:30
created

BeanDescriptor::getBeanNamespace()   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 TheCodingMachine\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 TheCodingMachine\TDBM\TDBMException;
12
use TheCodingMachine\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
     * @var string
50
     */
51
    private $beanNamespace;
52
    /**
53
     * @var string
54
     */
55
    private $generatedBeanNamespace;
56
57
    /**
58
     * @param Table $table
59
     * @param string $beanNamespace
60
     * @param string $generatedBeanNamespace
61
     * @param SchemaAnalyzer $schemaAnalyzer
62
     * @param Schema $schema
63
     * @param TDBMSchemaAnalyzer $tdbmSchemaAnalyzer
64
     * @param NamingStrategyInterface $namingStrategy
65
     */
66
    public function __construct(Table $table, string $beanNamespace, string $generatedBeanNamespace, SchemaAnalyzer $schemaAnalyzer, Schema $schema, TDBMSchemaAnalyzer $tdbmSchemaAnalyzer, NamingStrategyInterface $namingStrategy)
67
    {
68
        $this->table = $table;
69
        $this->beanNamespace = $beanNamespace;
70
        $this->generatedBeanNamespace = $generatedBeanNamespace;
71
        $this->schemaAnalyzer = $schemaAnalyzer;
72
        $this->schema = $schema;
73
        $this->tdbmSchemaAnalyzer = $tdbmSchemaAnalyzer;
74
        $this->namingStrategy = $namingStrategy;
75
        $this->initBeanPropertyDescriptors();
76
    }
77
78
    private function initBeanPropertyDescriptors()
79
    {
80
        $this->beanPropertyDescriptors = $this->getProperties($this->table);
81
    }
82
83
    /**
84
     * Returns the foreign-key the column is part of, if any. null otherwise.
85
     *
86
     * @param Table  $table
87
     * @param Column $column
88
     *
89
     * @return ForeignKeyConstraint|null
90
     */
91
    private function isPartOfForeignKey(Table $table, Column $column)
92
    {
93
        $localColumnName = $column->getName();
94
        foreach ($table->getForeignKeys() as $foreignKey) {
95
            foreach ($foreignKey->getColumns() as $columnName) {
96
                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...
97
                    return $foreignKey;
98
                }
99
            }
100
        }
101
102
        return;
103
    }
104
105
    /**
106
     * @return AbstractBeanPropertyDescriptor[]
107
     */
108
    public function getBeanPropertyDescriptors()
109
    {
110
        return $this->beanPropertyDescriptors;
111
    }
112
113
    /**
114
     * Returns the list of columns that are not nullable and not autogenerated for a given table and its parent.
115
     *
116
     * @return AbstractBeanPropertyDescriptor[]
117
     */
118
    public function getConstructorProperties()
119
    {
120
        $constructorProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
121
            return $property->isCompulsory();
122
        });
123
124
        return $constructorProperties;
125
    }
126
127
    /**
128
     * Returns the list of columns that have default values for a given table.
129
     *
130
     * @return AbstractBeanPropertyDescriptor[]
131
     */
132
    public function getPropertiesWithDefault()
133
    {
134
        $properties = $this->getPropertiesForTable($this->table);
135
        $defaultProperties = array_filter($properties, function (AbstractBeanPropertyDescriptor $property) {
136
            return $property->hasDefault();
137
        });
138
139
        return $defaultProperties;
140
    }
141
142
    /**
143
     * Returns the list of properties exposed as getters and setters in this class.
144
     *
145
     * @return AbstractBeanPropertyDescriptor[]
146
     */
147
    public function getExposedProperties(): array
148
    {
149
        $exposedProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
150
            return $property->getTable()->getName() == $this->table->getName();
151
        });
152
153
        return $exposedProperties;
154
    }
155
156
    /**
157
     * Returns the list of properties for this table (including parent tables).
158
     *
159
     * @param Table $table
160
     *
161
     * @return AbstractBeanPropertyDescriptor[]
162
     */
163
    private function getProperties(Table $table)
164
    {
165
        $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
166
        if ($parentRelationship) {
167
            $parentTable = $this->schema->getTable($parentRelationship->getForeignTableName());
168
            $properties = $this->getProperties($parentTable);
169
            // we merge properties by overriding property names.
170
            $localProperties = $this->getPropertiesForTable($table);
171
            foreach ($localProperties as $name => $property) {
172
                // We do not override properties if this is a primary key!
173
                if ($property->isPrimaryKey()) {
174
                    continue;
175
                }
176
                $properties[$name] = $property;
177
            }
178
        } else {
179
            $properties = $this->getPropertiesForTable($table);
180
        }
181
182
        return $properties;
183
    }
184
185
    /**
186
     * Returns the list of properties for this table (ignoring parent tables).
187
     *
188
     * @param Table $table
189
     *
190
     * @return AbstractBeanPropertyDescriptor[]
191
     */
192
    private function getPropertiesForTable(Table $table)
193
    {
194
        $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
195
        if ($parentRelationship) {
196
            $ignoreColumns = $parentRelationship->getLocalColumns();
197
        } else {
198
            $ignoreColumns = [];
199
        }
200
201
        $beanPropertyDescriptors = [];
202
203
        foreach ($table->getColumns() as $column) {
204
            if (array_search($column->getName(), $ignoreColumns) !== false) {
205
                continue;
206
            }
207
208
            $fk = $this->isPartOfForeignKey($table, $column);
209
            if ($fk !== null) {
210
                // Check that previously added descriptors are not added on same FK (can happen with multi key FK).
211
                foreach ($beanPropertyDescriptors as $beanDescriptor) {
212
                    if ($beanDescriptor instanceof ObjectBeanPropertyDescriptor && $beanDescriptor->getForeignKey() === $fk) {
213
                        continue 2;
214
                    }
215
                }
216
                // Check that this property is not an inheritance relationship
217
                $parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
218
                if ($parentRelationship === $fk) {
219
                    continue;
220
                }
221
222
                $beanPropertyDescriptors[] = new ObjectBeanPropertyDescriptor($table, $fk, $this->schemaAnalyzer, $this->namingStrategy);
223
            } else {
224
                $beanPropertyDescriptors[] = new ScalarBeanPropertyDescriptor($table, $column, $this->namingStrategy);
225
            }
226
        }
227
228
        // Now, let's get the name of all properties and let's check there is no duplicate.
229
        /** @var $names AbstractBeanPropertyDescriptor[] */
230
        $names = [];
231
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
232
            $name = $beanDescriptor->getGetterName();
233
            if (isset($names[$name])) {
234
                $names[$name]->useAlternativeName();
235
                $beanDescriptor->useAlternativeName();
236
            } else {
237
                $names[$name] = $beanDescriptor;
238
            }
239
        }
240
241
        // Final check (throw exceptions if problem arises)
242
        $names = [];
243
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
244
            $name = $beanDescriptor->getGetterName();
245
            if (isset($names[$name])) {
246
                throw new TDBMException('Unsolvable name conflict while generating method name');
247
            } else {
248
                $names[$name] = $beanDescriptor;
249
            }
250
        }
251
252
        // Last step, let's rebuild the list with a map:
253
        $beanPropertyDescriptorsMap = [];
254
        foreach ($beanPropertyDescriptors as $beanDescriptor) {
255
            $beanPropertyDescriptorsMap[$beanDescriptor->getVariableName()] = $beanDescriptor;
256
        }
257
258
        return $beanPropertyDescriptorsMap;
259
    }
260
261
    private function generateBeanConstructor() : string
262
    {
263
        $constructorProperties = $this->getConstructorProperties();
264
265
        $constructorCode = '    /**
266
     * The constructor takes all compulsory arguments.
267
     *
268
%s
269
     */
270
    public function __construct(%s)
271
    {
272
%s%s    }
273
    ';
274
275
        $paramAnnotations = [];
276
        $arguments = [];
277
        $assigns = [];
278
        $parentConstructorArguments = [];
279
280
        foreach ($constructorProperties as $property) {
281
            $className = $property->getClassName();
282
            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...
283
                $arguments[] = $className.' '.$property->getVariableName();
284
            } else {
285
                $arguments[] = $property->getVariableName();
286
            }
287
            $paramAnnotations[] = $property->getParamAnnotation();
288
            if ($property->getTable()->getName() === $this->table->getName()) {
289
                $assigns[] = $property->getConstructorAssignCode()."\n";
290
            } else {
291
                $parentConstructorArguments[] = $property->getVariableName();
292
            }
293
        }
294
295
        $parentConstructorCode = sprintf("        parent::__construct(%s);\n", implode(', ', $parentConstructorArguments));
296
297
        foreach ($this->getPropertiesWithDefault() as $property) {
298
            $assigns[] = $property->assignToDefaultCode()."\n";
299
        }
300
301
        return sprintf($constructorCode, implode("\n", $paramAnnotations), implode(', ', $arguments), $parentConstructorCode, implode('', $assigns));
302
    }
303
304
    /**
305
     * Returns the descriptors of one-to-many relationships (the foreign keys pointing on this beans)
306
     *
307
     * @return DirectForeignKeyMethodDescriptor[]
308
     */
309
    private function getDirectForeignKeysDescriptors(): array
310
    {
311
        $fks = $this->tdbmSchemaAnalyzer->getIncomingForeignKeys($this->table->getName());
312
313
        $descriptors = [];
314
315
        foreach ($fks as $fk) {
316
            $descriptors[] = new DirectForeignKeyMethodDescriptor($fk, $this->table, $this->namingStrategy);
317
        }
318
319
        return $descriptors;
320
    }
321
322
    /**
323
     * @return PivotTableMethodsDescriptor[]
324
     */
325
    private function getPivotTableDescriptors(): array
326
    {
327
        $descs = [];
328
        foreach ($this->schemaAnalyzer->detectJunctionTables(true) as $table) {
329
            // There are exactly 2 FKs since this is a pivot table.
330
            $fks = array_values($table->getForeignKeys());
331
332
            if ($fks[0]->getForeignTableName() === $this->table->getName()) {
333
                list($localFk, $remoteFk) = $fks;
334
            } elseif ($fks[1]->getForeignTableName() === $this->table->getName()) {
335
                list($remoteFk, $localFk) = $fks;
336
            } else {
337
                continue;
338
            }
339
340
            $descs[] = new PivotTableMethodsDescriptor($table, $localFk, $remoteFk, $this->namingStrategy);
341
        }
342
343
        return $descs;
344
    }
345
346
    /**
347
     * Returns the list of method descriptors (and applies the alternative name if needed).
348
     *
349
     * @return MethodDescriptorInterface[]
350
     */
351
    public function getMethodDescriptors(): array
352
    {
353
        $directForeignKeyDescriptors = $this->getDirectForeignKeysDescriptors();
354
        $pivotTableDescriptors = $this->getPivotTableDescriptors();
355
356
        $descriptors = array_merge($directForeignKeyDescriptors, $pivotTableDescriptors);
357
358
        // Descriptors by method names
359
        $descriptorsByMethodName = [];
360
361
        foreach ($descriptors as $descriptor) {
362
            $descriptorsByMethodName[$descriptor->getName()][] = $descriptor;
363
        }
364
365
        foreach ($descriptorsByMethodName as $descriptorsForMethodName) {
366
            if (count($descriptorsForMethodName) > 1) {
367
                foreach ($descriptorsForMethodName as $descriptor) {
368
                    $descriptor->useAlternativeName();
369
                }
370
            }
371
        }
372
373
        return $descriptors;
374
    }
375
376
    public function generateJsonSerialize(): string
377
    {
378
        $tableName = $this->table->getName();
379
        $parentFk = $this->schemaAnalyzer->getParentRelationship($tableName);
380
        if ($parentFk !== null) {
381
            $initializer = '$array = parent::jsonSerialize($stopRecursion);';
382
        } else {
383
            $initializer = '$array = [];';
384
        }
385
386
        $str = '
387
    /**
388
     * Serializes the object for JSON encoding.
389
     *
390
     * @param bool $stopRecursion Parameter used internally by TDBM to stop embedded objects from embedding other objects.
391
     * @return array
392
     */
393
    public function jsonSerialize($stopRecursion = false)
394
    {
395
        %s
396
%s
397
%s
398
        return $array;
399
    }
400
';
401
402
        $propertiesCode = '';
403
        foreach ($this->beanPropertyDescriptors as $beanPropertyDescriptor) {
404
            $propertiesCode .= $beanPropertyDescriptor->getJsonSerializeCode();
405
        }
406
407
        // Many2many relationships
408
        $methodsCode = '';
409
        foreach ($this->getMethodDescriptors() as $methodDescriptor) {
410
            $methodsCode .= $methodDescriptor->getJsonSerializeCode();
411
        }
412
413
        return sprintf($str, $initializer, $propertiesCode, $methodsCode);
414
    }
415
416
    /**
417
     * Returns as an array the class we need to extend from and the list of use statements.
418
     *
419
     * @param ForeignKeyConstraint|null $parentFk
420
     * @return array
421
     */
422
    private function generateExtendsAndUseStatements(ForeignKeyConstraint $parentFk = null): array
423
    {
424
        $classes = [];
425
        if ($parentFk !== null) {
426
            $extends = $this->namingStrategy->getBeanClassName($parentFk->getForeignTableName());
427
            $classes[] = $extends;
428
        }
429
430
        foreach ($this->getBeanPropertyDescriptors() as $beanPropertyDescriptor) {
431
            $className = $beanPropertyDescriptor->getClassName();
432
            if (null !== $className) {
433
                $classes[] = $beanPropertyDescriptor->getClassName();
434
            }
435
        }
436
437
        foreach ($this->getMethodDescriptors() as $descriptor) {
438
            $classes = array_merge($classes, $descriptor->getUsedClasses());
439
        }
440
441
        $classes = array_unique($classes);
442
443
        return $classes;
444
    }
445
446
    /**
447
     * Writes the PHP bean file with all getters and setters from the table passed in parameter.
448
     *
449
     * @return string
450
     */
451
    public function generatePhpCode(): string
452
    {
453
        $tableName = $this->table->getName();
454
        $baseClassName = $this->namingStrategy->getBaseBeanClassName($tableName);
455
        $className = $this->namingStrategy->getBeanClassName($tableName);
456
        $parentFk = $this->schemaAnalyzer->getParentRelationship($this->table->getName());
457
458
        $classes = $this->generateExtendsAndUseStatements($parentFk);
459
460
        $uses = array_map(function ($className) {
461
            return 'use '.$this->beanNamespace.'\\'.$className.";\n";
462
        }, $classes);
463
        $use = implode('', $uses);
464
465
        $extends = $this->getExtendedBeanClassName();
466
        if ($extends === null) {
467
            $extends = 'AbstractTDBMObject';
468
            $use .= "use TheCodingMachine\\TDBM\\AbstractTDBMObject;\n";
469
        }
470
471
        $str = "<?php
472
namespace {$this->generatedBeanNamespace};
473
474
use TheCodingMachine\\TDBM\\ResultIterator;
475
use TheCodingMachine\\TDBM\\ResultArray;
476
use TheCodingMachine\\TDBM\\AlterableResultIterator;
477
$use
478
/*
479
 * This file has been automatically generated by TDBM.
480
 * DO NOT edit this file, as it might be overwritten.
481
 * If you need to perform changes, edit the $className class instead!
482
 */
483
484
/**
485
 * The $baseClassName class maps the '$tableName' table in database.
486
 */
487
abstract class $baseClassName extends $extends implements \\JsonSerializable
488
{
489
";
490
491
        $str .= $this->generateBeanConstructor();
492
493
        foreach ($this->getExposedProperties() as $property) {
494
            $str .= $property->getGetterSetterCode();
495
        }
496
497
        foreach ($this->getMethodDescriptors() as $methodDescriptor) {
498
            $str .= $methodDescriptor->getCode();
499
        }
500
        $str .= $this->generateJsonSerialize();
501
502
        $str .= $this->generateGetUsedTablesCode();
503
504
        $str .= $this->generateOnDeleteCode();
505
506
        $str .= '}
507
';
508
509
        return $str;
510
    }
511
512
    /**
513
     * @param string $beanNamespace
514
     * @param string $beanClassName
515
     *
516
     * @return array first element: list of used beans, second item: PHP code as a string
517
     */
518
    public function generateFindByDaoCode($beanNamespace, $beanClassName)
519
    {
520
        $code = '';
521
        $usedBeans = [];
522
        foreach ($this->table->getIndexes() as $index) {
523
            if (!$index->isPrimary()) {
524
                list($usedBeansForIndex, $codeForIndex) = $this->generateFindByDaoCodeForIndex($index, $beanNamespace, $beanClassName);
525
                $code .= $codeForIndex;
526
                $usedBeans = array_merge($usedBeans, $usedBeansForIndex);
527
            }
528
        }
529
530
        return [$usedBeans, $code];
531
    }
532
533
    /**
534
     * @param Index  $index
535
     * @param string $beanNamespace
536
     * @param string $beanClassName
537
     *
538
     * @return array first element: list of used beans, second item: PHP code as a string
539
     */
540
    private function generateFindByDaoCodeForIndex(Index $index, $beanNamespace, $beanClassName)
541
    {
542
        $columns = $index->getColumns();
543
        $usedBeans = [];
544
545
        /*
546
         * The list of elements building this index (expressed as columns or foreign keys)
547
         * @var AbstractBeanPropertyDescriptor[]
548
         */
549
        $elements = [];
550
551
        foreach ($columns as $column) {
552
            $fk = $this->isPartOfForeignKey($this->table, $this->table->getColumn($column));
553
            if ($fk !== null) {
554
                if (!in_array($fk, $elements)) {
555
                    $elements[] = new ObjectBeanPropertyDescriptor($this->table, $fk, $this->schemaAnalyzer, $this->namingStrategy);
556
                }
557
            } else {
558
                $elements[] = new ScalarBeanPropertyDescriptor($this->table, $this->table->getColumn($column), $this->namingStrategy);
559
            }
560
        }
561
562
        // If the index is actually only a foreign key, let's bypass it entirely.
563
        if (count($elements) === 1 && $elements[0] instanceof ObjectBeanPropertyDescriptor) {
564
            return [[], ''];
565
        }
566
567
        $functionParameters = [];
568
        $first = true;
569
        foreach ($elements as $element) {
570
            $functionParameter = $element->getClassName();
571
            if ($functionParameter) {
572
                $usedBeans[] = $beanNamespace.'\\'.$functionParameter;
573
                $functionParameter .= ' ';
574
            }
575
            $functionParameter .= $element->getVariableName();
576
            if ($first) {
577
                $first = false;
578
            } else {
579
                $functionParameter .= ' = null';
580
            }
581
            $functionParameters[] = $functionParameter;
582
        }
583
584
        $functionParametersString = implode(', ', $functionParameters);
585
586
        $count = 0;
587
588
        $params = [];
589
        $filterArrayCode = '';
590
        $commentArguments = [];
591
        foreach ($elements as $element) {
592
            $params[] = $element->getParamAnnotation();
593
            if ($element instanceof ScalarBeanPropertyDescriptor) {
594
                $filterArrayCode .= '            '.var_export($element->getColumnName(), true).' => '.$element->getVariableName().",\n";
595
            } else {
596
                ++$count;
597
                $filterArrayCode .= '            '.$count.' => '.$element->getVariableName().",\n";
598
            }
599
            $commentArguments[] = substr($element->getVariableName(), 1);
600
        }
601
        $paramsString = implode("\n", $params);
602
603
        $methodName = $this->namingStrategy->getFindByIndexMethodName($index, $elements);
604
605
        if ($index->isUnique()) {
606
            $returnType = "{$beanClassName}";
607
608
            $code = "
609
    /**
610
     * Get a $beanClassName filtered by ".implode(', ', $commentArguments).".
611
     *
612
$paramsString
613
     * @param array \$additionalTablesFetch A list of additional tables to fetch (for performance improvement)
614
     * @return $returnType
615
     */
616
    public function $methodName($functionParametersString, array \$additionalTablesFetch = array()) : $returnType
617
    {
618
        \$filter = [
619
".$filterArrayCode."        ];
620
        return \$this->findOne(\$filter, [], \$additionalTablesFetch);
621
    }
622
";
623
        } else {
624
            $returnType = "{$beanClassName}[]|ResultIterator|ResultArray";
625
626
            $code = "
627
    /**
628
     * Get a list of $beanClassName filtered by ".implode(', ', $commentArguments).".
629
     *
630
$paramsString
631
     * @param mixed \$orderBy The order string
632
     * @param array \$additionalTablesFetch A list of additional tables to fetch (for performance improvement)
633
     * @param string \$mode Either TDBMService::MODE_ARRAY or TDBMService::MODE_CURSOR (for large datasets). Defaults to TDBMService::MODE_ARRAY.
634
     * @return $returnType
635
     */
636
    public function $methodName($functionParametersString, \$orderBy = null, array \$additionalTablesFetch = array(), \$mode = null) : iterable
637
    {
638
        \$filter = [
639
".$filterArrayCode."        ];
640
        return \$this->find(\$filter, [], \$orderBy, \$additionalTablesFetch, \$mode);
641
    }
642
";
643
        }
644
645
        return [$usedBeans, $code];
646
    }
647
648
    /**
649
     * Generates the code for the getUsedTable protected method.
650
     *
651
     * @return string
652
     */
653
    private function generateGetUsedTablesCode()
654
    {
655
        $hasParentRelationship = $this->schemaAnalyzer->getParentRelationship($this->table->getName()) !== null;
656
        if ($hasParentRelationship) {
657
            $code = sprintf('        $tables = parent::getUsedTables();
658
        $tables[] = %s;
659
660
        return $tables;', var_export($this->table->getName(), true));
661
        } else {
662
            $code = sprintf('        return [ %s ];', var_export($this->table->getName(), true));
663
        }
664
665
        return sprintf('
666
    /**
667
     * Returns an array of used tables by this bean (from parent to child relationship).
668
     *
669
     * @return string[]
670
     */
671
    protected function getUsedTables() : array
672
    {
673
%s
674
    }
675
', $code);
676
    }
677
678
    private function generateOnDeleteCode()
679
    {
680
        $code = '';
681
        $relationships = $this->getPropertiesForTable($this->table);
682
        foreach ($relationships as $relationship) {
683
            if ($relationship instanceof ObjectBeanPropertyDescriptor) {
684
                $code .= sprintf('        $this->setRef('.var_export($relationship->getForeignKey()->getName(), true).', null, '.var_export($this->table->getName(), true).");\n");
685
            }
686
        }
687
688
        if ($code) {
689
            return sprintf('
690
    /**
691
     * Method called when the bean is removed from database.
692
     *
693
     */
694
    protected function onDelete() : void
695
    {
696
        parent::onDelete();
697
%s    }
698
', $code);
699
        }
700
701
        return '';
702
    }
703
704
    /**
705
     * Returns the bean class name (without the namespace).
706
     *
707
     * @return string
708
     */
709
    public function getBeanClassName() : string
710
    {
711
        return $this->namingStrategy->getBeanClassName($this->table->getName());
712
    }
713
714
    /**
715
     * Returns the base bean class name (without the namespace).
716
     *
717
     * @return string
718
     */
719
    public function getBaseBeanClassName() : string
720
    {
721
        return $this->namingStrategy->getBaseBeanClassName($this->table->getName());
722
    }
723
724
    /**
725
     * Returns the DAO class name (without the namespace).
726
     *
727
     * @return string
728
     */
729
    public function getDaoClassName() : string
730
    {
731
        return $this->namingStrategy->getDaoClassName($this->table->getName());
732
    }
733
734
    /**
735
     * Returns the base DAO class name (without the namespace).
736
     *
737
     * @return string
738
     */
739
    public function getBaseDaoClassName() : string
740
    {
741
        return $this->namingStrategy->getBaseDaoClassName($this->table->getName());
742
    }
743
744
    /**
745
     * Returns the table used to build this bean.
746
     *
747
     * @return Table
748
     */
749
    public function getTable(): Table
750
    {
751
        return $this->table;
752
    }
753
754
    /**
755
     * Returns the extended bean class name (without the namespace), or null if the bean is not extended.
756
     *
757
     * @return string
758
     */
759
    public function getExtendedBeanClassName(): ?string
760
    {
761
        $parentFk = $this->schemaAnalyzer->getParentRelationship($this->table->getName());
762
        if ($parentFk !== null) {
763
            return $this->namingStrategy->getBeanClassName($parentFk->getForeignTableName());
764
        } else {
765
            return null;
766
        }
767
    }
768
769
    /**
770
     * @return string
771
     */
772
    public function getBeanNamespace(): string
773
    {
774
        return $this->beanNamespace;
775
    }
776
777
    /**
778
     * @return string
779
     */
780
    public function getGeneratedBeanNamespace(): string
781
    {
782
        return $this->generatedBeanNamespace;
783
    }
784
}
785