Passed
Push — master ( edf8ce...eba372 )
by Roeland
13:54 queued 15s
created
lib/private/Files/Config/UserMountCacheListener.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -29,21 +29,21 @@
 block discarded – undo
29 29
  * Listen to hooks and update the mount cache as needed
30 30
  */
31 31
 class UserMountCacheListener {
32
-	/**
33
-	 * @var IUserMountCache
34
-	 */
35
-	private $userMountCache;
32
+    /**
33
+     * @var IUserMountCache
34
+     */
35
+    private $userMountCache;
36 36
 
37
-	/**
38
-	 * UserMountCacheListener constructor.
39
-	 *
40
-	 * @param IUserMountCache $userMountCache
41
-	 */
42
-	public function __construct(IUserMountCache $userMountCache) {
43
-		$this->userMountCache = $userMountCache;
44
-	}
37
+    /**
38
+     * UserMountCacheListener constructor.
39
+     *
40
+     * @param IUserMountCache $userMountCache
41
+     */
42
+    public function __construct(IUserMountCache $userMountCache) {
43
+        $this->userMountCache = $userMountCache;
44
+    }
45 45
 
46
-	public function listen(Manager $manager) {
47
-		$manager->listen('\OC\User', 'postDelete', [$this->userMountCache, 'removeUserMounts']);
48
-	}
46
+    public function listen(Manager $manager) {
47
+        $manager->listen('\OC\User', 'postDelete', [$this->userMountCache, 'removeUserMounts']);
48
+    }
49 49
 }
Please login to merge, or discard this patch.
lib/private/Files/Config/CachedMountInfo.php 1 patch
Indentation   +110 added lines, -110 removed lines patch added patch discarded remove patch
@@ -28,114 +28,114 @@
 block discarded – undo
28 28
 use OCP\IUser;
29 29
 
30 30
 class CachedMountInfo implements ICachedMountInfo {
31
-	/**
32
-	 * @var IUser
33
-	 */
34
-	protected $user;
35
-
36
-	/**
37
-	 * @var int
38
-	 */
39
-	protected $storageId;
40
-
41
-	/**
42
-	 * @var int
43
-	 */
44
-	protected $rootId;
45
-
46
-	/**
47
-	 * @var string
48
-	 */
49
-	protected $mountPoint;
50
-
51
-	/**
52
-	 * @var int|null
53
-	 */
54
-	protected $mountId;
55
-
56
-	/**
57
-	 * @var string
58
-	 */
59
-	protected $rootInternalPath;
60
-
61
-	/**
62
-	 * CachedMountInfo constructor.
63
-	 *
64
-	 * @param IUser $user
65
-	 * @param int $storageId
66
-	 * @param int $rootId
67
-	 * @param string $mountPoint
68
-	 * @param int|null $mountId
69
-	 * @param string $rootInternalPath
70
-	 */
71
-	public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null, $rootInternalPath = '') {
72
-		$this->user = $user;
73
-		$this->storageId = $storageId;
74
-		$this->rootId = $rootId;
75
-		$this->mountPoint = $mountPoint;
76
-		$this->mountId = $mountId;
77
-		$this->rootInternalPath = $rootInternalPath;
78
-	}
79
-
80
-	/**
81
-	 * @return IUser
82
-	 */
83
-	public function getUser() {
84
-		return $this->user;
85
-	}
86
-
87
-	/**
88
-	 * @return int the numeric storage id of the mount
89
-	 */
90
-	public function getStorageId() {
91
-		return $this->storageId;
92
-	}
93
-
94
-	/**
95
-	 * @return int the fileid of the root of the mount
96
-	 */
97
-	public function getRootId() {
98
-		return $this->rootId;
99
-	}
100
-
101
-	/**
102
-	 * @return Node the root node of the mount
103
-	 */
104
-	public function getMountPointNode() {
105
-		// TODO injection etc
106
-		Filesystem::initMountPoints($this->getUser()->getUID());
107
-		$userNode = \OC::$server->getUserFolder($this->getUser()->getUID());
108
-		$nodes = $userNode->getParent()->getById($this->getRootId());
109
-		if (count($nodes) > 0) {
110
-			return $nodes[0];
111
-		} else {
112
-			return null;
113
-		}
114
-	}
115
-
116
-	/**
117
-	 * @return string the mount point of the mount for the user
118
-	 */
119
-	public function getMountPoint() {
120
-		return $this->mountPoint;
121
-	}
122
-
123
-	/**
124
-	 * Get the id of the configured mount
125
-	 *
126
-	 * @return int|null mount id or null if not applicable
127
-	 * @since 9.1.0
128
-	 */
129
-	public function getMountId() {
130
-		return $this->mountId;
131
-	}
132
-
133
-	/**
134
-	 * Get the internal path (within the storage) of the root of the mount
135
-	 *
136
-	 * @return string
137
-	 */
138
-	public function getRootInternalPath() {
139
-		return $this->rootInternalPath;
140
-	}
31
+    /**
32
+     * @var IUser
33
+     */
34
+    protected $user;
35
+
36
+    /**
37
+     * @var int
38
+     */
39
+    protected $storageId;
40
+
41
+    /**
42
+     * @var int
43
+     */
44
+    protected $rootId;
45
+
46
+    /**
47
+     * @var string
48
+     */
49
+    protected $mountPoint;
50
+
51
+    /**
52
+     * @var int|null
53
+     */
54
+    protected $mountId;
55
+
56
+    /**
57
+     * @var string
58
+     */
59
+    protected $rootInternalPath;
60
+
61
+    /**
62
+     * CachedMountInfo constructor.
63
+     *
64
+     * @param IUser $user
65
+     * @param int $storageId
66
+     * @param int $rootId
67
+     * @param string $mountPoint
68
+     * @param int|null $mountId
69
+     * @param string $rootInternalPath
70
+     */
71
+    public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null, $rootInternalPath = '') {
72
+        $this->user = $user;
73
+        $this->storageId = $storageId;
74
+        $this->rootId = $rootId;
75
+        $this->mountPoint = $mountPoint;
76
+        $this->mountId = $mountId;
77
+        $this->rootInternalPath = $rootInternalPath;
78
+    }
79
+
80
+    /**
81
+     * @return IUser
82
+     */
83
+    public function getUser() {
84
+        return $this->user;
85
+    }
86
+
87
+    /**
88
+     * @return int the numeric storage id of the mount
89
+     */
90
+    public function getStorageId() {
91
+        return $this->storageId;
92
+    }
93
+
94
+    /**
95
+     * @return int the fileid of the root of the mount
96
+     */
97
+    public function getRootId() {
98
+        return $this->rootId;
99
+    }
100
+
101
+    /**
102
+     * @return Node the root node of the mount
103
+     */
104
+    public function getMountPointNode() {
105
+        // TODO injection etc
106
+        Filesystem::initMountPoints($this->getUser()->getUID());
107
+        $userNode = \OC::$server->getUserFolder($this->getUser()->getUID());
108
+        $nodes = $userNode->getParent()->getById($this->getRootId());
109
+        if (count($nodes) > 0) {
110
+            return $nodes[0];
111
+        } else {
112
+            return null;
113
+        }
114
+    }
115
+
116
+    /**
117
+     * @return string the mount point of the mount for the user
118
+     */
119
+    public function getMountPoint() {
120
+        return $this->mountPoint;
121
+    }
122
+
123
+    /**
124
+     * Get the id of the configured mount
125
+     *
126
+     * @return int|null mount id or null if not applicable
127
+     * @since 9.1.0
128
+     */
129
+    public function getMountId() {
130
+        return $this->mountId;
131
+    }
132
+
133
+    /**
134
+     * Get the internal path (within the storage) of the root of the mount
135
+     *
136
+     * @return string
137
+     */
138
+    public function getRootInternalPath() {
139
+        return $this->rootInternalPath;
140
+    }
141 141
 }
Please login to merge, or discard this patch.
lib/private/Files/ObjectStore/Mapper.php 2 patches
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -31,25 +31,25 @@
 block discarded – undo
31 31
  * Map a user to a bucket.
32 32
  */
33 33
 class Mapper {
34
-	/** @var IUser */
35
-	private $user;
34
+    /** @var IUser */
35
+    private $user;
36 36
 
37
-	/**
38
-	 * Mapper constructor.
39
-	 *
40
-	 * @param IUser $user
41
-	 */
42
-	public function __construct(IUser $user) {
43
-		$this->user = $user;
44
-	}
37
+    /**
38
+     * Mapper constructor.
39
+     *
40
+     * @param IUser $user
41
+     */
42
+    public function __construct(IUser $user) {
43
+        $this->user = $user;
44
+    }
45 45
 
46
-	/**
47
-	 * @param int $numBuckets
48
-	 * @return string
49
-	 */
50
-	public function getBucket($numBuckets = 64) {
51
-		$hash = md5($this->user->getUID());
52
-		$num = hexdec(substr($hash, 0, 4));
53
-		return (string)($num % $numBuckets);
54
-	}
46
+    /**
47
+     * @param int $numBuckets
48
+     * @return string
49
+     */
50
+    public function getBucket($numBuckets = 64) {
51
+        $hash = md5($this->user->getUID());
52
+        $num = hexdec(substr($hash, 0, 4));
53
+        return (string)($num % $numBuckets);
54
+    }
55 55
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -50,6 +50,6 @@
 block discarded – undo
50 50
 	public function getBucket($numBuckets = 64) {
51 51
 		$hash = md5($this->user->getUID());
52 52
 		$num = hexdec(substr($hash, 0, 4));
53
-		return (string)($num % $numBuckets);
53
+		return (string) ($num % $numBuckets);
54 54
 	}
55 55
 }
Please login to merge, or discard this patch.
lib/private/Files/SimpleFS/SimpleFile.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@
 block discarded – undo
26 26
 use OCP\Files\NotPermittedException;
27 27
 use OCP\Files\SimpleFS\ISimpleFile;
28 28
 
29
-class SimpleFile implements ISimpleFile  {
29
+class SimpleFile implements ISimpleFile {
30 30
 
31 31
 	/** @var File $file */
32 32
 	private $file;
Please login to merge, or discard this patch.
Indentation   +148 added lines, -148 removed lines patch added patch discarded remove patch
@@ -29,153 +29,153 @@
 block discarded – undo
29 29
 
30 30
 class SimpleFile implements ISimpleFile  {
31 31
 
32
-	/** @var File $file */
33
-	private $file;
34
-
35
-	/**
36
-	 * File constructor.
37
-	 *
38
-	 * @param File $file
39
-	 */
40
-	public function __construct(File $file) {
41
-		$this->file = $file;
42
-	}
43
-
44
-	/**
45
-	 * Get the name
46
-	 *
47
-	 * @return string
48
-	 */
49
-	public function getName() {
50
-		return $this->file->getName();
51
-	}
52
-
53
-	/**
54
-	 * Get the size in bytes
55
-	 *
56
-	 * @return int
57
-	 */
58
-	public function getSize() {
59
-		return $this->file->getSize();
60
-	}
61
-
62
-	/**
63
-	 * Get the ETag
64
-	 *
65
-	 * @return string
66
-	 */
67
-	public function getETag() {
68
-		return $this->file->getEtag();
69
-	}
70
-
71
-	/**
72
-	 * Get the last modification time
73
-	 *
74
-	 * @return int
75
-	 */
76
-	public function getMTime() {
77
-		return $this->file->getMTime();
78
-	}
79
-
80
-	/**
81
-	 * Get the content
82
-	 *
83
-	 * @throws NotPermittedException
84
-	 * @throws NotFoundException
85
-	 * @return string
86
-	 */
87
-	public function getContent() {
88
-		$result = $this->file->getContent();
89
-
90
-		if ($result === false) {
91
-			$this->checkFile();
92
-		}
93
-
94
-		return $result;
95
-	}
96
-
97
-	/**
98
-	 * Overwrite the file
99
-	 *
100
-	 * @param string|resource $data
101
-	 * @throws NotPermittedException
102
-	 * @throws NotFoundException
103
-	 */
104
-	public function putContent($data) {
105
-		try {
106
-			return $this->file->putContent($data);
107
-		} catch (NotFoundException $e) {
108
-			$this->checkFile();
109
-		}
110
-	}
111
-
112
-	/**
113
-	 * Sometimes there are some issues with the AppData. Most of them are from
114
-	 * user error. But we should handle them gracefull anyway.
115
-	 *
116
-	 * If for some reason the current file can't be found. We remove it.
117
-	 * Then traverse up and check all folders if they exists. This so that the
118
-	 * next request will have a valid appdata structure again.
119
-	 *
120
-	 * @throws NotFoundException
121
-	 */
122
-	private function checkFile() {
123
-		$cur = $this->file;
124
-
125
-		while ($cur->stat() === false) {
126
-			$parent = $cur->getParent();
127
-			try {
128
-				$cur->delete();
129
-			} catch (NotFoundException $e) {
130
-				// Just continue then
131
-			}
132
-			$cur = $parent;
133
-		}
134
-
135
-		if ($cur !== $this->file) {
136
-			throw new NotFoundException('File does not exist');
137
-		}
138
-	}
139
-
140
-
141
-	/**
142
-	 * Delete the file
143
-	 *
144
-	 * @throws NotPermittedException
145
-	 */
146
-	public function delete() {
147
-		$this->file->delete();
148
-	}
149
-
150
-	/**
151
-	 * Get the MimeType
152
-	 *
153
-	 * @return string
154
-	 */
155
-	public function getMimeType() {
156
-		return $this->file->getMimeType();
157
-	}
158
-
159
-	/**
160
-	 * Open the file as stream for reading, resulting resource can be operated as stream like the result from php's own fopen
161
-	 *
162
-	 * @return resource
163
-	 * @throws \OCP\Files\NotPermittedException
164
-	 * @since 14.0.0
165
-	 */
166
-	public function read() {
167
-		return $this->file->fopen('r');
168
-	}
169
-
170
-	/**
171
-	 * Open the file as stream for writing, resulting resource can be operated as stream like the result from php's own fopen
172
-	 *
173
-	 * @return resource
174
-	 * @throws \OCP\Files\NotPermittedException
175
-	 * @since 14.0.0
176
-	 */
177
-	public function write() {
178
-		return $this->file->fopen('w');
179
-	}
32
+    /** @var File $file */
33
+    private $file;
34
+
35
+    /**
36
+     * File constructor.
37
+     *
38
+     * @param File $file
39
+     */
40
+    public function __construct(File $file) {
41
+        $this->file = $file;
42
+    }
43
+
44
+    /**
45
+     * Get the name
46
+     *
47
+     * @return string
48
+     */
49
+    public function getName() {
50
+        return $this->file->getName();
51
+    }
52
+
53
+    /**
54
+     * Get the size in bytes
55
+     *
56
+     * @return int
57
+     */
58
+    public function getSize() {
59
+        return $this->file->getSize();
60
+    }
61
+
62
+    /**
63
+     * Get the ETag
64
+     *
65
+     * @return string
66
+     */
67
+    public function getETag() {
68
+        return $this->file->getEtag();
69
+    }
70
+
71
+    /**
72
+     * Get the last modification time
73
+     *
74
+     * @return int
75
+     */
76
+    public function getMTime() {
77
+        return $this->file->getMTime();
78
+    }
79
+
80
+    /**
81
+     * Get the content
82
+     *
83
+     * @throws NotPermittedException
84
+     * @throws NotFoundException
85
+     * @return string
86
+     */
87
+    public function getContent() {
88
+        $result = $this->file->getContent();
89
+
90
+        if ($result === false) {
91
+            $this->checkFile();
92
+        }
93
+
94
+        return $result;
95
+    }
96
+
97
+    /**
98
+     * Overwrite the file
99
+     *
100
+     * @param string|resource $data
101
+     * @throws NotPermittedException
102
+     * @throws NotFoundException
103
+     */
104
+    public function putContent($data) {
105
+        try {
106
+            return $this->file->putContent($data);
107
+        } catch (NotFoundException $e) {
108
+            $this->checkFile();
109
+        }
110
+    }
111
+
112
+    /**
113
+     * Sometimes there are some issues with the AppData. Most of them are from
114
+     * user error. But we should handle them gracefull anyway.
115
+     *
116
+     * If for some reason the current file can't be found. We remove it.
117
+     * Then traverse up and check all folders if they exists. This so that the
118
+     * next request will have a valid appdata structure again.
119
+     *
120
+     * @throws NotFoundException
121
+     */
122
+    private function checkFile() {
123
+        $cur = $this->file;
124
+
125
+        while ($cur->stat() === false) {
126
+            $parent = $cur->getParent();
127
+            try {
128
+                $cur->delete();
129
+            } catch (NotFoundException $e) {
130
+                // Just continue then
131
+            }
132
+            $cur = $parent;
133
+        }
134
+
135
+        if ($cur !== $this->file) {
136
+            throw new NotFoundException('File does not exist');
137
+        }
138
+    }
139
+
140
+
141
+    /**
142
+     * Delete the file
143
+     *
144
+     * @throws NotPermittedException
145
+     */
146
+    public function delete() {
147
+        $this->file->delete();
148
+    }
149
+
150
+    /**
151
+     * Get the MimeType
152
+     *
153
+     * @return string
154
+     */
155
+    public function getMimeType() {
156
+        return $this->file->getMimeType();
157
+    }
158
+
159
+    /**
160
+     * Open the file as stream for reading, resulting resource can be operated as stream like the result from php's own fopen
161
+     *
162
+     * @return resource
163
+     * @throws \OCP\Files\NotPermittedException
164
+     * @since 14.0.0
165
+     */
166
+    public function read() {
167
+        return $this->file->fopen('r');
168
+    }
169
+
170
+    /**
171
+     * Open the file as stream for writing, resulting resource can be operated as stream like the result from php's own fopen
172
+     *
173
+     * @return resource
174
+     * @throws \OCP\Files\NotPermittedException
175
+     * @since 14.0.0
176
+     */
177
+    public function write() {
178
+        return $this->file->fopen('w');
179
+    }
180 180
 
181 181
 }
Please login to merge, or discard this patch.
lib/private/Files/Storage/Wrapper/Encoding.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
 				// no point in continuing if the section was not found, use original path
81 81
 				return $fullPath;
82 82
 			}
83
-			$path = $convertedPath . '/';
83
+			$path = $convertedPath.'/';
84 84
 		}
