Completed
Pull Request — master (#5550)
by Andreas
16:28
created
lib/private/Files/ObjectStore/ObjectStoreStorage.php 1 patch
Indentation   +386 added lines, -386 removed lines patch added patch discarded remove patch
@@ -31,390 +31,390 @@
 block discarded – undo
31 31
 use OCP\Files\ObjectStore\IObjectStore;
32 32
 
33 33
 class ObjectStoreStorage extends \OC\Files\Storage\Common {
34
-	/**
35
-	 * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
36
-	 */
37
-	protected $objectStore;
38
-	/**
39
-	 * @var string $id
40
-	 */
41
-	protected $id;
42
-	/**
43
-	 * @var \OC\User\User $user
44
-	 */
45
-	protected $user;
46
-
47
-	private $objectPrefix = 'urn:oid:';
48
-
49
-	private $logger;
50
-
51
-	public function __construct($params) {
52
-		if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
53
-			$this->objectStore = $params['objectstore'];
54
-		} else {
55
-			throw new \Exception('missing IObjectStore instance');
56
-		}
57
-		if (isset($params['storageid'])) {
58
-			$this->id = 'object::store:' . $params['storageid'];
59
-		} else {
60
-			$this->id = 'object::store:' . $this->objectStore->getStorageId();
61
-		}
62
-		if (isset($params['objectPrefix'])) {
63
-			$this->objectPrefix = $params['objectPrefix'];
64
-		}
65
-		//initialize cache with root directory in cache
66
-		if (!$this->is_dir('/')) {
67
-			$this->mkdir('/');
68
-		}
69
-
70
-		$this->logger = \OC::$server->getLogger();
71
-	}
72
-
73
-	public function mkdir($path) {
74
-		$path = $this->normalizePath($path);
75
-
76
-		if ($this->file_exists($path)) {
77
-			return false;
78
-		}
79
-
80
-		$mTime = time();
81
-		$data = [
82
-			'mimetype' => 'httpd/unix-directory',
83
-			'size' => 0,
84
-			'mtime' => $mTime,
85
-			'storage_mtime' => $mTime,
86
-			'permissions' => \OCP\Constants::PERMISSION_ALL,
87
-		];
88
-		if ($path === '') {
89
-			//create root on the fly
90
-			$data['etag'] = $this->getETag('');
91
-			$this->getCache()->put('', $data);
92
-			return true;
93
-		} else {
94
-			// if parent does not exist, create it
95
-			$parent = $this->normalizePath(dirname($path));
96
-			$parentType = $this->filetype($parent);
97
-			if ($parentType === false) {
98
-				if (!$this->mkdir($parent)) {
99
-					// something went wrong
100
-					return false;
101
-				}
102
-			} else if ($parentType === 'file') {
103
-				// parent is a file
104
-				return false;
105
-			}
106
-			// finally create the new dir
107
-			$mTime = time(); // update mtime
108
-			$data['mtime'] = $mTime;
109
-			$data['storage_mtime'] = $mTime;
110
-			$data['etag'] = $this->getETag($path);
111
-			$this->getCache()->put($path, $data);
112
-			return true;
113
-		}
114
-	}
115
-
116
-	/**
117
-	 * @param string $path
118
-	 * @return string
119
-	 */
120
-	private function normalizePath($path) {
121
-		$path = trim($path, '/');
122
-		//FIXME why do we sometimes get a path like 'files//username'?
123
-		$path = str_replace('//', '/', $path);
124
-
125
-		// dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
126
-		if (!$path || $path === '.') {
127
-			$path = '';
128
-		}
129
-
130
-		return $path;
131
-	}
132
-
133
-	/**
134
-	 * Object Stores use a NoopScanner because metadata is directly stored in
135
-	 * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
136
-	 *
137
-	 * @param string $path
138
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
139
-	 * @return \OC\Files\ObjectStore\NoopScanner
140
-	 */
141
-	public function getScanner($path = '', $storage = null) {
142
-		if (!$storage) {
143
-			$storage = $this;
144
-		}
145
-		if (!isset($this->scanner)) {
146
-			$this->scanner = new NoopScanner($storage);
147
-		}
148
-		return $this->scanner;
149
-	}
150
-
151
-	public function getId() {
152
-		return $this->id;
153
-	}
154
-
155
-	public function rmdir($path) {
156
-		$path = $this->normalizePath($path);
157
-
158
-		if (!$this->is_dir($path)) {
159
-			return false;
160
-		}
161
-
162
-		$this->rmObjects($path);
163
-
164
-		$this->getCache()->remove($path);
165
-
166
-		return true;
167
-	}
168
-
169
-	private function rmObjects($path) {
170
-		$children = $this->getCache()->getFolderContents($path);
171
-		foreach ($children as $child) {
172
-			if ($child['mimetype'] === 'httpd/unix-directory') {
173
-				$this->rmObjects($child['path']);
174
-			} else {
175
-				$this->unlink($child['path']);
176
-			}
177
-		}
178
-	}
179
-
180
-	public function unlink($path) {
181
-		$path = $this->normalizePath($path);
182
-		$stat = $this->stat($path);
183
-
184
-		if ($stat && isset($stat['fileid'])) {
185
-			if ($stat['mimetype'] === 'httpd/unix-directory') {
186
-				return $this->rmdir($path);
187
-			}
188
-			try {
189
-				$this->objectStore->deleteObject($this->getURN($stat['fileid']));
190
-			} catch (\Exception $ex) {
191
-				if ($ex->getCode() !== 404) {
192
-					$this->logger->logException($ex, [
193
-						'app' => 'objectstore',
194
-						'message' => 'Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path,
195
-					]);
196
-					return false;
197
-				} else {
198
-					//removing from cache is ok as it does not exist in the objectstore anyway
199
-				}
200
-			}
201
-			$this->getCache()->remove($path);
202
-			return true;
203
-		}
204
-		return false;
205
-	}
206
-
207
-	public function stat($path) {
208
-		$path = $this->normalizePath($path);
209
-		$cacheEntry = $this->getCache()->get($path);
210
-		if ($cacheEntry instanceof CacheEntry) {
211
-			return $cacheEntry->getData();
212
-		} else {
213
-			return false;
214
-		}
215
-	}
216
-
217
-	/**
218
-	 * Override this method if you need a different unique resource identifier for your object storage implementation.
219
-	 * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
220
-	 * You may need a mapping table to store your URN if it cannot be generated from the fileid.
221
-	 *
222
-	 * @param int $fileId the fileid
223
-	 * @return null|string the unified resource name used to identify the object
224
-	 */
225
-	protected function getURN($fileId) {
226
-		if (is_numeric($fileId)) {
227
-			return $this->objectPrefix . $fileId;
228
-		}
229
-		return null;
230
-	}
231
-
232
-	public function opendir($path) {
233
-		$path = $this->normalizePath($path);
234
-
235
-		try {
236
-			$files = array();
237
-			$folderContents = $this->getCache()->getFolderContents($path);
238
-			foreach ($folderContents as $file) {
239
-				$files[] = $file['name'];
240
-			}
241
-
242
-			return IteratorDirectory::wrap($files);
243
-		} catch (\Exception $e) {
244
-			$this->logger->logException($e);
245
-			return false;
246
-		}
247
-	}
248
-
249
-	public function filetype($path) {
250
-		$path = $this->normalizePath($path);
251
-		$stat = $this->stat($path);
252
-		if ($stat) {
253
-			if ($stat['mimetype'] === 'httpd/unix-directory') {
254
-				return 'dir';
255
-			}
256
-			return 'file';
257
-		} else {
258
-			return false;
259
-		}
260
-	}
261
-
262
-	public function fopen($path, $mode) {
263
-		$path = $this->normalizePath($path);
264
-
265
-		switch ($mode) {
266
-			case 'r':
267
-			case 'rb':
268
-				$stat = $this->stat($path);
269
-				if (is_array($stat)) {
270
-					try {
271
-						return $this->objectStore->readObject($this->getURN($stat['fileid']));
272
-					} catch (\Exception $ex) {
273
-						$this->logger->logException($ex, [
274
-							'app' => 'objectstore',
275
-							'message' => 'Count not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
276
-						]);
277
-						return false;
278
-					}
279
-				} else {
280
-					return false;
281
-				}
282
-			case 'w':
283
-			case 'wb':
284
-			case 'a':
285
-			case 'ab':
286
-			case 'r+':
287
-			case 'w+':
288
-			case 'wb+':
289
-			case 'a+':
290
-			case 'x':
291
-			case 'x+':
292
-			case 'c':
293
-			case 'c+':
294
-				if (strrpos($path, '.') !== false) {
295
-					$ext = substr($path, strrpos($path, '.'));
296
-				} else {
297
-					$ext = '';
298
-				}
299
-				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
300
-				if ($this->file_exists($path)) {
301
-					$source = $this->fopen($path, 'r');
302
-					file_put_contents($tmpFile, $source);
303
-				}
304
-				$handle = fopen($tmpFile, $mode);
305
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
306
-					$this->writeBack($tmpFile, $path);
307
-				});
308
-		}
309
-		return false;
310
-	}
311
-
312
-	public function file_exists($path) {
313
-		$path = $this->normalizePath($path);
314
-		return (bool)$this->stat($path);
315
-	}
316
-
317
-	public function rename($source, $target) {
318
-		$source = $this->normalizePath($source);
319
-		$target = $this->normalizePath($target);
320
-		$this->remove($target);
321
-		$this->getCache()->move($source, $target);
322
-		$this->touch(dirname($target));
323
-		return true;
324
-	}
325
-
326
-	public function getMimeType($path) {
327
-		$path = $this->normalizePath($path);
328
-		$stat = $this->stat($path);
329
-		if (is_array($stat)) {
330
-			return $stat['mimetype'];
331
-		} else {
332
-			return false;
333
-		}
334
-	}
335
-
336
-	public function touch($path, $mtime = null) {
337
-		if (is_null($mtime)) {
338
-			$mtime = time();
339
-		}
340
-
341
-		$path = $this->normalizePath($path);
342
-		$dirName = dirname($path);
343
-		$parentExists = $this->is_dir($dirName);
344
-		if (!$parentExists) {
345
-			return false;
346
-		}
347
-
348
-		$stat = $this->stat($path);
349
-		if (is_array($stat)) {
350
-			// update existing mtime in db
351
-			$stat['mtime'] = $mtime;
352
-			$this->getCache()->update($stat['fileid'], $stat);
353
-		} else {
354
-			$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
355
-			// create new file
356
-			$stat = array(
357
-				'etag' => $this->getETag($path),
358
-				'mimetype' => $mimeType,
359
-				'size' => 0,
360
-				'mtime' => $mtime,
361
-				'storage_mtime' => $mtime,
362
-				'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
363
-			);
364
-			$fileId = $this->getCache()->put($path, $stat);
365
-			try {
366
-				//read an empty file from memory
367
-				$this->objectStore->writeObject($this->getURN($fileId), fopen('php://memory', 'r'));
368
-			} catch (\Exception $ex) {
369
-				$this->getCache()->remove($path);
370
-				$this->logger->logException($ex, [
371
-					'app' => 'objectstore',
372
-					'message' => 'Could not create object ' . $this->getURN($fileId) . ' for ' . $path,
373
-				]);
374
-				return false;
375
-			}
376
-		}
377
-		return true;
378
-	}
379
-
380
-	public function writeBack($tmpFile, $path) {
381
-		$stat = $this->stat($path);
382
-		if (empty($stat)) {
383
-			// create new file
384
-			$stat = array(
385
-				'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
386
-			);
387
-		}
388
-		// update stat with new data
389
-		$mTime = time();
390
-		$stat['size'] = filesize($tmpFile);
391
-		$stat['mtime'] = $mTime;
392
-		$stat['storage_mtime'] = $mTime;
393
-		$stat['mimetype'] = \OC::$server->getMimeTypeDetector()->detect($tmpFile);
394
-		$stat['etag'] = $this->getETag($path);
395
-
396
-		$fileId = $this->getCache()->put($path, $stat);
397
-		try {
398
-			//upload to object storage
399
-			$this->objectStore->writeObject($this->getURN($fileId), fopen($tmpFile, 'r'));
400
-		} catch (\Exception $ex) {
401
-			$this->getCache()->remove($path);
402
-			$this->logger->logException($ex, [
403
-				'app' => 'objectstore',
404
-				'message' => 'Could not create object ' . $this->getURN($fileId) . ' for ' . $path,
405
-			]);
406
-			throw $ex; // make this bubble up
407
-		}
408
-	}
409
-
410
-	/**
411
-	 * external changes are not supported, exclusive access to the object storage is assumed
412
-	 *
413
-	 * @param string $path
414
-	 * @param int $time
415
-	 * @return false
416
-	 */
417
-	public function hasUpdated($path, $time) {
418
-		return false;
419
-	}
34
+    /**
35
+     * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
36
+     */
37
+    protected $objectStore;
38
+    /**
39
+     * @var string $id
40
+     */
41
+    protected $id;
42
+    /**
43
+     * @var \OC\User\User $user
44
+     */
45
+    protected $user;
46
+
47
+    private $objectPrefix = 'urn:oid:';
48
+
49
+    private $logger;
50
+
51
+    public function __construct($params) {
52
+        if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
53
+            $this->objectStore = $params['objectstore'];
54
+        } else {
55
+            throw new \Exception('missing IObjectStore instance');
56
+        }
57
+        if (isset($params['storageid'])) {
58
+            $this->id = 'object::store:' . $params['storageid'];
59
+        } else {
60
+            $this->id = 'object::store:' . $this->objectStore->getStorageId();
61
+        }
62
+        if (isset($params['objectPrefix'])) {
63
+            $this->objectPrefix = $params['objectPrefix'];
64
+        }
65
+        //initialize cache with root directory in cache
66
+        if (!$this->is_dir('/')) {
67
+            $this->mkdir('/');
68
+        }
69
+
70
+        $this->logger = \OC::$server->getLogger();
71
+    }
72
+
73
+    public function mkdir($path) {
74
+        $path = $this->normalizePath($path);
75
+
76
+        if ($this->file_exists($path)) {
77
+            return false;
78
+        }
79
+
80
+        $mTime = time();
81
+        $data = [
82
+            'mimetype' => 'httpd/unix-directory',
83
+            'size' => 0,
84
+            'mtime' => $mTime,
85
+            'storage_mtime' => $mTime,
86
+            'permissions' => \OCP\Constants::PERMISSION_ALL,
87
+        ];
88
+        if ($path === '') {
89
+            //create root on the fly
90
+            $data['etag'] = $this->getETag('');
91
+            $this->getCache()->put('', $data);
92
+            return true;
93
+        } else {
94
+            // if parent does not exist, create it
95
+            $parent = $this->normalizePath(dirname($path));
96
+            $parentType = $this->filetype($parent);
97
+            if ($parentType === false) {
98
+                if (!$this->mkdir($parent)) {
99
+                    // something went wrong
100
+                    return false;
101
+                }
102
+            } else if ($parentType === 'file') {
103
+                // parent is a file
104
+                return false;
105
+            }
106
+            // finally create the new dir
107
+            $mTime = time(); // update mtime
108
+            $data['mtime'] = $mTime;
109
+            $data['storage_mtime'] = $mTime;
110
+            $data['etag'] = $this->getETag($path);
111
+            $this->getCache()->put($path, $data);
112
+            return true;
113
+        }
114
+    }
115
+
116
+    /**
117
+     * @param string $path
118
+     * @return string
119
+     */
120
+    private function normalizePath($path) {
121
+        $path = trim($path, '/');
122
+        //FIXME why do we sometimes get a path like 'files//username'?
123
+        $path = str_replace('//', '/', $path);
124
+
125
+        // dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
126
+        if (!$path || $path === '.') {
127
+            $path = '';
128
+        }
129
+
130
+        return $path;
131
+    }
132
+
133
+    /**
134
+     * Object Stores use a NoopScanner because metadata is directly stored in
135
+     * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
136
+     *
137
+     * @param string $path
138
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
139
+     * @return \OC\Files\ObjectStore\NoopScanner
140
+     */
141
+    public function getScanner($path = '', $storage = null) {
142
+        if (!$storage) {
143
+            $storage = $this;
144
+        }
145
+        if (!isset($this->scanner)) {
146
+            $this->scanner = new NoopScanner($storage);
147
+        }
148
+        return $this->scanner;
149
+    }
150
+
151
+    public function getId() {
152
+        return $this->id;
153
+    }
154
+
155
+    public function rmdir($path) {
156
+        $path = $this->normalizePath($path);
157
+
158
+        if (!$this->is_dir($path)) {
159
+            return false;
160
+        }
161
+
162
+        $this->rmObjects($path);
163
+
164
+        $this->getCache()->remove($path);
165
+
166
+        return true;
167
+    }
168
+
169
+    private function rmObjects($path) {
170
+        $children = $this->getCache()->getFolderContents($path);
171
+        foreach ($children as $child) {
172
+            if ($child['mimetype'] === 'httpd/unix-directory') {
173
+                $this->rmObjects($child['path']);
174
+            } else {
175
+                $this->unlink($child['path']);
176
+            }
177
+        }
178
+    }
179
+
180
+    public function unlink($path) {
181
+        $path = $this->normalizePath($path);
182
+        $stat = $this->stat($path);
183
+
184
+        if ($stat && isset($stat['fileid'])) {
185
+            if ($stat['mimetype'] === 'httpd/unix-directory') {
186
+                return $this->rmdir($path);
187
+            }
188
+            try {
189
+                $this->objectStore->deleteObject($this->getURN($stat['fileid']));
190
+            } catch (\Exception $ex) {
191
+                if ($ex->getCode() !== 404) {
192
+                    $this->logger->logException($ex, [
193
+                        'app' => 'objectstore',
194
+                        'message' => 'Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path,
195
+                    ]);
196
+                    return false;
197
+                } else {
198
+                    //removing from cache is ok as it does not exist in the objectstore anyway
199
+                }
200
+            }
201
+            $this->getCache()->remove($path);
202
+            return true;
203
+        }
204
+        return false;
205
+    }
206
+
207
+    public function stat($path) {
208
+        $path = $this->normalizePath($path);
209
+        $cacheEntry = $this->getCache()->get($path);
210
+        if ($cacheEntry instanceof CacheEntry) {
211
+            return $cacheEntry->getData();
212
+        } else {
213
+            return false;
214
+        }
215
+    }
216
+
217
+    /**
218
+     * Override this method if you need a different unique resource identifier for your object storage implementation.
219
+     * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
220
+     * You may need a mapping table to store your URN if it cannot be generated from the fileid.
221
+     *
222
+     * @param int $fileId the fileid
223
+     * @return null|string the unified resource name used to identify the object
224
+     */
225
+    protected function getURN($fileId) {
226
+        if (is_numeric($fileId)) {
227
+            return $this->objectPrefix . $fileId;
228
+        }
229
+        return null;
230
+    }
231
+
232
+    public function opendir($path) {
233
+        $path = $this->normalizePath($path);
234
+
235
+        try {
236
+            $files = array();
237
+            $folderContents = $this->getCache()->getFolderContents($path);
238
+            foreach ($folderContents as $file) {
239
+                $files[] = $file['name'];
240
+            }
241
+
242
+            return IteratorDirectory::wrap($files);
243
+        } catch (\Exception $e) {
244
+            $this->logger->logException($e);
245
+            return false;
246
+        }
247
+    }
248
+
249
+    public function filetype($path) {
250
+        $path = $this->normalizePath($path);
251
+        $stat = $this->stat($path);
252
+        if ($stat) {
253
+            if ($stat['mimetype'] === 'httpd/unix-directory') {
254
+                return 'dir';
255
+            }
256
+            return 'file';
257
+        } else {
258
+            return false;
259
+        }
260
+    }
261
+
262
+    public function fopen($path, $mode) {
263
+        $path = $this->normalizePath($path);
264
+
265
+        switch ($mode) {
266
+            case 'r':
267
+            case 'rb':
268
+                $stat = $this->stat($path);
269
+                if (is_array($stat)) {
270
+                    try {
271
+                        return $this->objectStore->readObject($this->getURN($stat['fileid']));
272
+                    } catch (\Exception $ex) {
273
+                        $this->logger->logException($ex, [
274
+                            'app' => 'objectstore',
275
+                            'message' => 'Count not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
276
+                        ]);
277
+                        return false;
278
+                    }
279
+                } else {
280
+                    return false;
281
+                }
282
+            case 'w':
283
+            case 'wb':
284
+            case 'a':
285
+            case 'ab':
286
+            case 'r+':
287
+            case 'w+':
288
+            case 'wb+':
289
+            case 'a+':
290
+            case 'x':
291
+            case 'x+':
292
+            case 'c':
293
+            case 'c+':
294
+                if (strrpos($path, '.') !== false) {
295
+                    $ext = substr($path, strrpos($path, '.'));
296
+                } else {
297
+                    $ext = '';
298
+                }
299
+                $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
300
+                if ($this->file_exists($path)) {
301
+                    $source = $this->fopen($path, 'r');
302
+                    file_put_contents($tmpFile, $source);
303
+                }
304
+                $handle = fopen($tmpFile, $mode);
305
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
306
+                    $this->writeBack($tmpFile, $path);
307
+                });
308
+        }
309
+        return false;
310
+    }
311
+
312
+    public function file_exists($path) {
313
+        $path = $this->normalizePath($path);
314
+        return (bool)$this->stat($path);
315
+    }
316
+
317
+    public function rename($source, $target) {
318
+        $source = $this->normalizePath($source);
319
+        $target = $this->normalizePath($target);
320
+        $this->remove($target);
321
+        $this->getCache()->move($source, $target);
322
+        $this->touch(dirname($target));
323
+        return true;
324
+    }
325
+
326
+    public function getMimeType($path) {
327
+        $path = $this->normalizePath($path);
328
+        $stat = $this->stat($path);
329
+        if (is_array($stat)) {
330
+            return $stat['mimetype'];
331
+        } else {
332
+            return false;
333
+        }
334
+    }
335
+
336
+    public function touch($path, $mtime = null) {
337
+        if (is_null($mtime)) {
338
+            $mtime = time();
339
+        }
340
+
341
+        $path = $this->normalizePath($path);
342
+        $dirName = dirname($path);
343
+        $parentExists = $this->is_dir($dirName);
344
+        if (!$parentExists) {
345
+            return false;
346
+        }
347
+
348
+        $stat = $this->stat($path);
349
+        if (is_array($stat)) {
350
+            // update existing mtime in db
351
+            $stat['mtime'] = $mtime;
352
+            $this->getCache()->update($stat['fileid'], $stat);
353
+        } else {
354
+            $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
355
+            // create new file
356
+            $stat = array(
357
+                'etag' => $this->getETag($path),
358
+                'mimetype' => $mimeType,
359
+                'size' => 0,
360
+                'mtime' => $mtime,
361
+                'storage_mtime' => $mtime,
362
+                'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
363
+            );
364
+            $fileId = $this->getCache()->put($path, $stat);
365
+            try {
366
+                //read an empty file from memory
367
+                $this->objectStore->writeObject($this->getURN($fileId), fopen('php://memory', 'r'));
368
+            } catch (\Exception $ex) {
369
+                $this->getCache()->remove($path);
370
+                $this->logger->logException($ex, [
371
+                    'app' => 'objectstore',
372
+                    'message' => 'Could not create object ' . $this->getURN($fileId) . ' for ' . $path,
373
+                ]);
374
+                return false;
375
+            }
376
+        }
377
+        return true;
378
+    }
379
+
380
+    public function writeBack($tmpFile, $path) {
381
+        $stat = $this->stat($path);
382
+        if (empty($stat)) {
383
+            // create new file
384
+            $stat = array(
385
+                'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
386
+            );
387
+        }
388
+        // update stat with new data
389
+        $mTime = time();
390
+        $stat['size'] = filesize($tmpFile);
391
+        $stat['mtime'] = $mTime;
392
+        $stat['storage_mtime'] = $mTime;
393
+        $stat['mimetype'] = \OC::$server->getMimeTypeDetector()->detect($tmpFile);
394
+        $stat['etag'] = $this->getETag($path);
395
+
396
+        $fileId = $this->getCache()->put($path, $stat);
397
+        try {
398
+            //upload to object storage
399
+            $this->objectStore->writeObject($this->getURN($fileId), fopen($tmpFile, 'r'));
400
+        } catch (\Exception $ex) {
401
+            $this->getCache()->remove($path);
402
+            $this->logger->logException($ex, [
403
+                'app' => 'objectstore',
404
+                'message' => 'Could not create object ' . $this->getURN($fileId) . ' for ' . $path,
405
+            ]);
406
+            throw $ex; // make this bubble up
407
+        }
408
+    }
409
+
410
+    /**
411
+     * external changes are not supported, exclusive access to the object storage is assumed
412
+     *
413
+     * @param string $path
414
+     * @param int $time
415
+     * @return false
416
+     */
417
+    public function hasUpdated($path, $time) {
418
+        return false;
419
+    }
420 420
 }
