Passed
Push — master ( dbd0cf...f323c5 )
by Blizzz
12:55 queued 12s
created

Filesystem::touch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Bart Visscher <[email protected]>
7
 * @author Christopher Schäpers <[email protected]>
8
 * @author Christoph Wurst <[email protected]>
9
 * @author Florin Peter <[email protected]>
10
 * @author Joas Schilling <[email protected]>
11
 * @author Jörn Friedrich Dreyer <[email protected]>
12
 * @author korelstar <[email protected]>
13
 * @author Lukas Reschke <[email protected]>
14
 * @author Michael Gapczynski <[email protected]>
15
 * @author Morris Jobke <[email protected]>
16
 * @author Robin Appelman <[email protected]>
17
 * @author Robin McCorkell <[email protected]>
18
 * @author Roeland Jago Douma <[email protected]>
19
 * @author Sam Tuke <[email protected]>
20
 * @author Stephan Peijnik <[email protected]>
21
 * @author Vincent Petry <[email protected]>
22
 *
23
 * @license AGPL-3.0
24
 *
25
 * This code is free software: you can redistribute it and/or modify
26
 * it under the terms of the GNU Affero General Public License, version 3,
27
 * as published by the Free Software Foundation.
28
 *
29
 * This program is distributed in the hope that it will be useful,
30
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
 * GNU Affero General Public License for more details.
33
 *
34
 * You should have received a copy of the GNU Affero General Public License, version 3,
35
 * along with this program. If not, see <http://www.gnu.org/licenses/>
36
 *
37
 */
