Passed
Push — master ( b3f59a...eecd46 )
by Julius
16:28 queued 12s
created
lib/private/Files/ObjectStore/ObjectStoreStorage.php 2 patches
Indentation   +662 added lines, -662 removed lines patch added patch discarded remove patch
@@ -48,669 +48,669 @@
 block discarded – undo
48 48
 use OCP\Files\Storage\IStorage;
49 49
 
50 50
 class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFileWrite {
51
-	use CopyDirectory;
52
-
53
-	/**
54
-	 * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
55
-	 */
56
-	protected $objectStore;
57
-	/**
58
-	 * @var string $id
59
-	 */
60
-	protected $id;
61
-	/**
62
-	 * @var \OC\User\User $user
63
-	 */
64
-	protected $user;
65
-
66
-	private $objectPrefix = 'urn:oid:';
67
-
68
-	private $logger;
69
-
70
-	/** @var bool */
71
-	protected $validateWrites = true;
72
-
73
-	public function __construct($params) {
74
-		if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
75
-			$this->objectStore = $params['objectstore'];
76
-		} else {
77
-			throw new \Exception('missing IObjectStore instance');
78
-		}
79
-		if (isset($params['storageid'])) {
80
-			$this->id = 'object::store:' . $params['storageid'];
81
-		} else {
82
-			$this->id = 'object::store:' . $this->objectStore->getStorageId();
83
-		}
84
-		if (isset($params['objectPrefix'])) {
85
-			$this->objectPrefix = $params['objectPrefix'];
86
-		}
87
-		if (isset($params['validateWrites'])) {
88
-			$this->validateWrites = (bool)$params['validateWrites'];
89
-		}
90
-		//initialize cache with root directory in cache
91
-		if (!$this->is_dir('/')) {
92
-			$this->mkdir('/');
93
-		}
94
-
95
-		$this->logger = \OC::$server->getLogger();
96
-	}
97
-
98
-	public function mkdir($path) {
99
-		$path = $this->normalizePath($path);
100
-		if ($this->file_exists($path)) {
101
-			return false;
102
-		}
103
-
104
-		$mTime = time();
105
-		$data = [
106
-			'mimetype' => 'httpd/unix-directory',
107
-			'size' => 0,
108
-			'mtime' => $mTime,
109
-			'storage_mtime' => $mTime,
110
-			'permissions' => \OCP\Constants::PERMISSION_ALL,
111
-		];
112
-		if ($path === '') {
113
-			//create root on the fly
114
-			$data['etag'] = $this->getETag('');
115
-			$this->getCache()->put('', $data);
116
-			return true;
117
-		} else {
118
-			// if parent does not exist, create it
119
-			$parent = $this->normalizePath(dirname($path));
120
-			$parentType = $this->filetype($parent);
121
-			if ($parentType === false) {
122
-				if (!$this->mkdir($parent)) {
123
-					// something went wrong
124
-					return false;
125
-				}
126
-			} elseif ($parentType === 'file') {
127
-				// parent is a file
128
-				return false;
129
-			}
130
-			// finally create the new dir
131
-			$mTime = time(); // update mtime
132
-			$data['mtime'] = $mTime;
133
-			$data['storage_mtime'] = $mTime;
134
-			$data['etag'] = $this->getETag($path);
135
-			$this->getCache()->put($path, $data);
136
-			return true;
137
-		}
138
-	}
139
-
140
-	/**
141
-	 * @param string $path
142
-	 * @return string
143
-	 */
144
-	private function normalizePath($path) {
145
-		$path = trim($path, '/');
146
-		//FIXME why do we sometimes get a path like 'files//username'?
147
-		$path = str_replace('//', '/', $path);
148
-
149
-		// dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
150
-		if (!$path || $path === '.') {
151
-			$path = '';
152
-		}
153
-
154
-		return $path;
155
-	}
156
-
157
-	/**
158
-	 * Object Stores use a NoopScanner because metadata is directly stored in
159
-	 * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
160
-	 *
161
-	 * @param string $path
162
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
163
-	 * @return \OC\Files\ObjectStore\NoopScanner
164
-	 */
165
-	public function getScanner($path = '', $storage = null) {
166
-		if (!$storage) {
167
-			$storage = $this;
168
-		}
169
-		if (!isset($this->scanner)) {
170
-			$this->scanner = new NoopScanner($storage);
171
-		}
172
-		return $this->scanner;
173
-	}
174
-
175
-	public function getId() {
176
-		return $this->id;
177
-	}
178
-
179
-	public function rmdir($path) {
180
-		$path = $this->normalizePath($path);
181
-		$entry = $this->getCache()->get($path);
182
-
183
-		if (!$entry || $entry->getMimeType() !== ICacheEntry::DIRECTORY_MIMETYPE) {
184
-			return false;
185
-		}
186
-
187
-		return $this->rmObjects($entry);
188
-	}
189
-
190
-	private function rmObjects(ICacheEntry $entry): bool {
191
-		$children = $this->getCache()->getFolderContentsById($entry->getId());
192
-		foreach ($children as $child) {
193
-			if ($child->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE) {
194
-				if (!$this->rmObjects($child)) {
195
-					return false;
196
-				}
197
-			} else {
198
-				if (!$this->rmObject($child)) {
199
-					return false;
200
-				}
201
-			}
202
-		}
203
-
204
-		$this->getCache()->remove($entry->getPath());
205
-
206
-		return true;
207
-	}
208
-
209
-	public function unlink($path) {
210
-		$path = $this->normalizePath($path);
211
-		$entry = $this->getCache()->get($path);
212
-
213
-		if ($entry instanceof ICacheEntry) {
214
-			if ($entry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE) {
215
-				return $this->rmObjects($entry);
216
-			} else {
217
-				return $this->rmObject($entry);
218
-			}
219
-		}
220
-		return false;
221
-	}
222
-
223
-	public function rmObject(ICacheEntry $entry): bool {
224
-		try {
225
-			$this->objectStore->deleteObject($this->getURN($entry->getId()));
226
-		} catch (\Exception $ex) {
227
-			if ($ex->getCode() !== 404) {
228
-				$this->logger->logException($ex, [
229
-					'app' => 'objectstore',
230
-					'message' => 'Could not delete object ' . $this->getURN($entry->getId()) . ' for ' . $entry->getPath(),
231
-				]);
232
-				return false;
233
-			}
234
-			//removing from cache is ok as it does not exist in the objectstore anyway
235
-		}
236
-		$this->getCache()->remove($entry->getPath());
237
-		return true;
238
-	}
239
-
240
-	public function stat($path) {
241
-		$path = $this->normalizePath($path);
242
-		$cacheEntry = $this->getCache()->get($path);
243
-		if ($cacheEntry instanceof CacheEntry) {
244
-			return $cacheEntry->getData();
245
-		} else {
246
-			return false;
247
-		}
248
-	}
249
-
250
-	public function getPermissions($path) {
251
-		$stat = $this->stat($path);
252
-
253
-		if (is_array($stat) && isset($stat['permissions'])) {
254
-			return $stat['permissions'];
255
-		}
256
-
257
-		return parent::getPermissions($path);
258
-	}
259
-
260
-	/**
261
-	 * Override this method if you need a different unique resource identifier for your object storage implementation.
262
-	 * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
263
-	 * You may need a mapping table to store your URN if it cannot be generated from the fileid.
264
-	 *
265
-	 * @param int $fileId the fileid
266
-	 * @return null|string the unified resource name used to identify the object
267
-	 */
268
-	public function getURN($fileId) {
269
-		if (is_numeric($fileId)) {
270
-			return $this->objectPrefix . $fileId;
271
-		}
272
-		return null;
273
-	}
274
-
275
-	public function opendir($path) {
276
-		$path = $this->normalizePath($path);
277
-
278
-		try {
279
-			$files = [];
280
-			$folderContents = $this->getCache()->getFolderContents($path);
281
-			foreach ($folderContents as $file) {
282
-				$files[] = $file['name'];
283
-			}
284
-
285
-			return IteratorDirectory::wrap($files);
286
-		} catch (\Exception $e) {
287
-			$this->logger->logException($e);
288
-			return false;
289
-		}
290
-	}
291
-
292
-	public function filetype($path) {
293
-		$path = $this->normalizePath($path);
294
-		$stat = $this->stat($path);
295
-		if ($stat) {
296
-			if ($stat['mimetype'] === 'httpd/unix-directory') {
297
-				return 'dir';
298
-			}
299
-			return 'file';
300
-		} else {
301
-			return false;
302
-		}
303
-	}
304
-
305
-	public function fopen($path, $mode) {
306
-		$path = $this->normalizePath($path);
307
-
308
-		if (strrpos($path, '.') !== false) {
309
-			$ext = substr($path, strrpos($path, '.'));
310
-		} else {
311
-			$ext = '';
312
-		}
313
-
314
-		switch ($mode) {
315
-			case 'r':
316
-			case 'rb':
317
-				$stat = $this->stat($path);
318
-				if (is_array($stat)) {
319
-					$filesize = $stat['size'] ?? 0;
320
-					// Reading 0 sized files is a waste of time
321
-					if ($filesize === 0) {
322
-						return fopen('php://memory', $mode);
323
-					}
324
-
325
-					try {
326
-						$handle = $this->objectStore->readObject($this->getURN($stat['fileid']));
327
-						if ($handle === false) {
328
-							return false; // keep backward compatibility
329
-						}
330
-						$streamStat = fstat($handle);
331
-						$actualSize = $streamStat['size'] ?? -1;
332
-						if ($actualSize > -1 && $actualSize !== $filesize) {
333
-							$this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]);
334
-						}
335
-						return $handle;
336
-					} catch (NotFoundException $e) {
337
-						$this->logger->logException($e, [
338
-							'app' => 'objectstore',
339
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
340
-						]);
341
-						throw $e;
342
-					} catch (\Exception $ex) {
343
-						$this->logger->logException($ex, [
344
-							'app' => 'objectstore',
345
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
346
-						]);
347
-						return false;
348
-					}
349
-				} else {
350
-					return false;
351
-				}
352
-				// no break
353
-			case 'w':
354
-			case 'wb':
355
-			case 'w+':
356
-			case 'wb+':
357
-				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
358
-				$handle = fopen($tmpFile, $mode);
359
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
360
-					$this->writeBack($tmpFile, $path);
361
-					unlink($tmpFile);
362
-				});
363
-			case 'a':
364
-			case 'ab':
365
-			case 'r+':
366
-			case 'a+':
367
-			case 'x':
368
-			case 'x+':
369
-			case 'c':
370
-			case 'c+':
371
-				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
372
-				if ($this->file_exists($path)) {
373
-					$source = $this->fopen($path, 'r');
374
-					file_put_contents($tmpFile, $source);
375
-				}
376
-				$handle = fopen($tmpFile, $mode);
377
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
378
-					$this->writeBack($tmpFile, $path);
379
-					unlink($tmpFile);
380
-				});
381
-		}
382
-		return false;
383
-	}
384
-
385
-	public function file_exists($path) {
386
-		$path = $this->normalizePath($path);
387
-		return (bool)$this->stat($path);
388
-	}
389
-
390
-	public function rename($source, $target) {
391
-		$source = $this->normalizePath($source);
392
-		$target = $this->normalizePath($target);
393
-		$this->remove($target);
394
-		$this->getCache()->move($source, $target);
395
-		$this->touch(dirname($target));
396
-		return true;
397
-	}
398
-
399
-	public function getMimeType($path) {
400
-		$path = $this->normalizePath($path);
401
-		return parent::getMimeType($path);
402
-	}
403
-
404
-	public function touch($path, $mtime = null) {
405
-		if (is_null($mtime)) {
406
-			$mtime = time();
407
-		}
408
-
409
-		$path = $this->normalizePath($path);
410
-		$dirName = dirname($path);
411
-		$parentExists = $this->is_dir($dirName);
412
-		if (!$parentExists) {
413
-			return false;
414
-		}
415
-
416
-		$stat = $this->stat($path);
417
-		if (is_array($stat)) {
418
-			// update existing mtime in db
419
-			$stat['mtime'] = $mtime;
420
-			$this->getCache()->update($stat['fileid'], $stat);
421
-		} else {
422
-			try {
423
-				//create a empty file, need to have at least on char to make it
424
-				// work with all object storage implementations
425
-				$this->file_put_contents($path, ' ');
426
-				$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
427
-				$stat = [
428
-					'etag' => $this->getETag($path),
429
-					'mimetype' => $mimeType,
430
-					'size' => 0,
431
-					'mtime' => $mtime,
432
-					'storage_mtime' => $mtime,
433
-					'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
434
-				];
435
-				$this->getCache()->put($path, $stat);
436
-			} catch (\Exception $ex) {
437
-				$this->logger->logException($ex, [
438
-					'app' => 'objectstore',
439
-					'message' => 'Could not create object for ' . $path,
440
-				]);
441
-				throw $ex;
442
-			}
443
-		}
444
-		return true;
445
-	}
446
-
447
-	public function writeBack($tmpFile, $path) {
448
-		$size = filesize($tmpFile);
449
-		$this->writeStream($path, fopen($tmpFile, 'r'), $size);
450
-	}
451
-
452
-	/**
453
-	 * external changes are not supported, exclusive access to the object storage is assumed
454
-	 *
455
-	 * @param string $path
456
-	 * @param int $time
457
-	 * @return false
458
-	 */
459
-	public function hasUpdated($path, $time) {
460
-		return false;
461
-	}
462
-
463
-	public function needsPartFile() {
464
-		return false;
465
-	}
466
-
467
-	public function file_put_contents($path, $data) {
468
-		$handle = $this->fopen($path, 'w+');
469
-		$result = fwrite($handle, $data);
470
-		fclose($handle);
471
-		return $result;
472
-	}
473
-
474
-	public function writeStream(string $path, $stream, int $size = null): int {
475
-		$stat = $this->stat($path);
476
-		if (empty($stat)) {
477
-			// create new file
478
-			$stat = [
479
-				'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
480
-			];
481
-		}
482
-		// update stat with new data
483
-		$mTime = time();
484
-		$stat['size'] = (int)$size;
485
-		$stat['mtime'] = $mTime;
486
-		$stat['storage_mtime'] = $mTime;
487
-
488
-		$mimetypeDetector = \OC::$server->getMimeTypeDetector();
489
-		$mimetype = $mimetypeDetector->detectPath($path);
490
-
491
-		$stat['mimetype'] = $mimetype;
492
-		$stat['etag'] = $this->getETag($path);
493
-		$stat['checksum'] = '';
494
-
495
-		$exists = $this->getCache()->inCache($path);
496
-		$uploadPath = $exists ? $path : $path . '.part';
497
-
498
-		if ($exists) {
499
-			$fileId = $stat['fileid'];
500
-		} else {
501
-			$fileId = $this->getCache()->put($uploadPath, $stat);
502
-		}
503
-
504
-		$urn = $this->getURN($fileId);
505
-		try {
506
-			//upload to object storage
507
-			if ($size === null) {
508
-				$countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) {
509
-					$this->getCache()->update($fileId, [
510
-						'size' => $writtenSize,
511
-					]);
512
-					$size = $writtenSize;
513
-				});
514
-				$this->objectStore->writeObject($urn, $countStream, $mimetype);
515
-				if (is_resource($countStream)) {
516
-					fclose($countStream);
517
-				}
518
-				$stat['size'] = $size;
519
-			} else {
520
-				$this->objectStore->writeObject($urn, $stream, $mimetype);
521
-				if (is_resource($stream)) {
522
-					fclose($stream);
523
-				}
524
-			}
525
-		} catch (\Exception $ex) {
526
-			if (!$exists) {
527
-				/*
51
+    use CopyDirectory;
52
+
53
+    /**
54
+     * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
55
+     */
56
+    protected $objectStore;
57
+    /**
58
+     * @var string $id
59
+     */
60
+    protected $id;
61
+    /**
62
+     * @var \OC\User\User $user
63
+     */
64
+    protected $user;
65
+
66
+    private $objectPrefix = 'urn:oid:';
67
+
68
+    private $logger;
69
+
70
+    /** @var bool */
71
+    protected $validateWrites = true;
72
+
73
+    public function __construct($params) {
74
+        if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
75
+            $this->objectStore = $params['objectstore'];
76
+        } else {
77
+            throw new \Exception('missing IObjectStore instance');
78
+        }
79
+        if (isset($params['storageid'])) {
80
+            $this->id = 'object::store:' . $params['storageid'];
81
+        } else {
82
+            $this->id = 'object::store:' . $this->objectStore->getStorageId();
83
+        }
84
+        if (isset($params['objectPrefix'])) {
85
+            $this->objectPrefix = $params['objectPrefix'];
86
+        }
87
+        if (isset($params['validateWrites'])) {
88
+            $this->validateWrites = (bool)$params['validateWrites'];
89
+        }
90
+        //initialize cache with root directory in cache
91
+        if (!$this->is_dir('/')) {
92
+            $this->mkdir('/');
93
+        }
94
+
95
+        $this->logger = \OC::$server->getLogger();
96
+    }
97
+
98
+    public function mkdir($path) {
99
+        $path = $this->normalizePath($path);
100
+        if ($this->file_exists($path)) {
101
+            return false;
102
+        }
103
+
104
+        $mTime = time();
105
+        $data = [
106
+            'mimetype' => 'httpd/unix-directory',
107
+            'size' => 0,
108
+            'mtime' => $mTime,
109
+            'storage_mtime' => $mTime,
110
+            'permissions' => \OCP\Constants::PERMISSION_ALL,
111
+        ];
112
+        if ($path === '') {
113
+            //create root on the fly
114
+            $data['etag'] = $this->getETag('');
115
+            $this->getCache()->put('', $data);
116
+            return true;
117
+        } else {
118
+            // if parent does not exist, create it
119
+            $parent = $this->normalizePath(dirname($path));
120
+            $parentType = $this->filetype($parent);
121
+            if ($parentType === false) {
122
+                if (!$this->mkdir($parent)) {
123
+                    // something went wrong
124
+                    return false;
125
+                }
126
+            } elseif ($parentType === 'file') {
127
+                // parent is a file
128
+                return false;
129
+            }
130
+            // finally create the new dir
131
+            $mTime = time(); // update mtime
132
+            $data['mtime'] = $mTime;
133
+            $data['storage_mtime'] = $mTime;
134
+            $data['etag'] = $this->getETag($path);
135
+            $this->getCache()->put($path, $data);
136
+            return true;
137
+        }
138
+    }
139
+
140
+    /**
141
+     * @param string $path
142
+     * @return string
143
+     */
144
+    private function normalizePath($path) {
145
+        $path = trim($path, '/');
146
+        //FIXME why do we sometimes get a path like 'files//username'?
147
+        $path = str_replace('//', '/', $path);
148
+
149
+        // dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
150
+        if (!$path || $path === '.') {
151
+            $path = '';
152
+        }
153
+
154
+        return $path;
155
+    }
156
+
157
+    /**
158
+     * Object Stores use a NoopScanner because metadata is directly stored in
159
+     * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
160
+     *
161
+     * @param string $path
162
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
163
+     * @return \OC\Files\ObjectStore\NoopScanner
164
+     */
165
+    public function getScanner($path = '', $storage = null) {
166
+        if (!$storage) {
167
+            $storage = $this;
168
+        }
169
+        if (!isset($this->scanner)) {
170
+            $this->scanner = new NoopScanner($storage);
171
+        }
172
+        return $this->scanner;
173
+    }
174
+
175
+    public function getId() {
176
+        return $this->id;
177
+    }
178
+
179
+    public function rmdir($path) {
180
+        $path = $this->normalizePath($path);
181
+        $entry = $this->getCache()->get($path);
182
+
183
+        if (!$entry || $entry->getMimeType() !== ICacheEntry::DIRECTORY_MIMETYPE) {
184
+            return false;
185
+        }
186
+
187
+        return $this->rmObjects($entry);
188
+    }
189
+
190
+    private function rmObjects(ICacheEntry $entry): bool {
191
+        $children = $this->getCache()->getFolderContentsById($entry->getId());
192
+        foreach ($children as $child) {
193
+            if ($child->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE) {
194
+                if (!$this->rmObjects($child)) {
195
+                    return false;
196
+                }
197
+            } else {
198
+                if (!$this->rmObject($child)) {
199
+                    return false;
200
+                }
201
+            }
202
+        }
203
+
204
+        $this->getCache()->remove($entry->getPath());
205
+
206
+        return true;
207
+    }
208
+
209
+    public function unlink($path) {
210
+        $path = $this->normalizePath($path);
211
+        $entry = $this->getCache()->get($path);
212
+
213
+        if ($entry instanceof ICacheEntry) {
214
+            if ($entry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE) {
215
+                return $this->rmObjects($entry);
216
+            } else {
217
+                return $this->rmObject($entry);
218
+            }
219
+        }
220
+        return false;
221
+    }
222
+
223
+    public function rmObject(ICacheEntry $entry): bool {
224
+        try {
225
+            $this->objectStore->deleteObject($this->getURN($entry->getId()));
226
+        } catch (\Exception $ex) {
227
+            if ($ex->getCode() !== 404) {
228
+                $this->logger->logException($ex, [
229
+                    'app' => 'objectstore',
230
+                    'message' => 'Could not delete object ' . $this->getURN($entry->getId()) . ' for ' . $entry->getPath(),
231
+                ]);
232
+                return false;
233
+            }
234
+            //removing from cache is ok as it does not exist in the objectstore anyway
235
+        }
236
+        $this->getCache()->remove($entry->getPath());
237
+        return true;
238
+    }
239
+
240
+    public function stat($path) {
241
+        $path = $this->normalizePath($path);
242
+        $cacheEntry = $this->getCache()->get($path);
243
+        if ($cacheEntry instanceof CacheEntry) {
244
+            return $cacheEntry->getData();
245
+        } else {
246
+            return false;
247
+        }
248
+    }
249
+
250
+    public function getPermissions($path) {
251
+        $stat = $this->stat($path);
252
+
253
+        if (is_array($stat) && isset($stat['permissions'])) {
254
+            return $stat['permissions'];
255
+        }
256
+
257
+        return parent::getPermissions($path);
258
+    }
259
+
260
+    /**
261
+     * Override this method if you need a different unique resource identifier for your object storage implementation.
262
+     * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
263
+     * You may need a mapping table to store your URN if it cannot be generated from the fileid.
264
+     *
265
+     * @param int $fileId the fileid
266
+     * @return null|string the unified resource name used to identify the object
267
+     */
268
+    public function getURN($fileId) {
269
+        if (is_numeric($fileId)) {
270
+            return $this->objectPrefix . $fileId;
271
+        }
272
+        return null;
273
+    }
274
+
275
+    public function opendir($path) {
276
+        $path = $this->normalizePath($path);
277
+
278
+        try {
279
+            $files = [];
280
+            $folderContents = $this->getCache()->getFolderContents($path);
281
+            foreach ($folderContents as $file) {
282
+                $files[] = $file['name'];
283
+            }
284
+
285
+            return IteratorDirectory::wrap($files);
286
+        } catch (\Exception $e) {
287
+            $this->logger->logException($e);
288
+            return false;
289
+        }
290
+    }
291
+
292
+    public function filetype($path) {
293
+        $path = $this->normalizePath($path);
294
+        $stat = $this->stat($path);
295
+        if ($stat) {
296
+            if ($stat['mimetype'] === 'httpd/unix-directory') {
297
+                return 'dir';
298
+            }
299
+            return 'file';
300
+        } else {
301
+            return false;
302
+        }
303
+    }
304
+
305
+    public function fopen($path, $mode) {
306
+        $path = $this->normalizePath($path);
307
+
308
+        if (strrpos($path, '.') !== false) {
309
+            $ext = substr($path, strrpos($path, '.'));
310
+        } else {
311
+            $ext = '';
312
+        }
313
+
314
+        switch ($mode) {
315
+            case 'r':
316
+            case 'rb':
317
+                $stat = $this->stat($path);
318
+                if (is_array($stat)) {
319
+                    $filesize = $stat['size'] ?? 0;
320
+                    // Reading 0 sized files is a waste of time
321
+                    if ($filesize === 0) {
322
+                        return fopen('php://memory', $mode);
323
+                    }
324
+
325
+                    try {
326
+                        $handle = $this->objectStore->readObject($this->getURN($stat['fileid']));
327
+                        if ($handle === false) {
328
+                            return false; // keep backward compatibility
329
+                        }
330
+                        $streamStat = fstat($handle);
331
+                        $actualSize = $streamStat['size'] ?? -1;
332
+                        if ($actualSize > -1 && $actualSize !== $filesize) {
333
+                            $this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]);
334
+                        }
335
+                        return $handle;
336
+                    } catch (NotFoundException $e) {
337
+                        $this->logger->logException($e, [
338
+                            'app' => 'objectstore',
339
+                            'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
340
+                        ]);
341
+                        throw $e;
342
+                    } catch (\Exception $ex) {
343
+                        $this->logger->logException($ex, [
344
+                            'app' => 'objectstore',
345
+                            'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
346
+                        ]);
347
+                        return false;
348
+                    }
349
+                } else {
350
+                    return false;
351
+                }
352
+                // no break
353
+            case 'w':
354
+            case 'wb':
355
+            case 'w+':
356
+            case 'wb+':
357
+                $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
358
+                $handle = fopen($tmpFile, $mode);
359
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
360
+                    $this->writeBack($tmpFile, $path);
361
+                    unlink($tmpFile);
362
+                });
363
+            case 'a':
364
+            case 'ab':
365
+            case 'r+':
366
+            case 'a+':
367
+            case 'x':
368
+            case 'x+':
369
+            case 'c':
370
+            case 'c+':
371
+                $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
372
+                if ($this->file_exists($path)) {
373
+                    $source = $this->fopen($path, 'r');
374
+                    file_put_contents($tmpFile, $source);
375
+                }
376
+                $handle = fopen($tmpFile, $mode);
377
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
378
+                    $this->writeBack($tmpFile, $path);
379
+                    unlink($tmpFile);
380
+                });
381
+        }
382
+        return false;
383
+    }
384
+
385
+    public function file_exists($path) {
386
+        $path = $this->normalizePath($path);
387
+        return (bool)$this->stat($path);
388
+    }
389
+
390
+    public function rename($source, $target) {
391
+        $source = $this->normalizePath($source);
392
+        $target = $this->normalizePath($target);
393
+        $this->remove($target);
394
+        $this->getCache()->move($source, $target);
395
+        $this->touch(dirname($target));
396
+        return true;
397
+    }
398
+
399
+    public function getMimeType($path) {
400
+        $path = $this->normalizePath($path);
401
+        return parent::getMimeType($path);
402
+    }
403
+
404
+    public function touch($path, $mtime = null) {
405
+        if (is_null($mtime)) {
406
+            $mtime = time();
407
+        }
408
+
409
+        $path = $this->normalizePath($path);
410
+        $dirName = dirname($path);
411
+        $parentExists = $this->is_dir($dirName);
412
+        if (!$parentExists) {
413
+            return false;
414
+        }
415
+
416
+        $stat = $this->stat($path);
417
+        if (is_array($stat)) {
418
+            // update existing mtime in db
419
+            $stat['mtime'] = $mtime;
420
+            $this->getCache()->update($stat['fileid'], $stat);
421
+        } else {
422
+            try {
423
+                //create a empty file, need to have at least on char to make it
424
+                // work with all object storage implementations
425
+                $this->file_put_contents($path, ' ');
426
+                $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
427
+                $stat = [
428
+                    'etag' => $this->getETag($path),
429
+                    'mimetype' => $mimeType,
430
+                    'size' => 0,
431
+                    'mtime' => $mtime,
432
+                    'storage_mtime' => $mtime,
433
+                    'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
434
+                ];
435
+                $this->getCache()->put($path, $stat);
436
+            } catch (\Exception $ex) {
437
+                $this->logger->logException($ex, [
438
+                    'app' => 'objectstore',
439
+                    'message' => 'Could not create object for ' . $path,
440
+                ]);
441
+                throw $ex;
442
+            }
443
+        }
444
+        return true;
445
+    }
446
+
447
+    public function writeBack($tmpFile, $path) {
448
+        $size = filesize($tmpFile);
449
+        $this->writeStream($path, fopen($tmpFile, 'r'), $size);
450
+    }
451
+
452
+    /**
453
+     * external changes are not supported, exclusive access to the object storage is assumed
454
+     *
455
+     * @param string $path
456
+     * @param int $time
457
+     * @return false
458
+     */
459
+    public function hasUpdated($path, $time) {
460
+        return false;
461
+    }
462
+
463
+    public function needsPartFile() {
464
+        return false;
465
+    }
466
+
467
+    public function file_put_contents($path, $data) {
468
+        $handle = $this->fopen($path, 'w+');
469
+        $result = fwrite($handle, $data);
470
+        fclose($handle);
471
+        return $result;
472
+    }
473
+
474
+    public function writeStream(string $path, $stream, int $size = null): int {
475
+        $stat = $this->stat($path);
476
+        if (empty($stat)) {
477
+            // create new file
478
+            $stat = [
479
+                'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
480
+            ];
481
+        }
482
+        // update stat with new data
483
+        $mTime = time();
484
+        $stat['size'] = (int)$size;
485
+        $stat['mtime'] = $mTime;
486
+        $stat['storage_mtime'] = $mTime;
487
+
488
+        $mimetypeDetector = \OC::$server->getMimeTypeDetector();
489
+        $mimetype = $mimetypeDetector->detectPath($path);
490
+
491
+        $stat['mimetype'] = $mimetype;
492
+        $stat['etag'] = $this->getETag($path);
493
+        $stat['checksum'] = '';
494
+
495
+        $exists = $this->getCache()->inCache($path);
496
+        $uploadPath = $exists ? $path : $path . '.part';
497
+
498
+        if ($exists) {
499
+            $fileId = $stat['fileid'];
500
+        } else {
501
+            $fileId = $this->getCache()->put($uploadPath, $stat);
502
+        }
503
+
504
+        $urn = $this->getURN($fileId);
505
+        try {
506
+            //upload to object storage
507
+            if ($size === null) {
508
+                $countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) {
509
+                    $this->getCache()->update($fileId, [
510
+                        'size' => $writtenSize,
511
+                    ]);
512
+                    $size = $writtenSize;
513
+                });
514
+                $this->objectStore->writeObject($urn, $countStream, $mimetype);
515
+                if (is_resource($countStream)) {
516
+                    fclose($countStream);
517
+                }
518
+                $stat['size'] = $size;
519
+            } else {
520
+                $this->objectStore->writeObject($urn, $stream, $mimetype);
521
+                if (is_resource($stream)) {
522
+                    fclose($stream);
523
+                }
524
+            }
525
+        } catch (\Exception $ex) {
526
+            if (!$exists) {
527
+                /*
528 528
 				 * Only remove the entry if we are dealing with a new file.
529 529
 				 * Else people lose access to existing files
530 530
 				 */
531
-				$this->getCache()->remove($uploadPath);
532
-				$this->logger->logException($ex, [
533
-					'app' => 'objectstore',
534
-					'message' => 'Could not create object ' . $urn . ' for ' . $path,
535
-				]);
536
-			} else {
537
-				$this->logger->logException($ex, [
538
-					'app' => 'objectstore',
539
-					'message' => 'Could not update object ' . $urn . ' for ' . $path,
540
-				]);
541
-			}
542
-			throw $ex; // make this bubble up
543
-		}
544
-
545
-		if ($exists) {
546
-			$this->getCache()->update($fileId, $stat);
547
-		} else {
548
-			if (!$this->validateWrites || $this->objectStore->objectExists($urn)) {
549
-				$this->getCache()->move($uploadPath, $path);
550
-			} else {
551
-				$this->getCache()->remove($uploadPath);
552
-				throw new \Exception("Object not found after writing (urn: $urn, path: $path)", 404);
553
-			}
554
-		}
555
-
556
-		return $size;
557
-	}
558
-
559
-	public function getObjectStore(): IObjectStore {
560
-		return $this->objectStore;
561
-	}
562
-
563
-	public function copyFromStorage(
564
-		IStorage $sourceStorage,
565
-		$sourceInternalPath,
566
-		$targetInternalPath,
567
-		$preserveMtime = false
568
-	) {
569
-		if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
570
-			/** @var ObjectStoreStorage $sourceStorage */
571
-			if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
572
-				/** @var CacheEntry $sourceEntry */
573
-				$sourceEntry = $sourceStorage->getCache()->get($sourceInternalPath);
574
-				$sourceEntryData = $sourceEntry->getData();
575
-				// $sourceEntry['permissions'] here is the permissions from the jailed storage for the current
576
-				// user. Instead we use $sourceEntryData['scan_permissions'] that are the permissions from the
577
-				// unjailed storage.
578
-				if (is_array($sourceEntryData) && array_key_exists('scan_permissions', $sourceEntryData)) {
579
-					$sourceEntry['permissions'] = $sourceEntryData['scan_permissions'];
580
-				}
581
-				$this->copyInner($sourceEntry, $targetInternalPath);
582
-				return true;
583
-			}
584
-		}
585
-
586
-		return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
587
-	}
588
-
589
-	public function copy($source, $target) {
590
-		$source = $this->normalizePath($source);
591
-		$target = $this->normalizePath($target);
592
-
593
-		$cache = $this->getCache();
594
-		$sourceEntry = $cache->get($source);
595
-		if (!$sourceEntry) {
596
-			throw new NotFoundException('Source object not found');
597
-		}
598
-
599
-		$this->copyInner($sourceEntry, $target);
600
-
601
-		return true;
602
-	}
603
-
604
-	private function copyInner(ICacheEntry $sourceEntry, string $to) {
605
-		$cache = $this->getCache();
606
-
607
-		if ($sourceEntry->getMimeType() === FileInfo::MIMETYPE_FOLDER) {
608
-			if ($cache->inCache($to)) {
609
-				$cache->remove($to);
610
-			}
611
-			$this->mkdir($to);
612
-
613
-			foreach ($cache->getFolderContentsById($sourceEntry->getId()) as $child) {
614
-				$this->copyInner($child, $to . '/' . $child->getName());
615
-			}
616
-		} else {
617
-			$this->copyFile($sourceEntry, $to);
618
-		}
619
-	}
620
-
621
-	private function copyFile(ICacheEntry $sourceEntry, string $to) {
622
-		$cache = $this->getCache();
623
-
624
-		$sourceUrn = $this->getURN($sourceEntry->getId());
625
-
626
-		if (!$cache instanceof Cache) {
627
-			throw new \Exception("Invalid source cache for object store copy");
628
-		}
629
-
630
-		$targetId = $cache->copyFromCache($cache, $sourceEntry, $to);
631
-
632
-		$targetUrn = $this->getURN($targetId);
633
-
634
-		try {
635
-			$this->objectStore->copyObject($sourceUrn, $targetUrn);
636
-		} catch (\Exception $e) {
637
-			$cache->remove($to);
638
-
639
-			throw $e;
640
-		}
641
-	}
642
-
643
-	public function startChunkedWrite(string $targetPath): string {
644
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
645
-			throw new GenericFileException('Object store does not support multipart upload');
646
-		}
647
-		$cacheEntry = $this->getCache()->get($targetPath);
648
-		$urn = $this->getURN($cacheEntry->getId());
649
-		return $this->objectStore->initiateMultipartUpload($urn);
650
-	}
651
-
652
-	/**
653
-	 *
654
-	 * @throws GenericFileException
655
-	 */
656
-	public function putChunkedWritePart(
657
-		string $targetPath,
658
-		string $writeToken,
659
-		string $chunkId,
660
-		$data,
661
-		$size = null
662
-	): ?array {
663
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
664
-			throw new GenericFileException('Object store does not support multipart upload');
665
-		}
666
-		$cacheEntry = $this->getCache()->get($targetPath);
667
-		$urn = $this->getURN($cacheEntry->getId());
668
-
669
-		$result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int)$chunkId, $data, $size);
670
-
671
-		$parts[$chunkId] = [
672
-			'PartNumber' => $chunkId,
673
-			'ETag' => trim($result->get('ETag'), '"'),
674
-		];
675
-		return $parts[$chunkId];
676
-	}
677
-
678
-	public function completeChunkedWrite(string $targetPath, string $writeToken): int {
679
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
680
-			throw new GenericFileException('Object store does not support multipart upload');
681
-		}
682
-		$cacheEntry = $this->getCache()->get($targetPath);
683
-		$urn = $this->getURN($cacheEntry->getId());
684
-		$parts = $this->objectStore->getMultipartUploads($urn, $writeToken);
685
-		$sortedParts = array_values($parts);
686
-		sort($sortedParts);
687
-		try {
688
-			$size = $this->objectStore->completeMultipartUpload($urn, $writeToken, $sortedParts);
689
-			$stat = $this->stat($targetPath);
690
-			$mtime = time();
691
-			if (is_array($stat)) {
692
-				$stat['size'] = $size;
693
-				$stat['mtime'] = $mtime;
694
-				$stat['mimetype'] = $this->getMimeType($targetPath);
695
-				$this->getCache()->update($stat['fileid'], $stat);
696
-			}
697
-		} catch (S3MultipartUploadException|S3Exception $e) {
698
-			$this->objectStore->abortMultipartUpload($urn, $writeToken);
699
-			$this->logger->logException($e, [
700
-				'app' => 'objectstore',
701
-				'message' => 'Could not compete multipart upload ' . $urn . ' with uploadId ' . $writeToken,
702
-			]);
703
-			throw new GenericFileException('Could not write chunked file');
704
-		}
705
-		return $size;
706
-	}
707
-
708
-	public function cancelChunkedWrite(string $targetPath, string $writeToken): void {
709
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
710
-			throw new GenericFileException('Object store does not support multipart upload');
711
-		}
712
-		$cacheEntry = $this->getCache()->get($targetPath);
713
-		$urn = $this->getURN($cacheEntry->getId());
714
-		$this->objectStore->abortMultipartUpload($urn, $writeToken);
715
-	}
531
+                $this->getCache()->remove($uploadPath);
532
+                $this->logger->logException($ex, [
533
+                    'app' => 'objectstore',
534
+                    'message' => 'Could not create object ' . $urn . ' for ' . $path,
535
+                ]);
536
+            } else {
537
+                $this->logger->logException($ex, [
538
+                    'app' => 'objectstore',
539
+                    'message' => 'Could not update object ' . $urn . ' for ' . $path,
540
+                ]);
541
+            }
542
+            throw $ex; // make this bubble up
543
+        }
544
+
545
+        if ($exists) {
546
+            $this->getCache()->update($fileId, $stat);
547
+        } else {
548
+            if (!$this->validateWrites || $this->objectStore->objectExists($urn)) {
549
+                $this->getCache()->move($uploadPath, $path);
550
+            } else {
551
+                $this->getCache()->remove($uploadPath);
552
+                throw new \Exception("Object not found after writing (urn: $urn, path: $path)", 404);
553
+            }
554
+        }
555
+
556
+        return $size;
557
+    }
558
+
559
+    public function getObjectStore(): IObjectStore {
560
+        return $this->objectStore;
561
+    }
562
+
563
+    public function copyFromStorage(
564
+        IStorage $sourceStorage,
565
+        $sourceInternalPath,
566
+        $targetInternalPath,
567
+        $preserveMtime = false
568
+    ) {
569
+        if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
570
+            /** @var ObjectStoreStorage $sourceStorage */
571
+            if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
572
+                /** @var CacheEntry $sourceEntry */
573
+                $sourceEntry = $sourceStorage->getCache()->get($sourceInternalPath);
574
+                $sourceEntryData = $sourceEntry->getData();
575
+                // $sourceEntry['permissions'] here is the permissions from the jailed storage for the current
576
+                // user. Instead we use $sourceEntryData['scan_permissions'] that are the permissions from the
577
+                // unjailed storage.
578
+                if (is_array($sourceEntryData) && array_key_exists('scan_permissions', $sourceEntryData)) {
579
+                    $sourceEntry['permissions'] = $sourceEntryData['scan_permissions'];
580
+                }
581
+                $this->copyInner($sourceEntry, $targetInternalPath);
582
+                return true;
583
+            }
584
+        }
585
+
586
+        return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
587
+    }
588
+
589
+    public function copy($source, $target) {
590
+        $source = $this->normalizePath($source);
591
+        $target = $this->normalizePath($target);
592
+
593
+        $cache = $this->getCache();
594
+        $sourceEntry = $cache->get($source);
595
+        if (!$sourceEntry) {
596
+            throw new NotFoundException('Source object not found');
597
+        }
598
+
599
+        $this->copyInner($sourceEntry, $target);
600
+
601
+        return true;
602
+    }
603
+
604
+    private function copyInner(ICacheEntry $sourceEntry, string $to) {
605
+        $cache = $this->getCache();
606
+
607
+        if ($sourceEntry->getMimeType() === FileInfo::MIMETYPE_FOLDER) {
608
+            if ($cache->inCache($to)) {
609
+                $cache->remove($to);
610
+            }
611
+            $this->mkdir($to);
612
+
613
+            foreach ($cache->getFolderContentsById($sourceEntry->getId()) as $child) {
614
+                $this->copyInner($child, $to . '/' . $child->getName());
615
+            }
616
+        } else {
617
+            $this->copyFile($sourceEntry, $to);
618
+        }
619
+    }
620
+
621
+    private function copyFile(ICacheEntry $sourceEntry, string $to) {
622
+        $cache = $this->getCache();
623
+
624
+        $sourceUrn = $this->getURN($sourceEntry->getId());
625
+
626
+        if (!$cache instanceof Cache) {
627
+            throw new \Exception("Invalid source cache for object store copy");
628
+        }
629
+
630
+        $targetId = $cache->copyFromCache($cache, $sourceEntry, $to);
631
+
632
+        $targetUrn = $this->getURN($targetId);
633
+
634
+        try {
635
+            $this->objectStore->copyObject($sourceUrn, $targetUrn);
636
+        } catch (\Exception $e) {
637
+            $cache->remove($to);
638
+
639
+            throw $e;
640
+        }
641
+    }
642
+
643
+    public function startChunkedWrite(string $targetPath): string {
644
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
645
+            throw new GenericFileException('Object store does not support multipart upload');
646
+        }
647
+        $cacheEntry = $this->getCache()->get($targetPath);
648
+        $urn = $this->getURN($cacheEntry->getId());
649
+        return $this->objectStore->initiateMultipartUpload($urn);
650
+    }
651
+
652
+    /**
653
+     *
654
+     * @throws GenericFileException
655
+     */
656
+    public function putChunkedWritePart(
657
+        string $targetPath,
658
+        string $writeToken,
659
+        string $chunkId,
660
+        $data,
661
+        $size = null
662
+    ): ?array {
663
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
664
+            throw new GenericFileException('Object store does not support multipart upload');
665
+        }
666
+        $cacheEntry = $this->getCache()->get($targetPath);
667
+        $urn = $this->getURN($cacheEntry->getId());
668
+
669
+        $result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int)$chunkId, $data, $size);
670
+
671
+        $parts[$chunkId] = [
672
+            'PartNumber' => $chunkId,
673
+            'ETag' => trim($result->get('ETag'), '"'),
674
+        ];
675
+        return $parts[$chunkId];
676
+    }
677
+
678
+    public function completeChunkedWrite(string $targetPath, string $writeToken): int {
679
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
680
+            throw new GenericFileException('Object store does not support multipart upload');
681
+        }
682
+        $cacheEntry = $this->getCache()->get($targetPath);
683
+        $urn = $this->getURN($cacheEntry->getId());
684
+        $parts = $this->objectStore->getMultipartUploads($urn, $writeToken);
685
+        $sortedParts = array_values($parts);
686
+        sort($sortedParts);
687
+        try {
688
+            $size = $this->objectStore->completeMultipartUpload($urn, $writeToken, $sortedParts);
689
+            $stat = $this->stat($targetPath);
690
+            $mtime = time();
691
+            if (is_array($stat)) {
692
+                $stat['size'] = $size;
693
+                $stat['mtime'] = $mtime;
694
+                $stat['mimetype'] = $this->getMimeType($targetPath);
695
+                $this->getCache()->update($stat['fileid'], $stat);
696
+            }
697
+        } catch (S3MultipartUploadException|S3Exception $e) {
698
+            $this->objectStore->abortMultipartUpload($urn, $writeToken);
699
+            $this->logger->logException($e, [
700
+                'app' => 'objectstore',
701
+                'message' => 'Could not compete multipart upload ' . $urn . ' with uploadId ' . $writeToken,
702
+            ]);
703
+            throw new GenericFileException('Could not write chunked file');
704
+        }
705
+        return $size;
706
+    }
707
+
708
+    public function cancelChunkedWrite(string $targetPath, string $writeToken): void {
709
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
710
+            throw new GenericFileException('Object store does not support multipart upload');
711
+        }
712
+        $cacheEntry = $this->getCache()->get($targetPath);
713
+        $urn = $this->getURN($cacheEntry->getId());
714
+        $this->objectStore->abortMultipartUpload($urn, $writeToken);
715
+    }
716 716
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -77,15 +77,15 @@  discard block
 block discarded – undo
