Passed
Push — master ( c4d71c...15ef35 )
by Morris
13:37 queued 11s
created
apps/files_versions/lib/Versions/IVersionManager.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -25,12 +25,12 @@
 block discarded – undo
25 25
  * @since 15.0.0
26 26
  */
27 27
 interface IVersionManager extends IVersionBackend {
28
-	/**
29
-	 * Register a new backend
30
-	 *
31
-	 * @param string $storageType
32
-	 * @param IVersionBackend $backend
33
-	 * @since 15.0.0
34
-	 */
35
-	public function registerBackend(string $storageType, IVersionBackend $backend);
28
+    /**
29
+     * Register a new backend
30
+     *
31
+     * @param string $storageType
32
+     * @param IVersionBackend $backend
33
+     * @since 15.0.0
34
+     */
35
+    public function registerBackend(string $storageType, IVersionBackend $backend);
36 36
 }
Please login to merge, or discard this patch.
apps/files_versions/lib/Versions/Version.php 1 patch
Indentation   +84 added lines, -84 removed lines patch added patch discarded remove patch
@@ -26,88 +26,88 @@
 block discarded – undo
26 26
 use OCP\IUser;
27 27
 
28 28
 class Version implements IVersion {
29
-	/** @var int */
30
-	private $timestamp;
31
-
32
-	/** @var int */
33
-	private $revisionId;
34
-
35
-	/** @var string */
36
-	private $name;
37
-
38
-	/** @var int */
39
-	private $size;
40
-
41
-	/** @var string */
42
-	private $mimetype;
43
-
44
-	/** @var string */
45
-	private $path;
46
-
47
-	/** @var FileInfo */
48
-	private $sourceFileInfo;
49
-
50
-	/** @var IVersionBackend */
51
-	private $backend;
52
-
53
-	/** @var IUser */
54
-	private $user;
55
-
56
-	public function __construct(
57
-		int $timestamp,
58
-		int $revisionId,
59
-		string $name,
60
-		int $size,
61
-		string $mimetype,
62
-		string $path,
63
-		FileInfo $sourceFileInfo,
64
-		IVersionBackend $backend,
65
-		IUser $user
66
-	) {
67
-		$this->timestamp = $timestamp;
68
-		$this->revisionId = $revisionId;
69
-		$this->name = $name;
70
-		$this->size = $size;
71
-		$this->mimetype = $mimetype;
72
-		$this->path = $path;
73
-		$this->sourceFileInfo = $sourceFileInfo;
74
-		$this->backend = $backend;
75
-		$this->user = $user;
76
-	}
77
-
78
-	public function getBackend(): IVersionBackend {
79
-		return $this->backend;
80
-	}
81
-
82
-	public function getSourceFile(): FileInfo {
83
-		return $this->sourceFileInfo;
84
-	}
85
-
86
-	public function getRevisionId(): int {
87
-		return $this->revisionId;
88
-	}
89
-
90
-	public function getTimestamp(): int {
91
-		return $this->timestamp;
92
-	}
93
-
94
-	public function getSize(): int {
95
-		return $this->size;
96
-	}
97
-
98
-	public function getSourceFileName(): string {
99
-		return $this->name;
100
-	}
101
-
102
-	public function getMimeType(): string {
103
-		return $this->mimetype;
104
-	}
105
-
106
-	public function getVersionPath(): string {
107
-		return $this->path;
108
-	}
109
-
110
-	public function getUser(): IUser {
111
-		return $this->user;
112
-	}
29
+    /** @var int */
30
+    private $timestamp;
31
+
32
+    /** @var int */
33
+    private $revisionId;
34
+
35
+    /** @var string */
36
+    private $name;
37
+
38
+    /** @var int */
39
+    private $size;
40
+
41
+    /** @var string */
42
+    private $mimetype;
43
+
44
+    /** @var string */
45
+    private $path;
46
+
47
+    /** @var FileInfo */
48
+    private $sourceFileInfo;
49
+
50
+    /** @var IVersionBackend */
51
+    private $backend;
52
+
53
+    /** @var IUser */
54
+    private $user;
55
+
56
+    public function __construct(
57
+        int $timestamp,
58
+        int $revisionId,
59
+        string $name,
60
+        int $size,
61
+        string $mimetype,
62
+        string $path,
63
+        FileInfo $sourceFileInfo,
64
+        IVersionBackend $backend,
65
+        IUser $user
66
+    ) {
67
+        $this->timestamp = $timestamp;
68
+        $this->revisionId = $revisionId;
69
+        $this->name = $name;
70
+        $this->size = $size;
71
+        $this->mimetype = $mimetype;
72
+        $this->path = $path;
73
+        $this->sourceFileInfo = $sourceFileInfo;
74
+        $this->backend = $backend;
75
+        $this->user = $user;
76
+    }
77
+
78
+    public function getBackend(): IVersionBackend {
79
+        return $this->backend;
80
+    }
81
+
82
+    public function getSourceFile(): FileInfo {
83
+        return $this->sourceFileInfo;
84
+    }
85
+
86
+    public function getRevisionId(): int {
87
+        return $this->revisionId;
88
+    }
89
+
90
+    public function getTimestamp(): int {
91
+        return $this->timestamp;
92
+    }
93
+
94
+    public function getSize(): int {
95
+        return $this->size;
96
+    }
97
+
98
+    public function getSourceFileName(): string {
99
+        return $this->name;
100
+    }
101
+
102
+    public function getMimeType(): string {
103
+        return $this->mimetype;
104
+    }
105
+
106
+    public function getVersionPath(): string {
107
+        return $this->path;
108
+    }
109
+
110
+    public function getUser(): IUser {
111
+        return $this->user;
112
+    }
113 113
 }
Please login to merge, or discard this patch.
apps/files_versions/lib/Versions/IVersion.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -29,71 +29,71 @@
 block discarded – undo
29 29
  * @since 15.0.0
30 30
  */
31 31
 interface IVersion {
32
-	/**
33
-	 * @return IVersionBackend
34
-	 * @since 15.0.0
35
-	 */
36
-	public function getBackend(): IVersionBackend;
32
+    /**
33
+     * @return IVersionBackend
34
+     * @since 15.0.0
35
+     */
36
+    public function getBackend(): IVersionBackend;
37 37
 
38
-	/**
39
-	 * Get the file info of the source file
40
-	 *
41
-	 * @return FileInfo
42
-	 * @since 15.0.0
43
-	 */
44
-	public function getSourceFile(): FileInfo;
38
+    /**
39
+     * Get the file info of the source file
40
+     *
41
+     * @return FileInfo
42
+     * @since 15.0.0
43
+     */
44
+    public function getSourceFile(): FileInfo;
45 45
 
46
-	/**
47
-	 * Get the id of the revision for the file
48
-	 *
49
-	 * @return int
50
-	 * @since 15.0.0
51
-	 */
52
-	public function getRevisionId(): int;
46
+    /**
47
+     * Get the id of the revision for the file
48
+     *
49
+     * @return int
50
+     * @since 15.0.0
51
+     */
52
+    public function getRevisionId(): int;
53 53
 
54
-	/**
55
-	 * Get the timestamp this version was created
56
-	 *
57
-	 * @return int
58
-	 * @since 15.0.0
59
-	 */
60
-	public function getTimestamp(): int;
54
+    /**
55
+     * Get the timestamp this version was created
56
+     *
57
+     * @return int
58
+     * @since 15.0.0
59
+     */
60
+    public function getTimestamp(): int;
61 61
 
62
-	/**
63
-	 * Get the size of this version
64
-	 *
65
-	 * @return int
66
-	 * @since 15.0.0
67
-	 */
68
-	public function getSize(): int;
62
+    /**
63
+     * Get the size of this version
64
+     *
65
+     * @return int
66
+     * @since 15.0.0
67
+     */
68
+    public function getSize(): int;
69 69
 
70
-	/**
71
-	 * Get the name of the source file at the time of making this version
72
-	 *
73
-	 * @return string
74
-	 * @since 15.0.0
75
-	 */
76
-	public function getSourceFileName(): string;
70
+    /**
71
+     * Get the name of the source file at the time of making this version
72
+     *
73
+     * @return string
74
+     * @since 15.0.0
75
+     */
76
+    public function getSourceFileName(): string;
77 77
 
78
-	/**
79
-	 * Get the mimetype of this version
80
-	 *
81
-	 * @return string
82
-	 * @since 15.0.0
83
-	 */
84
-	public function getMimeType(): string;
78
+    /**
79
+     * Get the mimetype of this version
80
+     *
81
+     * @return string
82
+     * @since 15.0.0
83
+     */
84
+    public function getMimeType(): string;
85 85
 
86
-	/**
87
-	 * Get the path of this version
88
-	 *
89
-	 * @return string
90
-	 * @since 15.0.0
91
-	 */
92
-	public function getVersionPath(): string;
86
+    /**
87
+     * Get the path of this version
88
+     *
89
+     * @return string
90
+     * @since 15.0.0
91
+     */
92
+    public function getVersionPath(): string;
93 93
 
94
-	/**
95
-	 * @return IUser
96
-	 * @since 15.0.0
97
-	 */
98
-	public function getUser(): IUser;
94
+    /**
95
+     * @return IUser
96
+     * @since 15.0.0
97
+     */
98
+    public function getUser(): IUser;
99 99
 }
Please login to merge, or discard this patch.
apps/files_versions/lib/Versions/VersionManager.php 2 patches
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -27,67 +27,67 @@
 block discarded – undo
27 27
 use OCP\IUser;
28 28
 
29 29
 class VersionManager implements IVersionManager {
30
-	/** @var IVersionBackend[] */
31
-	private $backends = [];
30
+    /** @var IVersionBackend[] */
31
+    private $backends = [];
32 32
 
33
-	public function registerBackend(string $storageType, IVersionBackend $backend) {
34
-		$this->backends[$storageType] = $backend;
35
-	}
33
+    public function registerBackend(string $storageType, IVersionBackend $backend) {
34
+        $this->backends[$storageType] = $backend;
35
+    }
36 36
 
37
-	/**
38
-	 * @return IVersionBackend[]
39
-	 */
40
-	private function getBackends(): array {
41
-		return $this->backends;
42
-	}
37
+    /**
38
+     * @return IVersionBackend[]
39
+     */
40
+    private function getBackends(): array {
41
+        return $this->backends;
42
+    }
43 43
 
44
-	/**
45
-	 * @param IStorage $storage
46
-	 * @return IVersionBackend
47
-	 * @throws BackendNotFoundException
48
-	 */
49
-	public function getBackendForStorage(IStorage $storage): IVersionBackend {
50
-		$fullType = get_class($storage);
51
-		$backends = $this->getBackends();
52
-		$foundType = array_reduce(array_keys($backends), function ($type, $registeredType) use ($storage) {
53
-			if (
54
-				$storage->instanceOfStorage($registeredType) &&
55
-				($type === '' || is_subclass_of($registeredType, $type))
56
-			) {
57
-				return $registeredType;
58
-			} else {
59
-				return $type;
60
-			}
61
-		}, '');
62
-		if ($foundType === '') {
63
-			throw new BackendNotFoundException("Version backend for $fullType not found");
64
-		} else {
65
-			return $backends[$foundType];
66
-		}
67
-	}
44
+    /**
45
+     * @param IStorage $storage
46
+     * @return IVersionBackend
47
+     * @throws BackendNotFoundException
48
+     */
49
+    public function getBackendForStorage(IStorage $storage): IVersionBackend {
50
+        $fullType = get_class($storage);
51
+        $backends = $this->getBackends();
52
+        $foundType = array_reduce(array_keys($backends), function ($type, $registeredType) use ($storage) {
53
+            if (
54
+                $storage->instanceOfStorage($registeredType) &&
55
+                ($type === '' || is_subclass_of($registeredType, $type))
56
+            ) {
57
+                return $registeredType;
58
+            } else {
59
+                return $type;
60
+            }
61
+        }, '');
62
+        if ($foundType === '') {
63
+            throw new BackendNotFoundException("Version backend for $fullType not found");
64
+        } else {
65
+            return $backends[$foundType];
66
+        }
67
+    }
68 68
 
69
-	public function getVersionsForFile(IUser $user, FileInfo $file): array {
70
-		$backend = $this->getBackendForStorage($file->getStorage());
71
-		return $backend->getVersionsForFile($user, $file);
72
-	}
69
+    public function getVersionsForFile(IUser $user, FileInfo $file): array {
70
+        $backend = $this->getBackendForStorage($file->getStorage());
71
+        return $backend->getVersionsForFile($user, $file);
72
+    }
73 73
 
74
-	public function createVersion(IUser $user, FileInfo $file) {
75
-		$backend = $this->getBackendForStorage($file->getStorage());
76
-		$backend->createVersion($user, $file);
77
-	}
74
+    public function createVersion(IUser $user, FileInfo $file) {
75
+        $backend = $this->getBackendForStorage($file->getStorage());
76
+        $backend->createVersion($user, $file);
77
+    }
78 78
 
79
-	public function rollback(IVersion $version) {
80
-		$backend = $version->getBackend();
81
-		return $backend->rollback($version);
82
-	}
79
+    public function rollback(IVersion $version) {
80
+        $backend = $version->getBackend();
81
+        return $backend->rollback($version);
82
+    }
83 83
 
84
-	public function read(IVersion $version) {
85
-		$backend = $version->getBackend();
86
-		return $backend->read($version);
87
-	}
84
+    public function read(IVersion $version) {
85
+        $backend = $version->getBackend();
86
+        return $backend->read($version);
87
+    }
88 88
 
89
-	public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
90
-		$backend = $this->getBackendForStorage($sourceFile->getStorage());
91
-		return $backend->getVersionFile($user, $sourceFile, $revision);
92
-	}
89
+    public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
90
+        $backend = $this->getBackendForStorage($sourceFile->getStorage());
91
+        return $backend->getVersionFile($user, $sourceFile, $revision);
92
+    }
93 93
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -49,7 +49,7 @@
 block discarded – undo
