@@ -348,7 +348,7 @@ discard block |
||
348 | 348 | $classMetadata->expects($this->once())->method('getName')->willReturn($entityName); |
349 | 349 | $targetMetadata->expects($this->once())->method('getName')->willReturn($mapping['targetEntity']); |
350 | 350 | |
351 | - $methodName = 'get' . ucfirst($mapping['fieldName']); |
|
351 | + $methodName = 'get'.ucfirst($mapping['fieldName']); |
|
352 | 352 | |
353 | 353 | $errorMessage = sprintf( |
354 | 354 | 'Failed to find required entity method \'%s::%s\'. The method is required for cascade operations ' |
@@ -454,7 +454,7 @@ discard block |
||
454 | 454 | $classMetadata->expects($this->once())->method('getName')->willReturn($entityName); |
455 | 455 | $targetMetadata->expects($this->once())->method('getName')->willReturn($mapping['targetEntity']); |
456 | 456 | |
457 | - $methodName = 'get' . ucfirst($mapping['fieldName']); |
|
457 | + $methodName = 'get'.ucfirst($mapping['fieldName']); |
|
458 | 458 | |
459 | 459 | $errorMessage = sprintf( |
460 | 460 | 'The call to resolve entity of type \'%s\' from method call \'%s::%s\' failed: %s', |
@@ -1,1 +1,1 @@ |
||
1 | -<?php declare(strict_types=1); namespace Arp\DoctrineEntityRepository; use Arp\DoctrineEntityRepository\Constant\EntityEventOption; use Arp\DoctrineEntityRepository\Constant\FlushMode; use Arp\DoctrineEntityRepository\Constant\QueryServiceOption; use Arp\DoctrineEntityRepository\Constant\TransactionMode; use Arp\DoctrineEntityRepository\Exception\EntityNotFoundException; use Arp\DoctrineEntityRepository\Exception\EntityRepositoryException; use Arp\DoctrineEntityRepository\Persistence\PersistServiceInterface; use Arp\DoctrineEntityRepository\Query\QueryServiceInterface; use Arp\Entity\EntityInterface; use Psr\Log\LoggerInterface; /** * @author Alex Patterson <[email protected]> * @package Arp\DoctrineEntityRepository */ abstract class AbstractEntityRepository implements EntityRepositoryInterface { /** * @var string */ protected string $entityName; /** * @var QueryServiceInterface */ protected QueryServiceInterface $queryService; /** * @var PersistServiceInterface */ protected PersistServiceInterface $persistService; /** * @var LoggerInterface */ protected LoggerInterface $logger; /** * @param string $entityName * @param QueryServiceInterface $queryService * @param PersistServiceInterface $persistService * @param LoggerInterface $logger */ public function __construct( string $entityName, QueryServiceInterface $queryService, PersistServiceInterface $persistService, LoggerInterface $logger ) { $this->entityName = $entityName; $this->queryService = $queryService; $this->persistService = $persistService; $this->logger = $logger; } /** * Return the fully qualified class name of the mapped entity instance. * * @return string */ public function getClassName(): string { return $this->entityName; } /** * Return a single entity instance matching the provided $id. * * @param string $id * * @return EntityInterface|null * * @throws EntityRepositoryException */ public function find($id): ?EntityInterface { try { return $this->queryService->findOneById($id); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to find entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Return a single entity instance matching the provided $criteria. * * @param array $criteria The entity filter criteria. * * @return EntityInterface|null * * @throws EntityRepositoryException */ public function findOneBy(array $criteria): ?EntityInterface { try { return $this->queryService->findOne($criteria); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to find entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Return all of the entities within the collection. * * @return EntityInterface[] * * @throws EntityRepositoryException */ public function findAll(): array { return $this->findBy([]); } /** * Return a collection of entities that match the provided $criteria. * * @param array $criteria * @param array|null $orderBy * @param int|null $limit * @param int|null $offset * * @return EntityInterface[]|iterable * * @throws EntityRepositoryException */ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): iterable { try { $options = [ QueryServiceOption::LIMIT => $limit, QueryServiceOption::OFFSET => $offset, QueryServiceOption::ORDER_BY => $orderBy, ]; return $this->queryService->findMany($criteria, $options); } catch (\Throwable $e) { $errorMessage = sprintf( 'Unable to return a collection of type \'%s\': %s', $this->entityName, $e->getMessage() ); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Save a single entity instance. * * @param EntityInterface $entity * @param array $options * * @return EntityInterface * * @throws EntityRepositoryException */ public function save(EntityInterface $entity, array $options = []): EntityInterface { try { return $this->persistService->save($entity, $options); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to save entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Save a collection of entities in a single transaction. * * @param iterable|EntityInterface[] $collection The collection of entities that should be saved. * @param array $options the optional save options. * * @return iterable * * @throws EntityRepositoryException If the save cannot be completed */ public function saveCollection(iterable $collection, array $options = []): iterable { $flushMode = $options[EntityEventOption::FLUSH_MODE] ?? FlushMode::ENABLED; $transactionMode = $options[EntityEventOption::TRANSACTION_MODE] ?? TransactionMode::ENABLED; try { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->beginTransaction(); } $entities = []; $saveOptions = [ EntityEventOption::FLUSH_MODE => FlushMode::DISABLED, EntityEventOption::TRANSACTION_MODE => TransactionMode::DISABLED ]; foreach ($collection as $entity) { $entities[] = $this->save($entity, $saveOptions); } if (FlushMode::ENABLED === $flushMode) { $this->persistService->flush(); } if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->commitTransaction(); } return $entities; } catch (\Throwable $e) { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->rollbackTransaction(); } $errorMessage = sprintf( 'Unable to save collection of type \'%s\' : %s', $this->entityName, $e->getMessage() ); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Delete an entity. * * @param EntityInterface|string $entity * @param array $options * * @return bool * * @throws EntityRepositoryException */ public function delete($entity, array $options = []): bool { if (!is_string($entity) && !$entity instanceof EntityInterface) { throw new EntityRepositoryException( sprintf( 'The \'entity\' argument must be a \'string\' or an object of type \'%s\'; ' . '\'%s\' provided in \'%s\'', EntityInterface::class, (is_object($entity) ? get_class($entity) : gettype($entity)), __METHOD__ ) ); } if (is_string($entity)) { $id = $entity; $entity = $this->find($id); if (null === $entity) { $errorMessage = sprintf( 'Unable to delete entity \'%s::%s\': The entity could not be found', $this->entityName, $id ); $this->logger->error($errorMessage); throw new EntityNotFoundException($errorMessage); } } try { return $this->persistService->delete($entity, $options); } catch (\Throwable $e) { $errorMessage = sprintf( 'Unable to delete entity of type \'%s\': %s', $this->entityName, $e->getMessage() ); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Perform a deletion of a collection of entities. * * @param iterable|EntityInterface $collection * @param array $options * * @return int * * @throws EntityRepositoryException */ public function deleteCollection(iterable $collection, array $options = []): int { $flushMode = $options[EntityEventOption::FLUSH_MODE] ?? FlushMode::ENABLED; $transactionMode = $options[EntityEventOption::TRANSACTION_MODE] ?? TransactionMode::ENABLED; try { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->beginTransaction(); } $deleteOptions = [ EntityEventOption::FLUSH_MODE => FlushMode::DISABLED, EntityEventOption::TRANSACTION_MODE => TransactionMode::DISABLED, ]; $deleted = 0; foreach ($collection as $entity) { if (true === $this->delete($entity, $deleteOptions)) { $deleted++; } } if (FlushMode::ENABLED === $flushMode) { $this->persistService->flush(); } if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->commitTransaction(); } return $deleted; } catch (\Throwable $e) { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->rollbackTransaction(); } $errorMessage = sprintf( 'Unable to delete collection of type \'%s\' : %s', $this->entityName, $e->getMessage() ); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * @throws EntityRepositoryException */ public function clear(): void { try { $this->persistService->clear(); } catch (\Throwable $e) { $errorMessage = sprintf( 'Unable to clear entity of type \'%s\': %s', $this->entityName, $e->getMessage() ); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * @param EntityInterface $entity * * @throws EntityRepositoryException */ public function refresh(EntityInterface $entity): void { try { $this->persistService->refresh($entity); } catch (\Throwable $e) { $errorMessage = sprintf( 'Unable to refresh entity of type \'%s\': %s', $this->entityName, $e->getMessage() ); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } } |
|
2 | 1 | \ No newline at end of file |
2 | +<?php declare(strict_types=1); namespace Arp\DoctrineEntityRepository; use Arp\DoctrineEntityRepository\Constant\EntityEventOption; use Arp\DoctrineEntityRepository\Constant\FlushMode; use Arp\DoctrineEntityRepository\Constant\QueryServiceOption; use Arp\DoctrineEntityRepository\Constant\TransactionMode; use Arp\DoctrineEntityRepository\Exception\EntityNotFoundException; use Arp\DoctrineEntityRepository\Exception\EntityRepositoryException; use Arp\DoctrineEntityRepository\Persistence\PersistServiceInterface; use Arp\DoctrineEntityRepository\Query\QueryServiceInterface; use Arp\Entity\EntityInterface; use Psr\Log\LoggerInterface; /** * @author Alex Patterson <[email protected]> * @package Arp\DoctrineEntityRepository */ abstract class AbstractEntityRepository implements EntityRepositoryInterface { /** * @var string */ protected string $entityName; /** * @var QueryServiceInterface */ protected QueryServiceInterface $queryService; /** * @var PersistServiceInterface */ protected PersistServiceInterface $persistService; /** * @var LoggerInterface */ protected LoggerInterface $logger; /** * @param string $entityName * @param QueryServiceInterface $queryService * @param PersistServiceInterface $persistService * @param LoggerInterface $logger */ public function __construct(string $entityName, QueryServiceInterface $queryService, PersistServiceInterface $persistService, LoggerInterface $logger) { $this->entityName = $entityName; $this->queryService = $queryService; $this->persistService = $persistService; $this->logger = $logger; } /** * Return the fully qualified class name of the mapped entity instance. * * @return string */ public function getClassName(): string { return $this->entityName; } /** * Return a single entity instance matching the provided $id. * * @param string $id * * @return EntityInterface|null * * @throws EntityRepositoryException */ public function find($id): ?EntityInterface { try { return $this->queryService->findOneById($id); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to find entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Return a single entity instance matching the provided $criteria. * * @param array $criteria The entity filter criteria. * * @return EntityInterface|null * * @throws EntityRepositoryException */ public function findOneBy(array $criteria): ?EntityInterface { try { return $this->queryService->findOne($criteria); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to find entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Return all of the entities within the collection. * * @return EntityInterface[] * * @throws EntityRepositoryException */ public function findAll(): array { return $this->findBy([]); } /** * Return a collection of entities that match the provided $criteria. * * @param array $criteria * @param array|null $orderBy * @param int|null $limit * @param int|null $offset * * @return EntityInterface[]|iterable * * @throws EntityRepositoryException */ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): iterable { try { $options = [QueryServiceOption::LIMIT => $limit, QueryServiceOption::OFFSET => $offset, QueryServiceOption::ORDER_BY => $orderBy, ]; return $this->queryService->findMany($criteria, $options); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to return a collection of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Save a single entity instance. * * @param EntityInterface $entity * @param array $options * * @return EntityInterface * * @throws EntityRepositoryException */ public function save(EntityInterface $entity, array $options = []): EntityInterface { try { return $this->persistService->save($entity, $options); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to save entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Save a collection of entities in a single transaction. * * @param iterable|EntityInterface[] $collection The collection of entities that should be saved. * @param array $options the optional save options. * * @return iterable * * @throws EntityRepositoryException If the save cannot be completed */ public function saveCollection(iterable $collection, array $options = []): iterable { $flushMode = $options[EntityEventOption::FLUSH_MODE] ?? FlushMode::ENABLED; $transactionMode = $options[EntityEventOption::TRANSACTION_MODE] ?? TransactionMode::ENABLED; try { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->beginTransaction(); } $entities = []; $saveOptions = [EntityEventOption::FLUSH_MODE => FlushMode::DISABLED, EntityEventOption::TRANSACTION_MODE => TransactionMode::DISABLED]; foreach ($collection as $entity) { $entities[] = $this->save($entity, $saveOptions); } if (FlushMode::ENABLED === $flushMode) { $this->persistService->flush(); } if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->commitTransaction(); } return $entities; } catch (\Throwable $e) { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->rollbackTransaction(); } $errorMessage = sprintf('Unable to save collection of type \'%s\' : %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Delete an entity. * * @param EntityInterface|string $entity * @param array $options * * @return bool * * @throws EntityRepositoryException */ public function delete($entity, array $options = []): bool { if (!is_string($entity) && !$entity instanceof EntityInterface) { throw new EntityRepositoryException(sprintf('The \'entity\' argument must be a \'string\' or an object of type \'%s\'; '.'\'%s\' provided in \'%s\'', EntityInterface::class, (is_object($entity) ? get_class($entity) : gettype($entity)), __METHOD__)); } if (is_string($entity)) { $id = $entity; $entity = $this->find($id); if (null === $entity) { $errorMessage = sprintf('Unable to delete entity \'%s::%s\': The entity could not be found', $this->entityName, $id); $this->logger->error($errorMessage); throw new EntityNotFoundException($errorMessage); } } try { return $this->persistService->delete($entity, $options); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to delete entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * Perform a deletion of a collection of entities. * * @param iterable|EntityInterface $collection * @param array $options * * @return int * * @throws EntityRepositoryException */ public function deleteCollection(iterable $collection, array $options = []): int { $flushMode = $options[EntityEventOption::FLUSH_MODE] ?? FlushMode::ENABLED; $transactionMode = $options[EntityEventOption::TRANSACTION_MODE] ?? TransactionMode::ENABLED; try { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->beginTransaction(); } $deleteOptions = [EntityEventOption::FLUSH_MODE => FlushMode::DISABLED, EntityEventOption::TRANSACTION_MODE => TransactionMode::DISABLED, ]; $deleted = 0; foreach ($collection as $entity) { if (true === $this->delete($entity, $deleteOptions)) { $deleted++; } } if (FlushMode::ENABLED === $flushMode) { $this->persistService->flush(); } if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->commitTransaction(); } return $deleted; } catch (\Throwable $e) { if (TransactionMode::ENABLED === $transactionMode) { $this->persistService->rollbackTransaction(); } $errorMessage = sprintf('Unable to delete collection of type \'%s\' : %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * @throws EntityRepositoryException */ public function clear(): void { try { $this->persistService->clear(); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to clear entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } /** * @param EntityInterface $entity * * @throws EntityRepositoryException */ public function refresh(EntityInterface $entity): void { try { $this->persistService->refresh($entity); } catch (\Throwable $e) { $errorMessage = sprintf('Unable to refresh entity of type \'%s\': %s', $this->entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new EntityRepositoryException($errorMessage, $e->getCode(), $e); } } } |
|
3 | 3 | \ No newline at end of file |
@@ -1,1 +1,1 @@ |
||
1 | -<?php declare(strict_types=1); namespace Arp\DoctrineEntityRepository; use Arp\DoctrineEntityRepository\Exception\EntityRepositoryException; use Arp\Entity\EntityInterface; use Doctrine\Persistence\ObjectRepository; /** * @author Alex Patterson <[email protected]> * @package Arp\DoctrineEntityRepository */ interface EntityRepositoryInterface extends ObjectRepository { /** * Save a single entity instance. * * @param EntityInterface $entity * @param array $options * * @return EntityInterface * * @throws EntityRepositoryException */ public function save(EntityInterface $entity, array $options = []): EntityInterface; /** * Save a collection of entities in a single transaction. * * @param iterable|EntityInterface[] $collection The collection of entities that should be saved. * @param array $options the optional save options. * * @return iterable * * @throws EntityRepositoryException If the save cannot be completed */ public function saveCollection(iterable $collection, array $options = []): iterable; /** * Delete an entity. * * @param EntityInterface|int|string $entity * @param array $options * * @return bool * * @throws EntityRepositoryException */ public function delete($entity, array $options = []): bool; /** * Perform a deletion of a collection of entities. * * @param iterable|EntityInterface $collection * @param array $options * * @return int * * @throws EntityRepositoryException */ public function deleteCollection(iterable $collection, array $options = []): int; /** * @throws EntityRepositoryException */ public function clear(): void; /** * @param EntityInterface $entity * * @throws EntityRepositoryException */ public function refresh(EntityInterface $entity): void; } |
|
2 | 1 | \ No newline at end of file |
2 | +<?php declare(strict_types=1); namespace Arp\DoctrineEntityRepository; use Arp\DoctrineEntityRepository\Exception\EntityRepositoryException; use Arp\Entity\EntityInterface; use Doctrine\Persistence\ObjectRepository; /** * @author Alex Patterson <[email protected]> * @package Arp\DoctrineEntityRepository */ interface EntityRepositoryInterface extends ObjectRepository { /** * Save a single entity instance. * * @param EntityInterface $entity * @param array $options * * @return EntityInterface * * @throws EntityRepositoryException */ public function save(EntityInterface $entity, array $options = []): EntityInterface; /** * Save a collection of entities in a single transaction. * * @param iterable|EntityInterface[] $collection The collection of entities that should be saved. * @param array $options the optional save options. * * @return iterable * * @throws EntityRepositoryException If the save cannot be completed */ public function saveCollection(iterable $collection, array $options = []): iterable; /** * Delete an entity. * * @param EntityInterface|int|string $entity * @param array $options * * @return bool * * @throws EntityRepositoryException */ public function delete($entity, array $options = []): bool; /** * Perform a deletion of a collection of entities. * * @param iterable|EntityInterface $collection * @param array $options * * @return int * * @throws EntityRepositoryException */ public function deleteCollection(iterable $collection, array $options = []): int; /** * @throws EntityRepositoryException */ public function clear(): void; /** * @param EntityInterface $entity * * @throws EntityRepositoryException */ public function refresh(EntityInterface $entity): void; } |
|
3 | 3 | \ No newline at end of file |
@@ -1,1 +1,1 @@ |
||
1 | -<?php declare(strict_types=1); namespace Arp\DoctrineEntityRepository\Persistence; use Arp\DoctrineEntityRepository\EntityRepositoryInterface; use Arp\DoctrineEntityRepository\Persistence\Exception\PersistenceException; use Arp\Entity\EntityInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Psr\Log\LoggerInterface; /** * @author Alex Patterson <[email protected]> * @package Arp\DoctrineEntityRepository\Persistence */ abstract class AbstractCascadeService { /** * @var LoggerInterface */ protected LoggerInterface $logger; /** * @var array */ protected array $options; /** * @var array */ protected array $collectionOptions; /** * @param LoggerInterface $logger * @param array $options * @param array $collectionOptions */ public function __construct(LoggerInterface $logger, array $options = [], array $collectionOptions = []) { $this->logger = $logger; $this->options = $options; $this->collectionOptions = $collectionOptions; } /** * @param EntityManagerInterface $entityManager * @param string $entityName * * @return EntityRepositoryInterface * @throws PersistenceException * @todo We should implement a way to decorate the call the getRepository() with a concrete implementation * of the EntityRepositoryProviderInterface * */ protected function getTargetRepository( EntityManagerInterface $entityManager, string $entityName ): EntityRepositoryInterface { try { /** @var EntityRepositoryInterface $targetRepository */ $targetRepository = $entityManager->getRepository($entityName); } catch (\Throwable $e) { $errorMessage = sprintf( 'An error occurred while attempting to load the repository for entity class \'%s\' : %s', $entityName, $e->getMessage() ); $this->logger->error($errorMessage, ['exception' => $e]); throw new PersistenceException($errorMessage, $e->getCode(), $e); } if (null === $targetRepository || !($targetRepository instanceof EntityRepositoryInterface)) { $errorMessage = sprintf( 'The entity repository must be an object of type \'%s\'; \'%s\' returned in \'%s::%s\'', EntityRepositoryInterface::class, (is_object($targetRepository) ? get_class($targetRepository) : gettype($targetRepository)), static::class, __FUNCTION__ ); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage); } return $targetRepository; } /** * @param EntityInterface $sourceEntity * @param string $fieldName * @param ClassMetadata $sourceMetadata * @param ClassMetadata $targetMetadata * * @return EntityInterface|EntityInterface[]|iterable * * @throws PersistenceException */ protected function resolveTargetEntityOrCollection( EntityInterface $sourceEntity, string $fieldName, ClassMetadata $sourceMetadata, ClassMetadata $targetMetadata ) { $methodName = 'get' . ucfirst($fieldName); if (!method_exists($sourceEntity, $methodName)) { $errorMessage = sprintf( 'Failed to find required entity method \'%s::%s\'. The method is required for cascade operations ' . 'of field \'%s\' of target entity \'%s\'', $sourceMetadata->getName(), $methodName, $fieldName, $targetMetadata->getName() ); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage); } try { $targetEntityOrCollection = $sourceEntity->{$methodName}(); } catch (\Throwable $e) { $errorMessage = sprintf( 'The call to resolve entity of type \'%s\' from method call \'%s::%s\' failed: %s', $targetMetadata->getName(), $sourceMetadata->getName(), $methodName, $e->getMessage() ); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage, $e->getCode(), $e); } return $targetEntityOrCollection; } /** * @param EntityInterface|EntityInterface[]|iterable $entityOrCollection * @param array $mapping * * @return bool */ protected function isValidAssociation($entityOrCollection, array $mapping): bool { if (null === $entityOrCollection) { /** * @todo mapping class has a methods to fetch the id field mapping directly * * Note that we are hard coding the '0' key as the single field the we use as the id/primary key. * If we implement EntityInterface correctly we will never have a composite key. */ return isset($mapping['joinColumns'][0]['nullable']) ? (bool)$mapping['joinColumns'][0]['nullable'] : false; } return (is_callable($entityOrCollection) || $entityOrCollection instanceof EntityInterface); } /** * @param EntityManagerInterface $entityManager * @param string $entityName * * @return ClassMetadata * * @throws PersistenceException */ protected function getClassMetadata(EntityManagerInterface $entityManager, string $entityName): ClassMetadata { try { return $entityManager->getClassMetadata($entityName); } catch (\Throwable $e) { $errorMessage = sprintf( 'The entity metadata mapping for class \'%s\' could not be loaded: %s', $entityName, $e->getMessage() ); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage, $e->getCode(), $e); } } } |
|
2 | 1 | \ No newline at end of file |
2 | +<?php declare(strict_types=1); namespace Arp\DoctrineEntityRepository\Persistence; use Arp\DoctrineEntityRepository\EntityRepositoryInterface; use Arp\DoctrineEntityRepository\Persistence\Exception\PersistenceException; use Arp\Entity\EntityInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Psr\Log\LoggerInterface; /** * @author Alex Patterson <[email protected]> * @package Arp\DoctrineEntityRepository\Persistence */ abstract class AbstractCascadeService { /** * @var LoggerInterface */ protected LoggerInterface $logger; /** * @var array */ protected array $options; /** * @var array */ protected array $collectionOptions; /** * @param LoggerInterface $logger * @param array $options * @param array $collectionOptions */ public function __construct(LoggerInterface $logger, array $options = [], array $collectionOptions = []) { $this->logger = $logger; $this->options = $options; $this->collectionOptions = $collectionOptions; } /** * @param EntityManagerInterface $entityManager * @param string $entityName * * @return EntityRepositoryInterface * @throws PersistenceException * @todo We should implement a way to decorate the call the getRepository() with a concrete implementation * of the EntityRepositoryProviderInterface * */ protected function getTargetRepository(EntityManagerInterface $entityManager, string $entityName): EntityRepositoryInterface { try { /** @var EntityRepositoryInterface $targetRepository */ $targetRepository = $entityManager->getRepository($entityName); } catch (\Throwable $e) { $errorMessage = sprintf('An error occurred while attempting to load the repository for entity class \'%s\' : %s', $entityName, $e->getMessage()); $this->logger->error($errorMessage, ['exception' => $e]); throw new PersistenceException($errorMessage, $e->getCode(), $e); } if (null === $targetRepository || !($targetRepository instanceof EntityRepositoryInterface)) { $errorMessage = sprintf('The entity repository must be an object of type \'%s\'; \'%s\' returned in \'%s::%s\'', EntityRepositoryInterface::class, (is_object($targetRepository) ? get_class($targetRepository) : gettype($targetRepository)), static::class, __FUNCTION__); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage); } return $targetRepository; } /** * @param EntityInterface $sourceEntity * @param string $fieldName * @param ClassMetadata $sourceMetadata * @param ClassMetadata $targetMetadata * * @return EntityInterface|EntityInterface[]|iterable * * @throws PersistenceException */ protected function resolveTargetEntityOrCollection(EntityInterface $sourceEntity, string $fieldName, ClassMetadata $sourceMetadata, ClassMetadata $targetMetadata) { $methodName = 'get'.ucfirst($fieldName); if (!method_exists($sourceEntity, $methodName)) { $errorMessage = sprintf('Failed to find required entity method \'%s::%s\'. The method is required for cascade operations '.'of field \'%s\' of target entity \'%s\'', $sourceMetadata->getName(), $methodName, $fieldName, $targetMetadata->getName()); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage); } try { $targetEntityOrCollection = $sourceEntity->{$methodName}(); } catch (\Throwable $e) { $errorMessage = sprintf('The call to resolve entity of type \'%s\' from method call \'%s::%s\' failed: %s', $targetMetadata->getName(), $sourceMetadata->getName(), $methodName, $e->getMessage()); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage, $e->getCode(), $e); } return $targetEntityOrCollection; } /** * @param EntityInterface|EntityInterface[]|iterable $entityOrCollection * @param array $mapping * * @return bool */ protected function isValidAssociation($entityOrCollection, array $mapping): bool { if (null === $entityOrCollection) { /** * @todo mapping class has a methods to fetch the id field mapping directly * * Note that we are hard coding the '0' key as the single field the we use as the id/primary key. * If we implement EntityInterface correctly we will never have a composite key. */ return isset($mapping['joinColumns'][0]['nullable']) ? (bool) $mapping['joinColumns'][0]['nullable'] : false; } return (is_callable($entityOrCollection) || $entityOrCollection instanceof EntityInterface); } /** * @param EntityManagerInterface $entityManager * @param string $entityName * * @return ClassMetadata * * @throws PersistenceException */ protected function getClassMetadata(EntityManagerInterface $entityManager, string $entityName): ClassMetadata { try { return $entityManager->getClassMetadata($entityName); } catch (\Throwable $e) { $errorMessage = sprintf('The entity metadata mapping for class \'%s\' could not be loaded: %s', $entityName, $e->getMessage()); $this->logger->error($errorMessage); throw new PersistenceException($errorMessage, $e->getCode(), $e); } } } |
|
3 | 3 | \ No newline at end of file |
@@ -168,7 +168,7 @@ discard block |
||
168 | 168 | { |
169 | 169 | $entityName = $this->getEntityName(); |
170 | 170 | |
171 | - if (! $entity instanceof $entityName) { |
|
171 | + if (!$entity instanceof $entityName) { |
|
172 | 172 | throw new PersistenceException( |
173 | 173 | sprintf( |
174 | 174 | 'The \'entity\' argument must be an object of type \'%s\'; \'%s\' provided in \'%s\'', |
@@ -251,7 +251,7 @@ discard block |
||
251 | 251 | { |
252 | 252 | $entityName = $this->getEntityName(); |
253 | 253 | |
254 | - if (! $entity instanceof $entityName) { |
|
254 | + if (!$entity instanceof $entityName) { |
|
255 | 255 | throw new PersistenceException( |
256 | 256 | sprintf( |
257 | 257 | 'The \'entity\' argument must be an object of type \'%s\'; \'%s\' provided in \'%s\'', |
@@ -49,7 +49,7 @@ |
||
49 | 49 | $entity = $event->getEntity(); |
50 | 50 | |
51 | 51 | if (null === $entity) { |
52 | - $errorMessage= sprintf('Missing required entity in \'%s\'', static::class); |
|
52 | + $errorMessage = sprintf('Missing required entity in \'%s\'', static::class); |
|
53 | 53 | $this->logger->error($errorMessage); |
54 | 54 | |
55 | 55 | throw new PersistenceException($errorMessage); |
@@ -69,7 +69,7 @@ |
||
69 | 69 | throw new InvalidArgumentException($errorMessage); |
70 | 70 | } |
71 | 71 | |
72 | - if (! $entity instanceof EntityInterface || !$entity instanceof $entityName) { |
|
72 | + if (!$entity instanceof EntityInterface || !$entity instanceof $entityName) { |
|
73 | 73 | $errorMessage = sprintf( |
74 | 74 | 'The entity class of type \'%s\' does not match the expected \'%s\' for event \'%s\'', |
75 | 75 | (is_object($entity) ? get_class($entity) : gettype($entity)), |
@@ -23,7 +23,7 @@ |
||
23 | 23 | { |
24 | 24 | $entity = $event->getEntity(); |
25 | 25 | |
26 | - if (null === $entity || ! $entity instanceof DateUpdatedAwareInterface) { |
|
26 | + if (null === $entity || !$entity instanceof DateUpdatedAwareInterface) { |
|
27 | 27 | return; |
28 | 28 | } |
29 | 29 |
@@ -49,7 +49,7 @@ |
||
49 | 49 | $entity = $event->getEntity(); |
50 | 50 | |
51 | 51 | if (null === $entity) { |
52 | - $errorMessage= sprintf('Missing required entity in \'%s\'', static::class); |
|
52 | + $errorMessage = sprintf('Missing required entity in \'%s\'', static::class); |
|
53 | 53 | $this->logger->error($errorMessage); |
54 | 54 | |
55 | 55 | throw new PersistenceException($errorMessage); |