Extra updates for entities are stored as (entity, changeset) tuples.
public scheduleExtraUpdate ( object $entity, array $changeset ) | ||
$entity | object | The entity for which to schedule an extra update. |
$changeset | array | The changeset of the entity (what to update). |
/** * Updates modification date for a source. * * @param SourceInterface $source * @param UnitOfWork $uow */ protected function setSourceModificationDate(SourceInterface $source, UnitOfWork $uow) { $uow->scheduleExtraUpdate($source, ['datetimeModified' => [0 => $source->getDatetimeModified(), 1 => new \DateTime()]]); }
/** * Updates a field * * @param ORM\UnitOfWork $uow * @param mixed $object * @param ORM\Mapping\ClassMetadata $classMetadata * @param string $field */ private function updateField(ORM\UnitOfWork $uow, $object, ORM\Mapping\ClassMetadata $classMetadata, $field) { $property = $classMetadata->getReflectionProperty($field); $oldValue = $property->getValue($object); $newValue = $this->getDateValue($classMetadata, $field); $property->setValue($object, $newValue); $uow->propertyChanged($object, $field, $oldValue, $newValue); $uow->scheduleExtraUpdate($object, [$field => [$oldValue, $newValue]]); }
/** * Flush for update * * @param object $entity * @param \Doctrine\ORM\EntityManager $entityManager * @param \Doctrine\ORM\UnitOfWork $unitOfWork */ protected function onFlushForUpdates(&$entity, EntityManager &$entityManager, UnitOfWork &$unitOfWork) { $className = get_class($entity); $this->initializeAnnotationsForEntity($className); if (count(self::$storedProperties[$className]['annotations']) > 0) { foreach (self::$storedProperties[$className]['annotations'] as $propertyName => &$annotations) { /* @var $annotation Traceable */ foreach ($annotations as $annotation) { $run = $annotation->on === 'update'; if ($annotation->on === 'change') { $changeSet = $unitOfWork->getEntityChangeSet($entity); if (isset($changeSet[$annotation->field])) { $type = $this->getPropertyType($className, $annotation->field); $values = $annotation->getFieldValues($type, $entity); $run = count($values) === 0 || in_array($changeSet[$annotation->field][1], $values); } } if ($run) { list($oldValue, $value) = $this->updateEntityPropertyValue($entity, $className, $propertyName, $annotation); $entityManager->persist($entity); $unitOfWork->propertyChanged($entity, $propertyName, $oldValue, $value); $unitOfWork->scheduleExtraUpdate($entity, array($propertyName => array($oldValue, $value))); break; } } } } }
public function onFlush(OnFlushEventArgs $eventArgs) { if (!$this->active) { return; } // Clear updateData $this->updateData = $this->extraUpdates = array(); $this->em = $eventArgs->getEntityManager(); $this->conn = $this->em->getConnection(); $this->uow = $this->em->getUnitOfWork(); $this->platform = $this->conn->getDatabasePlatform(); $this->revisionId = null; // reset revision $this->draft = false; $processedEntities = array(); foreach ($this->uow->getScheduledEntityDeletions() as $entity) { if (!$this->annotationReader->isRevised(get_class($entity), true)) { continue; } //doctrine is fine deleting elements multiple times. We are not. $hash = $this->getHash($entity); if (in_array($hash, $processedEntities)) { continue; } $processedEntities[] = $hash; $this->extraUpdates[spl_object_hash($entity)] = $entity; $persister = $this->uow->getEntityPersister(get_class($entity)); $this->updateData[spl_object_hash($entity)] = $this->prepareUpdateData($persister, $entity); $entityData = array_merge($this->getOriginalEntityData($entity), $this->uow->getEntityIdentifier($entity)); $this->saveRevisionEntityData($this->em->getClassMetadata(get_class($entity)), $entityData, 'DEL'); if ($this->annotationReader->isDraft($entity) && $entity->isDraft()) { $this->resetRevisedData($entity); $this->setRevisionInfo($entity); $persister = $this->uow->getEntityPersister(get_class($entity)); $this->updateData[spl_object_hash($entity)] = $this->prepareUpdateData($persister, $entity); $fieldName = 'deletedAt'; $reflProp = new \ReflectionProperty($entity, $fieldName); $reflProp->setAccessible(true); $oldValue = $reflProp->getValue($entity); $reflProp->setValue($entity, null); $this->uow->scheduleExtraUpdate($entity, array($fieldName => array($oldValue, null))); } if (isset($this->softDeletes[spl_object_hash($entity)])) { $this->em->persist($entity); } } foreach ($this->uow->getScheduledEntityInsertions() as $entity) { if (!$this->annotationReader->isRevised(get_class($entity), true)) { continue; } $this->setRevisionInfo($entity); $this->extraUpdates[spl_object_hash($entity)] = $entity; $persister = $this->uow->getEntityPersister(get_class($entity)); $this->updateData[spl_object_hash($entity)] = $this->prepareUpdateData($persister, $entity); if ($this->annotationReader->isDraft($entity) && $entity->isDraft()) { $this->insertDrafts[spl_object_hash($entity)] = $entity; $this->resetRevisedData($entity); $this->uow->recomputeSingleEntityChangeSet($this->em->getClassMetadata(get_class($entity)), $entity); } } foreach ($this->uow->getScheduledEntityUpdates() as $entity) { if (!$this->annotationReader->isRevised(get_class($entity), true)) { continue; } $this->setRevisionInfo($entity); $this->extraUpdates[spl_object_hash($entity)] = $entity; $persister = $this->uow->getEntityPersister(get_class($entity)); $this->updateData[spl_object_hash($entity)] = $this->prepareUpdateData($persister, $entity); if ($this->annotationReader->isDraft($entity) && $entity->isDraft()) { $this->resetRevisedData($entity); } } }