49 49
 	public function getBackendForStorage(IStorage $storage): IVersionBackend {
50 50
 		$fullType = get_class($storage);
51 51
 		$backends = $this->getBackends();
52
-		$foundType = array_reduce(array_keys($backends), function ($type, $registeredType) use ($storage) {
52
+		$foundType = array_reduce(array_keys($backends), function($type, $registeredType) use ($storage) {
53 53
 			if (
54 54
 				$storage->instanceOfStorage($registeredType) &&
55 55
 				($type === '' || is_subclass_of($registeredType, $type))
Please login to merge, or discard this patch.
apps/files_versions/lib/Versions/LegacyVersionsBackend.php 2 patches
Indentation   +61 added lines, -61 removed lines patch added patch discarded remove patch
@@ -31,75 +31,75 @@
 block discarded – undo
31 31
 use OCP\IUser;
32 32
 
33 33
 class LegacyVersionsBackend implements IVersionBackend {
34
-	/** @var IRootFolder */
35
-	private $rootFolder;
34
+    /** @var IRootFolder */
35
+    private $rootFolder;
36 36
 
37
-	public function __construct(IRootFolder $rootFolder) {
38
-		$this->rootFolder = $rootFolder;
39
-	}
37
+    public function __construct(IRootFolder $rootFolder) {
38
+        $this->rootFolder = $rootFolder;
39
+    }
40 40
 
41
-	public function getVersionsForFile(IUser $user, FileInfo $file): array {
42
-		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
43
-		$versions = Storage::getVersions($user->getUID(), $userFolder->getRelativePath($file->getPath()));
41
+    public function getVersionsForFile(IUser $user, FileInfo $file): array {
42
+        $userFolder = $this->rootFolder->getUserFolder($user->getUID());
43
+        $versions = Storage::getVersions($user->getUID(), $userFolder->getRelativePath($file->getPath()));
44 44
 
45
-		return array_map(function (array $data) use ($file, $user) {
46
-			return new Version(
47
-				(int)$data['version'],
48
-				(int)$data['version'],
49
-				$data['name'],
50
-				(int)$data['size'],
51
-				$data['mimetype'],
52
-				$data['path'],
53
-				$file,
54
-				$this,
55
-				$user
56
-			);
57
-		}, $versions);
58
-	}
45
+        return array_map(function (array $data) use ($file, $user) {
46
+            return new Version(
47
+                (int)$data['version'],
48
+                (int)$data['version'],
49
+                $data['name'],
50
+                (int)$data['size'],
51
+                $data['mimetype'],
52
+                $data['path'],
53
+                $file,
54
+                $this,
55
+                $user
56
+            );
57
+        }, $versions);
58
+    }
59 59
 
60
-	public function createVersion(IUser $user, FileInfo $file) {
61
-		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
62
-		$relativePath = $userFolder->getRelativePath($file->getPath());
63
-		$userView = new View('/' . $user->getUID());
64
-		// create all parent folders
65
-		Storage::createMissingDirectories($relativePath, $userView);
60
+    public function createVersion(IUser $user, FileInfo $file) {
61
+        $userFolder = $this->rootFolder->getUserFolder($user->getUID());
62
+        $relativePath = $userFolder->getRelativePath($file->getPath());
63
+        $userView = new View('/' . $user->getUID());
64
+        // create all parent folders
65
+        Storage::createMissingDirectories($relativePath, $userView);
66 66
 
67
-		Storage::scheduleExpire($user->getUID(), $relativePath);
67
+        Storage::scheduleExpire($user->getUID(), $relativePath);
68 68
 
69
-		// store a new version of a file
70
-		$userView->copy('files/' . $relativePath, 'files_versions/' . $relativePath . '.v' . $file->getMtime());
71
-		// ensure the file is scanned
72
-		$userView->getFileInfo('files_versions/' . $relativePath . '.v' . $file->getMtime());
73
-	}
69
+        // store a new version of a file
70
+        $userView->copy('files/' . $relativePath, 'files_versions/' . $relativePath . '.v' . $file->getMtime());
71
+        // ensure the file is scanned
72
+        $userView->getFileInfo('files_versions/' . $relativePath . '.v' . $file->getMtime());
73
+    }
74 74
 
75
-	public function rollback(IVersion $version) {
76
-		return Storage::rollback($version->getVersionPath(), $version->getRevisionId());
77
-	}
75
+    public function rollback(IVersion $version) {
76
+        return Storage::rollback($version->getVersionPath(), $version->getRevisionId());
77
+    }
78 78
 
79
-	private function getVersionFolder(IUser $user): Folder {
80
-		$userRoot = $this->rootFolder->getUserFolder($user->getUID())
81
-			->getParent();
82
-		try {
83
-			/** @var Folder $folder */
84
-			$folder = $userRoot->get('files_versions');
85
-			return $folder;
86
-		} catch (NotFoundException $e) {
87
-			return $userRoot->newFolder('files_versions');
88
-		}
89
-	}
79
+    private function getVersionFolder(IUser $user): Folder {
80
+        $userRoot = $this->rootFolder->getUserFolder($user->getUID())
81
+            ->getParent();
82
+        try {
83
+            /** @var Folder $folder */
84
+            $folder = $userRoot->get('files_versions');
85
+            return $folder;
86
+        } catch (NotFoundException $e) {
87
+            return $userRoot->newFolder('files_versions');
88
+        }
89
+    }
90 90
 
91
-	public function read(IVersion $version) {
92
-		$versions = $this->getVersionFolder($version->getUser());
93
-		/** @var File $file */
94
-		$file = $versions->get($version->getVersionPath() . '.v' . $version->getRevisionId());
95
-		return $file->fopen('r');
96
-	}
91
+    public function read(IVersion $version) {
92
+        $versions = $this->getVersionFolder($version->getUser());
93
+        /** @var File $file */
94
+        $file = $versions->get($version->getVersionPath() . '.v' . $version->getRevisionId());
95
+        return $file->fopen('r');
96
+    }
97 97
 
98
-	public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
99
-		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
100
-		$versionFolder = $this->getVersionFolder($user);
101
-		/** @var File $file */
102
-		$file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()) . '.v' . $revision);
103
-		return $file;
104
-	}
98
+    public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
99
+        $userFolder = $this->rootFolder->getUserFolder($user->getUID());
100
+        $versionFolder = $this->getVersionFolder($user);
101
+        /** @var File $file */
102
+        $file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()) . '.v' . $revision);
103
+        return $file;
104
+    }
105 105
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -42,12 +42,12 @@  discard block
 block discarded – undo
42 42
 		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
43 43
 		$versions = Storage::getVersions($user->getUID(), $userFolder->getRelativePath($file->getPath()));
44 44
 
45
-		return array_map(function (array $data) use ($file, $user) {
45
+		return array_map(function(array $data) use ($file, $user) {
46 46
 			return new Version(
47
-				(int)$data['version'],
48
-				(int)$data['version'],
47
+				(int) $data['version'],
48
+				(int) $data['version'],
49 49
 				$data['name'],
50
-				(int)$data['size'],
50
+				(int) $data['size'],
51 51
 				$data['mimetype'],
52 52
 				$data['path'],
53 53
 				$file,
@@ -60,16 +60,16 @@  discard block
 block discarded – undo
60 60
 	public function createVersion(IUser $user, FileInfo $file) {
61 61
 		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
62 62
 		$relativePath = $userFolder->getRelativePath($file->getPath());
63
-		$userView = new View('/' . $user->getUID());
63
+		$userView = new View('/'.$user->getUID());
64 64
 		// create all parent folders
65 65
 		Storage::createMissingDirectories($relativePath, $userView);
66 66
 
67 67
 		Storage::scheduleExpire($user->getUID(), $relativePath);
68 68
 
69 69
 		// store a new version of a file
70
-		$userView->copy('files/' . $relativePath, 'files_versions/' . $relativePath . '.v' . $file->getMtime());
70
+		$userView->copy('files/'.$relativePath, 'files_versions/'.$relativePath.'.v'.$file->getMtime());
71 71
 		// ensure the file is scanned
72
-		$userView->getFileInfo('files_versions/' . $relativePath . '.v' . $file->getMtime());
72
+		$userView->getFileInfo('files_versions/'.$relativePath.'.v'.$file->getMtime());
73 73
 	}
74 74
 
75 75
 	public function rollback(IVersion $version) {
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 	public function read(IVersion $version) {
92 92
 		$versions = $this->getVersionFolder($version->getUser());
93 93
 		/** @var File $file */
94
-		$file = $versions->get($version->getVersionPath() . '.v' . $version->getRevisionId());
94
+		$file = $versions->get($version->getVersionPath().'.v'.$version->getRevisionId());
95 95
 		return $file->fopen('r');
96 96
 	}
97 97
 
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
 		$userFolder = $this->rootFolder->getUserFolder($user->getUID());
100 100
 		$versionFolder = $this->getVersionFolder($user);
101 101
 		/** @var File $file */
102
-		$file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()) . '.v' . $revision);
102
+		$file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()).'.v'.$revision);
103 103
 		return $file;
104 104
 	}
105 105
 }
Please login to merge, or discard this patch.
apps/files_versions/lib/Versions/IVersionBackend.php 1 patch
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -31,51 +31,51 @@
 block discarded – undo
31 31
  * @since 15.0.0
32 32
  */
33 33
 interface IVersionBackend {
34
-	/**
35
-	 * Get all versions for a file
36
-	 *
37
-	 * @param IUser $user
38
-	 * @param FileInfo $file
39
-	 * @return IVersion[]
40
-	 * @since 15.0.0
41
-	 */
42
-	public function getVersionsForFile(IUser $user, FileInfo $file): array;
34
+    /**
35
+     * Get all versions for a file
36
+     *
37
+     * @param IUser $user
38
+     * @param FileInfo $file
39
+     * @return IVersion[]
40
+     * @since 15.0.0
41
+     */
42
+    public function getVersionsForFile(IUser $user, FileInfo $file): array;
43 43
 
44
-	/**
45
-	 * Create a new version for a file
46
-	 *
47
-	 * @param IUser $user
48
-	 * @param FileInfo $file
49
-	 * @since 15.0.0
50
-	 */
51
-	public function createVersion(IUser $user, FileInfo $file);
44
+    /**
45
+     * Create a new version for a file
46
+     *
47
+     * @param IUser $user
48
+     * @param FileInfo $file
49
+     * @since 15.0.0
50
+     */
51
+    public function createVersion(IUser $user, FileInfo $file);
52 52
 
53
-	/**
54
-	 * Restore this version
55
-	 *
56
-	 * @param IVersion $version
57
-	 * @since 15.0.0
58
-	 */
59
-	public function rollback(IVersion $version);
53
+    /**
54
+     * Restore this version
55
+     *
56
+     * @param IVersion $version
57
+     * @since 15.0.0
58
+     */
59
+    public function rollback(IVersion $version);
60 60
 
61
-	/**
62
-	 * Open the file for reading
63
-	 *
64
-	 * @param IVersion $version
65
-	 * @return resource
66
-	 * @throws NotFoundException
67
-	 * @since 15.0.0
68
-	 */
69
-	public function read(IVersion $version);
61
+    /**
62
+     * Open the file for reading
63
+     *
64
+     * @param IVersion $version
65
+     * @return resource
66
+     * @throws NotFoundException
67
+     * @since 15.0.0
68
+     */
69
+    public function read(IVersion $version);
70 70
 
71
-	/**
72
-	 * Get the preview for a specific version of a file
73
-	 *
74
-	 * @param IUser $user
75
-	 * @param FileInfo $sourceFile
76
-	 * @param int $revision
77
-	 * @return ISimpleFile
78
-	 * @since 15.0.0
79
-	 */
80
-	public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File;
71
+    /**
72
+     * Get the preview for a specific version of a file
73
+     *
74
+     * @param IUser $user
75
+     * @param FileInfo $sourceFile
76
+     * @param int $revision
77
+     * @return ISimpleFile
78
+     * @since 15.0.0
79
+     */
80
+    public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File;
81 81
 }
Please login to merge, or discard this patch.
apps/files_versions/lib/Storage.php 2 patches
Indentation   +797 added lines, -797 removed lines patch added patch discarded remove patch
@@ -55,802 +55,802 @@
 block discarded – undo
55 55
 
56 56
 class Storage {
57 57
 
58
-	const DEFAULTENABLED=true;
59
-	const DEFAULTMAXSIZE=50; // unit: percentage; 50% of available disk space/quota
60
-	const VERSIONS_ROOT = 'files_versions/';
61
-
62
-	const DELETE_TRIGGER_MASTER_REMOVED = 0;
63
-	const DELETE_TRIGGER_RETENTION_CONSTRAINT = 1;
64
-	const DELETE_TRIGGER_QUOTA_EXCEEDED = 2;
65
-
66
-	// files for which we can remove the versions after the delete operation was successful
67
-	private static $deletedFiles = array();
68
-
69
-	private static $sourcePathAndUser = array();
70
-
71
-	private static $max_versions_per_interval = array(
72
-		//first 10sec, one version every 2sec
73
-		1 => array('intervalEndsAfter' => 10,      'step' => 2),
74
-		//next minute, one version every 10sec
75
-		2 => array('intervalEndsAfter' => 60,      'step' => 10),
76
-		//next hour, one version every minute
77
-		3 => array('intervalEndsAfter' => 3600,    'step' => 60),
78
-		//next 24h, one version every hour
79
-		4 => array('intervalEndsAfter' => 86400,   'step' => 3600),
80
-		//next 30days, one version per day
81
-		5 => array('intervalEndsAfter' => 2592000, 'step' => 86400),
82
-		//until the end one version per week
83
-		6 => array('intervalEndsAfter' => -1,      'step' => 604800),
84
-	);
85
-
86
-	/** @var \OCA\Files_Versions\AppInfo\Application */
87
-	private static $application;
88
-
89
-	/**
90
-	 * get the UID of the owner of the file and the path to the file relative to
91
-	 * owners files folder
92
-	 *
93
-	 * @param string $filename
94
-	 * @return array
95
-	 * @throws \OC\User\NoUserException
96
-	 */
97
-	public static function getUidAndFilename($filename) {
98
-		$uid = Filesystem::getOwner($filename);
99
-		$userManager = \OC::$server->getUserManager();
100
-		// if the user with the UID doesn't exists, e.g. because the UID points
101
-		// to a remote user with a federated cloud ID we use the current logged-in
102
-		// user. We need a valid local user to create the versions
103
-		if (!$userManager->userExists($uid)) {
104
-			$uid = User::getUser();
105
-		}
106
-		Filesystem::initMountPoints($uid);
107
-		if ( $uid !== User::getUser() ) {
108
-			$info = Filesystem::getFileInfo($filename);
109
-			$ownerView = new View('/'.$uid.'/files');
110
-			try {
111
-				$filename = $ownerView->getPath($info['fileid']);
112
-				// make sure that the file name doesn't end with a trailing slash
113
-				// can for example happen single files shared across servers
114
-				$filename = rtrim($filename, '/');
115
-			} catch (NotFoundException $e) {
116
-				$filename = null;
117
-			}
118
-		}
119
-		return [$uid, $filename];
120
-	}
121
-
122
-	/**
123
-	 * Remember the owner and the owner path of the source file
124
-	 *
125
-	 * @param string $source source path
126
-	 */
127
-	public static function setSourcePathAndUser($source) {
128
-		list($uid, $path) = self::getUidAndFilename($source);
129
-		self::$sourcePathAndUser[$source] = array('uid' => $uid, 'path' => $path);
130
-	}
131
-
132
-	/**
133
-	 * Gets the owner and the owner path from the source path
134
-	 *
135
-	 * @param string $source source path
136
-	 * @return array with user id and path
137
-	 */
138
-	public static function getSourcePathAndUser($source) {
139
-
140
-		if (isset(self::$sourcePathAndUser[$source])) {
141
-			$uid = self::$sourcePathAndUser[$source]['uid'];
142
-			$path = self::$sourcePathAndUser[$source]['path'];
143
-			unset(self::$sourcePathAndUser[$source]);
144
-		} else {
145
-			$uid = $path = false;
146
-		}
147
-		return array($uid, $path);
148
-	}
149
-
150
-	/**
151
-	 * get current size of all versions from a given user
152
-	 *
153
-	 * @param string $user user who owns the versions
154
-	 * @return int versions size
155
-	 */
156
-	private static function getVersionsSize($user) {
157
-		$view = new View('/' . $user);
158
-		$fileInfo = $view->getFileInfo('/files_versions');
159
-		return isset($fileInfo['size']) ? $fileInfo['size'] : 0;
160
-	}
161
-
162
-	/**
163
-	 * store a new version of a file.
164
-	 */
165
-	public static function store($filename) {
166
-
167
-		// if the file gets streamed we need to remove the .part extension
168
-		// to get the right target
169
-		$ext = pathinfo($filename, PATHINFO_EXTENSION);
170
-		if ($ext === 'part') {
171
-			$filename = substr($filename, 0, -5);
172
-		}
173
-
174
-		// we only handle existing files
175
-		if (! Filesystem::file_exists($filename) || Filesystem::is_dir($filename)) {
176
-			return false;
177
-		}
178
-
179
-		list($uid, $filename) = self::getUidAndFilename($filename);
180
-
181
-		$files_view = new View('/'.$uid .'/files');
182
-
183
-		$eventDispatcher = \OC::$server->getEventDispatcher();
184
-		$fileInfo = $files_view->getFileInfo($filename);
185
-		$id = $fileInfo->getId();
186
-		$nodes = \OC::$server->getRootFolder()->getById($id);
187
-		foreach ($nodes as $node) {
188
-			$event = new CreateVersionEvent($node);
189
-			$eventDispatcher->dispatch('OCA\Files_Versions::createVersion', $event);
190
-			if ($event->shouldCreateVersion() === false) {
191
-				return false;
192
-			}
193
-		}
194
-
195
-		// no use making versions for empty files
196
-		if ($fileInfo->getSize() === 0) {
197
-			return false;
198
-		}
199
-
200
-		/** @var IVersionManager $versionManager */
201
-		$versionManager = \OC::$server->query(IVersionManager::class);
202
-		$userManager = \OC::$server->getUserManager();
203
-		$user = $userManager->get($uid);
204
-
205
-		$versionManager->createVersion($user, $fileInfo);
206
-	}
207
-
208
-
209
-	/**
210
-	 * mark file as deleted so that we can remove the versions if the file is gone
211
-	 * @param string $path
212
-	 */
213
-	public static function markDeletedFile($path) {
214
-		list($uid, $filename) = self::getUidAndFilename($path);
215
-		self::$deletedFiles[$path] = array(
216
-			'uid' => $uid,
217
-			'filename' => $filename);
218
-	}
219
-
220
-	/**
221
-	 * delete the version from the storage and cache
222
-	 *
223
-	 * @param View $view
224
-	 * @param string $path
225
-	 */
226
-	protected static function deleteVersion($view, $path) {
227
-		$view->unlink($path);
228
-		/**
229
-		 * @var \OC\Files\Storage\Storage $storage
230
-		 * @var string $internalPath
231
-		 */
232
-		list($storage, $internalPath) = $view->resolvePath($path);
233
-		$cache = $storage->getCache($internalPath);
234
-		$cache->remove($internalPath);
235
-	}
236
-
237
-	/**
238
-	 * Delete versions of a file
239
-	 */
240
-	public static function delete($path) {
241
-
242
-		$deletedFile = self::$deletedFiles[$path];
243
-		$uid = $deletedFile['uid'];
244
-		$filename = $deletedFile['filename'];
245
-
246
-		if (!Filesystem::file_exists($path)) {
247
-
248
-			$view = new View('/' . $uid . '/files_versions');
249
-
250
-			$versions = self::getVersions($uid, $filename);
251
-			if (!empty($versions)) {
252
-				foreach ($versions as $v) {
253
-					\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $path . $v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
254
-					self::deleteVersion($view, $filename . '.v' . $v['version']);
255
-					\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path . $v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
256
-				}
257
-			}
258
-		}
259
-		unset(self::$deletedFiles[$path]);
260
-	}
261
-
262
-	/**
263
-	 * Rename or copy versions of a file of the given paths
264
-	 *
265
-	 * @param string $sourcePath source path of the file to move, relative to
266
-	 * the currently logged in user's "files" folder
267
-	 * @param string $targetPath target path of the file to move, relative to
268
-	 * the currently logged in user's "files" folder
269
-	 * @param string $operation can be 'copy' or 'rename'
270
-	 */
271
-	public static function renameOrCopy($sourcePath, $targetPath, $operation) {
272
-		list($sourceOwner, $sourcePath) = self::getSourcePathAndUser($sourcePath);
273
-
274
-		// it was a upload of a existing file if no old path exists
275
-		// in this case the pre-hook already called the store method and we can
276
-		// stop here
277
-		if ($sourcePath === false) {
278
-			return true;
279
-		}
280
-
281
-		list($targetOwner, $targetPath) = self::getUidAndFilename($targetPath);
282
-
283
-		$sourcePath = ltrim($sourcePath, '/');
284
-		$targetPath = ltrim($targetPath, '/');
285
-
286
-		$rootView = new View('');
287
-
288
-		// did we move a directory ?
289
-		if ($rootView->is_dir('/' . $targetOwner . '/files/' . $targetPath)) {
290
-			// does the directory exists for versions too ?
291
-			if ($rootView->is_dir('/' . $sourceOwner . '/files_versions/' . $sourcePath)) {
292
-				// create missing dirs if necessary
293
-				self::createMissingDirectories($targetPath, new View('/'. $targetOwner));
294
-
295
-				// move the directory containing the versions
296
-				$rootView->$operation(
297
-					'/' . $sourceOwner . '/files_versions/' . $sourcePath,
298
-					'/' . $targetOwner . '/files_versions/' . $targetPath
299
-				);
300
-			}
301
-		} else if ($versions = Storage::getVersions($sourceOwner, '/' . $sourcePath)) {
302
-			// create missing dirs if necessary
303
-			self::createMissingDirectories($targetPath, new View('/'. $targetOwner));
304
-
305
-			foreach ($versions as $v) {
306
-				// move each version one by one to the target directory
307
-				$rootView->$operation(
308
-					'/' . $sourceOwner . '/files_versions/' . $sourcePath.'.v' . $v['version'],
309
-					'/' . $targetOwner . '/files_versions/' . $targetPath.'.v'.$v['version']
310
-				);
311
-			}
312
-		}
313
-
314
-		// if we moved versions directly for a file, schedule expiration check for that file
315
-		if (!$rootView->is_dir('/' . $targetOwner . '/files/' . $targetPath)) {
316
-			self::scheduleExpire($targetOwner, $targetPath);
317
-		}
318
-
319
-	}
320
-
321
-	/**
322
-	 * Rollback to an old version of a file.
323
-	 *
324
-	 * @param string $file file name
325
-	 * @param int $revision revision timestamp
326
-	 * @return bool
327
-	 */
328
-	public static function rollback($file, $revision) {
329
-
330
-		// add expected leading slash
331
-		$file = '/' . ltrim($file, '/');
332
-		list($uid, $filename) = self::getUidAndFilename($file);
333
-		if ($uid === null || trim($filename, '/') === '') {
334
-			return false;
335
-		}
336
-
337
-		// Fetch the userfolder to trigger view hooks
338
-		$userFolder = \OC::$server->getUserFolder($uid);
339
-
340
-		$users_view = new View('/'.$uid);
341
-		$files_view = new View('/'. User::getUser().'/files');
342
-
343
-		$versionCreated = false;
344
-
345
-		$fileInfo = $files_view->getFileInfo($file);
346
-
347
-		// check if user has the permissions to revert a version
348
-		if (!$fileInfo->isUpdateable()) {
349
-			return false;
350
-		}
351
-
352
-		//first create a new version
353
-		$version = 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename);
354
-		if (!$users_view->file_exists($version)) {
355
-			$users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename));
356
-			$versionCreated = true;
357
-		}
358
-
359
-		$fileToRestore =  'files_versions' . $filename . '.v' . $revision;
360
-
361
-		// Restore encrypted version of the old file for the newly restored file
362
-		// This has to happen manually here since the file is manually copied below
363
-		$oldVersion = $users_view->getFileInfo($fileToRestore)->getEncryptedVersion();
364
-		$oldFileInfo = $users_view->getFileInfo($fileToRestore);
365
-		$cache = $fileInfo->getStorage()->getCache();
366
-		$cache->update(
367
-			$fileInfo->getId(), [
368
-				'encrypted' => $oldVersion,
369
-				'encryptedVersion' => $oldVersion,
370
-				'size' => $oldFileInfo->getSize()
371
-			]
372
-		);
373
-
374
-		// rollback
375
-		if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) {
376
-			$files_view->touch($file, $revision);
377
-			Storage::scheduleExpire($uid, $file);
378
-
379
-			$node = $userFolder->get($file);
380
-
381
-			// TODO: move away from those legacy hooks!
382
-			\OC_Hook::emit('\OCP\Versions', 'rollback', array(
383
-				'path' => $filename,
384
-				'revision' => $revision,
385
-				'node' => $node,
386
-			));
387
-			return true;
388
-		} else if ($versionCreated) {
389
-			self::deleteVersion($users_view, $version);
390
-		}
391
-
392
-		return false;
393
-
394
-	}
395
-
396
-	/**
397
-	 * Stream copy file contents from $path1 to $path2
398
-	 *
399
-	 * @param View $view view to use for copying
400
-	 * @param string $path1 source file to copy
401
-	 * @param string $path2 target file
402
-	 *
403
-	 * @return bool true for success, false otherwise
404
-	 */
405
-	private static function copyFileContents($view, $path1, $path2) {
406
-		/** @var \OC\Files\Storage\Storage $storage1 */
407
-		list($storage1, $internalPath1) = $view->resolvePath($path1);
408
-		/** @var \OC\Files\Storage\Storage $storage2 */
409
-		list($storage2, $internalPath2) = $view->resolvePath($path2);
410
-
411
-		$view->lockFile($path1, ILockingProvider::LOCK_EXCLUSIVE);
412
-		$view->lockFile($path2, ILockingProvider::LOCK_EXCLUSIVE);
413
-
414
-		// TODO add a proper way of overwriting a file while maintaining file ids
415
-		if ($storage1->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage') || $storage2->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage')) {
416
-			$source = $storage1->fopen($internalPath1, 'r');
417
-			$target = $storage2->fopen($internalPath2, 'w');
418
-			list(, $result) = \OC_Helper::streamCopy($source, $target);
419
-			fclose($source);
420
-			fclose($target);
421
-
422
-			if ($result !== false) {
423
-				$storage1->unlink($internalPath1);
424
-			}
425
-		} else {
426
-			$result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
427
-		}
428
-
429
-		$view->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE);
430
-		$view->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE);
431
-
432
-		return ($result !== false);
433
-	}
434
-
435
-	/**
436
-	 * get a list of all available versions of a file in descending chronological order
437
-	 * @param string $uid user id from the owner of the file
438
-	 * @param string $filename file to find versions of, relative to the user files dir
439
-	 * @param string $userFullPath
440
-	 * @return array versions newest version first
441
-	 */
442
-	public static function getVersions($uid, $filename, $userFullPath = '') {
443
-		$versions = array();
444
-		if (empty($filename)) {
445
-			return $versions;
446
-		}
447
-		// fetch for old versions
448
-		$view = new View('/' . $uid . '/');
449
-
450
-		$pathinfo = pathinfo($filename);
451
-		$versionedFile = $pathinfo['basename'];
452
-
453
-		$dir = Filesystem::normalizePath(self::VERSIONS_ROOT . '/' . $pathinfo['dirname']);
454
-
455
-		$dirContent = false;
456
-		if ($view->is_dir($dir)) {
457
-			$dirContent = $view->opendir($dir);
458
-		}
459
-
460
-		if ($dirContent === false) {
461
-			return $versions;
462
-		}
463
-
464
-		if (is_resource($dirContent)) {
465
-			while (($entryName = readdir($dirContent)) !== false) {
466
-				if (!Filesystem::isIgnoredDir($entryName)) {
467
-					$pathparts = pathinfo($entryName);
468
-					$filename = $pathparts['filename'];
469
-					if ($filename === $versionedFile) {
470
-						$pathparts = pathinfo($entryName);
471
-						$timestamp = substr($pathparts['extension'], 1);
472
-						$filename = $pathparts['filename'];
473
-						$key = $timestamp . '#' . $filename;
474
-						$versions[$key]['version'] = $timestamp;
475
-						$versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($timestamp);
476
-						if (empty($userFullPath)) {
477
-							$versions[$key]['preview'] = '';
478
-						} else {
479
-							$versions[$key]['preview'] = \OC::$server->getURLGenerator('files_version.Preview.getPreview', ['file' => $userFullPath, 'version' => $timestamp]);
480
-						}
481
-						$versions[$key]['path'] = Filesystem::normalizePath($pathinfo['dirname'] . '/' . $filename);
482
-						$versions[$key]['name'] = $versionedFile;
483
-						$versions[$key]['size'] = $view->filesize($dir . '/' . $entryName);
484
-						$versions[$key]['mimetype'] = \OC::$server->getMimeTypeDetector()->detectPath($versionedFile);
485
-					}
486
-				}
487
-			}
488
-			closedir($dirContent);
489
-		}
490
-
491
-		// sort with newest version first
492
-		krsort($versions);
493
-
494
-		return $versions;
495
-	}
496
-
497
-	/**
498
-	 * Expire versions that older than max version retention time
499
-	 * @param string $uid
500
-	 */
501
-	public static function expireOlderThanMaxForUser($uid){
502
-		$expiration = self::getExpiration();
503
-		$threshold = $expiration->getMaxAgeAsTimestamp();
504
-		$versions = self::getAllVersions($uid);
505
-		if (!$threshold || !array_key_exists('all', $versions)) {
506
-			return;
507
-		}
508
-
509
-		$toDelete = [];
510
-		foreach (array_reverse($versions['all']) as $key => $version) {
511
-			if ((int)$version['version'] <$threshold) {
512
-				$toDelete[$key] = $version;
513
-			} else {
514
-				//Versions are sorted by time - nothing mo to iterate.
515
-				break;
516
-			}
517
-		}
518
-
519
-		$view = new View('/' . $uid . '/files_versions');
520
-		if (!empty($toDelete)) {
521
-			foreach ($toDelete as $version) {
522
-				\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_RETENTION_CONSTRAINT));
523
-				self::deleteVersion($view, $version['path'] . '.v' . $version['version']);
524
-				\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_RETENTION_CONSTRAINT));
525
-			}
526
-		}
527
-	}
528
-
529
-	/**
530
-	 * translate a timestamp into a string like "5 days ago"
531
-	 * @param int $timestamp
532
-	 * @return string for example "5 days ago"
533
-	 */
534
-	private static function getHumanReadableTimestamp($timestamp) {
535
-
536
-		$diff = time() - $timestamp;
537
-
538
-		if ($diff < 60) { // first minute
539
-			return  $diff . " seconds ago";
540
-		} elseif ($diff < 3600) { //first hour
541
-			return round($diff / 60) . " minutes ago";
542
-		} elseif ($diff < 86400) { // first day
543
-			return round($diff / 3600) . " hours ago";
544
-		} elseif ($diff < 604800) { //first week
545
-			return round($diff / 86400) . " days ago";
546
-		} elseif ($diff < 2419200) { //first month
547
-			return round($diff / 604800) . " weeks ago";
548
-		} elseif ($diff < 29030400) { // first year
549
-			return round($diff / 2419200) . " months ago";
550
-		} else {
551
-			return round($diff / 29030400) . " years ago";
552
-		}
553
-
554
-	}
555
-
556
-	/**
557
-	 * returns all stored file versions from a given user
558
-	 * @param string $uid id of the user
559
-	 * @return array with contains two arrays 'all' which contains all versions sorted by age and 'by_file' which contains all versions sorted by filename
560
-	 */
561
-	private static function getAllVersions($uid) {
562
-		$view = new View('/' . $uid . '/');
563
-		$dirs = array(self::VERSIONS_ROOT);
564
-		$versions = array();
565
-
566
-		while (!empty($dirs)) {
567
-			$dir = array_pop($dirs);
568
-			$files = $view->getDirectoryContent($dir);
569
-
570
-			foreach ($files as $file) {
571
-				$fileData = $file->getData();
572
-				$filePath = $dir . '/' . $fileData['name'];
573
-				if ($file['type'] === 'dir') {
574
-					$dirs[] = $filePath;
575
-				} else {
576
-					$versionsBegin = strrpos($filePath, '.v');
577
-					$relPathStart = strlen(self::VERSIONS_ROOT);
578
-					$version = substr($filePath, $versionsBegin + 2);
579
-					$relpath = substr($filePath, $relPathStart, $versionsBegin - $relPathStart);
580
-					$key = $version . '#' . $relpath;
581
-					$versions[$key] = array('path' => $relpath, 'timestamp' => $version);
582
-				}
583
-			}
584
-		}
585
-
586
-		// newest version first
587
-		krsort($versions);
588
-
589
-		$result = array();
590
-
591
-		foreach ($versions as $key => $value) {
592
-			$size = $view->filesize(self::VERSIONS_ROOT.'/'.$value['path'].'.v'.$value['timestamp']);
593
-			$filename = $value['path'];
594
-
595
-			$result['all'][$key]['version'] = $value['timestamp'];
596
-			$result['all'][$key]['path'] = $filename;
597
-			$result['all'][$key]['size'] = $size;
598
-
599
-			$result['by_file'][$filename][$key]['version'] = $value['timestamp'];
600
-			$result['by_file'][$filename][$key]['path'] = $filename;
601
-			$result['by_file'][$filename][$key]['size'] = $size;
602
-		}
603
-
604
-		return $result;
605
-	}
606
-
607
-	/**
608
-	 * get list of files we want to expire
609
-	 * @param array $versions list of versions
610
-	 * @param integer $time
611
-	 * @param bool $quotaExceeded is versions storage limit reached
612
-	 * @return array containing the list of to deleted versions and the size of them
613
-	 */
614
-	protected static function getExpireList($time, $versions, $quotaExceeded = false) {
615
-		$expiration = self::getExpiration();
616
-
617
-		if ($expiration->shouldAutoExpire()) {
618
-			list($toDelete, $size) = self::getAutoExpireList($time, $versions);
619
-		} else {
620
-			$size = 0;
621
-			$toDelete = [];  // versions we want to delete
622
-		}
623
-
624
-		foreach ($versions as $key => $version) {
625
-			if ($expiration->isExpired($version['version'], $quotaExceeded) && !isset($toDelete[$key])) {
626
-				$size += $version['size'];
627
-				$toDelete[$key] = $version['path'] . '.v' . $version['version'];
628
-			}
629
-		}
630
-
631
-		return [$toDelete, $size];
632
-	}
633
-
634
-	/**
635
-	 * get list of files we want to expire
636
-	 * @param array $versions list of versions
637
-	 * @param integer $time
638
-	 * @return array containing the list of to deleted versions and the size of them
639
-	 */
640
-	protected static function getAutoExpireList($time, $versions) {
641
-		$size = 0;
642
-		$toDelete = array();  // versions we want to delete
643
-
644
-		$interval = 1;
645
-		$step = Storage::$max_versions_per_interval[$interval]['step'];
646
-		if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] === -1) {
647
-			$nextInterval = -1;
648
-		} else {
649
-			$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
650
-		}
651
-
652
-		$firstVersion = reset($versions);
653
-		$firstKey = key($versions);
654
-		$prevTimestamp = $firstVersion['version'];
655
-		$nextVersion = $firstVersion['version'] - $step;
656
-		unset($versions[$firstKey]);
657
-
658
-		foreach ($versions as $key => $version) {
659
-			$newInterval = true;
660
-			while ($newInterval) {
661
-				if ($nextInterval === -1 || $prevTimestamp > $nextInterval) {
662
-					if ($version['version'] > $nextVersion) {
663
-						//distance between two version too small, mark to delete
664
-						$toDelete[$key] = $version['path'] . '.v' . $version['version'];
665
-						$size += $version['size'];
666
-						\OC::$server->getLogger()->info('Mark to expire '. $version['path'] .' next version should be ' . $nextVersion . " or smaller. (prevTimestamp: " . $prevTimestamp . "; step: " . $step, ['app' => 'files_versions']);
667
-					} else {
668
-						$nextVersion = $version['version'] - $step;
669
-						$prevTimestamp = $version['version'];
670
-					}
671
-					$newInterval = false; // version checked so we can move to the next one
672
-				} else { // time to move on to the next interval
673
-					$interval++;
674
-					$step = Storage::$max_versions_per_interval[$interval]['step'];
675
-					$nextVersion = $prevTimestamp - $step;
676
-					if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] === -1) {
677
-						$nextInterval = -1;
678
-					} else {
679
-						$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
680
-					}
681
-					$newInterval = true; // we changed the interval -> check same version with new interval
682
-				}
683
-			}
684
-		}
685
-
686
-		return array($toDelete, $size);
687
-	}
688
-
689
-	/**
690
-	 * Schedule versions expiration for the given file
691
-	 *
692
-	 * @param string $uid owner of the file
693
-	 * @param string $fileName file/folder for which to schedule expiration
694
-	 */
695
-	public static function scheduleExpire($uid, $fileName) {
696
-		// let the admin disable auto expire
697
-		$expiration = self::getExpiration();
698
-		if ($expiration->isEnabled()) {
699
-			$command = new Expire($uid, $fileName);
700
-			\OC::$server->getCommandBus()->push($command);
701
-		}
702
-	}
703
-
704
-	/**
705
-	 * Expire versions which exceed the quota.
706
-	 *
707
-	 * This will setup the filesystem for the given user but will not
708
-	 * tear it down afterwards.
709
-	 *
710
-	 * @param string $filename path to file to expire
711
-	 * @param string $uid user for which to expire the version
712
-	 * @return bool|int|null
713
-	 */
714
-	public static function expire($filename, $uid) {
715
-		$expiration = self::getExpiration();
716
-
717
-		if ($expiration->isEnabled()) {
718
-			// get available disk space for user
719
-			$user = \OC::$server->getUserManager()->get($uid);
720
-			if (is_null($user)) {
721
-				\OC::$server->getLogger()->error('Backends provided no user object for ' . $uid, ['app' => 'files_versions']);
722
-				throw new \OC\User\NoUserException('Backends provided no user object for ' . $uid);
723
-			}
724
-
725
-			\OC_Util::setupFS($uid);
726
-
727
-			if (!Filesystem::file_exists($filename)) {
728
-				return false;
729
-			}
730
-
731
-			if (empty($filename)) {
732
-				// file maybe renamed or deleted
733
-				return false;
734
-			}
735
-			$versionsFileview = new View('/'.$uid.'/files_versions');
736
-
737
-			$softQuota = true;
738
-			$quota = $user->getQuota();
739
-			if ( $quota === null || $quota === 'none' ) {
740
-				$quota = Filesystem::free_space('/');
741
-				$softQuota = false;
742
-			} else {
743
-				$quota = \OCP\Util::computerFileSize($quota);
744
-			}
745
-
746
-			// make sure that we have the current size of the version history
747
-			$versionsSize = self::getVersionsSize($uid);
748
-
749
-			// calculate available space for version history
750
-			// subtract size of files and current versions size from quota
751
-			if ($quota >= 0) {
752
-				if ($softQuota) {
753
-					$files_view = new View('/' . $uid . '/files');
754
-					$rootInfo = $files_view->getFileInfo('/', false);
755
-					$free = $quota - $rootInfo['size']; // remaining free space for user
756
-					if ($free > 0) {
757
-						$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions
758
-					} else {
759
-						$availableSpace = $free - $versionsSize;
760
-					}
761
-				} else {
762
-					$availableSpace = $quota;
763
-				}
764
-			} else {
765
-				$availableSpace = PHP_INT_MAX;
766
-			}
767
-
768
-			$allVersions = Storage::getVersions($uid, $filename);
769
-
770
-			$time = time();
771
-			list($toDelete, $sizeOfDeletedVersions) = self::getExpireList($time, $allVersions, $availableSpace <= 0);
772
-
773
-			$availableSpace = $availableSpace + $sizeOfDeletedVersions;
774
-			$versionsSize = $versionsSize - $sizeOfDeletedVersions;
775
-
776
-			// if still not enough free space we rearrange the versions from all files
777
-			if ($availableSpace <= 0) {
778
-				$result = Storage::getAllVersions($uid);
779
-				$allVersions = $result['all'];
780
-
781
-				foreach ($result['by_file'] as $versions) {
782
-					list($toDeleteNew, $size) = self::getExpireList($time, $versions, $availableSpace <= 0);
783
-					$toDelete = array_merge($toDelete, $toDeleteNew);
784
-					$sizeOfDeletedVersions += $size;
785
-				}
786
-				$availableSpace = $availableSpace + $sizeOfDeletedVersions;
787
-				$versionsSize = $versionsSize - $sizeOfDeletedVersions;
788
-			}
789
-
790
-			$logger = \OC::$server->getLogger();
791
-			foreach($toDelete as $key => $path) {
792
-				\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $path, 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
793
-				self::deleteVersion($versionsFileview, $path);
794
-				\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path, 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
795
-				unset($allVersions[$key]); // update array with the versions we keep
796
-				$logger->info('Expire: ' . $path, ['app' => 'files_versions']);
797
-			}
798
-
799
-			// Check if enough space is available after versions are rearranged.
800
-			// If not we delete the oldest versions until we meet the size limit for versions,
801
-			// but always keep the two latest versions
802
-			$numOfVersions = count($allVersions) -2 ;
803
-			$i = 0;
804
-			// sort oldest first and make sure that we start at the first element
805
-			ksort($allVersions);
806
-			reset($allVersions);
807
-			while ($availableSpace < 0 && $i < $numOfVersions) {
808
-				$version = current($allVersions);
809
-				\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
810
-				self::deleteVersion($versionsFileview, $version['path'] . '.v' . $version['version']);
811
-				\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
812
-				\OC::$server->getLogger()->info('running out of space! Delete oldest version: ' . $version['path'].'.v'.$version['version'], ['app' => 'files_versions']);
813
-				$versionsSize -= $version['size'];
814
-				$availableSpace += $version['size'];
815
-				next($allVersions);
816
-				$i++;
817
-			}
818
-
819
-			return $versionsSize; // finally return the new size of the version history
820
-		}
821
-
822
-		return false;
823
-	}
824
-
825
-	/**
826
-	 * Create recursively missing directories inside of files_versions
827
-	 * that match the given path to a file.
828
-	 *
829
-	 * @param string $filename $path to a file, relative to the user's
830
-	 * "files" folder
831
-	 * @param View $view view on data/user/
832
-	 */
833
-	public static function createMissingDirectories($filename, $view) {
834
-		$dirname = Filesystem::normalizePath(dirname($filename));
835
-		$dirParts = explode('/', $dirname);
836
-		$dir = "/files_versions";
837
-		foreach ($dirParts as $part) {
838
-			$dir = $dir . '/' . $part;
839
-			if (!$view->file_exists($dir)) {
840
-				$view->mkdir($dir);
841
-			}
842
-		}
843
-	}
844
-
845
-	/**
846
-	 * Static workaround
847
-	 * @return Expiration
848
-	 */
849
-	protected static function getExpiration(){
850
-		if (is_null(self::$application)) {
851
-			self::$application = new Application();
852
-		}
853
-		return self::$application->getContainer()->query(Expiration::class);
854
-	}
58
+    const DEFAULTENABLED=true;
59
+    const DEFAULTMAXSIZE=50; // unit: percentage; 50% of available disk space/quota
60
+    const VERSIONS_ROOT = 'files_versions/';
61
+
62
+    const DELETE_TRIGGER_MASTER_REMOVED = 0;
63
+    const DELETE_TRIGGER_RETENTION_CONSTRAINT = 1;
64
+    const DELETE_TRIGGER_QUOTA_EXCEEDED = 2;
65
+
66
+    // files for which we can remove the versions after the delete operation was successful
67
+    private static $deletedFiles = array();
68
+
69
+    private static $sourcePathAndUser = array();
70
+
71
+    private static $max_versions_per_interval = array(
72
+        //first 10sec, one version every 2sec
73
+        1 => array('intervalEndsAfter' => 10,      'step' => 2),
74
+        //next minute, one version every 10sec
75
+        2 => array('intervalEndsAfter' => 60,      'step' => 10),
76
+        //next hour, one version every minute
77
+        3 => array('intervalEndsAfter' => 3600,    'step' => 60),
78
+        //next 24h, one version every hour
79
+        4 => array('intervalEndsAfter' => 86400,   'step' => 3600),
80
+        //next 30days, one version per day
81
+        5 => array('intervalEndsAfter' => 2592000, 'step' => 86400),
82
+        //until the end one version per week
83
+        6 => array('intervalEndsAfter' => -1,      'step' => 604800),
84
+    );
85
+
86
+    /** @var \OCA\Files_Versions\AppInfo\Application */
87
+    private static $application;
88
+
89
+    /**
90
+     * get the UID of the owner of the file and the path to the file relative to
91
+     * owners files folder
92
+     *
93
+     * @param string $filename
94
+     * @return array
95
+     * @throws \OC\User\NoUserException
96
+     */
97
+    public static function getUidAndFilename($filename) {
98
+        $uid = Filesystem::getOwner($filename);
99
+        $userManager = \OC::$server->getUserManager();
100
+        // if the user with the UID doesn't exists, e.g. because the UID points
101
+        // to a remote user with a federated cloud ID we use the current logged-in
102
+        // user. We need a valid local user to create the versions
103
+        if (!$userManager->userExists($uid)) {
104
+            $uid = User::getUser();
105
+        }
106
+        Filesystem::initMountPoints($uid);
107
+        if ( $uid !== User::getUser() ) {
108
+            $info = Filesystem::getFileInfo($filename);
109
+            $ownerView = new View('/'.$uid.'/files');
110
+            try {
111
+                $filename = $ownerView->getPath($info['fileid']);
112
+                // make sure that the file name doesn't end with a trailing slash
113
+                // can for example happen single files shared across servers
114
+                $filename = rtrim($filename, '/');
115
+            } catch (NotFoundException $e) {
116
+                $filename = null;
117
+            }
118
+        }
119
+        return [$uid, $filename];
120
+    }
121
+
122
+    /**
123
+     * Remember the owner and the owner path of the source file
124
+     *
125
+     * @param string $source source path
126
+     */
127
+    public static function setSourcePathAndUser($source) {
128
+        list($uid, $path) = self::getUidAndFilename($source);
129
+        self::$sourcePathAndUser[$source] = array('uid' => $uid, 'path' => $path);
130
+    }
131
+
132
+    /**
133
+     * Gets the owner and the owner path from the source path
134
+     *
135
+     * @param string $source source path
136
+     * @return array with user id and path
137
+     */
138
+    public static function getSourcePathAndUser($source) {
139
+
140
+        if (isset(self::$sourcePathAndUser[$source])) {
141
+            $uid = self::$sourcePathAndUser[$source]['uid'];
142
+            $path = self::$sourcePathAndUser[$source]['path'];
143
+            unset(self::$sourcePathAndUser[$source]);
144
+        } else {
145
+            $uid = $path = false;
146
+        }
147
+        return array($uid, $path);
148
+    }
149
+
150
+    /**
151
+     * get current size of all versions from a given user
152
+     *
153
+     * @param string $user user who owns the versions
154
+     * @return int versions size
155
+     */
156
+    private static function getVersionsSize($user) {
157
+        $view = new View('/' . $user);
158
+        $fileInfo = $view->getFileInfo('/files_versions');
159
+        return isset($fileInfo['size']) ? $fileInfo['size'] : 0;
160
+    }
161
+
162
+    /**
163
+     * store a new version of a file.
164
+     */
165
+    public static function store($filename) {
166
+
167
+        // if the file gets streamed we need to remove the .part extension
168
+        // to get the right target
169
+        $ext = pathinfo($filename, PATHINFO_EXTENSION);
170
+        if ($ext === 'part') {
171
+            $filename = substr($filename, 0, -5);
172
+        }
173
+
174
+        // we only handle existing files
175
+        if (! Filesystem::file_exists($filename) || Filesystem::is_dir($filename)) {
176
+            return false;
177
+        }
178
+
179
+        list($uid, $filename) = self::getUidAndFilename($filename);
180
+
181
+        $files_view = new View('/'.$uid .'/files');
182
+
183
+        $eventDispatcher = \OC::$server->getEventDispatcher();
184
+        $fileInfo = $files_view->getFileInfo($filename);
185
+        $id = $fileInfo->getId();
186
+        $nodes = \OC::$server->getRootFolder()->getById($id);
187
+        foreach ($nodes as $node) {
188
+            $event = new CreateVersionEvent($node);
189
+            $eventDispatcher->dispatch('OCA\Files_Versions::createVersion', $event);
190
+            if ($event->shouldCreateVersion() === false) {
191
+                return false;
192
+            }
193
+        }
194
+
195
+        // no use making versions for empty files
196
+        if ($fileInfo->getSize() === 0) {
197
+            return false;
198
+        }
199
+
200
+        /** @var IVersionManager $versionManager */
201
+        $versionManager = \OC::$server->query(IVersionManager::class);
202
+        $userManager = \OC::$server->getUserManager();
203
+        $user = $userManager->get($uid);
204
+
205
+        $versionManager->createVersion($user, $fileInfo);
206
+    }
207
+
208
+
209
+    /**
210
+     * mark file as deleted so that we can remove the versions if the file is gone
211
+     * @param string $path
212
+     */
213
+    public static function markDeletedFile($path) {
214
+        list($uid, $filename) = self::getUidAndFilename($path);
215
+        self::$deletedFiles[$path] = array(
216
+            'uid' => $uid,
217
+            'filename' => $filename);
218
+    }
219
+
220
+    /**
221
+     * delete the version from the storage and cache
222
+     *
223
+     * @param View $view
224
+     * @param string $path
225
+     */
226
+    protected static function deleteVersion($view, $path) {
227
+        $view->unlink($path);
228
+        /**
229
+         * @var \OC\Files\Storage\Storage $storage
230
+         * @var string $internalPath
231
+         */
232
+        list($storage, $internalPath) = $view->resolvePath($path);
233
+        $cache = $storage->getCache($internalPath);
234
+        $cache->remove($internalPath);
235
+    }
236
+
237
+    /**
238
+     * Delete versions of a file
239
+     */
240
+    public static function delete($path) {
241
+
242
+        $deletedFile = self::$deletedFiles[$path];
243
+        $uid = $deletedFile['uid'];
244
+        $filename = $deletedFile['filename'];
245
+
246
+        if (!Filesystem::file_exists($path)) {
247
+
248
+            $view = new View('/' . $uid . '/files_versions');
249
+
250
+            $versions = self::getVersions($uid, $filename);
251
+            if (!empty($versions)) {
252
+                foreach ($versions as $v) {
253
+                    \OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $path . $v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
254
+                    self::deleteVersion($view, $filename . '.v' . $v['version']);
255
+                    \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path . $v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
256
+                }
257
+            }
258
+        }
259
+        unset(self::$deletedFiles[$path]);
260
+    }
261
+
262
+    /**
263
+     * Rename or copy versions of a file of the given paths
264
+     *
265
+     * @param string $sourcePath source path of the file to move, relative to
266
+     * the currently logged in user's "files" folder
267
+     * @param string $targetPath target path of the file to move, relative to
268
+     * the currently logged in user's "files" folder
269
+     * @param string $operation can be 'copy' or 'rename'
270
+     */
271
+    public static function renameOrCopy($sourcePath, $targetPath, $operation) {
272
+        list($sourceOwner, $sourcePath) = self::getSourcePathAndUser($sourcePath);
273
+
274
+        // it was a upload of a existing file if no old path exists
275
+        // in this case the pre-hook already called the store method and we can
276
+        // stop here
277
+        if ($sourcePath === false) {
278
+            return true;
279
+        }
280
+
281
+        list($targetOwner, $targetPath) = self::getUidAndFilename($targetPath);
282
+
283
+        $sourcePath = ltrim($sourcePath, '/');
284
+        $targetPath = ltrim($targetPath, '/');
285
+
286
+        $rootView = new View('');
287
+
288
+        // did we move a directory ?
289
+        if ($rootView->is_dir('/' . $targetOwner . '/files/' . $targetPath)) {
290
+            // does the directory exists for versions too ?
291
+            if ($rootView->is_dir('/' . $sourceOwner . '/files_versions/' . $sourcePath)) {
292
+                // create missing dirs if necessary
293
+                self::createMissingDirectories($targetPath, new View('/'. $targetOwner));
294
+
295
+                // move the directory containing the versions
296
+                $rootView->$operation(
297
+                    '/' . $sourceOwner . '/files_versions/' . $sourcePath,
298
+                    '/' . $targetOwner . '/files_versions/' . $targetPath
299
+                );
300
+            }
301
+        } else if ($versions = Storage::getVersions($sourceOwner, '/' . $sourcePath)) {
302
+            // create missing dirs if necessary
303
+            self::createMissingDirectories($targetPath, new View('/'. $targetOwner));
304
+
305
+            foreach ($versions as $v) {
306
+                // move each version one by one to the target directory
307
+                $rootView->$operation(
308
+                    '/' . $sourceOwner . '/files_versions/' . $sourcePath.'.v' . $v['version'],
309
+                    '/' . $targetOwner . '/files_versions/' . $targetPath.'.v'.$v['version']
310
+                );
311
+            }
312
+        }
313
+
314
+        // if we moved versions directly for a file, schedule expiration check for that file
315
+        if (!$rootView->is_dir('/' . $targetOwner . '/files/' . $targetPath)) {
316
+            self::scheduleExpire($targetOwner, $targetPath);
317
+        }
318
+
319
+    }
320
+
321
+    /**
322
+     * Rollback to an old version of a file.
323
+     *
324
+     * @param string $file file name
325
+     * @param int $revision revision timestamp
326
+     * @return bool
327
+     */
328
+    public static function rollback($file, $revision) {
329
+
330
+        // add expected leading slash
331
+        $file = '/' . ltrim($file, '/');
332
+        list($uid, $filename) = self::getUidAndFilename($file);
333
+        if ($uid === null || trim($filename, '/') === '') {
334
+            return false;
335
+        }
336
+
337
+        // Fetch the userfolder to trigger view hooks
338
+        $userFolder = \OC::$server->getUserFolder($uid);
339
+
340
+        $users_view = new View('/'.$uid);
341
+        $files_view = new View('/'. User::getUser().'/files');
342
+
343
+        $versionCreated = false;
344
+
345
+        $fileInfo = $files_view->getFileInfo($file);
346
+
347
+        // check if user has the permissions to revert a version
348
+        if (!$fileInfo->isUpdateable()) {
349
+            return false;
350
+        }
351
+
352
+        //first create a new version
353
+        $version = 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename);
354
+        if (!$users_view->file_exists($version)) {
355
+            $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename));
356
+            $versionCreated = true;
357
+        }
358
+
359
+        $fileToRestore =  'files_versions' . $filename . '.v' . $revision;
360
+
361
+        // Restore encrypted version of the old file for the newly restored file
362
+        // This has to happen manually here since the file is manually copied below
363
+        $oldVersion = $users_view->getFileInfo($fileToRestore)->getEncryptedVersion();
364
+        $oldFileInfo = $users_view->getFileInfo($fileToRestore);
365
+        $cache = $fileInfo->getStorage()->getCache();
366
+        $cache->update(
367
+            $fileInfo->getId(), [
368
+                'encrypted' => $oldVersion,
369
+                'encryptedVersion' => $oldVersion,
370
+                'size' => $oldFileInfo->getSize()
371
+            ]
372
+        );
373
+
374
+        // rollback
375
+        if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) {
376
+            $files_view->touch($file, $revision);
377
+            Storage::scheduleExpire($uid, $file);
378
+
379
+            $node = $userFolder->get($file);
380
+
381
+            // TODO: move away from those legacy hooks!
382
+            \OC_Hook::emit('\OCP\Versions', 'rollback', array(
383
+                'path' => $filename,
384
+                'revision' => $revision,
385
+                'node' => $node,
386
+            ));
387
+            return true;
388
+        } else if ($versionCreated) {
389
+            self::deleteVersion($users_view, $version);
390
+        }
391
+
392
+        return false;
393
+
394
+    }
395
+
396
+    /**
397
+     * Stream copy file contents from $path1 to $path2
398
+     *
399
+     * @param View $view view to use for copying
400
+     * @param string $path1 source file to copy
401
+     * @param string $path2 target file
402
+     *
403
+     * @return bool true for success, false otherwise
404
+     */
405
+    private static function copyFileContents($view, $path1, $path2) {
406
+        /** @var \OC\Files\Storage\Storage $storage1 */
407
+        list($storage1, $internalPath1) = $view->resolvePath($path1);
408
+        /** @var \OC\Files\Storage\Storage $storage2 */
409
+        list($storage2, $internalPath2) = $view->resolvePath($path2);
410
+
411
+        $view->lockFile($path1, ILockingProvider::LOCK_EXCLUSIVE);
412
+        $view->lockFile($path2, ILockingProvider::LOCK_EXCLUSIVE);
413
+
414
+        // TODO add a proper way of overwriting a file while maintaining file ids
415
+        if ($storage1->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage') || $storage2->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage')) {
416
+            $source = $storage1->fopen($internalPath1, 'r');
417
+            $target = $storage2->fopen($internalPath2, 'w');
418
+            list(, $result) = \OC_Helper::streamCopy($source, $target);
419
+            fclose($source);
420
+            fclose($target);
421
+
422
+            if ($result !== false) {
423
+                $storage1->unlink($internalPath1);
424
+            }
425
+        } else {
426
+            $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
427
+        }
428
+
429
+        $view->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE);
430
+        $view->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE);
431
+
432
+        return ($result !== false);
433
+    }
434
+
435
+    /**
436
+     * get a list of all available versions of a file in descending chronological order
437
+     * @param string $uid user id from the owner of the file
438
+     * @param string $filename file to find versions of, relative to the user files dir
439
+     * @param string $userFullPath
440
+     * @return array versions newest version first
441
+     */
442
+    public static function getVersions($uid, $filename, $userFullPath = '') {
443
+        $versions = array();
444
+        if (empty($filename)) {
445
+            return $versions;
446
+        }
447
+        // fetch for old versions
448
+        $view = new View('/' . $uid . '/');
449
+
450
+        $pathinfo = pathinfo($filename);
451
+        $versionedFile = $pathinfo['basename'];
452
+
453
+        $dir = Filesystem::normalizePath(self::VERSIONS_ROOT . '/' . $pathinfo['dirname']);
454
+
455
+        $dirContent = false;
456
+        if ($view->is_dir($dir)) {
457
+            $dirContent = $view->opendir($dir);
458
+        }
459
+
460
+        if ($dirContent === false) {
461
+            return $versions;
462
+        }
463
+
464
+        if (is_resource($dirContent)) {
465
+            while (($entryName = readdir($dirContent)) !== false) {
466
+                if (!Filesystem::isIgnoredDir($entryName)) {
467
+                    $pathparts = pathinfo($entryName);
468
+                    $filename = $pathparts['filename'];
469
+                    if ($filename === $versionedFile) {
470
+                        $pathparts = pathinfo($entryName);
471
+                        $timestamp = substr($pathparts['extension'], 1);
472
+                        $filename = $pathparts['filename'];
473
+                        $key = $timestamp . '#' . $filename;
474
+                        $versions[$key]['version'] = $timestamp;
475
+                        $versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($timestamp);
476
+                        if (empty($userFullPath)) {
477
+                            $versions[$key]['preview'] = '';
478
+                        } else {
479
+                            $versions[$key]['preview'] = \OC::$server->getURLGenerator('files_version.Preview.getPreview', ['file' => $userFullPath, 'version' => $timestamp]);
480
+                        }
481
+                        $versions[$key]['path'] = Filesystem::normalizePath($pathinfo['dirname'] . '/' . $filename);
482
+                        $versions[$key]['name'] = $versionedFile;
483
+                        $versions[$key]['size'] = $view->filesize($dir . '/' . $entryName);
484
+                        $versions[$key]['mimetype'] = \OC::$server->getMimeTypeDetector()->detectPath($versionedFile);
485
+                    }
486
+                }
487
+            }
488
+            closedir($dirContent);
489
+        }
490
+
491
+        // sort with newest version first
492
+        krsort($versions);
493
+
494
+        return $versions;
495
+    }
496
+
497
+    /**
498
+     * Expire versions that older than max version retention time
499
+     * @param string $uid
500
+     */
501
+    public static function expireOlderThanMaxForUser($uid){
502
+        $expiration = self::getExpiration();
503
+        $threshold = $expiration->getMaxAgeAsTimestamp();
504
+        $versions = self::getAllVersions($uid);
505
+        if (!$threshold || !array_key_exists('all', $versions)) {
506
+            return;
507
+        }
508
+
509
+        $toDelete = [];
510
+        foreach (array_reverse($versions['all']) as $key => $version) {
511
+            if ((int)$version['version'] <$threshold) {
512
+                $toDelete[$key] = $version;
513
+            } else {
514
+                //Versions are sorted by time - nothing mo to iterate.
515
+                break;
516
+            }
517
+        }
518
+
519
+        $view = new View('/' . $uid . '/files_versions');
520
+        if (!empty($toDelete)) {
521
+            foreach ($toDelete as $version) {
522
+                \OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_RETENTION_CONSTRAINT));
523
+                self::deleteVersion($view, $version['path'] . '.v' . $version['version']);
524
+                \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_RETENTION_CONSTRAINT));
525
+            }
526
+        }
527
+    }
528
+
529
+    /**
530
+     * translate a timestamp into a string like "5 days ago"
531
+     * @param int $timestamp
532
+     * @return string for example "5 days ago"
533
+     */
534
+    private static function getHumanReadableTimestamp($timestamp) {
535
+
536
+        $diff = time() - $timestamp;
537
+
538
+        if ($diff < 60) { // first minute
539
+            return  $diff . " seconds ago";
540
+        } elseif ($diff < 3600) { //first hour
541
+            return round($diff / 60) . " minutes ago";
542
+        } elseif ($diff < 86400) { // first day
543
+            return round($diff / 3600) . " hours ago";
544
+        } elseif ($diff < 604800) { //first week
545
+            return round($diff / 86400) . " days ago";
546
+        } elseif ($diff < 2419200) { //first month
547
+            return round($diff / 604800) . " weeks ago";
548
+        } elseif ($diff < 29030400) { // first year
549
+            return round($diff / 2419200) . " months ago";
550
+        } else {
551
+            return round($diff / 29030400) . " years ago";
552
+        }
553
+
554
+    }
555
+
556
+    /**
557
+     * returns all stored file versions from a given user
558
+     * @param string $uid id of the user
559
+     * @return array with contains two arrays 'all' which contains all versions sorted by age and 'by_file' which contains all versions sorted by filename
560
+     */
561
+    private static function getAllVersions($uid) {
562
+        $view = new View('/' . $uid . '/');
563
+        $dirs = array(self::VERSIONS_ROOT);
564
+        $versions = array();
565
+
566
+        while (!empty($dirs)) {
567
+            $dir = array_pop($dirs);
568
+            $files = $view->getDirectoryContent($dir);
569
+
570
+            foreach ($files as $file) {
571
+                $fileData = $file->getData();
572
+                $filePath = $dir . '/' . $fileData['name'];
573
+                if ($file['type'] === 'dir') {
574
+                    $dirs[] = $filePath;
575
+                } else {
576
+                    $versionsBegin = strrpos($filePath, '.v');
577
+                    $relPathStart = strlen(self::VERSIONS_ROOT);
578
+                    $version = substr($filePath, $versionsBegin + 2);
579
+                    $relpath = substr($filePath, $relPathStart, $versionsBegin - $relPathStart);
580
+                    $key = $version . '#' . $relpath;
581
+                    $versions[$key] = array('path' => $relpath, 'timestamp' => $version);
582
+                }
583
+            }
584
+        }
585
+
586
+        // newest version first
587
+        krsort($versions);
588
+
589
+        $result = array();
590
+
591
+        foreach ($versions as $key => $value) {
592
+            $size = $view->filesize(self::VERSIONS_ROOT.'/'.$value['path'].'.v'.$value['timestamp']);
593
+            $filename = $value['path'];
594
+
595
+            $result['all'][$key]['version'] = $value['timestamp'];
596
+            $result['all'][$key]['path'] = $filename;
597
+            $result['all'][$key]['size'] = $size;
598
+
599
+            $result['by_file'][$filename][$key]['version'] = $value['timestamp'];
600
+            $result['by_file'][$filename][$key]['path'] = $filename;
601
+            $result['by_file'][$filename][$key]['size'] = $size;
602
+        }
603
+
604
+        return $result;
605
+    }
606
+
607
+    /**
608
+     * get list of files we want to expire
609
+     * @param array $versions list of versions
610
+     * @param integer $time
611
+     * @param bool $quotaExceeded is versions storage limit reached
612
+     * @return array containing the list of to deleted versions and the size of them
613
+     */
614
+    protected static function getExpireList($time, $versions, $quotaExceeded = false) {
615
+        $expiration = self::getExpiration();
616
+
617
+        if ($expiration->shouldAutoExpire()) {
618
+            list($toDelete, $size) = self::getAutoExpireList($time, $versions);
619
+        } else {
620
+            $size = 0;
621
+            $toDelete = [];  // versions we want to delete
622
+        }
623
+
624
+        foreach ($versions as $key => $version) {
625
+            if ($expiration->isExpired($version['version'], $quotaExceeded) && !isset($toDelete[$key])) {
626
+                $size += $version['size'];
627
+                $toDelete[$key] = $version['path'] . '.v' . $version['version'];
628
+            }
629
+        }
630
+
631
+        return [$toDelete, $size];
632
+    }
633
+
634
+    /**
635
+     * get list of files we want to expire
636
+     * @param array $versions list of versions
637
+     * @param integer $time
638
+     * @return array containing the list of to deleted versions and the size of them
639
+     */
640
+    protected static function getAutoExpireList($time, $versions) {
641
+        $size = 0;
642
+        $toDelete = array();  // versions we want to delete
643
+
644
+        $interval = 1;
645
+        $step = Storage::$max_versions_per_interval[$interval]['step'];
646
+        if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] === -1) {
647
+            $nextInterval = -1;
648
+        } else {
649
+            $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
650
+        }
651
+
652
+        $firstVersion = reset($versions);
653
+        $firstKey = key($versions);
654
+        $prevTimestamp = $firstVersion['version'];
655
+        $nextVersion = $firstVersion['version'] - $step;
656
+        unset($versions[$firstKey]);
657
+
658
+        foreach ($versions as $key => $version) {
659
+            $newInterval = true;
660
+            while ($newInterval) {
661
+                if ($nextInterval === -1 || $prevTimestamp > $nextInterval) {
662
+                    if ($version['version'] > $nextVersion) {
663
+                        //distance between two version too small, mark to delete
664
+                        $toDelete[$key] = $version['path'] . '.v' . $version['version'];
665
+                        $size += $version['size'];
666
+                        \OC::$server->getLogger()->info('Mark to expire '. $version['path'] .' next version should be ' . $nextVersion . " or smaller. (prevTimestamp: " . $prevTimestamp . "; step: " . $step, ['app' => 'files_versions']);
667
+                    } else {
668
+                        $nextVersion = $version['version'] - $step;
669
+                        $prevTimestamp = $version['version'];
670
+                    }
671
+                    $newInterval = false; // version checked so we can move to the next one
672
+                } else { // time to move on to the next interval
673
+                    $interval++;
674
+                    $step = Storage::$max_versions_per_interval[$interval]['step'];
675
+                    $nextVersion = $prevTimestamp - $step;
676
+                    if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] === -1) {
677
+                        $nextInterval = -1;
678
+                    } else {
679
+                        $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
680
+                    }
681
+                    $newInterval = true; // we changed the interval -> check same version with new interval
682
+                }
683
+            }
684
+        }
685
+
686
+        return array($toDelete, $size);
687
+    }
688
+
689
+    /**
690
+     * Schedule versions expiration for the given file
691
+     *
692
+     * @param string $uid owner of the file
693
+     * @param string $fileName file/folder for which to schedule expiration
694
+     */
695
+    public static function scheduleExpire($uid, $fileName) {
696
+        // let the admin disable auto expire
697
+        $expiration = self::getExpiration();
698
+        if ($expiration->isEnabled()) {
699
+            $command = new Expire($uid, $fileName);
700
+            \OC::$server->getCommandBus()->push($command);
701
+        }
702
+    }
703
+
704
+    /**
705
+     * Expire versions which exceed the quota.
706
+     *
707
+     * This will setup the filesystem for the given user but will not
708
+     * tear it down afterwards.
709
+     *
710
+     * @param string $filename path to file to expire
711
+     * @param string $uid user for which to expire the version
712
+     * @return bool|int|null
713
+     */
714
+    public static function expire($filename, $uid) {
715
+        $expiration = self::getExpiration();
716
+
717
+        if ($expiration->isEnabled()) {
718
+            // get available disk space for user
719
+            $user = \OC::$server->getUserManager()->get($uid);
720
+            if (is_null($user)) {
721
+                \OC::$server->getLogger()->error('Backends provided no user object for ' . $uid, ['app' => 'files_versions']);
722
+                throw new \OC\User\NoUserException('Backends provided no user object for ' . $uid);
723
+            }
724
+
725
+            \OC_Util::setupFS($uid);
726
+
727
+            if (!Filesystem::file_exists($filename)) {
728
+                return false;
729
+            }
730
+
731
+            if (empty($filename)) {
732
+                // file maybe renamed or deleted
733
+                return false;
734
+            }
735
+            $versionsFileview = new View('/'.$uid.'/files_versions');
736
+
737
+            $softQuota = true;
738
+            $quota = $user->getQuota();
739
+            if ( $quota === null || $quota === 'none' ) {
740
+                $quota = Filesystem::free_space('/');
741
+                $softQuota = false;
742
+            } else {
743
+                $quota = \OCP\Util::computerFileSize($quota);
744
+            }
745
+
746
+            // make sure that we have the current size of the version history
747
+            $versionsSize = self::getVersionsSize($uid);
748
+
749
+            // calculate available space for version history
750
+            // subtract size of files and current versions size from quota
751
+            if ($quota >= 0) {
752
+                if ($softQuota) {
753
+                    $files_view = new View('/' . $uid . '/files');
754
+                    $rootInfo = $files_view->getFileInfo('/', false);
755
+                    $free = $quota - $rootInfo['size']; // remaining free space for user
756
+                    if ($free > 0) {
757
+                        $availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions
758
+                    } else {
759
+                        $availableSpace = $free - $versionsSize;
760
+                    }
761
+                } else {
762
+                    $availableSpace = $quota;
763
+                }
764
+            } else {
765
+                $availableSpace = PHP_INT_MAX;
766
+            }
767
+
768
+            $allVersions = Storage::getVersions($uid, $filename);
769
+
770
+            $time = time();
771
+            list($toDelete, $sizeOfDeletedVersions) = self::getExpireList($time, $allVersions, $availableSpace <= 0);
772
+
773
+            $availableSpace = $availableSpace + $sizeOfDeletedVersions;
774
+            $versionsSize = $versionsSize - $sizeOfDeletedVersions;
775
+
776
+            // if still not enough free space we rearrange the versions from all files
777
+            if ($availableSpace <= 0) {
778
+                $result = Storage::getAllVersions($uid);
779
+                $allVersions = $result['all'];
780
+
781
+                foreach ($result['by_file'] as $versions) {
782
+                    list($toDeleteNew, $size) = self::getExpireList($time, $versions, $availableSpace <= 0);
783
+                    $toDelete = array_merge($toDelete, $toDeleteNew);
784
+                    $sizeOfDeletedVersions += $size;
785
+                }
786
+                $availableSpace = $availableSpace + $sizeOfDeletedVersions;
787
+                $versionsSize = $versionsSize - $sizeOfDeletedVersions;
788
+            }
789
+
790
+            $logger = \OC::$server->getLogger();
791
+            foreach($toDelete as $key => $path) {
792
+                \OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $path, 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
793
+                self::deleteVersion($versionsFileview, $path);
794
+                \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path, 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
795
+                unset($allVersions[$key]); // update array with the versions we keep
796
+                $logger->info('Expire: ' . $path, ['app' => 'files_versions']);
797
+            }
798
+
799
+            // Check if enough space is available after versions are rearranged.
800
+            // If not we delete the oldest versions until we meet the size limit for versions,
801
+            // but always keep the two latest versions
802
+            $numOfVersions = count($allVersions) -2 ;
803
+            $i = 0;
804
+            // sort oldest first and make sure that we start at the first element
805
+            ksort($allVersions);
806
+            reset($allVersions);
807
+            while ($availableSpace < 0 && $i < $numOfVersions) {
808
+                $version = current($allVersions);
809
+                \OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
810
+                self::deleteVersion($versionsFileview, $version['path'] . '.v' . $version['version']);
811
+                \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
812
+                \OC::$server->getLogger()->info('running out of space! Delete oldest version: ' . $version['path'].'.v'.$version['version'], ['app' => 'files_versions']);
813
+                $versionsSize -= $version['size'];
814
+                $availableSpace += $version['size'];
815
+                next($allVersions);
816
+                $i++;
817
+            }
818
+
819
+            return $versionsSize; // finally return the new size of the version history
820
+        }
821
+
822
+        return false;
823
+    }
824
+
825
+    /**
826
+     * Create recursively missing directories inside of files_versions
827
+     * that match the given path to a file.
828
+     *
829
+     * @param string $filename $path to a file, relative to the user's
830
+     * "files" folder
831
+     * @param View $view view on data/user/
832
+     */
833
+    public static function createMissingDirectories($filename, $view) {
834
+        $dirname = Filesystem::normalizePath(dirname($filename));
835
+        $dirParts = explode('/', $dirname);
836
+        $dir = "/files_versions";
837
+        foreach ($dirParts as $part) {
838
+            $dir = $dir . '/' . $part;
839
+            if (!$view->file_exists($dir)) {
840
+                $view->mkdir($dir);
841
+            }
842
+        }
843
+    }
844
+
845
+    /**
846
+     * Static workaround
847
+     * @return Expiration
848
+     */
849
+    protected static function getExpiration(){
850
+        if (is_null(self::$application)) {
851
+            self::$application = new Application();
852
+        }
853
+        return self::$application->getContainer()->query(Expiration::class);
854
+    }
855 855
 