Please login to merge, or discard this patch.
settings/templates/personal.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -11,14 +11,14 @@  discard block
 block discarded – undo
11 11
 <div id="app-navigation">
12 12
 	<ul class="with-icon">
13 13
 	<?php foreach($_['forms'] as $form) {
14
-		if (isset($form['anchor'])) {
15
-			$anchor = '#' . $form['anchor'];
16
-			$class = 'nav-icon-' . $form['anchor'];
17
-			$sectionName = $form['section-name'];
18
-			print_unescaped(sprintf("<li><a href='%s' class='%s'>%s</a></li>", \OCP\Util::sanitizeHTML($anchor),
19
-			\OCP\Util::sanitizeHTML($class), \OCP\Util::sanitizeHTML($sectionName)));
20
-		}
21
-	}?>
14
+        if (isset($form['anchor'])) {
15
+            $anchor = '#' . $form['anchor'];
16
+            $class = 'nav-icon-' . $form['anchor'];
17
+            $sectionName = $form['section-name'];
18
+            print_unescaped(sprintf("<li><a href='%s' class='%s'>%s</a></li>", \OCP\Util::sanitizeHTML($anchor),
19
+            \OCP\Util::sanitizeHTML($class), \OCP\Util::sanitizeHTML($sectionName)));
20
+        }
21
+    }?>
22 22
 	</ul>
