Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: api-platform/core
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v4.0.19
Choose a base ref
...
head repository: api-platform/core
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v4.0.20
Choose a head ref
  • 4 commits
  • 5 files changed
  • 4 contributors

Commits on Mar 7, 2025

  1. fix(doctrine): Add a proper exception when a doctrine manager could n…

    …ot be found for a resource class (#6995)
    
    * fix(doctrine): Add a proper exception when a doctrine manager could not be found for a resource class
    
    * Update ItemProvider.php
    
    ---------
    
    Co-authored-by: Antoine Bluchet <soyuka@users.noreply.github.com>
    lyrixx and soyuka authored Mar 7, 2025
    Copy the full SHA
    a434173 View commit details

Commits on Mar 8, 2025

  1. fix(doctrine): mapping ArrayAccess deprecation (#6982)

    * fix: Doctrine mapping ArrayAccess deprecation
    
    * fix tests
    
    ---------
    
    Co-authored-by: soyuka <soyuka@users.noreply.github.com>
    dunglas and soyuka authored Mar 8, 2025
    Copy the full SHA
    2849370 View commit details

Commits on Mar 12, 2025

  1. doc: comment typo in ApiResource.php

    Bartheyrman22 authored Mar 12, 2025
    Copy the full SHA
    7442b83 View commit details

Commits on Mar 14, 2025

  1. docs: changelog 4.0.20

    soyuka committed Mar 14, 2025
    Copy the full SHA
    1aa5017 View commit details
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## v4.0.20

### Bug fixes

* [284937039](https://github.com/api-platform/core/commit/284937039c61d4516687c648f4a7581ec1686f3d) fix(doctrine): mapping ArrayAccess deprecation (#6982)
* [a434173b8](https://github.com/api-platform/core/commit/a434173b82f735041a79cb5f469ee0e731ca5956) fix(doctrine): Add a proper exception when a doctrine manager could not be found for a resource class (#6995)


### Features

## v4.0.19

### Bug fixes
@@ -3016,4 +3026,4 @@ Please read #2825 if you have issues with the behavior of Readable/Writable Link
## 1.0.0 beta 2

* Preserve indexes when normalizing and denormalizing associative arrays
* Allow setting default order for property when registering a `Doctrine\Orm\Filter\OrderFilter` instance
* Allow setting default order for property when registering a `Doctrine\Orm\Filter\OrderFilter` instance
2 changes: 1 addition & 1 deletion src/Doctrine/Orm/Extension/EagerLoadingExtension.php
Original file line number Diff line number Diff line change
@@ -181,7 +181,7 @@ private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInt
$associationAlias = $existingJoin->getAlias();
$isLeftJoin = Join::LEFT_JOIN === $existingJoin->getJoinType();
} else {
$isNullable = $mapping['joinColumns'][0]['nullable'] ?? true;
$isNullable = $mapping['joinColumns'][0]?->nullable ?? true;
$isLeftJoin = false !== $wasLeftJoin || true === $isNullable;
$method = $isLeftJoin ? 'leftJoin' : 'innerJoin';

5 changes: 4 additions & 1 deletion src/Doctrine/Orm/State/ItemProvider.php
Original file line number Diff line number Diff line change
@@ -53,8 +53,11 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
$entityClass = $options->getEntityClass();
}

/** @var EntityManagerInterface $manager */
/** @var EntityManagerInterface|null $manager */
$manager = $this->managerRegistry->getManagerForClass($entityClass);
if (null === $manager) {
throw new RuntimeException(\sprintf('No manager found for class "%s". Are you sure it\'s an entity?', $entityClass));
}

$fetchData = $context['fetch_data'] ?? true;
if (!$fetchData && \array_key_exists('id', $uriVariables)) {
33 changes: 17 additions & 16 deletions src/Doctrine/Orm/Tests/Extension/EagerLoadingExtensionTest.php
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@
use ApiPlatform\Metadata\Property\PropertyNameCollection;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use PHPUnit\Framework\TestCase;
@@ -94,8 +95,8 @@ public function testApplyToCollection(): void

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => true]], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => RelatedDummy::class],
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: true)], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => RelatedDummy::class],
];

$relatedClassMetadataProphecy = $this->prophesize(ClassMetadata::class);
@@ -181,9 +182,9 @@ public function testApplyToItem(): void

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => true]], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => UnknownDummy::class],
'relatedDummy3' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinTable' => ['joinColumns' => [['nullable' => false]]], 'targetEntity' => UnknownDummy::class],
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: true)], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => UnknownDummy::class],
'relatedDummy3' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinTable' => ['joinColumns' => [new JoinColumn(nullable: false)]], 'targetEntity' => UnknownDummy::class],
'relatedDummy4' => ['fetch' => ClassMetadata::FETCH_EAGER, 'targetEntity' => UnknownDummy::class],
'relatedDummy5' => ['fetch' => ClassMetadata::FETCH_LAZY, 'targetEntity' => UnknownDummy::class],
'singleInheritanceRelation' => ['fetch' => ClassMetadata::FETCH_EAGER, 'targetEntity' => AbstractDummy::class],
@@ -200,7 +201,7 @@ public function testApplyToItem(): void
$relatedClassMetadataProphecy->hasField('embeddedDummy.name')->willReturn(true)->shouldBeCalled();

