Compare commits
7 Commits
perfCacheA
...
carl/node-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56c440937a | ||
|
|
ec40a61e34 | ||
|
|
ccc6077159 | ||
|
|
6d61b9f05a | ||
|
|
00e214080f | ||
|
|
5b67d03825 | ||
|
|
29bdc676f9 |
@@ -53,10 +53,6 @@ class CommentsSearchProvider implements IProvider {
|
||||
public function search(IUser $user, ISearchQuery $query): SearchResult {
|
||||
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
|
||||
|
||||
if ($userFolder === null) {
|
||||
return SearchResult::complete($this->l10n->t('Comments'), []);
|
||||
}
|
||||
|
||||
$result = [];
|
||||
$numComments = 50;
|
||||
$offset = 0;
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
*/
|
||||
namespace OCA\DAV\Connector\Sabre;
|
||||
|
||||
use OC\Files\Mount\DummyMountPoint;
|
||||
use OC\Files\Mount\MoveableMount;
|
||||
use OC\Files\Storage\FailedStorage;
|
||||
use OC\Files\Utils\PathHelper;
|
||||
use OC\Files\View;
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
@@ -113,9 +115,9 @@ class Directory extends Node implements
|
||||
$info = $this->fileView->getFileInfo($this->path . '/' . $name);
|
||||
if (!$info) {
|
||||
// use a dummy FileInfo which is acceptable here since it will be refreshed after the put is complete
|
||||
$info = new \OC\Files\FileInfo($path, null, null, [
|
||||
$info = new \OC\Files\FileInfo($path, new FailedStorage(['exception' => new \LogicException('Dummy storage') ]), '', [
|
||||
'type' => FileInfo::TYPE_FILE
|
||||
], null);
|
||||
], new DummyMountPoint());
|
||||
}
|
||||
$node = new File($this->fileView, $info);
|
||||
|
||||
|
||||
@@ -55,12 +55,6 @@ class File extends Node implements IFile {
|
||||
|
||||
/**
|
||||
* Sets up the node, expects a full path name
|
||||
*
|
||||
* @param View $view
|
||||
* @param FileInfo $info
|
||||
* @param ?\OCP\Share\IManager $shareManager
|
||||
* @param ?IRequest $request
|
||||
* @param ?IL10N $l10n
|
||||
*/
|
||||
public function __construct(View $view, FileInfo $info, ?IManager $shareManager = null, ?IRequest $request = null, ?IL10N $l10n = null) {
|
||||
parent::__construct($view, $info, $shareManager);
|
||||
@@ -369,7 +363,7 @@ class File extends Node implements IFile {
|
||||
if ($checksumHeader) {
|
||||
$checksum = trim($checksumHeader);
|
||||
$this->setChecksum($checksum);
|
||||
} elseif ($this->getChecksum() !== null && $this->getChecksum() !== '') {
|
||||
} elseif ($this->getChecksum() !== '') {
|
||||
$this->setChecksum('');
|
||||
}
|
||||
} catch (StorageNotAvailableException $e) {
|
||||
@@ -549,9 +543,6 @@ class File extends Node implements IFile {
|
||||
}
|
||||
$node = $this->getNode();
|
||||
$storage = $node->getStorage();
|
||||
if (!$storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($node->getPermissions() & Constants::PERMISSION_READ)) {
|
||||
return false;
|
||||
@@ -612,10 +603,8 @@ class File extends Node implements IFile {
|
||||
|
||||
/**
|
||||
* Get the checksum for this file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getChecksum() {
|
||||
public function getChecksum(): string {
|
||||
return $this->info->getChecksum();
|
||||
}
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ class FilesPlugin extends ServerPlugin {
|
||||
if ($node instanceof File) {
|
||||
//Add OC-Checksum header
|
||||
$checksum = $node->getChecksum();
|
||||
if ($checksum !== null && $checksum !== '') {
|
||||
if ($checksum !== '') {
|
||||
$response->addHeader('OC-Checksum', $checksum);
|
||||
}
|
||||
}
|
||||
@@ -312,7 +312,7 @@ class FilesPlugin extends ServerPlugin {
|
||||
});
|
||||
|
||||
$propFind->handle(self::INTERNAL_FILEID_PROPERTYNAME, function () use ($node) {
|
||||
return $node->getInternalFileId();
|
||||
return (string)$node->getInternalFileId();
|
||||
});
|
||||
|
||||
$propFind->handle(self::PERMISSIONS_PROPERTYNAME, function () use ($node) {
|
||||
@@ -500,7 +500,7 @@ class FilesPlugin extends ServerPlugin {
|
||||
|
||||
$propFind->handle(self::CHECKSUMS_PROPERTYNAME, function () use ($node) {
|
||||
$checksum = $node->getChecksum();
|
||||
if ($checksum === null || $checksum === '') {
|
||||
if ($checksum === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,18 +27,8 @@ use OCP\Share\IManager;
|
||||
abstract class Node implements \Sabre\DAV\INode {
|
||||
/**
|
||||
* The path to the current node
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
protected FileInfo $info;
|
||||
|
||||
/**
|
||||
* @var IManager
|
||||
*/
|
||||
protected $shareManager;
|
||||
|
||||
protected string $path = '';
|
||||
protected \OCP\Files\Node $node;
|
||||
|
||||
/**
|
||||
@@ -46,14 +36,11 @@ abstract class Node implements \Sabre\DAV\INode {
|
||||
*/
|
||||
public function __construct(
|
||||
protected View $fileView,
|
||||
FileInfo $info,
|
||||
?IManager $shareManager = null,
|
||||
protected FileInfo $info,
|
||||
protected ?IManager $shareManager = null,
|
||||
) {
|
||||
$this->path = $this->fileView->getRelativePath($info->getPath());
|
||||
$this->info = $info;
|
||||
if ($shareManager) {
|
||||
$this->shareManager = $shareManager;
|
||||
} else {
|
||||
if (!$this->shareManager) {
|
||||
$this->shareManager = Server::get(\OCP\Share\IManager::class);
|
||||
}
|
||||
if ($info instanceof Folder || $info instanceof File) {
|
||||
@@ -141,7 +128,7 @@ abstract class Node implements \Sabre\DAV\INode {
|
||||
public function getLastModified() {
|
||||
$timestamp = $this->info->getMtime();
|
||||
if (!empty($timestamp)) {
|
||||
return (int)$timestamp;
|
||||
return $timestamp;
|
||||
}
|
||||
return $timestamp;
|
||||
}
|
||||
@@ -207,7 +194,7 @@ abstract class Node implements \Sabre\DAV\INode {
|
||||
* @return int
|
||||
*/
|
||||
public function getId() {
|
||||
return $this->info->getId();
|
||||
return $this->info->getId() ?? -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,11 +208,8 @@ abstract class Node implements \Sabre\DAV\INode {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getInternalFileId() {
|
||||
return $this->info->getId();
|
||||
public function getInternalFileId(): int {
|
||||
return $this->info->getId() ?? -1;
|
||||
}
|
||||
|
||||
public function getInternalPath(): string {
|
||||
|
||||
@@ -70,6 +70,8 @@ class DirectoryTest extends \Test\TestCase {
|
||||
parent::setUp();
|
||||
|
||||
$this->view = $this->createMock(View::class);
|
||||
$this->view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
|
||||
$this->info = $this->createMock(FileInfo::class);
|
||||
$this->storage = $this->createMock(IStorage::class);
|
||||
$this->info->method('getStorage')
|
||||
@@ -107,7 +109,7 @@ class DirectoryTest extends \Test\TestCase {
|
||||
->willReturn(true);
|
||||
$this->view->expects($this->never())
|
||||
->method('rmdir');
|
||||
$dir = $this->getDir();
|
||||
$dir = $this->getDir('/');
|
||||
$dir->delete();
|
||||
}
|
||||
|
||||
@@ -231,6 +233,8 @@ class DirectoryTest extends \Test\TestCase {
|
||||
->method('isReadable')
|
||||
->willReturn(false);
|
||||
|
||||
$this->view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$dir = new Directory($this->view, $info);
|
||||
$dir->getChildren();
|
||||
}
|
||||
@@ -243,6 +247,8 @@ class DirectoryTest extends \Test\TestCase {
|
||||
->method('isReadable')
|
||||
->willReturn(false);
|
||||
|
||||
$this->view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$dir = new Directory($this->view, $this->info);
|
||||
$dir->getChild('test');
|
||||
}
|
||||
@@ -255,6 +261,8 @@ class DirectoryTest extends \Test\TestCase {
|
||||
->method('getFileInfo')
|
||||
->willThrowException(new StorageNotAvailableException());
|
||||
|
||||
$this->view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$dir = new Directory($this->view, $this->info);
|
||||
$dir->getChild('.');
|
||||
}
|
||||
@@ -269,6 +277,8 @@ class DirectoryTest extends \Test\TestCase {
|
||||
$this->view->expects($this->never())
|
||||
->method('getFileInfo');
|
||||
|
||||
$this->view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$dir = new Directory($this->view, $this->info);
|
||||
$dir->getChild('.');
|
||||
}
|
||||
@@ -562,12 +572,12 @@ class DirectoryTest extends \Test\TestCase {
|
||||
private function moveTest(string $source, string $destination, array $updatables, array $deletables): void {
|
||||
$view = new TestViewDirectory($updatables, $deletables);
|
||||
|
||||
$sourceInfo = new FileInfo($source, null, null, [
|
||||
$sourceInfo = new FileInfo($source, $this->createMock(IStorage::class), '', [
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
$targetInfo = new FileInfo(dirname($destination), null, null, [
|
||||
], $this->createMock(IMountPoint::class));
|
||||
$targetInfo = new FileInfo(dirname($destination), $this->createMock(IStorage::class), '', [
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$sourceNode = new Directory($view, $sourceInfo);
|
||||
$targetNode = $this->getMockBuilder(Directory::class)
|
||||
@@ -592,8 +602,8 @@ class DirectoryTest extends \Test\TestCase {
|
||||
|
||||
$view = new TestViewDirectory($updatables, $deletables);
|
||||
|
||||
$sourceInfo = new FileInfo($source, null, null, ['type' => FileInfo::TYPE_FOLDER], null);
|
||||
$targetInfo = new FileInfo(dirname($destination), null, null, ['type' => FileInfo::TYPE_FOLDER], null);
|
||||
$sourceInfo = new FileInfo($source, $this->createMock(IStorage::class), '', ['type' => FileInfo::TYPE_FOLDER], $this->createMock(IMountPoint::class));
|
||||
$targetInfo = new FileInfo(dirname($destination), $this->createMock(IStorage::class), '', ['type' => FileInfo::TYPE_FOLDER], $this->createMock(IMountPoint::class));
|
||||
|
||||
$sourceNode = new Directory($view, $sourceInfo);
|
||||
$targetNode = $this->getMockBuilder(Directory::class)
|
||||
|
||||
@@ -26,6 +26,7 @@ use OCP\Files\ForbiddenException;
|
||||
use OCP\Files\InvalidContentException;
|
||||
use OCP\Files\InvalidPathException;
|
||||
use OCP\Files\LockNotAcquiredException;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\Files\StorageNotAvailableException;
|
||||
@@ -184,10 +185,10 @@ class FileTest extends TestCase {
|
||||
->method('getRelativePath')
|
||||
->willReturnArgument(0);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -227,12 +228,12 @@ class FileTest extends TestCase {
|
||||
$info = new \OC\Files\FileInfo(
|
||||
$viewRoot . '/' . ltrim($path, '/'),
|
||||
$this->getMockStorage(),
|
||||
null,
|
||||
'',
|
||||
[
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
],
|
||||
null
|
||||
$this->createMock(IMountPoint::class),
|
||||
);
|
||||
|
||||
/** @var File&MockObject $file */
|
||||
@@ -495,10 +496,10 @@ class FileTest extends TestCase {
|
||||
'method' => 'PUT',
|
||||
], $this->requestId, $this->config, null);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info, null, $request);
|
||||
|
||||
@@ -529,10 +530,10 @@ class FileTest extends TestCase {
|
||||
// simulate situation where the target file is locked
|
||||
$view->lockFile('/test.txt', ILockingProvider::LOCK_EXCLUSIVE);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/' . $this->user . '/files/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/' . $this->user . '/files/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -567,10 +568,10 @@ class FileTest extends TestCase {
|
||||
->method('getRelativePath')
|
||||
->willReturnArgument(0);
|
||||
|
||||
$info = new \OC\Files\FileInfo("/i\nvalid", $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo("/i\nvalid", $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
$file = new File($view, $info);
|
||||
|
||||
// action
|
||||
@@ -608,10 +609,10 @@ class FileTest extends TestCase {
|
||||
->method('getRelativePath')
|
||||
->willReturnArgument(0);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/valid', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/valid', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
$file = new File($view, $info);
|
||||
|
||||
$file->setName("/i\nvalid");
|
||||
@@ -642,10 +643,10 @@ class FileTest extends TestCase {
|
||||
'method' => 'PUT',
|
||||
], $this->requestId, $this->config, null);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info, null, $request);
|
||||
|
||||
@@ -674,14 +675,17 @@ class FileTest extends TestCase {
|
||||
$view = $this->getMockBuilder(View::class)
|
||||
->getMock();
|
||||
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$view->expects($this->once())
|
||||
->method('unlink')
|
||||
->willReturn(true);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -698,10 +702,13 @@ class FileTest extends TestCase {
|
||||
$view = $this->getMockBuilder(View::class)
|
||||
->getMock();
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => 0,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -718,15 +725,18 @@ class FileTest extends TestCase {
|
||||
$view = $this->getMockBuilder(View::class)
|
||||
->getMock();
|
||||
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
// but fails
|
||||
$view->expects($this->once())
|
||||
->method('unlink')
|
||||
->willReturn(false);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -743,15 +753,18 @@ class FileTest extends TestCase {
|
||||
$view = $this->getMockBuilder(View::class)
|
||||
->getMock();
|
||||
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
// but fails
|
||||
$view->expects($this->once())
|
||||
->method('unlink')
|
||||
->willThrowException(new ForbiddenException('', true));
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -785,12 +798,12 @@ class FileTest extends TestCase {
|
||||
$info = new \OC\Files\FileInfo(
|
||||
'/' . $this->user . '/files/' . $path,
|
||||
$this->getMockStorage(),
|
||||
null,
|
||||
'',
|
||||
[
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
],
|
||||
null
|
||||
$this->createMock(IMountPoint::class)
|
||||
);
|
||||
|
||||
$file = new File($view, $info);
|
||||
@@ -921,10 +934,10 @@ class FileTest extends TestCase {
|
||||
->method('fopen')
|
||||
->willReturn(false);
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FILE,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -943,10 +956,10 @@ class FileTest extends TestCase {
|
||||
->method('fopen')
|
||||
->willThrowException(new ForbiddenException('', true));
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FILE,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -964,10 +977,10 @@ class FileTest extends TestCase {
|
||||
$view->expects($this->never())
|
||||
->method('fopen');
|
||||
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), '', [
|
||||
'permissions' => Constants::PERMISSION_CREATE, // no read perm
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
], null);
|
||||
], $this->createMock(IMountPoint::class));
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -1012,12 +1025,12 @@ class FileTest extends TestCase {
|
||||
$info = new \OC\Files\FileInfo(
|
||||
'/' . $this->user . '/files/' . $path,
|
||||
$this->getMockStorage(),
|
||||
null,
|
||||
'',
|
||||
[
|
||||
'permissions' => Constants::PERMISSION_ALL,
|
||||
'type' => FileInfo::TYPE_FOLDER,
|
||||
],
|
||||
null
|
||||
$this->createMock(IMountPoint::class)
|
||||
);
|
||||
|
||||
$file = new File($view, $info);
|
||||
|
||||
@@ -96,7 +96,7 @@ class FilesPluginTest extends TestCase {
|
||||
->willReturn('00000123instanceid');
|
||||
$node->expects($this->any())
|
||||
->method('getInternalFileId')
|
||||
->willReturn('123');
|
||||
->willReturn(123);
|
||||
$node->expects($this->any())
|
||||
->method('getEtag')
|
||||
->willReturn('"abc"');
|
||||
|
||||
@@ -57,6 +57,8 @@ class FilesReportPluginTest extends \Test\TestCase {
|
||||
|
||||
$this->tree = $this->createMock(Tree::class);
|
||||
$this->view = $this->createMock(View::class);
|
||||
$this->view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$this->view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$this->server = $this->getMockBuilder(Server::class)
|
||||
->setConstructorArgs([$this->tree])
|
||||
@@ -315,14 +317,14 @@ class FilesReportPluginTest extends \Test\TestCase {
|
||||
|
||||
$node1->expects($this->once())
|
||||
->method('getInternalFileId')
|
||||
->willReturn('111');
|
||||
->willReturn(111);
|
||||
$node1->expects($this->any())
|
||||
->method('getPath')
|
||||
->willReturn('/node1');
|
||||
$node1->method('getFileInfo')->willReturn($fileInfo);
|
||||
$node2->expects($this->once())
|
||||
->method('getInternalFileId')
|
||||
->willReturn('222');
|
||||
->willReturn(222);
|
||||
$node2->expects($this->once())
|
||||
->method('getSize')
|
||||
->willReturn(1024);
|
||||
|
||||
@@ -55,7 +55,7 @@ class NodeTest extends \Test\TestCase {
|
||||
public function testDavPermissions(int $permissions, string $type, bool $shared, int $shareRootPermissions, bool $mounted, string $internalPath, string $expected): void {
|
||||
$info = $this->getMockBuilder(FileInfo::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getPermissions', 'isShared', 'isMounted', 'getType', 'getInternalPath', 'getStorage', 'getMountPoint'])
|
||||
->onlyMethods(['getPermissions', 'isShared', 'isMounted', 'getType', 'getPath', 'getInternalPath', 'getStorage', 'getMountPoint'])
|
||||
->getMock();
|
||||
$info->method('getPermissions')
|
||||
->willReturn($permissions);
|
||||
@@ -65,6 +65,8 @@ class NodeTest extends \Test\TestCase {
|
||||
->willReturn($mounted);
|
||||
$info->method('getType')
|
||||
->willReturn($type);
|
||||
$info->method('getPath')
|
||||
->willReturn('');
|
||||
$info->method('getInternalPath')
|
||||
->willReturn($internalPath);
|
||||
$info->method('getMountPoint')
|
||||
@@ -94,8 +96,10 @@ class NodeTest extends \Test\TestCase {
|
||||
$info->method('getStorage')
|
||||
->willReturn($storage);
|
||||
$view = $this->createMock(View::class);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
|
||||
$node = new File($view, $info);
|
||||
$node = new File($view, $info);
|
||||
$this->assertEquals($expected, $node->getDavPermissions());
|
||||
}
|
||||
|
||||
@@ -160,15 +164,18 @@ class NodeTest extends \Test\TestCase {
|
||||
|
||||
$info = $this->getMockBuilder(FileInfo::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getStorage', 'getType', 'getMountPoint', 'getPermissions'])
|
||||
->onlyMethods(['getStorage', 'getType', 'getPath', 'getMountPoint', 'getPermissions'])
|
||||
->getMock();
|
||||
|
||||
$info->method('getStorage')->willReturn($storage);
|
||||
$info->method('getType')->willReturn($type);
|
||||
$info->method('getPath')->willReturn('');
|
||||
$info->method('getMountPoint')->willReturn($mountpoint);
|
||||
$info->method('getPermissions')->willReturn($permissions);
|
||||
|
||||
$view = $this->createMock(View::class);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
|
||||
$node = new File($view, $info);
|
||||
$this->invokePrivate($node, 'shareManager', [$shareManager]);
|
||||
@@ -196,14 +203,17 @@ class NodeTest extends \Test\TestCase {
|
||||
/** @var Folder&MockObject $info */
|
||||
$info = $this->getMockBuilder(Folder::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getStorage', 'getType'])
|
||||
->onlyMethods(['getStorage', 'getType', 'getPath'])
|
||||
->getMock();
|
||||
|
||||
$info->method('getStorage')->willReturn($storage);
|
||||
$info->method('getType')->willReturn(FileInfo::TYPE_FOLDER);
|
||||
$info->method('getPath')->willReturn('');
|
||||
|
||||
/** @var View&MockObject $view */
|
||||
$view = $this->createMock(View::class);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
|
||||
$node = new File($view, $info);
|
||||
$this->invokePrivate($node, 'shareManager', [$shareManager]);
|
||||
@@ -217,14 +227,17 @@ class NodeTest extends \Test\TestCase {
|
||||
/** @var Folder&MockObject */
|
||||
$info = $this->getMockBuilder(Folder::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getStorage', 'getType'])
|
||||
->onlyMethods(['getStorage', 'getType', 'getPath'])
|
||||
->getMock();
|
||||
|
||||
$info->method('getStorage')->willReturn($storage);
|
||||
$info->method('getType')->willReturn(FileInfo::TYPE_FOLDER);
|
||||
$info->method('getPath')->willReturn('');
|
||||
|
||||
/** @var View&MockObject */
|
||||
$view = $this->createMock(View::class);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
|
||||
$node = new File($view, $info);
|
||||
$this->invokePrivate($node, 'shareManager', [$shareManager]);
|
||||
@@ -243,6 +256,9 @@ class NodeTest extends \Test\TestCase {
|
||||
$view = $this->getMockBuilder(View::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
|
||||
$info = $this->getMockBuilder(FileInfo::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
@@ -263,6 +279,8 @@ class NodeTest extends \Test\TestCase {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
|
||||
$view = $this->createMock(View::class);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$info = $this->createMock(FileInfo::class);
|
||||
|
||||
$node = new File($view, $info);
|
||||
|
||||
@@ -19,6 +19,7 @@ use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
|
||||
use OCA\DAV\Connector\Sabre\File;
|
||||
use OCA\DAV\Connector\Sabre\ObjectTree;
|
||||
use OCP\Files\Mount\IMountManager;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
/**
|
||||
* Class ObjectTreeTest
|
||||
@@ -41,7 +42,7 @@ class ObjectTreeTest extends \Test\TestCase {
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('copyDataProvider')]
|
||||
public function testCopy(string $sourcePath, string $targetPath, string $targetParent): void {
|
||||
$view = $this->createMock(View::class);
|
||||
$view = $this->createView();
|
||||
$view->expects($this->once())
|
||||
->method('verifyPath')
|
||||
->with($targetParent);
|
||||
@@ -85,7 +86,7 @@ class ObjectTreeTest extends \Test\TestCase {
|
||||
public function testCopyFailNotCreatable($sourcePath, $targetPath, $targetParent): void {
|
||||
$this->expectException(\Sabre\DAV\Exception\Forbidden::class);
|
||||
|
||||
$view = $this->createMock(View::class);
|
||||
$view = $this->createView();
|
||||
$view->expects($this->never())
|
||||
->method('verifyPath');
|
||||
$view->expects($this->once())
|
||||
@@ -129,7 +130,7 @@ class ObjectTreeTest extends \Test\TestCase {
|
||||
): void {
|
||||
$rootNode = $this->createMock(Directory::class);
|
||||
$mountManager = $this->createMock(Manager::class);
|
||||
$view = $this->createMock(View::class);
|
||||
$view = $this->createView();
|
||||
$fileInfo = $this->createMock(FileInfo::class);
|
||||
$fileInfo->method('getType')
|
||||
->willReturn($type);
|
||||
@@ -240,4 +241,11 @@ class ObjectTreeTest extends \Test\TestCase {
|
||||
|
||||
$this->assertInstanceOf('\Sabre\DAV\INode', $tree->getNodeForPath($path));
|
||||
}
|
||||
|
||||
private function createView(): View&MockObject {
|
||||
$view = $this->createMock(View::class);
|
||||
$view->method('getAbsolutePath')->willReturnArgument(0);
|
||||
$view->method('getRelativePath')->willReturnArgument(0);
|
||||
return $view;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ abstract class RequestTestCase extends TestCase {
|
||||
$sapi = new Sapi($request);
|
||||
$server->sapi = $sapi;
|
||||
$server->httpRequest = $request;
|
||||
$server->exec();
|
||||
$server->start();
|
||||
return $sapi->getResponse();
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ class ViewOnlyPluginTest extends TestCase {
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('providesDataForCanGet')]
|
||||
public function testCanGet(bool $isVersion, ?bool $attrEnabled, bool $expectCanDownloadFile, bool $allowViewWithoutDownload): void {
|
||||
$nodeInfo = $this->createMock(File::class);
|
||||
$nodeInfo->method('getId')->willReturn(42);
|
||||
if ($isVersion) {
|
||||
$davPath = 'versions/alice/versions/117/123456';
|
||||
$version = $this->createMock(IVersion::class);
|
||||
|
||||
@@ -313,6 +313,9 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
|
||||
try {
|
||||
$fileId = $share->getNode()->getId();
|
||||
if ($fileId == null) {
|
||||
throw new \LogicException('Invalid node for share');
|
||||
}
|
||||
[$file, $link] = $this->getFile($user, $fileId);
|
||||
} catch (\Exception) {
|
||||
throw new ShareNotFound();
|
||||
@@ -388,6 +391,9 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
|
||||
|
||||
try {
|
||||
$fileId = $share->getNode()->getId();
|
||||
if ($fileId == null) {
|
||||
throw new \LogicException('Invalid node for share');
|
||||
}
|
||||
[$file, $link] = $this->getFile($user, $fileId);
|
||||
} catch (\Exception) {
|
||||
throw new ShareNotFound();
|
||||
|
||||
@@ -201,9 +201,7 @@ class ApiController extends Controller {
|
||||
];
|
||||
$shareTypes = [];
|
||||
|
||||
$nodeIds = array_map(function (Node $node) {
|
||||
return $node->getId();
|
||||
}, $nodes);
|
||||
$nodeIds = array_filter(array_map(fn (Node $node): ?int => $node->getId(), $nodes));
|
||||
|
||||
foreach ($requestedShareTypes as $shareType) {
|
||||
$nodesLeft = array_combine($nodeIds, array_fill(0, count($nodeIds), true));
|
||||
|
||||
@@ -99,7 +99,7 @@ class ConversionApiController extends OCSController {
|
||||
}
|
||||
|
||||
$file = $userFolder->get($convertedFileRelativePath);
|
||||
$fileId = $file->getId();
|
||||
$fileId = $file->getId() ?? -1;
|
||||
|
||||
return new DataResponse([
|
||||
'path' => $convertedFileRelativePath,
|
||||
|
||||
@@ -134,14 +134,18 @@ class SyncLivePhotosListener implements IEventListener {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->pendingRenames[] = $sourceFile->getId();
|
||||
$sourceFileId = $sourceFile->getId();
|
||||
if ($sourceFileId === null) {
|
||||
throw new \LogicException('Invalid source file given with a null id');
|
||||
}
|
||||
$this->pendingRenames[] = $sourceFileId;
|
||||
try {
|
||||
$peerFile->move($targetParent->getPath() . '/' . $peerTargetName);
|
||||
} catch (\Throwable $ex) {
|
||||
throw new AbortedEventException($ex->getMessage());
|
||||
}
|
||||
|
||||
$this->pendingRenames = array_diff($this->pendingRenames, [$sourceFile->getId()]);
|
||||
$this->pendingRenames = array_diff($this->pendingRenames, [$sourceFileId]);
|
||||
}
|
||||
|
||||
|
||||
@@ -163,15 +167,26 @@ class SyncLivePhotosListener implements IEventListener {
|
||||
$targetPeerFile = $peerFile->copy($targetParent->getPath() . '/' . $peerTargetName);
|
||||
}
|
||||
|
||||
$targetFileId = $targetFile->getId();
|
||||
if ($targetFileId === null) {
|
||||
throw new \LogicException('Invalid target file given with a null id');
|
||||
}
|
||||
|
||||
$targetPeerFileId = $targetPeerFile->getId();
|
||||
if ($targetPeerFileId === null) {
|
||||
throw new \LogicException('Invalid target peer file given with a null id');
|
||||
}
|
||||
|
||||
/** @var FilesMetadata $targetMetadata */
|
||||
$targetMetadata = $this->filesMetadataManager->getMetadata($targetFile->getId(), true);
|
||||
$targetMetadata = $this->filesMetadataManager->getMetadata($targetFileId, true);
|
||||
$targetMetadata->setStorageId($targetFile->getStorage()->getCache()->getNumericStorageId());
|
||||
$targetMetadata->setString('files-live-photo', (string)$targetPeerFile->getId());
|
||||
$targetMetadata->setString('files-live-photo', (string)$targetPeerFileId);
|
||||
$this->filesMetadataManager->saveMetadata($targetMetadata);
|
||||
|
||||
/** @var FilesMetadata $peerMetadata */
|
||||
$peerMetadata = $this->filesMetadataManager->getMetadata($targetPeerFile->getId(), true);
|
||||
$peerMetadata = $this->filesMetadataManager->getMetadata($targetPeerFileId, true);
|
||||
$peerMetadata->setStorageId($targetPeerFile->getStorage()->getCache()->getNumericStorageId());
|
||||
$peerMetadata->setString('files-live-photo', (string)$targetFile->getId());
|
||||
$peerMetadata->setString('files-live-photo', (string)$targetFileId);
|
||||
$this->filesMetadataManager->saveMetadata($peerMetadata);
|
||||
}
|
||||
|
||||
@@ -185,14 +200,22 @@ class SyncLivePhotosListener implements IEventListener {
|
||||
private function handleDeletion(BeforeNodeDeletedEvent $event, Node $peerFile): void {
|
||||
$deletedFile = $event->getNode();
|
||||
if ($deletedFile->getMimetype() === 'video/quicktime') {
|
||||
if (isset($this->pendingDeletion[$peerFile->getId()])) {
|
||||
unset($this->pendingDeletion[$peerFile->getId()]);
|
||||
$peerFileId = $peerFile->getId();
|
||||
if ($peerFileId === null) {
|
||||
throw new \LogicException('Invalid peer file given with a null id');
|
||||
}
|
||||
if (isset($this->pendingDeletion[$peerFileId])) {
|
||||
unset($this->pendingDeletion[$peerFileId]);
|
||||
return;
|
||||
} else {
|
||||
throw new AbortedEventException('Cannot delete the video part of a live photo');
|
||||
}
|
||||
} else {
|
||||
$this->pendingDeletion[$deletedFile->getId()] = true;
|
||||
$deletedFileId = $peerFile->getId();
|
||||
if ($deletedFileId === null) {
|
||||
throw new \LogicException('Invalid deleted file given with a null id');
|
||||
}
|
||||
$this->pendingDeletion[$deletedFileId] = true;
|
||||
try {
|
||||
$peerFile->delete();
|
||||
} catch (\Throwable $ex) {
|
||||
@@ -243,7 +266,7 @@ class SyncLivePhotosListener implements IEventListener {
|
||||
$this->pendingCopies[] = $peerFileId;
|
||||
if ($event instanceof BeforeNodeCopiedEvent) {
|
||||
$this->runMoveOrCopyChecks($sourceNode, $targetNode, $peerFile);
|
||||
} elseif ($event instanceof NodeCopiedEvent) {
|
||||
} elseif ($event instanceof NodeCopiedEvent && $peerFile instanceof File) {
|
||||
$this->handleCopy($sourceNode, $targetNode, $peerFile);
|
||||
}
|
||||
$this->pendingCopies = array_diff($this->pendingCopies, [$peerFileId]);
|
||||
|
||||
@@ -45,6 +45,9 @@ class TagService {
|
||||
}
|
||||
|
||||
$fileId = $this->homeFolder->get($path)->getId();
|
||||
if ($fileId === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$currentTags = $this->tagger->getTagsForObjects([$fileId]);
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ class ConversionApiControllerTest extends TestCase {
|
||||
$this->request = $this->createMock(IRequest::class);
|
||||
$this->fileConversionManager = $this->createMock(IConversionManager::class);
|
||||
$this->file = $this->createMock(File::class);
|
||||
$this->file->method('isReadable')->willReturn(true);
|
||||
$this->l10n = $this->createMock(IL10N::class);
|
||||
$this->user = 'userid';
|
||||
|
||||
|
||||
@@ -9,12 +9,14 @@ declare(strict_types=1);
|
||||
|
||||
use OC\Files\FileInfo;
|
||||
use OCA\Files\Helper;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
|
||||
class HelperTest extends \Test\TestCase {
|
||||
private static function makeFileInfo($name, $size, $mtime, $isDir = false): FileInfo {
|
||||
private function makeFileInfo($name, $size, $mtime, $isDir = false): FileInfo {
|
||||
return new FileInfo(
|
||||
'/' . $name,
|
||||
null,
|
||||
$this->createMock(IStorage::class),
|
||||
'/',
|
||||
[
|
||||
'name' => $name,
|
||||
@@ -23,21 +25,21 @@ class HelperTest extends \Test\TestCase {
|
||||
'type' => $isDir ? 'dir' : 'file',
|
||||
'mimetype' => $isDir ? 'httpd/unix-directory' : 'application/octet-stream'
|
||||
],
|
||||
null
|
||||
$this->createMock(IMountPoint::class),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file list for testing
|
||||
*/
|
||||
private static function getTestFileList(): array {
|
||||
private function getTestFileList(): array {
|
||||
return [
|
||||
self::makeFileInfo('a.txt', 4, 2.3 * pow(10, 9)),
|
||||
self::makeFileInfo('q.txt', 5, 150),
|
||||
self::makeFileInfo('subdir2', 87, 128, true),
|
||||
self::makeFileInfo('b.txt', 2.2 * pow(10, 9), 800),
|
||||
self::makeFileInfo('o.txt', 12, 100),
|
||||
self::makeFileInfo('subdir', 88, 125, true),
|
||||
$this->makeFileInfo('a.txt', 4, 2.3 * pow(10, 9)),
|
||||
$this->makeFileInfo('q.txt', 5, 150),
|
||||
$this->makeFileInfo('subdir2', 87, 128, true),
|
||||
$this->makeFileInfo('b.txt', 2.2 * pow(10, 9), 800),
|
||||
$this->makeFileInfo('o.txt', 12, 100),
|
||||
$this->makeFileInfo('subdir', 88, 125, true),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -81,7 +83,7 @@ class HelperTest extends \Test\TestCase {
|
||||
if (($sort === 'mtime') && (PHP_INT_SIZE < 8)) {
|
||||
$this->markTestSkipped('Skip mtime sorting on 32bit');
|
||||
}
|
||||
$files = self::getTestFileList();
|
||||
$files = $this->getTestFileList();
|
||||
$files = Helper::sortFiles($files, $sort, $sortDescending);
|
||||
$fileNames = [];
|
||||
foreach ($files as $fileInfo) {
|
||||
|
||||
@@ -90,7 +90,7 @@ class ListShares extends Base {
|
||||
if (is_numeric($file)) {
|
||||
return (int)$file;
|
||||
}
|
||||
return $this->getFile($file)->getId();
|
||||
return $this->getFile($file)->getId() ?? -1;
|
||||
}
|
||||
|
||||
private function getFile(string $file): Node {
|
||||
|
||||
@@ -73,7 +73,7 @@ class DeletedShareAPIController extends OCSController {
|
||||
if (!$node) {
|
||||
// fallback to guessing the path
|
||||
$node = $userFolder->get($share->getTarget());
|
||||
if ($node === null || $share->getTarget() === '') {
|
||||
if ($share->getTarget() === '') {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ class ShareAPIController extends OCSController {
|
||||
if (!$node) {
|
||||
// fallback to guessing the path
|
||||
$node = $userFolder->get($share->getTarget());
|
||||
if ($node === null || $share->getTarget() === '') {
|
||||
if ($share->getTarget() === '') {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
@@ -200,9 +200,9 @@ class ShareAPIController extends OCSController {
|
||||
$result['has_preview'] = $this->previewManager->isAvailable($node);
|
||||
$result['storage_id'] = $node->getStorage()->getId();
|
||||
$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
|
||||
$result['item_source'] = $node->getId();
|
||||
$result['file_source'] = $node->getId();
|
||||
$result['file_parent'] = $node->getParent()->getId();
|
||||
$result['item_source'] = $node->getId() ?? -1;
|
||||
$result['file_source'] = $node->getId() ?? -1;
|
||||
$result['file_parent'] = $node->getParent()->getId() ?? -1;
|
||||
$result['file_target'] = $share->getTarget();
|
||||
$result['item_size'] = $node->getSize();
|
||||
$result['item_mtime'] = $node->getMTime();
|
||||
@@ -1440,7 +1440,7 @@ class ShareAPIController extends OCSController {
|
||||
if (!$node) {
|
||||
// fallback to guessing the path
|
||||
$node = $userFolder->get($share->getTarget());
|
||||
if ($node === null || $share->getTarget() === '') {
|
||||
if ($share->getTarget() === '') {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,8 +138,8 @@ class ShareInfoController extends ApiController {
|
||||
private function format(Node $node, int $permissionMask): array {
|
||||
$entry = [];
|
||||
|
||||
$entry['id'] = $node->getId();
|
||||
$entry['parentId'] = $node->getParent()->getId();
|
||||
$entry['id'] = $node->getId() ?? -1;
|
||||
$entry['parentId'] = $node->getParent()->getId() ?? -1;
|
||||
$entry['mtime'] = $node->getMTime();
|
||||
|
||||
$entry['name'] = $node->getName();
|
||||
|
||||
@@ -522,7 +522,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
public function testDeleteShareOwnerless(): void {
|
||||
$ocs = $this->mockFormatShare();
|
||||
|
||||
$mount = $this->createMock(IShareOwnerlessMount::class);
|
||||
$mount = $this->createMockForIntersectionOfInterfaces([IShareOwnerlessMount::class, IMountPoint::class]);
|
||||
|
||||
$file = $this->createMock(File::class);
|
||||
$file
|
||||
@@ -609,7 +609,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
?string $password = null,
|
||||
string $label = '',
|
||||
?IShareAttributes $attributes = null,
|
||||
): MockObject {
|
||||
): IShare&MockObject {
|
||||
$share = $this->createMock(IShare::class);
|
||||
$share->method('getId')->willReturn($id);
|
||||
$share->method('getShareType')->willReturn($shareType);
|
||||
@@ -855,6 +855,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
$mountPoint->method('getMountType')->willReturn('');
|
||||
|
||||
$nodeParams = $shareParams[5];
|
||||
/** @var \OCP\Files\Node&MockObject $node */
|
||||
$node = $this->createMock($nodeParams['class']);
|
||||
$node->method('getId')->willReturn($nodeParams['id']);
|
||||
$node->method('getPath')->willReturn($nodeParams['path']);
|
||||
@@ -863,7 +864,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
$node->method('getSize')->willReturn(123465);
|
||||
$node->method('getMTime')->willReturn(1234567890);
|
||||
$node->method('getMimeType')->willReturn($nodeParams['mimeType']);
|
||||
$node->method('getMountPoint')->willReturn($mountPoint);
|
||||
$node->method('getInternalPath')->willReturn(ltrim($nodeParams['path'], '/'));
|
||||
|
||||
$shareParams[5] = $node;
|
||||
|
||||
@@ -4011,7 +4012,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
public function testUpdateShareOwnerless(): void {
|
||||
$ocs = $this->mockFormatShare();
|
||||
|
||||
$mount = $this->createMock(IShareOwnerlessMount::class);
|
||||
$mount = $this->createMockForIntersectionOfInterfaces([IShareOwnerlessMount::class, IMountPoint::class]);
|
||||
|
||||
$file = $this->createMock(File::class);
|
||||
$file
|
||||
@@ -4942,6 +4943,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
$expects['attributes'] = \json_encode($shareParams['attributes']);
|
||||
}
|
||||
if (isset($shareParams['node'])) {
|
||||
/** @var MockObject&\OCP\Files\Node $node */
|
||||
$node = $this->createMock($shareParams['node']['class']);
|
||||
|
||||
$node->method('getMimeType')->willReturn($shareParams['node']['mimeType']);
|
||||
@@ -4951,6 +4953,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
$node->method('getMountPoint')->willReturn($mountPoint);
|
||||
|
||||
$node->method('getPath')->willReturn($shareParams['node']['path']);
|
||||
$node->method('getInternalPath')->willReturn(ltrim($shareParams['node']['path'], '/'));
|
||||
$node->method('getId')->willReturn($shareParams['node']['id']);
|
||||
|
||||
$parent = $this->createMock(Folder::class);
|
||||
@@ -5169,6 +5172,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
|
||||
$file->method('getSize')->willReturn(123456);
|
||||
$file->method('getMTime')->willReturn(1234567890);
|
||||
$file->method('getInternalPath')->willReturn(ltrim('file', '/'));
|
||||
|
||||
$mountPoint = $this->createMock(IMountPoint::class);
|
||||
$mountPoint->method('getMountType')->willReturn('');
|
||||
|
||||
@@ -72,8 +72,13 @@ class SyncLivePhotosListener implements IEventListener {
|
||||
$sourceFile = $event->getSource();
|
||||
|
||||
if ($sourceFile->getMimetype() === 'video/quicktime') {
|
||||
if (isset($this->pendingRestores[$peerFile->getId()])) {
|
||||
unset($this->pendingRestores[$peerFile->getId()]);
|
||||
$peerFileId = $peerFile->getId();
|
||||
if ($peerFileId === null) {
|
||||
throw new \LogicException('Invalid peer file given with a null id');
|
||||
}
|
||||
|
||||
if (isset($this->pendingRestores[$peerFileId])) {
|
||||
unset($this->pendingRestores[$peerFileId]);
|
||||
return;
|
||||
} else {
|
||||
$event->abortOperation(new NotPermittedException('Cannot restore the video part of a live photo'));
|
||||
@@ -97,7 +102,12 @@ class SyncLivePhotosListener implements IEventListener {
|
||||
$event->abortOperation(new NotFoundException("Couldn't find peer file in trashbin"));
|
||||
}
|
||||
|
||||
$this->pendingRestores[$sourceFile->getId()] = true;
|
||||
$sourceFileId = $sourceFile->getId();
|
||||
if ($sourceFileId === null) {
|
||||
throw new \LogicException('Invalid source file given with a null id');
|
||||
}
|
||||
|
||||
$this->pendingRestores[$sourceFileId] = true;
|
||||
try {
|
||||
$this->trashManager->restoreItem($trashItem);
|
||||
} catch (\Throwable $ex) {
|
||||
|
||||
@@ -31,7 +31,7 @@ abstract class AbstractTrash implements ITrash {
|
||||
}
|
||||
|
||||
public function getFileId(): int {
|
||||
return $this->data->getId();
|
||||
return $this->data->getId() ?? -1;
|
||||
}
|
||||
|
||||
public function getFileInfo(): FileInfo {
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
namespace OCA\Files_Trashbin\Trash;
|
||||
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUser;
|
||||
use Override;
|
||||
|
||||
class TrashItem implements ITrashItem {
|
||||
|
||||
@@ -46,126 +49,150 @@ class TrashItem implements ITrashItem {
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function getEtag() {
|
||||
return $this->fileInfo->getEtag();
|
||||
}
|
||||
|
||||
public function getSize($includeMounts = true) {
|
||||
return $this->fileInfo->getSize($includeMounts);
|
||||
}
|
||||
|
||||
public function getMtime() {
|
||||
return $this->fileInfo->getMtime();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->fileInfo->getName();
|
||||
}
|
||||
|
||||
public function getInternalPath() {
|
||||
return $this->fileInfo->getInternalPath();
|
||||
}
|
||||
|
||||
public function getPath() {
|
||||
return $this->fileInfo->getPath();
|
||||
}
|
||||
|
||||
public function getMimetype(): string {
|
||||
return $this->fileInfo->getMimetype();
|
||||
}
|
||||
|
||||
public function getMimePart() {
|
||||
return $this->fileInfo->getMimePart();
|
||||
}
|
||||
|
||||
public function getStorage() {
|
||||
return $this->fileInfo->getStorage();
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
return $this->fileInfo->getId();
|
||||
}
|
||||
|
||||
public function isEncrypted() {
|
||||
return $this->fileInfo->isEncrypted();
|
||||
}
|
||||
|
||||
public function getPermissions() {
|
||||
return $this->fileInfo->getPermissions();
|
||||
}
|
||||
|
||||
public function getType() {
|
||||
return $this->fileInfo->getType();
|
||||
}
|
||||
|
||||
public function isReadable() {
|
||||
return $this->fileInfo->isReadable();
|
||||
}
|
||||
|
||||
public function isUpdateable() {
|
||||
return $this->fileInfo->isUpdateable();
|
||||
}
|
||||
|
||||
public function isCreatable() {
|
||||
return $this->fileInfo->isCreatable();
|
||||
}
|
||||
|
||||
public function isDeletable() {
|
||||
return $this->fileInfo->isDeletable();
|
||||
}
|
||||
|
||||
public function isShareable() {
|
||||
return $this->fileInfo->isShareable();
|
||||
}
|
||||
|
||||
public function isShared() {
|
||||
return $this->fileInfo->isShared();
|
||||
}
|
||||
|
||||
public function isMounted() {
|
||||
return $this->fileInfo->isMounted();
|
||||
}
|
||||
|
||||
public function getMountPoint() {
|
||||
return $this->fileInfo->getMountPoint();
|
||||
}
|
||||
|
||||
public function getOwner() {
|
||||
return $this->fileInfo->getOwner();
|
||||
}
|
||||
|
||||
public function getChecksum() {
|
||||
return $this->fileInfo->getChecksum();
|
||||
}
|
||||
|
||||
public function getExtension(): string {
|
||||
return $this->fileInfo->getExtension();
|
||||
}
|
||||
|
||||
public function getTitle(): string {
|
||||
return $this->getOriginalLocation();
|
||||
}
|
||||
|
||||
public function getCreationTime(): int {
|
||||
return $this->fileInfo->getCreationTime();
|
||||
}
|
||||
|
||||
public function getUploadTime(): int {
|
||||
return $this->fileInfo->getUploadTime();
|
||||
}
|
||||
|
||||
public function getParentId(): int {
|
||||
return $this->fileInfo->getParentId();
|
||||
}
|
||||
|
||||
public function getDeletedBy(): ?IUser {
|
||||
return $this->deletedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return array<string, int|string|bool|float|string[]|int[]>
|
||||
*/
|
||||
#[Override]
|
||||
public function getEtag(): string {
|
||||
return $this->fileInfo->getEtag();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getSize(bool $includeMounts = true): int|float {
|
||||
return $this->fileInfo->getSize($includeMounts);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMtime(): int {
|
||||
return $this->fileInfo->getMtime();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getName(): string {
|
||||
return $this->fileInfo->getName();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getInternalPath(): string {
|
||||
return $this->fileInfo->getInternalPath();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getPath(): string {
|
||||
return $this->fileInfo->getPath();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMimetype(): string {
|
||||
return $this->fileInfo->getMimetype();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMimePart(): string {
|
||||
return $this->fileInfo->getMimePart();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getStorage(): IStorage {
|
||||
return $this->fileInfo->getStorage();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getId(): ?int {
|
||||
return $this->fileInfo->getId();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isEncrypted(): bool {
|
||||
return $this->fileInfo->isEncrypted();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getPermissions(): int {
|
||||
return $this->fileInfo->getPermissions();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getType(): string {
|
||||
return $this->fileInfo->getType();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isReadable(): bool {
|
||||
return $this->fileInfo->isReadable();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isUpdateable(): bool {
|
||||
return $this->fileInfo->isUpdateable();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isCreatable(): bool {
|
||||
return $this->fileInfo->isCreatable();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isDeletable(): bool {
|
||||
return $this->fileInfo->isDeletable();
|
||||
}
|
||||
|
||||
public function isShareable(): bool {
|
||||
return $this->fileInfo->isShareable();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isShared(): bool {
|
||||
return $this->fileInfo->isShared();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isMounted(): bool {
|
||||
return $this->fileInfo->isMounted();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMountPoint(): IMountPoint {
|
||||
return $this->fileInfo->getMountPoint();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getOwner(): ?IUser {
|
||||
return $this->fileInfo->getOwner();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getChecksum(): string {
|
||||
return $this->fileInfo->getChecksum();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getExtension(): string {
|
||||
return $this->fileInfo->getExtension();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getTitle(): string {
|
||||
return $this->getOriginalLocation();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getCreationTime(): int {
|
||||
return $this->fileInfo->getCreationTime();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getUploadTime(): int {
|
||||
return $this->fileInfo->getUploadTime();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParentId(): int {
|
||||
return $this->fileInfo->getParentId();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMetadata(): array {
|
||||
return $this->fileInfo->getMetadata();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
namespace OCA\Files_Versions\Listener;
|
||||
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use OC\DB\Exceptions\DbalException;
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\Mount\MoveableMount;
|
||||
use OC\Files\Node\NonExistingFile;
|
||||
@@ -122,7 +121,12 @@ class FileEventsListener implements IEventListener {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->nodesTouched[$node->getId()] = $node;
|
||||
$nodeId = $node->getId();
|
||||
if ($nodeId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->nodesTouched[$nodeId] = $node;
|
||||
}
|
||||
|
||||
public function touch_hook(Node $node): void {
|
||||
@@ -142,13 +146,17 @@ class FileEventsListener implements IEventListener {
|
||||
return;
|
||||
}
|
||||
|
||||
$previousNode = $this->nodesTouched[$node->getId()] ?? null;
|
||||
$nodeId = $node->getId();
|
||||
if ($nodeId === null) {
|
||||
throw new \LogicException('Invalid node given');
|
||||
}
|
||||
$previousNode = $this->nodesTouched[$nodeId] ?? null;
|
||||
|
||||
if ($previousNode === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset($this->nodesTouched[$node->getId()]);
|
||||
unset($this->nodesTouched[$nodeId]);
|
||||
|
||||
try {
|
||||
if ($node instanceof File && $this->versionManager instanceof INeedSyncVersionBackend) {
|
||||
@@ -157,15 +165,15 @@ class FileEventsListener implements IEventListener {
|
||||
// We update the timestamp of the version entity associated with the previousNode.
|
||||
$this->versionManager->updateVersionEntity($node, $revision, ['timestamp' => $node->getMTime()]);
|
||||
}
|
||||
} catch (DbalException $ex) {
|
||||
} catch (Exception $ex) {
|
||||
// Ignore UniqueConstraintViolationException, as we are probably in the middle of a rollback
|
||||
// Where the previous node would temporary have the mtime of the old version, so the rollback touches it to fix it.
|
||||
if (!($ex->getPrevious() instanceof UniqueConstraintViolationException)) {
|
||||
// Where the previous node would temporarily have the mtime of the old version, so the rollback touches it to fix it.
|
||||
if ($ex->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
|
||||
throw $ex;
|
||||
}
|
||||
} catch (DoesNotExistException $ex) {
|
||||
// Ignore DoesNotExistException, as we are probably in the middle of a rollback
|
||||
// Where the previous node would temporary have a wrong mtime, so the rollback touches it to fix it.
|
||||
// Where the previous node would temporarily have a wrong mtime, so the rollback touches it to fix it.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,8 +216,13 @@ class FileEventsListener implements IEventListener {
|
||||
$path = $this->getPathForNode($node);
|
||||
$result = Storage::store($path);
|
||||
|
||||
$nodeId = $node->getId();
|
||||
if ($nodeId === null) {
|
||||
throw new \LogicException('Invalid node given');
|
||||
}
|
||||
|
||||
// Store the result of the version creation so it can be used in post_write_hook.
|
||||
$this->writeHookInfo[$node->getId()] = [
|
||||
$this->writeHookInfo[$nodeId] = [
|
||||
'previousNode' => $node,
|
||||
'versionCreated' => $result !== false
|
||||
];
|
||||
@@ -235,7 +248,12 @@ class FileEventsListener implements IEventListener {
|
||||
return;
|
||||
}
|
||||
|
||||
$writeHookInfo = $this->writeHookInfo[$node->getId()] ?? null;
|
||||
$nodeId = $node->getId();
|
||||
if ($nodeId === null) {
|
||||
throw new \LogicException('Invalid node given');
|
||||
}
|
||||
|
||||
$writeHookInfo = $this->writeHookInfo[$nodeId] ?? null;
|
||||
|
||||
if ($writeHookInfo === null) {
|
||||
return;
|
||||
|
||||
@@ -885,16 +885,16 @@ class Storage {
|
||||
if ($quota >= 0) {
|
||||
if ($softQuota) {
|
||||
$root = Server::get(IRootFolder::class);
|
||||
$userFolder = $root->getUserFolder($uid);
|
||||
if (is_null($userFolder)) {
|
||||
$availableSpace = 0;
|
||||
} else {
|
||||
try {
|
||||
$userFolder = $root->getUserFolder($uid);
|
||||
$free = $quota - $userFolder->getSize(false); // remaining free space for user
|
||||
if ($free > 0) {
|
||||
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions
|
||||
} else {
|
||||
$availableSpace = $free - $versionsSize;
|
||||
}
|
||||
} catch (NoUserException $e) {
|
||||
$availableSpace = 0;
|
||||
}
|
||||
} else {
|
||||
$availableSpace = $quota;
|
||||
|
||||
@@ -136,7 +136,7 @@ class Listener {
|
||||
foreach ($mounts as $mount) {
|
||||
$owner = $mount->getUser()->getUID();
|
||||
$ownerFolder = $this->rootFolder->getUserFolder($owner);
|
||||
$nodes = $ownerFolder->getById($event->getObjectId());
|
||||
$nodes = $ownerFolder->getById((int)$event->getObjectId());
|
||||
if (!empty($nodes)) {
|
||||
/** @var Node $node */
|
||||
$node = array_shift($nodes);
|
||||
|
||||
@@ -136,9 +136,9 @@ class File implements IEntity, IDisplayText, IUrl, IIcon, IContextPortation {
|
||||
if (!$this->event instanceof MapperEvent || $this->event->getObjectType() !== 'files') {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
$nodes = $this->root->getById((int)$this->event->getObjectId());
|
||||
if (is_array($nodes) && isset($nodes[0])) {
|
||||
$this->node = $nodes[0];
|
||||
$node = $this->root->getFirstNodeById((int)$this->event->getObjectId());
|
||||
if ($node !== null) {
|
||||
$this->node = $node;
|
||||
return $this->node;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -566,11 +566,6 @@
|
||||
<MoreSpecificReturnType>
|
||||
<code><![CDATA[Folder]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
<NullArgument>
|
||||
<code><![CDATA[null]]></code>
|
||||
<code><![CDATA[null]]></code>
|
||||
<code><![CDATA[null]]></code>
|
||||
</NullArgument>
|
||||
<ParamNameMismatch>
|
||||
<code><![CDATA[$fullSourcePath]]></code>
|
||||
</ParamNameMismatch>
|
||||
@@ -641,14 +636,6 @@
|
||||
<code><![CDATA[unlockFile]]></code>
|
||||
<code><![CDATA[verifyPath]]></code>
|
||||
</InternalMethod>
|
||||
<InvalidNullableReturnType>
|
||||
<code><![CDATA[int]]></code>
|
||||
<code><![CDATA[integer]]></code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement>
|
||||
<code><![CDATA[$this->info->getId()]]></code>
|
||||
<code><![CDATA[$this->info->getId()]]></code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="apps/dav/lib/Connector/Sabre/ObjectTree.php">
|
||||
<InternalMethod>
|
||||
@@ -1821,14 +1808,6 @@
|
||||
<code><![CDATA[new View('/' . $user . '/files_trashbin/files')]]></code>
|
||||
</InternalMethod>
|
||||
</file>
|
||||
<file src="apps/files_trashbin/lib/Sabre/AbstractTrash.php">
|
||||
<InvalidNullableReturnType>
|
||||
<code><![CDATA[int]]></code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement>
|
||||
<code><![CDATA[$this->data->getId()]]></code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="apps/files_trashbin/lib/Sabre/AbstractTrashFolder.php">
|
||||
<InvalidReturnStatement>
|
||||
<code><![CDATA[$entry]]></code>
|
||||
@@ -3724,44 +3703,11 @@
|
||||
<code><![CDATA[array{int, string, int}]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
</file>
|
||||
<file src="lib/private/Files/Filesystem.php">
|
||||
<LessSpecificReturnStatement>
|
||||
<code><![CDATA[$mount->getStorage()]]></code>
|
||||
<code><![CDATA[self::getMountManager()->findByNumericId($id)]]></code>
|
||||
<code><![CDATA[self::getMountManager()->findByStorageId($id)]]></code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType>
|
||||
<code><![CDATA[Mount\MountPoint[]]]></code>
|
||||
<code><![CDATA[Mount\MountPoint[]]]></code>
|
||||
<code><![CDATA[\OC\Files\Storage\Storage|null]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
</file>
|
||||
<file src="lib/private/Files/Mount/MountPoint.php">
|
||||
<UndefinedInterfaceMethod>
|
||||
<code><![CDATA[wrap]]></code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="lib/private/Files/Node/File.php">
|
||||
<InvalidReturnStatement>
|
||||
<code><![CDATA[$this->view->hash($type, $this->path, $raw)]]></code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType>
|
||||
<code><![CDATA[string]]></code>
|
||||
</InvalidReturnType>
|
||||
</file>
|
||||
<file src="lib/private/Files/Node/Folder.php">
|
||||
<LessSpecificReturnStatement>
|
||||
<code><![CDATA[array_map(function (FileInfo $file) {
|
||||
return $this->createNode($file->getPath(), $file);
|
||||
}, $files)]]></code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificImplementedParamType>
|
||||
<code><![CDATA[$node]]></code>
|
||||
</MoreSpecificImplementedParamType>
|
||||
<MoreSpecificReturnType>
|
||||
<code><![CDATA[\OC\Files\Node\Node[]]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
</file>
|
||||
<file src="lib/private/Files/Node/HookConnector.php">
|
||||
<UndefinedInterfaceMethod>
|
||||
<code><![CDATA[emit]]></code>
|
||||
@@ -3779,64 +3725,6 @@
|
||||
<code><![CDATA[emit]]></code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="lib/private/Files/Node/LazyFolder.php">
|
||||
<InvalidReturnStatement>
|
||||
<code><![CDATA[$this->__call(__FUNCTION__, func_get_args())]]></code>
|
||||
</InvalidReturnStatement>
|
||||
</file>
|
||||
<file src="lib/private/Files/Node/LazyUserFolder.php">
|
||||
<LessSpecificReturnStatement>
|
||||
<code><![CDATA[$node]]></code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType>
|
||||
<code><![CDATA[Folder]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
</file>
|
||||
<file src="lib/private/Files/Node/Node.php">
|
||||
<InvalidNullableReturnType>
|
||||
<code><![CDATA[FileInfo]]></code>
|
||||
</InvalidNullableReturnType>
|
||||
<InvalidReturnType>
|
||||
<code><![CDATA[getChecksum]]></code>
|
||||
</InvalidReturnType>
|
||||
<LessSpecificReturnStatement>
|
||||
<code><![CDATA[$this->parent]]></code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType>
|
||||
<code><![CDATA[INode|IRootFolder]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
<NullableReturnStatement>
|
||||
<code><![CDATA[$this->fileInfo]]></code>
|
||||
</NullableReturnStatement>
|
||||
<ParamNameMismatch>
|
||||
<code><![CDATA[$type]]></code>
|
||||
</ParamNameMismatch>
|
||||
<UndefinedInterfaceMethod>
|
||||
<code><![CDATA[$this->fileInfo]]></code>
|
||||
<code><![CDATA[$this->fileInfo]]></code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="lib/private/Files/Node/Root.php">
|
||||
<LessSpecificReturnStatement>
|
||||
<code><![CDATA[$folders]]></code>
|
||||
<code><![CDATA[$this->mountManager->findByNumericId($numericId)]]></code>
|
||||
<code><![CDATA[$this->mountManager->findByStorageId($storageId)]]></code>
|
||||
<code><![CDATA[$this->mountManager->findIn($mountPoint)]]></code>
|
||||
<code><![CDATA[$this->user]]></code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType>
|
||||
<code><![CDATA[MountPoint[]]]></code>
|
||||
<code><![CDATA[\OC\Files\Mount\MountPoint[]]]></code>
|
||||
<code><![CDATA[\OC\Files\Mount\MountPoint[]]]></code>
|
||||
<code><![CDATA[\OC\User\User]]></code>
|
||||
</MoreSpecificReturnType>
|
||||
<NullableReturnStatement>
|
||||
<code><![CDATA[$this->user]]></code>
|
||||
</NullableReturnStatement>
|
||||
<UndefinedMethod>
|
||||
<code><![CDATA[remove]]></code>
|
||||
</UndefinedMethod>
|
||||
</file>
|
||||
<file src="lib/private/Files/ObjectStore/S3ConnectionTrait.php">
|
||||
<InternalClass>
|
||||
<code><![CDATA[ClientResolver::_default_signature_provider()]]></code>
|
||||
|
||||
@@ -1737,6 +1737,7 @@ return array(
|
||||
'OC\\Files\\Filesystem' => $baseDir . '/lib/private/Files/Filesystem.php',
|
||||
'OC\\Files\\Lock\\LockManager' => $baseDir . '/lib/private/Files/Lock/LockManager.php',
|
||||
'OC\\Files\\Mount\\CacheMountProvider' => $baseDir . '/lib/private/Files/Mount/CacheMountProvider.php',
|
||||
'OC\\Files\\Mount\\DummyMountPoint' => $baseDir . '/lib/private/Files/Mount/DummyMountPoint.php',
|
||||
'OC\\Files\\Mount\\HomeMountPoint' => $baseDir . '/lib/private/Files/Mount/HomeMountPoint.php',
|
||||
'OC\\Files\\Mount\\LocalHomeMountProvider' => $baseDir . '/lib/private/Files/Mount/LocalHomeMountProvider.php',
|
||||
'OC\\Files\\Mount\\Manager' => $baseDir . '/lib/private/Files/Mount/Manager.php',
|
||||
|
||||
@@ -1778,6 +1778,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
||||
'OC\\Files\\Filesystem' => __DIR__ . '/../../..' . '/lib/private/Files/Filesystem.php',
|
||||
'OC\\Files\\Lock\\LockManager' => __DIR__ . '/../../..' . '/lib/private/Files/Lock/LockManager.php',
|
||||
'OC\\Files\\Mount\\CacheMountProvider' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/CacheMountProvider.php',
|
||||
'OC\\Files\\Mount\\DummyMountPoint' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/DummyMountPoint.php',
|
||||
'OC\\Files\\Mount\\HomeMountPoint' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/HomeMountPoint.php',
|
||||
'OC\\Files\\Mount\\LocalHomeMountProvider' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/LocalHomeMountProvider.php',
|
||||
'OC\\Files\\Mount\\Manager' => __DIR__ . '/../../..' . '/lib/private/Files/Mount/Manager.php',
|
||||
|
||||
@@ -149,6 +149,6 @@ class AppData implements IAppData {
|
||||
}
|
||||
|
||||
public function getId(): int {
|
||||
return $this->getAppDataFolder()->getId();
|
||||
return $this->getAppDataFolder()->getId() ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,61 +12,29 @@ use OCA\Files_Sharing\External\Mount;
|
||||
use OCA\Files_Sharing\ISharedMountPoint;
|
||||
use OCP\Files\Cache\ICacheEntry;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUser;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* @template-implements \ArrayAccess<string,mixed>
|
||||
*/
|
||||
class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||
private array|ICacheEntry $data;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $internalPath;
|
||||
|
||||
/**
|
||||
* @var \OCP\Files\Mount\IMountPoint
|
||||
*/
|
||||
private $mount;
|
||||
|
||||
private string $path;
|
||||
private IStorage $storage;
|
||||
private string $internalPath;
|
||||
private IMountPoint $mount;
|
||||
private ?IUser $owner;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
/** @var string[] */
|
||||
private array $childEtags = [];
|
||||
|
||||
/**
|
||||
* @var IMountPoint[]
|
||||
*/
|
||||
/** @var IMountPoint[] */
|
||||
private array $subMounts = [];
|
||||
|
||||
private bool $subMountsUsed = false;
|
||||
|
||||
/**
|
||||
* The size of the file/folder without any sub mount
|
||||
*/
|
||||
/** The size of the file/folder without any sub mount */
|
||||
private int|float $rawSize = 0;
|
||||
|
||||
/**
|
||||
* @param string|boolean $path
|
||||
* @param Storage\Storage $storage
|
||||
* @param string $internalPath
|
||||
* @param array|ICacheEntry $data
|
||||
* @param IMountPoint $mount
|
||||
* @param ?IUser $owner
|
||||
*/
|
||||
public function __construct($path, $storage, $internalPath, $data, $mount, $owner = null) {
|
||||
public function __construct(string|bool $path, IStorage $storage, string $internalPath, array|ICacheEntry $data, IMountPoint $mount, ?IUser $owner = null) {
|
||||
$this->path = $path;
|
||||
$this->storage = $storage;
|
||||
$this->internalPath = $internalPath;
|
||||
@@ -106,30 +74,23 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath() {
|
||||
#[Override]
|
||||
public function getPath(): string {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getStorage() {
|
||||
#[Override]
|
||||
public function getStorage(): IStorage {
|
||||
return $this->storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInternalPath() {
|
||||
#[Override]
|
||||
public function getInternalPath(): string {
|
||||
return $this->internalPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get FileInfo ID or null in case of part file
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getId() {
|
||||
#[Override]
|
||||
public function getId(): ?int {
|
||||
return isset($this->data['fileid']) ? (int)$this->data['fileid'] : null;
|
||||
}
|
||||
|
||||
@@ -137,40 +98,31 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||
return $this->data['mimetype'] ?? 'application/octet-stream';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMimePart() {
|
||||
#[Override]
|
||||
public function getMimePart(): string {
|
||||
return $this->data['mimepart'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
#[Override]
|
||||
public function getName(): string {
|
||||
return empty($this->data['name'])
|
||||
? basename($this->getPath())
|
||||
: $this->data['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEtag() {
|
||||
#[Override]
|
||||
public function getEtag(): string {
|
||||
$this->updateEntryFromSubMounts();
|
||||
if (count($this->childEtags) > 0) {
|
||||
$combinedEtag = $this->data['etag'] . '::' . implode('::', $this->childEtags);
|
||||
return md5($combinedEtag);
|
||||
} else {
|
||||
return $this->data['etag'];
|
||||
return $this->data['etag'] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeMounts
|
||||
* @return int|float
|
||||
*/
|
||||
public function getSize($includeMounts = true) {
|
||||
#[Override]
|
||||
public function getSize(bool $includeMounts = true): int|float {
|
||||
if ($includeMounts) {
|
||||
$this->updateEntryFromSubMounts();
|
||||
|
||||
@@ -184,18 +136,14 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMTime() {
|
||||
#[Override]
|
||||
public function getMTime(): int {
|
||||
$this->updateEntryFromSubMounts();
|
||||
return (int)$this->data['mtime'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEncrypted() {
|
||||
#[Override]
|
||||
public function isEncrypted(): bool {
|
||||
return $this->data['encrypted'] ?? false;
|
||||
}
|
||||
|
||||
@@ -206,108 +154,81 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||
return isset($this->data['encryptedVersion']) ? (int)$this->data['encryptedVersion'] : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPermissions() {
|
||||
return (int)$this->data['permissions'];
|
||||
#[Override]
|
||||
public function getPermissions(): int {
|
||||
/** @var \OCP\Constants::PERMISSION_* $permission */
|
||||
$permission = (int)$this->data['permissions'];
|
||||
return $permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string \OCP\Files\FileInfo::TYPE_FILE|\OCP\Files\FileInfo::TYPE_FOLDER
|
||||
*/
|
||||
public function getType() {
|
||||
#[Override]
|
||||
public function getType(): string {
|
||||
if (!isset($this->data['type'])) {
|
||||
$this->data['type'] = ($this->getMimetype() === self::MIMETYPE_FOLDER) ? self::TYPE_FOLDER : self::TYPE_FILE;
|
||||
}
|
||||
return $this->data['type'];
|
||||
}
|
||||
|
||||
public function getData() {
|
||||
public function getData(): array|ICacheEntry {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $permissions
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkPermissions($permissions) {
|
||||
protected function checkPermissions(int $permissions): bool {
|
||||
return ($this->getPermissions() & $permissions) === $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable() {
|
||||
#[Override]
|
||||
public function isReadable(): bool {
|
||||
return $this->checkPermissions(\OCP\Constants::PERMISSION_READ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isUpdateable() {
|
||||
#[Override]
|
||||
public function isUpdateable(): bool {
|
||||
return $this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether new files or folders can be created inside this folder
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCreatable() {
|
||||
#[Override]
|
||||
public function isCreatable(): bool {
|
||||
return $this->checkPermissions(\OCP\Constants::PERMISSION_CREATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeletable() {
|
||||
#[Override]
|
||||
public function isDeletable(): bool {
|
||||
return $this->checkPermissions(\OCP\Constants::PERMISSION_DELETE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isShareable() {
|
||||
#[Override]
|
||||
public function isShareable(): bool {
|
||||
return $this->checkPermissions(\OCP\Constants::PERMISSION_SHARE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file or folder is shared
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isShared() {
|
||||
#[Override]
|
||||
public function isShared(): bool {
|
||||
return $this->mount instanceof ISharedMountPoint;
|
||||
}
|
||||
|
||||
public function isMounted() {
|
||||
#[Override]
|
||||
public function isMounted(): bool {
|
||||
$isHome = $this->mount instanceof HomeMountPoint;
|
||||
return !$isHome && !$this->isShared();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mountpoint the file belongs to
|
||||
*
|
||||
* @return \OCP\Files\Mount\IMountPoint
|
||||
*/
|
||||
public function getMountPoint() {
|
||||
#[Override]
|
||||
public function getMountPoint(): IMountPoint {
|
||||
return $this->mount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the owner of the file
|
||||
*
|
||||
* @return ?IUser
|
||||
* Get the owner of the file.
|
||||
*/
|
||||
public function getOwner() {
|
||||
public function getOwner(): ?IUser {
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IMountPoint[] $mounts
|
||||
*/
|
||||
public function setSubMounts(array $mounts) {
|
||||
public function setSubMounts(array $mounts): void {
|
||||
$this->subMounts = $mounts;
|
||||
}
|
||||
|
||||
@@ -321,21 +242,23 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||
if ($subStorage) {
|
||||
$subCache = $subStorage->getCache('');
|
||||
$rootEntry = $subCache->get('');
|
||||
$this->addSubEntry($rootEntry, $mount->getMountPoint());
|
||||
if (!empty($rootEntry)) {
|
||||
$this->addSubEntry($rootEntry, $mount->getMountPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cache entry which is the child of this folder
|
||||
* Add a cache entry which is the child of this folder.
|
||||
*
|
||||
* Sets the size, etag and size to for cross-storage childs
|
||||
* Sets the size, etag and size to for cross-storage children.
|
||||
*
|
||||
* @param array|ICacheEntry $data cache entry for the child
|
||||
* @param string $entryPath full path of the child entry
|
||||
*/
|
||||
public function addSubEntry($data, $entryPath) {
|
||||
if (!$data) {
|
||||
public function addSubEntry(array|ICacheEntry $data, string $entryPath): void {
|
||||
if (empty($data)) {
|
||||
return;
|
||||
}
|
||||
$hasUnencryptedSize = isset($data['unencrypted_size']) && $data['unencrypted_size'] > 0;
|
||||
@@ -360,33 +283,32 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getChecksum() {
|
||||
return $this->data['checksum'];
|
||||
#[Override]
|
||||
public function getChecksum(): string {
|
||||
return $this->data['checksum'] ?? '';
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getExtension(): string {
|
||||
return pathinfo($this->getName(), PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getCreationTime(): int {
|
||||
return (int)$this->data['creation_time'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getUploadTime(): int {
|
||||
return (int)$this->data['upload_time'];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParentId(): int {
|
||||
return $this->data['parent'] ?? -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return array<string, int|string|bool|float|string[]|int[]>
|
||||
*/
|
||||
#[Override]
|
||||
public function getMetadata(): array {
|
||||
return $this->data['metadata'] ?? [];
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ class Filesystem {
|
||||
* get the storage mounted at $mountPoint
|
||||
*
|
||||
* @param string $mountPoint
|
||||
* @return \OC\Files\Storage\Storage|null
|
||||
* @return \OCP\Files\Storage\IStorage|null
|
||||
*/
|
||||
public static function getStorage($mountPoint) {
|
||||
$mount = self::getMountManager()->find($mountPoint);
|
||||
@@ -255,7 +255,7 @@ class Filesystem {
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return Mount\MountPoint[]
|
||||
* @return \OCP\Files\Mount\IMountPoint[]
|
||||
*/
|
||||
public static function getMountByStorageId($id) {
|
||||
return self::getMountManager()->findByStorageId($id);
|
||||
@@ -263,7 +263,7 @@ class Filesystem {
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return Mount\MountPoint[]
|
||||
* @return \OCP\Files\Mount\IMountPoint[]
|
||||
*/
|
||||
public static function getMountByNumericId($id) {
|
||||
return self::getMountManager()->findByNumericId($id);
|
||||
|
||||
70
lib/private/Files/Mount/DummyMountPoint.php
Normal file
70
lib/private/Files/Mount/DummyMountPoint.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH
|
||||
* SPDX-FileContributor: Carl Schwan
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC\Files\Mount;
|
||||
|
||||
use OC\Files\Storage\FailedStorage;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
|
||||
final class DummyMountPoint implements IMountPoint {
|
||||
public function getMountPoint(): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function setMountPoint($mountPoint): void {
|
||||
}
|
||||
|
||||
public function getStorage(): IStorage {
|
||||
return new FailedStorage(['exception' => new \LogicException('Dummy storage') ]);
|
||||
}
|
||||
|
||||
public function getStorageId(): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getNumericStorageId(): int {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getInternalPath($path): string {
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function wrapStorage($wrapper): void {
|
||||
}
|
||||
|
||||
public function getOption($name, $default): mixed {
|
||||
if ($name === 'previews') {
|
||||
return false;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
public function getOptions(): array {
|
||||
return ['previews' => false];
|
||||
}
|
||||
|
||||
public function getStorageRootId(): int {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getMountId(): ?int {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMountType(): string {
|
||||
return 'dummy';
|
||||
}
|
||||
|
||||
public function getMountProvider(): string {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -8,27 +8,18 @@
|
||||
namespace OC\Files\Node;
|
||||
|
||||
use OCP\Files\GenericFileException;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Lock\LockedException;
|
||||
use Override;
|
||||
|
||||
class File extends Node implements \OCP\Files\File {
|
||||
/**
|
||||
* Creates a Folder that represents a non-existing path
|
||||
*
|
||||
* @param string $path path
|
||||
* @return NonExistingFile non-existing node
|
||||
*/
|
||||
protected function createNonExistingNode($path) {
|
||||
#[Override]
|
||||
protected function createNonExistingNode(string $path): NonExistingFile {
|
||||
return new NonExistingFile($this->root, $this->view, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws NotPermittedException
|
||||
* @throws GenericFileException
|
||||
* @throws LockedException
|
||||
*/
|
||||
public function getContent() {
|
||||
#[Override]
|
||||
public function getContent(): string {
|
||||
if ($this->checkPermissions(\OCP\Constants::PERMISSION_READ)) {
|
||||
$content = $this->view->file_get_contents($this->path);
|
||||
if ($content === false) {
|
||||
@@ -40,13 +31,8 @@ class File extends Node implements \OCP\Files\File {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|resource $data
|
||||
* @throws NotPermittedException
|
||||
* @throws GenericFileException
|
||||
* @throws LockedException
|
||||
*/
|
||||
public function putContent($data) {
|
||||
#[Override]
|
||||
public function putContent($data): void {
|
||||
if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
|
||||
$this->sendHooks(['preWrite']);
|
||||
if ($this->view->file_put_contents($this->path, $data) === false) {
|
||||
@@ -59,13 +45,8 @@ class File extends Node implements \OCP\Files\File {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mode
|
||||
* @return resource|false
|
||||
* @throws NotPermittedException
|
||||
* @throws LockedException
|
||||
*/
|
||||
public function fopen($mode) {
|
||||
#[Override]
|
||||
public function fopen(string $mode) {
|
||||
$preHooks = [];
|
||||
$postHooks = [];
|
||||
$requiredPermissions = \OCP\Constants::PERMISSION_READ;
|
||||
@@ -100,12 +81,8 @@ class File extends Node implements \OCP\Files\File {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotPermittedException
|
||||
* @throws \OCP\Files\InvalidPathException
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
*/
|
||||
public function delete() {
|
||||
#[Override]
|
||||
public function delete(): void {
|
||||
if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
|
||||
$this->sendHooks(['preDelete']);
|
||||
$fileInfo = $this->getFileInfo();
|
||||
@@ -118,22 +95,16 @@ class File extends Node implements \OCP\Files\File {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param bool $raw
|
||||
* @return string
|
||||
*/
|
||||
public function hash($type, $raw = false) {
|
||||
return $this->view->hash($type, $this->path, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getChecksum() {
|
||||
return $this->getFileInfo()->getChecksum();
|
||||
#[Override]
|
||||
public function hash(string $type, bool $raw = false): string {
|
||||
$hash = $this->view->hash($type, $this->path, $raw);
|
||||
if ($hash === false) {
|
||||
throw new NotFoundException('Unable to compute hash of non-exiting file');
|
||||
}
|
||||
return $hash;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getExtension(): string {
|
||||
return $this->getFileInfo()->getExtension();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use OC\Files\Search\SearchOrder;
|
||||
use OC\Files\Search\SearchQuery;
|
||||
use OC\Files\Utils\PathHelper;
|
||||
use OC\User\LazyUser;
|
||||
use OCP\Constants;
|
||||
use OCP\Files\Cache\ICacheEntry;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\Folder as IFolder;
|
||||
@@ -26,31 +27,23 @@ use OCP\Files\Search\ISearchComparison;
|
||||
use OCP\Files\Search\ISearchOperator;
|
||||
use OCP\Files\Search\ISearchOrder;
|
||||
use OCP\Files\Search\ISearchQuery;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Server;
|
||||
use Override;
|
||||
|
||||
class Folder extends Node implements IFolder {
|
||||
|
||||
private ?IUserManager $userManager = null;
|
||||
|
||||
private bool $wasDeleted = false;
|
||||
|
||||
/**
|
||||
* Creates a Folder that represents a non-existing path
|
||||
*
|
||||
* @param string $path path
|
||||
* @return NonExistingFolder non-existing node
|
||||
*/
|
||||
protected function createNonExistingNode($path) {
|
||||
#[Override]
|
||||
protected function createNonExistingNode(string $path): NonExistingFolder {
|
||||
return new NonExistingFolder($this->root, $this->view, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path path relative to the folder
|
||||
* @return string
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
*/
|
||||
public function getFullPath($path) {
|
||||
#[Override]
|
||||
public function getFullPath(string $path): string {
|
||||
$path = $this->normalizePath($path);
|
||||
if (!$this->isValidPath($path)) {
|
||||
throw new NotPermittedException('Invalid path "' . $path . '"');
|
||||
@@ -58,31 +51,18 @@ class Folder extends Node implements IFolder {
|
||||
return $this->path . $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRelativePath($path) {
|
||||
#[Override]
|
||||
public function getRelativePath(string $path): ?string {
|
||||
return PathHelper::getRelativePath($this->getPath(), $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a node is a (grand-)child of the folder
|
||||
*
|
||||
* @param \OC\Files\Node\Node $node
|
||||
* @return bool
|
||||
*/
|
||||
public function isSubNode($node) {
|
||||
#[Override]
|
||||
public function isSubNode(INode $node): bool {
|
||||
return str_starts_with($node->getPath(), $this->path . '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* get the content of this directory
|
||||
*
|
||||
* @return Node[]
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
*/
|
||||
public function getDirectoryListing() {
|
||||
#[Override]
|
||||
public function getDirectoryListing(): array {
|
||||
$folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo(false));
|
||||
|
||||
return array_map(function (FileInfo $info) {
|
||||
@@ -108,11 +88,11 @@ class Folder extends Node implements IFolder {
|
||||
}
|
||||
}
|
||||
|
||||
public function get($path) {
|
||||
public function get(string $path): INode {
|
||||
return $this->root->get($this->getFullPath($path));
|
||||
}
|
||||
|
||||
public function nodeExists($path) {
|
||||
public function nodeExists(string $path): bool {
|
||||
try {
|
||||
$this->get($path);
|
||||
return true;
|
||||
@@ -121,13 +101,9 @@ class Folder extends Node implements IFolder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return \OC\Files\Node\Folder
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
*/
|
||||
public function newFolder($path) {
|
||||
if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
|
||||
#[Override]
|
||||
public function newFolder(string $path): self {
|
||||
if ($this->checkPermissions(Constants::PERMISSION_CREATE)) {
|
||||
$fullPath = $this->getFullPath($path);
|
||||
$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
|
||||
$this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
|
||||
@@ -156,18 +132,13 @@ class Folder extends Node implements IFolder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string | resource | null $content
|
||||
* @return \OC\Files\Node\File
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
*/
|
||||
public function newFile($path, $content = null) {
|
||||
#[Override]
|
||||
public function newFile(string $path, $content = null): File {
|
||||
if ($path === '') {
|
||||
throw new NotPermittedException('Could not create as provided path is empty');
|
||||
}
|
||||
$this->recreateIfNeeded();
|
||||
if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
|
||||
if ($this->checkPermissions(Constants::PERMISSION_CREATE)) {
|
||||
$fullPath = $this->getFullPath($path);
|
||||
$nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
|
||||
$this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
|
||||
@@ -190,20 +161,16 @@ class Folder extends Node implements IFolder {
|
||||
if ($uid === null) {
|
||||
$user = null;
|
||||
} else {
|
||||
/** @var IUserManager $userManager */
|
||||
$userManager = \OCP\Server::get(IUserManager::class);
|
||||
$user = $userManager->get($uid);
|
||||
if ($this->userManager === null) {
|
||||
$this->userManager = Server::get(IUserManager::class);
|
||||
}
|
||||
$user = $this->userManager->get($uid);
|
||||
}
|
||||
return new SearchQuery($operator, $limit, $offset, [], $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files with the name matching $query
|
||||
*
|
||||
* @param string|ISearchQuery $query
|
||||
* @return \OC\Files\Node\Node[]
|
||||
*/
|
||||
public function search($query) {
|
||||
#[Override]
|
||||
public function search(string|ISearchQuery $query): array {
|
||||
if (is_string($query)) {
|
||||
$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query . '%'));
|
||||
}
|
||||
@@ -217,7 +184,7 @@ class Folder extends Node implements IFolder {
|
||||
}
|
||||
|
||||
/** @var QuerySearchHelper $searchHelper */
|
||||
$searchHelper = \OC::$server->get(QuerySearchHelper::class);
|
||||
$searchHelper = Server::get(QuerySearchHelper::class);
|
||||
[$caches, $mountByMountPoint] = $searchHelper->getCachesAndMountPointsForSearch($this->root, $this->path, $limitToHome);
|
||||
$resultsPerCache = $searchHelper->searchInCaches($query, $caches);
|
||||
|
||||
@@ -264,7 +231,7 @@ class Folder extends Node implements IFolder {
|
||||
if ($ownerId !== false) {
|
||||
// Cache the user manager (for performance)
|
||||
if ($this->userManager === null) {
|
||||
$this->userManager = \OCP\Server::get(IUserManager::class);
|
||||
$this->userManager = Server::get(IUserManager::class);
|
||||
}
|
||||
$owner = new LazyUser($ownerId, $this->userManager);
|
||||
}
|
||||
@@ -279,13 +246,8 @@ class Folder extends Node implements IFolder {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files by mimetype
|
||||
*
|
||||
* @param string $mimetype
|
||||
* @return Node[]
|
||||
*/
|
||||
public function searchByMime($mimetype) {
|
||||
#[Override]
|
||||
public function searchByMime(string $mimetype): array {
|
||||
if (!str_contains($mimetype, '/')) {
|
||||
$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', $mimetype . '/%'));
|
||||
} else {
|
||||
@@ -294,37 +256,30 @@ class Folder extends Node implements IFolder {
|
||||
return $this->search($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files by tag
|
||||
*
|
||||
* @param string|int $tag name or tag id
|
||||
* @param string $userId owner of the tags
|
||||
* @return Node[]
|
||||
*/
|
||||
public function searchByTag($tag, $userId) {
|
||||
#[Override]
|
||||
public function searchByTag(string|int $tag, string $userId): array {
|
||||
$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'tagname', $tag), $userId);
|
||||
return $this->search($query);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function searchBySystemTag(string $tagName, string $userId, int $limit = 0, int $offset = 0): array {
|
||||
$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'systemtag', $tagName), $userId, $limit, $offset);
|
||||
return $this->search($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return \OCP\Files\Node[]
|
||||
*/
|
||||
public function getById($id) {
|
||||
return $this->root->getByIdInPath((int)$id, $this->getPath());
|
||||
#[Override]
|
||||
public function getById(int $id): array {
|
||||
return $this->root->getByIdInPath($id, $this->getPath());
|
||||
}
|
||||
|
||||
public function getFirstNodeById(int $id): ?\OCP\Files\Node {
|
||||
#[Override]
|
||||
public function getFirstNodeById(int $id): ?INode {
|
||||
return $this->root->getFirstNodeByIdInPath($id, $this->getPath());
|
||||
}
|
||||
|
||||
public function getAppDataDirectoryName(): string {
|
||||
$instanceId = \OC::$server->getConfig()->getSystemValueString('instanceid');
|
||||
$instanceId = Server::get(IConfig::class)->getSystemValueString('instanceid');
|
||||
return 'appdata_' . $instanceId;
|
||||
}
|
||||
|
||||
@@ -336,9 +291,6 @@ class Folder extends Node implements IFolder {
|
||||
* So in that case we directly check the mount of the root if it contains
|
||||
* the id. If it does we check if the path is inside the path we are working
|
||||
* in.
|
||||
*
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
protected function getByIdInRootMount(int $id): array {
|
||||
if (!method_exists($this->root, 'createNode')) {
|
||||
@@ -371,12 +323,14 @@ class Folder extends Node implements IFolder {
|
||||
))];
|
||||
}
|
||||
|
||||
public function getFreeSpace() {
|
||||
#[Override]
|
||||
public function getFreeSpace(): float|int|false {
|
||||
return $this->view->free_space($this->path);
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
|
||||
#[Override]
|
||||
public function delete(): void {
|
||||
if ($this->checkPermissions(Constants::PERMISSION_DELETE)) {
|
||||
$this->sendHooks(['preDelete']);
|
||||
$fileInfo = $this->getFileInfo();
|
||||
$this->view->rmdir($this->path);
|
||||
@@ -388,27 +342,21 @@ class Folder extends Node implements IFolder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a suffix to the name in case the file exists
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
public function getNonExistingName($filename) {
|
||||
#[Override]
|
||||
public function getNonExistingName(string $name): string {
|
||||
$path = $this->getPath();
|
||||
if ($path === '/') {
|
||||
$path = '';
|
||||
}
|
||||
if ($pos = strrpos($filename, '.')) {
|
||||
$name = substr($filename, 0, $pos);
|
||||
$ext = substr($filename, $pos);
|
||||
if ($pos = strrpos($name, '.')) {
|
||||
$name = substr($name, 0, $pos);
|
||||
$ext = substr($name, $pos);
|
||||
} else {
|
||||
$name = $filename;
|
||||
$name = $name;
|
||||
$ext = '';
|
||||
}
|
||||
|
||||
$newpath = $path . '/' . $filename;
|
||||
$newpath = $path . '/' . $name;
|
||||
if ($this->view->file_exists($newpath)) {
|
||||
if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
/** @var array<int<0, max>, array> $matches */
|
||||
@@ -437,12 +385,8 @@ class Folder extends Node implements IFolder {
|
||||
return trim($this->getRelativePath($newpath), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @return INode[]
|
||||
*/
|
||||
public function getRecent($limit, $offset = 0) {
|
||||
#[Override]
|
||||
public function getRecent(int $limit, int $offset = 0): array {
|
||||
$filterOutNonEmptyFolder = new SearchBinaryOperator(
|
||||
// filter out non empty folders
|
||||
ISearchBinaryOperator::OPERATOR_OR,
|
||||
@@ -505,7 +449,8 @@ class Folder extends Node implements IFolder {
|
||||
return $this->search($query);
|
||||
}
|
||||
|
||||
public function verifyPath($fileName, $readonly = false): void {
|
||||
#[Override]
|
||||
public function verifyPath(string $fileName, bool $readonly = false): void {
|
||||
$this->view->verifyPath(
|
||||
$this->getPath(),
|
||||
$fileName,
|
||||
|
||||
@@ -14,6 +14,9 @@ use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\Search\ISearchQuery;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUser;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
@@ -32,7 +35,6 @@ class LazyFolder implements Folder {
|
||||
protected array $data;
|
||||
|
||||
/**
|
||||
* @param IRootFolder $rootFolder
|
||||
* @param \Closure(): Folder $folderClosure
|
||||
* @param array $data
|
||||
*/
|
||||
@@ -65,77 +67,8 @@ class LazyFolder implements Folder {
|
||||
return call_user_func_array([$this->getRealFolder(), $method], $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getUser() {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function listen($scope, $method, callable $callback) {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function removeListener($scope = null, $method = null, ?callable $callback = null) {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function emit($scope, $method, $arguments = []) {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function mount($storage, $mountPoint, $arguments = []) {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getMount(string $mountPoint): IMountPoint {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IMountPoint[]
|
||||
*/
|
||||
public function getMountsIn(string $mountPoint): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getMountByStorageId($storageId) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getMountByNumericStorageId($numericId) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function unMount($mount) {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
public function get($path) {
|
||||
#[Override]
|
||||
public function get(string $path): \OCP\Files\Node {
|
||||
return $this->getRootFolder()->get($this->getFullPath($path));
|
||||
}
|
||||
|
||||
@@ -144,166 +77,128 @@ class LazyFolder implements Folder {
|
||||
return $this->getRootFolder()->getOrCreateFolder($this->getFullPath($path), $maxRetries);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function rename($targetPath) {
|
||||
#[Override]
|
||||
public function move(string $targetPath): \OCP\Files\Node {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function delete() {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function copy($targetPath) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function touch($mtime = null) {
|
||||
#[Override]
|
||||
public function delete(): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getStorage() {
|
||||
#[Override]
|
||||
public function copy(string $targetPath): \OCP\Files\Node {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPath() {
|
||||
#[Override]
|
||||
public function touch(?int $mtime = null): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getStorage(): IStorage {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getPath(): string {
|
||||
if (isset($this->data['path'])) {
|
||||
return $this->data['path'];
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getInternalPath() {
|
||||
#[Override]
|
||||
public function getInternalPath(): string {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getId() {
|
||||
#[Override]
|
||||
public function getId(): int {
|
||||
if (isset($this->data['fileid'])) {
|
||||
return $this->data['fileid'];
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function stat() {
|
||||
#[Override]
|
||||
public function stat(): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getMTime() {
|
||||
#[Override]
|
||||
public function getMTime(): int {
|
||||
if (isset($this->data['mtime'])) {
|
||||
return $this->data['mtime'];
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getSize($includeMounts = true): int|float {
|
||||
#[Override]
|
||||
public function getSize(bool $includeMounts = true): int|float {
|
||||
if (isset($this->data['size'])) {
|
||||
return $this->data['size'];
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getEtag() {
|
||||
#[Override]
|
||||
public function getEtag(): string {
|
||||
if (isset($this->data['etag'])) {
|
||||
return $this->data['etag'];
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPermissions() {
|
||||
#[Override]
|
||||
public function getPermissions(): int {
|
||||
if (isset($this->data['permissions'])) {
|
||||
return $this->data['permissions'];
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isReadable() {
|
||||
#[Override]
|
||||
public function isReadable(): bool {
|
||||
if (isset($this->data['permissions'])) {
|
||||
return ($this->data['permissions'] & Constants::PERMISSION_READ) == Constants::PERMISSION_READ;
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isUpdateable() {
|
||||
#[Override]
|
||||
public function isUpdateable(): bool {
|
||||
if (isset($this->data['permissions'])) {
|
||||
return ($this->data['permissions'] & Constants::PERMISSION_UPDATE) == Constants::PERMISSION_UPDATE;
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isDeletable() {
|
||||
#[Override]
|
||||
public function isDeletable(): bool {
|
||||
if (isset($this->data['permissions'])) {
|
||||
return ($this->data['permissions'] & Constants::PERMISSION_DELETE) == Constants::PERMISSION_DELETE;
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isShareable() {
|
||||
#[Override]
|
||||
public function isShareable(): bool {
|
||||
if (isset($this->data['permissions'])) {
|
||||
return ($this->data['permissions'] & Constants::PERMISSION_SHARE) == Constants::PERMISSION_SHARE;
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getParent() {
|
||||
#[Override]
|
||||
public function getParent(): IRootFolder|\OCP\Files\Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getName() {
|
||||
#[Override]
|
||||
public function getName(): string {
|
||||
if (isset($this->data['path'])) {
|
||||
return basename($this->data['path']);
|
||||
}
|
||||
@@ -313,13 +208,7 @@ class LazyFolder implements Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getUserFolder($userId) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMimetype(): string {
|
||||
if (isset($this->data['mimetype'])) {
|
||||
return $this->data['mimetype'];
|
||||
@@ -327,10 +216,8 @@ class LazyFolder implements Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getMimePart() {
|
||||
#[Override]
|
||||
public function getMimePart(): string {
|
||||
if (isset($this->data['mimetype'])) {
|
||||
[$part,] = explode('/', $this->data['mimetype']);
|
||||
return $part;
|
||||
@@ -338,66 +225,51 @@ class LazyFolder implements Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isEncrypted() {
|
||||
#[Override]
|
||||
public function isEncrypted(): bool {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getType() {
|
||||
#[Override]
|
||||
public function getType(): string {
|
||||
if (isset($this->data['type'])) {
|
||||
return $this->data['type'];
|
||||
}
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isShared() {
|
||||
#[Override]
|
||||
public function isShared(): bool {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isMounted() {
|
||||
#[Override]
|
||||
public function isMounted(): bool {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getMountPoint() {
|
||||
#[Override]
|
||||
public function getMountPoint(): IMountPoint {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOwner() {
|
||||
#[Override]
|
||||
public function getOwner(): ?IUser {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getChecksum() {
|
||||
#[Override]
|
||||
public function getChecksum(): string {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getExtension(): string {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getFullPath($path) {
|
||||
#[Override]
|
||||
public function getFullPath(string $path): string {
|
||||
if (isset($this->data['path'])) {
|
||||
$path = PathHelper::normalizePath($path);
|
||||
if (!Filesystem::isValidPath($path)) {
|
||||
@@ -408,148 +280,112 @@ class LazyFolder implements Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isSubNode($node) {
|
||||
#[Override]
|
||||
public function isSubNode(\OCP\Files\Node $node): bool {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getDirectoryListing() {
|
||||
#[Override]
|
||||
public function getDirectoryListing(): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
public function nodeExists($path) {
|
||||
#[Override]
|
||||
public function nodeExists(string $path): bool {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function newFolder($path) {
|
||||
#[Override]
|
||||
public function newFolder(string $path): \OCP\Files\Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function newFile($path, $content = null) {
|
||||
#[Override]
|
||||
public function newFile(string $path, $content = null): \OCP\Files\File {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function search($query) {
|
||||
#[Override]
|
||||
public function search(string|ISearchQuery $query): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function searchByMime($mimetype) {
|
||||
#[Override]
|
||||
public function searchByMime(string $mimetype): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function searchByTag($tag, $userId) {
|
||||
#[Override]
|
||||
public function searchByTag(int|string $tag, string $userId): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
public function searchBySystemTag(string $tagName, string $userId, int $limit = 0, int $offset = 0) {
|
||||
#[Override]
|
||||
public function searchBySystemTag(string $tagName, string $userId, int $limit = 0, int $offset = 0): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getById($id) {
|
||||
return $this->getRootFolder()->getByIdInPath((int)$id, $this->getPath());
|
||||
#[Override]
|
||||
public function getById(int $id): array {
|
||||
return $this->getRootFolder()->getByIdInPath($id, $this->getPath());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getFirstNodeById(int $id): ?\OCP\Files\Node {
|
||||
return $this->getRootFolder()->getFirstNodeByIdInPath($id, $this->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getFreeSpace() {
|
||||
#[Override]
|
||||
public function getFreeSpace(): int|float|false {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function isCreatable() {
|
||||
#[Override]
|
||||
public function isCreatable(): bool {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getNonExistingName($filename) {
|
||||
#[Override]
|
||||
public function getNonExistingName(string $name): string {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function move($targetPath) {
|
||||
#[Override]
|
||||
public function lock(int $type): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function changeLock(int $targetType): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function unlock(int $type): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getRecent(int $limit, int $offset = 0): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function lock($type) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function changeLock($targetType) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function unlock($type) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getRecent($limit, $offset = 0) {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[Override]
|
||||
public function getCreationTime(): int {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[Override]
|
||||
public function getUploadTime(): int {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
public function getRelativePath($path) {
|
||||
#[Override]
|
||||
public function getRelativePath(string $path): ?string {
|
||||
return PathHelper::getRelativePath($this->getPath(), $path);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParentId(): int {
|
||||
if (isset($this->data['parent'])) {
|
||||
return $this->data['parent'];
|
||||
@@ -557,15 +393,13 @@ class LazyFolder implements Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return array<string, int|string|bool|float|string[]|int[]>
|
||||
*/
|
||||
#[Override]
|
||||
public function getMetadata(): array {
|
||||
return $this->data['metadata'] ?? $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
public function verifyPath($fileName, $readonly = false): void {
|
||||
#[Override]
|
||||
public function verifyPath(string $fileName, $readonly = false): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Node;
|
||||
use OCP\Files\Node as INode;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* Class LazyRoot
|
||||
@@ -34,23 +35,48 @@ class LazyRoot extends LazyFolder implements IRootFolder {
|
||||
return $folder;
|
||||
}
|
||||
|
||||
public function getUserFolder($userId) {
|
||||
#[Override]
|
||||
public function listen($scope, $method, callable $callback): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function removeListener($scope = null, $method = null, ?callable $callback = null): void {
|
||||
$this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getUserFolder(string $userId): \OCP\Files\Folder {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
public function getByIdInPath(int $id, string $path) {
|
||||
#[Override]
|
||||
public function getByIdInPath(int $id, string $path): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getFirstNodeByIdInPath(int $id, string $path): ?Node {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getNodeFromCacheEntryAndMount(ICacheEntry $cacheEntry, IMountPoint $mountPoint): INode {
|
||||
return $this->getRootFolder()->getNodeFromCacheEntryAndMount($cacheEntry, $mountPoint);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getAppDataDirectoryName(): string {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMountsIn(string $mountPoint): array {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMount(string $mountPoint): IMountPoint {
|
||||
return $this->__call(__FUNCTION__, func_get_args());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use OCP\Files\FileInfo;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Mount\IMountManager;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IUser;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -53,6 +54,7 @@ class LazyUserFolder extends LazyFolder {
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
/** @var Folder $node */
|
||||
return $node;
|
||||
} catch (NotFoundException $e) {
|
||||
if (!$this->getRootFolder()->nodeExists('/' . $user->getUID())) {
|
||||
@@ -65,7 +67,7 @@ class LazyUserFolder extends LazyFolder {
|
||||
);
|
||||
}
|
||||
|
||||
public function getMountPoint() {
|
||||
public function getMountPoint(): IMountPoint {
|
||||
if ($this->folder !== null) {
|
||||
return $this->folder->getMountPoint();
|
||||
}
|
||||
|
||||
@@ -10,75 +10,56 @@ namespace OC\Files\Node;
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\Mount\MoveableMount;
|
||||
use OC\Files\Utils\PathHelper;
|
||||
use OC\Files\View;
|
||||
use OCP\EventDispatcher\GenericEvent;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\InvalidPathException;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Node as INode;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Lock\LockedException;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUser;
|
||||
use OCP\PreConditionNotMetException;
|
||||
use OCP\Server;
|
||||
use Override;
|
||||
|
||||
// FIXME: this class really should be abstract (+1)
|
||||
class Node implements INode {
|
||||
abstract class Node implements INode {
|
||||
/**
|
||||
* @var \OC\Files\View $view
|
||||
* @param string $path Absolute path to the node (e.g. /admin/files/folder/file)
|
||||
* @throws PreConditionNotMetException
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
protected IRootFolder $root;
|
||||
|
||||
/**
|
||||
* @var string $path Absolute path to the node (e.g. /admin/files/folder/file)
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
protected ?FileInfo $fileInfo;
|
||||
|
||||
protected ?INode $parent;
|
||||
|
||||
private bool $infoHasSubMountsIncluded;
|
||||
|
||||
/**
|
||||
* @param \OC\Files\View $view
|
||||
* @param \OCP\Files\IRootFolder $root
|
||||
* @param string $path
|
||||
* @param FileInfo $fileInfo
|
||||
*/
|
||||
public function __construct(IRootFolder $root, $view, $path, $fileInfo = null, ?INode $parent = null, bool $infoHasSubMountsIncluded = true) {
|
||||
public function __construct(
|
||||
protected IRootFolder $root,
|
||||
protected View $view,
|
||||
protected string $path,
|
||||
protected ?FileInfo $fileInfo = null,
|
||||
protected ?\OCP\Files\Folder $parent = null,
|
||||
protected bool $infoHasSubMountsIncluded = true,
|
||||
) {
|
||||
if (Filesystem::normalizePath($view->getRoot()) !== '/') {
|
||||
throw new PreConditionNotMetException('The view passed to the node should not have any fake root set');
|
||||
}
|
||||
$this->view = $view;
|
||||
$this->root = $root;
|
||||
$this->path = $path;
|
||||
$this->fileInfo = $fileInfo;
|
||||
$this->parent = $parent;
|
||||
$this->infoHasSubMountsIncluded = $infoHasSubMountsIncluded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Node of the same type that represents a non-existing path
|
||||
* Creates a Node of the same type that represents a non-existing path.
|
||||
*
|
||||
* @param string $path path
|
||||
* @return Node non-existing node
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function createNonExistingNode($path) {
|
||||
throw new \Exception('Must be implemented by subclasses');
|
||||
}
|
||||
abstract protected function createNonExistingNode(string $path): INode;
|
||||
|
||||
/**
|
||||
* Returns the matching file info
|
||||
* Returns the matching file info.
|
||||
*
|
||||
* @return FileInfo
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getFileInfo(bool $includeMountPoint = true) {
|
||||
if (!$this->fileInfo) {
|
||||
public function getFileInfo(bool $includeMountPoint = true): FileInfo {
|
||||
$fileInfo = $this->fileInfo;
|
||||
if (!$fileInfo) {
|
||||
if (!Filesystem::isValidPath($this->path)) {
|
||||
throw new InvalidPathException();
|
||||
}
|
||||
@@ -95,16 +76,15 @@ class Node implements INode {
|
||||
}
|
||||
$this->infoHasSubMountsIncluded = true;
|
||||
}
|
||||
return $this->fileInfo;
|
||||
return $fileInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $hooks
|
||||
*/
|
||||
protected function sendHooks($hooks, ?array $args = null) {
|
||||
protected function sendHooks(array $hooks, ?array $args = null): void {
|
||||
$args = !empty($args) ? $args : [$this];
|
||||
/** @var IEventDispatcher $dispatcher */
|
||||
$dispatcher = \OC::$server->get(IEventDispatcher::class);
|
||||
$dispatcher = Server::get(IEventDispatcher::class);
|
||||
foreach ($hooks as $hook) {
|
||||
if (method_exists($this->root, 'emit')) {
|
||||
$this->root->emit('\OC\Files', $hook, $args);
|
||||
@@ -121,30 +101,24 @@ class Node implements INode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $permissions
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
protected function checkPermissions($permissions) {
|
||||
protected function checkPermissions(int $permissions): bool {
|
||||
return ($this->getPermissions() & $permissions) === $permissions;
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
#[Override]
|
||||
public function delete(): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $mtime
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
public function touch($mtime = null) {
|
||||
#[Override]
|
||||
public function touch(?int $mtime = null): void {
|
||||
if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
|
||||
$this->sendHooks(['preTouch']);
|
||||
$this->view->touch($this->path, $mtime);
|
||||
$this->sendHooks(['postTouch']);
|
||||
if ($this->fileInfo) {
|
||||
if ($this->fileInfo instanceof \OC\Files\FileInfo) {
|
||||
if (is_null($mtime)) {
|
||||
$mtime = time();
|
||||
}
|
||||
@@ -155,7 +129,8 @@ class Node implements INode {
|
||||
}
|
||||
}
|
||||
|
||||
public function getStorage() {
|
||||
#[Override]
|
||||
public function getStorage(): IStorage {
|
||||
$storage = $this->getMountPoint()->getStorage();
|
||||
if (!$storage) {
|
||||
throw new \Exception('No storage for node');
|
||||
@@ -163,119 +138,77 @@ class Node implements INode {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath() {
|
||||
#[Override]
|
||||
public function getPath(): string {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInternalPath() {
|
||||
#[Override]
|
||||
public function getInternalPath(): string {
|
||||
return $this->getFileInfo(false)->getInternalPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getId() {
|
||||
return $this->getFileInfo(false)->getId() ?? -1;
|
||||
#[Override]
|
||||
public function getId(): ?int {
|
||||
return $this->getFileInfo(false)->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function stat() {
|
||||
#[Override]
|
||||
public function stat(): array|false {
|
||||
return $this->view->stat($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getMTime() {
|
||||
#[Override]
|
||||
public function getMTime(): int {
|
||||
return $this->getFileInfo()->getMTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeMounts
|
||||
* @return int|float
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getSize($includeMounts = true): int|float {
|
||||
#[Override]
|
||||
public function getSize(bool $includeMounts = true): int|float {
|
||||
return $this->getFileInfo()->getSize($includeMounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getEtag() {
|
||||
#[Override]
|
||||
public function getEtag(): string {
|
||||
return $this->getFileInfo()->getEtag();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getPermissions() {
|
||||
#[Override]
|
||||
public function getPermissions(): int {
|
||||
return $this->getFileInfo(false)->getPermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function isReadable() {
|
||||
#[Override]
|
||||
public function isReadable(): bool {
|
||||
return $this->getFileInfo(false)->isReadable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function isUpdateable() {
|
||||
#[Override]
|
||||
public function isUpdateable(): bool {
|
||||
return $this->getFileInfo(false)->isUpdateable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function isDeletable() {
|
||||
#[Override]
|
||||
public function isDeletable(): bool {
|
||||
return $this->getFileInfo(false)->isDeletable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function isShareable() {
|
||||
#[Override]
|
||||
public function isShareable(): bool {
|
||||
return $this->getFileInfo(false)->isShareable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function isCreatable() {
|
||||
#[Override]
|
||||
public function isCreatable(): bool {
|
||||
return $this->getFileInfo(false)->isCreatable();
|
||||
}
|
||||
|
||||
public function getParent(): INode|IRootFolder {
|
||||
#[Override]
|
||||
public function getParent(): \OCP\Files\Folder {
|
||||
if ($this->parent === null) {
|
||||
$newPath = dirname($this->path);
|
||||
if ($newPath === '' || $newPath === '.' || $newPath === '/') {
|
||||
@@ -286,8 +219,9 @@ class Node implements INode {
|
||||
try {
|
||||
$fileInfo = $this->getFileInfo();
|
||||
} catch (NotFoundException) {
|
||||
$this->parent = $this->root->get($newPath);
|
||||
/** @var \OCP\Files\Folder $this->parent */
|
||||
/** @var \OCP\Files\Folder $parent */
|
||||
$parent = $this->root->get($newPath);
|
||||
$this->parent = $parent;
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
@@ -306,102 +240,84 @@ class Node implements INode {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
#[Override]
|
||||
public function getName(): string {
|
||||
return basename($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function normalizePath($path) {
|
||||
protected function normalizePath(string $path): string {
|
||||
return PathHelper::normalizePath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the requested path is valid
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
* Check if the requested path is valid.
|
||||
*/
|
||||
public function isValidPath($path) {
|
||||
public function isValidPath(string $path): bool {
|
||||
return Filesystem::isValidPath($path);
|
||||
}
|
||||
|
||||
public function isMounted() {
|
||||
#[Override]
|
||||
public function isMounted(): bool {
|
||||
return $this->getFileInfo(false)->isMounted();
|
||||
}
|
||||
|
||||
public function isShared() {
|
||||
#[Override]
|
||||
public function isShared(): bool {
|
||||
return $this->getFileInfo(false)->isShared();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMimeType(): string {
|
||||
return $this->getFileInfo(false)->getMimetype();
|
||||
}
|
||||
|
||||
public function getMimePart() {
|
||||
#[Override]
|
||||
public function getMimePart(): string {
|
||||
return $this->getFileInfo(false)->getMimePart();
|
||||
}
|
||||
|
||||
public function getType() {
|
||||
#[Override]
|
||||
public function getType(): string {
|
||||
return $this->getFileInfo(false)->getType();
|
||||
}
|
||||
|
||||
public function isEncrypted() {
|
||||
#[Override]
|
||||
public function isEncrypted(): bool {
|
||||
return $this->getFileInfo(false)->isEncrypted();
|
||||
}
|
||||
|
||||
public function getMountPoint() {
|
||||
#[Override]
|
||||
public function getMountPoint(): IMountPoint {
|
||||
return $this->getFileInfo(false)->getMountPoint();
|
||||
}
|
||||
|
||||
public function getOwner() {
|
||||
#[Override]
|
||||
public function getOwner(): ?IUser {
|
||||
return $this->getFileInfo(false)->getOwner();
|
||||
}
|
||||
|
||||
public function getChecksum() {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getExtension(): string {
|
||||
return $this->getFileInfo(false)->getExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||
* @throws LockedException
|
||||
*/
|
||||
public function lock($type) {
|
||||
#[Override]
|
||||
public function lock(int $type): void {
|
||||
$this->view->lockFile($this->path, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||
* @throws LockedException
|
||||
*/
|
||||
public function changeLock($type) {
|
||||
$this->view->changeLock($this->path, $type);
|
||||
#[Override]
|
||||
public function changeLock(int $targetType): void {
|
||||
$this->view->changeLock($this->path, $targetType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||
* @throws LockedException
|
||||
*/
|
||||
public function unlock($type) {
|
||||
#[Override]
|
||||
public function unlock(int $type): void {
|
||||
$this->view->unlockFile($this->path, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $targetPath
|
||||
* @return INode
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException if copy not allowed or failed
|
||||
*/
|
||||
public function copy($targetPath) {
|
||||
#[Override]
|
||||
public function copy(string $targetPath): INode {
|
||||
$targetPath = $this->normalizePath($targetPath);
|
||||
$parent = $this->root->get(dirname($targetPath));
|
||||
if ($parent instanceof Folder && $this->isValidPath($targetPath) && $parent->isCreatable()) {
|
||||
@@ -420,16 +336,10 @@ class Node implements INode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $targetPath
|
||||
* @return INode
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException if move not allowed or failed
|
||||
* @throws LockedException
|
||||
*/
|
||||
public function move($targetPath) {
|
||||
#[Override]
|
||||
public function move(string $targetPath): INode {
|
||||
$targetPath = $this->normalizePath($targetPath);
|
||||
|
||||
$parent = $this->root->get(dirname($targetPath));
|
||||
if (
|
||||
($parent instanceof Folder)
|
||||
@@ -450,12 +360,10 @@ class Node implements INode {
|
||||
}
|
||||
|
||||
$mountPoint = $this->getMountPoint();
|
||||
if ($mountPoint) {
|
||||
// update the cached fileinfo with the new (internal) path
|
||||
/** @var \OC\Files\FileInfo $oldFileInfo */
|
||||
$oldFileInfo = $this->getFileInfo();
|
||||
$this->fileInfo = new \OC\Files\FileInfo($targetPath, $oldFileInfo->getStorage(), $mountPoint->getInternalPath($targetPath), $oldFileInfo->getData(), $mountPoint, $oldFileInfo->getOwner());
|
||||
}
|
||||
// update the cached fileinfo with the new (internal) path
|
||||
/** @var \OC\Files\FileInfo $oldFileInfo */
|
||||
$oldFileInfo = $this->getFileInfo();
|
||||
$this->fileInfo = new \OC\Files\FileInfo($targetPath, $oldFileInfo->getStorage(), $mountPoint->getInternalPath($targetPath), $oldFileInfo->getData(), $mountPoint, $oldFileInfo->getOwner());
|
||||
|
||||
$targetNode = $this->root->get($targetPath);
|
||||
$this->sendHooks(['postRename'], [$this, $targetNode]);
|
||||
@@ -467,23 +375,28 @@ class Node implements INode {
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getCreationTime(): int {
|
||||
return $this->getFileInfo()->getCreationTime();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getUploadTime(): int {
|
||||
return $this->getFileInfo()->getUploadTime();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParentId(): int {
|
||||
return $this->fileInfo->getParentId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return array<string, int|string|bool|float|string[]|int[]>
|
||||
*/
|
||||
#[Override]
|
||||
public function getMetadata(): array {
|
||||
return $this->fileInfo->getMetadata();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getChecksum(): string {
|
||||
return $this->getFileInfo()->getChecksum();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,29 +8,31 @@
|
||||
namespace OC\Files\Node;
|
||||
|
||||
use OCP\Files\NotFoundException;
|
||||
use Override;
|
||||
|
||||
class NonExistingFile extends File {
|
||||
/**
|
||||
* @param string $newPath
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
*/
|
||||
public function rename($newPath) {
|
||||
#[Override]
|
||||
public function move(string $targetPath): \OCP\Files\Node {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
#[Override]
|
||||
public function delete(): void {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function copy($targetPath) {
|
||||
#[Override]
|
||||
public function copy(string $targetPath): \OCP\Files\Node {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function touch($mtime = null) {
|
||||
#[Override]
|
||||
public function touch(?int $mtime = null): void {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
#[Override]
|
||||
public function getId(): ?int {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getId();
|
||||
} else {
|
||||
@@ -38,7 +40,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function getInternalPath() {
|
||||
#[Override]
|
||||
public function getInternalPath(): string {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getInternalPath();
|
||||
} else {
|
||||
@@ -46,11 +49,13 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function stat() {
|
||||
#[Override]
|
||||
public function stat(): array {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function getMTime() {
|
||||
#[Override]
|
||||
public function getMTime(): int {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getMTime();
|
||||
} else {
|
||||
@@ -58,7 +63,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function getSize($includeMounts = true): int|float {
|
||||
#[Override]
|
||||
public function getSize(bool $includeMounts = true): int|float {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getSize($includeMounts);
|
||||
} else {
|
||||
@@ -66,7 +72,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function getEtag() {
|
||||
#[Override]
|
||||
public function getEtag(): string {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getEtag();
|
||||
} else {
|
||||
@@ -74,7 +81,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function getPermissions() {
|
||||
#[Override]
|
||||
public function getPermissions(): int {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getPermissions();
|
||||
} else {
|
||||
@@ -82,7 +90,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function isReadable() {
|
||||
#[Override]
|
||||
public function isReadable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isReadable();
|
||||
} else {
|
||||
@@ -90,7 +99,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function isUpdateable() {
|
||||
#[Override]
|
||||
public function isUpdateable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isUpdateable();
|
||||
} else {
|
||||
@@ -98,7 +108,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function isDeletable() {
|
||||
#[Override]
|
||||
public function isDeletable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isDeletable();
|
||||
} else {
|
||||
@@ -106,7 +117,8 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function isShareable() {
|
||||
#[Override]
|
||||
public function isShareable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isShareable();
|
||||
} else {
|
||||
@@ -114,14 +126,17 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
public function getContent() {
|
||||
#[Override]
|
||||
public function getContent(): string {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function putContent($data) {
|
||||
#[Override]
|
||||
public function putContent($data): void {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMimeType(): string {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getMimeType();
|
||||
@@ -130,6 +145,7 @@ class NonExistingFile extends File {
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function fopen($mode) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
@@ -8,29 +8,32 @@
|
||||
namespace OC\Files\Node;
|
||||
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\Search\ISearchQuery;
|
||||
use Override;
|
||||
|
||||
class NonExistingFolder extends Folder {
|
||||
/**
|
||||
* @param string $newPath
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
*/
|
||||
public function rename($newPath) {
|
||||
#[Override]
|
||||
public function move(string $targetPath): \OCP\Files\Node {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
#[Override]
|
||||
public function delete(): void {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function copy($targetPath) {
|
||||
#[Override]
|
||||
public function copy(string $targetPath): \OCP\Files\Node {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function touch($mtime = null) {
|
||||
#[Override]
|
||||
public function touch(?int $mtime = null): void {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
#[Override]
|
||||
public function getId(): ?int {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getId();
|
||||
} else {
|
||||
@@ -38,7 +41,8 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function getInternalPath() {
|
||||
#[Override]
|
||||
public function getInternalPath(): string {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getInternalPath();
|
||||
} else {
|
||||
@@ -46,11 +50,13 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function stat() {
|
||||
#[Override]
|
||||
public function stat(): array|false {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function getMTime() {
|
||||
#[Override]
|
||||
public function getMTime(): int {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getMTime();
|
||||
} else {
|
||||
@@ -58,7 +64,8 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function getSize($includeMounts = true): int|float {
|
||||
#[Override]
|
||||
public function getSize(bool $includeMounts = true): int|float {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getSize($includeMounts);
|
||||
} else {
|
||||
@@ -66,7 +73,8 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function getEtag() {
|
||||
#[Override]
|
||||
public function getEtag(): string {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getEtag();
|
||||
} else {
|
||||
@@ -74,7 +82,8 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function getPermissions() {
|
||||
#[Override]
|
||||
public function getPermissions(): int {
|
||||
if ($this->fileInfo) {
|
||||
return parent::getPermissions();
|
||||
} else {
|
||||
@@ -82,7 +91,8 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function isReadable() {
|
||||
#[Override]
|
||||
public function isReadable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isReadable();
|
||||
} else {
|
||||
@@ -90,7 +100,7 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function isUpdateable() {
|
||||
public function isUpdateable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isUpdateable();
|
||||
} else {
|
||||
@@ -98,7 +108,8 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function isDeletable() {
|
||||
#[Override]
|
||||
public function isDeletable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isDeletable();
|
||||
} else {
|
||||
@@ -106,7 +117,8 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function isShareable() {
|
||||
#[Override]
|
||||
public function isShareable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isShareable();
|
||||
} else {
|
||||
@@ -114,55 +126,68 @@ class NonExistingFolder extends Folder {
|
||||
}
|
||||
}
|
||||
|
||||
public function get($path) {
|
||||
#[Override]
|
||||
public function get(string $path): \OCP\Files\Node {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function getDirectoryListing() {
|
||||
#[Override]
|
||||
public function getDirectoryListing(): array {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function nodeExists($path) {
|
||||
#[Override]
|
||||
public function nodeExists(string $path): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function newFolder($path) {
|
||||
#[Override]
|
||||
public function newFolder(string $path): Folder {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function newFile($path, $content = null) {
|
||||
#[Override]
|
||||
public function newFile(string $path, $content = null): File {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function search($query) {
|
||||
#[Override]
|
||||
public function search(string|ISearchQuery $query): array {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function searchByMime($mimetype) {
|
||||
#[Override]
|
||||
public function searchByMime(string $mimetype): array {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function searchByTag($tag, $userId) {
|
||||
#[Override]
|
||||
public function searchByTag(int|string $tag, string $userId): array {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function searchBySystemTag(string $tagName, string $userId, int $limit = 0, int $offset = 0): array {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function getById($id) {
|
||||
#[Override]
|
||||
public function getById(int $id): array {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getFirstNodeById(int $id): ?\OCP\Files\Node {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function getFreeSpace() {
|
||||
#[Override]
|
||||
public function getFreeSpace(): float|int|false {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function isCreatable() {
|
||||
#[Override]
|
||||
public function isCreatable(): bool {
|
||||
if ($this->fileInfo) {
|
||||
return parent::isCreatable();
|
||||
} else {
|
||||
|
||||
@@ -26,12 +26,14 @@ use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Node as INode;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Server;
|
||||
use Override;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
@@ -81,87 +83,42 @@ class Root extends Folder implements IRootFolder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user for which the filesystem is setup
|
||||
*
|
||||
* @return \OC\User\User
|
||||
* @internal Only used in unit tests
|
||||
*/
|
||||
public function getUser() {
|
||||
public function getUser(): ?IUser {
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope
|
||||
* @param string $method
|
||||
* @param callable $callback
|
||||
*/
|
||||
#[Override]
|
||||
public function listen($scope, $method, callable $callback) {
|
||||
$this->emitter->listen($scope, $method, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope optional
|
||||
* @param string $method optional
|
||||
* @param callable $callback optional
|
||||
*/
|
||||
#[Override]
|
||||
public function removeListener($scope = null, $method = null, ?callable $callback = null) {
|
||||
$this->emitter->removeListener($scope, $method, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope
|
||||
* @param string $method
|
||||
* @param Node[] $arguments
|
||||
*/
|
||||
public function emit($scope, $method, $arguments = []) {
|
||||
public function emit(string $scope, string $method, array $arguments = []) {
|
||||
$this->emitter->emit($scope, $method, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \OC\Files\Storage\Storage $storage
|
||||
* @param string $mountPoint
|
||||
* @param array $arguments
|
||||
*/
|
||||
public function mount($storage, $mountPoint, $arguments = []) {
|
||||
public function mount(IStorage $storage, string $mountPoint, array $arguments = []) {
|
||||
$mount = new MountPoint($storage, $mountPoint, $arguments);
|
||||
$this->mountManager->addMount($mount);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMount(string $mountPoint): IMountPoint {
|
||||
return $this->mountManager->find($mountPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mountPoint
|
||||
* @return \OC\Files\Mount\MountPoint[]
|
||||
*/
|
||||
#[Override]
|
||||
public function getMountsIn(string $mountPoint): array {
|
||||
return $this->mountManager->findIn($mountPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $storageId
|
||||
* @return \OC\Files\Mount\MountPoint[]
|
||||
*/
|
||||
public function getMountByStorageId($storageId) {
|
||||
return $this->mountManager->findByStorageId($storageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numericId
|
||||
* @return MountPoint[]
|
||||
*/
|
||||
public function getMountByNumericStorageId($numericId) {
|
||||
return $this->mountManager->findByNumericId($numericId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \OC\Files\Mount\MountPoint $mount
|
||||
*/
|
||||
public function unMount($mount) {
|
||||
$this->mountManager->remove($mount);
|
||||
}
|
||||
|
||||
public function get($path) {
|
||||
public function get(string $path): \OCP\Files\Node {
|
||||
$path = $this->normalizePath($path);
|
||||
if ($this->isValidPath($path)) {
|
||||
$fullPath = $this->getFullPath($path);
|
||||
@@ -176,154 +133,105 @@ class Root extends Folder implements IRootFolder {
|
||||
}
|
||||
}
|
||||
|
||||
//most operations can't be done on the root
|
||||
// most operations can't be done on the root
|
||||
|
||||
/**
|
||||
* @param string $targetPath
|
||||
* @return Node
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
*/
|
||||
public function rename($targetPath) {
|
||||
#[Override]
|
||||
public function move(string $targetPath): \OCP\Files\Node {
|
||||
throw new NotPermittedException();
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
#[Override]
|
||||
public function delete(): void {
|
||||
throw new NotPermittedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $targetPath
|
||||
* @return Node
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
*/
|
||||
public function copy($targetPath) {
|
||||
#[Override]
|
||||
public function copy(string $targetPath): \OCP\Files\Node {
|
||||
throw new NotPermittedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $mtime
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
*/
|
||||
public function touch($mtime = null) {
|
||||
#[Override]
|
||||
public function touch(?int $mtime = null): void {
|
||||
throw new NotPermittedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \OC\Files\Storage\Storage
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
*/
|
||||
public function getStorage() {
|
||||
#[Override]
|
||||
public function getStorage(): IStorage {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath() {
|
||||
#[Override]
|
||||
public function getPath(): string {
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInternalPath() {
|
||||
#[Override]
|
||||
public function getInternalPath(): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId() {
|
||||
#[Override]
|
||||
public function getId(): ?int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function stat() {
|
||||
#[Override]
|
||||
public function stat(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMTime() {
|
||||
#[Override]
|
||||
public function getMTime(): int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeMounts
|
||||
* @return int|float
|
||||
*/
|
||||
public function getSize($includeMounts = true): int|float {
|
||||
#[Override]
|
||||
public function getSize(bool $includeMounts = true): int|float {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEtag() {
|
||||
#[Override]
|
||||
public function getEtag(): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPermissions() {
|
||||
#[Override]
|
||||
public function getPermissions(): int {
|
||||
return \OCP\Constants::PERMISSION_CREATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable() {
|
||||
#[Override]
|
||||
public function isReadable(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isUpdateable() {
|
||||
#[Override]
|
||||
public function isUpdateable(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeletable() {
|
||||
#[Override]
|
||||
public function isDeletable(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isShareable() {
|
||||
#[Override]
|
||||
public function isShareable(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
*/
|
||||
public function getParent(): INode|IRootFolder {
|
||||
#[Override]
|
||||
public function getParent(): \OCP\Files\Folder {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
#[Override]
|
||||
public function getName(): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view to user's files folder
|
||||
*
|
||||
* @param string $userId user ID
|
||||
* @return \OCP\Files\Folder
|
||||
* @throws NoUserException
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
public function getUserFolder($userId) {
|
||||
#[Override]
|
||||
public function getUserFolder(string $userId): \OCP\Files\Folder {
|
||||
$userObject = $this->userManager->get($userId);
|
||||
|
||||
if (is_null($userObject)) {
|
||||
@@ -366,10 +274,11 @@ class Root extends Folder implements IRootFolder {
|
||||
return $this->userFolderCache->get($userId);
|
||||
}
|
||||
|
||||
public function getUserMountCache() {
|
||||
public function getUserMountCache(): IUserMountCache {
|
||||
return $this->userMountCache;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getFirstNodeByIdInPath(int $id, string $path): ?INode {
|
||||
// scope the cache by user, so we don't return nodes for different users
|
||||
if ($this->user) {
|
||||
@@ -380,7 +289,7 @@ class Root extends Folder implements IRootFolder {
|
||||
$node = $this->get($cachedPath);
|
||||
// by validating that the cached path still has the requested fileid we can work around the need to invalidate the cached path
|
||||
// if the cached path is invalid or a different file now we fall back to the uncached logic
|
||||
if ($node && $node->getId() === $id) {
|
||||
if ($node->getId() === $id) {
|
||||
return $node;
|
||||
}
|
||||
} catch (NotFoundException|NotPermittedException) {
|
||||
@@ -399,10 +308,7 @@ class Root extends Folder implements IRootFolder {
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return Node[]
|
||||
*/
|
||||
#[Override]
|
||||
public function getByIdInPath(int $id, string $path): array {
|
||||
$mountCache = $this->getUserMountCache();
|
||||
if ($path !== '' && strpos($path, '/', 1) > 0) {
|
||||
@@ -497,6 +403,7 @@ class Root extends Folder implements IRootFolder {
|
||||
return $folders;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getNodeFromCacheEntryAndMount(ICacheEntry $cacheEntry, IMountPoint $mountPoint): INode {
|
||||
$path = $cacheEntry->getPath();
|
||||
$fullPath = $mountPoint->getMountPoint() . $path;
|
||||
|
||||
@@ -14,6 +14,7 @@ use OCP\Files\Folder;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use Override;
|
||||
|
||||
class NewSimpleFile implements ISimpleFile {
|
||||
private Folder $parentFolder;
|
||||
@@ -68,21 +69,10 @@ class NewSimpleFile implements ISimpleFile {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
#[Override]
|
||||
public function getContent(): string {
|
||||
if ($this->file) {
|
||||
$result = $this->file->getContent();
|
||||
|
||||
if ($result === false) {
|
||||
$this->checkFile();
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $this->file->getContent();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\Lock\LockedException;
|
||||
use Override;
|
||||
|
||||
class SimpleFile implements ISimpleFile {
|
||||
private File $file;
|
||||
@@ -48,22 +49,9 @@ class SimpleFile implements ISimpleFile {
|
||||
return $this->file->getMTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content
|
||||
*
|
||||
* @throws GenericFileException
|
||||
* @throws LockedException
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
#[Override]
|
||||
public function getContent(): string {
|
||||
$result = $this->file->getContent();
|
||||
|
||||
if ($result === false) {
|
||||
$this->checkFile();
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $this->file->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,6 +146,6 @@ class SimpleFile implements ISimpleFile {
|
||||
}
|
||||
|
||||
public function getId(): int {
|
||||
return $this->file->getId();
|
||||
return $this->file->getId() ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,6 @@ class PathHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public static function normalizePath(string $path): string {
|
||||
if ($path === '' || $path === '/') {
|
||||
return '/';
|
||||
|
||||
@@ -338,7 +338,7 @@ class View {
|
||||
* @param string $path
|
||||
* @return mixed
|
||||
*/
|
||||
public function stat($path) {
|
||||
public function stat($path): array|false {
|
||||
return $this->basicOperation('stat', $path);
|
||||
}
|
||||
|
||||
@@ -1119,12 +1119,7 @@ class View {
|
||||
return $this->basicOperation('getMimeType', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $path
|
||||
* @param bool $raw
|
||||
*/
|
||||
public function hash($type, $path, $raw = false): string|bool {
|
||||
public function hash(string $type, string $path, bool $raw = false): string|false {
|
||||
$postFix = (substr($path, -1) === '/') ? '/' : '';
|
||||
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
|
||||
if (Filesystem::isValidPath($path)) {
|
||||
@@ -1149,11 +1144,9 @@ class View {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return mixed
|
||||
* @throws InvalidPathException
|
||||
*/
|
||||
public function free_space($path = '/') {
|
||||
public function free_space(string $path = '/'): float|int|false {
|
||||
$this->assertPathLength($path);
|
||||
$result = $this->basicOperation('free_space', $path);
|
||||
if ($result === null) {
|
||||
|
||||
@@ -97,7 +97,8 @@ class Generator {
|
||||
*/
|
||||
public function generatePreviews(File $file, array $specifications, ?string $mimeType = null, bool $cacheResult = true): ISimpleFile {
|
||||
//Make sure that we can read the file
|
||||
if (!$file->isReadable()) {
|
||||
$id = $file->getId();
|
||||
if ($id === null || !$file->isReadable()) {
|
||||
$this->logger->warning('Cannot read file: {path}, skipping preview generation.', ['path' => $file->getPath()]);
|
||||
throw new NotFoundException('Cannot read file');
|
||||
}
|
||||
@@ -106,7 +107,7 @@ class Generator {
|
||||
$mimeType = $file->getMimeType();
|
||||
}
|
||||
|
||||
[$file->getId() => $previews] = $this->previewMapper->getAvailablePreviews([$file->getId()]);
|
||||
[$id => $previews] = $this->previewMapper->getAvailablePreviews([$id]);
|
||||
|
||||
$previewVersion = null;
|
||||
if ($file instanceof IVersionedPreviewFile) {
|
||||
|
||||
@@ -216,7 +216,7 @@ class PreviewManager implements IPreview {
|
||||
}
|
||||
|
||||
$mount = $file->getMountPoint();
|
||||
if ($mount && !$mount->getOption('previews', true)) {
|
||||
if (!$mount->getOption('previews', true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -653,9 +653,7 @@ class DefaultShareProvider implements
|
||||
$childMountNodes = array_filter($node->getDirectoryListing(), function (Node $node): bool {
|
||||
return $node->getInternalPath() === '';
|
||||
});
|
||||
$childMountRootIds = array_map(function (Node $node): int {
|
||||
return $node->getId();
|
||||
}, $childMountNodes);
|
||||
$childMountRootIds = array_map(fn (Node $node): int => $node->getId() ?? -1, $childMountNodes);
|
||||
|
||||
$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
|
||||
$qb->andWhere(
|
||||
|
||||
@@ -123,7 +123,7 @@ class SpeechToTextManager implements ISpeechToTextManager {
|
||||
if (isset($this->taskProcessingManager->getAvailableTaskTypes()['core:audio2text'])) {
|
||||
$taskProcessingTask = new Task(
|
||||
AudioToText::ID,
|
||||
['input' => $file->getId()],
|
||||
['input' => $file->getId() ?? -1],
|
||||
$appId,
|
||||
$userId,
|
||||
'from-SpeechToTextManager||' . $file->getId() . '||' . ($userId ?? '') . '||' . $appId,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
// use OCP namespace for all classes that are considered public.
|
||||
// This means that they should be used by apps instead of the internal Nextcloud classes
|
||||
|
||||
namespace OCP\Files;
|
||||
|
||||
@@ -14,22 +14,21 @@ use OCP\AppFramework\Attribute\Consumable;
|
||||
use OCP\Lock\LockedException;
|
||||
|
||||
/**
|
||||
* Interface File
|
||||
* Represents a file, which is a leaf node in a hierarchical structure.
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
#[Consumable(since: '6.0.0')]
|
||||
interface File extends Node {
|
||||
/**
|
||||
* Get the content of the file as string
|
||||
* Get the content of the file as string.
|
||||
*
|
||||
* @return string
|
||||
* @throws NotPermittedException
|
||||
* @throws GenericFileException
|
||||
* @throws LockedException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getContent();
|
||||
public function getContent(): string;
|
||||
|
||||
/**
|
||||
* Write to the file from string data
|
||||
@@ -40,51 +39,39 @@ interface File extends Node {
|
||||
* @throws LockedException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function putContent($data);
|
||||
|
||||
/**
|
||||
* Get the mimetype of the file
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getMimeType(): string;
|
||||
public function putContent($data): void;
|
||||
|
||||
/**
|
||||
* Open the file as stream, resulting resource can be operated as stream like the result from php's own fopen
|
||||
*
|
||||
* @param string $mode
|
||||
* @return resource|false
|
||||
* @throws NotPermittedException
|
||||
* @throws LockedException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function fopen($mode);
|
||||
public function fopen(string $mode);
|
||||
|
||||
/**
|
||||
* Compute the hash of the file
|
||||
* Compute the hash of the file.
|
||||
*
|
||||
* Type of hash is set with $type and can be anything supported by php's hash_file
|
||||
*
|
||||
* @param string $type
|
||||
* @param bool $raw
|
||||
* @return string
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function hash($type, $raw = false);
|
||||
public function hash(string $type, bool $raw = false): string;
|
||||
|
||||
/**
|
||||
* Get the stored checksum for this file
|
||||
* Get the stored checksum for this file,
|
||||
*
|
||||
* @return string
|
||||
* @since 9.0.0
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getChecksum();
|
||||
public function getChecksum(): string;
|
||||
|
||||
/**
|
||||
* Get the extension of this file
|
||||
* Get the extension of this file.
|
||||
*
|
||||
* @return string
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getExtension(): string;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
@@ -8,7 +10,10 @@
|
||||
namespace OCP\Files;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
use OCP\Constants;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUser;
|
||||
|
||||
/**
|
||||
* Interface FileInfo
|
||||
@@ -54,53 +59,55 @@ interface FileInfo {
|
||||
public const BLACKLIST_FILES_REGEX = '\.(part|filepart)$';
|
||||
|
||||
/**
|
||||
* Get the Etag of the file or folder
|
||||
* Get the Etag of the file or folder.
|
||||
*
|
||||
* @return string
|
||||
* The Etag is a string id used to detect changes to a file or folder,
|
||||
* every time the file or folder is changed the Etag will change too.
|
||||
*
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getEtag();
|
||||
public function getEtag(): string;
|
||||
|
||||
/**
|
||||
* Get the size in bytes for the file or folder
|
||||
* Get the size of the file or folder in bytes.
|
||||
*
|
||||
* @param bool $includeMounts whether or not to include the size of any sub mounts, since 16.0.0
|
||||
* @return int|float
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getSize($includeMounts = true);
|
||||
public function getSize(bool $includeMounts = true): int|float;
|
||||
|
||||
/**
|
||||
* Get the last modified date as timestamp for the file or folder
|
||||
* Get the modified date of the file or folder as unix timestamp.
|
||||
*
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
*
|
||||
* @return int
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getMtime();
|
||||
public function getMtime(): int;
|
||||
|
||||
/**
|
||||
* Get the name of the file or folder
|
||||
* Get the name of the file or folder.
|
||||
*
|
||||
* @return string
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getName();
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Get the path relative to the storage
|
||||
* Get the path of the file or folder relative to the mountpoint of its storage.
|
||||
*
|
||||
* @return string
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getInternalPath();
|
||||
public function getInternalPath(): string;
|
||||
|
||||
/**
|
||||
* Get the absolute path
|
||||
* Get the full path of the file or folder.
|
||||
*
|
||||
* @return string
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getPath();
|
||||
public function getPath(): string;
|
||||
|
||||
/**
|
||||
* Get the full mimetype of the file or folder i.e. 'image/png'
|
||||
@@ -112,141 +119,147 @@ interface FileInfo {
|
||||
/**
|
||||
* Get the first part of the mimetype of the file or folder i.e. 'image'
|
||||
*
|
||||
* @return string
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getMimePart();
|
||||
public function getMimePart(): string;
|
||||
|
||||
/**
|
||||
* Get the storage the file or folder is storage on
|
||||
* Get the storage the file or folder is storage on.
|
||||
*
|
||||
* @return IStorage
|
||||
* @throws NotFoundException
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getStorage();
|
||||
public function getStorage(): IStorage;
|
||||
|
||||
/**
|
||||
* Get the file id of the file or folder
|
||||
* Get the internal file id for the file or folder.
|
||||
*
|
||||
* @return int|null
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getId();
|
||||
public function getId(): ?int;
|
||||
|
||||
/**
|
||||
* Check whether the node is encrypted.
|
||||
*
|
||||
* If it is a file, then it is server side encrypted.
|
||||
* If it is a folder, then it is end-to-end encrypted.
|
||||
*
|
||||
* @return bool
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function isEncrypted();
|
||||
public function isEncrypted(): bool;
|
||||
|
||||
/**
|
||||
* Get the permissions of the file or folder as bitmasked combination of the following constants
|
||||
* \OCP\Constants::PERMISSION_CREATE
|
||||
* \OCP\Constants::PERMISSION_READ
|
||||
* \OCP\Constants::PERMISSION_UPDATE
|
||||
* \OCP\Constants::PERMISSION_DELETE
|
||||
* \OCP\Constants::PERMISSION_SHARE
|
||||
* \OCP\Constants::PERMISSION_ALL
|
||||
* Get the permissions of the file or folder as bit-masked combination of the
|
||||
* following constants.
|
||||
*
|
||||
* @return int
|
||||
* Constants::PERMISSION_CREATE
|
||||
* Constants::PERMISSION_READ
|
||||
* Constants::PERMISSION_UPDATE
|
||||
* Constants::PERMISSION_DELETE
|
||||
* Constants::PERMISSION_SHARE
|
||||
* Constants::PERMISSION_ALL
|
||||
*
|
||||
* @return int-mask-of<Constants::PERMISSION_*>
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 7.0.0 - namespace of constants has changed in 8.0.0
|
||||
*/
|
||||
public function getPermissions();
|
||||
public function getPermissions(): int;
|
||||
|
||||
/**
|
||||
* Check whether this is a file or a folder
|
||||
*
|
||||
* @return string \OCP\Files\FileInfo::TYPE_FILE|\OCP\Files\FileInfo::TYPE_FOLDER
|
||||
* @return FileInfo::TYPE_FILE|FileInfo::TYPE_FOLDER
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getType();
|
||||
public function getType(): string;
|
||||
|
||||
/**
|
||||
* Check if the file or folder is readable
|
||||
* Check if the file or folder is readable.
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotFoundException
|
||||
* @throws InvalidPathException
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function isReadable();
|
||||
public function isReadable(): bool;
|
||||
|
||||
/**
|
||||
* Check if a file is writable
|
||||
* Check if the file or folder is writable.
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function isUpdateable();
|
||||
public function isUpdateable(): bool;
|
||||
|
||||
/**
|
||||
* Check whether new files or folders can be created inside this folder
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 8.0.0
|
||||
*/
|
||||
public function isCreatable();
|
||||
public function isCreatable(): bool;
|
||||
|
||||
/**
|
||||
* Check if a file or folder can be deleted
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function isDeletable();
|
||||
public function isDeletable(): bool;
|
||||
|
||||
/**
|
||||
* Check if a file or folder can be shared
|
||||
* Check if the file or folder is shareable.
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function isShareable();
|
||||
public function isShareable(): bool;
|
||||
|
||||
/**
|
||||
* Check if a file or folder is shared
|
||||
* Check if a file or folder is shared.
|
||||
*
|
||||
* @return bool
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function isShared();
|
||||
public function isShared(): bool;
|
||||
|
||||
/**
|
||||
* Check if a file or folder is mounted
|
||||
*
|
||||
* @return bool
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function isMounted();
|
||||
public function isMounted(): bool;
|
||||
|
||||
/**
|
||||
* Get the mountpoint the file belongs to
|
||||
* Get the mountpoint the file belongs to.
|
||||
*
|
||||
* @return \OCP\Files\Mount\IMountPoint
|
||||
* @since 8.0.0
|
||||
*/
|
||||
public function getMountPoint();
|
||||
public function getMountPoint(): IMountPoint;
|
||||
|
||||
/**
|
||||
* Get the owner of the file
|
||||
* Get the owner of the file.
|
||||
*
|
||||
* @return ?\OCP\IUser
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getOwner();
|
||||
public function getOwner(): ?IUser;
|
||||
|
||||
/**
|
||||
* Get the stored checksum(s) for this file
|
||||
* Get the stored checksum(s) for this file.
|
||||
*
|
||||
* Checksums are stored in the format TYPE:CHECKSUM, here may be multiple checksums separated by a single space
|
||||
* e.g. MD5:d3b07384d113edec49eaa6238ad5ff00 SHA1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
|
||||
*
|
||||
* @return string
|
||||
* @note This will return an empty string if no checksum is currently stored.
|
||||
*
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getChecksum();
|
||||
public function getChecksum(): string;
|
||||
|
||||
/**
|
||||
* Get the extension of the file
|
||||
@@ -275,7 +288,7 @@ interface FileInfo {
|
||||
* If the upload time is not known, 0 will be returned
|
||||
*
|
||||
* Upload time will be set automatically by the server for files uploaded over DAV
|
||||
* files created by Nextcloud apps generally do not have an the upload time set
|
||||
* files created by Nextcloud apps generally do not have the upload time set.
|
||||
*
|
||||
* @return int
|
||||
* @since 18.0.0
|
||||
@@ -283,16 +296,15 @@ interface FileInfo {
|
||||
public function getUploadTime(): int;
|
||||
|
||||
/**
|
||||
* Get the fileid or the parent folder
|
||||
* or -1 if this item has no parent folder (because it is the root)
|
||||
* Get the fileId or the parent folder or -1 if this item has no parent folder
|
||||
* (because it is the root).
|
||||
*
|
||||
* @return int
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getParentId(): int;
|
||||
|
||||
/**
|
||||
* Get the metadata, if available
|
||||
* Get the metadata, if available.
|
||||
*
|
||||
* @return array<string, int|string|bool|float|string[]|int[]>
|
||||
* @since 28.0.0
|
||||
|
||||
@@ -10,60 +10,63 @@
|
||||
|
||||
namespace OCP\Files;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
use OCP\Files\Search\ISearchQuery;
|
||||
|
||||
/**
|
||||
* Folder interface.
|
||||
*
|
||||
* Represents a container node that can hold files, subfolders,
|
||||
* or other nodes in a hierarchical structure.
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
#[Consumable(since: '6.0.0')]
|
||||
interface Folder extends Node {
|
||||
/**
|
||||
* Get the full path of an item in the folder within owncloud's filesystem
|
||||
*
|
||||
* @param string $path relative path of an item in the folder
|
||||
* @return string
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
* @throws NotPermittedException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getFullPath($path);
|
||||
public function getFullPath(string $path): string;
|
||||
|
||||
/**
|
||||
* Get the path of an item in the folder relative to the folder
|
||||
*
|
||||
* @param string $path absolute path of an item in the folder
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
* @return string|null
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getRelativePath($path);
|
||||
public function getRelativePath(string $path): ?string;
|
||||
|
||||
/**
|
||||
* check if a node is a (grand-)child of the folder
|
||||
* Check if a node is a (grand-)child of the folder.
|
||||
*
|
||||
* @param \OCP\Files\Node $node
|
||||
* @return bool
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function isSubNode($node);
|
||||
public function isSubNode(Node $node): bool;
|
||||
|
||||
/**
|
||||
* get the content of this directory
|
||||
* Get the content of this directory.
|
||||
*
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
* @return \OCP\Files\Node[]
|
||||
* @return Node[]
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getDirectoryListing();
|
||||
public function getDirectoryListing(): array;
|
||||
|
||||
/**
|
||||
* Get the node at $path
|
||||
* Get the node at $path.
|
||||
*
|
||||
* @param string $path relative path of the file or folder
|
||||
* @return \OCP\Files\Node
|
||||
* @throws \OCP\Files\NotFoundException
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function get($path);
|
||||
public function get(string $path): Node;
|
||||
|
||||
/**
|
||||
* Get or create new folder if the folder does not already exist.
|
||||
@@ -78,87 +81,81 @@ interface Folder extends Node {
|
||||
* Check if a file or folder exists in the folder
|
||||
*
|
||||
* @param string $path relative path of the file or folder
|
||||
* @return bool
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function nodeExists($path);
|
||||
public function nodeExists(string $path): bool;
|
||||
|
||||
/**
|
||||
* Create a new folder
|
||||
*
|
||||
* @param string $path relative path of the new folder
|
||||
* @return \OCP\Files\Folder
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
* @throws NotPermittedException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function newFolder($path);
|
||||
public function newFolder(string $path): Folder;
|
||||
|
||||
/**
|
||||
* Create a new file
|
||||
*
|
||||
* @param string $path relative path of the new file
|
||||
* @param string|resource|null $content content for the new file, since 19.0.0
|
||||
* @return \OCP\Files\File
|
||||
* @throws \OCP\Files\NotPermittedException
|
||||
* @throws NotPermittedException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function newFile($path, $content = null);
|
||||
public function newFile(string $path, $content = null): File;
|
||||
|
||||
/**
|
||||
* search for files with the name matching $query
|
||||
* Search for files with the name matching $query.
|
||||
*
|
||||
* @param string|ISearchQuery $query
|
||||
* @return \OCP\Files\Node[]
|
||||
* @return Node[]
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function search($query);
|
||||
public function search(string|ISearchQuery $query): array;
|
||||
|
||||
/**
|
||||
* search for files by mimetype
|
||||
* $mimetype can either be a full mimetype (image/png) or a wildcard mimetype (image)
|
||||
* Search for files by mimetype.
|
||||
*
|
||||
* @param string $mimetype
|
||||
* @return \OCP\Files\Node[]
|
||||
* @param string $mimetype can either be a full mimetype (image/png) or a wildcard mimetype (image)
|
||||
* @return Node[]
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function searchByMime($mimetype);
|
||||
public function searchByMime(string $mimetype): array;
|
||||
|
||||
/**
|
||||
* search for files by tag
|
||||
* Search for files by tag.
|
||||
*
|
||||
* @param string|int $tag tag name or tag id
|
||||
* @param string $userId owner of the tags
|
||||
* @return \OCP\Files\Node[]
|
||||
* @return Node[]
|
||||
* @since 8.0.0
|
||||
*/
|
||||
public function searchByTag($tag, $userId);
|
||||
public function searchByTag(string|int $tag, string $userId): array;
|
||||
|
||||
/**
|
||||
* search for files by system tag
|
||||
* Search for files by system tag.
|
||||
*
|
||||
* @param string|int $tag tag name
|
||||
* @param string $tag tag name
|
||||
* @param string $userId user id to ensure access on returned nodes
|
||||
* @return \OCP\Files\Node[]
|
||||
* @return Node[]
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function searchBySystemTag(string $tagName, string $userId, int $limit = 0, int $offset = 0);
|
||||
public function searchBySystemTag(string $tagName, string $userId, int $limit = 0, int $offset = 0): array;
|
||||
|
||||
/**
|
||||
* get a file or folder inside the folder by its internal id
|
||||
* Get a file or folder inside the folder by its internal id.
|
||||
*
|
||||
* This method could return multiple entries. For example once the file/folder
|
||||
* is shared or mounted (files_external) to the user multiple times.
|
||||
*
|
||||
* Note that the different entries can have different permissions.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \OCP\Files\Node[]
|
||||
* @return Node[]
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getById($id);
|
||||
public function getById(int $id): array;
|
||||
|
||||
/**
|
||||
* get a file or folder inside the folder by its internal id
|
||||
* Get a file or folder inside the folder by its internal id.
|
||||
*
|
||||
* Unlike getById, this method only returns a single node even if the user has
|
||||
* access to the file with the requested id multiple times.
|
||||
@@ -169,54 +166,47 @@ interface Folder extends Node {
|
||||
* Apps that require accurate information about the users access to the file should use getById
|
||||
* instead of pick the correct node out of the result.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Node|null
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getFirstNodeById(int $id): ?Node;
|
||||
|
||||
/**
|
||||
* Get the amount of free space inside the folder
|
||||
* Get the amount of free space inside the folder.
|
||||
*
|
||||
* @return int
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getFreeSpace();
|
||||
public function getFreeSpace(): int|float|false;
|
||||
|
||||
/**
|
||||
* Check if new files or folders can be created within the folder
|
||||
* Check if new files or folders can be created within the folder.
|
||||
*
|
||||
* @return bool
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function isCreatable();
|
||||
public function isCreatable(): bool;
|
||||
|
||||
/**
|
||||
* Add a suffix to the name in case the file exists
|
||||
* Add a suffix to the name in case the file exists.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string
|
||||
* @throws NotPermittedException
|
||||
* @since 8.1.0
|
||||
*/
|
||||
public function getNonExistingName($filename);
|
||||
public function getNonExistingName(string $name): string;
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @return \OCP\Files\Node[]
|
||||
* Get recent files and folders.
|
||||
*
|
||||
* @return Node[]
|
||||
* @since 9.1.0
|
||||
*/
|
||||
public function getRecent($limit, $offset = 0);
|
||||
public function getRecent(int $limit, int $offset = 0): array;
|
||||
|
||||
/**
|
||||
* Verify if the given path is valid and allowed from this folder.
|
||||
* Verify if the given fileName is valid and allowed from this folder.
|
||||
*
|
||||
* @param string $path the path from this folder
|
||||
* @param string $fileName
|
||||
* @param bool $readonly Check only if the path is allowed for read-only access
|
||||
* @throws InvalidPathException
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function verifyPath($fileName, $readonly = false): void;
|
||||
public function verifyPath(string $fileName, bool $readonly = false): void;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
@@ -16,23 +18,36 @@ use OCP\Files\Node as INode;
|
||||
/**
|
||||
* Interface IRootFolder
|
||||
*
|
||||
* Hooks available in scope \OC\Files. These are deprecated.
|
||||
* - preWrite(\OCP\Files\Node $node)
|
||||
* - postWrite(\OCP\Files\Node $node)
|
||||
* - preCreate(\OCP\Files\Node $node)
|
||||
* - postCreate(\OCP\Files\Node $node)
|
||||
* - preDelete(\OCP\Files\Node $node)
|
||||
* - postDelete(\OCP\Files\Node $node)
|
||||
* - preTouch(\OC\FilesP\Node $node, int $mtime)
|
||||
* - postTouch(\OCP\Files\Node $node)
|
||||
* - preCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
|
||||
* - postCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
|
||||
* - preRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
|
||||
* - postRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
|
||||
*
|
||||
* @since 8.0.0
|
||||
*/
|
||||
interface IRootFolder extends Folder, Emitter {
|
||||
/**
|
||||
* Returns a view to user's files folder
|
||||
* Returns a view to user's files folder.
|
||||
*
|
||||
* @param string $userId user ID
|
||||
* @return Folder
|
||||
* @throws NoUserException
|
||||
* @throws NotPermittedException
|
||||
*
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getUserFolder($userId);
|
||||
public function getUserFolder(string $userId): Folder;
|
||||
|
||||
/**
|
||||
* Get a file or folder by fileid, inside a parent path
|
||||
* Get a file or folder by fileId, inside a parent path.
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $path
|
||||
@@ -40,10 +55,10 @@ interface IRootFolder extends Folder, Emitter {
|
||||
*
|
||||
* @since 24.0.0
|
||||
*/
|
||||
public function getByIdInPath(int $id, string $path);
|
||||
public function getByIdInPath(int $id, string $path): array;
|
||||
|
||||
/**
|
||||
* get a file or folder inside the folder by its internal id
|
||||
* Get a file or folder inside the folder by its internal id.
|
||||
*
|
||||
* Unlike getByIdInPath, this method only returns a single node even if the user has
|
||||
* access to the file with the requested id multiple times.
|
||||
@@ -54,8 +69,6 @@ interface IRootFolder extends Folder, Emitter {
|
||||
* Apps that require accurate information about the users access to the file should use getByIdInPath
|
||||
* instead of pick the correct node out of the result.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Node|null
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getFirstNodeByIdInPath(int $id, string $path): ?Node;
|
||||
@@ -68,7 +81,7 @@ interface IRootFolder extends Folder, Emitter {
|
||||
public function getMountsIn(string $mountPoint): array;
|
||||
|
||||
/**
|
||||
* Create a `Node` for a file or folder from the cache entry and mountpoint
|
||||
* Create a `Node` for a file or folder from the cache entry and mountpoint.
|
||||
*
|
||||
* @param ICacheEntry $cacheEntry
|
||||
* @param IMountPoint $mountPoint
|
||||
|
||||
@@ -1,56 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
// use OCP namespace for all classes that are considered public.
|
||||
// This means that they should be used by apps instead of the internal Nextcloud classes
|
||||
|
||||
namespace OCP\Files;
|
||||
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
use OCP\Lock\ILockingProvider;
|
||||
use OCP\Lock\LockedException;
|
||||
|
||||
/**
|
||||
* Interface Node
|
||||
*
|
||||
* Represents a generic node in a hierarchical structure. This can be either
|
||||
* a \OCP\Files\Folder or \OCP\Files\File.
|
||||
*
|
||||
* @since 6.0.0 - extends FileInfo was added in 8.0.0
|
||||
*/
|
||||
#[Consumable(since: '6.0.0')]
|
||||
interface Node extends FileInfo {
|
||||
/**
|
||||
* Move the file or folder to a new location
|
||||
* Move the file or folder to a new location.
|
||||
*
|
||||
* @param string $targetPath the absolute target path
|
||||
* @return Node
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException if move not allowed or failed
|
||||
* @throws LockedException
|
||||
* @throws InvalidPathException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function move($targetPath);
|
||||
public function move(string $targetPath): Node;
|
||||
|
||||
/**
|
||||
* Delete the file or folder
|
||||
*
|
||||
* @return void
|
||||
* @throws NotPermittedException
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function delete();
|
||||
public function delete(): void;
|
||||
|
||||
/**
|
||||
* Copy the file or folder to a new location
|
||||
*
|
||||
* @param string $targetPath the absolute target path
|
||||
* @return Node
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function copy($targetPath);
|
||||
public function copy(string $targetPath): Node;
|
||||
|
||||
/**
|
||||
* Change the modified date of the file or folder
|
||||
@@ -63,158 +65,25 @@ interface Node extends FileInfo {
|
||||
* @return void
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function touch($mtime = null);
|
||||
public function touch(?int $mtime = null): void;
|
||||
|
||||
/**
|
||||
* Get the storage backend the file or folder is stored on
|
||||
* Get metadata of the file or folder.
|
||||
*
|
||||
* @return IStorage
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getStorage();
|
||||
|
||||
/**
|
||||
* Get the full path of the file or folder
|
||||
*
|
||||
* @return string
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getPath();
|
||||
|
||||
/**
|
||||
* Get the path of the file or folder relative to the mountpoint of it's storage
|
||||
*
|
||||
* @return string
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getInternalPath();
|
||||
|
||||
/**
|
||||
* Get the internal file id for the file or folder
|
||||
*
|
||||
* @return int
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getId();
|
||||
|
||||
/**
|
||||
* Get metadata of the file or folder
|
||||
* The returned array contains the following values:
|
||||
* - mtime
|
||||
* - size
|
||||
*
|
||||
* @return array
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function stat();
|
||||
public function stat(): array|false;
|
||||
|
||||
/**
|
||||
* Get the modified date of the file or folder as unix timestamp
|
||||
* Get the parent folder of the file or folder.
|
||||
*
|
||||
* @return int
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getMTime();
|
||||
|
||||
/**
|
||||
* Get the size of the file or folder in bytes
|
||||
*
|
||||
* @param bool $includeMounts
|
||||
* @return int|float
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getSize($includeMounts = true);
|
||||
|
||||
/**
|
||||
* Get the Etag of the file or folder
|
||||
* The Etag is an string id used to detect changes to a file or folder,
|
||||
* every time the file or folder is changed the Etag will change to
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getEtag();
|
||||
|
||||
|
||||
/**
|
||||
* Get the permissions of the file or folder as a combination of one or more of the following constants:
|
||||
* - \OCP\Constants::PERMISSION_READ
|
||||
* - \OCP\Constants::PERMISSION_UPDATE
|
||||
* - \OCP\Constants::PERMISSION_CREATE
|
||||
* - \OCP\Constants::PERMISSION_DELETE
|
||||
* - \OCP\Constants::PERMISSION_SHARE
|
||||
*
|
||||
* @return int
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0 - namespace of constants has changed in 8.0.0
|
||||
*/
|
||||
public function getPermissions();
|
||||
|
||||
/**
|
||||
* Check if the file or folder is readable
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function isReadable();
|
||||
|
||||
/**
|
||||
* Check if the file or folder is writable
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function isUpdateable();
|
||||
|
||||
/**
|
||||
* Check if the file or folder is deletable
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function isDeletable();
|
||||
|
||||
/**
|
||||
* Check if the file or folder is shareable
|
||||
*
|
||||
* @return bool
|
||||
* @throws InvalidPathException
|
||||
* @throws NotFoundException
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function isShareable();
|
||||
|
||||
/**
|
||||
* Get the parent folder of the file or folder
|
||||
*
|
||||
* @return Folder
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getParent();
|
||||
|
||||
/**
|
||||
* Get the filename of the file or folder
|
||||
*
|
||||
* @return string
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public function getName();
|
||||
public function getParent(): Folder;
|
||||
|
||||
/**
|
||||
* Acquire a lock on this file or folder.
|
||||
@@ -233,11 +102,11 @@ interface Node extends FileInfo {
|
||||
* Note that in most cases you won't need to manually manage the locks for any files you're working with,
|
||||
* any filesystem operation will automatically acquire the relevant locks for that operation.
|
||||
*
|
||||
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||
* @param ILockingProvider::LOCK_SHARED|ILockingProvider::LOCK_EXCLUSIVE $type
|
||||
* @throws LockedException
|
||||
* @since 9.1.0
|
||||
*/
|
||||
public function lock($type);
|
||||
public function lock(int $type): void;
|
||||
|
||||
/**
|
||||
* Check the type of an existing lock.
|
||||
@@ -248,11 +117,11 @@ interface Node extends FileInfo {
|
||||
* A locked exception will be thrown when these preconditions are not met.
|
||||
* Note that this is also the case if no existing lock exists for the file.
|
||||
*
|
||||
* @param int $targetType \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||
* @param ILockingProvider::LOCK_SHARED|ILockingProvider::LOCK_EXCLUSIVE $targetType
|
||||
* @throws LockedException
|
||||
* @since 9.1.0
|
||||
*/
|
||||
public function changeLock($targetType);
|
||||
public function changeLock(int $targetType): void;
|
||||
|
||||
/**
|
||||
* Release an existing lock.
|
||||
@@ -261,9 +130,9 @@ interface Node extends FileInfo {
|
||||
*
|
||||
* Note that this method will not give any sort of error when trying to free a lock that doesn't exist.
|
||||
*
|
||||
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||
* @param ILockingProvider::LOCK_SHARED|ILockingProvider::LOCK_EXCLUSIVE $type
|
||||
* @throws LockedException
|
||||
* @since 9.1.0
|
||||
*/
|
||||
public function unlock($type);
|
||||
public function unlock(int $type): void;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ final class Template implements \JsonSerializable {
|
||||
'templateId' => $this->templateId,
|
||||
'basename' => $this->file->getName(),
|
||||
'etag' => $this->file->getEtag(),
|
||||
'fileid' => $this->file->getId(),
|
||||
'fileid' => $this->file->getId() ?? -1,
|
||||
'filename' => $this->templateId,
|
||||
'lastmod' => $this->file->getMTime(),
|
||||
'mime' => $this->file->getMimetype(),
|
||||
|
||||
@@ -257,10 +257,10 @@ interface IManager {
|
||||
* @param bool $currentAccess Should the user have currently access to the file
|
||||
* @return ($currentAccess is true
|
||||
* ? array{
|
||||
* users?: array<string, array{node_id: int, node_path: string}>,
|
||||
* remote?: array<string, array{node_id: int, node_path: string}>,
|
||||
* users?: array<string, array{node_id: ?int, node_path: string}>,
|
||||
* remote?: array<string, array{node_id: ?int, node_path: string}>,
|
||||
* public?: bool,
|
||||
* mail?: array<string, array{node_id: int, node_path: string}>
|
||||
* mail?: array<string, array{node_id: ?int, node_path: string}>
|
||||
* }
|
||||
* : array{users?: list<string>, remote?: bool, public?: bool, mail?: list<string>})
|
||||
* @since 12.0.0
|
||||
|
||||
@@ -15,6 +15,7 @@ use OC\Encryption\Exceptions\DecryptionFailedException;
|
||||
use OC\Encryption\Manager;
|
||||
use OC\Files\FileInfo;
|
||||
use OC\Files\View;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUserManager;
|
||||
use OCP\UserInterface;
|
||||
@@ -250,15 +251,15 @@ class DecryptAllTest extends TestCase {
|
||||
[
|
||||
'/user1/files', '', null,
|
||||
[
|
||||
new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null),
|
||||
new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null),
|
||||
new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null),
|
||||
new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], $this->createMock(IMountPoint::class)),
|
||||
new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], $this->createMock(IMountPoint::class)),
|
||||
new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], $this->createMock(IMountPoint::class)),
|
||||
],
|
||||
],
|
||||
[
|
||||
'/user1/files/foo', '', null,
|
||||
[
|
||||
new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null)
|
||||
new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], $this->createMock(IMountPoint::class))
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -15,6 +15,7 @@ use OC\Files\View;
|
||||
use OCP\Constants;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
|
||||
@@ -85,8 +85,8 @@ class FolderTest extends NodeTestCase {
|
||||
->method('getDirectoryContent')
|
||||
->with('/bar/foo')
|
||||
->willReturn([
|
||||
new FileInfo('/bar/foo/asd', null, 'foo/asd', ['fileid' => 2, 'path' => '/bar/foo/asd', 'name' => 'asd', 'size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'], null),
|
||||
new FileInfo('/bar/foo/qwerty', null, 'foo/qwerty', ['fileid' => 3, 'path' => '/bar/foo/qwerty', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'httpd/unix-directory'], null),
|
||||
new FileInfo('/bar/foo/asd', $this->createMock(IStorage::class), 'foo/asd', ['fileid' => 2, 'path' => '/bar/foo/asd', 'name' => 'asd', 'size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'], $this->createMock(IMountPoint::class)),
|
||||
new FileInfo('/bar/foo/qwerty', $this->createMock(IStorage::class), 'foo/qwerty', ['fileid' => 3, 'path' => '/bar/foo/qwerty', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'httpd/unix-directory'], $this->createMock(IMountPoint::class)),
|
||||
]);
|
||||
$this->view->method('getFileInfo')
|
||||
->willReturn($this->createMock(FileInfo::class));
|
||||
@@ -489,12 +489,12 @@ class FolderTest extends NodeTestCase {
|
||||
|
||||
public function testIsSubNode(): void {
|
||||
$rootFolderMock = $this->createMock(IRootFolder::class);
|
||||
$file = new Node($rootFolderMock, $this->view, '/foo/bar');
|
||||
$file = new File($rootFolderMock, $this->view, '/foo/bar');
|
||||
$folder = new Folder($rootFolderMock, $this->view, '/foo');
|
||||
$this->assertTrue($folder->isSubNode($file));
|
||||
$this->assertFalse($folder->isSubNode($folder));
|
||||
|
||||
$file = new Node($rootFolderMock, $this->view, '/foobar');
|
||||
$file = new File($rootFolderMock, $this->view, '/foobar');
|
||||
$this->assertFalse($folder->isSubNode($file));
|
||||
}
|
||||
|
||||
|
||||
@@ -119,10 +119,12 @@ abstract class NodeTestCase extends \Test\TestCase {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
protected function getFileInfo($data, $internalPath = '', ?IStorage $storage = null) {
|
||||
protected function getFileInfo(array $data, string $internalPath = '', ?IStorage $storage = null): FileInfo {
|
||||
$mount = $this->createMock(IMountPoint::class);
|
||||
$mount->method('getStorage')
|
||||
->willReturn($storage);
|
||||
$mount->method('getInternalPath')
|
||||
->willReturnArgument(0);
|
||||
return new FileInfo('', $this->getMockStorage(), $internalPath, $data, $mount);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ use OC\User\NoUserException;
|
||||
use OCP\Cache\CappedMemoryCache;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Config\IUserMountCache;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IUser;
|
||||
@@ -75,8 +77,8 @@ class RootTest extends \Test\TestCase {
|
||||
return $view;
|
||||
}
|
||||
|
||||
protected function getFileInfo($data) {
|
||||
return new FileInfo('', null, '', $data, null);
|
||||
protected function getFileInfo($data): FileInfo {
|
||||
return new FileInfo('', $this->createMock(IStorage::class), '', $data, $this->createMock(IMountPoint::class));
|
||||
}
|
||||
|
||||
public function testGet(): void {
|
||||
|
||||
@@ -91,7 +91,7 @@ class SimpleFileTest extends \Test\TestCase {
|
||||
|
||||
public function testGetContentInvalidAppData(): void {
|
||||
$this->file->method('getContent')
|
||||
->willReturn(false);
|
||||
->willThrowException($this->createMock(NotFoundException::class));
|
||||
$this->file->method('stat')->willReturn(false);
|
||||
|
||||
$parent = $this->createMock(Folder::class);
|
||||
|
||||
@@ -905,7 +905,7 @@ class ViewTest extends \Test\TestCase {
|
||||
$info = $view->getFileInfo('test.part');
|
||||
|
||||
$this->assertInstanceOf('\OCP\Files\FileInfo', $info);
|
||||
$this->assertNull($info->getId());
|
||||
$this->assertEquals(null, $info->getId());
|
||||
$this->assertEquals(6, $sizeWritten);
|
||||
$this->assertEquals(6, $info->getSize());
|
||||
$this->assertEquals('foobar', $view->file_get_contents('test.part'));
|
||||
|
||||
@@ -779,7 +779,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
}
|
||||
|
||||
public function createShare($id, $type, $node, $sharedWith, $sharedBy, $shareOwner,
|
||||
$permissions, $expireDate = null, $password = null, $attributes = null) {
|
||||
$permissions, $expireDate = null, $password = null, $attributes = null): IShare&MockObject {
|
||||
$share = $this->createMock(IShare::class);
|
||||
|
||||
$share->method('getShareType')->willReturn($type);
|
||||
@@ -807,6 +807,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
File::class,
|
||||
[
|
||||
'getId' => 108,
|
||||
'getPath' => 'path',
|
||||
],
|
||||
'default',
|
||||
];
|
||||
@@ -815,6 +816,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
Node::class,
|
||||
[
|
||||
'getId' => 108,
|
||||
'getPath' => 'path',
|
||||
],
|
||||
'default',
|
||||
];
|
||||
@@ -854,6 +856,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
'getPath' => 'path',
|
||||
'getName' => 'name',
|
||||
'getOwner' => $user0,
|
||||
'getInternalPath' => 'not-null',
|
||||
],
|
||||
'default',
|
||||
];
|
||||
@@ -871,6 +874,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
'getPath' => 'path',
|
||||
'getName' => 'name',
|
||||
'getOwner' => $user0,
|
||||
'getInternalPath' => 'not-null',
|
||||
],
|
||||
'default',
|
||||
];
|
||||
@@ -908,6 +912,8 @@ class ManagerTest extends \Test\TestCase {
|
||||
'isShareable' => true,
|
||||
'getPermissions' => Constants::PERMISSION_ALL,
|
||||
'getId' => 42,
|
||||
'getPath' => 'path',
|
||||
'getInternalPath' => 'not-null',
|
||||
],
|
||||
'none',
|
||||
];
|
||||
@@ -923,6 +929,8 @@ class ManagerTest extends \Test\TestCase {
|
||||
'getPermissions' => Constants::PERMISSION_ALL,
|
||||
'getId' => 187,
|
||||
'getOwner' => $user0,
|
||||
'getPath' => 'path',
|
||||
'getInternalPath' => 'not-null',
|
||||
],
|
||||
'default',
|
||||
];
|
||||
@@ -939,6 +947,8 @@ class ManagerTest extends \Test\TestCase {
|
||||
'getPermissions' => Constants::PERMISSION_ALL,
|
||||
'getId' => 108,
|
||||
'getOwner' => $user0,
|
||||
'getPath' => 'path',
|
||||
'getInternalPath' => 'not-null',
|
||||
],
|
||||
'default',
|
||||
];
|
||||
@@ -963,13 +973,15 @@ class ManagerTest extends \Test\TestCase {
|
||||
'getPermissions' => Constants::PERMISSION_READ ^ Constants::PERMISSION_UPDATE,
|
||||
'getId' => 108,
|
||||
'getOwner' => $user0,
|
||||
'getPath' => 'path',
|
||||
'getInternalPath' => 'not-null',
|
||||
],
|
||||
'remote',
|
||||
];
|
||||
|
||||
$data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 1, null, null], null, false];
|
||||
$data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 3, null, null], null, false];
|
||||
$data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 31, null, null], 'Cannot increase permissions of ', true];
|
||||
$data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 31, null, null], 'Cannot increase permissions of path', true];
|
||||
|
||||
return $data;
|
||||
}
|
||||
@@ -983,7 +995,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
$return->method('getUID')
|
||||
->willReturn($uid);
|
||||
} elseif ($methodName === 'getMountPoint') {
|
||||
$return = $this->createMock($return);
|
||||
$return = $this->createMockForIntersectionOfInterfaces([IMountPoint::class, $return]);
|
||||
}
|
||||
$mock->method($methodName)->willReturn($return);
|
||||
}
|
||||
@@ -2945,7 +2957,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
}
|
||||
|
||||
public function testGetSharesByOwnerless(): void {
|
||||
$mount = $this->createMock(IShareOwnerlessMount::class);
|
||||
$mount = $this->createMockForIntersectionOfInterfaces([IMountPoint::class, IShareOwnerlessMount::class]);
|
||||
|
||||
$node = $this->createMock(Folder::class);
|
||||
$node
|
||||
@@ -4668,7 +4680,7 @@ class ManagerTest extends \Test\TestCase {
|
||||
$share1 = $this->createMock(IShare::class);
|
||||
$share2 = $this->createMock(IShare::class);
|
||||
|
||||
$mount = $this->createMock(IShareOwnerlessMount::class);
|
||||
$mount = $this->createMockForIntersectionOfInterfaces([IMountPoint::class, IShareOwnerlessMount::class]);
|
||||
|
||||
$folder = $this->createMock(Folder::class);
|
||||
$folder
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
namespace Test\Share20;
|
||||
|
||||
use OC\Share20\ShareHelper;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\Node;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Share\IManager;
|
||||
@@ -109,8 +110,7 @@ class ShareHelperTest extends TestCase {
|
||||
public function testGetPathsForUsers(array $users, array $nodes, array $expected): void {
|
||||
$lastNode = null;
|
||||
foreach ($nodes as $nodeId => $nodeName) {
|
||||
/** @var Node|\PHPUnit\Framework\MockObject\MockObject $node */
|
||||
$node = $this->createMock(Node::class);
|
||||
$node = $this->createMock(Folder::class);
|
||||
$node->expects($this->any())
|
||||
->method('getId')
|
||||
->willReturn($nodeId);
|
||||
@@ -166,8 +166,7 @@ class ShareHelperTest extends TestCase {
|
||||
public function testGetPathsForRemotes(array $remotes, array $nodes, array $expected): void {
|
||||
$lastNode = null;
|
||||
foreach ($nodes as $nodeId => $nodePath) {
|
||||
/** @var Node|\PHPUnit\Framework\MockObject\MockObject $node */
|
||||
$node = $this->createMock(Node::class);
|
||||
$node = $this->createMock(Folder::class);
|
||||
$node->expects($this->any())
|
||||
->method('getId')
|
||||
->willReturn($nodeId);
|
||||
|
||||
Reference in New Issue
Block a user