/** * 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(); }