23 23
 </div>
24 24
 
@@ -30,10 +30,10 @@  discard block
 block discarded – undo
30 30
 		<p id="quotatext">
31 31
 			<?php if ($_['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED): ?>
32 32
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong>',
33
-					[$_['usage'], $_['total_space']]));?>
33
+                    [$_['usage'], $_['total_space']]));?>
34 34
 			<?php else: ?>
35 35
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)',
36
-					[$_['usage'], $_['total_space'],  $_['usage_relative']]));?>
36
+                    [$_['usage'], $_['total_space'],  $_['usage_relative']]));?>
37 37
 			<?php endif ?>
38 38
 		</p>
39 39
 	</div>
@@ -99,17 +99,17 @@  discard block
 block discarded – undo
99 99
 			<div class="verify <?php if ($_['email'] === ''  || $_['emailScope'] !== 'public') p('hidden'); ?>">
100 100
 				<img id="verify-email" title="<?php p($_['emailMessage']); ?>" data-status="<?php p($_['emailVerification']) ?>" src="
101 101
 				<?php
102
-				switch($_['emailVerification']) {
103
-					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
104
-						p(image_path('core', 'actions/verifying.svg'));
105
-						break;
106
-					case \OC\Accounts\AccountManager::VERIFIED:
107
-						p(image_path('core', 'actions/verified.svg'));
108
-						break;
109
-					default:
110
-						p(image_path('core', 'actions/verify.svg'));
111
-				}
112
-				?>">
102
+                switch($_['emailVerification']) {
103
+                    case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
104
+                        p(image_path('core', 'actions/verifying.svg'));
105
+                        break;
106
+                    case \OC\Accounts\AccountManager::VERIFIED:
107
+                        p(image_path('core', 'actions/verified.svg'));
108
+                        break;
109
+                    default:
110
+                        p(image_path('core', 'actions/verify.svg'));
111
+                }
112
+                ?>">
113 113
 			</div>
