Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Doctrine ORM 3 #968

Merged
merged 1 commit into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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./'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using phpstan-doctrine here?

composer require --dev phpstan/phpstan-doctrine

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, I don't think that's the solution.
This class does not exist on doctrine orm 2.

- '/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
Loading