856 856
 }
Please login to merge, or discard this patch.
Spacing   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -55,8 +55,8 @@  discard block
 block discarded – undo
55 55
 
56 56
 class Storage {
57 57
 
58
-	const DEFAULTENABLED=true;
59
-	const DEFAULTMAXSIZE=50; // unit: percentage; 50% of available disk space/quota
58
+	const DEFAULTENABLED = true;
59
+	const DEFAULTMAXSIZE = 50; // unit: percentage; 50% of available disk space/quota
60 60
 	const VERSIONS_ROOT = 'files_versions/';
61 61
 
62 62
 	const DELETE_TRIGGER_MASTER_REMOVED = 0;
@@ -70,17 +70,17 @@  discard block
 block discarded – undo
70 70
 
71 71
 	private static $max_versions_per_interval = array(
72 72
 		//first 10sec, one version every 2sec
73
-		1 => array('intervalEndsAfter' => 10,      'step' => 2),
73
+		1 => array('intervalEndsAfter' => 10, 'step' => 2),
74 74
 		//next minute, one version every 10sec
75
-		2 => array('intervalEndsAfter' => 60,      'step' => 10),
75
+		2 => array('intervalEndsAfter' => 60, 'step' => 10),
76 76
 		//next hour, one version every minute
77
-		3 => array('intervalEndsAfter' => 3600,    'step' => 60),
77
+		3 => array('intervalEndsAfter' => 3600, 'step' => 60),
78 78
 		//next 24h, one version every hour
79
-		4 => array('intervalEndsAfter' => 86400,   'step' => 3600),
79
+		4 => array('intervalEndsAfter' => 86400, 'step' => 3600),
80 80
 		//next 30days, one version per day
81 81
 		5 => array('intervalEndsAfter' => 2592000, 'step' => 86400),
82 82
 		//until the end one version per week
83
-		6 => array('intervalEndsAfter' => -1,      'step' => 604800),
83
+		6 => array('intervalEndsAfter' => -1, 'step' => 604800),
84 84
 	);
85 85
 
86 86
 	/** @var \OCA\Files_Versions\AppInfo\Application */
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
 			$uid = User::getUser();
105 105
 		}