85 85
 		$path = rtrim($path, '/');
86 86
 		return $path;
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 	 * @return string|null original or converted path, or null if none of the forms was found
97 97
 	 */
98 98
 	private function findPathToUseLastSection($basePath, $lastSection) {
99
-		$fullPath = $basePath . $lastSection;
99
+		$fullPath = $basePath.$lastSection;
100 100
 		if ($lastSection === '' || $this->isAscii($lastSection) || $this->storage->file_exists($fullPath)) {
101 101
 			$this->namesCache[$fullPath] = $fullPath;
102 102
 			return $fullPath;
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
 		} else {
109 109
 			$otherFormPath = \Normalizer::normalize($lastSection, \Normalizer::FORM_C);
110 110
 		}
111
-		$otherFullPath = $basePath . $otherFormPath;
111
+		$otherFullPath = $basePath.$otherFormPath;
112 112
 		if ($this->storage->file_exists($otherFullPath)) {
113 113
 			$this->namesCache[$fullPath] = $otherFullPath;
114 114
 			return $otherFullPath;
Please login to merge, or discard this patch.
Indentation   +498 added lines, -498 removed lines patch added patch discarded remove patch
@@ -34,502 +34,502 @@
 block discarded – undo
34 34
  */
35 35
 class Encoding extends Wrapper {
36 36
 
37
-	/**
38
-	 * @var ICache
39
-	 */
40
-	private $namesCache;
41
-
42
-	/**
43
-	 * @param array $parameters
44
-	 */
45
-	public function __construct($parameters) {
46
-		$this->storage = $parameters['storage'];
47
-		$this->namesCache = new CappedMemoryCache();
48
-	}
49
-
50
-	/**
51
-	 * Returns whether the given string is only made of ASCII characters
52
-	 *
53
-	 * @param string $str string
54
-	 *
55
-	 * @return bool true if the string is all ASCII, false otherwise
56
-	 */
57
-	private function isAscii($str) {
58
-		return (bool) !preg_match('/[\\x80-\\xff]+/', $str);
59
-	}
60
-
61
-	/**
62
-	 * Checks whether the given path exists in NFC or NFD form after checking
63
-	 * each form for each path section and returns the correct form.
64
-	 * If no existing path found, returns the path as it was given.
65
-	 *
66
-	 * @param string $fullPath path to check
67
-	 *
68
-	 * @return string original or converted path
69
-	 */
70
-	private function findPathToUse($fullPath) {
71
-		$cachedPath = $this->namesCache[$fullPath];
72
-		if ($cachedPath !== null) {
73
-			return $cachedPath;
74
-		}
75
-
76
-		$sections = explode('/', $fullPath);
77
-		$path = '';
78
-		foreach ($sections as $section) {
79
-			$convertedPath = $this->findPathToUseLastSection($path, $section);
80
-			if ($convertedPath === null) {
81
-				// no point in continuing if the section was not found, use original path
82
-				return $fullPath;
83
-			}
84
-			$path = $convertedPath . '/';
85
-		}
86
-		$path = rtrim($path, '/');
87
-		return $path;
88
-	}
89
-
90
-	/**
91
-	 * Checks whether the last path section of the given path exists in NFC or NFD form
92
-	 * and returns the correct form. If no existing path found, returns null.
93
-	 *
94
-	 * @param string $basePath base path to check
95
-	 * @param string $lastSection last section of the path to check for NFD/NFC variations
96
-	 *
97
-	 * @return string|null original or converted path, or null if none of the forms was found
98
-	 */
99
-	private function findPathToUseLastSection($basePath, $lastSection) {
100
-		$fullPath = $basePath . $lastSection;
101
-		if ($lastSection === '' || $this->isAscii($lastSection) || $this->storage->file_exists($fullPath)) {
102
-			$this->namesCache[$fullPath] = $fullPath;
103
-			return $fullPath;
104
-		}
105
-
106
-		// swap encoding
107
-		if (\Normalizer::isNormalized($lastSection, \Normalizer::FORM_C)) {
108
-			$otherFormPath = \Normalizer::normalize($lastSection, \Normalizer::FORM_D);
109
-		} else {
110
-			$otherFormPath = \Normalizer::normalize($lastSection, \Normalizer::FORM_C);
111
-		}
112
-		$otherFullPath = $basePath . $otherFormPath;
113
-		if ($this->storage->file_exists($otherFullPath)) {
114
-			$this->namesCache[$fullPath] = $otherFullPath;
115
-			return $otherFullPath;
116
-		}
117
-
118
-		// return original path, file did not exist at all
119
-		$this->namesCache[$fullPath] = $fullPath;
120
-		return null;
121
-	}
122
-
123
-	/**
124
-	 * see http://php.net/manual/en/function.mkdir.php
125
-	 *
126
-	 * @param string $path
127
-	 * @return bool
128
-	 */
129
-	public function mkdir($path) {
130
-		// note: no conversion here, method should not be called with non-NFC names!
131
-		$result = $this->storage->mkdir($path);
132
-		if ($result) {
133
-			$this->namesCache[$path] = $path;
134
-		}
135
-		return $result;
136
-	}
137
-
138
-	/**
139
-	 * see http://php.net/manual/en/function.rmdir.php
140
-	 *
141
-	 * @param string $path
142
-	 * @return bool
143
-	 */
144
-	public function rmdir($path) {
145
-		$result = $this->storage->rmdir($this->findPathToUse($path));
146
-		if ($result) {
147
-			unset($this->namesCache[$path]);
148
-		}
149
-		return $result;
150
-	}
151
-
152
-	/**
153
-	 * see http://php.net/manual/en/function.opendir.php
154
-	 *
155
-	 * @param string $path
156
-	 * @return resource
157
-	 */
158
-	public function opendir($path) {
159
-		return $this->storage->opendir($this->findPathToUse($path));
160
-	}
161
-
162
-	/**
163
-	 * see http://php.net/manual/en/function.is_dir.php
164
-	 *
165
-	 * @param string $path
166
-	 * @return bool
167
-	 */
168
-	public function is_dir($path) {
169
-		return $this->storage->is_dir($this->findPathToUse($path));
170
-	}
171
-
172
-	/**
173
-	 * see http://php.net/manual/en/function.is_file.php
174
-	 *
175
-	 * @param string $path
176
-	 * @return bool
177
-	 */
178
-	public function is_file($path) {
179
-		return $this->storage->is_file($this->findPathToUse($path));
180
-	}
181
-
182
-	/**
183
-	 * see http://php.net/manual/en/function.stat.php
184
-	 * only the following keys are required in the result: size and mtime
185
-	 *
186
-	 * @param string $path
187
-	 * @return array
188
-	 */
189
-	public function stat($path) {
190
-		return $this->storage->stat($this->findPathToUse($path));
191
-	}
192
-
193
-	/**
194
-	 * see http://php.net/manual/en/function.filetype.php
195
-	 *
196
-	 * @param string $path
197
-	 * @return bool
198
-	 */
199
-	public function filetype($path) {
200
-		return $this->storage->filetype($this->findPathToUse($path));
201
-	}
202
-
203
-	/**
204
-	 * see http://php.net/manual/en/function.filesize.php
205
-	 * The result for filesize when called on a folder is required to be 0
206
-	 *
207
-	 * @param string $path
208
-	 * @return int
209
-	 */
210
-	public function filesize($path) {
211
-		return $this->storage->filesize($this->findPathToUse($path));
212
-	}
213
-
214
-	/**
215
-	 * check if a file can be created in $path
216
-	 *
217
-	 * @param string $path
218
-	 * @return bool
219
-	 */
220
-	public function isCreatable($path) {
221
-		return $this->storage->isCreatable($this->findPathToUse($path));
222
-	}
223
-
224
-	/**
225
-	 * check if a file can be read
226
-	 *
227
-	 * @param string $path
228
-	 * @return bool
229
-	 */
230
-	public function isReadable($path) {
231
-		return $this->storage->isReadable($this->findPathToUse($path));
232
-	}
233
-
234
-	/**
235
-	 * check if a file can be written to
236
-	 *
237
-	 * @param string $path
238
-	 * @return bool
239
-	 */
240
-	public function isUpdatable($path) {
241
-		return $this->storage->isUpdatable($this->findPathToUse($path));
242
-	}
243
-
244
-	/**
245
-	 * check if a file can be deleted
246
-	 *
247
-	 * @param string $path
248
-	 * @return bool
249
-	 */
250
-	public function isDeletable($path) {
251
-		return $this->storage->isDeletable($this->findPathToUse($path));
252
-	}
253
-
254
-	/**
255
-	 * check if a file can be shared
256
-	 *
257
-	 * @param string $path
258
-	 * @return bool
259
-	 */
260
-	public function isSharable($path) {
261
-		return $this->storage->isSharable($this->findPathToUse($path));
262
-	}
263
-
264
-	/**
265
-	 * get the full permissions of a path.
266
-	 * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
267
-	 *
268
-	 * @param string $path
269
-	 * @return int
270
-	 */
271
-	public function getPermissions($path) {
272
-		return $this->storage->getPermissions($this->findPathToUse($path));
273
-	}
274
-
275
-	/**
276
-	 * see http://php.net/manual/en/function.file_exists.php
277
-	 *
278
-	 * @param string $path
279
-	 * @return bool
280
-	 */
281
-	public function file_exists($path) {
282
-		return $this->storage->file_exists($this->findPathToUse($path));
283
-	}
284
-
285
-	/**
286
-	 * see http://php.net/manual/en/function.filemtime.php
287
-	 *
288
-	 * @param string $path
289
-	 * @return int
290
-	 */
291
-	public function filemtime($path) {
292
-		return $this->storage->filemtime($this->findPathToUse($path));
293
-	}
294
-
295
-	/**
296
-	 * see http://php.net/manual/en/function.file_get_contents.php
297
-	 *
298
-	 * @param string $path
299
-	 * @return string
300
-	 */
301
-	public function file_get_contents($path) {
302
-		return $this->storage->file_get_contents($this->findPathToUse($path));
303
-	}
304
-
305
-	/**
306
-	 * see http://php.net/manual/en/function.file_put_contents.php
307
-	 *
308
-	 * @param string $path
309
-	 * @param string $data
310
-	 * @return bool
311
-	 */
312
-	public function file_put_contents($path, $data) {
313
-		return $this->storage->file_put_contents($this->findPathToUse($path), $data);
314
-	}
315
-
316
-	/**
317
-	 * see http://php.net/manual/en/function.unlink.php
318
-	 *
319
-	 * @param string $path
320
-	 * @return bool
321
-	 */
322
-	public function unlink($path) {
323
-		$result = $this->storage->unlink($this->findPathToUse($path));
324
-		if ($result) {
325
-			unset($this->namesCache[$path]);
326
-		}
327
-		return $result;
328
-	}
329
-
330
-	/**
331
-	 * see http://php.net/manual/en/function.rename.php
332
-	 *
333
-	 * @param string $path1
334
-	 * @param string $path2
335
-	 * @return bool
336
-	 */
337
-	public function rename($path1, $path2) {
338
-		// second name always NFC
339
-		return $this->storage->rename($this->findPathToUse($path1), $this->findPathToUse($path2));
340
-	}
341
-
342
-	/**
343
-	 * see http://php.net/manual/en/function.copy.php
344
-	 *
345
-	 * @param string $path1
346
-	 * @param string $path2
347
-	 * @return bool
348
-	 */
349
-	public function copy($path1, $path2) {
350
-		return $this->storage->copy($this->findPathToUse($path1), $this->findPathToUse($path2));
351
-	}
352
-
353
-	/**
354
-	 * see http://php.net/manual/en/function.fopen.php
355
-	 *
356
-	 * @param string $path
357
-	 * @param string $mode
358
-	 * @return resource
359
-	 */
360
-	public function fopen($path, $mode) {
361
-		$result = $this->storage->fopen($this->findPathToUse($path), $mode);
362
-		if ($result && $mode !== 'r' && $mode !== 'rb') {
363
-			unset($this->namesCache[$path]);
364
-		}
365
-		return $result;
366
-	}
367
-
368
-	/**
369
-	 * get the mimetype for a file or folder
370
-	 * The mimetype for a folder is required to be "httpd/unix-directory"
371
-	 *
372
-	 * @param string $path
373
-	 * @return string
374
-	 */
375
-	public function getMimeType($path) {
376
-		return $this->storage->getMimeType($this->findPathToUse($path));
377
-	}
378
-
379
-	/**
380
-	 * see http://php.net/manual/en/function.hash.php
381
-	 *
382
-	 * @param string $type
383
-	 * @param string $path
384
-	 * @param bool $raw
385
-	 * @return string
386
-	 */
387
-	public function hash($type, $path, $raw = false) {
388
-		return $this->storage->hash($type, $this->findPathToUse($path), $raw);
389
-	}
390
-
391
-	/**
392
-	 * see http://php.net/manual/en/function.free_space.php
393
-	 *
394
-	 * @param string $path
395
-	 * @return int
396
-	 */
397
-	public function free_space($path) {
398
-		return $this->storage->free_space($this->findPathToUse($path));
399
-	}
400
-
401
-	/**
402
-	 * search for occurrences of $query in file names
403
-	 *
404
-	 * @param string $query
405
-	 * @return array
406
-	 */
407
-	public function search($query) {
408
-		return $this->storage->search($query);
409
-	}
410
-
411
-	/**
412
-	 * see http://php.net/manual/en/function.touch.php
413
-	 * If the backend does not support the operation, false should be returned
414
-	 *
415
-	 * @param string $path
416
-	 * @param int $mtime
417
-	 * @return bool
418
-	 */
419
-	public function touch($path, $mtime = null) {
420
-		return $this->storage->touch($this->findPathToUse($path), $mtime);
421
-	}
422
-
423
-	/**
424
-	 * get the path to a local version of the file.
425
-	 * The local version of the file can be temporary and doesn't have to be persistent across requests
426
-	 *
427
-	 * @param string $path
428
-	 * @return string
429
-	 */
430
-	public function getLocalFile($path) {
431
-		return $this->storage->getLocalFile($this->findPathToUse($path));
432
-	}
433
-
434
-	/**
435
-	 * check if a file or folder has been updated since $time
436
-	 *
437
-	 * @param string $path
438
-	 * @param int $time
439
-	 * @return bool
440
-	 *
441
-	 * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
442
-	 * returning true for other changes in the folder is optional
443
-	 */
444
-	public function hasUpdated($path, $time) {
445
-		return $this->storage->hasUpdated($this->findPathToUse($path), $time);
446
-	}
447
-
448
-	/**
449
-	 * get a cache instance for the storage
450
-	 *
451
-	 * @param string $path
452
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
453
-	 * @return \OC\Files\Cache\Cache
454
-	 */
455
-	public function getCache($path = '', $storage = null) {
456
-		if (!$storage) {
457
-			$storage = $this;
458
-		}
459
-		return $this->storage->getCache($this->findPathToUse($path), $storage);
460
-	}
461
-
462
-	/**
463
-	 * get a scanner instance for the storage
464
-	 *
465
-	 * @param string $path
466
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
467
-	 * @return \OC\Files\Cache\Scanner
468
-	 */
469
-	public function getScanner($path = '', $storage = null) {
470
-		if (!$storage) {
471
-			$storage = $this;
472
-		}
473
-		return $this->storage->getScanner($this->findPathToUse($path), $storage);
474
-	}
475
-
476
-	/**
477
-	 * get the ETag for a file or folder
478
-	 *
479
-	 * @param string $path
480
-	 * @return string
481
-	 */
482
-	public function getETag($path) {
483
-		return $this->storage->getETag($this->findPathToUse($path));
484
-	}
485
-
486
-	/**
487
-	 * @param IStorage $sourceStorage
488
-	 * @param string $sourceInternalPath
489
-	 * @param string $targetInternalPath
490
-	 * @return bool
491
-	 */
492
-	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
493
-		if ($sourceStorage === $this) {
494
-			return $this->copy($sourceInternalPath, $this->findPathToUse($targetInternalPath));
495
-		}
496
-
497
-		$result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $this->findPathToUse($targetInternalPath));
498
-		if ($result) {
499
-			unset($this->namesCache[$targetInternalPath]);
500
-		}
501
-		return $result;
502
-	}
503
-
504
-	/**
505
-	 * @param IStorage $sourceStorage
506
-	 * @param string $sourceInternalPath
507
-	 * @param string $targetInternalPath
508
-	 * @return bool
509
-	 */
510
-	public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
511
-		if ($sourceStorage === $this) {
512
-			$result = $this->rename($sourceInternalPath, $this->findPathToUse($targetInternalPath));
513
-			if ($result) {
514
-				unset($this->namesCache[$sourceInternalPath]);
515
-				unset($this->namesCache[$targetInternalPath]);
516
-			}
517
-			return $result;
518
-		}
519
-
520
-		$result = $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $this->findPathToUse($targetInternalPath));
521
-		if ($result) {
522
-			unset($this->namesCache[$sourceInternalPath]);
523
-			unset($this->namesCache[$targetInternalPath]);
524
-		}
525
-		return $result;
526
-	}
527
-
528
-	/**
529
-	 * @param string $path
530
-	 * @return array
531
-	 */
532
-	public function getMetaData($path) {
533
-		return $this->storage->getMetaData($this->findPathToUse($path));
534
-	}
37
+    /**
38
+     * @var ICache
39
+     */
40
+    private $namesCache;
41
+
42
+    /**
43
+     * @param array $parameters
44
+     */
45
+    public function __construct($parameters) {
46
+        $this->storage = $parameters['storage'];
47
+        $this->namesCache = new CappedMemoryCache();
48
+    }
49
+
50
+    /**
51
+     * Returns whether the given string is only made of ASCII characters
52
+     *
53
+     * @param string $str string
54
+     *
55
+     * @return bool true if the string is all ASCII, false otherwise
56
+     */
57
+    private function isAscii($str) {
58
+        return (bool) !preg_match('/[\\x80-\\xff]+/', $str);
59
+    }
60
+
61
+    /**
62
+     * Checks whether the given path exists in NFC or NFD form after checking
63
+     * each form for each path section and returns the correct form.
64
+     * If no existing path found, returns the path as it was given.
65
+     *
66
+     * @param string $fullPath path to check
67
+     *
68
+     * @return string original or converted path
69
+     */
70
+    private function findPathToUse($fullPath) {
71
+        $cachedPath = $this->namesCache[$fullPath];
72
+        if ($cachedPath !== null) {
73
+            return $cachedPath;
74
+        }
75
+
76
+        $sections = explode('/', $fullPath);
77
+        $path = '';
78
+        foreach ($sections as $section) {
79
+            $convertedPath = $this->findPathToUseLastSection($path, $section);
80
+            if ($convertedPath === null) {
81
+                // no point in continuing if the section was not found, use original path
82
+                return $fullPath;
83
+            }
84
+            $path = $convertedPath . '/';
85
+        }
86
+        $path = rtrim($path, '/');
87
+        return $path;
88
+    }
89
+
90
+    /**
91
+     * Checks whether the last path section of the given path exists in NFC or NFD form
92
+     * and returns the correct form. If no existing path found, returns null.
93
+     *
94
+     * @param string $basePath base path to check
95
+     * @param string $lastSection last section of the path to check for NFD/NFC variations
96
+     *
97
+     * @return string|null original or converted path, or null if none of the forms was found
98
+     */
99
+    private function findPathToUseLastSection($basePath, $lastSection) {
100
+        $fullPath = $basePath . $lastSection;
101
+        if ($lastSection === '' || $this->isAscii($lastSection) || $this->storage->file_exists($fullPath)) {
102
+            $this->namesCache[$fullPath] = $fullPath;
103
+            return $fullPath;
104
+        }
105
+
106
+        // swap encoding
107
+        if (\Normalizer::isNormalized($lastSection, \Normalizer::FORM_C)) {
108
+            $otherFormPath = \Normalizer::normalize($lastSection, \Normalizer::FORM_D);
109
+        } else {
110
+            $otherFormPath = \Normalizer::normalize($lastSection, \Normalizer::FORM_C);
111
+        }
112
+        $otherFullPath = $basePath . $otherFormPath;
113
+        if ($this->storage->file_exists($otherFullPath)) {
114
+            $this->namesCache[$fullPath] = $otherFullPath;
115
+            return $otherFullPath;
116
+        }
117
+
118
+        // return original path, file did not exist at all
119
+        $this->namesCache[$fullPath] = $fullPath;
120
+        return null;
121
+    }
122
+
123
+    /**
124
+     * see http://php.net/manual/en/function.mkdir.php
125
+     *
126
+     * @param string $path
127
+     * @return bool
128
+     */
129
+    public function mkdir($path) {
130
+        // note: no conversion here, method should not be called with non-NFC names!
131
+        $result = $this->storage->mkdir($path);
132
+        if ($result) {
133
+            $this->namesCache[$path] = $path;
134
+        }
135
+        return $result;
136
+    }
137
+
138
+    /**
139
+     * see http://php.net/manual/en/function.rmdir.php
140
+     *
141
+     * @param string $path
142
+     * @return bool
143
+     */
144
+    public function rmdir($path) {
145
+        $result = $this->storage->rmdir($this->findPathToUse($path));
146
+        if ($result) {
147
+            unset($this->namesCache[$path]);
148
+        }
149
+        return $result;
150
+    }
151
+
152
+    /**
153
+     * see http://php.net/manual/en/function.opendir.php
154
+     *
155
+     * @param string $path
156
+     * @return resource
157
+     */
158
+    public function opendir($path) {
159
+        return $this->storage->opendir($this->findPathToUse($path));
160
+    }
161
+
162
+    /**
163
+     * see http://php.net/manual/en/function.is_dir.php
164
+     *
165
+     * @param string $path
166
+     * @return bool
167
+     */
168
+    public function is_dir($path) {
169
+        return $this->storage->is_dir($this->findPathToUse($path));
170
+    }
171
+
172
+    /**
173
+     * see http://php.net/manual/en/function.is_file.php
174
+     *
175
+     * @param string $path
176
+     * @return bool
177
+     */
178
+    public function is_file($path) {
179
+        return $this->storage->is_file($this->findPathToUse($path));
180
+    }
181
+
182
+    /**
183
+     * see http://php.net/manual/en/function.stat.php
184
+     * only the following keys are required in the result: size and mtime
185
+     *
186
+     * @param string $path
187
+     * @return array
188
+     */
189
+    public function stat($path) {
190
+        return $this->storage->stat($this->findPathToUse($path));
191
+    }
192
+
193
+    /**
194
+     * see http://php.net/manual/en/function.filetype.php
195
+     *
196
+     * @param string $path
197
+     * @return bool
198
+     */
199
+    public function filetype($path) {
200
+        return $this->storage->filetype($this->findPathToUse($path));
201
+    }
202
+
203
+    /**
204
+     * see http://php.net/manual/en/function.filesize.php
205
+     * The result for filesize when called on a folder is required to be 0
206
+     *
207
+     * @param string $path
208
+     * @return int
209
+     */
210
+    public function filesize($path) {
211
+        return $this->storage->filesize($this->findPathToUse($path));
212
+    }
213
+
214
+    /**
215
+     * check if a file can be created in $path
216
+     *
217
+     * @param string $path
218
+     * @return bool
219
+     */
220
+    public function isCreatable($path) {
221
+        return $this->storage->isCreatable($this->findPathToUse($path));
222
+    }
223
+
224
+    /**
225
+     * check if a file can be read
226
+     *
227
+     * @param string $path
228
+     * @return bool
229
+     */
230
+    public function isReadable($path) {
231
+        return $this->storage->isReadable($this->findPathToUse($path));
232
+    }
233
+
234
+    /**
235
+     * check if a file can be written to
236
+     *
237
+     * @param string $path
238
+     * @return bool
239
+     */
240
+    public function isUpdatable($path) {
241
+        return $this->storage->isUpdatable($this->findPathToUse($path));
242
+    }
243
+
244
+    /**
245
+     * check if a file can be deleted
246
+     *
247
+     * @param string $path
248
+     * @return bool
249
+     */
250
+    public function isDeletable($path) {
251
+        return $this->storage->isDeletable($this->findPathToUse($path));
252
+    }
253
+
254
+    /**
255
+     * check if a file can be shared
256
+     *
257
+     * @param string $path
258
+     * @return bool
259
+     */
260
+    public function isSharable($path) {
261
+        return $this->storage->isSharable($this->findPathToUse($path));
262
+    }
263
+
264
+    /**
265
+     * get the full permissions of a path.
266
+     * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
267
+     *
268
+     * @param string $path
269
+     * @return int
270
+     */
271
+    public function getPermissions($path) {
272
+        return $this->storage->getPermissions($this->findPathToUse($path));
273
+    }
274
+
275
+    /**
276
+     * see http://php.net/manual/en/function.file_exists.php
277
+     *
278
+     * @param string $path
279
+     * @return bool
280
+     */
281
+    public function file_exists($path) {
282
+        return $this->storage->file_exists($this->findPathToUse($path));
283
+    }
284
+
285
+    /**
286
+     * see http://php.net/manual/en/function.filemtime.php
287
+     *
288
+     * @param string $path
289
+     * @return int
290
+     */
291
+    public function filemtime($path) {
292
+        return $this->storage->filemtime($this->findPathToUse($path));
293
+    }
294
+
295
+    /**
296
+     * see http://php.net/manual/en/function.file_get_contents.php
297
+     *
298
+     * @param string $path
299
+     * @return string
300
+     */
301
+    public function file_get_contents($path) {
302
+        return $this->storage->file_get_contents($this->findPathToUse($path));
303
+    }
304
+
305
+    /**
306
+     * see http://php.net/manual/en/function.file_put_contents.php
307
+     *
308
+     * @param string $path
309
+     * @param string $data
310
+     * @return bool
311
+     */
312
+    public function file_put_contents($path, $data) {
313
+        return $this->storage->file_put_contents($this->findPathToUse($path), $data);
314
+    }
315
+
316
+    /**
317
+     * see http://php.net/manual/en/function.unlink.php
318
+     *
319
+     * @param string $path
320
+     * @return bool
321
+     */
322
+    public function unlink($path) {
323
+        $result = $this->storage->unlink($this->findPathToUse($path));
324
+        if ($result) {
325
+            unset($this->namesCache[$path]);
326
+        }
327
+        return $result;
328
+    }
329
+
330
+    /**
331
+     * see http://php.net/manual/en/function.rename.php
332
+     *
333
+     * @param string $path1
334
+     * @param string $path2
335
+     * @return bool
336
+     */
337
+    public function rename($path1, $path2) {
338
+        // second name always NFC
339
+        return $this->storage->rename($this->findPathToUse($path1), $this->findPathToUse($path2));
340
+    }
341
+
342
+    /**
343
+     * see http://php.net/manual/en/function.copy.php
344
+     *
345
+     * @param string $path1
346
+     * @param string $path2
347
+     * @return bool
348
+     */
349
+    public function copy($path1, $path2) {
350
+        return $this->storage->copy($this->findPathToUse($path1), $this->findPathToUse($path2));
351
+    }
352
+
353
+    /**
354
+     * see http://php.net/manual/en/function.fopen.php
355
+     *
356
+     * @param string $path
357
+     * @param string $mode
358
+     * @return resource
359
+     */
360
+    public function fopen($path, $mode) {
361
+        $result = $this->storage->fopen($this->findPathToUse($path), $mode);
362
+        if ($result && $mode !== 'r' && $mode !== 'rb') {
363
+            unset($this->namesCache[$path]);
364
+        }
365
+        return $result;
366
+    }
367
+
368
+    /**
369
+     * get the mimetype for a file or folder
370
+     * The mimetype for a folder is required to be "httpd/unix-directory"
371
+     *
372
+     * @param string $path
373
+     * @return string
374
+     */
375
+    public function getMimeType($path) {
376
+        return $this->storage->getMimeType($this->findPathToUse($path));
377
+    }
378
+
379
+    /**
380
+     * see http://php.net/manual/en/function.hash.php
381
+     *
382
+     * @param string $type
383
+     * @param string $path
384
+     * @param bool $raw
385
+     * @return string
386
+     */
387
+    public function hash($type, $path, $raw = false) {
388
+        return $this->storage->hash($type, $this->findPathToUse($path), $raw);
389
+    }
390
+
391
+    /**
392
+     * see http://php.net/manual/en/function.free_space.php
393
+     *
394
+     * @param string $path
395
+     * @return int
396
+     */
397
+    public function free_space($path) {
398
+        return $this->storage->free_space($this->findPathToUse($path));
399
+    }
400
+
401
+    /**
402
+     * search for occurrences of $query in file names
403
+     *
404
+     * @param string $query
405
+     * @return array
406
+     */
407
+    public function search($query) {
408
+        return $this->storage->search($query);
409
+    }
410
+
411
+    /**
412
+     * see http://php.net/manual/en/function.touch.php
413
+     * If the backend does not support the operation, false should be returned
414
+     *
415
+     * @param string $path
416
+     * @param int $mtime
417
+     * @return bool
418
+     */
419
+    public function touch($path, $mtime = null) {
420
+        return $this->storage->touch($this->findPathToUse($path), $mtime);
421
+    }
422
+
423
+    /**
424
+     * get the path to a local version of the file.
425
+     * The local version of the file can be temporary and doesn't have to be persistent across requests
426
+     *
427
+     * @param string $path
428
+     * @return string
429
+     */
430
+    public function getLocalFile($path) {
431
+        return $this->storage->getLocalFile($this->findPathToUse($path));
432
+    }
433
+
434
+    /**
435
+     * check if a file or folder has been updated since $time
436
+     *
437
+     * @param string $path
438
+     * @param int $time
439
+     * @return bool
440
+     *
441
+     * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
442
+     * returning true for other changes in the folder is optional
443
+     */
444
+    public function hasUpdated($path, $time) {
445
+        return $this->storage->hasUpdated($this->findPathToUse($path), $time);
446
+    }
447
+
448
+    /**
449
+     * get a cache instance for the storage
450
+     *
451
+     * @param string $path
452
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
453
+     * @return \OC\Files\Cache\Cache
454
+     */
455
+    public function getCache($path = '', $storage = null) {
456
+        if (!$storage) {
457
+            $storage = $this;
458
+        }
459
+        return $this->storage->getCache($this->findPathToUse($path), $storage);
460
+    }
461
+
462
+    /**
463
+     * get a scanner instance for the storage
464
+     *
465
+     * @param string $path
466
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
467
+     * @return \OC\Files\Cache\Scanner
468
+     */
469
+    public function getScanner($path = '', $storage = null) {
470
+        if (!$storage) {
471
+            $storage = $this;
472
+        }
473
+        return $this->storage->getScanner($this->findPathToUse($path), $storage);
474
+    }
475
+
476
+    /**
477
+     * get the ETag for a file or folder
478
+     *
479
+     * @param string $path
480
+     * @return string
481
+     */
482
+    public function getETag($path) {
483
+        return $this->storage->getETag($this->findPathToUse($path));
484
+    }
485
+
486
+    /**
487
+     * @param IStorage $sourceStorage
488
+     * @param string $sourceInternalPath
489
+     * @param string $targetInternalPath
490
+     * @return bool
491
+     */
492
+    public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
493
+        if ($sourceStorage === $this) {
494
+            return $this->copy($sourceInternalPath, $this->findPathToUse($targetInternalPath));
495
+        }
496
+
497
+        $result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $this->findPathToUse($targetInternalPath));
498
+        if ($result) {
499
+            unset($this->namesCache[$targetInternalPath]);
500
+        }
501
+        return $result;
502
+    }
503
+
504
+    /**
505
+     * @param IStorage $sourceStorage
506
+     * @param string $sourceInternalPath
507
+     * @param string $targetInternalPath
508
+     * @return bool
509
+     */
510
+    public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
511
+        if ($sourceStorage === $this) {
512
+            $result = $this->rename($sourceInternalPath, $this->findPathToUse($targetInternalPath));
513
+            if ($result) {
514
+                unset($this->namesCache[$sourceInternalPath]);
515
+                unset($this->namesCache[$targetInternalPath]);
516
+            }
517
+            return $result;
518
+        }
519
+
520
+        $result = $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $this->findPathToUse($targetInternalPath));
521
+        if ($result) {
522
+            unset($this->namesCache[$sourceInternalPath]);
523
+            unset($this->namesCache[$targetInternalPath]);
524
+        }
525
+        return $result;
526
+    }
527
+
528
+    /**
529
+     * @param string $path
530
+     * @return array
531
+     */
532
+    public function getMetaData($path) {
533
+        return $this->storage->getMetaData($this->findPathToUse($path));
534
+    }
535 535
 }
