Beispiel #1
0
 /**
  * Push all recorded changes to the backend.
  *
  * The order is important to avoid conflicts
  * 1. operationsLog
  * 2. commit any other changes
  *
  * If transactions are enabled but we are not currently inside a
  * transaction, the session is responsible to start a transaction to make
  * sure the backend state does not get messed up in case of error.
  */
 public function save()
 {
     if (!$this->transport instanceof WritingInterface) {
         throw new UnsupportedRepositoryOperationException('Transport does not support writing');
     }
     try {
         $this->transport->prepareSave();
         $this->executeOperations($this->operationsLog);
         // loop through cached nodes and commit all dirty and set them to clean.
         if (isset($this->objectsByPath['Node'])) {
             foreach ($this->objectsByPath['Node'] as $node) {
                 /** @var $node Node */
                 if ($node->isModified()) {
                     if (!$node instanceof NodeInterface) {
                         throw new RepositoryException('Internal Error: Unknown type ' . get_class($node));
                     }
                     $this->transport->updateProperties($node);
                     if ($node->needsChildReordering()) {
                         $this->transport->reorderChildren($node);
                     }
                 }
             }
         }
         $this->transport->finishSave();
     } catch (\Exception $e) {
         $this->transport->rollbackSave();
         if (!$e instanceof RepositoryException) {
             throw new RepositoryException('Error inside the transport layer: ' . $e->getMessage(), null, $e);
         }
         throw $e;
     }
     foreach ($this->operationsLog as $operation) {
         if ($operation instanceof MoveNodeOperation) {
             if (isset($this->objectsByPath['Node'][$operation->dstPath])) {
                 // might not be set if moved again afterwards
                 // move is not treated as modified, need to confirm separately
                 $this->objectsByPath['Node'][$operation->dstPath]->confirmSaved();
             }
         }
     }
     //clear those lists before reloading the newly added nodes from backend, to avoid collisions
     $this->nodesRemove = array();
     $this->propertiesRemove = array();
     $this->nodesMove = array();
     foreach ($this->operationsLog as $operation) {
         if ($operation instanceof AddNodeOperation) {
             if (!$operation->node->isDeleted()) {
                 $operation->node->confirmSaved();
             }
         }
     }
     if (isset($this->objectsByPath['Node'])) {
         foreach ($this->objectsByPath['Node'] as $item) {
             /** @var $item Item */
             if ($item->isModified() || $item->isMoved()) {
                 $item->confirmSaved();
             }
         }
     }
     $this->nodesAdd = array();
     $this->operationsLog = array();
 }