Compare commits
12 Commits
carl/serve
...
jtr/refact
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92ba2258b9 | ||
|
|
7d36a854f8 | ||
|
|
0619f16ba1 | ||
|
|
86244b3c79 | ||
|
|
b9a7524f0d | ||
|
|
2c5e71476e | ||
|
|
baa537bef0 | ||
|
|
3e88ade603 | ||
|
|
54ada0dd49 | ||
|
|
d628760b60 | ||
|
|
2e5710964c | ||
|
|
ebeae5e4b7 |
@@ -19,136 +19,257 @@ use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\SimpleFS\ISimpleFolder;
|
||||
|
||||
/**
|
||||
* Implements app-specific data storage {@see \OCP\Files\IAppData} by wrapping IRootFolder and
|
||||
* Folder objects and re-using {@see \OCP\Files\SimpleFS\SIimpleFolder} overlaid on Nextcloud's
|
||||
* virtual file system.
|
||||
*
|
||||
* @internal This class is not part of the public API and may change without notice.
|
||||
*/
|
||||
class AppData implements IAppData {
|
||||
private IRootFolder $rootFolder;
|
||||
private SystemConfig $config;
|
||||
private string $appId;
|
||||
private ?Folder $folder = null;
|
||||
/** @var CappedMemoryCache<ISimpleFolder|NotFoundException> */
|
||||
/**
|
||||
* Cached reference to the app-specific Folder for this application.
|
||||
* This is the Folder instance for "{$instanceAppDataFolderName}/{$appId}" and is created
|
||||
* or retrieved on first access via getOrCreateAppDataFolder().
|
||||
*
|
||||
* @var Folder|null
|
||||
*/
|
||||
private ?Folder $appDataFolder = null;
|
||||
/**
|
||||
* Caches references to subfolders or lookup errors for app-specific data directories.
|
||||
* Keys are in the format "{$appId}/{$name}". Values are either ISimpleFolder on success,
|
||||
* or NotFoundException if the folder was not found.
|
||||
*
|
||||
* @var CappedMemoryCache<ISimpleFolder|NotFoundException>
|
||||
*/
|
||||
private CappedMemoryCache $folders;
|
||||
|
||||
/**
|
||||
* AppData constructor.
|
||||
*
|
||||
* @param IRootFolder $rootFolder
|
||||
* @param SystemConfig $systemConfig
|
||||
* @param string $appId
|
||||
*/
|
||||
public function __construct(IRootFolder $rootFolder,
|
||||
SystemConfig $systemConfig,
|
||||
string $appId) {
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->config = $systemConfig;
|
||||
$this->appId = $appId;
|
||||
public function __construct(
|
||||
private IRootFolder $rootFolder,
|
||||
private SystemConfig $config,
|
||||
private string $appId
|
||||
) {
|
||||
$this->folders = new CappedMemoryCache();
|
||||
}
|
||||
|
||||
private function getAppDataFolderName() {
|
||||
$instanceId = $this->config->getValue('instanceid', null);
|
||||
if ($instanceId === null) {
|
||||
throw new \RuntimeException('no instance id!');
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* TODO: Possible memory optimization opportunity for larger folders.
|
||||
*/
|
||||
public function getDirectoryListing(): array {
|
||||
$nodes = $this->getOrCreateAppDataFolder()->getDirectoryListing();
|
||||
$subFolders = [];
|
||||
|
||||
return 'appdata_' . $instanceId;
|
||||
foreach ($nodes as $node) {
|
||||
if ($node instanceof Folder) {
|
||||
$subFolders[] = new SimpleFolder($node);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return ISimpleFolder[] */
|
||||
return $subFolders;
|
||||
}
|
||||
|
||||
protected function getAppDataRootFolder(): Folder {
|
||||
$name = $this->getAppDataFolderName();
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Wraps retrieved Folder in an SimpleFolder.
|
||||
* Uses an in-memory cache for performance.
|
||||
*
|
||||
* @throws \RuntimeException for unrecoverable errors
|
||||
*/
|
||||
public function getFolder(string $name): ISimpleFolder {
|
||||
$cacheKey = $this->buildCacheKey($name);
|
||||
// Check cache
|
||||
$cachedFolder = $this->folders->get($cacheKey);
|
||||
if ($cachedFolder instanceof ISimpleFolder) {
|
||||
return $cachedFolder;
|
||||
}
|
||||
if ($cachedFolder instanceof NotFoundException) {
|
||||
// We can use the cached NotFound w/o cache management since cache is in-request only
|
||||
throw $cachedFolder;
|
||||
}
|
||||
|
||||
if ($name === '/') {
|
||||
// Special case: app's appdata root folder
|
||||
// Get the Folder object representing this app's appdata root folder
|
||||
$appDataFolder = $this->getOrCreateAppDataFolder();
|
||||
$requestedFolder = $appDataFolder;
|
||||
// Try to get the subfolder (within app's appdata folder) by path
|
||||
} else {
|
||||
// Standard case: subfolder within app's appdata
|
||||
try {
|
||||
// We don't want to create the subfolder if it doesn't exist.
|
||||
// So we retrieve the subfolder directly by path,
|
||||
// instead of calling getOrCreateAppDataFolder().
|
||||
$appDataPath = $this->buildAppDataPath($name);
|
||||
$requestedFolder = $this->rootFolder->get($appDataPath);
|
||||
} catch (NotFoundException $e) {
|
||||
$this->folders->set($cacheKey, $e);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->wrapAndCacheFolder($cacheKey, $requestedFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function newFolder(string $name): ISimpleFolder {
|
||||
$cacheKey = $this->buildCacheKey($name);
|
||||
$newFolder = $this->getOrCreateAppDataFolder()->newFolder($name);
|
||||
|
||||
return $this->wrapAndCacheFolder($cacheKey, $newFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the top-level appdata folder for the current Nextcloud instance.
|
||||
*
|
||||
* @return string The appdata folder name, including the instance identifier.
|
||||
* @throws \RuntimeException for unrecoverable errors
|
||||
*/
|
||||
private function getInstanceAppDataFolderName(): string {
|
||||
$instanceId = $this->config->getValue('instanceid', null);
|
||||
if ($instanceId === null) {
|
||||
throw new \RuntimeException(
|
||||
'Could not determine instance appdata folder; configuration is missing an instance id!'
|
||||
);
|
||||
}
|
||||
|
||||
$instanceAppDataFolderName = 'appdata_' . $instanceId;
|
||||
return $instanceAppDataFolderName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the top-level appdata folder for the current Nextcloud instance.
|
||||
* Creates the folder if it does not exist.
|
||||
*
|
||||
* Protected rather than private since it's also used by downstream \OC\Preview\Storage\Root class.
|
||||
*
|
||||
* @return Folder The instance appdata folder.
|
||||
* @throws \RuntimeException If the folder cannot be created due to permissions.
|
||||
*/
|
||||
protected function getInstanceAppDataFolder(): Folder {
|
||||
$instanceAppDataFolderName = $this->getInstanceAppDataFolderName();
|
||||
|
||||
try {
|
||||
/** @var Folder $node */
|
||||
$node = $this->rootFolder->get($name);
|
||||
$node = $this->rootFolder->get($instanceAppDataFolderName);
|
||||
return $node;
|
||||
} catch (NotFoundException $e) {
|
||||
try {
|
||||
return $this->rootFolder->newFolder($name);
|
||||
return $this->rootFolder->newFolder($instanceAppDataFolderName);
|
||||
} catch (NotPermittedException $e) {
|
||||
throw new \RuntimeException('Could not get appdata folder');
|
||||
throw new \RuntimeException(
|
||||
'Could not get nor create instance appdata folder '
|
||||
. $instanceAppDataFolderName
|
||||
. ' while trying to get or create dedicated appdata folder for '
|
||||
. $this->appId
|
||||
. '. Check data directory permissions!'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Folder
|
||||
* @throws \RuntimeException
|
||||
* Retrieves the app-specific data folder for the current application.
|
||||
* Creates the folder if it does not already exist and caches the reference.
|
||||
*
|
||||
* @return Folder The Folder object representing the app's data directory.
|
||||
* @throws \RuntimeException If the folder cannot be accessed or created.
|
||||
*/
|
||||
private function getAppDataFolder(): Folder {
|
||||
if ($this->folder === null) {
|
||||
$name = $this->getAppDataFolderName();
|
||||
|
||||
try {
|
||||
$this->folder = $this->rootFolder->get($name . '/' . $this->appId);
|
||||
} catch (NotFoundException $e) {
|
||||
$appDataRootFolder = $this->getAppDataRootFolder();
|
||||
|
||||
try {
|
||||
$this->folder = $appDataRootFolder->get($this->appId);
|
||||
} catch (NotFoundException $e) {
|
||||
try {
|
||||
$this->folder = $appDataRootFolder->newFolder($this->appId);
|
||||
} catch (NotPermittedException $e) {
|
||||
throw new \RuntimeException('Could not get appdata folder for ' . $this->appId);
|
||||
}
|
||||
}
|
||||
}
|
||||
private function getOrCreateAppDataFolder(): Folder {
|
||||
if ($this->appDataFolder !== null) {
|
||||
return $this->appDataFolder;
|
||||
}
|
||||
|
||||
return $this->folder;
|
||||
}
|
||||
|
||||
public function getFolder(string $name): ISimpleFolder {
|
||||
$key = $this->appId . '/' . $name;
|
||||
if ($cachedFolder = $this->folders->get($key)) {
|
||||
if ($cachedFolder instanceof \Exception) {
|
||||
throw $cachedFolder;
|
||||
} else {
|
||||
return $cachedFolder;
|
||||
}
|
||||
}
|
||||
// Try direct lookup
|
||||
$appDataFolderName = $this->buildAppDataPath();
|
||||
try {
|
||||
// Hardening if somebody wants to retrieve '/'
|
||||
if ($name === '/') {
|
||||
$node = $this->getAppDataFolder();
|
||||
} else {
|
||||
$path = $this->getAppDataFolderName() . '/' . $this->appId . '/' . $name;
|
||||
$node = $this->rootFolder->get($path);
|
||||
}
|
||||
$this->appDataFolder = $this->rootFolder->get($appDataFolderName);
|
||||
return $this->appDataFolder;
|
||||
} catch (NotFoundException $e) {
|
||||
$this->folders->set($key, $e);
|
||||
throw $e;
|
||||
// Continue
|
||||
}
|
||||
|
||||
/** @var Folder $node */
|
||||
$folder = new SimpleFolder($node);
|
||||
$this->folders->set($key, $folder);
|
||||
return $folder;
|
||||
// Try indirect lookup (instance + appId) - slower/more queries
|
||||
// TODO: This fallback seems redundant/unnecessary at this point...
|
||||
// - Can be removed since #12883?
|
||||
// - I suspect it was just left in to be conservative, but is presumably already a no-op.
|
||||
$instanceAppDataFolder = $this->getInstanceAppDataFolder();
|
||||
try {
|
||||
$node = $instanceAppDataFolder->get($this->appId);
|
||||
if (!($node instanceof Folder)) {
|
||||
throw new \RuntimeException('Appdata node is not a folder!');
|
||||
}
|
||||
$this->appDataFolder = $node;
|
||||
return $this->appDataFolder;
|
||||
} catch (NotFoundException $e) {
|
||||
// Continue
|
||||
}
|
||||
|
||||
// Still not found, try to create
|
||||
try {
|
||||
$this->appDataFolder = $instanceAppDataFolder->newFolder($this->appId);
|
||||
return $this->appDataFolder;
|
||||
} catch (NotPermittedException $e) {
|
||||
throw new \RuntimeException('Could not get nor create appdata folder for ' . $this->appId);
|
||||
}
|
||||
}
|
||||
|
||||
public function newFolder(string $name): ISimpleFolder {
|
||||
$key = $this->appId . '/' . $name;
|
||||
$folder = $this->getAppDataFolder()->newFolder($name);
|
||||
/**
|
||||
* Returns the numeric ID of the app-specific data folder.
|
||||
*
|
||||
* Public rather than private since it's called by OC\Preview\BackgroundCleanupJob class.
|
||||
*
|
||||
* Note: Seems to only be used by downstream \OC\Preview\Storage\Root class.
|
||||
*
|
||||
* @return int The folder's unique identifier.
|
||||
*/
|
||||
public function getId(): int {
|
||||
return $this->getOrCreateAppDataFolder()->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the folder name and generates a cache key.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
* @throws \RuntimeException if the name is empty
|
||||
*/
|
||||
private function buildCacheKey(string $name): string {
|
||||
if ($name === '') {
|
||||
throw new \RuntimeException('Appdata folder name cannot be (empty).');
|
||||
}
|
||||
return $this->appId . '/' . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a Folder as SimpleFolder, caches it, and returns it.
|
||||
*
|
||||
* @param string $cacheKey
|
||||
* @param Folder $folder
|
||||
* @return ISimpleFolder
|
||||
*/
|
||||
private function wrapAndCacheFolder(string $cacheKey, Folder $folder): ISimpleFolder {
|
||||
$simpleFolder = new SimpleFolder($folder);
|
||||
$this->folders->set($key, $simpleFolder);
|
||||
$this->folders->set($cacheKey, $simpleFolder);
|
||||
return $simpleFolder;
|
||||
}
|
||||
|
||||
public function getDirectoryListing(): array {
|
||||
$listing = $this->getAppDataFolder()->getDirectoryListing();
|
||||
|
||||
$fileListing = array_map(function (Node $folder) {
|
||||
if ($folder instanceof Folder) {
|
||||
return new SimpleFolder($folder);
|
||||
}
|
||||
return null;
|
||||
}, $listing);
|
||||
|
||||
$fileListing = array_filter($fileListing);
|
||||
|
||||
return array_values($fileListing);
|
||||
}
|
||||
|
||||
public function getId(): int {
|
||||
return $this->getAppDataFolder()->getId();
|
||||
|
||||
/**
|
||||
* Builds the full path to a subfolder in an app's appdata directory.
|
||||
*
|
||||
* If $subfolder is provided, returns the path to that subfolder;
|
||||
* otherwise returns the path to the root of the app's appdata folder.
|
||||
*
|
||||
* @param string|null $subfolder Optional subfolder name
|
||||
* @return string
|
||||
*/
|
||||
private function buildAppDataPath(?string $subfolder = null): string {
|
||||
$base = $this->getInstanceAppDataFolderName() . '/' . $this->appId;
|
||||
return $subfolder === null ? $base : $base . '/' . $subfolder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,46 +13,44 @@ use OCP\Files\NotFoundException;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\Files\SimpleFS\ISimpleFolder;
|
||||
|
||||
/**
|
||||
* Concrete implementation of {@see \OCP\Files\SimpleFS\ISimpleFolder}.
|
||||
*
|
||||
* Wraps a Folder object to expose simplified filesystem operations.
|
||||
*
|
||||
* @internal This class is not part of the public API and may change without notice.
|
||||
*/
|
||||
class SimpleFolder implements ISimpleFolder {
|
||||
/** @var Folder */
|
||||
private $folder;
|
||||
public function __construct(private Folder $folder) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Folder constructor.
|
||||
*
|
||||
* @param Folder $folder
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Folder $folder) {
|
||||
$this->folder = $folder;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->folder->getName();
|
||||
}
|
||||
|
||||
public function getDirectoryListing(): array {
|
||||
$listing = $this->folder->getDirectoryListing();
|
||||
|
||||
$fileListing = array_map(function (Node $file) {
|
||||
if ($file instanceof File) {
|
||||
return new SimpleFile($file);
|
||||
}
|
||||
return null;
|
||||
}, $listing);
|
||||
|
||||
$fileListing = array_filter($fileListing);
|
||||
|
||||
return array_values($fileListing);
|
||||
}
|
||||
|
||||
public function delete(): void {
|
||||
$this->folder->delete();
|
||||
$nodes = $this->folder->getDirectoryListing();
|
||||
$files = [];
|
||||
foreach ($nodes as $node) {
|
||||
if ($node instanceof File) {
|
||||
$files[] = new SimpleFile($node);
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* (NotFoundException|NotPermittedException) are treated equally in the underlying class and not passed up;
|
||||
* Both situations will return false here.
|
||||
*/
|
||||
public function fileExists(string $name): bool {
|
||||
return $this->folder->nodeExists($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFile(string $name): ISimpleFile {
|
||||
$file = $this->folder->get($name);
|
||||
|
||||
@@ -63,6 +61,9 @@ class SimpleFolder implements ISimpleFolder {
|
||||
return new SimpleFile($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function newFile(string $name, $content = null): ISimpleFile {
|
||||
if ($content === null) {
|
||||
// delay creating the file until it's written to
|
||||
@@ -73,6 +74,23 @@ class SimpleFolder implements ISimpleFolder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete(): void {
|
||||
$this->folder->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->folder->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFolder(string $name): ISimpleFolder {
|
||||
$folder = $this->folder->get($name);
|
||||
|
||||
@@ -83,6 +101,12 @@ class SimpleFolder implements ISimpleFolder {
|
||||
return new SimpleFolder($folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* (AlreadyExistsException|InvalidPathException) and other storage-specific exceptions may bubble up here.
|
||||
* The implementation does not handle them and the interface does not define if we should.
|
||||
*/
|
||||
public function newFolder(string $path): ISimpleFolder {
|
||||
$folder = $this->folder->newFolder($path);
|
||||
return new SimpleFolder($folder);
|
||||
|
||||
@@ -4,14 +4,65 @@
|
||||
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\Files;
|
||||
|
||||
use OCP\Files\SimpleFS\ISimpleRoot;
|
||||
use OCP\Files\SimpleFS\ISimpleFolder;
|
||||
|
||||
/**
|
||||
* Interface IAppData
|
||||
* Interface for accessing app-specific data storage in Nextcloud.
|
||||
*
|
||||
* Implementations of this interface provide a virtual filesystem abstraction
|
||||
* for storing application data that is isolated from user files. Each Nextcloud
|
||||
* application can store, retrieve, and manage its own data within a dedicated
|
||||
* subfolder of the instance-wide appdata directory.
|
||||
*
|
||||
* This interface extends {@see OCP\Files\SimpleFS\ISimpleRoot}, allowing
|
||||
* applications to work with files and folders using simplified filesystem
|
||||
* operations.
|
||||
*
|
||||
* Typical use cases include caching, storing previews, thumbnails, configuration,
|
||||
* or other non-user-specific data for an app.
|
||||
*
|
||||
* @since 11.0.0
|
||||
*/
|
||||
interface IAppData extends ISimpleRoot {
|
||||
|
||||
/**
|
||||
* Returns a list of subfolders in the app-specific data folder.
|
||||
*
|
||||
* Unlike ISimpleRoot, this method only lists folders within the current application's
|
||||
* data storage area, not user directories or files. The returned folders are isolated
|
||||
* from other applications. Files within the appdata folder are not included.
|
||||
*
|
||||
* @return ISimpleFolder[] List of subfolders in the appdata directory.
|
||||
*/
|
||||
public function getDirectoryListing(): array;
|
||||
|
||||
/**
|
||||
* Retrieves a named subfolder from the app-specific data storage.
|
||||
*
|
||||
* The folder is always relative to the application's own appdata directory, and is
|
||||
* isolated from other apps and user files. If the folder does not exist, an exception
|
||||
* is thrown.
|
||||
*
|
||||
* @param string $name Name of the subfolder to retrieve.
|
||||
* @return ISimpleFolder The requested folder.
|
||||
* @throws \OCP\Files\NotFoundException If the folder does not exist.
|
||||
*/
|
||||
public function getFolder(string $name): ISimpleFolder;
|
||||
|
||||
/**
|
||||
* Creates a new subfolder within the app-specific data directory.
|
||||
*
|
||||
* The folder is created inside the application's appdata storage and is not visible
|
||||
* to other apps or users. If a folder with the given name already exists, an exception
|
||||
* may be thrown.
|
||||
*
|
||||
* @param string $name Name of the folder to create.
|
||||
* @return ISimpleFolder The created folder.
|
||||
* @throws \OCP\Files\NotPermittedException If the folder cannot be created.
|
||||
*/
|
||||
public function newFolder(string $name): ISimpleFolder;
|
||||
}
|
||||
|
||||
@@ -10,74 +10,90 @@ use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
|
||||
/**
|
||||
* Interface ISimpleFolder
|
||||
* Interface for representing and manipulating simple folders in Nextcloud's virtual filesystem.
|
||||
*
|
||||
* Provides methods for listing, creating, retrieving, and deleting folders.
|
||||
*
|
||||
* @since 11.0.0
|
||||
* @api
|
||||
*/
|
||||
interface ISimpleFolder {
|
||||
/**
|
||||
* Get all the files in a folder
|
||||
* Get all the files in this folder.
|
||||
*
|
||||
* @return ISimpleFile[]
|
||||
* @return ISimpleFile[] Array of files contained in the folder.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getDirectoryListing(): array;
|
||||
|
||||
/**
|
||||
* Check if a file with $name exists
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
* @since 11.0.0
|
||||
*/
|
||||
/**
|
||||
* Check if a file with the given name exists in this folder.
|
||||
*
|
||||
* @param string $name Name of the file to check.
|
||||
* @return bool True if the file exists, false otherwise.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function fileExists(string $name): bool;
|
||||
|
||||
/**
|
||||
* Get the file named $name from the folder
|
||||
/**
|
||||
* Get the file named $name from this folder.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @since 11.0.0
|
||||
*/
|
||||
* @param string $name Name of the file to retrieve.
|
||||
* @return ISimpleFile The file object.
|
||||
* @throws NotFoundException If the file does not exist.
|
||||
* @throws NotPermittedException If access to the file is not permitted.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getFile(string $name): ISimpleFile;
|
||||
|
||||
/**
|
||||
* Creates a new file with $name in the folder
|
||||
*
|
||||
* @param string|resource|null $content @since 19.0.0
|
||||
* @throws NotPermittedException
|
||||
* @since 11.0.0
|
||||
*/
|
||||
/**
|
||||
* Creates a new file with the given name in this folder.
|
||||
*
|
||||
* @param string $name Name of the new file.
|
||||
* @param string|resource|null $content Initial content for the file (optional).
|
||||
* @return ISimpleFile The newly created file object.
|
||||
* @throws NotPermittedException If file creation is not permitted.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function newFile(string $name, $content = null): ISimpleFile;
|
||||
|
||||
/**
|
||||
* Remove the folder and all the files in it
|
||||
*
|
||||
* @throws NotPermittedException
|
||||
* @since 11.0.0
|
||||
*/
|
||||
/**
|
||||
* Remove this folder and all its contents.
|
||||
*
|
||||
* @return void
|
||||
* @throws NotPermittedException If deletion is not permitted.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function delete(): void;
|
||||
|
||||
/**
|
||||
* Get the folder name
|
||||
*
|
||||
* @since 11.0.0
|
||||
*/
|
||||
/**
|
||||
* Get the name of this folder.
|
||||
*
|
||||
* @return string The folder name.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Get the folder named $name from the current folder
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @since 25.0.0
|
||||
*/
|
||||
/**
|
||||
* Get the subfolder named $name from this folder.
|
||||
*
|
||||
* @param string $name Name of the subfolder to retrieve.
|
||||
* @return ISimpleFolder The subfolder object.
|
||||
* @throws NotFoundException If the subfolder does not exist.
|
||||
* @since 25.0.0
|
||||
*/
|
||||
public function getFolder(string $name): ISimpleFolder;
|
||||
|
||||
/**
|
||||
* Creates a new folder with $name in the current folder
|
||||
*
|
||||
* @param string|resource|null $content @since 19.0.0
|
||||
* @throws NotPermittedException
|
||||
* @since 25.0.0
|
||||
*/
|
||||
/**
|
||||
* Creates a new subfolder with the given path in this folder.
|
||||
*
|
||||
* @param string $path Path (name) of the new subfolder.
|
||||
* @return ISimpleFolder The newly created subfolder object.
|
||||
* @throws NotPermittedException If folder creation is not permitted.
|
||||
* @since 25.0.0
|
||||
*/
|
||||
// TODO: rename $path -> $name for consistency (already the case in parallel interfaces such as ISimpleRoot).
|
||||
// Alternatively/related, clarify whether nested paths/names are officially accepted here (versus for getFolder() where they're not).
|
||||
// Same technically applies to some other methods with different behavior, such as fileExists().
|
||||
public function newFolder(string $path): ISimpleFolder;
|
||||
}
|
||||
|
||||
@@ -10,35 +10,42 @@ use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
|
||||
/**
|
||||
* Interface ISimpleRoot
|
||||
* Interface for representing and manipulating root of a simple folder structure in Nextcloud's virtual filesystem.
|
||||
*
|
||||
* Provides methods for listing, creating, and retrieving folders within the root.
|
||||
*
|
||||
* @since 11.0.0
|
||||
* @api
|
||||
*/
|
||||
interface ISimpleRoot {
|
||||
/**
|
||||
* Get the folder with name $name
|
||||
* Get all folders at the root of the simple filesystem.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws \RuntimeException
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getFolder(string $name): ISimpleFolder;
|
||||
|
||||
/**
|
||||
* Get all the Folders
|
||||
*
|
||||
* @return ISimpleFolder[]
|
||||
* @throws NotFoundException
|
||||
* @throws \RuntimeException
|
||||
* @return ISimpleFolder[] Array of ISimpleFolder instances representing each folder.
|
||||
* @throws NotFoundException If no folders are found.
|
||||
* @throws \RuntimeException For general runtime errors.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getDirectoryListing(): array;
|
||||
|
||||
/**
|
||||
* Create a new folder named $name
|
||||
* Get the folder named $name from the root of the simple filesystem.
|
||||
*
|
||||
* @throws NotPermittedException
|
||||
* @throws \RuntimeException
|
||||
* @param string $name The name of the folder to retrieve.
|
||||
* @return ISimpleFolder The folder instance corresponding to the provided name.
|
||||
* @throws NotFoundException If the folder with the given name does not exist.
|
||||
* @throws \RuntimeException For general runtime errors.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getFolder(string $name): ISimpleFolder;
|
||||
|
||||
/**
|
||||
* Creates a new folder named $name at the root of the simple filesystem.
|
||||
*
|
||||
* @param string $name The name of the new folder to create.
|
||||
* @return ISimpleFolder The newly created folder instance.
|
||||
* @throws NotPermittedException If folder creation is not permitted.
|
||||
* @throws \RuntimeException For general runtime errors.
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function newFolder(string $name): ISimpleFolder;
|
||||
|
||||
Reference in New Issue
Block a user