106 106
 		Filesystem::initMountPoints($uid);
107
-		if ( $uid !== User::getUser() ) {
107
+		if ($uid !== User::getUser()) {
108 108
 			$info = Filesystem::getFileInfo($filename);
109 109
 			$ownerView = new View('/'.$uid.'/files');
110 110
 			try {
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
 	 * @return int versions size
155 155
 	 */
156 156
 	private static function getVersionsSize($user) {
157
-		$view = new View('/' . $user);
157
+		$view = new View('/'.$user);
158 158
 		$fileInfo = $view->getFileInfo('/files_versions');
159 159
 		return isset($fileInfo['size']) ? $fileInfo['size'] : 0;
160 160
 	}
@@ -172,13 +172,13 @@  discard block
 block discarded – undo
172 172
 		}
173 173
 
174 174
 		// we only handle existing files
175
-		if (! Filesystem::file_exists($filename) || Filesystem::is_dir($filename)) {
175
+		if (!Filesystem::file_exists($filename) || Filesystem::is_dir($filename)) {
176 176
 			return false;
177 177
 		}
178 178
 
179 179
 		list($uid, $filename) = self::getUidAndFilename($filename);
180 180
 
181
-		$files_view = new View('/'.$uid .'/files');
181
+		$files_view = new View('/'.$uid.'/files');
182 182
 
183 183
 		$eventDispatcher = \OC::$server->getEventDispatcher();
184 184
 		$fileInfo = $files_view->getFileInfo($filename);
@@ -245,14 +245,14 @@  discard block
 block discarded – undo
245 245
 
246 246
 		if (!Filesystem::file_exists($path)) {
247 247
 
248
-			$view = new View('/' . $uid . '/files_versions');
248
+			$view = new View('/'.$uid.'/files_versions');
249 249
 
250 250
 			$versions = self::getVersions($uid, $filename);
251 251
 			if (!empty($versions)) {
252 252
 				foreach ($versions as $v) {
253
-					\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $path . $v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
254
-					self::deleteVersion($view, $filename . '.v' . $v['version']);
255
-					\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path . $v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
253
+					\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $path.$v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
254
+					self::deleteVersion($view, $filename.'.v'.$v['version']);
255
+					\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path.$v['version'], 'trigger' => self::DELETE_TRIGGER_MASTER_REMOVED));
256 256
 				}
257 257
 			}
258 258
 		}
@@ -286,33 +286,33 @@  discard block
 block discarded – undo
286 286
 		$rootView = new View('');
287 287
 
288 288
 		// did we move a directory ?
289
-		if ($rootView->is_dir('/' . $targetOwner . '/files/' . $targetPath)) {
289
+		if ($rootView->is_dir('/'.$targetOwner.'/files/'.$targetPath)) {
290 290
 			// does the directory exists for versions too ?
291
-			if ($rootView->is_dir('/' . $sourceOwner . '/files_versions/' . $sourcePath)) {
291
+			if ($rootView->is_dir('/'.$sourceOwner.'/files_versions/'.$sourcePath)) {
292 292
 				// create missing dirs if necessary
293
-				self::createMissingDirectories($targetPath, new View('/'. $targetOwner));
293
+				self::createMissingDirectories($targetPath, new View('/'.$targetOwner));
294 294
 
295 295
 				// move the directory containing the versions
296 296
 				$rootView->$operation(
297
-					'/' . $sourceOwner . '/files_versions/' . $sourcePath,
298
-					'/' . $targetOwner . '/files_versions/' . $targetPath
297
+					'/'.$sourceOwner.'/files_versions/'.$sourcePath,
298
+					'/'.$targetOwner.'/files_versions/'.$targetPath
299 299
 				);
300 300
 			}
301
-		} else if ($versions = Storage::getVersions($sourceOwner, '/' . $sourcePath)) {
301
+		} else if ($versions = Storage::getVersions($sourceOwner, '/'.$sourcePath)) {
302 302
 			// create missing dirs if necessary
303
-			self::createMissingDirectories($targetPath, new View('/'. $targetOwner));
303
+			self::createMissingDirectories($targetPath, new View('/'.$targetOwner));
304 304
 
305 305
 			foreach ($versions as $v) {
306 306
 				// move each version one by one to the target directory
307 307
 				$rootView->$operation(
308
-					'/' . $sourceOwner . '/files_versions/' . $sourcePath.'.v' . $v['version'],
309
-					'/' . $targetOwner . '/files_versions/' . $targetPath.'.v'.$v['version']
308
+					'/'.$sourceOwner.'/files_versions/'.$sourcePath.'.v'.$v['version'],
309
+					'/'.$targetOwner.'/files_versions/'.$targetPath.'.v'.$v['version']
310 310
 				);
311 311
 			}
312 312
 		}
313 313
 
314 314
 		// if we moved versions directly for a file, schedule expiration check for that file
315
-		if (!$rootView->is_dir('/' . $targetOwner . '/files/' . $targetPath)) {
315
+		if (!$rootView->is_dir('/'.$targetOwner.'/files/'.$targetPath)) {
316 316
 			self::scheduleExpire($targetOwner, $targetPath);
317 317
 		}
318 318
 
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
 	public static function rollback($file, $revision) {
329 329
 
330 330
 		// add expected leading slash
331
-		$file = '/' . ltrim($file, '/');
331
+		$file = '/'.ltrim($file, '/');
332 332
 		list($uid, $filename) = self::getUidAndFilename($file);
333 333
 		if ($uid === null || trim($filename, '/') === '') {
334 334
 			return false;
@@ -338,7 +338,7 @@  discard block
 block discarded – undo
338 338
 		$userFolder = \OC::$server->getUserFolder($uid);
339 339
 
340 340
 		$users_view = new View('/'.$uid);
341
-		$files_view = new View('/'. User::getUser().'/files');
341
+		$files_view = new View('/'.User::getUser().'/files');
342 342
 
343 343
 		$versionCreated = false;
344 344
 
@@ -356,7 +356,7 @@  discard block
 block discarded – undo
356 356
 			$versionCreated = true;
357 357
 		}
358 358
 
359
-		$fileToRestore =  'files_versions' . $filename . '.v' . $revision;
359
+		$fileToRestore = 'files_versions'.$filename.'.v'.$revision;
360 360
 
361 361
 		// Restore encrypted version of the old file for the newly restored file
362 362
 		// This has to happen manually here since the file is manually copied below
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
 		);
373 373
 
374 374
 		// rollback
375
-		if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) {
375
+		if (self::copyFileContents($users_view, $fileToRestore, 'files'.$filename)) {
376 376
 			$files_view->touch($file, $revision);
377 377
 			Storage::scheduleExpire($uid, $file);
378 378
 
@@ -445,12 +445,12 @@  discard block
 block discarded – undo
445 445
 			return $versions;
446 446
 		}
447 447
 		// fetch for old versions
448
-		$view = new View('/' . $uid . '/');
448
+		$view = new View('/'.$uid.'/');
449 449
 
450 450
 		$pathinfo = pathinfo($filename);
451 451
 		$versionedFile = $pathinfo['basename'];
452 452
 
453
-		$dir = Filesystem::normalizePath(self::VERSIONS_ROOT . '/' . $pathinfo['dirname']);
453
+		$dir = Filesystem::normalizePath(self::VERSIONS_ROOT.'/'.$pathinfo['dirname']);
454 454
 
455 455
 		$dirContent = false;
456 456
 		if ($view->is_dir($dir)) {
@@ -470,7 +470,7 @@  discard block
 block discarded – undo
470 470
 						$pathparts = pathinfo($entryName);
471 471
 						$timestamp = substr($pathparts['extension'], 1);
472 472
 						$filename = $pathparts['filename'];
473
-						$key = $timestamp . '#' . $filename;
473
+						$key = $timestamp.'#'.$filename;
474 474
 						$versions[$key]['version'] = $timestamp;
475 475
 						$versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($timestamp);
476 476
 						if (empty($userFullPath)) {
@@ -478,9 +478,9 @@  discard block
 block discarded – undo
478 478
 						} else {
479 479
 							$versions[$key]['preview'] = \OC::$server->getURLGenerator('files_version.Preview.getPreview', ['file' => $userFullPath, 'version' => $timestamp]);
480 480
 						}
481
-						$versions[$key]['path'] = Filesystem::normalizePath($pathinfo['dirname'] . '/' . $filename);
481
+						$versions[$key]['path'] = Filesystem::normalizePath($pathinfo['dirname'].'/'.$filename);
482 482
 						$versions[$key]['name'] = $versionedFile;
483
-						$versions[$key]['size'] = $view->filesize($dir . '/' . $entryName);
483
+						$versions[$key]['size'] = $view->filesize($dir.'/'.$entryName);
484 484
 						$versions[$key]['mimetype'] = \OC::$server->getMimeTypeDetector()->detectPath($versionedFile);
485 485
 					}
486 486
 				}
@@ -498,7 +498,7 @@  discard block
 block discarded – undo
498 498
 	 * Expire versions that older than max version retention time
499 499
 	 * @param string $uid
500 500
 	 */
501
-	public static function expireOlderThanMaxForUser($uid){
501
+	public static function expireOlderThanMaxForUser($uid) {
502 502
 		$expiration = self::getExpiration();
503 503
 		$threshold = $expiration->getMaxAgeAsTimestamp();
504 504
 		$versions = self::getAllVersions($uid);
@@ -508,7 +508,7 @@  discard block
 block discarded – undo
508 508
 
509 509
 		$toDelete = [];
510 510
 		foreach (array_reverse($versions['all']) as $key => $version) {
511
-			if ((int)$version['version'] <$threshold) {
511
+			if ((int) $version['version'] < $threshold) {
512 512
 				$toDelete[$key] = $version;
513 513
 			} else {
514 514
 				//Versions are sorted by time - nothing mo to iterate.
@@ -516,11 +516,11 @@  discard block
 block discarded – undo
516 516
 			}
517 517
 		}
518 518
 
519
-		$view = new View('/' . $uid . '/files_versions');
519
+		$view = new View('/'.$uid.'/files_versions');
520 520
 		if (!empty($toDelete)) {
521 521
 			foreach ($toDelete as $version) {
522 522
 				\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_RETENTION_CONSTRAINT));
523
-				self::deleteVersion($view, $version['path'] . '.v' . $version['version']);
523
+				self::deleteVersion($view, $version['path'].'.v'.$version['version']);
524 524
 				\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_RETENTION_CONSTRAINT));
525 525
 			}
526 526
 		}
@@ -536,19 +536,19 @@  discard block
 block discarded – undo
536 536
 		$diff = time() - $timestamp;
537 537
 
538 538
 		if ($diff < 60) { // first minute
539
-			return  $diff . " seconds ago";
539
+			return  $diff." seconds ago";
540 540
 		} elseif ($diff < 3600) { //first hour
541
-			return round($diff / 60) . " minutes ago";
541
+			return round($diff / 60)." minutes ago";
542 542
 		} elseif ($diff < 86400) { // first day
543
-			return round($diff / 3600) . " hours ago";
543
+			return round($diff / 3600)." hours ago";
544 544
 		} elseif ($diff < 604800) { //first week
545
-			return round($diff / 86400) . " days ago";
545
+			return round($diff / 86400)." days ago";
546 546
 		} elseif ($diff < 2419200) { //first month
547
-			return round($diff / 604800) . " weeks ago";
547
+			return round($diff / 604800)." weeks ago";
548 548
 		} elseif ($diff < 29030400) { // first year
549
-			return round($diff / 2419200) . " months ago";
549
+			return round($diff / 2419200)." months ago";
550 550
 		} else {
551
-			return round($diff / 29030400) . " years ago";
551
+			return round($diff / 29030400)." years ago";
552 552
 		}
553 553
 
554 554
 	}
@@ -559,7 +559,7 @@  discard block
 block discarded – undo
559 559
 	 * @return array with contains two arrays 'all' which contains all versions sorted by age and 'by_file' which contains all versions sorted by filename
560 560
 	 */
561 561
 	private static function getAllVersions($uid) {
562
-		$view = new View('/' . $uid . '/');
562
+		$view = new View('/'.$uid.'/');
563 563
 		$dirs = array(self::VERSIONS_ROOT);
564 564
 		$versions = array();
565 565
 
@@ -569,7 +569,7 @@  discard block
 block discarded – undo
569 569
 
570 570
 			foreach ($files as $file) {
571 571
 				$fileData = $file->getData();
572
-				$filePath = $dir . '/' . $fileData['name'];
572
+				$filePath = $dir.'/'.$fileData['name'];
573 573
 				if ($file['type'] === 'dir') {
574 574
 					$dirs[] = $filePath;
575 575
 				} else {
@@ -577,7 +577,7 @@  discard block
 block discarded – undo
577 577
 					$relPathStart = strlen(self::VERSIONS_ROOT);
578 578
 					$version = substr($filePath, $versionsBegin + 2);
579 579
 					$relpath = substr($filePath, $relPathStart, $versionsBegin - $relPathStart);
580
-					$key = $version . '#' . $relpath;
580
+					$key = $version.'#'.$relpath;
581 581
 					$versions[$key] = array('path' => $relpath, 'timestamp' => $version);
582 582
 				}
583 583
 			}
@@ -618,13 +618,13 @@  discard block
 block discarded – undo
618 618
 			list($toDelete, $size) = self::getAutoExpireList($time, $versions);
619 619
 		} else {
620 620
 			$size = 0;
621
-			$toDelete = [];  // versions we want to delete
621
+			$toDelete = []; // versions we want to delete
622 622
 		}
623 623
 
624 624
 		foreach ($versions as $key => $version) {
625 625
 			if ($expiration->isExpired($version['version'], $quotaExceeded) && !isset($toDelete[$key])) {
626 626
 				$size += $version['size'];
627
-				$toDelete[$key] = $version['path'] . '.v' . $version['version'];
627
+				$toDelete[$key] = $version['path'].'.v'.$version['version'];
628 628
 			}
629 629
 		}
630 630
 
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
 	 */
640 640
 	protected static function getAutoExpireList($time, $versions) {
641 641
 		$size = 0;
642
-		$toDelete = array();  // versions we want to delete
642
+		$toDelete = array(); // versions we want to delete
643 643
 
644 644
 		$interval = 1;
645 645
 		$step = Storage::$max_versions_per_interval[$interval]['step'];
@@ -661,9 +661,9 @@  discard block
 block discarded – undo
661 661
 				if ($nextInterval === -1 || $prevTimestamp > $nextInterval) {
662 662
 					if ($version['version'] > $nextVersion) {
663 663
 						//distance between two version too small, mark to delete
664
-						$toDelete[$key] = $version['path'] . '.v' . $version['version'];
664
+						$toDelete[$key] = $version['path'].'.v'.$version['version'];
665 665
 						$size += $version['size'];
666
-						\OC::$server->getLogger()->info('Mark to expire '. $version['path'] .' next version should be ' . $nextVersion . " or smaller. (prevTimestamp: " . $prevTimestamp . "; step: " . $step, ['app' => 'files_versions']);
666
+						\OC::$server->getLogger()->info('Mark to expire '.$version['path'].' next version should be '.$nextVersion." or smaller. (prevTimestamp: ".$prevTimestamp."; step: ".$step, ['app' => 'files_versions']);
667 667
 					} else {
668 668
 						$nextVersion = $version['version'] - $step;
669 669
 						$prevTimestamp = $version['version'];
@@ -718,8 +718,8 @@  discard block
 block discarded – undo
718 718
 			// get available disk space for user
719 719
 			$user = \OC::$server->getUserManager()->get($uid);
720 720
 			if (is_null($user)) {
721
-				\OC::$server->getLogger()->error('Backends provided no user object for ' . $uid, ['app' => 'files_versions']);
722
-				throw new \OC\User\NoUserException('Backends provided no user object for ' . $uid);
721
+				\OC::$server->getLogger()->error('Backends provided no user object for '.$uid, ['app' => 'files_versions']);
722
+				throw new \OC\User\NoUserException('Backends provided no user object for '.$uid);
723 723
 			}
724 724
 
725 725
 			\OC_Util::setupFS($uid);
@@ -736,7 +736,7 @@  discard block
 block discarded – undo
736 736
 
737 737
 			$softQuota = true;
738 738
 			$quota = $user->getQuota();
739
-			if ( $quota === null || $quota === 'none' ) {
739
+			if ($quota === null || $quota === 'none') {
740 740
 				$quota = Filesystem::free_space('/');
741 741
 				$softQuota = false;
742 742
 			} else {
@@ -750,7 +750,7 @@  discard block
 block discarded – undo
750 750
 			// subtract size of files and current versions size from quota
751 751
 			if ($quota >= 0) {
752 752
 				if ($softQuota) {
753
-					$files_view = new View('/' . $uid . '/files');
753
+					$files_view = new View('/'.$uid.'/files');
754 754
 					$rootInfo = $files_view->getFileInfo('/', false);
755 755
 					$free = $quota - $rootInfo['size']; // remaining free space for user
756 756
 					if ($free > 0) {
@@ -788,18 +788,18 @@  discard block
 block discarded – undo
788 788
 			}
789 789
 
790 790
 			$logger = \OC::$server->getLogger();
791
-			foreach($toDelete as $key => $path) {
791
+			foreach ($toDelete as $key => $path) {
792 792
 				\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $path, 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
793 793
 				self::deleteVersion($versionsFileview, $path);
794 794
 				\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $path, 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
795 795
 				unset($allVersions[$key]); // update array with the versions we keep
796
-				$logger->info('Expire: ' . $path, ['app' => 'files_versions']);
796
+				$logger->info('Expire: '.$path, ['app' => 'files_versions']);
797 797
 			}
798 798
 
799 799
 			// Check if enough space is available after versions are rearranged.
800 800
 			// If not we delete the oldest versions until we meet the size limit for versions,
801 801
 			// but always keep the two latest versions
802
-			$numOfVersions = count($allVersions) -2 ;
802
+			$numOfVersions = count($allVersions) - 2;
803 803
 			$i = 0;
804 804
 			// sort oldest first and make sure that we start at the first element
805 805
 			ksort($allVersions);
@@ -807,9 +807,9 @@  discard block
 block discarded – undo
807 807
 			while ($availableSpace < 0 && $i < $numOfVersions) {
808 808
 				$version = current($allVersions);
809 809
 				\OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
810
-				self::deleteVersion($versionsFileview, $version['path'] . '.v' . $version['version']);
810
+				self::deleteVersion($versionsFileview, $version['path'].'.v'.$version['version']);
811 811
 				\OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'], 'trigger' => self::DELETE_TRIGGER_QUOTA_EXCEEDED));
812
-				\OC::$server->getLogger()->info('running out of space! Delete oldest version: ' . $version['path'].'.v'.$version['version'], ['app' => 'files_versions']);
812
+				\OC::$server->getLogger()->info('running out of space! Delete oldest version: '.$version['path'].'.v'.$version['version'], ['app' => 'files_versions']);
813 813
 				$versionsSize -= $version['size'];
814 814
 				$availableSpace += $version['size'];
815 815
 				next($allVersions);
@@ -835,7 +835,7 @@  discard block
 block discarded – undo
835 835
 		$dirParts = explode('/', $dirname);
836 836
 		$dir = "/files_versions";
837 837
 		foreach ($dirParts as $part) {
838
-			$dir = $dir . '/' . $part;
838
+			$dir = $dir.'/'.$part;
839 839
 			if (!$view->file_exists($dir)) {
840 840
 				$view->mkdir($dir);
841 841
 			}
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
 	 * Static workaround
847 847
 	 * @return Expiration
848 848
 	 */
849
-	protected static function getExpiration(){
849
+	protected static function getExpiration() {
850 850
 		if (is_null(self::$application)) {
851 851
 			self::$application = new Application();
852 852
 		}
Please login to merge, or discard this patch.
apps/files_versions/lib/Controller/PreviewController.php 2 patches
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -38,70 +38,70 @@
 block discarded – undo
38 38
 
39 39
 class PreviewController extends Controller {
40 40
 
41
-	/** @var IRootFolder */
42
-	private $rootFolder;
41
+    /** @var IRootFolder */
42
+    private $rootFolder;
43 43
 
44
-	/** @var IUserSession */
45
-	private $userSession;
44
+    /** @var IUserSession */
45
+    private $userSession;
46 46
 
47
-	/** @var IMimeTypeDetector */
48
-	private $mimeTypeDetector;
47
+    /** @var IMimeTypeDetector */
48
+    private $mimeTypeDetector;
49 49
 
50
-	/** @var IVersionManager */
51
-	private $versionManager;
50
+    /** @var IVersionManager */
51
+    private $versionManager;
52 52
 
53
-	/** @var IPreview */
54
-	private $previewManager;
53
+    /** @var IPreview */
54
+    private $previewManager;
55 55
 
56
-	public function __construct(
57
-		$appName,
58
-		IRequest $request,
59
-		IRootFolder $rootFolder,
60
-		IUserSession $userSession,
61
-		IMimeTypeDetector $mimeTypeDetector,
62
-		IVersionManager $versionManager,
63
-		IPreview $previewManager
64
-	) {
65
-		parent::__construct($appName, $request);
56
+    public function __construct(
57
+        $appName,
58
+        IRequest $request,
59
+        IRootFolder $rootFolder,
60
+        IUserSession $userSession,
61
+        IMimeTypeDetector $mimeTypeDetector,
62
+        IVersionManager $versionManager,
63
+        IPreview $previewManager
64
+    ) {
65
+        parent::__construct($appName, $request);
66 66
 
67
-		$this->rootFolder = $rootFolder;
68
-		$this->userSession = $userSession;
69
-		$this->mimeTypeDetector = $mimeTypeDetector;
70
-		$this->versionManager = $versionManager;
71
-		$this->previewManager = $previewManager;
72
-	}
67
+        $this->rootFolder = $rootFolder;
68
+        $this->userSession = $userSession;
69
+        $this->mimeTypeDetector = $mimeTypeDetector;
70
+        $this->versionManager = $versionManager;
71
+        $this->previewManager = $previewManager;
72
+    }
73 73
 
74
-	/**
75
-	 * @NoAdminRequired
76
-	 * @NoCSRFRequired
77
-	 *
78
-	 * @param string $file
79
-	 * @param int $x
80
-	 * @param int $y
81
-	 * @param string $version
82
-	 * @return DataResponse|FileDisplayResponse
83
-	 */
84
-	public function getPreview(
85
-		$file = '',
86
-		$x = 44,
87
-		$y = 44,
88
-		$version = ''
89
-	) {
90
-		if ($file === '' || $version === '' || $x === 0 || $y === 0) {
91
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
92
-		}
74
+    /**
75
+     * @NoAdminRequired
76
+     * @NoCSRFRequired
77
+     *
78
+     * @param string $file
79
+     * @param int $x
80
+     * @param int $y
81
+     * @param string $version
82
+     * @return DataResponse|FileDisplayResponse
83
+     */
84
+    public function getPreview(
85
+        $file = '',
86
+        $x = 44,
87
+        $y = 44,
88
+        $version = ''
89
+    ) {
90
+        if ($file === '' || $version === '' || $x === 0 || $y === 0) {
91
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
92
+        }
93 93
 
94
-		try {
95
-			$user = $this->userSession->getUser();
96
-			$userFolder = $this->rootFolder->getUserFolder($user->getUID());
97
-			$file = $userFolder->get($file);
98
-			$versionFile = $this->versionManager->getVersionFile($user, $file, (int)$version);
99
-			$preview = $this->previewManager->getPreview($versionFile, $x, $y, true, IPreview::MODE_FILL, $versionFile->getMimetype());
100
-			return new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => $preview->getMimeType()]);
101
-		} catch (NotFoundException $e) {
102
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
103
-		} catch (\InvalidArgumentException $e) {
104
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
105
-		}
106
-	}
94
+        try {
95
+            $user = $this->userSession->getUser();
96
+            $userFolder = $this->rootFolder->getUserFolder($user->getUID());
97
+            $file = $userFolder->get($file);
98
+            $versionFile = $this->versionManager->getVersionFile($user, $file, (int)$version);
99
+            $preview = $this->previewManager->getPreview($versionFile, $x, $y, true, IPreview::MODE_FILL, $versionFile->getMimetype());
100
+            return new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => $preview->getMimeType()]);
101
+        } catch (NotFoundException $e) {
102
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
103
+        } catch (\InvalidArgumentException $e) {
104
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
105
+        }
106
+    }
107 107
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -95,7 +95,7 @@
 block discarded – undo
95 95
 			$user = $this->userSession->getUser();
96 96
 			$userFolder = $this->rootFolder->getUserFolder($user->getUID());
97 97
 			$file = $userFolder->get($file);
98
-			$versionFile = $this->versionManager->getVersionFile($user, $file, (int)$version);
98
+			$versionFile = $this->versionManager->getVersionFile($user, $file, (int) $version);
99 99
 			$preview = $this->previewManager->getPreview($versionFile, $x, $y, true, IPreview::MODE_FILL, $versionFile->getMimetype());
100 100
 			return new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => $preview->getMimeType()]);
101 101
 		} catch (NotFoundException $e) {
Please login to merge, or discard this patch.
apps/files_versions/lib/AppInfo/Application.php 2 patches
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -31,58 +31,58 @@
 block discarded – undo
31 31
 use OCA\Files_Versions\Capabilities;
32 32
 
33 33
 class Application extends App {
34
-	public function __construct(array $urlParams = array()) {
35
-		parent::__construct('files_versions', $urlParams);
34
+    public function __construct(array $urlParams = array()) {
35
+        parent::__construct('files_versions', $urlParams);
36 36
 
37
-		$container = $this->getContainer();
37
+        $container = $this->getContainer();
38 38
 
39
-		/*
39
+        /*
40 40
 		 * Register capabilities
41 41
 		 */
42
-		$container->registerCapability(Capabilities::class);
42
+        $container->registerCapability(Capabilities::class);
43 43
 
44
-		/*
44
+        /*
45 45
 		 * Register $principalBackend for the DAV collection
46 46
 		 */
47
-		$container->registerService('principalBackend', function (IAppContainer $c) {
48
-			$server = $c->getServer();
49
-			return new Principal(
50
-				$server->getUserManager(),
51
-				$server->getGroupManager(),
52
-				$server->getShareManager(),
53
-				$server->getUserSession(),
54
-				$server->getConfig()
55
-			);
56
-		});
47
+        $container->registerService('principalBackend', function (IAppContainer $c) {
48
+            $server = $c->getServer();
49
+            return new Principal(
50
+                $server->getUserManager(),
51
+                $server->getGroupManager(),
52
+                $server->getShareManager(),
53
+                $server->getUserSession(),
54
+                $server->getConfig()
55
+            );
56
+        });
57 57
 
58
-		$container->registerService(IVersionManager::class, function(IAppContainer $c) {
59
-			return new VersionManager();
60
-		});
58
+        $container->registerService(IVersionManager::class, function(IAppContainer $c) {
59
+            return new VersionManager();
60
+        });
61 61
 
62
-		$this->registerVersionBackends();
63
-	}
62
+        $this->registerVersionBackends();
63
+    }
64 64
 
65
-	public function registerVersionBackends() {
66
-		$server = $this->getContainer()->getServer();
67
-		$logger = $server->getLogger();
68
-		$appManager = $server->getAppManager();
69
-		/** @var IVersionManager $versionManager */
70
-		$versionManager = $this->getContainer()->getServer()->query(IVersionManager::class);
71
-		foreach($appManager->getInstalledApps() as $app) {
72
-			$appInfo = $appManager->getAppInfo($app);
73
-			if (isset($appInfo['versions'])) {
74
-				$backends = $appInfo['versions'];
75
-				foreach($backends as $backend) {
76
-					$class = $backend['@value'];
77
-					$for = $backend['@attributes']['for'];
78
-					try {
79
-						$backendObject = $server->query($class);
80
-						$versionManager->registerBackend($for, $backendObject);
81
-					} catch (\Exception $e) {
82
-						$logger->logException($e);
83
-					}
84
-				}
85
-			}
86
-		}
87
-	}
65
+    public function registerVersionBackends() {
66
+        $server = $this->getContainer()->getServer();
67
+        $logger = $server->getLogger();
68
+        $appManager = $server->getAppManager();
69
+        /** @var IVersionManager $versionManager */
70
+        $versionManager = $this->getContainer()->getServer()->query(IVersionManager::class);
71
+        foreach($appManager->getInstalledApps() as $app) {
72
+            $appInfo = $appManager->getAppInfo($app);
73
+            if (isset($appInfo['versions'])) {
74
+                $backends = $appInfo['versions'];
75
+                foreach($backends as $backend) {
76
+                    $class = $backend['@value'];
77
+                    $for = $backend['@attributes']['for'];
78
+                    try {
79
+                        $backendObject = $server->query($class);
80
+                        $versionManager->registerBackend($for, $backendObject);
81
+                    } catch (\Exception $e) {
82
+                        $logger->logException($e);
83
+                    }
84
+                }
85
+            }
86
+        }
87
+    }
88 88
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -44,7 +44,7 @@  discard block
 block discarded – undo
44 44
 		/*
45 45
 		 * Register $principalBackend for the DAV collection
46 46
 		 */
47
-		$container->registerService('principalBackend', function (IAppContainer $c) {
47
+		$container->registerService('principalBackend', function(IAppContainer $c) {
48 48
 			$server = $c->getServer();
49 49
 			return new Principal(
50 50
 				$server->getUserManager(),
@@ -68,11 +68,11 @@  discard block
 block discarded – undo
68 68
 		$appManager = $server->getAppManager();
69 69
 		/** @var IVersionManager $versionManager */
70 70
 		$versionManager = $this->getContainer()->getServer()->query(IVersionManager::class);
71
-		foreach($appManager->getInstalledApps() as $app) {
71
+		foreach ($appManager->getInstalledApps() as $app) {
72 72
 			$appInfo = $appManager->getAppInfo($app);
73 73
 			if (isset($appInfo['versions'])) {
74 74
 				$backends = $appInfo['versions'];
75
-				foreach($backends as $backend) {
75
+				foreach ($backends as $backend) {
76 76
 					$class = $backend['@value'];
77 77
 					$for = $backend['@attributes']['for'];
78 78
 					try {
Please login to merge, or discard this patch.