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