/** * {@inheritdoc} */ public function save(EntityInterface $entity) { // We return SAVED_UPDATED by default because the logic below might not // update the entity if its values haven't changed, so returning FALSE // would be confusing in that situation. $return = SAVED_UPDATED; $transaction = $this->database->startTransaction(); try { // Load the stored entity, if any. if (!$entity->isNew() && !isset($entity->original)) { $id = $entity->id(); if ($entity->getOriginalId() !== NULL) { $id = $entity->getOriginalId(); } $entity->original = $this->loadUnchanged($id); } if ($entity->isNew()) { $entity->mlid = $this->database->insert($this->entityType->getBaseTable())->fields(array('menu_name' => $entity->menu_name))->execute(); $entity->enforceIsNew(); } // Unlike the save() method from EntityDatabaseStorage, we invoke the // 'presave' hook first because we want to allow modules to alter the // entity before all the logic from our preSave() method. $this->invokeHook('presave', $entity); $entity->preSave($this); // If every value in $entity->original is the same in the $entity, there // is no reason to run the update queries or clear the caches. We use // array_intersect_key() with the $entity as the first parameter because // $entity may have additional keys left over from building a router entry. // The intersect removes the extra keys, allowing a meaningful comparison. if ($entity->isNew() || array_intersect_key(get_object_vars($entity), get_object_vars($entity->original)) != get_object_vars($entity->original)) { $return = drupal_write_record($this->entityType->getBaseTable(), $entity, $this->idKey); if ($return) { if (!$entity->isNew()) { $this->resetCache(array($entity->{$this->idKey})); $entity->postSave($this, TRUE); $this->invokeHook('update', $entity); } else { $return = SAVED_NEW; $this->resetCache(); $entity->enforceIsNew(FALSE); $entity->postSave($this, FALSE); $this->invokeHook('insert', $entity); } } } // Ignore replica server temporarily. db_ignore_replica(); unset($entity->original); return $return; } catch (\Exception $e) { $transaction->rollback(); watchdog_exception($this->entityTypeId, $e); throw new EntityStorageException($e->getMessage(), $e->getCode(), $e); } }
/** * {@inheritdoc} */ public function save(EntityInterface $entity) { $id = $entity->id(); // Track the original ID. if ($entity->getOriginalId() !== NULL) { $id = $entity->getOriginalId(); } // Track if this entity is new. $is_new = $entity->isNew(); // Track if this entity exists already. $id_exists = $this->has($id, $entity); // A new entity should not already exist. if ($id_exists && $is_new) { throw new EntityStorageException(SafeMarkup::format('@type entity with ID @id already exists.', array('@type' => $this->entityTypeId, '@id' => $id))); } // Load the original entity, if any. if ($id_exists && !isset($entity->original)) { $entity->original = $this->loadUnchanged($id); } // Allow code to run before saving. $entity->preSave($this); $this->invokeHook('presave', $entity); // Perform the save and reset the static cache for the changed entity. $return = $this->doSave($id, $entity); $this->resetCache(array($id)); // The entity is no longer new. $entity->enforceIsNew(FALSE); // Allow code to run after saving. $entity->postSave($this, !$is_new); $this->invokeHook($is_new ? 'insert' : 'update', $entity); // After saving, this is now the "original entity", and subsequent saves // will be updates instead of inserts, and updates must always be able to // correctly identify the original entity. $entity->setOriginalId($entity->id()); unset($entity->original); return $return; }
/** * Performs presave entity processing. * * @param \Drupal\Core\Entity\EntityInterface $entity * The saved entity. * * @return int|string * The processed entity identifier. * * @throws \Drupal\Core\Entity\EntityStorageException * If the entity identifier is invalid. */ protected function doPreSave(EntityInterface $entity) { $id = $entity->id(); // Track the original ID. if ($entity->getOriginalId() !== NULL) { $id = $entity->getOriginalId(); } // Track if this entity exists already. $id_exists = $this->has($id, $entity); // A new entity should not already exist. if ($id_exists && $entity->isNew()) { throw new EntityStorageException("'{$this->entityTypeId}' entity with ID '{$id}' already exists."); } // Load the original entity, if any. if ($id_exists && !isset($entity->original)) { $entity->original = $this->loadUnchanged($id); } // Allow code to run before saving. $entity->preSave($this); $this->invokeHook('presave', $entity); return $id; }