Skip to content

Commit 611df04

Browse files
authored
chore(v3): remove ORM v2 code (#1097)
1 parent 222650c commit 611df04

12 files changed

+80
-311
lines changed

config/makers.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
1515
use Zenstruck\Foundry\Maker\Factory\FactoryCandidatesClassesExtractor;
1616
use Zenstruck\Foundry\Maker\Factory\FactoryClassMap;
1717
use Zenstruck\Foundry\Maker\Factory\FactoryGenerator;
18-
use Zenstruck\Foundry\Maker\Factory\LegacyORMDefaultPropertiesGuesser;
1918
use Zenstruck\Foundry\Maker\Factory\NoPersistenceObjectsAutoCompleter;
2019
use Zenstruck\Foundry\Maker\Factory\ObjectDefaultPropertiesGuesser;
2120
use Zenstruck\Foundry\Maker\Factory\ODMDefaultPropertiesGuesser;
2221
use Zenstruck\Foundry\Maker\Factory\ORMDefaultPropertiesGuesser;
2322
use Zenstruck\Foundry\Maker\MakeFactory;
2423
use Zenstruck\Foundry\Maker\MakeStory;
2524
use Zenstruck\Foundry\Maker\NamespaceGuesser;
26-
use Zenstruck\Foundry\ORM\DoctrineOrmVersionGuesser;
2725

2826
return static function(ContainerConfigurator $container): void {
2927
$container->services()
@@ -42,7 +40,7 @@
4240
])
4341
->tag('maker.command')
4442

45-
->set('.zenstruck_foundry.maker.factory.orm_default_properties_guesser', DoctrineOrmVersionGuesser::isOrmV3() ? ORMDefaultPropertiesGuesser::class : LegacyORMDefaultPropertiesGuesser::class)
43+
->set('.zenstruck_foundry.maker.factory.orm_default_properties_guesser', ORMDefaultPropertiesGuesser::class)
4644
->args([
4745
service('.zenstruck_foundry.persistence_manager')->nullOnInvalid(),
4846
service('.zenstruck_foundry.maker.factory.factory_class_map'),

config/orm.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,14 @@
1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

1414
use DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver;
15-
use Zenstruck\Foundry\ORM\DoctrineOrmVersionGuesser;
16-
use Zenstruck\Foundry\ORM\OrmV2PersistenceStrategy;
17-
use Zenstruck\Foundry\ORM\OrmV3PersistenceStrategy;
15+
use Zenstruck\Foundry\ORM\ORMPersistenceStrategy;
1816
use Zenstruck\Foundry\ORM\ResetDatabase\BaseOrmResetter;
1917
use Zenstruck\Foundry\ORM\ResetDatabase\DamaDatabaseResetter;
2018
use Zenstruck\Foundry\ORM\ResetDatabase\OrmResetter;
2119

2220
return static function(ContainerConfigurator $container): void {
2321
$container->services()
24-
->set('.zenstruck_foundry.persistence_strategy.orm', DoctrineOrmVersionGuesser::isOrmV3() ? OrmV3PersistenceStrategy::class : OrmV2PersistenceStrategy::class)
22+
->set('.zenstruck_foundry.persistence_strategy.orm', ORMPersistenceStrategy::class)
2523
->args([
2624
service('doctrine'),
2725
])

phpstan.neon

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,5 @@ parameters:
6363
- tests/Fixture/Maker/expected/can_create_factory_with_embeddable_odm.php
6464
- tests/Fixture/Maker/expected/can_create_factory_with_embeddable_orm.php
6565

66-
# phpstan runs with orm 3 - there are too many failures in these files which are compatible with orm 2
67-
- ./src/Maker/Factory/LegacyORMDefaultPropertiesGuesser.php
66+
# dual ORM/ODM FieldMapping type in this file requires exclusion
6867
- ./src/Maker/Factory/DoctrineScalarFieldsDefaultPropertiesGuesser.php
69-
- ./src/ORM/OrmV2PersistenceStrategy.php

src/Maker/Factory/DoctrineScalarFieldsDefaultPropertiesGuesser.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ public function supports(MakeFactoryData $makeFactoryData): bool
104104
return $makeFactoryData->isPersisted();
105105
}
106106

107-
// handles both ORM 3 & 4
108107
private function extractFieldMappingData(FieldMapping|array $fieldMapping, string $field, mixed $default = null): mixed
109108
{
110109
if ($fieldMapping instanceof FieldMapping) {

src/Maker/Factory/LegacyORMDefaultPropertiesGuesser.php

Lines changed: 0 additions & 83 deletions
This file was deleted.

src/Maker/Factory/ORMDefaultPropertiesGuesser.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use Doctrine\ORM\Mapping\ClassMetadata as ORMClassMetadata;
1515
use Doctrine\ORM\Mapping\ToOneAssociationMapping;
1616
use Symfony\Component\Console\Style\SymfonyStyle;
17-
use Zenstruck\Foundry\ORM\DoctrineOrmVersionGuesser;
1817
use Zenstruck\Foundry\Persistence\Exception\NoPersistenceStrategy;
1918

2019
/**
@@ -24,10 +23,6 @@ final class ORMDefaultPropertiesGuesser extends AbstractDoctrineDefaultPropertie
2423
{
2524
public function __invoke(SymfonyStyle $io, MakeFactoryData $makeFactoryData, MakeFactoryQuery $makeFactoryQuery): void
2625
{
27-
if (!DoctrineOrmVersionGuesser::isOrmV3()) {
28-
return;
29-
}
30-
3126
$metadata = $this->getClassMetadata($makeFactoryData);
3227

3328
if (!$metadata instanceof ORMClassMetadata) {

src/ORM/DoctrineOrmVersionGuesser.php

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/ORM/AbstractORMPersistenceStrategy.php renamed to src/ORM/ORMPersistenceStrategy.php

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,17 @@
1212
namespace Zenstruck\Foundry\ORM;
1313

1414
use Doctrine\ORM\EntityManagerInterface;
15+
use Doctrine\ORM\Mapping\AssociationMapping;
16+
use Doctrine\ORM\Mapping\ManyToOneAssociationMapping;
1517
use Doctrine\ORM\Mapping\MappingException as ORMMappingException;
18+
use Doctrine\ORM\Mapping\OneToManyAssociationMapping;
19+
use Doctrine\ORM\Mapping\OneToOneAssociationMapping;
1620
use Doctrine\Persistence\Mapping\MappingException;
1721
use Zenstruck\Foundry\Persistence\PersistenceStrategy;
22+
use Zenstruck\Foundry\Persistence\Relationship\ManyToOneRelationship;
23+
use Zenstruck\Foundry\Persistence\Relationship\OneToManyRelationship;
24+
use Zenstruck\Foundry\Persistence\Relationship\OneToOneRelationship;
25+
use Zenstruck\Foundry\Persistence\Relationship\RelationshipMetadata;
1826

1927
/**
2028
* @author Kevin Bond <kevinbond@gmail.com>
@@ -24,16 +32,16 @@
2432
* @method EntityManagerInterface objectManagerFor(string $class)
2533
* @method list<EntityManagerInterface> objectManagers()
2634
*/
27-
abstract class AbstractORMPersistenceStrategy extends PersistenceStrategy
35+
final class ORMPersistenceStrategy extends PersistenceStrategy
2836
{
29-
final public function contains(object $object): bool
37+
public function contains(object $object): bool
3038
{
3139
$em = $this->objectManagerFor($object::class);
3240

3341
return $em->contains($object) && !$em->getUnitOfWork()->isScheduledForInsert($object);
3442
}
3543

36-
final public function hasChanges(object $object): bool
44+
public function hasChanges(object $object): bool
3745
{
3846
$em = $this->objectManagerFor($object::class);
3947

@@ -50,12 +58,12 @@ final public function hasChanges(object $object): bool
5058
return (bool) $unitOfWork->getEntityChangeSet($object);
5159
}
5260

53-
final public function truncate(string $class): void
61+
public function truncate(string $class): void
5462
{
5563
$this->objectManagerFor($class)->createQuery("DELETE {$class} e")->execute();
5664
}
5765

58-
final public function embeddablePropertiesFor(object $object, string $owner): ?array
66+
public function embeddablePropertiesFor(object $object, string $owner): ?array
5967
{
6068
try {
6169
$metadata = $this->objectManagerFor($owner)->getClassMetadata($object::class);
@@ -76,17 +84,17 @@ final public function embeddablePropertiesFor(object $object, string $owner): ?a
7684
return $properties;
7785
}
7886

79-
final public function isEmbeddable(object $object): bool
87+
public function isEmbeddable(object $object): bool
8088
{
8189
return $this->objectManagerFor($object::class)->getClassMetadata($object::class)->isEmbeddedClass;
8290
}
8391

84-
final public function isScheduledForInsert(object $object): bool
92+
public function isScheduledForInsert(object $object): bool
8593
{
8694
return $this->objectManagerFor($object::class)->getUnitOfWork()->isScheduledForInsert($object);
8795
}
8896

89-
final public function managedNamespaces(): array
97+
public function managedNamespaces(): array
9098
{
9199
$namespaces = [];
92100

@@ -97,7 +105,7 @@ final public function managedNamespaces(): array
97105
return \array_values(\array_merge(...$namespaces));
98106
}
99107

100-
final public function getIdentifierValues(object $object): array
108+
public function getIdentifierValues(object $object): array
101109
{
102110
$identifiers = $this->classMetadata($object::class)->getIdentifierValues($object);
103111

@@ -118,4 +126,60 @@ function(mixed $value) use ($object) {
118126
$identifiers
119127
);
120128
}
129+
130+
public function bidirectionalRelationshipMetadata(string $parent, string $child, string $field): ?RelationshipMetadata
131+
{
132+
$associationMapping = $this->getAssociationMapping($parent, $child, $field);
133+
134+
if (null === $associationMapping) {
135+
return null;
136+
}
137+
138+
if (!\is_a(
139+
$child,
140+
$associationMapping->targetEntity,
141+
allow_string: true
142+
)) { // is_a() handles inheritance as well
143+
throw new \LogicException("Cannot find correct association named \"{$field}\" between classes [parent: \"{$parent}\", child: \"{$child}\"]");
144+
}
145+
146+
$inverseField = $associationMapping->isOwningSide() ? $associationMapping->inversedBy : $associationMapping->mappedBy;
147+
148+
if (null === $inverseField) {
149+
return null;
150+
}
151+
152+
return match (true) {
153+
$associationMapping instanceof OneToManyAssociationMapping => new OneToManyRelationship(
154+
inverseField: $inverseField,
155+
collectionIndexedBy: $associationMapping->isIndexed() ? $associationMapping->indexBy() : null
156+
),
157+
$associationMapping instanceof OneToOneAssociationMapping => new OneToOneRelationship(
158+
inverseField: $inverseField,
159+
isOwning: $associationMapping->isOwningSide()
160+
),
161+
$associationMapping instanceof ManyToOneAssociationMapping => new ManyToOneRelationship(
162+
inverseField: $inverseField,
163+
),
164+
default => null,
165+
};
166+
}
167+
168+
/**
169+
* @param class-string $entityClass
170+
*/
171+
private function getAssociationMapping(string $entityClass, string $targetEntity, string $field): ?AssociationMapping
172+
{
173+
try {
174+
$associationMapping = $this->objectManagerFor($entityClass)->getClassMetadata($entityClass)->getAssociationMapping($field);
175+
} catch (MappingException|ORMMappingException) {
176+
return null;
177+
}
178+
179+
if (!\is_a($targetEntity, $associationMapping->targetEntity, allow_string: true)) {
180+
return null;
181+
}
182+
183+
return $associationMapping;
184+
}
121185
}

0 commit comments

Comments
 (0)