From 7bfe1c44dcfb199f5ef70b7326eb9b71cfbebc56 Mon Sep 17 00:00:00 2001 From: Mathieu Girard Date: Thu, 23 Feb 2023 16:47:16 +0100 Subject: [PATCH] =?UTF-8?q?Correction=20sur=20la=20d=C3=A9tection=20des=20?= =?UTF-8?q?changements=20pour=20UnitOfWork?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DoctrineCiphersweetSubscriber.php | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/Subscribers/DoctrineCiphersweetSubscriber.php b/src/Subscribers/DoctrineCiphersweetSubscriber.php index 5397463..850ffc6 100644 --- a/src/Subscribers/DoctrineCiphersweetSubscriber.php +++ b/src/Subscribers/DoctrineCiphersweetSubscriber.php @@ -46,6 +46,8 @@ class DoctrineCiphersweetSubscriber implements EventSubscriber */ private array $postFlushDecryptQueue = []; + private array $entitiesToEncrypt = []; + private IndexableFieldsService $indexableFieldsService; private PropertyHydratorService $propertyHydratorService; @@ -84,6 +86,12 @@ public function onFlush(OnFlushEventArgs $args): void foreach ($unitOfWork->getScheduledEntityUpdates() as $entity) { $this->entityOnFlush($entity, $em); $unitOfWork->recomputeSingleEntityChangeSet($em->getClassMetadata(\get_class($entity)), $entity); + unset($this->entitiesToEncrypt[spl_object_id($entity)]); + } + + foreach ($this->entitiesToEncrypt as $entity) { + $this->entityOnFlush($entity, $em); + $unitOfWork->recomputeSingleEntityChangeSet($em->getClassMetadata(\get_class($entity)), $entity); } } @@ -105,7 +113,7 @@ public function onClear(OnClearEventArgs $args): void */ private function entityOnFlush(object $entity, EntityManagerInterface $em): void { - $objId = spl_object_hash($entity); + $objId = spl_object_id($entity); $fields = []; @@ -161,7 +169,7 @@ public function processFields(object $entity, EntityManagerInterface $em, $isEnc $properties = $this->getEncryptedFields($entity, $em); $unitOfWork = $em->getUnitOfWork(); - $oid = spl_object_hash($entity); + $oid = spl_object_id($entity); $entityClassName = $em->getClassMetadata(get_class($entity))->getName(); @@ -175,8 +183,12 @@ public function processFields(object $entity, EntityManagerInterface $em, $isEnc $context = $this->buildContext($entityClassName, $refProperty); if ($isEncryptOperation) { - $value = $this->handleEncryptOperation($entity, $oid, $value, $refProperty, $em, $context, $force); + $value = $this->handleEncryptOperation($entity, $oid, $value, $refProperty, $context, $force); } else { + $oldValue = $value; + if (!$this->isValueEncrypted($oldValue)) { + $this->entitiesToEncrypt[$oid] = $entity; + } $value = $this->handleDecryptOperation($oid, $value, $refProperty, $context); } @@ -189,7 +201,7 @@ public function processFields(object $entity, EntityManagerInterface $em, $isEnc if (!$isEncryptOperation && !\defined('_DONOTENCRYPT')) { //we don't want the object to be dirty immediately after reading - $unitOfWork->setOriginalEntityProperty($oid, $refProperty->getName(), $value); + $unitOfWork->setOriginalEntityProperty(spl_object_id($entity), $refProperty->getName(), $value); } } @@ -224,10 +236,9 @@ private function buildContext(string $entityClassName, \ReflectionProperty $refP /** * @param object $entity - * @param string $oid + * @param int $oid * @param mixed $value * @param \ReflectionProperty $refProperty - * @param EntityManagerInterface $em * @param array $context * @param string|null $force * @return mixed|string|null @@ -235,7 +246,7 @@ private function buildContext(string $entityClassName, \ReflectionProperty $refP * @throws \Odandb\DoctrineCiphersweetEncryptionBundle\Exception\UndefinedGeneratorException * @throws \ReflectionException */ - private function handleEncryptOperation(object $entity, string $oid, $value, \ReflectionProperty $refProperty, EntityManagerInterface $em, array $context, ?string $force = null) + private function handleEncryptOperation(object $entity, int $oid, $value, \ReflectionProperty $refProperty, array $context, ?string $force = null) { /** * @var IndexableField $indexableAnnotationConfig @@ -280,13 +291,13 @@ private function handleEncryptOperation(object $entity, string $oid, $value, \Re } /** - * @param string $oid + * @param int $oid * @param mixed $value * @param \ReflectionProperty $refProperty * @param array $context * @return string */ - private function handleDecryptOperation(string $oid, $value, \ReflectionProperty $refProperty, array $context): string + private function handleDecryptOperation(int $oid, $value, \ReflectionProperty $refProperty, array $context): string { /** * @var IndexableField $indexableAnnotationConfig @@ -376,12 +387,12 @@ private function storeIndexes(object $entity, \ReflectionProperty $refProperty, */ public function postFlush(PostFlushEventArgs $args): void { - $unitOfWork = $args->getEntityManager()->getUnitOfWork(); + $unitOfWork = $args->getObjectManager()->getUnitOfWork(); foreach ($this->postFlushDecryptQueue as $pair) { $fieldPairs = $pair['fields']; $entity = $pair['entity']; - $oid = spl_object_hash($entity); + $oid = spl_object_id($entity); foreach ($fieldPairs as $fieldPair) { /** @var \ReflectionProperty $field */ @@ -402,7 +413,7 @@ public function postFlush(PostFlushEventArgs $args): void */ private function addToDecodedRegistry($entity): void { - $this->decodedRegistry[spl_object_hash($entity)] = true; + $this->decodedRegistry[spl_object_id($entity)] = true; } /** @@ -411,8 +422,8 @@ private function addToDecodedRegistry($entity): void */ public function postLoad(LifecycleEventArgs $args): void { - $entity = $args->getEntity(); - if (!$this->hasInDecodedRegistry($entity) && $this->processFields($entity, $args->getEntityManager(), false)) { + $entity = $args->getObject(); + if (!$this->hasInDecodedRegistry($entity) && $this->processFields($entity, $args->getObjectManager(), false)) { $this->addToDecodedRegistry($entity); } } @@ -424,7 +435,7 @@ public function postLoad(LifecycleEventArgs $args): void */ private function hasInDecodedRegistry(object $entity): bool { - return isset($this->decodedRegistry[spl_object_hash($entity)]); + return isset($this->decodedRegistry[spl_object_id($entity)]); } /**