77 77
 			throw new \Exception('missing IObjectStore instance');
78 78
 		}
79 79
 		if (isset($params['storageid'])) {
80
-			$this->id = 'object::store:' . $params['storageid'];
80
+			$this->id = 'object::store:'.$params['storageid'];
81 81
 		} else {
82
-			$this->id = 'object::store:' . $this->objectStore->getStorageId();
82
+			$this->id = 'object::store:'.$this->objectStore->getStorageId();
83 83
 		}
84 84
 		if (isset($params['objectPrefix'])) {
85 85
 			$this->objectPrefix = $params['objectPrefix'];
86 86
 		}
87 87
 		if (isset($params['validateWrites'])) {
88
-			$this->validateWrites = (bool)$params['validateWrites'];
88
+			$this->validateWrites = (bool) $params['validateWrites'];
89 89
 		}
90 90
 		//initialize cache with root directory in cache
91 91
 		if (!$this->is_dir('/')) {
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 			if ($ex->getCode() !== 404) {
228 228
 				$this->logger->logException($ex, [
229 229
 					'app' => 'objectstore',
230
-					'message' => 'Could not delete object ' . $this->getURN($entry->getId()) . ' for ' . $entry->getPath(),
230
+					'message' => 'Could not delete object '.$this->getURN($entry->getId()).' for '.$entry->getPath(),
231 231
 				]);
232 232
 				return false;
233 233
 			}
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
 	 */
268 268
 	public function getURN($fileId) {
269 269
 		if (is_numeric($fileId)) {
270
-			return $this->objectPrefix . $fileId;
270
+			return $this->objectPrefix.$fileId;
271 271
 		}
272 272
 		return null;
273 273
 	}
@@ -330,19 +330,19 @@  discard block
 block discarded – undo
330 330
 						$streamStat = fstat($handle);
331 331
 						$actualSize = $streamStat['size'] ?? -1;
332 332
 						if ($actualSize > -1 && $actualSize !== $filesize) {
333
-							$this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]);
333
+							$this->getCache()->update((int) $stat['fileid'], ['size' => $actualSize]);
334 334
 						}
