Skip to content

Commit 1cf3827

Browse files
authored
Merge pull request #6201 from soyuka/merge-main
Merge 3.2
2 parents 6d6f856 + 655c4cf commit 1cf3827

31 files changed

+532
-325
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ These namespaces are deprecated:
5656

5757
Most of the classes have moved to `ApiPlatform\Metadata`.
5858

59+
## v3.2.15
60+
61+
### Bug fixes
62+
63+
* [09aacf98a](https://github.com/api-platform/core/commit/09aacf98a2e4d0ffa00fbefa59cb2b31f35fbb54) fix(symfony): revert breaking change on attributes extractor (#6170)
64+
* [4138cb7c0](https://github.com/api-platform/core/commit/4138cb7c031b38731162d99b3d43754251fc5913) fix(openapi): resource name parameter description (#6178)
65+
* [5e4b6312a](https://github.com/api-platform/core/commit/5e4b6312a057ba4d1f45c395c7a215dc393acd80) fix(jsonschema): multiple type support (draft4) (#6171)
66+
* [8535f9def](https://github.com/api-platform/core/commit/8535f9def6fbd2baff9cedc79c34103940eb4fca) fix(doctrine): read parent class properties on PUT (#6176)
67+
* [a188c9473](https://github.com/api-platform/core/commit/a188c947396e0400ba6e1aadaa262d2e785fd941) fix(symfony): autoconfigure legacy alias fixes #6177 (#6181)
68+
* [e7b442149](https://github.com/api-platform/core/commit/e7b4421496b58f7c3db414d11dd357a8dc759323) fix(validator): stop considering properties marked with NotBlank(allowNull=true) as required (#6184)
69+
>>>>>>> upstream/3.2
70+
5971
## v3.2.14
6072

6173
### Bug fixes

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"doctrine/doctrine-bundle": "^1.12 || ^2.0",
4848
"doctrine/mongodb-odm": "^2.2",
4949
"doctrine/mongodb-odm-bundle": "^4.0 || ^5.0",
50-
"doctrine/orm": "^2.14",
50+
"doctrine/orm": "^2.14 || ^3.0",
5151
"elasticsearch/elasticsearch": "^7.11 || ^8.4",
5252
"friends-of-behat/mink-browserkit-driver": "^1.3.1",
5353
"friends-of-behat/mink-extension": "^2.2",

src/Doctrine/Common/Tests/State/PersistProcessorTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use ApiPlatform\Metadata\Get;
1919
use ApiPlatform\State\ProcessorInterface;
2020
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
21-
use Doctrine\ORM\Mapping\ClassMetadataInfo;
21+
use Doctrine\ORM\Mapping\ClassMetadata as ORMClassMetadata;
2222
use Doctrine\Persistence\ManagerRegistry;
2323
use Doctrine\Persistence\ObjectManager;
2424
use PHPUnit\Framework\TestCase;
@@ -84,8 +84,8 @@ public function testPersistWithNullManager(): void
8484
public static function getTrackingPolicyParameters(): array
8585
{
8686
return [
87-
'deferred explicit ORM' => [ClassMetadataInfo::class, true, true],
88-
'deferred implicit ORM' => [ClassMetadataInfo::class, false, false],
87+
'deferred explicit ORM' => [ORMClassMetadata::class, true, true],
88+
'deferred implicit ORM' => [ORMClassMetadata::class, false, false],
8989
'deferred explicit ODM' => [ClassMetadata::class, true, true],
9090
'deferred implicit ODM' => [ClassMetadata::class, false, false],
9191
];
@@ -98,15 +98,15 @@ public function testTrackingPolicy(string $metadataClass, bool $deferredExplicit
9898
{
9999
$dummy = new Dummy();
100100

101-
$classMetadataInfo = $this->prophesize($metadataClass);
101+
$classMetadata = $this->prophesize($metadataClass);
102102
if (method_exists($metadataClass, 'isChangeTrackingDeferredExplicit')) {
103-
$classMetadataInfo->isChangeTrackingDeferredExplicit()->willReturn($deferredExplicit)->shouldBeCalled();
103+
$classMetadata->isChangeTrackingDeferredExplicit()->willReturn($deferredExplicit)->shouldBeCalled();
104104
} else {
105105
$persisted = false;
106106
}
107107

108108
$objectManagerProphecy = $this->prophesize(ObjectManager::class);
109-
$objectManagerProphecy->getClassMetadata(Dummy::class)->willReturn($classMetadataInfo)->shouldBeCalled();
109+
$objectManagerProphecy->getClassMetadata(Dummy::class)->willReturn($classMetadata)->shouldBeCalled();
110110
$objectManagerProphecy->contains($dummy)->willReturn(true);
111111
$objectManagerProphecy->persist($dummy)->should($persisted ? new CallPrediction() : new NoCallsPrediction());
112112
$objectManagerProphecy->flush()->shouldBeCalled();

src/Doctrine/Common/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
},
3232
"require-dev": {
3333
"doctrine/mongodb-odm": "^2.6",
34-
"doctrine/orm": "^2.17",
34+
"doctrine/orm": "^2.17 || ^3.0",
3535
"phpspec/prophecy-phpunit": "^2.0",
3636
"phpunit/phpunit": "^10.0",
3737
"symfony/phpunit-bridge": "^6.4 || ^7.0"

src/Doctrine/EventListener/PublishMercureUpdatesListener.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public function __construct(LegacyResourceClassResolverInterface|ResourceClassRe
103103
public function onFlush(EventArgs $eventArgs): void
104104
{
105105
if ($eventArgs instanceof OrmOnFlushEventArgs) {
106+
// @phpstan-ignore-next-line
106107
$uow = method_exists($eventArgs, 'getObjectManager') ? $eventArgs->getObjectManager()->getUnitOfWork() : $eventArgs->getEntityManager()->getUnitOfWork();
107108
} elseif ($eventArgs instanceof MongoDbOdmOnFlushEventArgs) {
108109
$uow = $eventArgs->getDocumentManager()->getUnitOfWork();

src/Doctrine/EventListener/PurgeHttpCacheListener.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Doctrine\ORM\EntityManagerInterface;
2929
use Doctrine\ORM\Event\OnFlushEventArgs;
3030
use Doctrine\ORM\Event\PreUpdateEventArgs;
31+
use Doctrine\ORM\Mapping\AssociationMapping;
3132
use Doctrine\ORM\PersistentCollection;
3233
use Symfony\Component\PropertyAccess\PropertyAccess;
3334
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
@@ -57,6 +58,7 @@ public function preUpdate(PreUpdateEventArgs $eventArgs): void
5758
$this->gatherResourceAndItemTags($object, true);
5859

5960
$changeSet = $eventArgs->getEntityChangeSet();
61+
// @phpstan-ignore-next-line
6062
$objectManager = method_exists($eventArgs, 'getObjectManager') ? $eventArgs->getObjectManager() : $eventArgs->getEntityManager();
6163
$associationMappings = $objectManager->getClassMetadata(ClassUtils::getClass($eventArgs->getObject()))->getAssociationMappings();
6264

@@ -75,6 +77,7 @@ public function preUpdate(PreUpdateEventArgs $eventArgs): void
7577
*/
7678
public function onFlush(OnFlushEventArgs $eventArgs): void
7779
{
80+
// @phpstan-ignore-next-line
7881
$em = method_exists($eventArgs, 'getObjectManager') ? $eventArgs->getObjectManager() : $eventArgs->getEntityManager();
7982
$uow = $em->getUnitOfWork();
8083

@@ -125,12 +128,19 @@ private function gatherResourceAndItemTags(object $entity, bool $purgeItem): voi
125128
private function gatherRelationTags(EntityManagerInterface $em, object $entity): void
126129
{
127130
$associationMappings = $em->getClassMetadata(ClassUtils::getClass($entity))->getAssociationMappings();
128-
foreach (array_keys($associationMappings) as $property) {
131+
/** @var array|AssociationMapping $associationMapping according to the version of doctrine orm */
132+
foreach ($associationMappings as $property => $associationMapping) {
133+
if ($associationMapping instanceof AssociationMapping && ($associationMapping->targetEntity ?? null) && !$this->resourceClassResolver->isResourceClass($associationMapping->targetEntity)) {
134+
return;
135+
}
136+
129137
if (
130-
\array_key_exists('targetEntity', $associationMappings[$property])
131-
&& !$this->resourceClassResolver->isResourceClass($associationMappings[$property]['targetEntity'])) {
138+
\is_array($associationMapping)
139+
&& \array_key_exists('targetEntity', $associationMapping)
140+
&& !$this->resourceClassResolver->isResourceClass($associationMapping['targetEntity'])) {
132141
return;
133142
}
143+
134144
if ($this->propertyAccessor->isReadable($entity, $property)) {
135145
$this->addTagsFor($this->propertyAccessor->getValue($entity, $property));
136146
}

src/Doctrine/Orm/AbstractPaginator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function __construct(DoctrinePaginator $paginator)
3232
{
3333
$query = $paginator->getQuery();
3434

35-
if (null === ($firstResult = $query->getFirstResult()) || null === $maxResults = $query->getMaxResults()) { // @phpstan-ignore-line
35+
if (null === ($firstResult = $query->getFirstResult()) || $firstResult < 0 || null === $maxResults = $query->getMaxResults()) { // @phpstan-ignore-line
3636
throw new InvalidArgumentException(sprintf('"%1$s::setFirstResult()" or/and "%1$s::setMaxResults()" was/were not applied to the query.', Query::class));
3737
}
3838

src/Doctrine/Orm/Extension/EagerLoadingExtension.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2424
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2525
use Doctrine\ORM\Mapping\ClassMetadata;
26-
use Doctrine\ORM\Mapping\ClassMetadataInfo;
2726
use Doctrine\ORM\Query\Expr\Join;
2827
use Doctrine\ORM\Query\Expr\Select;
2928
use Doctrine\ORM\QueryBuilder;
@@ -137,9 +136,9 @@ private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInt
137136

138137
if (
139138
// Always skip extra lazy associations
140-
ClassMetadataInfo::FETCH_EXTRA_LAZY === $mapping['fetch']
139+
ClassMetadata::FETCH_EXTRA_LAZY === $mapping['fetch']
141140
// We don't want to interfere with doctrine on this association
142-
|| (false === $forceEager && ClassMetadataInfo::FETCH_EAGER !== $mapping['fetch'])
141+
|| (false === $forceEager && ClassMetadata::FETCH_EAGER !== $mapping['fetch'])
143142
) {
144143
continue;
145144
}

src/Doctrine/Orm/Extension/FilterEagerLoadingExtension.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use ApiPlatform\Metadata\Operation;
2020
use ApiPlatform\Metadata\ResourceClassResolverInterface;
2121
use Doctrine\ORM\EntityManagerInterface;
22-
use Doctrine\ORM\Mapping\ClassMetadataInfo;
22+
use Doctrine\ORM\Mapping\ClassMetadata;
2323
use Doctrine\ORM\Query\Expr\Join;
2424
use Doctrine\ORM\QueryBuilder;
2525

@@ -111,12 +111,12 @@ public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGenerator
111111
*
112112
* @param array $checked array cache of tested metadata classes
113113
*/
114-
private function hasFetchEagerAssociation(EntityManagerInterface $em, ClassMetadataInfo $classMetadata, array &$checked = []): bool
114+
private function hasFetchEagerAssociation(EntityManagerInterface $em, ClassMetadata $classMetadata, array &$checked = []): bool
115115
{
116116
$checked[] = $classMetadata->name;
117117

118118
foreach ($classMetadata->getAssociationMappings() as $mapping) {
119-
if (ClassMetadataInfo::FETCH_EAGER === $mapping['fetch']) {
119+
if (ClassMetadata::FETCH_EAGER === $mapping['fetch']) {
120120
return true;
121121
}
122122

src/Doctrine/Orm/Filter/ExistsFilter.php

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
use ApiPlatform\Doctrine\Orm\Util\QueryBuilderHelper;
1919
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
2020
use ApiPlatform\Metadata\Operation;
21-
use Doctrine\ORM\Mapping\ClassMetadataInfo;
21+
use Doctrine\ORM\Mapping\AssociationMapping;
22+
use Doctrine\ORM\Mapping\ClassMetadata;
23+
use Doctrine\ORM\Mapping\ManyToManyOwningSideMapping;
24+
use Doctrine\ORM\Mapping\ToOneOwningSideMapping;
2225
use Doctrine\ORM\Query\Expr\Join;
2326
use Doctrine\ORM\QueryBuilder;
2427
use Doctrine\Persistence\ManagerRegistry;
@@ -199,7 +202,7 @@ protected function isNullableField(string $property, string $resourceClass): boo
199202

200203
if ($metadata->hasAssociation($field)) {
201204
if ($metadata->isSingleValuedAssociation($field)) {
202-
if (!($metadata instanceof ClassMetadataInfo)) {
205+
if (!($metadata instanceof ClassMetadata)) {
203206
return false;
204207
}
205208

@@ -211,7 +214,7 @@ protected function isNullableField(string $property, string $resourceClass): boo
211214
return true;
212215
}
213216

214-
if ($metadata instanceof ClassMetadataInfo && $metadata->hasField($field)) {
217+
if ($metadata instanceof ClassMetadata && $metadata->hasField($field)) {
215218
return $metadata->isNullable($field);
216219
}
217220

@@ -223,8 +226,26 @@ protected function isNullableField(string $property, string $resourceClass): boo
223226
*
224227
* @see https://github.com/doctrine/doctrine2/blob/v2.5.4/lib/Doctrine/ORM/Tools/EntityGenerator.php#L1221-L1246
225228
*/
226-
private function isAssociationNullable(array $associationMapping): bool
229+
private function isAssociationNullable(AssociationMapping|array $associationMapping): bool
227230
{
231+
if ($associationMapping instanceof AssociationMapping) {
232+
if (!empty($associationMapping->id)) {
233+
return false;
234+
}
235+
236+
if ($associationMapping instanceof ToOneOwningSideMapping || $associationMapping instanceof ManyToManyOwningSideMapping) {
237+
foreach ($associationMapping->joinColumns as $joinColumn) {
238+
if (false === $joinColumn->nullable) {
239+
return false;
240+
}
241+
}
242+
243+
return true;
244+
}
245+
246+
return true;
247+
}
248+
228249
if (!empty($associationMapping['id'])) {
229250
return false;
230251
}

0 commit comments

Comments
 (0)