computeChangeSet() public method

Modifies/populates the following properties: {@link _originalEntityData} If the entity is NEW or MANAGED but not yet fully persisted (only has an id) then it was not fetched from the database and therefore we have no original entity data yet. All of the current entity data is stored as the original entity data. {@link _entityChangeSets} The changes detected on all properties of the entity are stored there. A change is a tuple array where the first entry is the old value and the second entry is the new value of the property. Changesets are used by persisters to INSERT/UPDATE the persistent entity state. {@link _entityUpdates} If the entity is already fully MANAGED (has been fetched from the database before) and any changes to its properties are detected, then a reference to the entity is stored there to mark it for an update. {@link _collectionDeletions} If a PersistentCollection has been de-referenced in a fully MANAGED entity, then this collection is marked for deletion.
public computeChangeSet ( 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 compute the changes.
 /**
  * @param OnFlushEventArgs $args
  */
 public function onFlush(OnFlushEventArgs $args)
 {
     $this->initializeFromEventArgs($args);
     $entities = array_merge($this->uow->getScheduledEntityInsertions(), $this->uow->getScheduledEntityDeletions(), $this->uow->getScheduledEntityUpdates());
     /** @var Opportunity[] $entities */
     $entities = array_filter($entities, function ($entity) {
         return 'OroCRM\\Bundle\\SalesBundle\\Entity\\Opportunity' === ClassUtils::getClass($entity);
     });
     foreach ($entities as $entity) {
         if (!$entity->getId() && $this->isValuable($entity)) {
             // handle creation, just add to prev lifetime value and recalculate change set
             $b2bCustomer = $entity->getCustomer();
             $b2bCustomer->setLifetime($b2bCustomer->getLifetime() + $entity->getCloseRevenue());
             $this->scheduleUpdate($b2bCustomer);
             $this->uow->computeChangeSet($this->em->getClassMetadata(ClassUtils::getClass($b2bCustomer)), $b2bCustomer);
         } elseif ($this->uow->isScheduledForDelete($entity) && $this->isValuable($entity)) {
             $this->scheduleUpdate($entity->getCustomer());
         } elseif ($this->uow->isScheduledForUpdate($entity)) {
             // handle update
             $changeSet = $this->uow->getEntityChangeSet($entity);
             if ($this->isChangeSetValuable($changeSet)) {
                 if (!empty($changeSet['customer']) && $changeSet['customer'][0] instanceof B2bCustomer && B2bCustomerRepository::VALUABLE_STATUS === $this->getOldStatus($entity, $changeSet)) {
                     // handle change of b2b customer
                     $this->scheduleUpdate($changeSet['customer'][0]);
                 }
                 if ($this->isValuable($entity, isset($changeSet['closeRevenue'])) || B2bCustomerRepository::VALUABLE_STATUS === $this->getOldStatus($entity, $changeSet) && $entity->getCustomer()) {
                     $this->scheduleUpdate($entity->getCustomer());
                 }
             }
         }
     }
 }
 /**
  * Deletes an entity if it is in relation to another entity
  *
  * Doctrine is obviously unable to entities detached from the relational entity when merging the relational entity,
  * so this had to be implemented.
  *
  * @param object $relationalEntity
  * @param string $fieldName
  * @param ClassMetadata $metadata
  * @param boolean $recomputeChangeSet
  */
 public function deleteOnRelationalModification($relationalEntity, $fieldName, ClassMetadata $metadata, $recomputeChangeSet = true)
 {
     if ($recomputeChangeSet) {
         $this->unitOfWork->computeChangeSet($metadata, $relationalEntity);
     }
     $changeSet = $this->unitOfWork->getEntityChangeSet($relationalEntity);
     if (!isset($changeSet[$fieldName])) {
         return;
     }
     $orgValue = $changeSet[$fieldName][0];
     if (null !== $orgValue && $this->entityManager->contains($orgValue)) {
         $this->entityManager->remove($orgValue);
     }
 }
Example #3
0
 /**
  * @param EntityManager $em
  * @param UnitOfWork    $uow
  * @param User          $entity
  * @param Organization  $organization
  */
 protected function createCalendar($em, $uow, $entity, $organization)
 {
     // create a default calendar for assigned organization
     $calendar = new Calendar();
     $calendar->setOwner($entity);
     $calendar->setOrganization($organization);
     // connect the calendar to itself
     $calendarConnection = new CalendarConnection($calendar);
     $calendar->addConnection($calendarConnection);
     $em->persist($calendar);
     $em->persist($calendarConnection);
     $uow->computeChangeSet($this->getClassMetadata($calendar, $em), $calendar);
     $uow->computeChangeSet($this->getClassMetadata($calendarConnection, $em), $calendarConnection);
 }
 /**
  * @param Ticket $ticket
  */
 protected function startAutoReply(Ticket $ticket)
 {
     $ticketText = $ticket->getSubject() . ' ' . $ticket->getDescription();
     $repository = $this->registry->getManager()->getRepository('DiamanteDeskBundle:Article');
     $results = [];
     /** @var Article $article */
     foreach ($repository->findByStatus(1) as $article) {
         $articleText = $article->getTitle() . ' ' . $article->getContent();
         $results[$article->getId()] = $this->compare($ticketText, $articleText);
     }
     $maxResult = max($results);
     /**
      * TODO: should be configured by admin
      */
     if ($maxResult < 3) {
         return;
     }
     $articleId = array_search(max($results), $results);
     /**
      * TODO: should be extracted from previous call of $repository->getAll()
      */
     $article = $repository->find($articleId);
     /**
      * TODO: should be extracted from configuration???
      */
     $user = User::fromString('oro_1');
     $content = $this->getAutoReplayNoticeHtml() . $article->getContent();
     $comment = new Comment($content, $ticket, $user, false);
     $this->registry->getManager()->persist($comment);
     $this->uow->computeChangeSet($this->em->getClassMetadata($comment->getClassName()), $comment);
     /**
      * TODO: should be executed workflowEven?
      */
 }
 /**
  * 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);
     }
 }
 /**
  * Do the stuff
  *
  * @param TaggableInterface $entity
  * @param boolean           $update true if entity is being updated, false otherwise
  */
 protected function setTags(TaggableInterface $entity, $update = false)
 {
     $tagNames = $entity->getTagNames();
     if (empty($tagNames)) {
         return;
     }
     // need to clone here, to avoid getting new tags
     $oldTags = is_object($entityTags = $entity->getTags()) ? clone $entityTags : $entityTags;
     $tagClassMetadata = $this->em->getClassMetadata(get_class($this->tag));
     $repository = $this->em->getRepository(get_class($this->tag));
     foreach ($tagNames as $tagName) {
         $tag = $repository->findOneByName($tagName);
         if (empty($tag)) {
             // if tag doesn't exist, create it
             $tag = clone $this->tag;
             $tag->setName($tagName);
             $this->em->persist($tag);
             // see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#onflush
             $this->uow->computeChangeSet($tagClassMetadata, $tag);
         }
         if (!$entity->hasTag($tag)) {
             // add tag only if not already added
             $entity->addTag($tag);
         }
     }
     // if updating, need to check if some tags were removed
     if ($update) {
         foreach ($oldTags as $oldTag) {
             if (!in_array($oldTag->getName(), $tagNames)) {
                 $entity->removeTag($oldTag);
             }
         }
     }
     // see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#onflush
     $entityClassMetadata = $this->em->getClassMetadata(get_class($entity));
     $this->uow->computeChangeSets($entityClassMetadata, $entity);
 }
 /**
  * Compute changeset
  * @param object $entity
  */
 protected function computeChangeset($entity)
 {
     $this->uow->persist($entity);
     $this->uow->computeChangeSet($this->getMetadata($entity), $entity);
 }
 /**
  * Manage urls.
  *
  * @param View $page
  *
  * @return void
  */
 protected function updateBusinessPageUrl(BusinessPage $page, EntityManager $em, UnitOfWork $uow)
 {
     $oldSlug = $page->getSlug();
     $staticUrl = $page->getStaticUrl();
     $computedPage = $this->businessPageBuilder->generateEntityPageFromTemplate($page->getTemplate(), $page->getBusinessEntity(), $em);
     $newSlug = $computedPage->getSlug();
     if ($staticUrl) {
         $staticUrl = preg_replace('/' . $oldSlug . '/', $newSlug, $staticUrl);
         $page->setStaticUrl($staticUrl);
     }
     $page->setSlug($newSlug);
     $meta = $em->getClassMetadata(get_class($page));
     $em->persist($page);
     $uow->computeChangeSet($meta, $page);
 }
Example #9
0
 /**
  * Record the route history of the page
  *
  * @param WebViewInterface $view
  * @param string           $initialUrl
  */
 protected function addRouteHistory(WebViewInterface $view, $initialUrl, UnitOfWork $uow, EntityManager $entityManager)
 {
     $route = new Route();
     $route->setUrl($initialUrl);
     $route->setView($view);
     $meta = $entityManager->getClassMetadata(get_class($route));
     $entityManager->persist($route);
     $uow->computeChangeSet($meta, $route);
     //add the route to the page
     $view->addRoute($route);
 }
Example #10
0
 /**
  * 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);
                     }
                 }
             }
         }
     }
 }
Example #11
0
 /**
  * @param EntityManager $em
  * @param UnitOfWork    $uow
  * @param User          $user
  * @param Organization  $organization
  */
 protected function createCalendar($em, $uow, $user, $organization)
 {
     // create default user's calendar
     $calendar = new Calendar();
     $calendar->setOwner($user)->setOrganization($organization);
     $em->persist($calendar);
     $uow->computeChangeSet($this->getClassMetadata($calendar, $em), $calendar);
     $this->insertedCalendars[] = $calendar;
 }
 /**
  * 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;
     }
 }