The passed entity must be a managed entity. If the entity already has a change set
because this method is invoked during a commit cycle then the change sets are added.
whereby changes detected in this method prevail.
public recomputeSingleEntityChangeSet ( Doctrine\ORM\Mapping\ClassMetadata $class, object $entity ) | ||
$class | Doctrine\ORM\Mapping\ClassMetadata | The class descriptor of the entity. |
$entity | object | The entity for which to (re)calculate the change set. |
public function onFlush(OnFlushEventArgs $e) { $this->init($e); foreach ($this->uow->getScheduledEntityInsertions() as $entity) { if ($entity instanceof RoundedEntityInterface) { $entity->setRound($this->round); $this->uow->recomputeSingleEntityChangeSet($this->em->getClassMetadata(get_class($entity)), $entity); } } //$this->uow->computeChangeSets(); }
/** * Computes or re-computes changes of given entity. * * @param $entity * * @author Andreas Glaser */ protected function computeChangeSet($entity) { if ($this->unitOfWork->getEntityChangeSet($entity)) { $this->unitOfWork->recomputeSingleEntityChangeSet($this->entityManager->getClassMetadata(get_class($entity)), $entity); } else { $this->unitOfWork->computeChangeSet($this->entityManager->getClassMetadata(get_class($entity)), $entity); } }
/** * @param $changeset The changeset for the entity * @param $expectedFields List of filds which should be updated/set * * @dataProvider provideLifecycle */ public function testOnFlush($changeset, $expectedFields) { $entity = $this->userBlameObject->reveal(); $this->unitOfWork->getScheduledEntityInsertions()->willReturn([$entity]); $this->unitOfWork->getScheduledEntityUpdates()->willReturn([]); $this->entityManager->getClassMetadata(get_class($entity))->willReturn($this->classMetadata); $this->unitOfWork->getEntityChangeSet($this->userBlameObject->reveal())->willReturn($changeset); foreach (['creator', 'changer'] as $field) { $prophecy = $this->classMetadata->setFieldValue($this->userBlameObject->reveal(), $field, $this->user->reveal()); if (in_array($field, $expectedFields)) { $prophecy->shouldBeCalled(); continue; } $prophecy->shouldNotBeCalled(); } if (count($expectedFields)) { $this->unitOfWork->recomputeSingleEntityChangeSet($this->classMetadata->reveal(), $this->userBlameObject->reveal())->shouldBeCalled(); } $this->subscriber->onFlush($this->onFlushEvent->reveal()); }
/** * @param array $entities * @param EntityManagerInterface $entityManager */ private function processEntities($entities, EntityManagerInterface $entityManager, UnitOfWork $unitOfWork) { foreach ($entities as $customer) { if (!$customer instanceof CustomerInterface) { continue; } $user = $customer->getUser(); if (null === $user) { continue; } if ($customer->getEmail() === $user->getUsername() && $customer->getEmailCanonical() === $user->getUsernameCanonical()) { continue; } $user->setUsername($customer->getEmail()); $user->setUsernameCanonical($customer->getEmailCanonical()); /** @var ClassMetadata $userMetadata */ $userMetadata = $entityManager->getClassMetadata(get_class($user)); $unitOfWork->recomputeSingleEntityChangeSet($userMetadata, $user); } }
/** * Builds the page's url by get all page parents slugs and implode them with "/". * Builds the pages children urls with new page slug * If page has a custom url, we don't modify it, but we modify children urls * @param WebViewInterface $view * @param integer $depth * * @return void */ public function buildUrl(WebViewInterface $view, UnitOfWork $uow, EntityManager $entityManager, $depth = 0) { $initialUrl = $view->getUrl(); // build url binded with parents url if (method_exists($view, 'isHomepage') && $view->isHomepage()) { $url = array(''); } else { $url = array($view->getSlug()); } //get the slug of the parents $url = $this->getParentSlugs($view, $url); //reorder the list of slugs $url = array_reverse($url); //build an url based on the slugs $url = implode('/', $url); //get the next free url $url = $this->getNextAvailaibleUrl($url, $entityManager); //update url of the view $view->setUrl($url); //the metadata of the page $meta = $entityManager->getClassMetadata(get_class($view)); if ($depth === 0) { $uow->recomputeSingleEntityChangeSet($meta, $view); } else { $uow->computeChangeSet($meta, $view); } $this->rebuildChildrenUrl($view, $uow, $entityManager, $depth); if ($view->getId()) { $this->addRouteHistory($view, $initialUrl, $uow, $entityManager); } }
protected function populateMeta(EntityManager $em, UnitOfWork $uow, ImageInterface $entity) { $meta = $em->getClassMetadata(get_class($entity)); $meta->getReflectionProperty('size')->setValue($entity, $this->imageManager->getTemporaryImage($entity)->getSize()); $uow->recomputeSingleEntityChangeSet($meta, $entity); }
/** * Takes an entity and works out whether it has a relation to CMF's URL Model. If so, * it updates the properties of the associated URL object. * * @param object $entity * @param \Doctrine\ORM\EntityManager $em * @param \Doctrine\ORM\UnitOfWork|null $uow * @return void */ protected function process(&$entity, &$em, &$uow) { $entity_class = get_class($entity); $entity_namespace = trim(\CMF::slug(str_replace('\\', '/', \Inflector::get_namespace($entity_class))), '/'); $metadata = $em->getClassMetadata($entity_class); // Ignore URL entities themselves if ($metadata->name == 'CMF\\Model\\URL') { return; } $url_associations = $metadata->getAssociationsByTargetClass('CMF\\Model\\URL'); if (!empty($url_associations)) { // A bit hacky, but if this is a root tree item don't bother if (property_exists($entity, 'is_root') && $entity->is_root === true) { return; } $url_field = null; foreach ($url_associations as $key => $association) { if ($association['type'] == ClassMetadataInfo::ONE_TO_ONE && $association['orphanRemoval']) { $url_field = $key; break; } } if ($url_field == null) { return; } $settings = $entity->settings(); $url_settings = isset($settings[$url_field]) ? $settings[$url_field] : array(); $url_item = $entity->get($url_field); if ($new_url = is_null($url_item)) { $url_item = new \CMF\Model\URL(); } // Don't run if this is an alias... $alias = $url_item->alias; if (!is_null($alias) && !empty($alias)) { return; } // Don't run if this is an external link... if ($url_item->isExternal()) { return; } $prefix = $this->getPrefix($entity); $slug = ''; if (isset($url_settings['keep_updated']) && !$url_settings['keep_updated']) { $slug = \CMF::slug($url_item->slug); } else { $slug = $entity->urlSlug(); } $url = $prefix . $slug; if ($url != '/') { $url = rtrim($url, '/'); } $current_url = $url_item->url; $entity_id = $entity->id; $url_id = $url_item->get('id'); // Check for duplicates, only if this is an already existing item if (!empty($entity_id) && !is_null($entity_id)) { // Set data from the entity if the prefix is null if (is_null($prefix)) { $prefix = $this->getPrefix($entity); $url = $prefix . $slug; } // Set data from the entity if the slug is null if (is_null($slug)) { $slug = $entity->urlSlug(); $url = $prefix . $slug; } // Set it to the item's ID if empty if (is_null($slug)) { $slug = $entity_id . ""; $url = $prefix . $slug; } $slug_orig = $slug; $unique = $this->checkUnique($url, $entity_id, $url_id); $counter = 2; while (!$unique) { $slug = $slug_orig . '-' . $counter; $url = $prefix . $slug; $unique = $this->checkUnique($url, $entity_id, $url_id); $counter++; } // Add it to the list of saved URLs $this->savedUrls[$url] = $entity_id; } $url_item->set('item_id', $entity->get('id')); $url_item->set('prefix', $prefix); $url_item->set('slug', $slug); $url_item->set('url', $url); $url_item->set('type', $metadata->name); $entity->set($url_field, $url_item); $em->persist($url_item); // Skip this if the url hasn't changed if (!$new_url && $current_url == $url) { return; } $url_metadata = $em->getClassMetadata('CMF\\Model\\URL'); $url_changeset = $uow->getEntityChangeSet($url_item); if (!empty($url_changeset)) { $uow->recomputeSingleEntityChangeSet($url_metadata, $url_item); } else { $uow->computeChangeSet($url_metadata, $url_item); } $uow->recomputeSingleEntityChangeSet($metadata, $entity); $associations = $metadata->getAssociationMappings(); foreach ($associations as $association_name => $association) { // Only do it if it's the inverse side, to prevent the dreaded infinite recursion if (!$association['isOwningSide']) { $items = $entity->{$association_name}; if (!empty($items)) { foreach ($items as $item) { $this->process($item, $em, $uow); } } } } } }
/** * @param object $entity Entity to recompute change set */ protected function recomputeChangeSet($entity) { $this->checkIfInitialized(); $this->uow->recomputeSingleEntityChangeSet($this->em->getClassMetadata(ClassUtils::getClass($entity)), $entity); }
/** * Recompute the single object changeset from a UnitOfWork. * * @param \Doctrine\ORM\UnitOfWork $uow * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $meta * @param object $object * @return null */ public function recomputeSingleObjectChangeSet(UnitOfWork $uow, ClassMetadataInfo $meta, $object) { $uow->recomputeSingleEntityChangeSet($meta, $object); }
/** * @param $entity */ private function recoumputeChanges($entity) { if ($this->uow->getEntityChangeSet($entity)) { $this->uow->recomputeSingleEntityChangeSet($this->em->getClassMetadata(get_class($entity)), $entity); } }
/** * Generates new full path and validates its uniqueness * @param PageLocalization $pageData * @return PageLocalization if changes were made */ protected function generatePath(PageLocalization $pageData, $force = false) { $page = $pageData->getMaster(); $oldPath = $pageData->getPath(); $changes = false; $oldPathEntity = $pageData->getPathEntity(); list($newPath, $active, $limited, $inSitemap) = $this->findPagePath($pageData); if (!$page->isRoot()) { if (!Path::compare($oldPath, $newPath) || $force) { $suffix = null; // Check duplicates only if path is not null if (!is_null($newPath)) { // Additional check for path length $pathString = $newPath->getPath(); if (mb_strlen($pathString) > 255) { throw new Exception\RuntimeException('Overall path length shouldn\'t be more than 255 symbols'); } $i = 2; $e = null; $pathPart = $pageData->getPathPart(); $pathValid = false; do { try { $this->checkForDuplicates($pageData, $newPath); $pathValid = true; } catch (DuplicatePagePathException $e) { if ($force) { // loop stoper if ($i > 101) { throw new Exception\RuntimeException("Couldn't find unique path for new page", null, $e); } // Will try adding unique suffix after 100 iterations if ($i > 100) { $suffix = uniqid(); } else { $suffix = $i; } $pageData->setPathPart($pathPart . '-' . $suffix); list($newPath, $active, $limited, $inSitemap) = $this->findPagePath($pageData); $i++; } } } while ($force && !$pathValid); if ($e instanceof DuplicatePagePathException && !$pathValid) { throw $e; } } // Validation passed, set the new path $pageData->setPathData($newPath, $active, $limited, $inSitemap); if (!is_null($suffix)) { $pageData->setTitle($pageData->getTitle() . " ({$suffix})"); } $changes = true; } } elseif ($page->getLeftValue() == 1) { $newPath = new Path(''); // Root page if (!$newPath->equals($oldPath)) { $changes = true; $pageData->setPathData($newPath, $active, $limited, $inSitemap); } // Another root page... } else { $newPath = null; $active = false; $pageData->setPathData($newPath, $active, $limited, $inSitemap); } if ($oldPathEntity->isActive() !== $active || $oldPathEntity->isVisibleInSitemap() != $inSitemap) { $pageData->setPathData($newPath, $active, $limited, $inSitemap); $changes = true; } if ($changes) { $pathEntity = $pageData->getPathEntity(); $pathMetaData = $this->em->getClassMetadata($pathEntity->CN()); $localizationMetaData = $this->em->getClassMetadata($pageData->CN()); if ($this->unitOfWork->getEntityState($pathEntity, UnitOfWork::STATE_NEW) === UnitOfWork::STATE_NEW) { $this->em->persist($pathEntity); // } elseif ($this->unitOfWork->getEntityState($pathEntity) === UnitOfWork::STATE_DETACHED) { // $pathEntity = $this->em->merge($pathEntity); } /* * Add the path changes to the changeset, must call different * methods depending on is the entity inside the unit of work * changeset */ if ($this->unitOfWork->getEntityChangeSet($pathEntity)) { $this->unitOfWork->recomputeSingleEntityChangeSet($pathMetaData, $pathEntity); } else { $this->unitOfWork->computeChangeSet($pathMetaData, $pathEntity); } if ($this->unitOfWork->getEntityChangeSet($pageData)) { $this->unitOfWork->recomputeSingleEntityChangeSet($localizationMetaData, $pageData); } else { $this->unitOfWork->computeChangeSet($localizationMetaData, $pageData); } return $pageData; } }
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); } } }