Please login to merge, or discard this patch.
lib/private/Files/Storage/Storage.php 1 patch
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -32,90 +32,90 @@
 block discarded – undo
32 32
  */
33 33
 interface Storage extends \OCP\Files\Storage {
34 34
 
35
-	/**
36
-	 * get a cache instance for the storage
37
-	 *
38
-	 * @param string $path
39
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
40
-	 * @return \OC\Files\Cache\Cache
41
-	 */
42
-	public function getCache($path = '', $storage = null);
35
+    /**
36
+     * get a cache instance for the storage
37
+     *
38
+     * @param string $path
39
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
40
+     * @return \OC\Files\Cache\Cache
41
+     */
42
+    public function getCache($path = '', $storage = null);
43 43
 
44
-	/**
45
-	 * get a scanner instance for the storage
46
-	 *
47
-	 * @param string $path
48
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
49
-	 * @return \OC\Files\Cache\Scanner
50
-	 */
51
-	public function getScanner($path = '', $storage = null);
44
+    /**
45
+     * get a scanner instance for the storage
46
+     *
47
+     * @param string $path
48
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
49
+     * @return \OC\Files\Cache\Scanner
50
+     */
51
+    public function getScanner($path = '', $storage = null);
52 52
 
53 53
 
54
-	/**
55
-	 * get the user id of the owner of a file or folder
56
-	 *
57
-	 * @param string $path
58
-	 * @return string
59
-	 */
60
-	public function getOwner($path);
54
+    /**
55
+     * get the user id of the owner of a file or folder
56
+     *
57
+     * @param string $path
58
+     * @return string
59
+     */
60
+    public function getOwner($path);
61 61
 
62
-	/**
63
-	 * get a watcher instance for the cache
64
-	 *
65
-	 * @param string $path
66
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
67
-	 * @return \OC\Files\Cache\Watcher
68
-	 */
69
-	public function getWatcher($path = '', $storage = null);
62
+    /**
63
+     * get a watcher instance for the cache
64
+     *
65
+     * @param string $path
66
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
67
+     * @return \OC\Files\Cache\Watcher
68
+     */
69
+    public function getWatcher($path = '', $storage = null);
70 70
 
71
-	/**
72
-	 * get a propagator instance for the cache
73
-	 *
74
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
75
-	 * @return \OC\Files\Cache\Propagator
76
-	 */
77
-	public function getPropagator($storage = null);
71
+    /**
72
+     * get a propagator instance for the cache
73
+     *
74
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
75
+     * @return \OC\Files\Cache\Propagator
76
+     */
77
+    public function getPropagator($storage = null);
78 78
 
79
-	/**
80
-	 * get a updater instance for the cache
81
-	 *
82
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
83
-	 * @return \OC\Files\Cache\Updater
84
-	 */
85
-	public function getUpdater($storage = null);
79
+    /**
80
+     * get a updater instance for the cache
81
+     *
82
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
83
+     * @return \OC\Files\Cache\Updater
84
+     */
85
+    public function getUpdater($storage = null);
86 86
 
87
-	/**
88
-	 * @return \OC\Files\Cache\Storage
89
-	 */
90
-	public function getStorageCache();
87
+    /**
88
+     * @return \OC\Files\Cache\Storage
89
+     */
90
+    public function getStorageCache();
91 91
 
92
-	/**
93
-	 * @param string $path
94
-	 * @return array
95
-	 */
96
-	public function getMetaData($path);
92
+    /**
93
+     * @param string $path
94
+     * @return array
95
+     */
96
+    public function getMetaData($path);
97 97
 
98
-	/**
99
-	 * @param string $path The path of the file to acquire the lock for
100
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
101
-	 * @param \OCP\Lock\ILockingProvider $provider
102
-	 * @throws \OCP\Lock\LockedException
103
-	 */
104
-	public function acquireLock($path, $type, ILockingProvider $provider);
98
+    /**
99
+     * @param string $path The path of the file to acquire the lock for
100
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
101
+     * @param \OCP\Lock\ILockingProvider $provider
102
+     * @throws \OCP\Lock\LockedException
103
+     */
104
+    public function acquireLock($path, $type, ILockingProvider $provider);
105 105
 
106
-	/**
107
-	 * @param string $path The path of the file to release the lock for
108
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
109
-	 * @param \OCP\Lock\ILockingProvider $provider
110
-	 * @throws \OCP\Lock\LockedException
111
-	 */
112
-	public function releaseLock($path, $type, ILockingProvider $provider);
106
+    /**
107
+     * @param string $path The path of the file to release the lock for
108
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
109
+     * @param \OCP\Lock\ILockingProvider $provider
110
+     * @throws \OCP\Lock\LockedException
111
+     */
112
+    public function releaseLock($path, $type, ILockingProvider $provider);
113 113
 
114
-	/**
115
-	 * @param string $path The path of the file to change the lock for
116
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
117
-	 * @param \OCP\Lock\ILockingProvider $provider
118
-	 * @throws \OCP\Lock\LockedException
119
-	 */
120
-	public function changeLock($path, $type, ILockingProvider $provider);
114
+    /**
115
+     * @param string $path The path of the file to change the lock for
116
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
117
+     * @param \OCP\Lock\ILockingProvider $provider
118
+     * @throws \OCP\Lock\LockedException
119
+     */
120
+    public function changeLock($path, $type, ILockingProvider $provider);
121 121
 }