114 114
 			<input type="email" name="email" id="email" value="<?php if(!$_['displayNameChangeSupported'] && empty($_['email'])) p($l->t('No email address set')); else p($_['email']); ?>"
115 115
 				<?php if(!$_['displayNameChangeSupported']) { print_unescaped('disabled="1"'); } ?>
@@ -172,17 +172,17 @@  discard block
 block discarded – undo
172 172
 			<div class="verify <?php if ($_['website'] === ''  || $_['websiteScope'] !== 'public') p('hidden'); ?>">
173 173
 				<img id="verify-website" title="<?php p($_['websiteMessage']); ?>" data-status="<?php p($_['websiteVerification']) ?>" src="
174 174
 				<?php
175
-				switch($_['websiteVerification']) {
176
-					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
177
-						p(image_path('core', 'actions/verifying.svg'));
178
-						break;
179
-					case \OC\Accounts\AccountManager::VERIFIED:
180
-						p(image_path('core', 'actions/verified.svg'));
181
-						break;
182
-					default:
183
-						p(image_path('core', 'actions/verify.svg'));
184
-				}
185
-				?>"
175
+                switch($_['websiteVerification']) {
176
+                    case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
177
+                        p(image_path('core', 'actions/verifying.svg'));
178
+                        break;
179
+                    case \OC\Accounts\AccountManager::VERIFIED:
180
+                        p(image_path('core', 'actions/verified.svg'));
181
+                        break;
182
+                    default:
183
+                        p(image_path('core', 'actions/verify.svg'));
184
+                }
185
+                ?>"
186 186
 				<?php if($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
187 187
 				>
188 188
 				<div class="verification-dialog popovermenu bubble menu">
@@ -217,17 +217,17 @@  discard block
 block discarded – undo
217 217
 			<div class="verify <?php if ($_['twitter'] === ''  || $_['twitterScope'] !== 'public') p('hidden'); ?>">
218 218
 				<img id="verify-twitter" title="<?php p($_['twitterMessage']); ?>" data-status="<?php p($_['twitterVerification']) ?>" src="
219 219
 				<?php
220
-				switch($_['twitterVerification']) {
221
-					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
222
-						p(image_path('core', 'actions/verifying.svg'));
223
-						break;
224
-					case \OC\Accounts\AccountManager::VERIFIED:
225
-						p(image_path('core', 'actions/verified.svg'));
226
-						break;
227
-					default:
228
-						p(image_path('core', 'actions/verify.svg'));
229
-				}
230
-				?>"
220
+                switch($_['twitterVerification']) {
221
+                    case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
222
+                        p(image_path('core', 'actions/verifying.svg'));
223
+                        break;
224
+                    case \OC\Accounts\AccountManager::VERIFIED:
225
+                        p(image_path('core', 'actions/verified.svg'));
226
+                        break;
227
+                    default:
228
+                        p(image_path('core', 'actions/verify.svg'));
229
+                }
230
+                ?>"
231 231
 				<?php if($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
232 232
 				>
233 233
 				<div class="verification-dialog popovermenu bubble menu">
@@ -292,9 +292,9 @@  discard block
 block discarded – undo
292 292
 	</div>
293 293
 	<div class="personal-settings-setting-box personal-settings-password-box">
294 294
 		<?php
295
-		if($_['passwordChangeSupported']) {
296
-			script('jquery-showpassword');
297
-		?>
295
+        if($_['passwordChangeSupported']) {
296
+            script('jquery-showpassword');
297
+        ?>
298 298
 		<form id="passwordform" class="section">
299 299
 			<h2 class="inlineblock"><?php p($l->t('Password'));?></h2>
300 300
 			<div id="password-error-msg" class="msg success inlineblock" style="display: none;">Saved</div>
@@ -317,8 +317,8 @@  discard block
 block discarded – undo
317 317
 			<br/>
318 318
 		</form>
319 319
 		<?php
320
-		}
321
-		?>
320
+        }
321
+        ?>
322 322
 	</div>
323 323
 	<span class="msg"></span>
324 324
 </div>
@@ -344,15 +344,15 @@  discard block
 block discarded – undo
344 344
 
345 345
 		<p>
346 346
 			<?php print_unescaped(str_replace(
347
-				[
348
-					'{contributeopen}',
349
-					'{linkclose}',
350
-				],
351
-				[
352
-					'<a href="https://nextcloud.com/contribute" target="_blank" rel="noreferrer">',
353
-					'</a>',
354
-				],
355
-				$l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?>
347
+                [
348
+                    '{contributeopen}',
349
+                    '{linkclose}',
350
+                ],
351
+                [
352
+                    '<a href="https://nextcloud.com/contribute" target="_blank" rel="noreferrer">',
353
+                    '</a>',
354
+                ],
355
+                $l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?>
356 356
 		</p>
357 357
 
358 358
 	<?php if(OC_APP::isEnabled('firstrunwizard')) {?>
@@ -401,7 +401,7 @@  discard block
 block discarded – undo
401 401
 </div>
402 402
 
403 403
 <?php foreach($_['forms'] as $form) {
404
-	if (isset($form['form'])) {?>
404
+    if (isset($form['form'])) {?>
405 405
 	<div id="<?php isset($form['anchor']) ? p($form['anchor']) : p('');?>"><?php print_unescaped($form['form']);?></div>
406 406
 	<?php }
407 407
 };?>
Please login to merge, or discard this patch.