335 335
 						return $handle;
336 336
 					} catch (NotFoundException $e) {
337 337
 						$this->logger->logException($e, [
338 338
 							'app' => 'objectstore',
339
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
339
+							'message' => 'Could not get object '.$this->getURN($stat['fileid']).' for file '.$path,
340 340
 						]);
341 341
 						throw $e;
342 342
 					} catch (\Exception $ex) {
343 343
 						$this->logger->logException($ex, [
344 344
 							'app' => 'objectstore',
345
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
345
+							'message' => 'Could not get object '.$this->getURN($stat['fileid']).' for file '.$path,
346 346
 						]);
347 347
 						return false;
348 348
 					}
@@ -356,7 +356,7 @@  discard block
 block discarded – undo
356 356
 			case 'wb+':
357 357
 				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
358 358
 				$handle = fopen($tmpFile, $mode);
359
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
359
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
360 360
 					$this->writeBack($tmpFile, $path);
361 361
 					unlink($tmpFile);
362 362
 				});
@@ -374,7 +374,7 @@  discard block
 block discarded – undo
374 374
 					file_put_contents($tmpFile, $source);
375 375
 				}
376 376
 				$handle = fopen($tmpFile, $mode);
377
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
377
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
378 378
 					$this->writeBack($tmpFile, $path);