Please login to merge, or discard this patch.
lib/private/Files/Storage/LocalTempFileTrait.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -37,45 +37,45 @@
 block discarded – undo
37 37
  */
38 38
 trait LocalTempFileTrait {
39 39
 
40
-	/** @var string[] */
41
-	protected $cachedFiles = [];
40
+    /** @var string[] */
41
+    protected $cachedFiles = [];
42 42
 
43
-	/**
44
-	 * @param string $path
45
-	 * @return string
46
-	 */
47
-	protected function getCachedFile($path) {
48
-		if (!isset($this->cachedFiles[$path])) {
49
-			$this->cachedFiles[$path] = $this->toTmpFile($path);
50
-		}
51
-		return $this->cachedFiles[$path];
52
-	}
43
+    /**
44
+     * @param string $path
45
+     * @return string
46
+     */
47
+    protected function getCachedFile($path) {
48
+        if (!isset($this->cachedFiles[$path])) {
49
+            $this->cachedFiles[$path] = $this->toTmpFile($path);
50
+        }
51
+        return $this->cachedFiles[$path];
52
+    }
53 53
 
54
-	/**
55
-	 * @param string $path
56
-	 */
57
-	protected function removeCachedFile($path) {
58
-		unset($this->cachedFiles[$path]);
59
-	}
54
+    /**
55
+     * @param string $path
56
+     */
57
+    protected function removeCachedFile($path) {
58
+        unset($this->cachedFiles[$path]);
59
+    }
60 60
 
61
-	/**
62
-	 * @param string $path
63
-	 * @return string
64
-	 */
65
-	protected function toTmpFile($path) { //no longer in the storage api, still useful here
66
-		$source = $this->fopen($path, 'r');
67
-		if (!$source) {
68
-			return false;
69
-		}
70
-		if ($pos = strrpos($path, '.')) {
71
-			$extension = substr($path, $pos);
72
-		} else {
73
-			$extension = '';
74
-		}
75
-		$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
76
-		$target = fopen($tmpFile, 'w');
77
-		\OC_Helper::streamCopy($source, $target);
78
-		fclose($target);
79
-		return $tmpFile;
80
-	}
61
+    /**
62
+     * @param string $path
63
+     * @return string
64
+     */
65
+    protected function toTmpFile($path) { //no longer in the storage api, still useful here
66
+        $source = $this->fopen($path, 'r');
67
+        if (!$source) {
68
+            return false;
69
+        }
70
+        if ($pos = strrpos($path, '.')) {
71
+            $extension = substr($path, $pos);
72
+        } else {
73
+            $extension = '';
74
+        }
75
+        $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
76
+        $target = fopen($tmpFile, 'w');
77
+        \OC_Helper::streamCopy($source, $target);
78
+        fclose($target);
79
+        return $tmpFile;
80
+    }
81 81
 }
Please login to merge, or discard this patch.
lib/private/Files/Storage/Common.php 3 patches
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -289,7 +289,9 @@
 block discarded – undo
289 289
 		$dh = $this->opendir($dir);
