Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge release 2.19.1 into 2.20.x #11360

Merged
merged 8 commits into from
Mar 16, 2024
5 changes: 5 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,10 @@ jobs:
with:
dependency-versions: "highest"

- name: "Add orphan metadata where needed"
run: |
printf '%s\n\n%s\n' ":orphan:" "$(cat docs/en/sidebar.rst)" > docs/en/sidebar.rst
printf '%s\n\n%s\n' ":orphan:" "$(cat docs/en/reference/installation.rst)" > docs/en/reference/installation.rst

- name: "Run guides-cli"
run: "vendor/bin/guides -vvv --no-progress docs/en 2>&1 | grep -v 'No template found for rendering directive' | ( ! grep WARNING )"
2 changes: 0 additions & 2 deletions docs/en/reference/installation.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
:orphan:

Installation
============

Expand Down
2 changes: 0 additions & 2 deletions docs/en/sidebar.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
:orphan:

.. toc::

.. tocheader:: Tutorials
Expand Down
14 changes: 13 additions & 1 deletion src/UnitOfWork.php
Original file line number Diff line number Diff line change
Expand Up @@ -3249,7 +3249,19 @@ private function eagerLoadCollections(array $collections, array $mapping): void
foreach ($found as $targetValue) {
$sourceEntity = $targetProperty->getValue($targetValue);

$id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity));
if ($sourceEntity === null && isset($targetClass->associationMappings[$mappedBy]['joinColumns'])) {
// case where the hydration $targetValue itself has not yet fully completed, for example
// in case a bi-directional association is being hydrated and deferring eager loading is
// not possible due to subclassing.
$data = $this->getOriginalEntityData($targetValue);
$id = [];
foreach ($targetClass->associationMappings[$mappedBy]['joinColumns'] as $joinColumn) {
$id[] = $data[$joinColumn['name']];
}
} else {
$id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity));
}

$idHash = implode(' ', $id);

if (isset($mapping['indexBy'])) {
Expand Down
50 changes: 50 additions & 0 deletions tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Models\AbstractFetchEager;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity()
* @ORM\Table(name="abstract_fetch_eager_remote_control")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"mobile"="MobileRemoteControl"})
*/
abstract class AbstractRemoteControl
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @var int
*/
public $id;

/**
* /**
*
* @ORM\Column(type="string")
*
* @var string
*/
public $name;

/**
* @ORM\OneToMany(targetEntity="User", mappedBy="remoteControl", fetch="EAGER")
*
* @var Collection<User>
*/
public $users;

public function __construct(string $name)
{
$this->name = $name;
$this->users = new ArrayCollection();
}
}
14 changes: 14 additions & 0 deletions tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Models\AbstractFetchEager;

use Doctrine\ORM\Mapping as ORM;

/**

Check failure on line 9 in tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.2)

Found multi-line doc comment with single line content, use one-line doc comment instead.
* @ORM\Entity()
*/
class MobileRemoteControl extends AbstractRemoteControl
{
}
36 changes: 36 additions & 0 deletions tests/Tests/Models/AbstractFetchEager/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Models\AbstractFetchEager;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity()
* @ORM\Table(name="abstract_fetch_eager_user")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @var int
*/
public $id;

/**
* @ORM\ManyToOne(targetEntity="AbstractRemoteControl", inversedBy="users")
* @ORM\JoinColumn(nullable=false)
*
* @var AbstractRemoteControl
*/
public $remoteControl;

public function __construct(AbstractRemoteControl $control)
{
$this->remoteControl = $control;
}
}
37 changes: 37 additions & 0 deletions tests/Tests/ORM/Functional/AbstractFetchEagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional;

use Doctrine\Tests\Models\AbstractFetchEager\AbstractRemoteControl;
use Doctrine\Tests\Models\AbstractFetchEager\MobileRemoteControl;
use Doctrine\Tests\Models\AbstractFetchEager\User;
use Doctrine\Tests\OrmFunctionalTestCase;

final class AbstractFetchEagerTest extends OrmFunctionalTestCase
{
public function testWithAbstractFetchEager(): void
{
$this->createSchemaForModels(
AbstractRemoteControl::class,
User::class

Check failure on line 18 in tests/Tests/ORM/Functional/AbstractFetchEagerTest.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.2)

Multi-line function calls must have a trailing comma after the last parameter.
);

$control = new MobileRemoteControl('smart');
$user = new User($control);

$entityManage = $this->getEntityManager();

$entityManage->persist($control);
$entityManage->persist($user);
$entityManage->flush();
$entityManage->clear();

$user = $entityManage->find(User::class, $user->id);

self::assertNotNull($user);
self::assertEquals('smart', $user->remoteControl->name);
self::assertTrue($user->remoteControl->users->contains($user));
}
}
Loading