diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index 1950446e7..423ed3b53 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -45,6 +45,8 @@ use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; */ class SchemaTool { + private const KNOWN_COLUMN_OPTIONS = ['comment', 'unsigned', 'fixed', 'default']; + /** * @var \Doctrine\ORM\EntityManagerInterface */ @@ -467,19 +469,8 @@ class SchemaTool $options['columnDefinition'] = $mapping['columnDefinition']; } - if (isset($mapping['options'])) { - $knownOptions = ['comment', 'unsigned', 'fixed', 'default']; - - foreach ($knownOptions as $knownOption) { - if (array_key_exists($knownOption, $mapping['options'])) { - $options[$knownOption] = $mapping['options'][$knownOption]; - - unset($mapping['options'][$knownOption]); - } - } - - $options['customSchemaOptions'] = $mapping['options']; - } + // the 'default' option can be overwritten here + $options = $this->gatherColumnOptions($mapping) + $options; if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == [$mapping['fieldName']]) { $options['autoincrement'] = true; @@ -690,9 +681,7 @@ class SchemaTool $columnOptions['notnull'] = ! $joinColumn['nullable']; } - if (isset($fieldMapping['options'])) { - $columnOptions['options'] = $fieldMapping['options']; - } + $columnOptions = $columnOptions + $this->gatherColumnOptions($fieldMapping); if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) { $columnOptions['length'] = $fieldMapping['length']; @@ -745,6 +734,23 @@ class SchemaTool } } + /** + * @param mixed[] $mapping + * + * @return mixed[] + */ + private function gatherColumnOptions(array $mapping) : array + { + if (! isset($mapping['options'])) { + return []; + } + + $options = array_intersect_key($mapping['options'], array_flip(self::KNOWN_COLUMN_OPTIONS)); + $options['customSchemaOptions'] = array_diff_key($mapping['options'], $options); + + return $options; + } + /** * Drops the database schema for the given classes. * diff --git a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php index 6750442e8..ea520d8fc 100644 --- a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php @@ -18,6 +18,8 @@ use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedChildClass; use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedIdentityClass; use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedRootClass; use Doctrine\Tests\Models\Forum\ForumAvatar; +use Doctrine\Tests\Models\Forum\ForumBoard; +use Doctrine\Tests\Models\Forum\ForumCategory; use Doctrine\Tests\Models\Forum\ForumUser; use Doctrine\Tests\Models\NullDefault\NullDefaultColumn; use Doctrine\Tests\OrmTestCase; @@ -86,6 +88,44 @@ class SchemaToolTest extends OrmTestCase $this->assertEquals($customColumnDef, $table->getColumn('avatar_id')->getColumnDefinition()); } + /** + * @group 6830 + */ + public function testPassColumnOptionsToJoinColumn() : void + { + $em = $this->_getTestEntityManager(); + $category = $em->getClassMetadata(GH6830Category::class); + $board = $em->getClassMetadata(GH6830Board::class); + + $schemaTool = new SchemaTool($em); + $schema = $schemaTool->getSchemaFromMetadata([$category, $board]); + + self::assertTrue($schema->hasTable('GH6830Category')); + self::assertTrue($schema->hasTable('GH6830Board')); + + $tableCategory = $schema->getTable('GH6830Category'); + $tableBoard = $schema->getTable('GH6830Board'); + + self::assertTrue($tableBoard->hasColumn('category_id')); + + self::assertSame( + $tableCategory->getColumn('id')->getFixed(), + $tableBoard->getColumn('category_id')->getFixed(), + 'Foreign key/join column should have the same value of option `fixed` as the referenced column' + ); + + self::assertEquals( + $tableCategory->getColumn('id')->getCustomSchemaOptions(), + $tableBoard->getColumn('category_id')->getCustomSchemaOptions(), + 'Foreign key/join column should have the same custom options as the referenced column' + ); + + self::assertEquals( + ['collation' => 'latin1_bin', 'foo' => 'bar'], + $tableBoard->getColumn('category_id')->getCustomSchemaOptions() + ); + } + /** * @group DDC-283 */ @@ -322,3 +362,40 @@ class SecondEntity */ public $name; } + +/** + * @Entity + */ +class GH6830Board +{ + /** + * @Id + * @Column(type="integer") + */ + public $id; + + /** + * @ManyToOne(targetEntity=GH6830Category::class, inversedBy="boards") + * @JoinColumn(name="category_id", referencedColumnName="id") + */ + public $category; +} + +/** + * @Entity + */ +class GH6830Category +{ + /** + * @Id + * @Column(type="string", length=8, options={"fixed":true, "collation":"latin1_bin", "foo":"bar"}) + * + * @var string + */ + public $id; + + /** + * @OneToMany(targetEntity=GH6830Board::class, mappedBy="category") + */ + public $boards; +}