protected function applyRevision(Entity &$entity, $revision_payload) { global $user; // Preserve the original entity. $original_entity = clone $entity; // Apply changes to the entity. $entity->definition = (object) array_replace_recursive((array) $entity->definition, (array) $revision_payload['additions']); // Apply deletions to the entity. $deletions_definition = (array) $entity->definition; $keys_to_delete = array(); $this->applyRevisionDeletions($deletions_definition, $revision_payload['deletions'], $keys_to_delete); $entity->definition = (object) $deletions_definition; // Run the beforeDependencies preparer. $preparer_registry = new PreparerRegistry(); $preparer_registry->beforeDependencies($entity); // Revert references. $unresolver = new Unresolver($entity); $entity->definition = $unresolver->unresolvedDefinition(); // Check to see if there were any errors reverting references. if ($errors = $unresolver->errors()) { $this->transaction->addErrors($errors); return false; // Stop processing this entity if there were errors. } // Unset the node VID and the user ID. $entity->definition->revision = true; if (isset($entity->definition->revision_uid)) { $user->uid = $entity->definition->revision_uid; } elseif (isset($entity->definition->uid)) { $user->uid = $entity->definition->uid; } // Get the old stuff for the node. $old_revision_information = array('uid' => $user->uid, 'vuuid' => $entity->vuuid()); // Set unchanging properties to the node that was sent. $unchanging_properties = publisher_get_unchanging_properties($entity->type()); foreach ($unchanging_properties as $property) { if (!isset($revision_payload['additions'][$property])) { continue; } $entity->definition->{$property} = $revision_payload['additions'][$property]; } // Get the revision table for the entity. $entity_info = entity_get_info($entity->type()); if (array_key_exists('revision table', $entity_info)) { $revision_table = $entity_info['revision table']; $revision_key = $entity_info['entity keys']['revision']; $revision_uuid_key = $entity_info['entity keys']['revision uuid']; } // Update the VID to an existing revision. if ($entity->supportsRevisions() && isset($revision_key)) { $this->setEntityRevisionID($entity->vuuid(), $entity); } // Run the preparers beforeSave. $preparer_registry->beforeSave($entity); // Run the entity handlers with the metadata. foreach (EntityHandlerRegistry::getEntityHandlers($entity) as $handler) { if (!$handler instanceof EntityHandlerBase) { continue; } $handler->entity =& $entity; $handler->original_entity = $original_entity; $handler->unhandleRevision($this->getEntityFromMetadata($entity->uuid())); } // Save the entity. try { $entity->save(); } catch (\Exception $ex) { // ...and try to catch any exceptions thrown by this (sometimes, the exceptions still aren't caught). $this->transaction->addError($ex); return false; } if (isset($revision_table) && isset($revision_key)) { // Reset the UID and VUUID for the revision. $cloned_definition = clone $entity->definition; $cloned_definition->uid = $old_revision_information['uid']; $cloned_definition->{$revision_uuid_key} = $old_revision_information['vuuid']; drupal_write_record($revision_table, $cloned_definition, $revision_key); // Delete duplicate revisions that no longer apply. $this->checkForDuplicateRevisions($cloned_definition, $entity); // Reset the revision cache in the entity class. Entity::getLatestRevisionID($entity->id(), $entity->type(), true); } // Run the preparers afterSave events. $preparer_registry->afterSave($entity); return true; }
public function diff() { // Get the preparer registry. $preparer_registry = new PreparerRegistry(); if (!$this->revisions_table) { // Prepare the entity. $preparer_registry->beforeSend($this->entity); $resolver = new Resolver($this->entity); return array($this->entity->vuuid() => array('additions' => $resolver->resolvedDefinition(), 'deletions' => array())); } // Get the revisions in between the two mentioned. If the old is blank, get the entire history. $revision_ids = $this->getRevisionHistory($this->old_revision_id, $this->new_revision_id); if ($revision_ids === false) { return false; } $payload = array(); $before_id = $this->old_revision_id ? $this->old_revision_id : -1; foreach ($revision_ids as $current_id) { // Load the entities. if ($before_id === -1) { $old_entity = null; } else { $old_entity = clone $this->entity; $old_entity->setRevision($before_id); } $new_entity = clone $this->entity; $new_entity->setRevision($current_id); // Pass the entity through the preparers to add any additional field metadata. if ($old_entity !== null) { $preparer_registry->beforeSend($old_entity); } $preparer_registry->beforeSend($new_entity); $payload[$current_id . '|' . $new_entity->vuuid()] = $this->singleDiff($old_entity, $new_entity); // Update the before ID. $before_id = $current_id; } return $payload; }