290 290
 		if (is_resource($dh)) {
291 291
 			while (($item = readdir($dh)) !== false) {
292
-				if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
292
+				if (\OC\Files\Filesystem::isIgnoredDir($item)) {
293
+				    continue;
294
+				}
293 295
 				if (strstr(strtolower($item), strtolower($query)) !== false) {
294 296
 					$files[] = $dir . '/' . $item;
295 297
 				}
Please login to merge, or discard this patch.
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
 			$this->mkdir($path2);
225 225
 			while ($file = readdir($dir)) {
226 226
 				if (!Filesystem::isIgnoredDir($file)) {
227
-					if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
227
+					if (!$this->copy($path1.'/'.$file, $path2.'/'.$file)) {
228 228
 						return false;
229 229
 					}
230 230
 				}
@@ -278,12 +278,12 @@  discard block
 block discarded – undo
278 278
 		if (is_resource($dh)) {
279 279
 			while (($file = readdir($dh)) !== false) {
280 280
 				if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
281
-					if ($this->is_dir($path . '/' . $file)) {
282
-						mkdir($target . '/' . $file);
283
-						$this->addLocalFolder($path . '/' . $file, $target . '/' . $file);
281
+					if ($this->is_dir($path.'/'.$file)) {
282
+						mkdir($target.'/'.$file);
283
+						$this->addLocalFolder($path.'/'.$file, $target.'/'.$file);
284 284
 					} else {
285
-						$tmp = $this->toTmpFile($path . '/' . $file);
286
-						rename($tmp, $target . '/' . $file);
285
+						$tmp = $this->toTmpFile($path.'/'.$file);
286
+						rename($tmp, $target.'/'.$file);
287 287
 					}
288 288
 				}
289 289
 			}
@@ -302,10 +302,10 @@  discard block
 block discarded – undo
302 302
 			while (($item = readdir($dh)) !== false) {
303 303
 				if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
304 304
 				if (strstr(strtolower($item), strtolower($query)) !== false) {
305
-					$files[] = $dir . '/' . $item;
305
+					$files[] = $dir.'/'.$item;
306 306
 				}
307
-				if ($this->is_dir($dir . '/' . $item)) {
308
-					$files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
307
+				if ($this->is_dir($dir.'/'.$item)) {
308
+					$files = array_merge($files, $this->searchInDir($query, $dir.'/'.$item));
309 309
 				}
310 310
 			}
311 311
 		}
@@ -356,7 +356,7 @@  discard block
 block discarded – undo
356 356
 		if (!isset($this->watcher)) {
357 357
 			$this->watcher = new Watcher($storage);
358 358
 			$globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
359
-			$this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
359
+			$this->watcher->setPolicy((int) $this->getMountOption('filesystem_check_changes', $globalPolicy));
360 360
 		}
361 361
 		return $this->watcher;
362 362
 	}
@@ -373,7 +373,7 @@  discard block
 block discarded – undo
373 373
 		}
374 374
 		if (!isset($storage->propagator)) {
375 375
 			$config = \OC::$server->getSystemConfig();
376
-			$storage->propagator = new Propagator($storage, \OC::$server->getDatabaseConnection(), ['appdata_' . $config->getValue('instanceid')]);
376
+			$storage->propagator = new Propagator($storage, \OC::$server->getDatabaseConnection(), ['appdata_'.$config->getValue('instanceid')]);
377 377
 		}
378 378
 		return $storage->propagator;
379 379
 	}
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
 	 */
432 432
 	public function cleanPath($path) {
433 433
 		if (strlen($path) == 0 or $path[0] != '/') {
434
-			$path = '/' . $path;
434
+			$path = '/'.$path;
435 435
 		}
436 436
 
437 437
 		$output = [];
@@ -459,7 +459,7 @@  discard block
 block discarded – undo
459 459
 			\OC::$server->getLogger()->info("External storage not available: stat() failed");
460 460
 			return false;
461 461
 		} catch (\Exception $e) {
462
-			\OC::$server->getLogger()->info("External storage not available: " . $e->getMessage());
462
+			\OC::$server->getLogger()->info("External storage not available: ".$e->getMessage());
463 463
 			\OC::$server->getLogger()->logException($e, ['level' => ILogger::DEBUG]);
464 464
 			return false;
465 465
 		}
@@ -612,7 +612,7 @@  discard block
 block discarded – undo
612 612
 			if (is_resource($dh)) {
613 613
 				while ($result and ($file = readdir($dh)) !== false) {
614 614
 					if (!Filesystem::isIgnoredDir($file)) {
615
-						$result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
615
+						$result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath.'/'.$file, $targetInternalPath.'/'.$file);
616 616
 					}
617 617
 				}
618 618
 			}
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
 				$this->getCache()->remove($targetInternalPath);
639 639
 			}
640 640
 		}
641
-		return (bool)$result;
641
+		return (bool) $result;
642 642
 	}
643 643
 
644 644
 	/**
@@ -744,7 +744,7 @@  discard block
 block discarded – undo
744 744
 			);
745 745
 		}
746 746
 		try {
747
-			$provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
747
+			$provider->acquireLock('files/'.md5($this->getId().'::'.trim($path, '/')), $type);
748 748
 		} catch (LockedException $e) {
749 749
 			if ($logger) {
750 750
 				$logger->logException($e, ['level' => ILogger::INFO]);
@@ -776,7 +776,7 @@  discard block
 block discarded – undo
776 776
 			);
777 777
 		}
778 778
 		try {
779
-			$provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
779
+			$provider->releaseLock('files/'.md5($this->getId().'::'.trim($path, '/')), $type);
780 780
 		} catch (LockedException $e) {
781 781
 			if ($logger) {
782 782
 				$logger->logException($e, ['level' => ILogger::INFO]);
@@ -808,7 +808,7 @@  discard block
 block discarded – undo
808 808
 			);
809 809
 		}
810 810
 		try {
811
-			$provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
811
+			$provider->changeLock('files/'.md5($this->getId().'::'.trim($path, '/')), $type);
812 812
 		} catch (LockedException $e) {
813 813
 			\OC::$server->getLogger()->logException($e, ['level' => ILogger::INFO]);
814 814
 			throw $e;
Please login to merge, or discard this patch.
Indentation   +782 added lines, -782 removed lines patch added patch discarded remove patch
@@ -77,790 +77,790 @@
 block discarded – undo
77 77
  */
78 78
 abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
79 79
 
