Skip to content

Commit

Permalink
Prevents incorrect table aliases to be generated
Browse files Browse the repository at this point in the history
When a defined subclass has a case typo, the query builder will be lost
and will generate exotic table alias. This commit fixes the issue at the
root by prohibiting case typo in discriminator map.

See doctrine#8112 for the consequence of
such typo.
  • Loading branch information
gquemener committed Apr 24, 2020
1 parent 73ec483 commit cad84ac
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -2816,6 +2816,11 @@ public function addDiscriminatorMapClass($name, $className)
throw MappingException::invalidClassInDiscriminatorMap($className, $this->name);
}

$refl = new ReflectionClass($className);
if ($refl->name !== $className) {
throw MappingException::invalidClassInDiscriminatorMap($className, $this->name);
}

if (is_subclass_of($className, $this->name) && ! in_array($className, $this->subClasses)) {
$this->subClasses[] = $className;
}
Expand Down
49 changes: 49 additions & 0 deletions tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,14 @@ public function testDiscriminatorColumnDefaultName()
$this->assertEquals('dtype', $class->discriminatorColumn['name']);
}

/**
* @expectedException \Doctrine\ORM\Mapping\MappingException
* @expectedExceptionMessage Entity class 'Doctrine\Tests\ORM\Mapping\cube' used in the discriminator map of class 'Doctrine\Tests\ORM\Mapping\Shape' does not exist.
*/
public function testInvalidSubClassCase()
{
$this->createClassMetadata(Shape::class);
}
}

/**
Expand Down Expand Up @@ -1344,6 +1352,47 @@ public static function loadMetadata(ClassMetadataInfo $metadata)
}
}

/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorMap({"cube" = cube::class})
* @DiscriminatorColumn(name="discr", length=32, type="string")
*/
abstract class Shape
{
/** @Id @Column(type="string") @GeneratedValue(strategy="AUTO") */
public $id;

public static function loadMetadata(ClassMetadataInfo $metadata)
{
$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE);
$metadata->setDiscriminatorColumn([
'name' => 'discr',
'type' => 'string',
'length' => 32,
]);
$metadata->setDiscriminatorMap([
'cube' => cube::class,
]);
$metadata->mapField([
'fieldName' => 'id',
'type' => 'string',
'length' => NULL,
'precision' => 0,
'scale' => 0,
'nullable' => false,
'unique' => false,
'id' => true,
'columnName' => 'id',
]);
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
}
}

/** @Entity */
class Cube extends Shape
{
}

/**
* @Entity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\Tests\ORM\Mapping\cube;

/* @var $metadata ClassMetadataInfo */
$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE);
$metadata->setDiscriminatorColumn([
'name' => 'discr',
'type' => 'string',
'length' => 32,
]);
$metadata->setDiscriminatorMap([
'cube' => cube::class,
]);
$metadata->mapField([
'fieldName' => 'id',
'type' => 'string',
'length' => NULL,
'precision' => 0,
'scale' => 0,
'nullable' => false,
'unique' => false,
'id' => true,
'columnName' => 'id',
]);
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\ORM\Mapping\Shape" inheritance-type="SINGLE_TABLE">
<discriminator-column name="discr" type="string" length="32" />
<discriminator-map>
<discriminator-mapping value="cube" class="Doctrine\Tests\ORM\Mapping\cube" />
</discriminator-map>
<id name="id" type="integer" column="id">
<generator strategy="AUTO" />
</id>
</entity>
</doctrine-mapping>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Doctrine\Tests\ORM\Mapping\Shape:
type: entity
inheritanceType: SINGLE_TABLE
discriminatorMap:
cube: Doctrine\Tests\ORM\Mapping\cube
discriminatorColumn:
type: string
name: discr
length: 32
id:
id:
type: integer
generator:
strategy: AUTO

0 comments on commit cad84ac

Please sign in to comment.