diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 9a1d744f69..0dbee62412 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -17766,6 +17766,12 @@ parameters: count: 1 path: src/lib/Persistence/Cache/UserPreferenceHandler.php + - + message: '#^Return type \(Doctrine\\ORM\\Mapping\\ClassMetadataFactory\) of method Ibexa\\Core\\Persistence\\Doctrine\\SiteAccessAwareEntityManager\:\:getMetadataFactory\(\) should be compatible with return type \(Doctrine\\Persistence\\Mapping\\ClassMetadataFactory\\>\) of method Doctrine\\Persistence\\ObjectManager\:\:getMetadataFactory\(\)$#' + identifier: method.childReturnType + count: 2 + path: src/lib/Persistence/Doctrine/SiteAccessAwareEntityManager.php + - message: '#^Property Ibexa\\Core\\Persistence\\FieldTypeRegistry\:\:\$coreFieldTypes \(array\\) does not accept array\\.$#' identifier: assign.propertyType diff --git a/src/bundle/Core/Resources/config/services.yml b/src/bundle/Core/Resources/config/services.yml index 166b1940cc..f8db70e326 100644 --- a/src/bundle/Core/Resources/config/services.yml +++ b/src/bundle/Core/Resources/config/services.yml @@ -367,9 +367,11 @@ services: - { name: console.command } ibexa.doctrine.orm.entity_manager: - class: Doctrine\ORM\EntityManager - lazy: true - factory: ['@ibexa.doctrine.orm.entity_manager_factory', 'getEntityManager'] + class: Ibexa\Core\Persistence\Doctrine\SiteAccessAwareEntityManager + arguments: + $entityManagerFactory: '@ibexa.doctrine.orm.entity_manager_factory' + tags: + - { name: 'kernel.reset', method: 'reset' } ibexa.doctrine.orm.entity_manager_factory: class: Ibexa\Bundle\Core\Entity\EntityManagerFactory diff --git a/src/lib/Persistence/Doctrine/SiteAccessAwareEntityManager.php b/src/lib/Persistence/Doctrine/SiteAccessAwareEntityManager.php new file mode 100644 index 0000000000..88a2d51a8c --- /dev/null +++ b/src/lib/Persistence/Doctrine/SiteAccessAwareEntityManager.php @@ -0,0 +1,308 @@ +entityManagerFactory = $entityManagerFactory; + } + + public function onConfigScopeChange(ScopeChangeEvent $event): void + { + $this->resolvedEntityManager = null; + } + + public function reset(): void + { + $this->resolvedEntityManager = null; + } + + private function getWrapped(): EntityManagerInterface + { + return $this->resolvedEntityManager ??= $this->entityManagerFactory->getEntityManager(); + } + + public function getConnection(): Connection + { + return $this->getWrapped()->getConnection(); + } + + public function getExpressionBuilder(): Expr + { + return $this->getWrapped()->getExpressionBuilder(); + } + + public function beginTransaction(): void + { + $this->getWrapped()->beginTransaction(); + } + + public function transactional($func) + { + return $this->getWrapped()->transactional($func); + } + + /** + * @return mixed + */ + public function wrapInTransaction(callable $func) + { + return $this->getWrapped()->wrapInTransaction($func); + } + + public function commit(): void + { + $this->getWrapped()->commit(); + } + + public function rollback(): void + { + $this->getWrapped()->rollback(); + } + + public function createQuery($dql = ''): Query + { + return $this->getWrapped()->createQuery($dql); + } + + public function createNamedQuery($name): Query + { + return $this->getWrapped()->createNamedQuery($name); + } + + public function createNativeQuery($sql, ResultSetMapping $rsm): NativeQuery + { + return $this->getWrapped()->createNativeQuery($sql, $rsm); + } + + public function createNamedNativeQuery($name): NativeQuery + { + return $this->getWrapped()->createNamedNativeQuery($name); + } + + public function createQueryBuilder(): QueryBuilder + { + return $this->getWrapped()->createQueryBuilder(); + } + + /** + * @template T of object + * + * @param class-string $entityName + * + * @return T|null + */ + public function getReference($entityName, $id): ?object + { + return $this->getWrapped()->getReference($entityName, $id); + } + + /** + * @template T of object + * + * @param class-string $entityName + * + * @return T|null + */ + public function getPartialReference($entityName, $identifier): ?object + { + return $this->getWrapped()->getPartialReference($entityName, $identifier); + } + + public function close(): void + { + $this->getWrapped()->close(); + } + + /** + * @template T of object + * + * @param T $entity + * @param bool $deep + * + * @return T + */ + public function copy($entity, $deep = false): object + { + /** @var T */ + return $this->getWrapped()->copy($entity, $deep); + } + + public function lock($entity, $lockMode, $lockVersion = null): void + { + $this->getWrapped()->lock($entity, $lockMode, $lockVersion); + } + + public function getEventManager(): \Doctrine\Common\EventManager + { + return $this->getWrapped()->getEventManager(); + } + + public function getConfiguration(): Configuration + { + return $this->getWrapped()->getConfiguration(); + } + + public function isOpen(): bool + { + return $this->getWrapped()->isOpen(); + } + + public function getUnitOfWork(): UnitOfWork + { + return $this->getWrapped()->getUnitOfWork(); + } + + public function getHydrator($hydrationMode): AbstractHydrator + { + return $this->getWrapped()->getHydrator($hydrationMode); + } + + public function newHydrator($hydrationMode): AbstractHydrator + { + return $this->getWrapped()->newHydrator($hydrationMode); + } + + public function getProxyFactory(): ProxyFactory + { + return $this->getWrapped()->getProxyFactory(); + } + + public function getFilters(): FilterCollection + { + return $this->getWrapped()->getFilters(); + } + + public function isFiltersStateClean(): bool + { + return $this->getWrapped()->isFiltersStateClean(); + } + + public function hasFilters(): bool + { + return $this->getWrapped()->hasFilters(); + } + + public function getCache(): ?Cache + { + return $this->getWrapped()->getCache(); + } + + public function find($className, $id): ?object + { + return $this->getWrapped()->find($className, $id); + } + + public function persist(object $object): void + { + $this->getWrapped()->persist($object); + } + + public function remove(object $object): void + { + $this->getWrapped()->remove($object); + } + + public function clear(): void + { + $this->getWrapped()->clear(); + } + + public function detach(object $object): void + { + $this->getWrapped()->detach($object); + } + + public function refresh(object $object, ?int $lockMode = null): void + { + $this->getWrapped()->refresh($object, $lockMode); + } + + public function flush(): void + { + $this->getWrapped()->flush(); + } + + /** + * @template T of object + * + * @param class-string $className + * + * @return EntityRepository + */ + public function getRepository($className): EntityRepository + { + return $this->getWrapped()->getRepository($className); + } + + /** + * @template T of object + * + * @param class-string $className + * + * @return ClassMetadata + */ + public function getClassMetadata($className): ClassMetadata + { + return $this->getWrapped()->getClassMetadata($className); + } + + public function getMetadataFactory(): ClassMetadataFactory + { + return $this->getWrapped()->getMetadataFactory(); + } + + public function initializeObject(object $obj): void + { + $this->getWrapped()->initializeObject($obj); + } + + /** + * @param mixed $value + */ + public function isUninitializedObject($value): bool + { + return $this->getWrapped()->isUninitializedObject($value); + } + + public function contains(object $object): bool + { + return $this->getWrapped()->contains($object); + } +}