Last active
May 20, 2020 08:34
-
-
Save uginroot/33a2851d87bae3e261585c4befea35dc to your computer and use it in GitHub Desktop.
Doctrine change identity generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Helper; | |
use Doctrine\ORM\EntityManagerInterface; | |
use Doctrine\ORM\Id\AbstractIdGenerator; | |
use Doctrine\ORM\Mapping\ClassMetadata; | |
use ReflectionClass; | |
use RuntimeException; | |
class ChangeIdentityGeneratorHelper | |
{ | |
/** | |
* @var EntityManagerInterface | |
*/ | |
private $entityManager; | |
private $conditionIdentityMap = []; | |
public function __construct(EntityManagerInterface $entityManager) | |
{ | |
$this->entityManager = $entityManager; | |
} | |
private function saveCondition(ClassMetadata $metadata): void | |
{ | |
if(array_key_exists($metadata->getName(), $this->conditionIdentityMap)){ | |
throw new RuntimeException(sprintf('Class %s condition already exist', $metadata->getName())); | |
} | |
$this->conditionIdentityMap[$metadata->getName()] = [$metadata->idGenerator, $metadata->generatorType]; | |
} | |
private function restoreCondition(ClassMetadata $metadata): void | |
{ | |
if(!array_key_exists($metadata->getName(), $this->conditionIdentityMap)){ | |
throw new RuntimeException(sprintf('Class %s condition not found', $metadata->getName())); | |
} | |
[$idGenerator, $idGeneratorType] = $this->conditionIdentityMap[$metadata->getName()]; | |
$this->replaceIdentity($metadata, $idGeneratorType, $idGenerator); | |
} | |
private function replaceIdentity( | |
ClassMetadata $metadata, | |
int $generatorType, | |
AbstractIdGenerator $abstractIdGenerator | |
): void | |
{ | |
$metadata->setIdGeneratorType($generatorType); | |
$metadata->setIdGenerator($abstractIdGenerator); | |
} | |
private function resetInsertSql(ClassMetadata $classMetadata): void | |
{ | |
$uow = $this->entityManager->getUnitOfWork(); | |
$persister = $uow->getEntityPersister($classMetadata->getName()); | |
$class = new ReflectionClass($persister); | |
$property = $class->getProperty('insertSql'); | |
$property->setAccessible(true); | |
$property->setValue($persister, null); | |
$property->setAccessible(false); | |
} | |
private function getMetadata(string $entityClass): ClassMetadata | |
{ | |
return $this->entityManager->getClassMetadata($entityClass); | |
} | |
public function changeIdentity(string $entityClass, int $generatorType, AbstractIdGenerator $abstractIdGenerator):void | |
{ | |
$metadata = $this->getMetadata($entityClass); | |
$this->saveCondition($metadata); | |
$this->replaceIdentity($metadata, $generatorType, $abstractIdGenerator); | |
$this->resetInsertSql($metadata); | |
} | |
public function restoreIdentity(string $entityClass):void | |
{ | |
$metadata = $this->getMetadata($entityClass); | |
$this->restoreCondition($metadata); | |
$this->resetInsertSql($metadata); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment