Skip to content

Commit

Permalink
Merge 2.12.x into 2.13.x (#9931)
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus authored Jul 25, 2022
2 parents 2da2870 + 6c64bc6 commit 5085dbe
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 51 deletions.
5 changes: 2 additions & 3 deletions lib/Doctrine/ORM/Internal/Hydration/HydrationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,8 @@ public static function missingDiscriminatorMetaMappingColumn($entityName, $discr
}

/**
* @param string $discrValue
* @param string[] $discrValues
* @psalm-param list<string> $discrValues
* @param string $discrValue
* @param list<int|string> $discrValues
*
* @return HydrationException
*/
Expand Down
12 changes: 5 additions & 7 deletions lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -554,9 +554,9 @@ class ClassMetadataInfo implements ClassMetadata
*
* @see discriminatorColumn
*
* @var array<string, string>
* @var array<int|string, string>
*
* @psalm-var array<string, class-string>
* @psalm-var array<int|string, class-string>
*/
public $discriminatorMap = [];

Expand Down Expand Up @@ -3254,7 +3254,7 @@ final public function getDiscriminatorColumn(): array
* Sets the discriminator values used by this class.
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
*
* @psalm-param array<string, class-string> $map
* @param array<int|string, string> $map
*
* @return void
*/
Expand All @@ -3268,9 +3268,8 @@ public function setDiscriminatorMap(array $map)
/**
* Adds one entry of the discriminator map with a new class and corresponding name.
*
* @param string $name
* @param string $className
* @psalm-param class-string $className
* @param int|string $name
* @param string $className
*
* @return void
*
Expand Down Expand Up @@ -3744,7 +3743,6 @@ public function getAssociationsByTargetClass($targetClass)

/**
* @param string|null $className
* @psalm-param string|class-string|null $className
*
* @return string|null null if the input value is null
* @psalm-return class-string|null
Expand Down
8 changes: 2 additions & 6 deletions lib/Doctrine/ORM/Mapping/DiscriminatorMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@
#[Attribute(Attribute::TARGET_CLASS)]
final class DiscriminatorMap implements Annotation
{
/**
* @var array<string, string>
* @psalm-var array<string, class-string>
*/
/** @var array<int|string, string> */
public $value;

/**
* @param array<string, string> $value
* @psalm-param array<string, class-string> $value
* @param array<int|string, string> $value
*/
public function __construct(array $value)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function exportClassMetadata(ClassMetadataInfo $metadata)

foreach ($metadata->discriminatorMap as $value => $className) {
$discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping');
$discriminatorMappingXml->addAttribute('value', $value);
$discriminatorMappingXml->addAttribute('value', (string) $value);
$discriminatorMappingXml->addAttribute('class', $className);
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Doctrine/ORM/Utility/IdentifierFlattener.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

use function assert;
use function implode;
use function is_object;
use function is_a;

/**
* The IdentifierFlattener utility now houses some of the identifier manipulation logic from unit of work, so that it
Expand Down Expand Up @@ -55,7 +55,7 @@ public function flattenIdentifier(ClassMetadata $class, array $id): array
$flatId = [];

foreach ($class->identifier as $field) {
if (isset($class->associationMappings[$field]) && isset($id[$field]) && is_object($id[$field])) {
if (isset($class->associationMappings[$field]) && isset($id[$field]) && is_a($id[$field], $class->associationMappings[$field]['targetEntity'])) {
$targetClassMetadata = $this->metadataFactory->getMetadataFor(
$class->associationMappings[$field]['targetEntity']
);
Expand Down
6 changes: 2 additions & 4 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,7 @@
</PropertyNotSetInConstructor>
</file>
<file src="lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php">
<ArgumentTypeCoercion occurrences="2">
<code>$class</code>
<ArgumentTypeCoercion occurrences="1">
<code>$repositoryClassName</code>
</ArgumentTypeCoercion>
<DeprecatedMethod occurrences="1">
Expand Down Expand Up @@ -871,8 +870,7 @@
</MissingParamType>
</file>
<file src="lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php">
<ArgumentTypeCoercion occurrences="3">
<code>$map</code>
<ArgumentTypeCoercion occurrences="2">
<code>(string) $xmlRoot['repository-class']</code>
<code>isset($xmlRoot['repository-class']) ? (string) $xmlRoot['repository-class'] : null</code>
</ArgumentTypeCoercion>
Expand Down
219 changes: 219 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/GH9335Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\Tests\OrmFunctionalTestCase;

/**
* @group GH9335
*/
final class GH9335Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();

if (! DBALType::hasType(GH9335IntObjectType::class)) {
DBALType::addType(GH9335IntObjectType::class, GH9335IntObjectType::class);
}

$this->setUpEntitySchema([GH9335Book::class, GH9335Author::class]);
}

/**
* Verifies that entities with foreign keys with custom id object types don't throw an exception
*
* The test passes when refresh() does not throw an exception
*/
public function testFlattenIdentifierWithObjectId(): void
{
$author = new GH9335Author('Douglas Adams');
$book = new GH9335Book(new GH9335IntObject(42), 'The Hitchhiker\'s Guide to the Galaxy', $author);

$this->_em->persist($author);
$this->_em->persist($book);
$this->_em->flush();

$this->_em->refresh($book);

self::assertInstanceOf(GH9335IntObject::class, $book->getId());
}
}