379 379
 					unlink($tmpFile);
380 380
 				});
@@ -384,7 +384,7 @@  discard block
 block discarded – undo
384 384
 
385 385
 	public function file_exists($path) {
386 386
 		$path = $this->normalizePath($path);
387
-		return (bool)$this->stat($path);
387
+		return (bool) $this->stat($path);
388 388
 	}
389 389
 
390 390
 	public function rename($source, $target) {
@@ -436,7 +436,7 @@  discard block
 block discarded – undo
436 436
 			} catch (\Exception $ex) {
437 437
 				$this->logger->logException($ex, [
438 438
 					'app' => 'objectstore',
439
-					'message' => 'Could not create object for ' . $path,
439
+					'message' => 'Could not create object for '.$path,
440 440
 				]);
441 441
 				throw $ex;
442 442
 			}
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
 		}
482 482
 		// update stat with new data
483 483
 		$mTime = time();
484
-		$stat['size'] = (int)$size;
484
+		$stat['size'] = (int) $size;
485 485
 		$stat['mtime'] = $mTime;
486 486
 		$stat['storage_mtime'] = $mTime;
487 487
 
@@ -493,7 +493,7 @@  discard block
 block discarded – undo
493 493
 		$stat['checksum'] = '';
494 494
 
495 495
 		$exists = $this->getCache()->inCache($path);