80
-	use LocalTempFileTrait;
81
-
82
-	protected $cache;
83
-	protected $scanner;
84
-	protected $watcher;
85
-	protected $propagator;
86
-	protected $storageCache;
87
-	protected $updater;
88
-
89
-	protected $mountOptions = [];
90
-	protected $owner = null;
91
-
92
-	private $shouldLogLocks = null;
93
-	private $logger;
94
-
95
-	public function __construct($parameters) {
96
-	}
97
-
98
-	/**
99
-	 * Remove a file or folder
100
-	 *
101
-	 * @param string $path
102
-	 * @return bool
103
-	 */
104
-	protected function remove($path) {
105
-		if ($this->is_dir($path)) {
106
-			return $this->rmdir($path);
107
-		} elseif ($this->is_file($path)) {
108
-			return $this->unlink($path);
109
-		} else {
110
-			return false;
111
-		}
112
-	}
113
-
114
-	public function is_dir($path) {
115
-		return $this->filetype($path) === 'dir';
116
-	}
117
-
118
-	public function is_file($path) {
119
-		return $this->filetype($path) === 'file';
120
-	}
121
-
122
-	public function filesize($path) {
123
-		if ($this->is_dir($path)) {
124
-			return 0; //by definition
125
-		} else {
126
-			$stat = $this->stat($path);
127
-			if (isset($stat['size'])) {
128
-				return $stat['size'];
129
-			} else {
130
-				return 0;
131
-			}
132
-		}
133
-	}
134
-
135
-	public function isReadable($path) {
136
-		// at least check whether it exists
137
-		// subclasses might want to implement this more thoroughly
138
-		return $this->file_exists($path);
139
-	}
140
-
141
-	public function isUpdatable($path) {
142
-		// at least check whether it exists
143
-		// subclasses might want to implement this more thoroughly
144
-		// a non-existing file/folder isn't updatable
145
-		return $this->file_exists($path);
146
-	}
147
-
148
-	public function isCreatable($path) {
149
-		if ($this->is_dir($path) && $this->isUpdatable($path)) {
150
-			return true;
151
-		}
152
-		return false;
153
-	}
154
-
155
-	public function isDeletable($path) {
156
-		if ($path === '' || $path === '/') {
157
-			return false;
158
-		}
159
-		$parent = dirname($path);
160
-		return $this->isUpdatable($parent) && $this->isUpdatable($path);
161
-	}
162
-
163
-	public function isSharable($path) {
164
-		return $this->isReadable($path);
165
-	}
166
-
167
-	public function getPermissions($path) {
168
-		$permissions = 0;
169
-		if ($this->isCreatable($path)) {
170
-			$permissions |= \OCP\Constants::PERMISSION_CREATE;
171
-		}
172
-		if ($this->isReadable($path)) {
173
-			$permissions |= \OCP\Constants::PERMISSION_READ;
174
-		}
175
-		if ($this->isUpdatable($path)) {
176
-			$permissions |= \OCP\Constants::PERMISSION_UPDATE;
177
-		}
178
-		if ($this->isDeletable($path)) {
179
-			$permissions |= \OCP\Constants::PERMISSION_DELETE;
180
-		}
181
-		if ($this->isSharable($path)) {
182
-			$permissions |= \OCP\Constants::PERMISSION_SHARE;
183
-		}
184
-		return $permissions;
185
-	}
186
-
187
-	public function filemtime($path) {
188
-		$stat = $this->stat($path);
189
-		if (isset($stat['mtime']) && $stat['mtime'] > 0) {
190
-			return $stat['mtime'];
191
-		} else {
192
-			return 0;
193
-		}
194
-	}
195
-
196
-	public function file_get_contents($path) {
197
-		$handle = $this->fopen($path, "r");
198
-		if (!$handle) {
199
-			return false;
200
-		}
201
-		$data = stream_get_contents($handle);
202
-		fclose($handle);
203
-		return $data;
204
-	}
205
-
206
-	public function file_put_contents($path, $data) {
207
-		$handle = $this->fopen($path, "w");
208
-		$this->removeCachedFile($path);
209
-		$count = fwrite($handle, $data);
210
-		fclose($handle);
211
-		return $count;
212
-	}
213
-
214
-	public function rename($path1, $path2) {
215
-		$this->remove($path2);
216
-
217
-		$this->removeCachedFile($path1);
218
-		return $this->copy($path1, $path2) and $this->remove($path1);
219
-	}
220
-
221
-	public function copy($path1, $path2) {
222
-		if ($this->is_dir($path1)) {
223
-			$this->remove($path2);
224
-			$dir = $this->opendir($path1);
225
-			$this->mkdir($path2);
226
-			while ($file = readdir($dir)) {
227
-				if (!Filesystem::isIgnoredDir($file)) {
228
-					if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
229
-						return false;
230
-					}
231
-				}
232
-			}
233
-			closedir($dir);
234
-			return true;
235
-		} else {
236
-			$source = $this->fopen($path1, 'r');
237
-			$target = $this->fopen($path2, 'w');
238
-			list(, $result) = \OC_Helper::streamCopy($source, $target);
239
-			if (!$result) {
240
-				\OC::$server->getLogger()->warning("Failed to write data while copying $path1 to $path2");
241
-			}
242
-			$this->removeCachedFile($path2);
243
-			return $result;
244
-		}
245
-	}
246
-
247
-	public function getMimeType($path) {
248
-		if ($this->is_dir($path)) {
249
-			return 'httpd/unix-directory';
250
-		} elseif ($this->file_exists($path)) {
251
-			return \OC::$server->getMimeTypeDetector()->detectPath($path);
252
-		} else {
253
-			return false;
254
-		}
255
-	}
256
-
257
-	public function hash($type, $path, $raw = false) {
258
-		$fh = $this->fopen($path, 'rb');
259
-		$ctx = hash_init($type);
260
-		hash_update_stream($ctx, $fh);
261
-		fclose($fh);
262
-		return hash_final($ctx, $raw);
263
-	}
264
-
265
-	public function search($query) {
266
-		return $this->searchInDir($query);
267
-	}
268
-
269
-	public function getLocalFile($path) {
270
-		return $this->getCachedFile($path);
271
-	}
272
-
273
-	/**
274
-	 * @param string $path
275
-	 * @param string $target
276
-	 */
277
-	private function addLocalFolder($path, $target) {
278
-		$dh = $this->opendir($path);
279
-		if (is_resource($dh)) {
280
-			while (($file = readdir($dh)) !== false) {
281
-				if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
282
-					if ($this->is_dir($path . '/' . $file)) {
283
-						mkdir($target . '/' . $file);
284
-						$this->addLocalFolder($path . '/' . $file, $target . '/' . $file);
285
-					} else {
286
-						$tmp = $this->toTmpFile($path . '/' . $file);
287
-						rename($tmp, $target . '/' . $file);
288
-					}
289
-				}
290
-			}
291
-		}
292
-	}
293
-
294
-	/**
295
-	 * @param string $query
296
-	 * @param string $dir
297
-	 * @return array
298
-	 */
299
-	protected function searchInDir($query, $dir = '') {
300
-		$files = [];
301
-		$dh = $this->opendir($dir);
302
-		if (is_resource($dh)) {
303
-			while (($item = readdir($dh)) !== false) {
304
-				if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
305
-				if (strstr(strtolower($item), strtolower($query)) !== false) {
306
-					$files[] = $dir . '/' . $item;
307
-				}
308
-				if ($this->is_dir($dir . '/' . $item)) {
309
-					$files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
310
-				}
311
-			}
312
-		}
313
-		closedir($dh);
314
-		return $files;
315
-	}
316
-
317
-	/**
318
-	 * check if a file or folder has been updated since $time
319
-	 *
320
-	 * The method is only used to check if the cache needs to be updated. Storage backends that don't support checking
321
-	 * the mtime should always return false here. As a result storage implementations that always return false expect
322
-	 * exclusive access to the backend and will not pick up files that have been added in a way that circumvents
323
-	 * ownClouds filesystem.
324
-	 *
325
-	 * @param string $path
326
-	 * @param int $time
327
-	 * @return bool
328
-	 */
329
-	public function hasUpdated($path, $time) {
330
-		return $this->filemtime($path) > $time;
331
-	}
332
-
333
-	public function getCache($path = '', $storage = null) {
334
-		if (!$storage) {
335
-			$storage = $this;
336
-		}
337
-		if (!isset($storage->cache)) {
338
-			$storage->cache = new Cache($storage);
339
-		}
340
-		return $storage->cache;
341
-	}
342
-
343
-	public function getScanner($path = '', $storage = null) {
344
-		if (!$storage) {
345
-			$storage = $this;
346
-		}
347
-		if (!isset($storage->scanner)) {
348
-			$storage->scanner = new Scanner($storage);
349
-		}
350
-		return $storage->scanner;
351
-	}
352
-
353
-	public function getWatcher($path = '', $storage = null) {
354
-		if (!$storage) {
355
-			$storage = $this;
356
-		}
357
-		if (!isset($this->watcher)) {
358
-			$this->watcher = new Watcher($storage);
359
-			$globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
360
-			$this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
361
-		}
362
-		return $this->watcher;
363
-	}
364
-
365
-	/**
366
-	 * get a propagator instance for the cache
367
-	 *
368
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
369
-	 * @return \OC\Files\Cache\Propagator
370
-	 */
371
-	public function getPropagator($storage = null) {
372
-		if (!$storage) {
373
-			$storage = $this;
374
-		}
375
-		if (!isset($storage->propagator)) {
376
-			$config = \OC::$server->getSystemConfig();
377
-			$storage->propagator = new Propagator($storage, \OC::$server->getDatabaseConnection(), ['appdata_' . $config->getValue('instanceid')]);
378
-		}
379
-		return $storage->propagator;
380
-	}
381
-
382
-	public function getUpdater($storage = null) {
383
-		if (!$storage) {
384
-			$storage = $this;
385
-		}
386
-		if (!isset($storage->updater)) {
387
-			$storage->updater = new Updater($storage);
388
-		}
389
-		return $storage->updater;
390
-	}
391
-
392
-	public function getStorageCache($storage = null) {
393
-		if (!$storage) {
394
-			$storage = $this;
395
-		}
396
-		if (!isset($this->storageCache)) {
397
-			$this->storageCache = new \OC\Files\Cache\Storage($storage);
398
-		}
399
-		return $this->storageCache;
400
-	}
401
-
402
-	/**
403
-	 * get the owner of a path
404
-	 *
405
-	 * @param string $path The path to get the owner
406
-	 * @return string|false uid or false
407
-	 */
408
-	public function getOwner($path) {
409
-		if ($this->owner === null) {
410
-			$this->owner = \OC_User::getUser();
411
-		}
412
-
413
-		return $this->owner;
414
-	}
415
-
416
-	/**
417
-	 * get the ETag for a file or folder
418
-	 *
419
-	 * @param string $path
420
-	 * @return string
421
-	 */
422
-	public function getETag($path) {
423
-		return uniqid();
424
-	}
425
-
426
-	/**
427
-	 * clean a path, i.e. remove all redundant '.' and '..'
428
-	 * making sure that it can't point to higher than '/'
429
-	 *
430
-	 * @param string $path The path to clean
431
-	 * @return string cleaned path
432
-	 */
433
-	public function cleanPath($path) {
434
-		if (strlen($path) == 0 or $path[0] != '/') {
435
-			$path = '/' . $path;
436
-		}
437
-
438
-		$output = [];
439
-		foreach (explode('/', $path) as $chunk) {
440
-			if ($chunk == '..') {
441
-				array_pop($output);
442
-			} elseif ($chunk == '.') {
443
-			} else {
444
-				$output[] = $chunk;
445
-			}
446
-		}
447
-		return implode('/', $output);
448
-	}
449
-
450
-	/**
451
-	 * Test a storage for availability
452
-	 *
453
-	 * @return bool
454
-	 */
455
-	public function test() {
456
-		try {
457
-			if ($this->stat('')) {
458
-				return true;
459
-			}
460
-			\OC::$server->getLogger()->info("External storage not available: stat() failed");
461
-			return false;
462
-		} catch (\Exception $e) {
463
-			\OC::$server->getLogger()->info("External storage not available: " . $e->getMessage());
464
-			\OC::$server->getLogger()->logException($e, ['level' => ILogger::DEBUG]);
465
-			return false;
466
-		}
467
-	}
468
-
469
-	/**
470
-	 * get the free space in the storage
471
-	 *
472
-	 * @param string $path
473
-	 * @return int|false
474
-	 */
475
-	public function free_space($path) {
476
-		return \OCP\Files\FileInfo::SPACE_UNKNOWN;
477
-	}
478
-
479
-	/**
480
-	 * {@inheritdoc}
481
-	 */
482
-	public function isLocal() {
483
-		// the common implementation returns a temporary file by
484
-		// default, which is not local
485
-		return false;
486
-	}
487
-
488
-	/**
489
-	 * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
490
-	 *
491
-	 * @param string $class
492
-	 * @return bool
493
-	 */
494
-	public function instanceOfStorage($class) {
495
-		if (ltrim($class, '\\') === 'OC\Files\Storage\Shared') {
496
-			// FIXME Temporary fix to keep existing checks working
497
-			$class = '\OCA\Files_Sharing\SharedStorage';
498
-		}
499
-		return is_a($this, $class);
500
-	}
501
-
502
-	/**
503
-	 * A custom storage implementation can return an url for direct download of a give file.
504
-	 *
505
-	 * For now the returned array can hold the parameter url - in future more attributes might follow.
506
-	 *
507
-	 * @param string $path
508
-	 * @return array|false
509
-	 */
510
-	public function getDirectDownload($path) {
511
-		return [];
512
-	}
513
-
514
-	/**
515
-	 * @inheritdoc
516
-	 * @throws InvalidPathException
517
-	 */
518
-	public function verifyPath($path, $fileName) {
519
-
520
-		// verify empty and dot files
521
-		$trimmed = trim($fileName);
522
-		if ($trimmed === '') {
523
-			throw new EmptyFileNameException();
524
-		}
525
-
526
-		if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
527
-			throw new InvalidDirectoryException();
528
-		}
529
-
530
-		if (!\OC::$server->getDatabaseConnection()->supports4ByteText()) {
531
-			// verify database - e.g. mysql only 3-byte chars
532
-			if (preg_match('%(?:
80
+    use LocalTempFileTrait;
81
+
82
+    protected $cache;
83
+    protected $scanner;
84
+    protected $watcher;
85
+    protected $propagator;
86
+    protected $storageCache;
87
+    protected $updater;
88
+
89
+    protected $mountOptions = [];
90
+    protected $owner = null;
91
+
92
+    private $shouldLogLocks = null;
93
+    private $logger;
94
+
95
+    public function __construct($parameters) {
96
+    }
97
+
98
+    /**
99
+     * Remove a file or folder
100
+     *
101
+     * @param string $path
102
+     * @return bool
103
+     */
104
+    protected function remove($path) {
105
+        if ($this->is_dir($path)) {
106
+            return $this->rmdir($path);
107
+        } elseif ($this->is_file($path)) {
108
+            return $this->unlink($path);
109
+        } else {
110
+            return false;
111
+        }
112
+    }
113
+
114
+    public function is_dir($path) {
115
+        return $this->filetype($path) === 'dir';
116
+    }
117
+
118
+    public function is_file($path) {
119
+        return $this->filetype($path) === 'file';
120
+    }
121
+
122
+    public function filesize($path) {
123
+        if ($this->is_dir($path)) {
124
+            return 0; //by definition
125
+        } else {
126
+            $stat = $this->stat($path);
127
+            if (isset($stat['size'])) {
128
+                return $stat['size'];
129
+            } else {
130
+                return 0;
131
+            }
132
+        }
133
+    }
134
+
135
+    public function isReadable($path) {
136
+        // at least check whether it exists
137
+        // subclasses might want to implement this more thoroughly
138
+        return $this->file_exists($path);
139
+    }
140
+
141
+    public function isUpdatable($path) {
142
+        // at least check whether it exists
143
+        // subclasses might want to implement this more thoroughly
144
+        // a non-existing file/folder isn't updatable
145
+        return $this->file_exists($path);
146
+    }
147
+
148
+    public function isCreatable($path) {
149
+        if ($this->is_dir($path) && $this->isUpdatable($path)) {
150
+            return true;
151
+        }
152
+        return false;
153
+    }
154
+
155
+    public function isDeletable($path) {
156
+        if ($path === '' || $path === '/') {
157
+            return false;
158
+        }
159
+        $parent = dirname($path);
160
+        return $this->isUpdatable($parent) && $this->isUpdatable($path);
161
+    }
162
+
163
+    public function isSharable($path) {
164
+        return $this->isReadable($path);
165
+    }
166
+
167
+    public function getPermissions($path) {
168
+        $permissions = 0;
169
+        if ($this->isCreatable($path)) {
170
+            $permissions |= \OCP\Constants::PERMISSION_CREATE;
171
+        }
172
+        if ($this->isReadable($path)) {
173
+            $permissions |= \OCP\Constants::PERMISSION_READ;
174
+        }
175
+        if ($this->isUpdatable($path)) {
176
+            $permissions |= \OCP\Constants::PERMISSION_UPDATE;
177
+        }
178
+        if ($this->isDeletable($path)) {
179
+            $permissions |= \OCP\Constants::PERMISSION_DELETE;
180
+        }
181
+        if ($this->isSharable($path)) {
182
+            $permissions |= \OCP\Constants::PERMISSION_SHARE;
183
+        }
184
+        return $permissions;
185
+    }
186
+
187
+    public function filemtime($path) {
188
+        $stat = $this->stat($path);
189
+        if (isset($stat['mtime']) && $stat['mtime'] > 0) {
190
+            return $stat['mtime'];
191
+        } else {
192
+            return 0;
193
+        }
194
+    }
195
+
196
+    public function file_get_contents($path) {
197
+        $handle = $this->fopen($path, "r");
198
+        if (!$handle) {
199
+            return false;
200
+        }
201
+        $data = stream_get_contents($handle);
202
+        fclose($handle);
203
+        return $data;
204
+    }
205
+
206
+    public function file_put_contents($path, $data) {
207
+        $handle = $this->fopen($path, "w");
208
+        $this->removeCachedFile($path);
209
+        $count = fwrite($handle, $data);
210
+        fclose($handle);
211
+        return $count;
212
+    }
213
+
214
+    public function rename($path1, $path2) {
215
+        $this->remove($path2);
216
+
217
+        $this->removeCachedFile($path1);
218
+        return $this->copy($path1, $path2) and $this->remove($path1);
219
+    }
220
+
221
+    public function copy($path1, $path2) {
222
+        if ($this->is_dir($path1)) {
223
+            $this->remove($path2);
224
+            $dir = $this->opendir($path1);
225
+            $this->mkdir($path2);
226
+            while ($file = readdir($dir)) {
227
+                if (!Filesystem::isIgnoredDir($file)) {
228
+                    if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
229
+                        return false;
230
+                    }
231
+                }
232
+            }
233
+            closedir($dir);
234
+            return true;
235
+        } else {
236
+            $source = $this->fopen($path1, 'r');
237
+            $target = $this->fopen($path2, 'w');
238
+            list(, $result) = \OC_Helper::streamCopy($source, $target);
239
+            if (!$result) {
240
+                \OC::$server->getLogger()->warning("Failed to write data while copying $path1 to $path2");
241
+            }
242
+            $this->removeCachedFile($path2);
243
+            return $result;
244
+        }
245
+    }
246
+
247
+    public function getMimeType($path) {
248
+        if ($this->is_dir($path)) {
249
+            return 'httpd/unix-directory';
250
+        } elseif ($this->file_exists($path)) {
251
+            return \OC::$server->getMimeTypeDetector()->detectPath($path);
252
+        } else {
253
+            return false;
254
+        }
255
+    }
256
+
257
+    public function hash($type, $path, $raw = false) {
258
+        $fh = $this->fopen($path, 'rb');
259
+        $ctx = hash_init($type);
260
+        hash_update_stream($ctx, $fh);
261
+        fclose($fh);
262
+        return hash_final($ctx, $raw);
263
+    }
264
+
265
+    public function search($query) {
266
+        return $this->searchInDir($query);
267
+    }
268
+
269
+    public function getLocalFile($path) {
270
+        return $this->getCachedFile($path);
271
+    }
272
+
273
+    /**
274
+     * @param string $path
275
+     * @param string $target
276
+     */
277
+    private function addLocalFolder($path, $target) {
278
+        $dh = $this->opendir($path);
279
+        if (is_resource($dh)) {
280
+            while (($file = readdir($dh)) !== false) {
281
+                if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
282
+                    if ($this->is_dir($path . '/' . $file)) {
283
+                        mkdir($target . '/' . $file);
284
+                        $this->addLocalFolder($path . '/' . $file, $target . '/' . $file);
285
+                    } else {
286
+                        $tmp = $this->toTmpFile($path . '/' . $file);
287
+                        rename($tmp, $target . '/' . $file);
288
+                    }
289
+                }
290
+            }
291
+        }
292
+    }
293
+
294
+    /**
295
+     * @param string $query
296
+     * @param string $dir
297
+     * @return array
298
+     */
299
+    protected function searchInDir($query, $dir = '') {
300
+        $files = [];
301
+        $dh = $this->opendir($dir);
302
+        if (is_resource($dh)) {
303
+            while (($item = readdir($dh)) !== false) {
304
+                if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
305
+                if (strstr(strtolower($item), strtolower($query)) !== false) {
306
+                    $files[] = $dir . '/' . $item;
307
+                }
308
+                if ($this->is_dir($dir . '/' . $item)) {
309
+                    $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
310
+                }
311
+            }
312
+        }
313
+        closedir($dh);
314
+        return $files;
315
+    }
316
+
317
+    /**
318
+     * check if a file or folder has been updated since $time
319
+     *
320
+     * The method is only used to check if the cache needs to be updated. Storage backends that don't support checking
321
+     * the mtime should always return false here. As a result storage implementations that always return false expect
322
+     * exclusive access to the backend and will not pick up files that have been added in a way that circumvents
323
+     * ownClouds filesystem.
324
+     *
325
+     * @param string $path
326
+     * @param int $time
327
+     * @return bool
328
+     */
329
+    public function hasUpdated($path, $time) {
330
+        return $this->filemtime($path) > $time;
331
+    }
332
+
333
+    public function getCache($path = '', $storage = null) {
334
+        if (!$storage) {
335
+            $storage = $this;
336
+        }
337
+        if (!isset($storage->cache)) {
338
+            $storage->cache = new Cache($storage);
339
+        }
340
+        return $storage->cache;
341
+    }
342
+
343
+    public function getScanner($path = '', $storage = null) {
344
+        if (!$storage) {
345
+            $storage = $this;
346
+        }
347
+        if (!isset($storage->scanner)) {
348
+            $storage->scanner = new Scanner($storage);
349
+        }
350
+        return $storage->scanner;
351
+    }
352
+
353
+    public function getWatcher($path = '', $storage = null) {
354
+        if (!$storage) {
355
+            $storage = $this;
356
+        }
357
+        if (!isset($this->watcher)) {
358
+            $this->watcher = new Watcher($storage);
359
+            $globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
360
+            $this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
361
+        }
362
+        return $this->watcher;
363
+    }
364
+
365
+    /**
366
+     * get a propagator instance for the cache
367
+     *
368
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
369
+     * @return \OC\Files\Cache\Propagator
370
+     */
371
+    public function getPropagator($storage = null) {
372
+        if (!$storage) {
373
+            $storage = $this;
374
+        }
375
+        if (!isset($storage->propagator)) {
376
+            $config = \OC::$server->getSystemConfig();
377
+            $storage->propagator = new Propagator($storage, \OC::$server->getDatabaseConnection(), ['appdata_' . $config->getValue('instanceid')]);
378
+        }
379
+        return $storage->propagator;
380
+    }
381
+
382
+    public function getUpdater($storage = null) {
383
+        if (!$storage) {
384
+            $storage = $this;
385
+        }
386
+        if (!isset($storage->updater)) {
387
+            $storage->updater = new Updater($storage);
388
+        }
389
+        return $storage->updater;
390
+    }
391
+
392
+    public function getStorageCache($storage = null) {
393
+        if (!$storage) {
394
+            $storage = $this;
395
+        }
396
+        if (!isset($this->storageCache)) {
397
+            $this->storageCache = new \OC\Files\Cache\Storage($storage);
398
+        }
399
+        return $this->storageCache;
400
+    }
401
+
402
+    /**
403
+     * get the owner of a path
404
+     *
405
+     * @param string $path The path to get the owner
406
+     * @return string|false uid or false
407
+     */
408
+    public function getOwner($path) {
409
+        if ($this->owner === null) {
410
+            $this->owner = \OC_User::getUser();
411
+        }
412
+
413
+        return $this->owner;
414
+    }
415
+
416
+    /**
417
+     * get the ETag for a file or folder
418
+     *
419
+     * @param string $path
420
+     * @return string
421
+     */
422
+    public function getETag($path) {
423
+        return uniqid();
424
+    }
425
+
426
+    /**
427
+     * clean a path, i.e. remove all redundant '.' and '..'
428
+     * making sure that it can't point to higher than '/'
429
+     *
430
+     * @param string $path The path to clean
431
+     * @return string cleaned path
432
+     */
433
+    public function cleanPath($path) {
434
+        if (strlen($path) == 0 or $path[0] != '/') {
435
+            $path = '/' . $path;
436
+        }
437
+
438
+        $output = [];
439
+        foreach (explode('/', $path) as $chunk) {
440
+            if ($chunk == '..') {
441
+                array_pop($output);
442
+            } elseif ($chunk == '.') {
443
+            } else {
444
+                $output[] = $chunk;
445
+            }
446
+        }
447
+        return implode('/', $output);
448
+    }
449
+
450
+    /**
451
+     * Test a storage for availability
452
+     *
453
+     * @return bool
454
+     */
455
+    public function test() {
456
+        try {
457
+            if ($this->stat('')) {
458
+                return true;
459
+            }
460
+            \OC::$server->getLogger()->info("External storage not available: stat() failed");
461
+            return false;
462
+        } catch (\Exception $e) {
463
+            \OC::$server->getLogger()->info("External storage not available: " . $e->getMessage());
464
+            \OC::$server->getLogger()->logException($e, ['level' => ILogger::DEBUG]);
465
+            return false;
466
+        }
467
+    }
468
+
469
+    /**
470
+     * get the free space in the storage
471
+     *
472
+     * @param string $path
473
+     * @return int|false
474
+     */
475
+    public function free_space($path) {
476
+        return \OCP\Files\FileInfo::SPACE_UNKNOWN;
477
+    }
478
+
479
+    /**
480
+     * {@inheritdoc}
481
+     */
482
+    public function isLocal() {
483
+        // the common implementation returns a temporary file by
484
+        // default, which is not local
485
+        return false;
486
+    }
487
+
488
+    /**
489
+     * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
490
+     *
491
+     * @param string $class
492
+     * @return bool
493
+     */
494
+    public function instanceOfStorage($class) {
495
+        if (ltrim($class, '\\') === 'OC\Files\Storage\Shared') {
496
+            // FIXME Temporary fix to keep existing checks working
497
+            $class = '\OCA\Files_Sharing\SharedStorage';
498
+        }
499
+        return is_a($this, $class);
500
+    }
501
+
502
+    /**
503
+     * A custom storage implementation can return an url for direct download of a give file.
504
+     *
505
+     * For now the returned array can hold the parameter url - in future more attributes might follow.
506
+     *
507
+     * @param string $path
508
+     * @return array|false
509
+     */
510
+    public function getDirectDownload($path) {
511
+        return [];
512
+    }
513
+
514
+    /**
515
+     * @inheritdoc
516
+     * @throws InvalidPathException
517
+     */
518
+    public function verifyPath($path, $fileName) {
519
+
520
+        // verify empty and dot files
521
+        $trimmed = trim($fileName);
522
+        if ($trimmed === '') {
523
+            throw new EmptyFileNameException();
524
+        }
525
+
526
+        if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
527
+            throw new InvalidDirectoryException();
528
+        }
529
+
530
+        if (!\OC::$server->getDatabaseConnection()->supports4ByteText()) {
531
+            // verify database - e.g. mysql only 3-byte chars
532
+            if (preg_match('%(?:
533 533
       \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
534 534
     | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
535 535
     | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
536 536
 )%xs', $fileName)) {
537
-				throw new InvalidCharacterInPathException();
538
-			}
539
-		}
540
-
541
-		// 255 characters is the limit on common file systems (ext/xfs)
542
-		// oc_filecache has a 250 char length limit for the filename
543
-		if (isset($fileName[250])) {
544
-			throw new FileNameTooLongException();
545
-		}
546
-
547
-		// NOTE: $path will remain unverified for now
548
-		$this->verifyPosixPath($fileName);
549
-	}
550
-
551
-	/**
552
-	 * @param string $fileName
553
-	 * @throws InvalidPathException
554
-	 */
555
-	protected function verifyPosixPath($fileName) {
556
-		$fileName = trim($fileName);
557
-		$this->scanForInvalidCharacters($fileName, "\\/");
558
-		$reservedNames = ['*'];
559
-		if (in_array($fileName, $reservedNames)) {
560
-			throw new ReservedWordException();
561
-		}
562
-	}
563
-
564
-	/**
565
-	 * @param string $fileName
566
-	 * @param string $invalidChars
567
-	 * @throws InvalidPathException
568
-	 */
569
-	private function scanForInvalidCharacters($fileName, $invalidChars) {
570
-		foreach (str_split($invalidChars) as $char) {
571
-			if (strpos($fileName, $char) !== false) {
572
-				throw new InvalidCharacterInPathException();
573
-			}
574
-		}
575
-
576
-		$sanitizedFileName = filter_var($fileName, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);
577
-		if ($sanitizedFileName !== $fileName) {
578
-			throw new InvalidCharacterInPathException();
579
-		}
580
-	}
581
-
582
-	/**
583
-	 * @param array $options
584
-	 */
585
-	public function setMountOptions(array $options) {
586
-		$this->mountOptions = $options;
587
-	}
588
-
589
-	/**
590
-	 * @param string $name
591
-	 * @param mixed $default
592
-	 * @return mixed
593
-	 */
594
-	public function getMountOption($name, $default = null) {
595
-		return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
596
-	}
597
-
598
-	/**
599
-	 * @param IStorage $sourceStorage
600
-	 * @param string $sourceInternalPath
601
-	 * @param string $targetInternalPath
602
-	 * @param bool $preserveMtime
603
-	 * @return bool
604
-	 */
605
-	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
606
-		if ($sourceStorage === $this) {
607
-			return $this->copy($sourceInternalPath, $targetInternalPath);
608
-		}
609
-
610
-		if ($sourceStorage->is_dir($sourceInternalPath)) {
611
-			$dh = $sourceStorage->opendir($sourceInternalPath);
612
-			$result = $this->mkdir($targetInternalPath);
613
-			if (is_resource($dh)) {
614
-				while ($result and ($file = readdir($dh)) !== false) {
615
-					if (!Filesystem::isIgnoredDir($file)) {
616
-						$result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
617
-					}
618
-				}
619
-			}
620
-		} else {
621
-			$source = $sourceStorage->fopen($sourceInternalPath, 'r');
622
-			// TODO: call fopen in a way that we execute again all storage wrappers
623
-			// to avoid that we bypass storage wrappers which perform important actions
624
-			// for this operation. Same is true for all other operations which
625
-			// are not the same as the original one.Once this is fixed we also
626
-			// need to adjust the encryption wrapper.
627
-			$target = $this->fopen($targetInternalPath, 'w');
628
-			list(, $result) = \OC_Helper::streamCopy($source, $target);
629
-			if ($result and $preserveMtime) {
630
-				$this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
631
-			}
632
-			fclose($source);
633
-			fclose($target);
634
-
635
-			if (!$result) {
636
-				// delete partially written target file
637
-				$this->unlink($targetInternalPath);
638
-				// delete cache entry that was created by fopen
639
-				$this->getCache()->remove($targetInternalPath);
640
-			}
641
-		}
642
-		return (bool)$result;
643
-	}
644
-
645
-	/**
646
-	 * Check if a storage is the same as the current one, including wrapped storages
647
-	 *
648
-	 * @param IStorage $storage
649
-	 * @return bool
650
-	 */
651
-	private function isSameStorage(IStorage $storage): bool {
652
-		while ($storage->instanceOfStorage(Wrapper::class)) {
653
-			/**
654
-			 * @var Wrapper $sourceStorage
655
-			 */
656
-			$storage = $storage->getWrapperStorage();
657
-		}
658
-
659
-		return $storage === $this;
660
-	}
661
-
662
-	/**
663
-	 * @param IStorage $sourceStorage
664
-	 * @param string $sourceInternalPath
665
-	 * @param string $targetInternalPath
666
-	 * @return bool
667
-	 */
668
-	public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
669
-		if ($this->isSameStorage($sourceStorage)) {
670
-			// resolve any jailed paths
671
-			while ($sourceStorage->instanceOfStorage(Jail::class)) {
672
-				/**
673
-				 * @var Jail $sourceStorage
674
-				 */
675
-				$sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
676
-				$sourceStorage = $sourceStorage->getUnjailedStorage();
677
-			}
678
-
679
-			return $this->rename($sourceInternalPath, $targetInternalPath);
680
-		}
681
-
682
-		if (!$sourceStorage->isDeletable($sourceInternalPath)) {
683
-			return false;
684
-		}
685
-
686
-		$result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true);
687
-		if ($result) {
688
-			if ($sourceStorage->is_dir($sourceInternalPath)) {
689
-				$result &= $sourceStorage->rmdir($sourceInternalPath);
690
-			} else {
691
-				$result &= $sourceStorage->unlink($sourceInternalPath);
692
-			}
693
-		}
694
-		return $result;
695
-	}
696
-
697
-	/**
698
-	 * @inheritdoc
699
-	 */
700
-	public function getMetaData($path) {
701
-		$permissions = $this->getPermissions($path);
702
-		if (!$permissions & \OCP\Constants::PERMISSION_READ) {
703
-			//can't read, nothing we can do
704
-			return null;
705
-		}
706
-
707
-		$data = [];
708
-		$data['mimetype'] = $this->getMimeType($path);
709
-		$data['mtime'] = $this->filemtime($path);
710
-		if ($data['mtime'] === false) {
711
-			$data['mtime'] = time();
712
-		}
713
-		if ($data['mimetype'] == 'httpd/unix-directory') {
714
-			$data['size'] = -1; //unknown
715
-		} else {
716
-			$data['size'] = $this->filesize($path);
717
-		}
718
-		$data['etag'] = $this->getETag($path);
719
-		$data['storage_mtime'] = $data['mtime'];
720
-		$data['permissions'] = $permissions;
721
-
722
-		return $data;
723
-	}
724
-
725
-	/**
726
-	 * @param string $path
727
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
728
-	 * @param \OCP\Lock\ILockingProvider $provider
729
-	 * @throws \OCP\Lock\LockedException
730
-	 */
731
-	public function acquireLock($path, $type, ILockingProvider $provider) {
732
-		$logger = $this->getLockLogger();
733
-		if ($logger) {
734
-			$typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
735
-			$logger->info(
736
-				sprintf(
737
-					'acquire %s lock on "%s" on storage "%s"',
738
-					$typeString,
739
-					$path,
740
-					$this->getId()
741
-				),
742
-				[
743
-					'app' => 'locking',
744
-				]
745
-			);
746
-		}
747
-		try {
748
-			$provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
749
-		} catch (LockedException $e) {
750
-			if ($logger) {
751
-				$logger->logException($e, ['level' => ILogger::INFO]);
752
-			}
753
-			throw $e;
754
-		}
755
-	}
756
-
757
-	/**
758
-	 * @param string $path
759
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
760
-	 * @param \OCP\Lock\ILockingProvider $provider
761
-	 * @throws \OCP\Lock\LockedException
762
-	 */
763
-	public function releaseLock($path, $type, ILockingProvider $provider) {
764
-		$logger = $this->getLockLogger();
765
-		if ($logger) {
766
-			$typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
767
-			$logger->info(
768
-				sprintf(
769
-					'release %s lock on "%s" on storage "%s"',
770
-					$typeString,
771
-					$path,
772
-					$this->getId()
773
-				),
774
-				[
775
-					'app' => 'locking',
776
-				]
777
-			);
778
-		}
779
-		try {
780
-			$provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
781
-		} catch (LockedException $e) {
782
-			if ($logger) {
783
-				$logger->logException($e, ['level' => ILogger::INFO]);
784
-			}
785
-			throw $e;
786
-		}
787
-	}
788
-
789
-	/**
790
-	 * @param string $path
791
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
792
-	 * @param \OCP\Lock\ILockingProvider $provider
793
-	 * @throws \OCP\Lock\LockedException
794
-	 */
795
-	public function changeLock($path, $type, ILockingProvider $provider) {
796
-		$logger = $this->getLockLogger();
797
-		if ($logger) {
798
-			$typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
799
-			$logger->info(
800
-				sprintf(
801
-					'change lock on "%s" to %s on storage "%s"',
802
-					$path,
803
-					$typeString,
804
-					$this->getId()
805
-				),
806
-				[
807
-					'app' => 'locking',
808
-				]
809
-			);
810
-		}
811
-		try {
812
-			$provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
813
-		} catch (LockedException $e) {
814
-			\OC::$server->getLogger()->logException($e, ['level' => ILogger::INFO]);
815
-			throw $e;
816
-		}
817
-	}
818
-
819
-	private function getLockLogger() {
820
-		if (is_null($this->shouldLogLocks)) {
821
-			$this->shouldLogLocks = \OC::$server->getConfig()->getSystemValue('filelocking.debug', false);
822
-			$this->logger = $this->shouldLogLocks ? \OC::$server->getLogger() : null;
823
-		}
824
-		return $this->logger;
825
-	}
826
-
827
-	/**
828
-	 * @return array [ available, last_checked ]
829
-	 */
830
-	public function getAvailability() {
831
-		return $this->getStorageCache()->getAvailability();
832
-	}
833
-
834
-	/**
835
-	 * @param bool $isAvailable
836
-	 */
837
-	public function setAvailability($isAvailable) {
838
-		$this->getStorageCache()->setAvailability($isAvailable);
839
-	}
840
-
841
-	/**
842
-	 * @return bool
843
-	 */
844
-	public function needsPartFile() {
845
-		return true;
846
-	}
847
-
848
-	/**
849
-	 * fallback implementation
850
-	 *
851
-	 * @param string $path
852
-	 * @param resource $stream
853
-	 * @param int $size
854
-	 * @return int
855
-	 */
856
-	public function writeStream(string $path, $stream, int $size = null): int {
857
-		$target = $this->fopen($path, 'w');
858
-		if (!$target) {
859
-			return 0;
860
-		}
861
-		list($count, $result) = \OC_Helper::streamCopy($stream, $target);
862
-		fclose($stream);
863
-		fclose($target);
864
-		return $count;
865
-	}
537
+                throw new InvalidCharacterInPathException();
538
+            }
539
+        }
540
+
541
+        // 255 characters is the limit on common file systems (ext/xfs)
542
+        // oc_filecache has a 250 char length limit for the filename
543
+        if (isset($fileName[250])) {
544
+            throw new FileNameTooLongException();
545
+        }
546
+
547
+        // NOTE: $path will remain unverified for now
548
+        $this->verifyPosixPath($fileName);
549
+    }
550
+
551
+    /**
552
+     * @param string $fileName
553
+     * @throws InvalidPathException
554
+     */
555
+    protected function verifyPosixPath($fileName) {
556
+        $fileName = trim($fileName);
557
+        $this->scanForInvalidCharacters($fileName, "\\/");
558
+        $reservedNames = ['*'];
559
+        if (in_array($fileName, $reservedNames)) {
560
+            throw new ReservedWordException();
561
+        }
562
+    }
563
+
564
+    /**
565
+     * @param string $fileName
566
+     * @param string $invalidChars
567
+     * @throws InvalidPathException
568
+     */
569
+    private function scanForInvalidCharacters($fileName, $invalidChars) {
570
+        foreach (str_split($invalidChars) as $char) {
571
+            if (strpos($fileName, $char) !== false) {
572
+                throw new InvalidCharacterInPathException();
573
+            }
574
+        }
575
+
576
+        $sanitizedFileName = filter_var($fileName, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);
577
+        if ($sanitizedFileName !== $fileName) {
578
+            throw new InvalidCharacterInPathException();
579
+        }
580
+    }
581
+
582
+    /**
583
+     * @param array $options
584
+     */
585
+    public function setMountOptions(array $options) {
586
+        $this->mountOptions = $options;
587
+    }
588
+
589
+    /**
590
+     * @param string $name
591
+     * @param mixed $default
592
+     * @return mixed
593
+     */
594
+    public function getMountOption($name, $default = null) {
595
+        return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
596
+    }
597
+
598
+    /**
599
+     * @param IStorage $sourceStorage
600
+     * @param string $sourceInternalPath
601
+     * @param string $targetInternalPath
602
+     * @param bool $preserveMtime
603
+     * @return bool
604
+     */
605
+    public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
606
+        if ($sourceStorage === $this) {
607
+            return $this->copy($sourceInternalPath, $targetInternalPath);
608
+        }
609
+
610
+        if ($sourceStorage->is_dir($sourceInternalPath)) {
611
+            $dh = $sourceStorage->opendir($sourceInternalPath);
612
+            $result = $this->mkdir($targetInternalPath);
613
+            if (is_resource($dh)) {
614
+                while ($result and ($file = readdir($dh)) !== false) {
615
+                    if (!Filesystem::isIgnoredDir($file)) {
616
+                        $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
617
+                    }
618
+                }
619
+            }
620
+        } else {
621
+            $source = $sourceStorage->fopen($sourceInternalPath, 'r');
622
+            // TODO: call fopen in a way that we execute again all storage wrappers
623
+            // to avoid that we bypass storage wrappers which perform important actions
624
+            // for this operation. Same is true for all other operations which
625
+            // are not the same as the original one.Once this is fixed we also
626
+            // need to adjust the encryption wrapper.
627
+            $target = $this->fopen($targetInternalPath, 'w');
628
+            list(, $result) = \OC_Helper::streamCopy($source, $target);
629
+            if ($result and $preserveMtime) {
630
+                $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
631
+            }
632
+            fclose($source);
633
+            fclose($target);
634
+
635
+            if (!$result) {
636
+                // delete partially written target file
637
+                $this->unlink($targetInternalPath);
638
+                // delete cache entry that was created by fopen
639
+                $this->getCache()->remove($targetInternalPath);
640
+            }
641
+        }
642
+        return (bool)$result;
643
+    }
644
+
645
+    /**
646
+     * Check if a storage is the same as the current one, including wrapped storages
647
+     *
648
+     * @param IStorage $storage
649
+     * @return bool
650
+     */
651
+    private function isSameStorage(IStorage $storage): bool {
652
+        while ($storage->instanceOfStorage(Wrapper::class)) {
653
+            /**
654
+             * @var Wrapper $sourceStorage
655
+             */
656
+            $storage = $storage->getWrapperStorage();
657
+        }
658
+
659
+        return $storage === $this;
660
+    }
661
+
662
+    /**
663
+     * @param IStorage $sourceStorage
664
+     * @param string $sourceInternalPath
665
+     * @param string $targetInternalPath
666
+     * @return bool
667
+     */
668
+    public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
669
+        if ($this->isSameStorage($sourceStorage)) {
670
+            // resolve any jailed paths
671
+            while ($sourceStorage->instanceOfStorage(Jail::class)) {
672
+                /**
673
+                 * @var Jail $sourceStorage
674
+                 */
675
+                $sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
676
+                $sourceStorage = $sourceStorage->getUnjailedStorage();
677
+            }
678
+
679
+            return $this->rename($sourceInternalPath, $targetInternalPath);
680
+        }
681
+
682
+        if (!$sourceStorage->isDeletable($sourceInternalPath)) {
683
+            return false;
684
+        }
685
+
686
+        $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true);
687
+        if ($result) {
688
+            if ($sourceStorage->is_dir($sourceInternalPath)) {
689
+                $result &= $sourceStorage->rmdir($sourceInternalPath);
690
+            } else {
691
+                $result &= $sourceStorage->unlink($sourceInternalPath);
692
+            }
693
+        }
694
+        return $result;
695
+    }
696
+
697
+    /**
698
+     * @inheritdoc
699
+     */
700
+    public function getMetaData($path) {
701
+        $permissions = $this->getPermissions($path);
702
+        if (!$permissions & \OCP\Constants::PERMISSION_READ) {
703
+            //can't read, nothing we can do
704
+            return null;
705
+        }
706
+
707
+        $data = [];
708
+        $data['mimetype'] = $this->getMimeType($path);
709
+        $data['mtime'] = $this->filemtime($path);
710
+        if ($data['mtime'] === false) {
711
+            $data['mtime'] = time();
712
+        }
713
+        if ($data['mimetype'] == 'httpd/unix-directory') {
714
+            $data['size'] = -1; //unknown
715
+        } else {
716
+            $data['size'] = $this->filesize($path);
717
+        }
718
+        $data['etag'] = $this->getETag($path);
719
+        $data['storage_mtime'] = $data['mtime'];
720
+        $data['permissions'] = $permissions;
721
+
722
+        return $data;
723
+    }
724
+
725
+    /**
726
+     * @param string $path
727
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
728
+     * @param \OCP\Lock\ILockingProvider $provider
729
+     * @throws \OCP\Lock\LockedException
730
+     */
731
+    public function acquireLock($path, $type, ILockingProvider $provider) {
732
+        $logger = $this->getLockLogger();
733
+        if ($logger) {
734
+            $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
735
+            $logger->info(
736
+                sprintf(
737
+                    'acquire %s lock on "%s" on storage "%s"',
738
+                    $typeString,
739
+                    $path,
740
+                    $this->getId()
741
+                ),
742
+                [
743
+                    'app' => 'locking',
744
+                ]
745
+            );
746
+        }
747
+        try {
748
+            $provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
749
+        } catch (LockedException $e) {
750
+            if ($logger) {
751
+                $logger->logException($e, ['level' => ILogger::INFO]);
752
+            }
753
+            throw $e;
754
+        }
755
+    }
756
+
757
+    /**
758
+     * @param string $path
759
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
760
+     * @param \OCP\Lock\ILockingProvider $provider
761
+     * @throws \OCP\Lock\LockedException
762
+     */
763
+    public function releaseLock($path, $type, ILockingProvider $provider) {
764
+        $logger = $this->getLockLogger();
765
+        if ($logger) {
766
+            $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
767
+            $logger->info(
768
+                sprintf(
769
+                    'release %s lock on "%s" on storage "%s"',
770
+                    $typeString,
771
+                    $path,
772
+                    $this->getId()
773
+                ),
774
+                [
775
+                    'app' => 'locking',
776
+                ]
777
+            );
778
+        }
779
+        try {
780
+            $provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
781
+        } catch (LockedException $e) {
782
+            if ($logger) {
783
+                $logger->logException($e, ['level' => ILogger::INFO]);
784
+            }
785
+            throw $e;
786
+        }
787
+    }
788
+
789
+    /**
790
+     * @param string $path
791
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
792
+     * @param \OCP\Lock\ILockingProvider $provider
793
+     * @throws \OCP\Lock\LockedException
794
+     */
795
+    public function changeLock($path, $type, ILockingProvider $provider) {
796
+        $logger = $this->getLockLogger();
797
+        if ($logger) {
798
+            $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
799
+            $logger->info(
800
+                sprintf(
801
+                    'change lock on "%s" to %s on storage "%s"',
802
+                    $path,
803
+                    $typeString,
804
+                    $this->getId()
805
+                ),
806
+                [
807
+                    'app' => 'locking',
808
+                ]
809
+            );
810
+        }
811
+        try {
812
+            $provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
813
+        } catch (LockedException $e) {
814
+            \OC::$server->getLogger()->logException($e, ['level' => ILogger::INFO]);
815
+            throw $e;
816
+        }
817
+    }
818
+
819
+    private function getLockLogger() {
820
+        if (is_null($this->shouldLogLocks)) {
821
+            $this->shouldLogLocks = \OC::$server->getConfig()->getSystemValue('filelocking.debug', false);
822
+            $this->logger = $this->shouldLogLocks ? \OC::$server->getLogger() : null;
823
+        }
824
+        return $this->logger;
825
+    }
826
+
827
+    /**
828
+     * @return array [ available, last_checked ]
829
+     */
830
+    public function getAvailability() {
831
+        return $this->getStorageCache()->getAvailability();
832
+    }
833
+
834
+    /**
835
+     * @param bool $isAvailable
836
+     */
837
+    public function setAvailability($isAvailable) {
838
+        $this->getStorageCache()->setAvailability($isAvailable);
839
+    }
840
+
841
+    /**
842
+     * @return bool
843
+     */
844
+    public function needsPartFile() {
845
+        return true;
846
+    }
847
+
848
+    /**
849
+     * fallback implementation
850
+     *
851
+     * @param string $path
852
+     * @param resource $stream
853
+     * @param int $size
854
+     * @return int
855
+     */
856
+    public function writeStream(string $path, $stream, int $size = null): int {
857
+        $target = $this->fopen($path, 'w');
858
+        if (!$target) {
859
+            return 0;
860
+        }
861
+        list($count, $result) = \OC_Helper::streamCopy($stream, $target);
862
+        fclose($stream);
863
+        fclose($target);
864
+        return $count;
865
+    }
866 866
 }