38
namespace OC\Files;
39
40
use OCP\Cache\CappedMemoryCache;
41
use OC\Files\Mount\MountPoint;
42
use OC\User\NoUserException;
43
use OCP\EventDispatcher\IEventDispatcher;
44
use OCP\Files\Events\Node\FilesystemTornDownEvent;
45
use OCP\Files\NotFoundException;
46
use OCP\Files\Storage\IStorageFactory;
47
use OCP\IUser;
48
use OCP\IUserManager;
49
use OCP\IUserSession;
50
51
class Filesystem {
52
53
	/**
54
	 * @var Mount\Manager $mounts
55
	 */
56
	private static $mounts;
57
58
	public static $loaded = false;
59
	/**
60
	 * @var \OC\Files\View $defaultInstance
61
	 */
62
	private static $defaultInstance;
63
64
	private static $usersSetup = [];
65
66
	private static $normalizedPathCache = null;
67
68
	private static $listeningForProviders = false;
0 ignored issues
show
introduced by
The private property $listeningForProviders is not used, and could be removed.
Loading history...
69
70
	/** @var string[]|null */
71
	private static $blacklist = null;
72
73
	/**
74
	 * classname which used for hooks handling
75
	 * used as signalclass in OC_Hooks::emit()
76
	 */
77
	public const CLASSNAME = 'OC_Filesystem';
78
79
	/**
80
	 * signalname emitted before file renaming
81
	 *
82
	 * @param string $oldpath
83
	 * @param string $newpath
84
	 */
85
	public const signal_rename = 'rename';
86
87
	/**
88
	 * signal emitted after file renaming
89
	 *
90
	 * @param string $oldpath
91
	 * @param string $newpath
92
	 */
93
	public const signal_post_rename = 'post_rename';
94
95
	/**
96
	 * signal emitted before file/dir creation
97
	 *
98
	 * @param string $path
99
	 * @param bool $run changing this flag to false in hook handler will cancel event
100
	 */
101
	public const signal_create = 'create';
102
103
	/**
104
	 * signal emitted after file/dir creation
105
	 *
106
	 * @param string $path
107
	 * @param bool $run changing this flag to false in hook handler will cancel event
108
	 */
109
	public const signal_post_create = 'post_create';
110
111
	/**
112
	 * signal emits before file/dir copy
113
	 *
114
	 * @param string $oldpath
115
	 * @param string $newpath
116
	 * @param bool $run changing this flag to false in hook handler will cancel event
117
	 */
118
	public const signal_copy = 'copy';
119
120
	/**
121
	 * signal emits after file/dir copy
122
	 *
123
	 * @param string $oldpath
124
	 * @param string $newpath
125
	 */
126
	public const signal_post_copy = 'post_copy';
127
128
	/**
129
	 * signal emits before file/dir save
130
	 *
131
	 * @param string $path
132
	 * @param bool $run changing this flag to false in hook handler will cancel event
133
	 */
134
	public const signal_write = 'write';
135
136
	/**
137
	 * signal emits after file/dir save
138
	 *
139
	 * @param string $path
140
	 */
141
	public const signal_post_write = 'post_write';
142
143
	/**
144
	 * signal emitted before file/dir update
145
	 *
146
	 * @param string $path
147
	 * @param bool $run changing this flag to false in hook handler will cancel event
148
	 */
149
	public const signal_update = 'update';
150
151
	/**
152
	 * signal emitted after file/dir update
153
	 *
154
	 * @param string $path
155
	 * @param bool $run changing this flag to false in hook handler will cancel event
156
	 */
157
	public const signal_post_update = 'post_update';
158
159
	/**
160
	 * signal emits when reading file/dir
161
	 *
162
	 * @param string $path
163
	 */
164
	public const signal_read = 'read';
165
166
	/**
167
	 * signal emits when removing file/dir
168
	 *
169
	 * @param string $path
170
	 */
171
	public const signal_delete = 'delete';
172
173
	/**
174
	 * parameters definitions for signals
175
	 */
176
	public const signal_param_path = 'path';
177
	public const signal_param_oldpath = 'oldpath';
178
	public const signal_param_newpath = 'newpath';
179
180
	/**
181
	 * run - changing this flag to false in hook handler will cancel event
182
	 */
183
	public const signal_param_run = 'run';
184
185
	public const signal_create_mount = 'create_mount';
186
	public const signal_delete_mount = 'delete_mount';
187
	public const signal_param_mount_type = 'mounttype';
188
	public const signal_param_users = 'users';
189
190
	/**
191
	 * @var \OC\Files\Storage\StorageFactory $loader
192
	 */
193
	private static $loader;
194
195
	/** @var bool */
196
	private static $logWarningWhenAddingStorageWrapper = true;
197
198
	/**
199
	 * @param bool $shouldLog
200
	 * @return bool previous value
201
	 * @internal
202
	 */
203
	public static function logWarningWhenAddingStorageWrapper($shouldLog) {
204
		$previousValue = self::$logWarningWhenAddingStorageWrapper;
205
		self::$logWarningWhenAddingStorageWrapper = (bool) $shouldLog;
206
		return $previousValue;
207
	}
208
209
	/**
210
	 * @param string $wrapperName
211
	 * @param callable $wrapper
212
	 * @param int $priority
213
	 */
214
	public static function addStorageWrapper($wrapperName, $wrapper, $priority = 50) {
215
		if (self::$logWarningWhenAddingStorageWrapper) {
216
			\OC::$server->getLogger()->warning("Storage wrapper '{wrapper}' was not registered via the 'OC_Filesystem - preSetup' hook which could cause potential problems.", [
217
				'wrapper' => $wrapperName,
218
				'app' => 'filesystem',
219
			]);
220
		}
221
222
		$mounts = self::getMountManager()->getAll();
223
		if (!self::getLoader()->addStorageWrapper($wrapperName, $wrapper, $priority, $mounts)) {
224
			// do not re-wrap if storage with this name already existed
225
			return;
226
		}
227
	}
228
229
	/**
230
	 * Returns the storage factory
231
	 *
232
	 * @return IStorageFactory
233
	 */
234
	public static function getLoader() {
235
		if (!self::$loader) {
236
			self::$loader = \OC::$server->query(IStorageFactory::class);
237
		}
238
		return self::$loader;
239
	}
240
241
	/**
242
	 * Returns the mount manager
243
	 *
244
	 * @return \OC\Files\Mount\Manager
245
	 */
246
	public static function getMountManager($user = '') {
0 ignored issues
show
Unused Code introduced by
The parameter $user is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

246
	public static function getMountManager(/** @scrutinizer ignore-unused */ $user = '') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
247
		self::initMountManager();
248
		return self::$mounts;
249
	}
250
251
	/**
252
	 * get the mountpoint of the storage object for a path
253
	 * ( note: because a storage is not always mounted inside the fakeroot, the
254
	 * returned mountpoint is relative to the absolute root of the filesystem
255
	 * and doesn't take the chroot into account )
256
	 *
257
	 * @param string $path
258
	 * @return string
259
	 */
260
	public static function getMountPoint($path) {
261
		if (!self::$mounts) {
262
			\OC_Util::setupFS();
263
		}
264
		$mount = self::$mounts->find($path);
265
		return $mount->getMountPoint();
266
	}
267
268
	/**
269
	 * get a list of all mount points in a directory
270
	 *
271
	 * @param string $path
272
	 * @return string[]
273
	 */
274
	public static function getMountPoints($path) {
275
		if (!self::$mounts) {
276
			\OC_Util::setupFS();
277
		}
278
		$result = [];
279
		$mounts = self::$mounts->findIn($path);
280
		foreach ($mounts as $mount) {
281
			$result[] = $mount->getMountPoint();
282
		}
283
		return $result;
284
	}
285
286
	/**
287
	 * get the storage mounted at $mountPoint
288
	 *
289
	 * @param string $mountPoint
290
	 * @return \OC\Files\Storage\Storage|null
291
	 */
292
	public static function getStorage($mountPoint) {
293
		$mount = self::getMountManager()->find($mountPoint);
294
		return $mount->getStorage();
295
	}
296
297
	/**
298
	 * @param string $id
299
	 * @return Mount\MountPoint[]
300
	 */
301
	public static function getMountByStorageId($id) {
302
		return self::getMountManager()->findByStorageId($id);
303
	}
304
305
	/**
306
	 * @param int $id
307
	 * @return Mount\MountPoint[]
308
	 */
309
	public static function getMountByNumericId($id) {
310
		return self::getMountManager()->findByNumericId($id);
311
	}
312
313
	/**
314
	 * resolve a path to a storage and internal path
315
	 *
316
	 * @param string $path
317
	 * @return array an array consisting of the storage and the internal path
318
	 */
319
	public static function resolvePath($path) {
320
		$mount = self::getMountManager()->find($path);
321
		return [$mount->getStorage(), rtrim($mount->getInternalPath($path), '/')];
322
	}
323
324
	public static function init($user, $root) {
325
		if (self::$defaultInstance) {
326
			return false;
327
		}
328
		self::initInternal($root);
329
330
		//load custom mount config
331
		self::initMountPoints($user);
332
333
		return true;
334
	}
335
336
	public static function initInternal($root) {
337
		if (self::$defaultInstance) {
338
			return false;
339
		}
340
		self::getLoader();
341
		self::$defaultInstance = new View($root);
342
		/** @var IEventDispatcher $eventDispatcher */
343
		$eventDispatcher = \OC::$server->get(IEventDispatcher::class);
344
		$eventDispatcher->addListener(FilesystemTornDownEvent::class, function () {
345
			self::$defaultInstance = null;
346
			self::$usersSetup = [];
347
			self::$loaded = false;
348
		});
349
350
		if (!self::$mounts) {
351
			self::$mounts = \OC::$server->getMountManager();
352
		}
353
354
		self::$loaded = true;
355
356
		return true;
357
	}
358
359
	public static function initMountManager() {
360
		if (!self::$mounts) {
361
			self::$mounts = \OC::$server->getMountManager();
362
		}
363
	}
364
365
	/**
366
	 * Initialize system and personal mount points for a user
367
	 *
368
	 * @param string|IUser|null $user
369
	 * @throws \OC\User\NoUserException if the user is not available
370
	 */
371
	public static function initMountPoints($user = '') {
372
		/** @var IUserManager $userManager */
373
		$userManager = \OC::$server->get(IUserManager::class);
374
375
		$userObject = ($user instanceof IUser) ? $user : $userManager->get($user);
376
		if ($userObject) {
377
			/** @var SetupManager $setupManager */
378
			$setupManager = \OC::$server->get(SetupManager::class);
379
			$setupManager->setupForUser($userObject);
380
		} else {
381
			throw new NoUserException();
382
		}
383
	}
384
385
	/**
386
	 * get the default filesystem view
387
	 *
388
	 * @return View
389
	 */
390
	public static function getView() {
391
		if (!self::$defaultInstance) {
392
			/** @var IUserSession $session */
393
			$session = \OC::$server->get(IUserSession::class);
394
			$user = $session->getUser();
395
			if ($user) {
396
				$userDir = '/' . $user->getUID() . '/files';
397
				self::initInternal($userDir);
398
			}
399
		}
400
		return self::$defaultInstance;
401
	}
402
403
	/**
404
	 * tear down the filesystem, removing all storage providers
405
	 */
406
	public static function tearDown() {
407
		\OC_Util::tearDownFS();
408
	}
409
410
	/**
411
	 * get the relative path of the root data directory for the current user
412
	 *
413
	 * @return string
414
	 *
415
	 * Returns path like /admin/files
416
	 */
417
	public static function getRoot() {
418
		if (!self::$defaultInstance) {
419
			return null;
420
		}
421
		return self::$defaultInstance->getRoot();
422
	}
423
424
	/**
425
	 * mount an \OC\Files\Storage\Storage in our virtual filesystem
426
	 *
427
	 * @param \OC\Files\Storage\Storage|string $class
428
	 * @param array $arguments
429
	 * @param string $mountpoint
430
	 */
431
	public static function mount($class, $arguments, $mountpoint) {
432
		if (!self::$mounts) {
433
			\OC_Util::setupFS();
434
		}
435
		$mount = new Mount\MountPoint($class, $mountpoint, $arguments, self::getLoader());
436
		self::$mounts->addMount($mount);
437
	}
438
439
	/**
440
	 * return the path to a local version of the file
441
	 * we need this because we can't know if a file is stored local or not from
442
	 * outside the filestorage and for some purposes a local file is needed
443
	 *
444
	 * @param string $path
445
	 * @return string
446
	 */
447
	public static function getLocalFile($path) {
448
		return self::$defaultInstance->getLocalFile($path);
449
	}
450
451
	/**
452
	 * @param string $path
453
	 * @return string
454
	 */
455
	public static function getLocalFolder($path) {
456
		return self::$defaultInstance->getLocalFolder($path);
457
	}
458
459
	/**
460
	 * return path to file which reflects one visible in browser
461
	 *
462
	 * @param string $path
463
	 * @return string
464
	 */
465
	public static function getLocalPath($path) {
466
		$datadir = \OC_User::getHome(\OC_User::getUser()) . '/files';
467
		$newpath = $path;
468
		if (strncmp($newpath, $datadir, strlen($datadir)) == 0) {
469
			$newpath = substr($path, strlen($datadir));
470
		}
471
		return $newpath;
472
	}
473
474
	/**
475
	 * check if the requested path is valid
476
	 *
477
	 * @param string $path
478
	 * @return bool
479
	 */
480
	public static function isValidPath($path) {
481
		$path = self::normalizePath($path);
482
		if (!$path || $path[0] !== '/') {
483
			$path = '/' . $path;
484
		}
485
		if (strpos($path, '/../') !== false || strrchr($path, '/') === '/..') {
486
			return false;
487
		}
488
		return true;
489
	}
490
491
	/**
492
	 * @param string $filename
493
	 * @return bool
494
	 */
495
	public static function isFileBlacklisted($filename) {
496
		$filename = self::normalizePath($filename);
497
498
		if (self::$blacklist === null) {
499
			self::$blacklist = \OC::$server->getConfig()->getSystemValue('blacklisted_files', ['.htaccess']);
500
		}
501
502
		$filename = strtolower(basename($filename));
503
		return in_array($filename, self::$blacklist);
504
	}
505
506
	/**
507
	 * check if the directory should be ignored when scanning
508
	 * NOTE: the special directories . and .. would cause never ending recursion
509
	 *
510
	 * @param string $dir
511
	 * @return boolean
512
	 */
513
	public static function isIgnoredDir($dir) {
514
		if ($dir === '.' || $dir === '..') {
515
			return true;
516
		}
517
		return false;
518
	}
519
520
	/**
521
	 * following functions are equivalent to their php builtin equivalents for arguments/return values.
522
	 */
523
	public static function mkdir($path) {
524
		return self::$defaultInstance->mkdir($path);
525
	}
526
527
	public static function rmdir($path) {
528
		return self::$defaultInstance->rmdir($path);
529
	}
530
531
	public static function is_dir($path) {
532
		return self::$defaultInstance->is_dir($path);
533
	}
534
535
	public static function is_file($path) {
536
		return self::$defaultInstance->is_file($path);
537
	}
538
539
	public static function stat($path) {
540
		return self::$defaultInstance->stat($path);
541
	}
542
543
	public static function filetype($path) {
544
		return self::$defaultInstance->filetype($path);
545
	}
546
547
	public static function filesize($path) {
548
		return self::$defaultInstance->filesize($path);
549
	}
550
551
	public static function readfile($path) {
552
		return self::$defaultInstance->readfile($path);
553
	}
554
555
	public static function isCreatable($path) {
556
		return self::$defaultInstance->isCreatable($path);
557
	}
558
559
	public static function isReadable($path) {
560
		return self::$defaultInstance->isReadable($path);
561
	}
562
563
	public static function isUpdatable($path) {
564
		return self::$defaultInstance->isUpdatable($path);
565
	}
566
567
	public static function isDeletable($path) {
568
		return self::$defaultInstance->isDeletable($path);
569
	}
570
571
	public static function isSharable($path) {
572
		return self::$defaultInstance->isSharable($path);
573
	}
574
575
	public static function file_exists($path) {
576
		return self::$defaultInstance->file_exists($path);
577
	}
578
579
	public static function filemtime($path) {
580
		return self::$defaultInstance->filemtime($path);
581
	}
582
583
	public static function touch($path, $mtime = null) {
584
		return self::$defaultInstance->touch($path, $mtime);
585
	}
586
587
	/**
588
	 * @return string
589
	 */
590
	public static function file_get_contents($path) {
591
		return self::$defaultInstance->file_get_contents($path);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::defaultInst...ile_get_contents($path) also could return the type boolean which is incompatible with the documented return type string.
Loading history...
592
	}
593
594
	public static function file_put_contents($path, $data) {
595
		return self::$defaultInstance->file_put_contents($path, $data);
596
	}
597
598
	public static function unlink($path) {
599
		return self::$defaultInstance->unlink($path);
600
	}
601
602
	public static function rename($path1, $path2) {
603
		return self::$defaultInstance->rename($path1, $path2);
604
	}
605
606
	public static function copy($path1, $path2) {
607
		return self::$defaultInstance->copy($path1, $path2);
608
	}
609
610
	public static function fopen($path, $mode) {
611
		return self::$defaultInstance->fopen($path, $mode);
612
	}
613
614
	/**
615
	 * @return string
616
	 */
617
	public static function toTmpFile($path) {
618
		return self::$defaultInstance->toTmpFile($path);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::defaultInstance->toTmpFile($path) returns the type false which is incompatible with the documented return type string.
Loading history...
619
	}
620
621
	public static function fromTmpFile($tmpFile, $path) {
622
		return self::$defaultInstance->fromTmpFile($tmpFile, $path);
623
	}
624
625
	public static function getMimeType($path) {
626
		return self::$defaultInstance->getMimeType($path);
627
	}
628
629
	public static function hash($type, $path, $raw = false) {
630
		return self::$defaultInstance->hash($type, $path, $raw);
631
	}
632
633
	public static function free_space($path = '/') {
634
		return self::$defaultInstance->free_space($path);
635
	}
636
637
	public static function search($query) {
638
		return self::$defaultInstance->search($query);
639
	}
640
641
	/**
642
	 * @param string $query
643
	 */
644
	public static function searchByMime($query) {
645
		return self::$defaultInstance->searchByMime($query);
646
	}
647
648
	/**
649
	 * @param string|int $tag name or tag id
650
	 * @param string $userId owner of the tags
651
	 * @return FileInfo[] array or file info
652
	 */
653
	public static function searchByTag($tag, $userId) {
654
		return self::$defaultInstance->searchByTag($tag, $userId);
655
	}
656
657
	/**
658
	 * check if a file or folder has been updated since $time
659
	 *
660
	 * @param string $path
661
	 * @param int $time
662
	 * @return bool
663
	 */
664
	public static function hasUpdated($path, $time) {
665
		return self::$defaultInstance->hasUpdated($path, $time);
666
	}
667
668
	/**
669
	 * Fix common problems with a file path
670
	 *
671
	 * @param string $path
672
	 * @param bool $stripTrailingSlash whether to strip the trailing slash
673
	 * @param bool $isAbsolutePath whether the given path is absolute
674
	 * @param bool $keepUnicode true to disable unicode normalization
675
	 * @return string
676
	 */
677
	public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false, $keepUnicode = false) {
678
		/**
679
		 * FIXME: This is a workaround for existing classes and files which call
680
		 *        this function with another type than a valid string. This
681
		 *        conversion should get removed as soon as all existing
682
		 *        function calls have been fixed.
683
		 */
684
		$path = (string)$path;
685
686
		if ($path === '') {
687
			return '/';
688
		}
689
690
		if (is_null(self::$normalizedPathCache)) {
691
			self::$normalizedPathCache = new CappedMemoryCache(2048);
692
		}
693
694
		$cacheKey = json_encode([$path, $stripTrailingSlash, $isAbsolutePath, $keepUnicode]);
695
696
		if ($cacheKey && isset(self::$normalizedPathCache[$cacheKey])) {
697
			return self::$normalizedPathCache[$cacheKey];
698
		}
699
700
		//normalize unicode if possible
701
		if (!$keepUnicode) {
702
			$path = \OC_Util::normalizeUnicode($path);
703
		}
704
705
		//add leading slash, if it is already there we strip it anyway
706
		$path = '/' . $path;
707
708
		$patterns = [
709
			'#\\\\#s',       // no windows style '\\' slashes
710
			'#/\.(/\.)*/#s', // remove '/./'
711
			'#\//+#s',       // remove sequence of slashes
712
			'#/\.$#s',       // remove trailing '/.'
713
		];
714
715
		do {
716
			$count = 0;
717
			$path = preg_replace($patterns, '/', $path, -1, $count);
718
		} while ($count > 0);
719
720
		//remove trailing slash
721
		if ($stripTrailingSlash && strlen($path) > 1) {
722
			$path = rtrim($path, '/');
723
		}
724
725
		self::$normalizedPathCache[$cacheKey] = $path;
726
727
		return $path;
728
	}
