added DiffTaskResultService, including revert logic
This commit is contained in:
parent
5b6470a53b
commit
a0e91fbf7b
3 changed files with 163 additions and 0 deletions
9
lib/Exceptions/AlreadyRevertedException.php
Normal file
9
lib/Exceptions/AlreadyRevertedException.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\GroupfolderFilesystemSnapshots\Exceptions;
|
||||||
|
|
||||||
|
class AlreadyRevertedException extends \RuntimeException {
|
||||||
|
public function __construct(string $message = 'Diff task result has already been reverted.') {
|
||||||
|
parent::__construct($message);
|
||||||
|
}
|
||||||
|
}
|
9
lib/Exceptions/ChangesMadeSinceDiffException.php
Normal file
9
lib/Exceptions/ChangesMadeSinceDiffException.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\GroupfolderFilesystemSnapshots\Exceptions;
|
||||||
|
|
||||||
|
class ChangesMadeSinceDiffException extends \RuntimeException {
|
||||||
|
public function __construct(string $message = 'Conflicting changes have been made to the files, since the restore process started') {
|
||||||
|
parent::__construct($message);
|
||||||
|
}
|
||||||
|
}
|
145
lib/Service/DiffTaskResultService.php
Normal file
145
lib/Service/DiffTaskResultService.php
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
namespace OCA\GroupfolderFilesystemSnapshots\Service;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Db\DoesNotExistException;
|
||||||
|
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||||
|
|
||||||
|
use OCA\GroupfolderFilesystemSnapshots\Exceptions\NotFoundException;
|
||||||
|
use OCA\GroupfolderFilesystemSnapshots\Exceptions\AlreadyRevertedException;
|
||||||
|
use OCA\GroupfolderFilesystemSnapshots\Exceptions\ChangesMadeSinceDiffException;
|
||||||
|
|
||||||
|
use OCA\GroupfolderFilesystemSnapshots\Db\DiffTaskResult;
|
||||||
|
use OCA\GroupfolderFilesystemSnapshots\Db\DiffTaskResultMapper;
|
||||||
|
use OCA\GroupfolderFilesystemSnapshots\Db\DiffTaskMapper;
|
||||||
|
use OCA\GroupfolderFilesystemSnapshots\Manager\PathManager;
|
||||||
|
|
||||||
|
class DiffTaskResultService {
|
||||||
|
|
||||||
|
private DiffTaskResultMapper $mapper;
|
||||||
|
private DiffTaskMapper $diffTaskMapper;
|
||||||
|
private PathManager $pathManager;
|
||||||
|
|
||||||
|
public function __construct(DiffTaskResultMapper $mapper, DiffTaskMapper $diffTaskMapper, PathManager $pathManager){
|
||||||
|
$this->mapper = $mapper;
|
||||||
|
$this->diffTaskMapper = $diffTaskMapper;
|
||||||
|
$this->pathManager = $pathManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DiffTaskResult[]
|
||||||
|
*/
|
||||||
|
public function findAll(int $taskId): array {
|
||||||
|
return $this->mapper->findAll($taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return never
|
||||||
|
*/
|
||||||
|
private function handleException ($e, $criteria) {
|
||||||
|
if ($e instanceof DoesNotExistException ||
|
||||||
|
$e instanceof MultipleObjectsReturnedException) {
|
||||||
|
throw new NotFoundException($e->getMessage(), $criteria);
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find(int $id): DiffTaskResult {
|
||||||
|
try {
|
||||||
|
return $this->mapper->find($id);
|
||||||
|
} catch(Exception $e) {
|
||||||
|
$this->handleException($e, ["id" => $id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revert(int $id, string $userId) {
|
||||||
|
$diffTaskResult = $this->find($id);
|
||||||
|
|
||||||
|
if($diffTaskResult->getReverted()) {
|
||||||
|
throw new AlreadyRevertedException;
|
||||||
|
}
|
||||||
|
|
||||||
|
$taskId = $diffTaskResult->getTaskId();
|
||||||
|
$diffTask = $this->diffTaskMapper->find($taskId, $userId);
|
||||||
|
|
||||||
|
$snapshotPath = $this->pathManager->getGroupFolderSnapshotDirectory($diffTask->getGroupfolderId(), $diffTask->getRelativePath(), $diffTask->getSnapshotId());
|
||||||
|
|
||||||
|
$gruenerFolder = $this->pathManager->getGroupfolderMountById($diffTask->getGroupfolderId())->get($diffTask->getRelativePath());
|
||||||
|
|
||||||
|
switch($diffTaskResult->getType()) {
|
||||||
|
case "CREATION":
|
||||||
|
$currentFile = $this->getSubfolderMustExist($gruenerFolder, $diffTaskResult->getCurrentPath());
|
||||||
|
$currentFile->delete();
|
||||||
|
break;
|
||||||
|
case "RENAME":
|
||||||
|
$currentFile = $this->getSubfolderMustExist($gruenerFolder, $diffTaskResult->getCurrentPath());
|
||||||
|
$beforeDirectory = $this->getOrCreateSubdirectoryByFilepath($gruenerFolder, $diffTaskResult->getBeforePath());
|
||||||
|
|
||||||
|
$currentFile->move($beforeDirectory->getPath() . DIRECTORY_SEPARATOR . basename($diffTaskResult->getBeforePath()));
|
||||||
|
break;
|
||||||
|
case "DELETION":
|
||||||
|
$beforeFileFilesystemPath = $snapshotPath . DIRECTORY_SEPARATOR . $diffTaskResult->getBeforePath();
|
||||||
|
|
||||||
|
$beforeDirectory = $this->getOrCreateSubdirectoryByFilepath($gruenerFolder, $diffTaskResult->getBeforePath());
|
||||||
|
$restoredFile = $beforeDirectory->newFile(basename($diffTaskResult->getBeforePath()));
|
||||||
|
|
||||||
|
$this->copyFilesystemFileToNextcloudFile($beforeFileFilesystemPath, $restoredFile);
|
||||||
|
break;
|
||||||
|
case "EDIT":
|
||||||
|
$currentFile = $this->getSubfolderMustExist($gruenerFolder, $diffTaskResult->getCurrentPath());
|
||||||
|
$beforeFileFilesystemPath = $snapshotPath . DIRECTORY_SEPARATOR . $diffTaskResult->getBeforePath();
|
||||||
|
|
||||||
|
$this->copyFilesystemFileToNextcloudFile($beforeFileFilesystemPath, $currentFile);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->mapper->markReverted($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSubfolderMustExist(\OCP\Files\Folder $parent, string $path) {
|
||||||
|
if($parent->nodeExists($path)) {
|
||||||
|
return $parent->get($path);
|
||||||
|
} else {
|
||||||
|
throw new ChangesMadeSinceDiffException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getOrCreateSubdirectoryByFilepath(\OCP\Files\Folder $parent, string $filepath) {
|
||||||
|
$pathSplit = explode('/', trim($filepath, '/'));
|
||||||
|
array_pop($pathSplit);
|
||||||
|
|
||||||
|
$beforeDirectory = $parent;
|
||||||
|
foreach($pathSplit as $subdir) {
|
||||||
|
if($beforeDirectory->nodeExists($subdir)) {
|
||||||
|
$temp = $beforeDirectory->get($subdir);
|
||||||
|
if($temp instanceof \OCP\Files\Folder) {
|
||||||
|
$beforeDirectory = $temp;
|
||||||
|
} else {
|
||||||
|
throw new ChangesMadeSinceDiffException;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$beforeDirectory = $beforeDirectory->newFolder($subdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $beforeDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function copyFilesystemFileToNextcloudFile(string $filesystemPath, \OCP\Files\File $nextcloudFile) {
|
||||||
|
$snapshotFileStream = fopen($filesystemPath, 'r');
|
||||||
|
$snapshotFileMtime = filemtime($filesystemPath);
|
||||||
|
|
||||||
|
$restoredFileStream = $nextcloudFile->fopen('w');
|
||||||
|
|
||||||
|
stream_copy_to_stream($snapshotFileStream, $restoredFileStream);
|
||||||
|
|
||||||
|
fclose($snapshotFileStream);
|
||||||
|
fclose($restoredFileStream);
|
||||||
|
|
||||||
|
$nextcloudFile->touch($snapshotFileMtime);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue