/**
* Store the document content to its origin
* @NoAdminRequired
*/
public function save()
{
$response = new JSONResponse();
try {
$esId = $this->request->server['HTTP_WEBODF_SESSION_ID'];
$session = $this->loadSession($esId);
$memberId = $this->request->server['HTTP_WEBODF_MEMBER_ID'];
$currentMember = $this->loadMember($memberId, $esId);
// Extra info for future usage
// $sessionRevision = $this->request->server['HTTP_WEBODF_SESSION_REVISION'];
//NB ouch! New document content is passed as an input stream content
$stream = fopen('php://input', 'r');
if (!$stream) {
throw new \Exception('New content missing');
}
$content = stream_get_contents($stream);
try {
if ($currentMember->getIsGuest()) {
$file = File::getByShareToken($currentMember->getToken());
} else {
$file = new File($session->getFileId());
}
$view = $file->getOwnerView(true);
$path = $file->getPath(true);
} catch (\Exception $e) {
//File was deleted or unshared. We need to save content as new file anyway
//Sorry, but for guests it would be lost :(
if ($this->uid) {
$view = new View('/' . $this->uid . '/files');
$dir = \OC::$server->getConfig()->getUserValue($this->uid, 'richdocuments', 'save_path', '');
$path = Helper::getNewFileName($view, $dir . 'New Document.odt');
} else {
throw $e;
}
}
$member = new Db\Member();
$members = $member->getActiveCollection($esId);
$memberIds = array_map(function ($x) {
return $x['member_id'];
}, $members);
// Active users except current user
$memberCount = count($memberIds) - 1;
if ($view->file_exists($path)) {
$currentHash = $view->hash('sha1', $path, false);
if (!Helper::isVersionsEnabled() && $currentHash !== $session->getGenesisHash()) {
// Original file was modified externally. Save to a new one
$path = Helper::getNewFileName($view, $path, '-conflict');
}
$mimetype = $view->getMimeType($path);
} else {
$mimetype = Storage::MIMETYPE_LIBREOFFICE_WORDPROCESSOR;
}
$data = Filter::write($content, $mimetype);
if ($view->file_put_contents($path, $data['content'])) {
// Not a last user
if ($memberCount > 0) {
// Update genesis hash to prevent conflicts
$this->logger->debug('Update hash', ['app' => $this->appName]);
$session->updateGenesisHash($esId, sha1($data['content']));
} else {
// Last user. Kill session data
Db\Session::cleanUp($esId);
}
$view->touch($path);
}
$response->setData(['status' => 'success']);
} catch (\Exception $e) {
$response->setStatus(Http::STATUS_INTERNAL_SERVER_ERROR);
$response->setData([]);
$this->logger->warning('Saving failed. Reason:' . $e->getMessage(), ['app' => $this->appName]);
}
return $response;
}