Skip to content

Commit 27db626

Browse files
authored
Merge pull request #188 from thecodingmachine/5.1
Porting Inheritance fix to 5.2
2 parents 2340c9e + 1b91945 commit 27db626

File tree

5 files changed

+87
-15
lines changed

5 files changed

+87
-15
lines changed

src/Utils/BeanDescriptor.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public function getBeanPropertyDescriptors(): array
214214
public function getConstructorProperties(): array
215215
{
216216
$constructorProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
217-
return $property->isCompulsory();
217+
return !$property instanceof InheritanceReferencePropertyDescriptor && $property->isCompulsory();
218218
});
219219

220220
return $constructorProperties;
@@ -243,7 +243,7 @@ public function getPropertiesWithDefault(): array
243243
public function getExposedProperties(): array
244244
{
245245
$exposedProperties = array_filter($this->beanPropertyDescriptors, function (AbstractBeanPropertyDescriptor $property) {
246-
return $property->getTable()->getName() == $this->table->getName();
246+
return !$property instanceof InheritanceReferencePropertyDescriptor && $property->getTable()->getName() === $this->table->getName();
247247
});
248248

249249
return $exposedProperties;
@@ -269,7 +269,7 @@ private function getProperties(Table $table): array
269269
$localProperties = $this->getPropertiesForTable($table);
270270
foreach ($localProperties as $name => $property) {
271271
// We do not override properties if this is a primary key!
272-
if ($property->isPrimaryKey()) {
272+
if (!$property instanceof InheritanceReferencePropertyDescriptor && $property->isPrimaryKey()) {
273273
continue;
274274
}
275275
$properties[$name] = $property;
@@ -292,14 +292,14 @@ private function getPropertiesForTable(Table $table): array
292292
{
293293
$parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
294294
if ($parentRelationship) {
295-
$ignoreColumns = $parentRelationship->getUnquotedLocalColumns();
295+
$ignoreColumns = $parentRelationship->getUnquotedForeignColumns();
296296
} else {
297297
$ignoreColumns = [];
298298
}
299299

300300
$beanPropertyDescriptors = [];
301301
foreach ($table->getColumns() as $column) {
302-
if (array_search($column->getName(), $ignoreColumns) !== false) {
302+
if (in_array($column->getName(), $ignoreColumns, true)) {
303303
continue;
304304
}
305305

@@ -311,13 +311,20 @@ private function getPropertiesForTable(Table $table): array
311311
continue 2;
312312
}
313313
}
314+
$propertyDescriptor = new ObjectBeanPropertyDescriptor($table, $fk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser, $this->registry->getBeanForTableName($fk->getForeignTableName()));
314315
// Check that this property is not an inheritance relationship
315316
$parentRelationship = $this->schemaAnalyzer->getParentRelationship($table->getName());
316-
if ($parentRelationship === $fk) {
317-
continue;
317+
if ($parentRelationship !== null && $parentRelationship->getName() === $fk->getName()) {
318+
$beanPropertyDescriptors[] = new InheritanceReferencePropertyDescriptor(
319+
$table,
320+
$column,
321+
$this->namingStrategy,
322+
$this->annotationParser,
323+
$propertyDescriptor
324+
);
325+
} else {
326+
$beanPropertyDescriptors[] = $propertyDescriptor;
318327
}
319-
320-
$beanPropertyDescriptors[] = new ObjectBeanPropertyDescriptor($table, $fk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser, $this->registry->getBeanForTableName($fk->getForeignTableName()));
321328
} else {
322329
$beanPropertyDescriptors[] = new ScalarBeanPropertyDescriptor($table, $column, $this->namingStrategy, $this->annotationParser);
323330
}

src/Utils/DefaultNamingStrategy.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,11 @@ protected function getUpperCamelCaseName(AbstractBeanPropertyDescriptor $propert
338338
{
339339
if ($property instanceof ObjectBeanPropertyDescriptor) {
340340
return $this->getForeignKeyUpperCamelCaseName($property->getForeignKey(), $property->isAlternativeName());
341-
} elseif ($property instanceof ScalarBeanPropertyDescriptor) {
341+
}
342+
if ($property instanceof ScalarBeanPropertyDescriptor) {
342343
return $this->getScalarColumnUpperCamelCaseName($property->getColumnName(), $property->isAlternativeName());
343-
} else {
344-
throw new TDBMException('Unexpected property type. Should be either ObjectBeanPropertyDescriptor or ScalarBeanPropertyDescriptor'); // @codeCoverageIgnore
345344
}
345+
throw new TDBMException('Unexpected property type. Should be either ObjectBeanPropertyDescriptor or ScalarBeanPropertyDescriptor'); // @codeCoverageIgnore
346346
}
347347

348348
private function getSchema(): Schema
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
4+
namespace TheCodingMachine\TDBM\Utils;
5+
6+
use Doctrine\DBAL\Schema\Column;
7+
use Doctrine\DBAL\Schema\Table;
8+
use TheCodingMachine\TDBM\Utils\Annotation\AnnotationParser;
9+
10+
/**
11+
* This class represents a reference to a AbstractBeanPropertyDescriptor used in an inheritance schema
12+
*/
13+
class InheritanceReferencePropertyDescriptor extends ScalarBeanPropertyDescriptor
14+
{
15+
/** @var AbstractBeanPropertyDescriptor */
16+
private $referencedPropertyDescriptor;
17+
18+
public function __construct(
19+
Table $table,
20+
Column $column,
21+
NamingStrategyInterface $namingStrategy,
22+
AnnotationParser $annotationParser,
23+
AbstractBeanPropertyDescriptor $referencedPropertyDescriptor
24+
) {
25+
parent::__construct($table, $column, $namingStrategy, $annotationParser);
26+
$this->referencedPropertyDescriptor = $referencedPropertyDescriptor;
27+
}
28+
29+
/**
30+
* @return ScalarBeanPropertyDescriptor|ObjectBeanPropertyDescriptor
31+
*/
32+
public function getNonScalarReferencedPropertyDescriptor(): AbstractBeanPropertyDescriptor
33+
{
34+
if ($this->referencedPropertyDescriptor instanceof InheritanceReferencePropertyDescriptor) {
35+
return $this->referencedPropertyDescriptor->getNonScalarReferencedPropertyDescriptor();
36+
}
37+
assert($this->referencedPropertyDescriptor instanceof ScalarBeanPropertyDescriptor || $this->referencedPropertyDescriptor instanceof ObjectBeanPropertyDescriptor);
38+
return $this->referencedPropertyDescriptor;
39+
}
40+
41+
public function getJsonSerializeCode(): string
42+
{
43+
return $this->getNonScalarReferencedPropertyDescriptor()->getJsonSerializeCode();
44+
}
45+
}

src/Utils/ObjectBeanPropertyDescriptor.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,18 @@ private function getLazySerializeCode(string $propertyAccess): string
258258
$rows = [];
259259
foreach ($this->getForeignKey()->getUnquotedForeignColumns() as $column) {
260260
$descriptor = $this->getBeanPropertyDescriptor($column);
261-
$indexName = ltrim($descriptor->getVariableName(), '$');
262-
$columnGetterName = $descriptor->getGetterName();
263-
$rows[] = "'$indexName' => $propertyAccess->$columnGetterName()";
261+
if ($descriptor instanceof InheritanceReferencePropertyDescriptor) {
262+
$descriptor = $descriptor->getNonScalarReferencedPropertyDescriptor();
263+
}
264+
if ($descriptor instanceof ObjectBeanPropertyDescriptor) {
265+
$rows[] = trim($descriptor->getLazySerializeCode($propertyAccess), '[]');
266+
} elseif ($descriptor instanceof ScalarBeanPropertyDescriptor) {
267+
$indexName = ltrim($descriptor->getVariableName(), '$');
268+
$columnGetterName = $descriptor->getGetterName();
269+
$rows[] = "'$indexName' => $propertyAccess->$columnGetterName()";
270+
} else {
271+
throw new TDBMException('PropertyDescriptor of class `' . get_class($descriptor) . '` cannot be serialized.');
272+
}
264273
}
265274
return '[' . implode(', ', $rows) . ']';
266275
}

tests/TDBMAbstractServiceTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,17 @@ private static function initSchema(Connection $connection): void
395395
->column('fk_2')->integer()
396396
->then()->getDbalTable()->addForeignKeyConstraint($targetTable->getDbalTable(), ['fk_1', 'fk_2'], ['id_1', 'id_2']);
397397

398+
// Test case, the problem here is:
399+
// - `inheritance_agency` have an FK to `inheritance_society.**id_entity**`
400+
// - `inheritance_society` have an FK to `inheritance_entity.**id**`
401+
$db->table('inheritance_entity')
402+
->column('id')->integer()->primaryKey()->autoIncrement();
403+
$db->table('inheritance_society')
404+
->column('id_entity')->references('inheritance_entity')->primaryKey()
405+
->then();
406+
$db->table('inheritance_agency')
407+
->column('id')->integer()->primaryKey()->autoIncrement()
408+
->column('id_parent_society')->references('inheritance_society');
398409

399410
$sqlStmts = $toSchema->getMigrateFromSql($fromSchema, $connection->getDatabasePlatform());
400411

0 commit comments

Comments
 (0)