Please login to merge, or discard this patch.
lib/private/Files/Storage/StorageFactory.php 2 patches
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -29,80 +29,80 @@
 block discarded – undo
29 29
 use OCP\Files\Storage\IStorageFactory;
30 30
 
31 31
 class StorageFactory implements IStorageFactory {
32
-	/**
33
-	 * @var array[] [$name=>['priority'=>$priority, 'wrapper'=>$callable] $storageWrappers
34
-	 */
35
-	private $storageWrappers = [];
32
+    /**
33
+     * @var array[] [$name=>['priority'=>$priority, 'wrapper'=>$callable] $storageWrappers
34
+     */
35
+    private $storageWrappers = [];
36 36
 
37
-	/**
38
-	 * allow modifier storage behaviour by adding wrappers around storages
39
-	 *
40
-	 * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage
41
-	 *
42
-	 * @param string $wrapperName name of the wrapper
43
-	 * @param callable $callback callback
44
-	 * @param int $priority wrappers with the lower priority are applied last (meaning they get called first)
45
-	 * @param \OCP\Files\Mount\IMountPoint[] $existingMounts existing mount points to apply the wrapper to
46
-	 * @return bool true if the wrapper was added, false if there was already a wrapper with this
47
-	 * name registered
48
-	 */
49
-	public function addStorageWrapper($wrapperName, $callback, $priority = 50, $existingMounts = []) {
50
-		if (isset($this->storageWrappers[$wrapperName])) {
51
-			return false;
52
-		}
37
+    /**
38
+     * allow modifier storage behaviour by adding wrappers around storages
39
+     *
40
+     * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage
41
+     *
42
+     * @param string $wrapperName name of the wrapper
43
+     * @param callable $callback callback
44
+     * @param int $priority wrappers with the lower priority are applied last (meaning they get called first)
45
+     * @param \OCP\Files\Mount\IMountPoint[] $existingMounts existing mount points to apply the wrapper to
46
+     * @return bool true if the wrapper was added, false if there was already a wrapper with this
47
+     * name registered
48
+     */
49
+    public function addStorageWrapper($wrapperName, $callback, $priority = 50, $existingMounts = []) {
50
+        if (isset($this->storageWrappers[$wrapperName])) {
51
+            return false;
52
+        }
53 53
 
54
-		// apply to existing mounts before registering it to prevent applying it double in MountPoint::createStorage
55
-		foreach ($existingMounts as $mount) {
56
-			$mount->wrapStorage($callback);
57
-		}
54
+        // apply to existing mounts before registering it to prevent applying it double in MountPoint::createStorage
55
+        foreach ($existingMounts as $mount) {
56
+            $mount->wrapStorage($callback);
57
+        }
58 58
 
59
-		$this->storageWrappers[$wrapperName] = ['wrapper' => $callback, 'priority' => $priority];
60
-		return true;
61
-	}
59
+        $this->storageWrappers[$wrapperName] = ['wrapper' => $callback, 'priority' => $priority];
60
+        return true;
61
+    }
62 62
 
63
-	/**
64
-	 * Remove a storage wrapper by name.
65
-	 * Note: internal method only to be used for cleanup
66
-	 *
67
-	 * @param string $wrapperName name of the wrapper
68
-	 * @internal
69
-	 */
70
-	public function removeStorageWrapper($wrapperName) {
71
-		unset($this->storageWrappers[$wrapperName]);
72
-	}
63
+    /**
64
+     * Remove a storage wrapper by name.
65
+     * Note: internal method only to be used for cleanup
66
+     *
67
+     * @param string $wrapperName name of the wrapper
68
+     * @internal
69
+     */
70
+    public function removeStorageWrapper($wrapperName) {
71
+        unset($this->storageWrappers[$wrapperName]);
72
+    }
73 73
 
74
-	/**
75
-	 * Create an instance of a storage and apply the registered storage wrappers
76
-	 *
77
-	 * @param \OCP\Files\Mount\IMountPoint $mountPoint
78
-	 * @param string $class
79
-	 * @param array $arguments
80
-	 * @return \OCP\Files\Storage
81
-	 */
82
-	public function getInstance(IMountPoint $mountPoint, $class, $arguments) {
83
-		return $this->wrap($mountPoint, new $class($arguments));
84
-	}
74
+    /**
75
+     * Create an instance of a storage and apply the registered storage wrappers
76
+     *
77
+     * @param \OCP\Files\Mount\IMountPoint $mountPoint
78
+     * @param string $class
79
+     * @param array $arguments
80
+     * @return \OCP\Files\Storage
81
+     */
82
+    public function getInstance(IMountPoint $mountPoint, $class, $arguments) {
83
+        return $this->wrap($mountPoint, new $class($arguments));
84
+    }
85 85
 
86
-	/**
87
-	 * @param \OCP\Files\Mount\IMountPoint $mountPoint
88
-	 * @param \OCP\Files\Storage $storage
89
-	 * @return \OCP\Files\Storage
90
-	 */
91
-	public function wrap(IMountPoint $mountPoint, $storage) {
92
-		$wrappers = array_values($this->storageWrappers);
93
-		usort($wrappers, function ($a, $b) {
94
-			return $b['priority'] - $a['priority'];
95
-		});
96
-		/** @var callable[] $wrappers */
97
-		$wrappers = array_map(function ($wrapper) {
98
-			return $wrapper['wrapper'];
99
-		}, $wrappers);
100
-		foreach ($wrappers as $wrapper) {
101
-			$storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint);
102
-			if (!($storage instanceof \OCP\Files\Storage)) {
103
-				throw new \Exception('Invalid result from storage wrapper');
104
-			}
105
-		}
106
-		return $storage;
107
-	}
86
+    /**
87
+     * @param \OCP\Files\Mount\IMountPoint $mountPoint
88
+     * @param \OCP\Files\Storage $storage
89
+     * @return \OCP\Files\Storage
90
+     */
91
+    public function wrap(IMountPoint $mountPoint, $storage) {
92
+        $wrappers = array_values($this->storageWrappers);
93
+        usort($wrappers, function ($a, $b) {
94
+            return $b['priority'] - $a['priority'];
95
+        });
96
+        /** @var callable[] $wrappers */
97
+        $wrappers = array_map(function ($wrapper) {
98
+            return $wrapper['wrapper'];
99
+        }, $wrappers);
100
+        foreach ($wrappers as $wrapper) {
101
+            $storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint);
102
+            if (!($storage instanceof \OCP\Files\Storage)) {
103
+                throw new \Exception('Invalid result from storage wrapper');
104
+            }
105
+        }
106
+        return $storage;
107
+    }
108 108
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -90,11 +90,11 @@
 block discarded – undo
90 90
 	 */
91 91
 	public function wrap(IMountPoint $mountPoint, $storage) {
92 92
 		$wrappers = array_values($this->storageWrappers);
93
-		usort($wrappers, function ($a, $b) {
93
+		usort($wrappers, function($a, $b) {
94 94
 			return $b['priority'] - $a['priority'];
95 95
 		});
96 96
 		/** @var callable[] $wrappers */
97
-		$wrappers = array_map(function ($wrapper) {
97
+		$wrappers = array_map(function($wrapper) {
98 98
 			return $wrapper['wrapper'];
99 99
 		}, $wrappers);
100 100
 		foreach ($wrappers as $wrapper) {
Please login to merge, or discard this patch.