Skip to content

Instantly share code, notes, and snippets.

@uginroot
Last active May 20, 2020 08:34
Show Gist options
  • Save uginroot/33a2851d87bae3e261585c4befea35dc to your computer and use it in GitHub Desktop.
Save uginroot/33a2851d87bae3e261585c4befea35dc to your computer and use it in GitHub Desktop.
Doctrine change identity generator
<?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