Skip to content

Commit

Permalink
Add support for Doctrine ORM 3 (#968)
Browse files Browse the repository at this point in the history
| Q               | A
| --------------- | -----
| Bug fix?        | no
| New feature?    | no
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | 
| License         | MIT

I've also tested on Sylius with Symlink (using composer repositories
option)


![image](https://github.com/user-attachments/assets/b327b6cb-54d8-429e-8be2-ff962b94c08d)
  • Loading branch information
GSadee authored Jan 15, 2025
2 parents eebdf34 + 7c515e1 commit 7f99b30
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 29 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ on:
jobs:
tests:
runs-on: ubuntu-latest
name: "PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}"
name: "PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, ORM ${{ matrix.orm }}"
env:
APP_ENV: ${{ matrix.app_env }}
strategy:
fail-fast: false
matrix:
orm: ['2.*', '3.*']
php: ["8.1", "8.2", "8.3"]
composer-flags: ['--no-scripts --prefer-stable --prefer-dist']
symfony: ["^6.4", "^7.1"]
Expand Down Expand Up @@ -47,6 +48,13 @@ jobs:
composer config extra.symfony.require "${{ matrix.symfony }}"
(cd src/Component && composer config extra.symfony.require "${{ matrix.symfony }}")
-
name: Restrict ORM version
if: matrix.orm != ''
run: |
composer require --dev doctrine/orm "${{ matrix.orm }}" --no-update --no-scripts
(cd src/Component && composer require --dev doctrine/orm "${{ matrix.orm }}" --no-update --no-scripts)
-
name: Remove hateoas on Symfony 7
if: matrix.symfony == '^7.0'
Expand All @@ -55,13 +63,12 @@ jobs:
-
name: Install dependencies
run: |
composer update --no-scripts
composer update ${{ matrix.composer-flags }}
(cd src/Component && composer update ${{ matrix.composer-flags }})
-
name: Prepare test application
run: |
(cd tests/Application && bin/console doctrine:database:create)
(cd tests/Application && bin/console doctrine:schema:create)
-
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ RUN composer update --with-all-dependencies --no-interaction --no-progress

WORKDIR /app/tests/Application

RUN php bin/console doctrine:database:create && php bin/console doctrine:schema:update --force
RUN php bin/console doctrine:schema:create

WORKDIR /app
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
},
"require-dev": {
"doctrine/doctrine-bundle": "^2.13",
"doctrine/orm": "^2.18",
"doctrine/orm": "^2.18 || ^3.3",
"friendsofsymfony/rest-bundle": "^3.7",
"jms/serializer-bundle": "^3.5 || ^4.0 || ^5.0",
"lchrusciel/api-test-case": "^5.0",
Expand Down Expand Up @@ -89,7 +89,7 @@
"winzou/state-machine-bundle": "^0.6.2"
},
"conflict": {
"doctrine/orm": "<2.18 || ^3.0",
"doctrine/orm": "<2.18",
"doctrine/doctrine-bundle": "<2.0 || ^3.0",
"friendsofsymfony/rest-bundle": "<3.0",
"jms/serializer-bundle": "<3.5",
Expand Down
2 changes: 2 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ parameters:
- %currentWorkingDirectory%/src/Component/vendor/*

ignoreErrors:
- '/Call to method type\(\) on an unknown class Doctrine\\ORM\\Mapping\\AssociationMapping./'
- '/Call to method getArguments\(\) on an unknown class ReflectionAttribute./'
- '/Call to method isChangeTrackingDeferredExplicit\(\) on an unknown class Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata./'
- '/Call to an undefined method ReflectionClass::getAttributes\(\)./'
Expand Down Expand Up @@ -75,6 +76,7 @@ parameters:
- '/Parameter \#2 \$class of static method Webmozart\\Assert\\Assert::isInstanceOf\(\) expects class-string<object>, string given./'
- '/Parameter \#1 \$objectOrClass of class ReflectionClass constructor expects class-string<object>\|object, object\|string given./'
- '/Parameter \#1 \$package of method Symfony\\Component\\DependencyInjection\\Alias::setDeprecated\(\)/'
- '/PHPDoc tag @var for variable \$value contains unknown class Doctrine\\ORM\\Mapping\\AssociationMapping./'
- '/Return typehint of method Sylius\\Bundle\\ResourceBundle\\Routing\\CrudRoutesAttributesLoader::getClassAttributes\(\) has invalid type ReflectionAttribute./'
- '/Return typehint of method Sylius\\Bundle\\ResourceBundle\\Routing\\RoutesAttributesLoader::getClassAttributes\(\) has invalid type ReflectionAttribute./'
- '/Unable to resolve the template type ExpectedType in call to method static method Webmozart\\Assert\\Assert::isInstanceOf\(\)/'
Expand Down
9 changes: 8 additions & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@
</errorLevel>
</InvalidArgument>

<InvalidPropertyAssignmentValue>
<errorLevel type="suppress">
<file name="src/Bundle/EventListener/ORMMappedSuperClassSubscriber.php" />
</errorLevel>
</InvalidPropertyAssignmentValue>

<InvalidReturnStatement>
<errorLevel type="suppress">
<file name="src/Component/src/Doctrine/Persistence/InMemoryRepository.php" />
Expand Down Expand Up @@ -281,7 +287,8 @@

<UndefinedDocblockClass>
<errorLevel type="suppress">
<referencedClass name="UnitEnum"/>
<referencedClass name="UnitEnum" />
<referencedClass name="Doctrine\ORM\Mapping\AssociationMapping" />
</errorLevel>
</UndefinedDocblockClass>

Expand Down
18 changes: 12 additions & 6 deletions src/Bundle/Doctrine/ORM/ContainerRepositoryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
namespace Sylius\Bundle\ResourceBundle\Doctrine\ORM;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository as DoctrineEntityRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Repository\RepositoryFactory;
use Doctrine\Persistence\ObjectRepository;

final class ContainerRepositoryFactory implements RepositoryFactory
{
Expand All @@ -25,7 +25,7 @@ final class ContainerRepositoryFactory implements RepositoryFactory
/** @var string[] */
private array $genericEntities;

/** @var ObjectRepository[] */
/** @var DoctrineEntityRepository[] */
private array $managedRepositories = [];

/**
Expand All @@ -37,8 +37,11 @@ public function __construct(RepositoryFactory $doctrineFactory, array $genericEn
$this->genericEntities = $genericEntities;
}

/** @psalm-suppress InvalidReturnType */
public function getRepository(EntityManagerInterface $entityManager, $entityName): ObjectRepository
/**
* @psalm-suppress InvalidReturnStatement
* @psalm-suppress InvalidReturnType
*/
public function getRepository(EntityManagerInterface $entityManager, $entityName): DoctrineEntityRepository
{
$metadata = $entityManager->getClassMetadata($entityName);

Expand All @@ -47,13 +50,16 @@ public function getRepository(EntityManagerInterface $entityManager, $entityName
return $this->getOrCreateRepository($entityManager, $metadata);
}

return $this->doctrineFactory->getRepository($entityManager, $entityName);
/** @var DoctrineEntityRepository $repository */
$repository = $this->doctrineFactory->getRepository($entityManager, $entityName);

return $repository;
}

private function getOrCreateRepository(
EntityManagerInterface $entityManager,
ClassMetadata $metadata,
): ObjectRepository {
): DoctrineEntityRepository {
$repositoryHash = $metadata->getName() . spl_object_hash($entityManager);

if (!isset($this->managedRepositories[$repositoryHash])) {
Expand Down
12 changes: 6 additions & 6 deletions src/Bundle/Doctrine/ORM/ResourceRepositoryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ trait ResourceRepositoryTrait
{
public function add(ResourceInterface $resource): void
{
$this->_em->persist($resource);
$this->_em->flush();
$this->getEntityManager()->persist($resource);
$this->getEntityManager()->flush();
}

public function remove(ResourceInterface $resource): void
{
if (null !== $this->find($resource->getId())) {
$this->_em->remove($resource);
$this->_em->flush();
$this->getEntityManager()->remove($resource);
$this->getEntityManager()->flush();
}
}

Expand Down Expand Up @@ -78,7 +78,7 @@ protected function getArrayPaginator($objects): Pagerfanta
protected function applyCriteria(QueryBuilder $queryBuilder, array $criteria = []): void
{
foreach ($criteria as $property => $value) {
if (!in_array($property, array_merge($this->_class->getAssociationNames(), $this->_class->getFieldNames()), true)) {
if (!in_array($property, array_merge($this->getClassMetadata()->getAssociationNames(), $this->getClassMetadata()->getFieldNames()), true)) {
continue;
}

Expand All @@ -101,7 +101,7 @@ protected function applyCriteria(QueryBuilder $queryBuilder, array $criteria = [
protected function applySorting(QueryBuilder $queryBuilder, array $sorting = []): void
{
foreach ($sorting as $property => $order) {
if (!in_array($property, array_merge($this->_class->getAssociationNames(), $this->_class->getFieldNames()), true)) {
if (!in_array($property, array_merge($this->getClassMetadata()->getAssociationNames(), $this->getClassMetadata()->getFieldNames()), true)) {
continue;
}

Expand Down
15 changes: 12 additions & 3 deletions src/Bundle/EventListener/ORMMappedSuperClassSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Doctrine\ORM\Configuration;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\AssociationMapping;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Webmozart\Assert\Assert;
Expand Down Expand Up @@ -80,9 +81,13 @@ private function setAssociationMappings(ClassMetadata $metadata, Configuration $
}

if ($parentMetadata->isMappedSuperclass) {
/**
* @var AssociationMapping|array{type: int} $value
*/
foreach ($parentMetadata->getAssociationMappings() as $key => $value) {
if ($this->isRelation($value['type']) && !isset($metadata->associationMappings[$key])) {
$metadata->associationMappings[$key] = $value;
$type = \is_array($value) ? $value['type'] : $value->type();
if ($this->isRelation($type) && !isset($metadata->associationMappings[$key])) {
$metadata->associationMappings[$key] = $value; /** @phpstan-ignore-line */
}
}
}
Expand All @@ -96,8 +101,12 @@ private function unsetAssociationMappings(ClassMetadata $metadata): void
return;
}

/**
* @var AssociationMapping|array{type: int} $value
*/
foreach ($metadata->getAssociationMappings() as $key => $value) {
if ($this->isRelation($value['type'])) {
$type = \is_array($value) ? $value['type'] : $value->type();
if ($this->isRelation($type)) {
unset($metadata->associationMappings[$key]);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Bundle/EventListener/ORMTranslatableListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
$classMetadata = $eventArgs->getClassMetadata();
$reflection = $classMetadata->getReflectionClass();

/** @psalm-suppress PossiblyNullReference */
if ($reflection->isAbstract()) {
return;
}
Expand Down Expand Up @@ -109,7 +110,7 @@ private function mapTranslatable(ClassMetadata $metadata): void
'mappedBy' => 'translatable',
'fetch' => ClassMetadata::FETCH_EXTRA_LAZY,
'indexBy' => 'locale',
'cascade' => ['persist', 'merge', 'remove'],
'cascade' => ['persist', 'remove'],
'orphanRemoval' => true,
]);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Component/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
},
"require-dev": {
"behat/transliterator": "^1.3",
"doctrine/orm": "^2.18",
"doctrine/orm": "^2.18 || ^3.3",
"matthiasnoback/symfony-dependency-injection-test": "^4.2.1 || ^5.1",
"phpspec/phpspec": "^7.3",
"phpspec/prophecy-phpunit": "^2.0",
Expand All @@ -59,7 +59,7 @@
"twig/twig": "^3.0"
},
"conflict": {
"doctrine/orm": "<2.18 || ^3.0",
"doctrine/orm": "<2.18",
"twig/twig": "<3.0"
},
"extra": {
Expand Down
2 changes: 0 additions & 2 deletions tests/Application/src/Entity/GedmoBaseExample.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
use Gedmo\Mapping\Annotation as Gedmo;
use Sylius\Resource\Model\ResourceInterface;

#[ORM\Entity]
#[ORM\MappedSuperclass]
#[ORM\Table(name: 'gedmo')]
class GedmoBaseExample implements ResourceInterface
{
#[ORM\Id]
Expand Down
2 changes: 0 additions & 2 deletions tests/Application/src/Entity/GedmoExtendedExample.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\MappedSuperclass]

class GedmoExtendedExample extends GedmoBaseExample
{
#[ORM\Column(length: 255)]
Expand Down

0 comments on commit 7f99b30

Please sign in to comment.