729
730
	/**
731
	 * get the filesystem info
732
	 *
733
	 * @param string $path
734
	 * @param boolean $includeMountPoints whether to add mountpoint sizes,
735
	 * defaults to true
736
	 * @return \OC\Files\FileInfo|false False if file does not exist
737
	 */
738
	public static function getFileInfo($path, $includeMountPoints = true) {
739
		return self::getView()->getFileInfo($path, $includeMountPoints);
740
	}
741
742
	/**
743
	 * change file metadata
744
	 *
745
	 * @param string $path
746
	 * @param array $data
747
	 * @return int
748
	 *
749
	 * returns the fileid of the updated file
750
	 */
751
	public static function putFileInfo($path, $data) {
752
		return self::$defaultInstance->putFileInfo($path, $data);
753
	}
754
755
	/**
756
	 * get the content of a directory
757
	 *
758
	 * @param string $directory path under datadirectory
759
	 * @param string $mimetype_filter limit returned content to this mimetype or mimepart
760
	 * @return \OC\Files\FileInfo[]
761
	 */
762
	public static function getDirectoryContent($directory, $mimetype_filter = '') {
763
		return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter);
764
	}
765
766
	/**
767
	 * Get the path of a file by id
768
	 *
769
	 * Note that the resulting path is not guaranteed to be unique for the id, multiple paths can point to the same file
770
	 *
771
	 * @param int $id
772
	 * @throws NotFoundException
773
	 * @return string
774
	 */
775
	public static function getPath($id) {
776
		return self::$defaultInstance->getPath($id);
777
	}
778
779
	/**
780
	 * Get the owner for a file or folder
781
	 *
782
	 * @param string $path
783
	 * @return string
784
	 */
785
	public static function getOwner($path) {
786
		return self::$defaultInstance->getOwner($path);
787
	}
788
789
	/**
790
	 * get the ETag for a file or folder
791
	 *
792
	 * @param string $path
793
	 * @return string
794
	 */
795
	public static function getETag($path) {
796
		return self::$defaultInstance->getETag($path);
797
	}
798
}
799