$relatedClassMetadataProphecy->associationMappings = [
'relation' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => UnknownDummy::class],
'relation' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => UnknownDummy::class],
'thirdLevel' => ['fetch' => ClassMetadata::FETCH_EAGER, 'targetEntity' => ThirdLevel::class, 'sourceEntity' => RelatedDummy::class, 'inversedBy' => 'relatedDummies', 'type' => ClassMetadata::TO_ONE],
];

@@ -361,13 +362,13 @@ public function testMaxJoinsReached(): void

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => RelatedDummy::class],
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => RelatedDummy::class],
];
$classMetadataProphecy->hasField('relatedDummy')->willReturn(true);

$relatedClassMetadataProphecy = $this->prophesize(ClassMetadata::class);
$relatedClassMetadataProphecy->associationMappings = [
'dummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => Dummy::class],
'dummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => Dummy::class],
];
$relatedClassMetadataProphecy->hasField('dummy')->willReturn(true);

@@ -410,13 +411,13 @@ public function testMaxDepth(): void

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => RelatedDummy::class],
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => RelatedDummy::class],
];
$classMetadataProphecy->hasField('relatedDummy')->willReturn(true);

$relatedClassMetadataProphecy = $this->prophesize(ClassMetadata::class);
$relatedClassMetadataProphecy->associationMappings = [
'dummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => Dummy::class],
'dummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => Dummy::class],
];
$relatedClassMetadataProphecy->hasField('dummy')->willReturn(true);

@@ -471,7 +472,7 @@ public function testForceEager(): void

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relation' => ['fetch' => ClassMetadata::FETCH_LAZY, 'targetEntity' => UnknownDummy::class, 'joinColumns' => [['nullable' => false]]],
'relation' => ['fetch' => ClassMetadata::FETCH_LAZY, 'targetEntity' => UnknownDummy::class, 'joinColumns' => [new JoinColumn(nullable: false)]],
];

$unknownClassMetadataProphecy = $this->prophesize(ClassMetadata::class);
@@ -577,7 +578,7 @@ public function testResourceClassNotFoundExceptionPropertyNameCollection(): void

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relation' => ['fetch' => ClassMetadata::FETCH_LAZY, 'targetEntity' => UnknownDummy::class, 'joinColumns' => [['nullable' => false]]],
'relation' => ['fetch' => ClassMetadata::FETCH_LAZY, 'targetEntity' => UnknownDummy::class, 'joinColumns' => [new JoinColumn(nullable: false)]],
];
$emProphecy = $this->prophesize(EntityManager::class);
$emProphecy->getClassMetadata(Dummy::class)->shouldBeCalled()->willReturn($classMetadataProphecy->reveal());
@@ -751,8 +752,8 @@ public function testApplyToCollectionNoPartial(): void

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => true]], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => RelatedDummy::class],
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: true)], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => RelatedDummy::class],
];

$emProphecy = $this->prophesize(EntityManager::class);
@@ -796,8 +797,8 @@ public function testApplyToCollectionWithANonReadableButFetchEagerProperty(): vo

$classMetadataProphecy = $this->prophesize(ClassMetadata::class);
$classMetadataProphecy->associationMappings = [
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => true]], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [['nullable' => false]], 'targetEntity' => RelatedDummy::class],
'relatedDummy' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: true)], 'targetEntity' => RelatedDummy::class],
'relatedDummy2' => ['fetch' => ClassMetadata::FETCH_EAGER, 'joinColumns' => [new JoinColumn(nullable: false)], 'targetEntity' => RelatedDummy::class],
];

$emProphecy = $this->prophesize(EntityManager::class);
2 changes: 1 addition & 1 deletion src/Metadata/ApiResource.php
Original file line number Diff line number Diff line change
@@ -142,7 +142,7 @@ public function __construct(
* #[ApiResource(
* uriTemplate: '/companies/{companyId}/employees/{id}',
* uriVariables: [
* 'companyId' => new Link(fromClass: Company::class, toProperty: 'company']),
* 'companyId' => new Link(fromClass: Company::class, toProperty: 'company'),
* 'id' => new Link(fromClass: Employee::class)
* ],
* operations: [new Get()]