class GH9335IntObjectType extends Type
{
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getIntegerTypeDeclarationSQL($column);
}

public function getName(): string
{
return self::class;
}

public function convertToDatabaseValue($value, AbstractPlatform $platform): int
{
return $value->wrappedInt;
}

public function convertToPHPValue($value, AbstractPlatform $platform): GH9335IntObject
{
return new GH9335IntObject((int) $value);
}

public function getBindingType(): int
{
return ParameterType::INTEGER;
}

public function requiresSQLCommentHint(AbstractPlatform $platform): bool
{
return true;
}
}

class GH9335IntObject
{
/** @var int */
public $wrappedInt;

public function __construct(int $wrappedInt)
{
$this->wrappedInt = $wrappedInt;
}

public function __toString(): string
{
return (string) $this->wrappedInt;
}
}

/**
* @Entity
*/
class GH9335Book
{
/**
* @var GH9335IntObject
* @Id
* @Column(type=GH9335IntObjectType::class, unique=true)
*/
private $id;

/**
* @Column(type="string")
* @var string
*/
private $title;


/**
* @OneToOne(targetEntity="GH9335Author", mappedBy="book", cascade={"persist", "remove"})
* @var GH9335Author
*/
private $author;

public function __construct(GH9335IntObject $id, string $title, ?GH9335Author $author = null)
{
$this->setId($id);
$this->setTitle($title);
$this->setAuthor($author);
}

public function getId(): ?GH9335IntObject
{
return $this->id;
}

public function setId($id): void
{
$this->id = $id;
}

public function getTitle(): ?string
{
return $this->title;
}

public function setTitle($title): void
{
$this->title = $title;
}

public function getAuthor(): ?GH9335Author
{
return $this->author;
}

public function setAuthor(?GH9335Author $author): self
{
$this->author = $author;

// set the owning side of the relation
if ($author) {
$author->setBook($this);
}

return $this;
}
}

/**
* @Entity
*/
class GH9335Author
{
/**
* @var GH9335Book
* @Id
* @OneToOne(targetEntity="GH9335Book", inversedBy="author")
* @JoinColumn(name="book")
*/
private $book;

/**
* @Column(type="string", nullable="true" )
* @var string
*/
private $name;

public function __construct(?string $name)
{
$this->setName($name);
}

public function getBook(): ?GH9335Book
{
return $this->book;
}

public function setBook(GH9335Book $book): self
{
$this->book = $book;

return $this;
}

public function getName(): string
{
return $this->name;
}

public function setName(string $name): void
{
$this->name = $name;
}
}
Loading

0 comments on commit 5085dbe

Please sign in to comment.