Passed
Push — master ( 9daee1...553543 )
by Morris
11:21
created

LegacyVersionsBackend   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 48
dl 0
loc 86
rs 10
c 0
b 0
f 0
wmc 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getVersionsForFile() 0 25 2
A __construct() 0 3 1
A getVersionFolder() 0 9 2
A rollback() 0 2 1
A read() 0 5 1
A createVersion() 0 13 1
A getVersionFile() 0 6 1
A useBackendForStorage() 0 2 1
1
<?php declare(strict_types=1);
2
/**
3
 * @copyright Copyright (c) 2018 Robin Appelman <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace OCA\Files_Versions\Versions;
23
24
use OC\Files\View;
25
use OCA\Files_Sharing\SharedStorage;
26
use OCA\Files_Versions\Storage;
27
use OCP\Files\File;
28
use OCP\Files\FileInfo;
29
use OCP\Files\Folder;
30
use OCP\Files\IRootFolder;
31
use OCP\Files\NotFoundException;
32
use OCP\Files\Storage\IStorage;
33
use OCP\IUser;
34
use OCP\IUserManager;
35
36
class LegacyVersionsBackend implements IVersionBackend {
37
	/** @var IRootFolder */
38
	private $rootFolder;
39
	/** @var IUserManager */
40
	private $userManager;
41
42
	public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
43
		$this->rootFolder = $rootFolder;
44
		$this->userManager = $userManager;
45
	}
46
47
	public function useBackendForStorage(IStorage $storage): bool {
48
		return true;
49
	}
50
51
	public function getVersionsForFile(IUser $user, FileInfo $file): array {
52
		$storage = $file->getStorage();
53
		if ($storage->instanceOfStorage(SharedStorage::class)) {
54
			$owner = $storage->getOwner('');
55
			$user = $this->userManager->get($owner);
56
		}
57
58
		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
59
		$nodes = $userFolder->getById($file->getId());
60
		$file2 = array_pop($nodes);
61
		$versions = Storage::getVersions($user->getUID(), $userFolder->getRelativePath($file2->getPath()));
62
63
		return array_map(function (array $data) use ($file, $user) {
64
			return new Version(
65
				(int)$data['version'],
66
				(int)$data['version'],
67
				$data['name'],
68
				(int)$data['size'],
69
				$data['mimetype'],
70
				$data['path'],
71
				$file,
72
				$this,
73
				$user
74
			);
75
		}, $versions);
76
	}
77
78
	public function createVersion(IUser $user, FileInfo $file) {
79
		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
80
		$relativePath = $userFolder->getRelativePath($file->getPath());
81
		$userView = new View('/' . $user->getUID());
82
		// create all parent folders
83
		Storage::createMissingDirectories($relativePath, $userView);
84
85
		Storage::scheduleExpire($user->getUID(), $relativePath);
86
87
		// store a new version of a file
88
		$userView->copy('files/' . $relativePath, 'files_versions/' . $relativePath . '.v' . $file->getMtime());
89
		// ensure the file is scanned
90
		$userView->getFileInfo('files_versions/' . $relativePath . '.v' . $file->getMtime());
91
	}
92
93
	public function rollback(IVersion $version) {
94
		return Storage::rollback($version->getVersionPath(), $version->getRevisionId());
95
	}
96
97
	private function getVersionFolder(IUser $user): Folder {
98
		$userRoot = $this->rootFolder->getUserFolder($user->getUID())
99
			->getParent();
100
		try {
101
			/** @var Folder $folder */
102
			$folder = $userRoot->get('files_versions');
103
			return $folder;
104
		} catch (NotFoundException $e) {
105
			return $userRoot->newFolder('files_versions');
106
		}
107
	}
108
109
	public function read(IVersion $version) {
110
		$versions = $this->getVersionFolder($version->getUser());
111
		/** @var File $file */
112
		$file = $versions->get($version->getVersionPath() . '.v' . $version->getRevisionId());
113
		return $file->fopen('r');
114
	}
115
116
	public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
117
		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
118
		$versionFolder = $this->getVersionFolder($user);
119
		/** @var File $file */
120
		$file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()) . '.v' . $revision);
121
		return $file;
122
	}
123
}
124