Skip to content

Commit

Permalink
Merge pull request #11363 from greg0ire/3.1.x
Browse files Browse the repository at this point in the history
Merge 2.19.x up into 3.1.x
  • Loading branch information
greg0ire authored Mar 16, 2024
2 parents 716fc97 + 196d3a6 commit b0d07ff
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 5 deletions.
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 @@ -2662,7 +2662,19 @@ private function eagerLoadCollections(array $collections, ToManyInverseSideMappi
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 ($mapping->indexBy !== null) {
Expand Down
35 changes: 35 additions & 0 deletions tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?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')]
public int $id;

#[ORM\Column(type: 'string')]
public string $name;

/** @var Collection<User> */
#[ORM\OneToMany(targetEntity: User::class, mappedBy: 'remoteControl', fetch: 'EAGER')]
public Collection $users;

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

declare(strict_types=1);

namespace Doctrine\Tests\Models\AbstractFetchEager;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class MobileRemoteControl extends AbstractRemoteControl
{
}
26 changes: 26 additions & 0 deletions tests/Tests/Models/AbstractFetchEager/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?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')]
public int $id;

#[ORM\ManyToOne(targetEntity: AbstractRemoteControl::class, inversedBy: 'users')]
#[ORM\JoinColumn(nullable: false)]
public AbstractRemoteControl $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,
);

$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));
}
}

0 comments on commit b0d07ff

Please sign in to comment.