496
-		$uploadPath = $exists ? $path : $path . '.part';
496
+		$uploadPath = $exists ? $path : $path.'.part';
497 497
 
498 498
 		if ($exists) {
499 499
 			$fileId = $stat['fileid'];
@@ -505,7 +505,7 @@  discard block
 block discarded – undo
505 505
 		try {
506 506
 			//upload to object storage
507 507
 			if ($size === null) {
508
-				$countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) {
508
+				$countStream = CountWrapper::wrap($stream, function($writtenSize) use ($fileId, &$size) {
509 509
 					$this->getCache()->update($fileId, [
510 510
 						'size' => $writtenSize,
511 511
 					]);
@@ -531,12 +531,12 @@  discard block
 block discarded – undo
531 531
 				$this->getCache()->remove($uploadPath);
532 532
 				$this->logger->logException($ex, [
533 533
 					'app' => 'objectstore',
534
-					'message' => 'Could not create object ' . $urn . ' for ' . $path,
534
+					'message' => 'Could not create object '.$urn.' for '.$path,
535 535
 				]);
536 536
 			} else {
537 537
 				$this->logger->logException($ex, [
538 538
 					'app' => 'objectstore',
539
-					'message' => 'Could not update object ' . $urn . ' for ' . $path,
539
+					'message' => 'Could not update object '.$urn.' for '.$path,
540 540
 				]);
541 541
 			}
542 542
 			throw $ex; // make this bubble up
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
 			$this->mkdir($to);
612 612
 
613 613
 			foreach ($cache->getFolderContentsById($sourceEntry->getId()) as $child) {
614
-				$this->copyInner($child, $to . '/' . $child->getName());
614
+				$this->copyInner($child, $to.'/'.$child->getName());
615 615
 			}
616 616
 		} else {
617 617
 			$this->copyFile($sourceEntry, $to);
@@ -666,7 +666,7 @@  discard block
 block discarded – undo
666 666
 		$cacheEntry = $this->getCache()->get($targetPath);
667 667
 		$urn = $this->getURN($cacheEntry->getId());
668 668
 
669
-		$result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int)$chunkId, $data, $size);
669
+		$result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int) $chunkId, $data, $size);
670 670
 
671 671
 		$parts[$chunkId] = [
672 672
 			'PartNumber' => $chunkId,
@@ -694,11 +694,11 @@  discard block
 block discarded – undo
694 694
 				$stat['mimetype'] = $this->getMimeType($targetPath);
695 695
 				$this->getCache()->update($stat['fileid'], $stat);
696 696
 			}
697
-		} catch (S3MultipartUploadException|S3Exception $e) {
697
+		} catch (S3MultipartUploadException | S3Exception $e) {
698 698
 			$this->objectStore->abortMultipartUpload($urn, $writeToken);
699 699
 			$this->logger->logException($e, [
700 700
 				'app' => 'objectstore',
701
-				'message' => 'Could not compete multipart upload ' . $urn . ' with uploadId ' . $writeToken,
701
+				'message' => 'Could not compete multipart upload '.$urn.' with uploadId '.$writeToken,
702 702
 			]);
703 703
 			throw new GenericFileException('Could not write chunked file');
704 704
 		}
Please login to merge, or discard this patch.