- <?php
- namespace EasyCorp\Bundle\EasyAdminBundle\Factory;
- use Doctrine\Common\Util\ClassUtils;
- use Doctrine\Persistence\ManagerRegistry;
- use Doctrine\Persistence\Mapping\ClassMetadata;
- use Doctrine\Persistence\ObjectManager;
- use Doctrine\Persistence\Proxy;
- use EasyCorp\Bundle\EasyAdminBundle\Collection\ActionCollection;
- use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection;
- use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
- use EasyCorp\Bundle\EasyAdminBundle\Dto\ActionConfigDto;
- use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
- use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityBuiltEvent;
- use EasyCorp\Bundle\EasyAdminBundle\Exception\EntityNotFoundException;
- use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
- use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
- use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
- /**
-  * @author Javier Eguiluz <javier.eguiluz@gmail.com>
-  */
- final class EntityFactory
- {
-     private $fieldFactory;
-     private $actionFactory;
-     private $authorizationChecker;
-     private $doctrine;
-     private $eventDispatcher;
-     public function __construct(FieldFactory $fieldFactory, ActionFactory $actionFactory, AuthorizationCheckerInterface $authorizationChecker, ManagerRegistry $doctrine, EventDispatcherInterface $eventDispatcher)
-     {
-         $this->fieldFactory = $fieldFactory;
-         $this->actionFactory = $actionFactory;
-         $this->authorizationChecker = $authorizationChecker;
-         $this->doctrine = $doctrine;
-         $this->eventDispatcher = $eventDispatcher;
-     }
-     public function processFields(EntityDto $entityDto, FieldCollection $fields): void
-     {
-         $this->fieldFactory->processFields($entityDto, $fields);
-     }
-     public function processFieldsForAll(EntityCollection $entities, FieldCollection $fields): void
-     {
-         foreach ($entities as $entity) {
-             $this->processFields($entity, clone $fields);
-             $entities->set($entity);
-         }
-     }
-     public function processActions(EntityDto $entityDto, ActionConfigDto $actionConfigDto): void
-     {
-         $this->actionFactory->processEntityActions($entityDto, $actionConfigDto);
-     }
-     public function processActionsForAll(EntityCollection $entities, ActionConfigDto $actionConfigDto): ActionCollection
-     {
-         foreach ($entities as $entity) {
-             $this->processActions($entity, clone $actionConfigDto);
-         }
-         return $this->actionFactory->processGlobalActions($actionConfigDto);
-     }
-     public function create(string $entityFqcn, $entityId = null, ?string $entityPermission = null): EntityDto
-     {
-         return $this->doCreate($entityFqcn, $entityId, $entityPermission);
-     }
-     public function createForEntityInstance($entityInstance): EntityDto
-     {
-         return $this->doCreate(null, null, null, $entityInstance);
-     }
-     public function createCollection(EntityDto $entityDto, ?iterable $entityInstances): EntityCollection
-     {
-         $entityDtos = [];
-         foreach ($entityInstances as $entityInstance) {
-             $newEntityDto = $entityDto->newWithInstance($entityInstance);
-             $newEntityId = $newEntityDto->getPrimaryKeyValueAsString();
-             if (!$this->authorizationChecker->isGranted(Permission::EA_ACCESS_ENTITY, $newEntityDto)) {
-                 $newEntityDto->markAsInaccessible();
-             }
-             $entityDtos[$newEntityId] = $newEntityDto;
-         }
-         return EntityCollection::new($entityDtos);
-     }
-     public function getEntityMetadata(string $entityFqcn): ClassMetadata
-     {
-         $entityManager = $this->getEntityManager($entityFqcn);
-         $entityMetadata = $entityManager->getClassMetadata($entityFqcn);
-         if (1 !== \count($entityMetadata->getIdentifierFieldNames())) {
-             throw new \RuntimeException(sprintf('EasyAdmin does not support Doctrine entities with composite primary keys (such as the ones used in the "%s" entity).', $entityFqcn));
-         }
-         return $entityMetadata;
-     }
-     private function doCreate(?string $entityFqcn = null, $entityId = null, ?string $entityPermission = null, $entityInstance = null): EntityDto
-     {
-         if (null === $entityInstance && null !== $entityFqcn) {
-             $entityInstance = null === $entityId ? null : $this->getEntityInstance($entityFqcn, $entityId);
-         }
-         if (null !== $entityInstance && null === $entityFqcn) {
-             if ($entityInstance instanceof Proxy) {
-                 $entityInstance->__load();
-             }
-             $entityFqcn = ClassUtils::getClass($entityInstance);
-         }
-         $entityMetadata = $this->getEntityMetadata($entityFqcn);
-         $entityDto = new EntityDto($entityFqcn, $entityMetadata, $entityPermission, $entityInstance);
-         if (!$this->authorizationChecker->isGranted(Permission::EA_ACCESS_ENTITY, $entityDto)) {
-             $entityDto->markAsInaccessible();
-         }
-         $this->eventDispatcher->dispatch(new AfterEntityBuiltEvent($entityDto));
-         return $entityDto;
-     }
-     private function getEntityManager(string $entityFqcn): ObjectManager
-     {
-         if (null === $entityManager = $this->doctrine->getManagerForClass($entityFqcn)) {
-             throw new \RuntimeException(sprintf('There is no Doctrine Entity Manager defined for the "%s" class', $entityFqcn));
-         }
-         return $entityManager;
-     }
-     /**
-      * @return object|null
-      */
-     private function getEntityInstance(string $entityFqcn, $entityIdValue)
-     {
-         $entityManager = $this->getEntityManager($entityFqcn);
-         if (null === $entityInstance = $entityManager->getRepository($entityFqcn)->find($entityIdValue)) {
-             $entityIdName = $entityManager->getClassMetadata($entityFqcn)->getIdentifierFieldNames()[0];
-             throw new EntityNotFoundException(['entity_name' => $entityFqcn, 'entity_id_name' => $entityIdName, 'entity_id_value' => $entityIdValue]);
-         }
-         return $entityInstance;
-     }
- }
-