aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/autoloader.php12
-rw-r--r--lib/base.php22
-rw-r--r--lib/composer/composer/autoload_classmap.php5
-rw-r--r--lib/composer/composer/autoload_static.php5
-rw-r--r--lib/l10n/cs.js2
-rw-r--r--lib/l10n/cs.json2
-rw-r--r--lib/l10n/de.js4
-rw-r--r--lib/l10n/de.json4
-rw-r--r--lib/l10n/de_DE.js2
-rw-r--r--lib/l10n/de_DE.json2
-rw-r--r--lib/l10n/en_GB.js2
-rw-r--r--lib/l10n/en_GB.json2
-rw-r--r--lib/l10n/es.js2
-rw-r--r--lib/l10n/es.json2
-rw-r--r--lib/l10n/et_EE.js2
-rw-r--r--lib/l10n/et_EE.json2
-rw-r--r--lib/l10n/ga.js2
-rw-r--r--lib/l10n/ga.json2
-rw-r--r--lib/l10n/it.js2
-rw-r--r--lib/l10n/it.json2
-rw-r--r--lib/l10n/pl.js2
-rw-r--r--lib/l10n/pl.json2
-rw-r--r--lib/l10n/pt_BR.js6
-rw-r--r--lib/l10n/pt_BR.json6
-rw-r--r--lib/l10n/sl.js1
-rw-r--r--lib/l10n/sl.json1
-rw-r--r--lib/l10n/sr.js2
-rw-r--r--lib/l10n/sr.json2
-rw-r--r--lib/l10n/sv.js2
-rw-r--r--lib/l10n/sv.json2
-rw-r--r--lib/l10n/zh_CN.js2
-rw-r--r--lib/l10n/zh_CN.json2
-rw-r--r--lib/l10n/zh_HK.js2
-rw-r--r--lib/l10n/zh_HK.json2
-rw-r--r--lib/l10n/zh_TW.js2
-rw-r--r--lib/l10n/zh_TW.json2
-rw-r--r--lib/private/Accounts/AccountManager.php4
-rw-r--r--lib/private/Accounts/AccountProperty.php24
-rw-r--r--lib/private/AppFramework/Bootstrap/Coordinator.php7
-rw-r--r--lib/private/AppFramework/Routing/RouteConfig.php279
-rw-r--r--lib/private/AppFramework/Routing/RouteParser.php4
-rw-r--r--lib/private/AppFramework/Utility/SimpleContainer.php8
-rw-r--r--lib/private/Calendar/Manager.php137
-rw-r--r--lib/private/DB/Adapter.php20
-rw-r--r--lib/private/DB/AdapterOCI8.php2
-rw-r--r--lib/private/DB/AdapterPgSql.php2
-rw-r--r--lib/private/DB/Connection.php29
-rw-r--r--lib/private/Encryption/EncryptionEventListener.php93
-rw-r--r--lib/private/Encryption/EncryptionWrapper.php10
-rw-r--r--lib/private/Encryption/HookManager.php75
-rw-r--r--lib/private/Encryption/Update.php130
-rw-r--r--lib/private/Encryption/Util.php2
-rw-r--r--lib/private/Files/Cache/Cache.php2
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php13
-rw-r--r--lib/private/Files/FilenameValidator.php37
-rw-r--r--lib/private/Files/SimpleFS/SimpleFile.php10
-rw-r--r--lib/private/Files/Storage/Temporary.php8
-rw-r--r--lib/private/Files/Storage/Wrapper/Encryption.php29
-rw-r--r--lib/private/Files/Type/Detection.php29
-rw-r--r--lib/private/Installer.php7
-rw-r--r--lib/private/IntegrityCheck/Checker.php4
-rw-r--r--lib/private/Log/LogDetails.php4
-rw-r--r--lib/private/Repair/MoveUpdaterStepFile.php3
-rw-r--r--lib/private/Route/Router.php12
-rw-r--r--lib/private/Security/RateLimiting/Limiter.php7
-rw-r--r--lib/private/ServerContainer.php23
-rw-r--r--lib/private/Support/CrashReport/Registry.php1
-rw-r--r--lib/private/TempManager.php3
-rw-r--r--lib/private/User/User.php5
-rw-r--r--lib/private/legacy/OC_App.php22
-rw-r--r--lib/private/legacy/OC_Helper.php89
-rw-r--r--lib/private/legacy/OC_Util.php2
-rw-r--r--lib/public/Accounts/IAccountManager.php28
-rw-r--r--lib/public/AppFramework/ApiController.php5
-rw-r--r--lib/public/AppFramework/App.php38
-rw-r--r--lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php3
-rw-r--r--lib/public/AppFramework/Http/Response.php7
-rw-r--r--lib/public/Defaults.php2
-rw-r--r--lib/public/Diagnostics/IQueryLogger.php2
-rw-r--r--lib/public/EventDispatcher/GenericEvent.php4
-rw-r--r--lib/public/Files.php52
-rw-r--r--lib/public/Files/IFilenameValidator.php13
-rw-r--r--lib/public/Files/IMimeTypeDetector.php8
-rw-r--r--lib/public/Files/SimpleFS/ISimpleFile.php10
-rw-r--r--lib/public/Files_FullTextSearch/Model/AFilesDocument.php2
-rw-r--r--lib/public/L10N/ILanguageIterator.php10
-rw-r--r--lib/public/Mail/IMailer.php2
-rw-r--r--lib/public/Profiler/IProfile.php2
-rw-r--r--lib/public/Security/ICrypto.php4
-rw-r--r--lib/public/Security/IHasher.php4
-rw-r--r--lib/public/Security/ISecureRandom.php2
-rw-r--r--lib/public/Template.php2
-rw-r--r--lib/public/Util.php81
93 files changed, 692 insertions, 843 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php
index 41b272a457c..7084eb93c89 100644
--- a/lib/autoloader.php
+++ b/lib/autoloader.php
@@ -22,10 +22,8 @@ class Autoloader {
/**
* Optional low-latency memory cache for class to path mapping.
- *
- * @var \OC\Memcache\Cache
*/
- protected $memoryCache;
+ protected ?ICache $memoryCache = null;
/**
* Autoloader constructor.
@@ -127,15 +125,15 @@ class Autoloader {
* @throws AutoloadNotAllowedException
*/
public function load(string $class): bool {
+ if (class_exists($class, false)) {
+ return false;
+ }
+
$pathsToRequire = null;
if ($this->memoryCache) {
$pathsToRequire = $this->memoryCache->get($class);
}
- if (class_exists($class, false)) {
- return false;
- }
-
if (!is_array($pathsToRequire)) {
// No cache or cache miss
$pathsToRequire = [];
diff --git a/lib/base.php b/lib/base.php
index aa463e206a3..45058db1600 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -6,13 +6,14 @@ declare(strict_types=1);
* SPDX-FileCopyrightText: 2013-2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
-use OC\Encryption\HookManager;
+
use OC\Profiler\BuiltInProfiler;
use OC\Share20\GroupDeletedListener;
use OC\Share20\Hooks;
use OC\Share20\UserDeletedListener;
use OC\Share20\UserRemovedListener;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Events\BeforeFileSystemSetupEvent;
use OCP\Group\Events\GroupDeletedEvent;
use OCP\Group\Events\UserRemovedEvent;
use OCP\IConfig;
@@ -22,7 +23,6 @@ use OCP\IURLGenerator;
use OCP\IUserSession;
use OCP\Security\Bruteforce\IThrottler;
use OCP\Server;
-use OCP\Share;
use OCP\Template\ITemplateManager;
use OCP\User\Events\UserChangedEvent;
use OCP\User\Events\UserDeletedEvent;
@@ -188,8 +188,6 @@ class OC {
}
public static function checkConfig(): void {
- $l = Server::get(\OCP\L10N\IFactory::class)->get('lib');
-
// Create config if it does not already exist
$configFilePath = self::$configDir . '/config.php';
if (!file_exists($configFilePath)) {
@@ -201,6 +199,7 @@ class OC {
if (!$configFileWritable && !OC_Helper::isReadOnlyConfigEnabled()
|| !$configFileWritable && \OCP\Util::needUpgrade()) {
$urlGenerator = Server::get(IURLGenerator::class);
+ $l = Server::get(\OCP\L10N\IFactory::class)->get('lib');
if (self::$CLI) {
echo $l->t('Cannot write into "config" directory!') . "\n";
@@ -711,6 +710,7 @@ class OC {
self::performSameSiteCookieProtection($config);
if (!defined('OC_CONSOLE')) {
+ $eventLogger->start('check_server', 'Run a few configuration checks');
$errors = OC_Util::checkServer($systemConfig);
if (count($errors) > 0) {
if (!self::$CLI) {
@@ -745,6 +745,7 @@ class OC {
} elseif (self::$CLI && $config->getSystemValueBool('installed', false)) {
$config->deleteAppValue('core', 'cronErrors');
}
+ $eventLogger->end('check_server');
}
// User and Groups
@@ -752,6 +753,7 @@ class OC {
self::$server->getSession()->set('user_id', '');
}
+ $eventLogger->start('setup_backends', 'Setup group and user backends');
Server::get(\OCP\IUserManager::class)->registerBackend(new \OC\User\Database());
Server::get(\OCP\IGroupManager::class)->addBackend(new \OC\Group\Database());
@@ -770,6 +772,7 @@ class OC {
// Run upgrades in incognito mode
OC_User::setIncognitoMode(true);
}
+ $eventLogger->end('setup_backends');
self::registerCleanupHooks($systemConfig);
self::registerShareHooks($systemConfig);
@@ -907,15 +910,16 @@ class OC {
}
private static function registerEncryptionWrapperAndHooks(): void {
+ /** @var \OC\Encryption\Manager */
$manager = Server::get(\OCP\Encryption\IManager::class);
- \OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage');
+ Server::get(IEventDispatcher::class)->addListener(
+ BeforeFileSystemSetupEvent::class,
+ $manager->setupStorage(...),
+ );
$enabled = $manager->isEnabled();
if ($enabled) {
- \OCP\Util::connectHook(Share::class, 'post_shared', HookManager::class, 'postShared');
- \OCP\Util::connectHook(Share::class, 'post_unshare', HookManager::class, 'postUnshared');
- \OCP\Util::connectHook('OC_Filesystem', 'post_rename', HookManager::class, 'postRename');
- \OCP\Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', HookManager::class, 'postRestore');
+ \OC\Encryption\EncryptionEventListener::register(Server::get(IEventDispatcher::class));
}
}
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index f15d4e2d55f..c0c086e4038 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1034,7 +1034,6 @@ return array(
'OC\\AppFramework\\OCS\\V1Response' => $baseDir . '/lib/private/AppFramework/OCS/V1Response.php',
'OC\\AppFramework\\OCS\\V2Response' => $baseDir . '/lib/private/AppFramework/OCS/V2Response.php',
'OC\\AppFramework\\Routing\\RouteActionHandler' => $baseDir . '/lib/private/AppFramework/Routing/RouteActionHandler.php',
- 'OC\\AppFramework\\Routing\\RouteConfig' => $baseDir . '/lib/private/AppFramework/Routing/RouteConfig.php',
'OC\\AppFramework\\Routing\\RouteParser' => $baseDir . '/lib/private/AppFramework/Routing/RouteParser.php',
'OC\\AppFramework\\ScopedPsrLogger' => $baseDir . '/lib/private/AppFramework/ScopedPsrLogger.php',
'OC\\AppFramework\\Services\\AppConfig' => $baseDir . '/lib/private/AppFramework/Services/AppConfig.php',
@@ -1266,6 +1265,8 @@ return array(
'OC\\Core\\Command\\Info\\File' => $baseDir . '/core/Command/Info/File.php',
'OC\\Core\\Command\\Info\\FileUtils' => $baseDir . '/core/Command/Info/FileUtils.php',
'OC\\Core\\Command\\Info\\Space' => $baseDir . '/core/Command/Info/Space.php',
+ 'OC\\Core\\Command\\Info\\Storage' => $baseDir . '/core/Command/Info/Storage.php',
+ 'OC\\Core\\Command\\Info\\Storages' => $baseDir . '/core/Command/Info/Storages.php',
'OC\\Core\\Command\\Integrity\\CheckApp' => $baseDir . '/core/Command/Integrity/CheckApp.php',
'OC\\Core\\Command\\Integrity\\CheckCore' => $baseDir . '/core/Command/Integrity/CheckCore.php',
'OC\\Core\\Command\\Integrity\\SignApp' => $baseDir . '/core/Command/Integrity/SignApp.php',
@@ -1539,6 +1540,7 @@ return array(
'OC\\DirectEditing\\Token' => $baseDir . '/lib/private/DirectEditing/Token.php',
'OC\\EmojiHelper' => $baseDir . '/lib/private/EmojiHelper.php',
'OC\\Encryption\\DecryptAll' => $baseDir . '/lib/private/Encryption/DecryptAll.php',
+ 'OC\\Encryption\\EncryptionEventListener' => $baseDir . '/lib/private/Encryption/EncryptionEventListener.php',
'OC\\Encryption\\EncryptionWrapper' => $baseDir . '/lib/private/Encryption/EncryptionWrapper.php',
'OC\\Encryption\\Exceptions\\DecryptionFailedException' => $baseDir . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php',
'OC\\Encryption\\Exceptions\\EmptyEncryptionDataException' => $baseDir . '/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php',
@@ -1549,7 +1551,6 @@ return array(
'OC\\Encryption\\Exceptions\\ModuleDoesNotExistsException' => $baseDir . '/lib/private/Encryption/Exceptions/ModuleDoesNotExistsException.php',
'OC\\Encryption\\Exceptions\\UnknownCipherException' => $baseDir . '/lib/private/Encryption/Exceptions/UnknownCipherException.php',
'OC\\Encryption\\File' => $baseDir . '/lib/private/Encryption/File.php',
- 'OC\\Encryption\\HookManager' => $baseDir . '/lib/private/Encryption/HookManager.php',
'OC\\Encryption\\Keys\\Storage' => $baseDir . '/lib/private/Encryption/Keys/Storage.php',
'OC\\Encryption\\Manager' => $baseDir . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => $baseDir . '/lib/private/Encryption/Update.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index dfb238acbf3..f2f817877d2 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1075,7 +1075,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\AppFramework\\OCS\\V1Response' => __DIR__ . '/../../..' . '/lib/private/AppFramework/OCS/V1Response.php',
'OC\\AppFramework\\OCS\\V2Response' => __DIR__ . '/../../..' . '/lib/private/AppFramework/OCS/V2Response.php',
'OC\\AppFramework\\Routing\\RouteActionHandler' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteActionHandler.php',
- 'OC\\AppFramework\\Routing\\RouteConfig' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteConfig.php',
'OC\\AppFramework\\Routing\\RouteParser' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteParser.php',
'OC\\AppFramework\\ScopedPsrLogger' => __DIR__ . '/../../..' . '/lib/private/AppFramework/ScopedPsrLogger.php',
'OC\\AppFramework\\Services\\AppConfig' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Services/AppConfig.php',
@@ -1307,6 +1306,8 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\Info\\File' => __DIR__ . '/../../..' . '/core/Command/Info/File.php',
'OC\\Core\\Command\\Info\\FileUtils' => __DIR__ . '/../../..' . '/core/Command/Info/FileUtils.php',
'OC\\Core\\Command\\Info\\Space' => __DIR__ . '/../../..' . '/core/Command/Info/Space.php',
+ 'OC\\Core\\Command\\Info\\Storage' => __DIR__ . '/../../..' . '/core/Command/Info/Storage.php',
+ 'OC\\Core\\Command\\Info\\Storages' => __DIR__ . '/../../..' . '/core/Command/Info/Storages.php',
'OC\\Core\\Command\\Integrity\\CheckApp' => __DIR__ . '/../../..' . '/core/Command/Integrity/CheckApp.php',
'OC\\Core\\Command\\Integrity\\CheckCore' => __DIR__ . '/../../..' . '/core/Command/Integrity/CheckCore.php',
'OC\\Core\\Command\\Integrity\\SignApp' => __DIR__ . '/../../..' . '/core/Command/Integrity/SignApp.php',
@@ -1580,6 +1581,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\DirectEditing\\Token' => __DIR__ . '/../../..' . '/lib/private/DirectEditing/Token.php',
'OC\\EmojiHelper' => __DIR__ . '/../../..' . '/lib/private/EmojiHelper.php',
'OC\\Encryption\\DecryptAll' => __DIR__ . '/../../..' . '/lib/private/Encryption/DecryptAll.php',
+ 'OC\\Encryption\\EncryptionEventListener' => __DIR__ . '/../../..' . '/lib/private/Encryption/EncryptionEventListener.php',
'OC\\Encryption\\EncryptionWrapper' => __DIR__ . '/../../..' . '/lib/private/Encryption/EncryptionWrapper.php',
'OC\\Encryption\\Exceptions\\DecryptionFailedException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php',
'OC\\Encryption\\Exceptions\\EmptyEncryptionDataException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php',
@@ -1590,7 +1592,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Encryption\\Exceptions\\ModuleDoesNotExistsException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/ModuleDoesNotExistsException.php',
'OC\\Encryption\\Exceptions\\UnknownCipherException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/UnknownCipherException.php',
'OC\\Encryption\\File' => __DIR__ . '/../../..' . '/lib/private/Encryption/File.php',
- 'OC\\Encryption\\HookManager' => __DIR__ . '/../../..' . '/lib/private/Encryption/HookManager.php',
'OC\\Encryption\\Keys\\Storage' => __DIR__ . '/../../..' . '/lib/private/Encryption/Keys/Storage.php',
'OC\\Encryption\\Manager' => __DIR__ . '/../../..' . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => __DIR__ . '/../../..' . '/lib/private/Encryption/Update.php',
diff --git a/lib/l10n/cs.js b/lib/l10n/cs.js
index 2233f31f686..b4304fb14ab 100644
--- a/lib/l10n/cs.js
+++ b/lib/l10n/cs.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Cíl neexistuje",
"Destination is not creatable" : "Cíl není možné vytvořit",
"Dot files are not allowed" : "Názvy souborů, začínající na tečku nejsou dovolené",
+ "%1$s (renamed)" : "%1$s (přejmenované)",
+ "renamed file" : "přejmenovaný soubor",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ je zakázáno v názvu souboru nebo složky.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ je zakázaná předpona pro názvy souborů či složek.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ není povoleno v rámci názvu souboru či složky.",
diff --git a/lib/l10n/cs.json b/lib/l10n/cs.json
index 087e2244eeb..f6cb00467cb 100644
--- a/lib/l10n/cs.json
+++ b/lib/l10n/cs.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Cíl neexistuje",
"Destination is not creatable" : "Cíl není možné vytvořit",
"Dot files are not allowed" : "Názvy souborů, začínající na tečku nejsou dovolené",
+ "%1$s (renamed)" : "%1$s (přejmenované)",
+ "renamed file" : "přejmenovaný soubor",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ je zakázáno v názvu souboru nebo složky.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ je zakázaná předpona pro názvy souborů či složek.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ není povoleno v rámci názvu souboru či složky.",
diff --git a/lib/l10n/de.js b/lib/l10n/de.js
index 672c6ca4f25..e44f2b89e2b 100644
--- a/lib/l10n/de.js
+++ b/lib/l10n/de.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein unzulässiger Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein unzulässiges Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
@@ -120,7 +122,7 @@ OC.L10N.register(
"__language_name__" : "Deutsch (Persönlich: Du)",
"This is an automatically sent email, please do not reply." : "Dies ist eine automatisch gesendete E-Mail. Bitte antworte nicht auf diese E-Mail.",
"Help & privacy" : "Hilfe & Datenschutz",
- "Appearance and accessibility" : "Erscheinungsbild und Barrierefreiheit",
+ "Appearance and accessibility" : "Aussehen und Barrierefreiheit",
"Apps" : "Apps",
"Personal settings" : "Persönliche Einstellungen",
"Administration settings" : "Verwaltungseinstellungen",
diff --git a/lib/l10n/de.json b/lib/l10n/de.json
index 17ce3b96f49..7a05dfc101f 100644
--- a/lib/l10n/de.json
+++ b/lib/l10n/de.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein unzulässiger Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein unzulässiges Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
@@ -118,7 +120,7 @@
"__language_name__" : "Deutsch (Persönlich: Du)",
"This is an automatically sent email, please do not reply." : "Dies ist eine automatisch gesendete E-Mail. Bitte antworte nicht auf diese E-Mail.",
"Help & privacy" : "Hilfe & Datenschutz",
- "Appearance and accessibility" : "Erscheinungsbild und Barrierefreiheit",
+ "Appearance and accessibility" : "Aussehen und Barrierefreiheit",
"Apps" : "Apps",
"Personal settings" : "Persönliche Einstellungen",
"Administration settings" : "Verwaltungseinstellungen",
diff --git a/lib/l10n/de_DE.js b/lib/l10n/de_DE.js
index aa926c96d4f..4bfd5faa7f2 100644
--- a/lib/l10n/de_DE.js
+++ b/lib/l10n/de_DE.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein verbotener Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein verbotenes Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
diff --git a/lib/l10n/de_DE.json b/lib/l10n/de_DE.json
index f23493df570..6faebb2c6c0 100644
--- a/lib/l10n/de_DE.json
+++ b/lib/l10n/de_DE.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein verbotener Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein verbotenes Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
diff --git a/lib/l10n/en_GB.js b/lib/l10n/en_GB.js
index 2494ab4aca4..d6a8da225ba 100644
--- a/lib/l10n/en_GB.js
+++ b/lib/l10n/en_GB.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Destination does not exist",
"Destination is not creatable" : "Destination is not creatable",
"Dot files are not allowed" : "Dot files are not allowed",
+ "%1$s (renamed)" : "%1$s (renamed)",
+ "renamed file" : "renamed file",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" is a forbidden file or folder name.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" is a forbidden prefix for file or folder names.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" is not allowed inside a file or folder name.",
diff --git a/lib/l10n/en_GB.json b/lib/l10n/en_GB.json
index 08e84f39af1..e1bd150aca6 100644
--- a/lib/l10n/en_GB.json
+++ b/lib/l10n/en_GB.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Destination does not exist",
"Destination is not creatable" : "Destination is not creatable",
"Dot files are not allowed" : "Dot files are not allowed",
+ "%1$s (renamed)" : "%1$s (renamed)",
+ "renamed file" : "renamed file",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" is a forbidden file or folder name.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" is a forbidden prefix for file or folder names.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" is not allowed inside a file or folder name.",
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index a3cf61509ec..e4076a5cc2c 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "El destino no existe",
"Destination is not creatable" : "El destino no se puede crear",
"Dot files are not allowed" : "Los archivos Dot no están permitidos",
+ "%1$s (renamed)" : "%1$s (renombrado)",
+ "renamed file" : "archivo renombrado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" Es un nombre de archivo o carpeta no permitido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "%1$s es un prefijo prohibido para nombres de archivo o carpeta.",
"\"%1$s\" is not allowed inside a file or folder name." : "«%1$s» no se permite en el nombre de un archivo o carpeta.",
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index 34d4db2eec4..ba3043cee36 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "El destino no existe",
"Destination is not creatable" : "El destino no se puede crear",
"Dot files are not allowed" : "Los archivos Dot no están permitidos",
+ "%1$s (renamed)" : "%1$s (renombrado)",
+ "renamed file" : "archivo renombrado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" Es un nombre de archivo o carpeta no permitido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "%1$s es un prefijo prohibido para nombres de archivo o carpeta.",
"\"%1$s\" is not allowed inside a file or folder name." : "«%1$s» no se permite en el nombre de un archivo o carpeta.",
diff --git a/lib/l10n/et_EE.js b/lib/l10n/et_EE.js
index 7932c79256b..ae5999fc496 100644
--- a/lib/l10n/et_EE.js
+++ b/lib/l10n/et_EE.js
@@ -84,6 +84,8 @@ OC.L10N.register(
"Destination does not exist" : "Sihtmeediat pole olemas",
"Destination is not creatable" : "Sihtmeedia pole loodav",
"Dot files are not allowed" : "Punktiga failid pole lubatud",
+ "%1$s (renamed)" : "%1$s (nimi on muudetud)",
+ "renamed file" : "muudetud nimega fail",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ on keelatud faili- või kaustanimi.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ on keelatud faili- või kaustanime eesliide.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ pole faili- või kaustanimes lubatud.",
diff --git a/lib/l10n/et_EE.json b/lib/l10n/et_EE.json
index 99c9583bf87..65621b2643a 100644
--- a/lib/l10n/et_EE.json
+++ b/lib/l10n/et_EE.json
@@ -82,6 +82,8 @@
"Destination does not exist" : "Sihtmeediat pole olemas",
"Destination is not creatable" : "Sihtmeedia pole loodav",
"Dot files are not allowed" : "Punktiga failid pole lubatud",
+ "%1$s (renamed)" : "%1$s (nimi on muudetud)",
+ "renamed file" : "muudetud nimega fail",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ on keelatud faili- või kaustanimi.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ on keelatud faili- või kaustanime eesliide.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ pole faili- või kaustanimes lubatud.",
diff --git a/lib/l10n/ga.js b/lib/l10n/ga.js
index 9b05143b101..807a668847e 100644
--- a/lib/l10n/ga.js
+++ b/lib/l10n/ga.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Níl ceann scríbe ann",
"Destination is not creatable" : "Níl ceann scríbe cruthaithe",
"Dot files are not allowed" : "Ní cheadaítear comhaid ponc",
+ "%1$s (renamed)" : "%1$s (athainmnithe)",
+ "renamed file" : "comhad athainmnithe",
"\"%1$s\" is a forbidden file or folder name." : "Is ainm toirmiscthe comhaid nó fillteáin é \"%1$s\".",
"\"%1$s\" is a forbidden prefix for file or folder names." : "Réimír toirmiscthe é \"%1$s\" d'ainmneacha comhaid nó fillteán.",
"\"%1$s\" is not allowed inside a file or folder name." : "Ní cheadaítear \"%1$s\" taobh istigh d'ainm comhaid nó fillteáin.",
diff --git a/lib/l10n/ga.json b/lib/l10n/ga.json
index ee093dac05e..657ef31f4e3 100644
--- a/lib/l10n/ga.json
+++ b/lib/l10n/ga.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Níl ceann scríbe ann",
"Destination is not creatable" : "Níl ceann scríbe cruthaithe",
"Dot files are not allowed" : "Ní cheadaítear comhaid ponc",
+ "%1$s (renamed)" : "%1$s (athainmnithe)",
+ "renamed file" : "comhad athainmnithe",
"\"%1$s\" is a forbidden file or folder name." : "Is ainm toirmiscthe comhaid nó fillteáin é \"%1$s\".",
"\"%1$s\" is a forbidden prefix for file or folder names." : "Réimír toirmiscthe é \"%1$s\" d'ainmneacha comhaid nó fillteán.",
"\"%1$s\" is not allowed inside a file or folder name." : "Ní cheadaítear \"%1$s\" taobh istigh d'ainm comhaid nó fillteáin.",
diff --git a/lib/l10n/it.js b/lib/l10n/it.js
index 50750f18726..33a2c8ad6bb 100644
--- a/lib/l10n/it.js
+++ b/lib/l10n/it.js
@@ -82,6 +82,8 @@ OC.L10N.register(
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Il modulo con ID: %s non esiste. Abilitalo nelle impostazioni delle applicazioni o contatta il tuo amministratore.",
"File is too large to convert" : "Il file è troppo grande per essere convertito",
"Dot files are not allowed" : "I file con un punto iniziale non sono consentiti",
+ "%1$s (renamed)" : "%1$s (rinominato)",
+ "renamed file" : "file rinominato",
"File already exists" : "Il file esiste già",
"Invalid path" : "Percorso non valido",
"Failed to create file from template" : "Impossibile creare un file dal modello",
diff --git a/lib/l10n/it.json b/lib/l10n/it.json
index c6a820d0f5d..4cd53fbed0a 100644
--- a/lib/l10n/it.json
+++ b/lib/l10n/it.json
@@ -80,6 +80,8 @@
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Il modulo con ID: %s non esiste. Abilitalo nelle impostazioni delle applicazioni o contatta il tuo amministratore.",
"File is too large to convert" : "Il file è troppo grande per essere convertito",
"Dot files are not allowed" : "I file con un punto iniziale non sono consentiti",
+ "%1$s (renamed)" : "%1$s (rinominato)",
+ "renamed file" : "file rinominato",
"File already exists" : "Il file esiste già",
"Invalid path" : "Percorso non valido",
"Failed to create file from template" : "Impossibile creare un file dal modello",
diff --git a/lib/l10n/pl.js b/lib/l10n/pl.js
index 0d9fd0cb98a..953682de0ab 100644
--- a/lib/l10n/pl.js
+++ b/lib/l10n/pl.js
@@ -82,6 +82,8 @@ OC.L10N.register(
"Empty file" : "Pusty plik",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Moduł o ID: %s nie istnieje. Włącz go w ustawieniach aplikacji lub skontaktuj się z administratorem.",
"Dot files are not allowed" : "Pliki z kropką są niedozwolone",
+ "%1$s (renamed)" : "%1$s (zmieniona nazwa)",
+ "renamed file" : "zmieniona nazwa pliku",
"Invalid parent path" : "Nieprawidłowa ścieżka nadrzędna",
"File already exists" : "Plik już istnieje",
"Invalid path" : "Niewłaściwa ścieżka",
diff --git a/lib/l10n/pl.json b/lib/l10n/pl.json
index c97634e8eff..4edf90eedba 100644
--- a/lib/l10n/pl.json
+++ b/lib/l10n/pl.json
@@ -80,6 +80,8 @@
"Empty file" : "Pusty plik",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Moduł o ID: %s nie istnieje. Włącz go w ustawieniach aplikacji lub skontaktuj się z administratorem.",
"Dot files are not allowed" : "Pliki z kropką są niedozwolone",
+ "%1$s (renamed)" : "%1$s (zmieniona nazwa)",
+ "renamed file" : "zmieniona nazwa pliku",
"Invalid parent path" : "Nieprawidłowa ścieżka nadrzędna",
"File already exists" : "Plik już istnieje",
"Invalid path" : "Niewłaściwa ścieżka",
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index 975a321f27c..bf7f7728be6 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Destino não existe",
"Destination is not creatable" : "Destino não pode ser criado",
"Dot files are not allowed" : "Arquivos Dot não são permitidos",
+ "%1$s (renamed)" : "%1$s (renomeado)",
+ "renamed file" : "arquivo renomeado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" é um nome de arquivo ou pasta proibido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" é um prefixo proibido para nomes de arquivos ou pastas.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" não é permitido dentro de um nome de arquivo ou pasta.",
@@ -141,7 +143,7 @@ OC.L10N.register(
"Profile picture" : "Foto do perfil",
"About" : "Sobre",
"Display name" : "Nome de exibição",
- "Headline" : "Título ",
+ "Headline" : "Título",
"Organisation" : "Organização",
"Role" : "Função",
"Pronouns" : "Pronomes",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Um Login válido deve ser fornecido",
"Login contains whitespace at the beginning or at the end" : "O login contém espaços em branco no início ou no final",
"Login must not consist of dots only" : "O login não deve consistir apenas de pontos",
- "Login is too long" : "O login é muito longo",
+ "Login is too long" : "Login é muito longo",
"Login is invalid because files already exist for this user" : "O login é inválido porque já existem arquivos para este usuário",
"Account disabled" : "Conta desativada",
"Login canceled by app" : "Login cancelado pelo aplicativo",
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index 56506c4cce0..ad7df10df2b 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Destino não existe",
"Destination is not creatable" : "Destino não pode ser criado",
"Dot files are not allowed" : "Arquivos Dot não são permitidos",
+ "%1$s (renamed)" : "%1$s (renomeado)",
+ "renamed file" : "arquivo renomeado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" é um nome de arquivo ou pasta proibido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" é um prefixo proibido para nomes de arquivos ou pastas.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" não é permitido dentro de um nome de arquivo ou pasta.",
@@ -139,7 +141,7 @@
"Profile picture" : "Foto do perfil",
"About" : "Sobre",
"Display name" : "Nome de exibição",
- "Headline" : "Título ",
+ "Headline" : "Título",
"Organisation" : "Organização",
"Role" : "Função",
"Pronouns" : "Pronomes",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "Um Login válido deve ser fornecido",
"Login contains whitespace at the beginning or at the end" : "O login contém espaços em branco no início ou no final",
"Login must not consist of dots only" : "O login não deve consistir apenas de pontos",
- "Login is too long" : "O login é muito longo",
+ "Login is too long" : "Login é muito longo",
"Login is invalid because files already exist for this user" : "O login é inválido porque já existem arquivos para este usuário",
"Account disabled" : "Conta desativada",
"Login canceled by app" : "Login cancelado pelo aplicativo",
diff --git a/lib/l10n/sl.js b/lib/l10n/sl.js
index 8677c681bcc..b9d564d8c3b 100644
--- a/lib/l10n/sl.js
+++ b/lib/l10n/sl.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Empty file" : "Prazna datoteka",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Modul z ID: %s ne obstaja. Omogočite ga med nastavitvami, ali pa stopite v stik s skrbnikom sistema.",
"Dot files are not allowed" : "Skrite datoteke niso dovoljene",
+ "Filenames must not end with \"%1$s\"." : "Imena datotek se naj ne končajo s \"%1$s\".",
"File already exists" : "Datoteka že obstaja",
"Invalid path" : "Neveljavna pot",
"Failed to create file from template" : "Ustvarjanje datoteke iz predloge je spodletelo",
diff --git a/lib/l10n/sl.json b/lib/l10n/sl.json
index 39c6044b937..1d526285b66 100644
--- a/lib/l10n/sl.json
+++ b/lib/l10n/sl.json
@@ -73,6 +73,7 @@
"Empty file" : "Prazna datoteka",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Modul z ID: %s ne obstaja. Omogočite ga med nastavitvami, ali pa stopite v stik s skrbnikom sistema.",
"Dot files are not allowed" : "Skrite datoteke niso dovoljene",
+ "Filenames must not end with \"%1$s\"." : "Imena datotek se naj ne končajo s \"%1$s\".",
"File already exists" : "Datoteka že obstaja",
"Invalid path" : "Neveljavna pot",
"Failed to create file from template" : "Ustvarjanje datoteke iz predloge je spodletelo",
diff --git a/lib/l10n/sr.js b/lib/l10n/sr.js
index b62a808994d..6bbd5d62333 100644
--- a/lib/l10n/sr.js
+++ b/lib/l10n/sr.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Одредиште не постоји",
"Destination is not creatable" : "Одредиште не може да се креира",
"Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени",
+ "%1$s (renamed)" : "%1$s (преименован)",
+ "renamed file" : "преименован фајл",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s” је забрањено име фајла или фолдера.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s” је забрањени префикс имена фајла или фолдера.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s” није дозвољено у имену фајла или фолдера.",
diff --git a/lib/l10n/sr.json b/lib/l10n/sr.json
index 7dbc69c583a..8d6b3cc72c3 100644
--- a/lib/l10n/sr.json
+++ b/lib/l10n/sr.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Одредиште не постоји",
"Destination is not creatable" : "Одредиште не може да се креира",
"Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени",
+ "%1$s (renamed)" : "%1$s (преименован)",
+ "renamed file" : "преименован фајл",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s” је забрањено име фајла или фолдера.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s” је забрањени префикс имена фајла или фолдера.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s” није дозвољено у имену фајла или фолдера.",
diff --git a/lib/l10n/sv.js b/lib/l10n/sv.js
index ed4c4af3ef0..f203a0471e7 100644
--- a/lib/l10n/sv.js
+++ b/lib/l10n/sv.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Destinationen finns inte",
"Destination is not creatable" : "Destinationen går inte att skapa",
"Dot files are not allowed" : "Dot-filer är inte tillåtna",
+ "%1$s (renamed)" : "%1$s (omdöpt)",
+ "renamed file" : "omdöpt fil",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" är ett förbjudet fil- eller mappnamn.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" är ett förbjudet prefix för fil- eller mappnamn.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" är inte tillåtet i ett fil- eller mappnamn.",
diff --git a/lib/l10n/sv.json b/lib/l10n/sv.json
index 55855426f34..3f3db6805e8 100644
--- a/lib/l10n/sv.json
+++ b/lib/l10n/sv.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Destinationen finns inte",
"Destination is not creatable" : "Destinationen går inte att skapa",
"Dot files are not allowed" : "Dot-filer är inte tillåtna",
+ "%1$s (renamed)" : "%1$s (omdöpt)",
+ "renamed file" : "omdöpt fil",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" är ett förbjudet fil- eller mappnamn.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" är ett förbjudet prefix för fil- eller mappnamn.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" är inte tillåtet i ett fil- eller mappnamn.",
diff --git a/lib/l10n/zh_CN.js b/lib/l10n/zh_CN.js
index 1637350f1e9..0cc4fd8d378 100644
--- a/lib/l10n/zh_CN.js
+++ b/lib/l10n/zh_CN.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "目标不存在",
"Destination is not creatable" : "目标不可创建",
"Dot files are not allowed" : "以 . 开头的文件不被允许",
+ "%1$s (renamed)" : "%1$s(已重命名)",
+ "renamed file" : "已重命名文件",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" 是禁止的文件或文件夹名称。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" 是文件或文件夹名称的禁止前缀。",
"\"%1$s\" is not allowed inside a file or folder name." : "文件或文件夹名称中不允许出现 \"%1$s\"。",
diff --git a/lib/l10n/zh_CN.json b/lib/l10n/zh_CN.json
index dd94f1bb5cf..2ba31a10e87 100644
--- a/lib/l10n/zh_CN.json
+++ b/lib/l10n/zh_CN.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "目标不存在",
"Destination is not creatable" : "目标不可创建",
"Dot files are not allowed" : "以 . 开头的文件不被允许",
+ "%1$s (renamed)" : "%1$s(已重命名)",
+ "renamed file" : "已重命名文件",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" 是禁止的文件或文件夹名称。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" 是文件或文件夹名称的禁止前缀。",
"\"%1$s\" is not allowed inside a file or folder name." : "文件或文件夹名称中不允许出现 \"%1$s\"。",
diff --git a/lib/l10n/zh_HK.js b/lib/l10n/zh_HK.js
index a85c29e400c..b4bb06b4cdc 100644
--- a/lib/l10n/zh_HK.js
+++ b/lib/l10n/zh_HK.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名的檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
diff --git a/lib/l10n/zh_HK.json b/lib/l10n/zh_HK.json
index b58db1e510c..6cc1edd0f35 100644
--- a/lib/l10n/zh_HK.json
+++ b/lib/l10n/zh_HK.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名的檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
diff --git a/lib/l10n/zh_TW.js b/lib/l10n/zh_TW.js
index 4f92a865290..016689524c5 100644
--- a/lib/l10n/zh_TW.js
+++ b/lib/l10n/zh_TW.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
diff --git a/lib/l10n/zh_TW.json b/lib/l10n/zh_TW.json
index 34b32540bc8..67f95c65e75 100644
--- a/lib/l10n/zh_TW.json
+++ b/lib/l10n/zh_TW.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index d69e72a29de..e8b67311636 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -131,9 +131,7 @@ class AccountManager implements IAccountManager {
$property->setScope(self::SCOPE_LOCAL);
}
} else {
- // migrate scope values to the new format
- // invalid scopes are mapped to a default value
- $property->setScope(AccountProperty::mapScopeToV2($property->getScope()));
+ $property->setScope($property->getScope());
}
}
diff --git a/lib/private/Accounts/AccountProperty.php b/lib/private/Accounts/AccountProperty.php
index 0c4ad568709..3a89e9bbc7a 100644
--- a/lib/private/Accounts/AccountProperty.php
+++ b/lib/private/Accounts/AccountProperty.php
@@ -55,16 +55,11 @@ class AccountProperty implements IAccountProperty {
* @since 15.0.0
*/
public function setScope(string $scope): IAccountProperty {
- $newScope = $this->mapScopeToV2($scope);
- if (!in_array($newScope, [
- IAccountManager::SCOPE_LOCAL,
- IAccountManager::SCOPE_FEDERATED,
- IAccountManager::SCOPE_PRIVATE,
- IAccountManager::SCOPE_PUBLISHED
- ])) {
+ if (!in_array($scope, IAccountManager::ALLOWED_SCOPES, )) {
throw new InvalidArgumentException('Invalid scope');
}
- $this->scope = $newScope;
+ /** @var IAccountManager::SCOPE_* $scope */
+ $this->scope = $scope;
return $this;
}
@@ -105,19 +100,6 @@ class AccountProperty implements IAccountProperty {
return $this->scope;
}
- public static function mapScopeToV2(string $scope): string {
- if (str_starts_with($scope, 'v2-')) {
- return $scope;
- }
-
- return match ($scope) {
- IAccountManager::VISIBILITY_PRIVATE, '' => IAccountManager::SCOPE_LOCAL,
- IAccountManager::VISIBILITY_CONTACTS_ONLY => IAccountManager::SCOPE_FEDERATED,
- IAccountManager::VISIBILITY_PUBLIC => IAccountManager::SCOPE_PUBLISHED,
- default => $scope,
- };
- }
-
/**
* Get the verification status of a property
*
diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php
index 2b04d291730..4e613703dec 100644
--- a/lib/private/AppFramework/Bootstrap/Coordinator.php
+++ b/lib/private/AppFramework/Bootstrap/Coordinator.php
@@ -83,11 +83,12 @@ class Coordinator {
$appNameSpace = App::buildAppNamespace($appId);
$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
try {
- if (class_exists($applicationClassName) && in_array(IBootstrap::class, class_implements($applicationClassName), true)) {
+ if (class_exists($applicationClassName) && is_a($applicationClassName, IBootstrap::class, true)) {
$this->eventLogger->start("bootstrap:register_app:$appId:application", "Load `Application` instance for $appId");
try {
- /** @var IBootstrap|App $application */
- $apps[$appId] = $application = $this->serverContainer->query($applicationClassName);
+ /** @var IBootstrap&App $application */
+ $application = $this->serverContainer->query($applicationClassName);
+ $apps[$appId] = $application;
} catch (QueryException $e) {
// Weird, but ok
$this->eventLogger->end("bootstrap:register_app:$appId");
diff --git a/lib/private/AppFramework/Routing/RouteConfig.php b/lib/private/AppFramework/Routing/RouteConfig.php
deleted file mode 100644
index 2b7f21a8ba5..00000000000
--- a/lib/private/AppFramework/Routing/RouteConfig.php
+++ /dev/null
@@ -1,279 +0,0 @@
-<?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
- */
-namespace OC\AppFramework\Routing;
-
-use OC\AppFramework\DependencyInjection\DIContainer;
-use OC\Route\Router;
-
-/**
- * Class RouteConfig
- * @package OC\AppFramework\routing
- */
-class RouteConfig {
- /** @var DIContainer */
- private $container;
-
- /** @var Router */
- private $router;
-
- /** @var array */
- private $routes;
-
- /** @var string */
- private $appName;
-
- /** @var string[] */
- private $controllerNameCache = [];
-
- protected $rootUrlApps = [
- 'cloud_federation_api',
- 'core',
- 'files_sharing',
- 'files',
- 'profile',
- 'settings',
- 'spreed',
- ];
-
- /**
- * @param \OC\AppFramework\DependencyInjection\DIContainer $container
- * @param \OC\Route\Router $router
- * @param array $routes
- * @internal param $appName
- */
- public function __construct(DIContainer $container, Router $router, $routes) {
- $this->routes = $routes;
- $this->container = $container;
- $this->router = $router;
- $this->appName = $container['AppName'];
- }
-
- /**
- * The routes and resource will be registered to the \OCP\Route\IRouter
- */
- public function register() {
- // parse simple
- $this->processIndexRoutes($this->routes);
-
- // parse resources
- $this->processIndexResources($this->routes);
-
- /*
- * OCS routes go into a different collection
- */
- $oldCollection = $this->router->getCurrentCollection();
- $this->router->useCollection($oldCollection . '.ocs');
-
- // parse ocs simple routes
- $this->processOCS($this->routes);
-
- // parse ocs simple routes
- $this->processOCSResources($this->routes);
-
- $this->router->useCollection($oldCollection);
- }
-
- private function processOCS(array $routes): void {
- $ocsRoutes = $routes['ocs'] ?? [];
- foreach ($ocsRoutes as $ocsRoute) {
- $this->processRoute($ocsRoute, 'ocs.');
- }
- }
-
- /**
- * Creates one route base on the give configuration
- * @param array $routes
- * @throws \UnexpectedValueException
- */
- private function processIndexRoutes(array $routes): void {
- $simpleRoutes = $routes['routes'] ?? [];
- foreach ($simpleRoutes as $simpleRoute) {
- $this->processRoute($simpleRoute);
- }
- }
-
- protected function processRoute(array $route, string $routeNamePrefix = ''): void {
- $name = $route['name'];
- $postfix = $route['postfix'] ?? '';
- $root = $this->buildRootPrefix($route, $routeNamePrefix);
-
- $url = $root . '/' . ltrim($route['url'], '/');
- $verb = strtoupper($route['verb'] ?? 'GET');
-
- $split = explode('#', $name, 2);
- if (count($split) !== 2) {
- throw new \UnexpectedValueException('Invalid route name: use the format foo#bar to reference FooController::bar');
- }
- [$controller, $action] = $split;
-
- $controllerName = $this->buildControllerName($controller);
- $actionName = $this->buildActionName($action);
-
- /*
- * The route name has to be lowercase, for symfony to match it correctly.
- * This is required because smyfony allows mixed casing for controller names in the routes.
- * To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
- * This is also safe on the PHP side because class and method names collide regardless of the casing.
- */
- $routeName = strtolower($routeNamePrefix . $this->appName . '.' . $controller . '.' . $action . $postfix);
-
- $router = $this->router->create($routeName, $url)
- ->method($verb);
-
- // optionally register requirements for route. This is used to
- // tell the route parser how url parameters should be matched
- if (array_key_exists('requirements', $route)) {
- $router->requirements($route['requirements']);
- }
-
- // optionally register defaults for route. This is used to
- // tell the route parser how url parameters should be default valued
- $defaults = [];
- if (array_key_exists('defaults', $route)) {
- $defaults = $route['defaults'];
- }
-
- $defaults['caller'] = [$this->appName, $controllerName, $actionName];
- $router->defaults($defaults);
- }
-
- /**
- * For a given name and url restful OCS routes are created:
- * - index
- * - show
- * - create
- * - update
- * - destroy
- *
- * @param array $routes
- */
- private function processOCSResources(array $routes): void {
- $this->processResources($routes['ocs-resources'] ?? [], 'ocs.');
- }
-
- /**
- * For a given name and url restful routes are created:
- * - index
- * - show
- * - create
- * - update
- * - destroy
- *
- * @param array $routes
- */
- private function processIndexResources(array $routes): void {
- $this->processResources($routes['resources'] ?? []);
- }
-
- /**
- * For a given name and url restful routes are created:
- * - index
- * - show
- * - create
- * - update
- * - destroy
- *
- * @param array $resources
- * @param string $routeNamePrefix
- */
- protected function processResources(array $resources, string $routeNamePrefix = ''): void {
- // declaration of all restful actions
- $actions = [
- ['name' => 'index', 'verb' => 'GET', 'on-collection' => true],
- ['name' => 'show', 'verb' => 'GET'],
- ['name' => 'create', 'verb' => 'POST', 'on-collection' => true],
- ['name' => 'update', 'verb' => 'PUT'],
- ['name' => 'destroy', 'verb' => 'DELETE'],
- ];
-
- foreach ($resources as $resource => $config) {
- $root = $this->buildRootPrefix($config, $routeNamePrefix);
-
- // the url parameter used as id to the resource
- foreach ($actions as $action) {
- $url = $root . '/' . ltrim($config['url'], '/');
- $method = $action['name'];
-
- $verb = strtoupper($action['verb'] ?? 'GET');
- $collectionAction = $action['on-collection'] ?? false;
- if (!$collectionAction) {
- $url .= '/{id}';
- }
- if (isset($action['url-postfix'])) {
- $url .= '/' . $action['url-postfix'];
- }
-
- $controller = $resource;
-
- $controllerName = $this->buildControllerName($controller);
- $actionName = $this->buildActionName($method);
-
- $routeName = $routeNamePrefix . $this->appName . '.' . strtolower($resource) . '.' . $method;
-
- $route = $this->router->create($routeName, $url)
- ->method($verb);
-
- $route->defaults(['caller' => [$this->appName, $controllerName, $actionName]]);
- }
- }
- }
-
- private function buildRootPrefix(array $route, string $routeNamePrefix): string {
- $defaultRoot = $this->appName === 'core' ? '' : '/apps/' . $this->appName;
- $root = $route['root'] ?? $defaultRoot;
-
- if ($routeNamePrefix !== '') {
- // In OCS all apps are whitelisted
- return $root;
- }
-
- if (!\in_array($this->appName, $this->rootUrlApps, true)) {
- // Only allow root URLS for some apps
- return $defaultRoot;
- }
-
- return $root;
- }
-
- /**
- * Based on a given route name the controller name is generated
- * @param string $controller
- * @return string
- */
- private function buildControllerName(string $controller): string {
- if (!isset($this->controllerNameCache[$controller])) {
- $this->controllerNameCache[$controller] = $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller';
- }
- return $this->controllerNameCache[$controller];
- }
-
- /**
- * Based on the action part of the route name the controller method name is generated
- * @param string $action
- * @return string
- */
- private function buildActionName(string $action): string {
- return $this->underScoreToCamelCase($action);
- }
-
- /**
- * Underscored strings are converted to camel case strings
- * @param string $str
- * @return string
- */
- private function underScoreToCamelCase(string $str): string {
- $pattern = '/_[a-z]?/';
- return preg_replace_callback(
- $pattern,
- function ($matches) {
- return strtoupper(ltrim($matches[0], '_'));
- },
- $str);
- }
-}
diff --git a/lib/private/AppFramework/Routing/RouteParser.php b/lib/private/AppFramework/Routing/RouteParser.php
index 894a74c727b..55e58234673 100644
--- a/lib/private/AppFramework/Routing/RouteParser.php
+++ b/lib/private/AppFramework/Routing/RouteParser.php
@@ -76,7 +76,7 @@ class RouteParser {
$url = $root . '/' . ltrim($route['url'], '/');
$verb = strtoupper($route['verb'] ?? 'GET');
- $split = explode('#', $name, 2);
+ $split = explode('#', $name, 3);
if (count($split) !== 2) {
throw new \UnexpectedValueException('Invalid route name: use the format foo#bar to reference FooController::bar');
}
@@ -87,7 +87,7 @@ class RouteParser {
/*
* The route name has to be lowercase, for symfony to match it correctly.
- * This is required because smyfony allows mixed casing for controller names in the routes.
+ * This is required because symfony allows mixed casing for controller names in the routes.
* To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
* This is also safe on the PHP side because class and method names collide regardless of the casing.
*/
diff --git a/lib/private/AppFramework/Utility/SimpleContainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php
index 24918992ea3..9af65a37ab8 100644
--- a/lib/private/AppFramework/Utility/SimpleContainer.php
+++ b/lib/private/AppFramework/Utility/SimpleContainer.php
@@ -153,13 +153,13 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
return $closure($this);
};
$name = $this->sanitizeName($name);
- if (isset($this[$name])) {
- unset($this[$name]);
+ if (isset($this->container[$name])) {
+ unset($this->container[$name]);
}
if ($shared) {
- $this[$name] = $wrapped;
+ $this->container[$name] = $wrapped;
} else {
- $this[$name] = $this->container->factory($wrapped);
+ $this->container[$name] = $this->container->factory($wrapped);
}
}
diff --git a/lib/private/Calendar/Manager.php b/lib/private/Calendar/Manager.php
index e86e0e1d410..21370e74d54 100644
--- a/lib/private/Calendar/Manager.php
+++ b/lib/private/Calendar/Manager.php
@@ -33,6 +33,7 @@ use Sabre\HTTP\Response;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Component\VEvent;
use Sabre\VObject\Component\VFreeBusy;
+use Sabre\VObject\ParseException;
use Sabre\VObject\Property\VCard\DateTime;
use Sabre\VObject\Reader;
use Throwable;
@@ -235,9 +236,14 @@ class Manager implements IManager {
$this->logger->warning('iMip message could not be processed because user has no calendars');
return false;
}
-
- /** @var VCalendar $vObject|null */
- $calendarObject = Reader::read($calendarData);
+
+ try {
+ /** @var VCalendar $vObject|null */
+ $calendarObject = Reader::read($calendarData);
+ } catch (ParseException $e) {
+ $this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
+ return false;
+ }
if (!isset($calendarObject->METHOD) || $calendarObject->METHOD->getValue() !== 'REQUEST') {
$this->logger->warning('iMip message contains an incorrect or invalid method');
@@ -249,6 +255,7 @@ class Manager implements IManager {
return false;
}
+ /** @var VEvent|null $vEvent */
$eventObject = $calendarObject->VEVENT;
if (!isset($eventObject->UID)) {
@@ -256,6 +263,11 @@ class Manager implements IManager {
return false;
}
+ if (!isset($eventObject->ORGANIZER)) {
+ $this->logger->warning('iMip message event dose not contains an organizer');
+ return false;
+ }
+
if (!isset($eventObject->ATTENDEE)) {
$this->logger->warning('iMip message event dose not contains any attendees');
return false;
@@ -296,7 +308,7 @@ class Manager implements IManager {
}
}
- $this->logger->warning('iMip message event could not be processed because the no corresponding event was found in any calendar');
+ $this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar');
return false;
}
@@ -309,23 +321,51 @@ class Manager implements IManager {
string $recipient,
string $calendarData,
): bool {
- /** @var VCalendar $vObject|null */
- $vObject = Reader::read($calendarData);
+
+ $calendars = $this->getCalendarsForPrincipal($principalUri);
+ if (empty($calendars)) {
+ $this->logger->warning('iMip message could not be processed because user has no calendars');
+ return false;
+ }
+
+ try {
+ /** @var VCalendar $vObject|null */
+ $vObject = Reader::read($calendarData);
+ } catch (ParseException $e) {
+ $this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
+ return false;
+ }
if ($vObject === null) {
+ $this->logger->warning('iMip message contains an invalid calendar object');
+ return false;
+ }
+
+ if (!isset($vObject->METHOD) || $vObject->METHOD->getValue() !== 'REPLY') {
+ $this->logger->warning('iMip message contains an incorrect or invalid method');
+ return false;
+ }
+
+ if (!isset($vObject->VEVENT)) {
+ $this->logger->warning('iMip message contains no event');
return false;
}
/** @var VEvent|null $vEvent */
- $vEvent = $vObject->{'VEVENT'};
+ $vEvent = $vObject->VEVENT;
+
+ if (!isset($vEvent->UID)) {
+ $this->logger->warning('iMip message event dose not contains a UID');
+ return false;
+ }
- if ($vEvent === null) {
+ if (!isset($vEvent->ORGANIZER)) {
+ $this->logger->warning('iMip message event dose not contains an organizer');
return false;
}
- // First, we check if the correct method is passed to us
- if (strcasecmp('REPLY', $vObject->{'METHOD'}->getValue()) !== 0) {
- $this->logger->warning('Wrong method provided for processing');
+ if (!isset($vEvent->ATTENDEE)) {
+ $this->logger->warning('iMip message event dose not contains any attendees');
return false;
}
@@ -333,7 +373,7 @@ class Manager implements IManager {
$organizer = substr($vEvent->{'ORGANIZER'}->getValue(), 7);
if (strcasecmp($recipient, $organizer) !== 0) {
- $this->logger->warning('Recipient and ORGANIZER must be identical');
+ $this->logger->warning('iMip message event could not be processed because recipient and ORGANIZER must be identical');
return false;
}
@@ -341,13 +381,7 @@ class Manager implements IManager {
/** @var DateTime $eventTime */
$eventTime = $vEvent->{'DTSTART'};
if ($eventTime->getDateTime()->getTimeStamp() < $this->timeFactory->getTime()) { // this might cause issues with recurrences
- $this->logger->warning('Only events in the future are processed');
- return false;
- }
-
- $calendars = $this->getCalendarsForPrincipal($principalUri);
- if (empty($calendars)) {
- $this->logger->warning('Could not find any calendars for principal ' . $principalUri);
+ $this->logger->warning('iMip message event could not be processed because the event is in the past');
return false;
}
@@ -369,14 +403,14 @@ class Manager implements IManager {
}
if (empty($found)) {
- $this->logger->info('Event not found in any calendar for principal ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
+ $this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
return false;
}
try {
$found->handleIMipMessage($name, $calendarData); // sabre will handle the scheduling behind the scenes
} catch (CalendarException $e) {
- $this->logger->error('Could not update calendar for iMIP processing', ['exception' => $e]);
+ $this->logger->error('An error occurred while processing the iMip message event', ['exception' => $e]);
return false;
}
return true;
@@ -393,29 +427,57 @@ class Manager implements IManager {
string $recipient,
string $calendarData,
): bool {
- /** @var VCalendar $vObject|null */
- $vObject = Reader::read($calendarData);
+
+ $calendars = $this->getCalendarsForPrincipal($principalUri);
+ if (empty($calendars)) {
+ $this->logger->warning('iMip message could not be processed because user has no calendars');
+ return false;
+ }
+
+ try {
+ /** @var VCalendar $vObject|null */
+ $vObject = Reader::read($calendarData);
+ } catch (ParseException $e) {
+ $this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
+ return false;
+ }
if ($vObject === null) {
+ $this->logger->warning('iMip message contains an invalid calendar object');
+ return false;
+ }
+
+ if (!isset($vObject->METHOD) || $vObject->METHOD->getValue() !== 'CANCEL') {
+ $this->logger->warning('iMip message contains an incorrect or invalid method');
+ return false;
+ }
+
+ if (!isset($vObject->VEVENT)) {
+ $this->logger->warning('iMip message contains no event');
return false;
}
/** @var VEvent|null $vEvent */
$vEvent = $vObject->{'VEVENT'};
- if ($vEvent === null) {
+ if (!isset($vEvent->UID)) {
+ $this->logger->warning('iMip message event dose not contains a UID');
+ return false;
+ }
+
+ if (!isset($vEvent->ORGANIZER)) {
+ $this->logger->warning('iMip message event dose not contains an organizer');
return false;
}
- // First, we check if the correct method is passed to us
- if (strcasecmp('CANCEL', $vObject->{'METHOD'}->getValue()) !== 0) {
- $this->logger->warning('Wrong method provided for processing');
+ if (!isset($vEvent->ATTENDEE)) {
+ $this->logger->warning('iMip message event dose not contains any attendees');
return false;
}
$attendee = substr($vEvent->{'ATTENDEE'}->getValue(), 7);
if (strcasecmp($recipient, $attendee) !== 0) {
- $this->logger->warning('Recipient must be an ATTENDEE of this event');
+ $this->logger->warning('iMip message event could not be processed because recipient must be an ATTENDEE of this event');
return false;
}
@@ -426,7 +488,7 @@ class Manager implements IManager {
$organizer = substr($vEvent->{'ORGANIZER'}->getValue(), 7);
$isNotOrganizer = ($replyTo !== null) ? (strcasecmp($sender, $organizer) !== 0 && strcasecmp($replyTo, $organizer) !== 0) : (strcasecmp($sender, $organizer) !== 0);
if ($isNotOrganizer) {
- $this->logger->warning('Sender must be the ORGANIZER of this event');
+ $this->logger->warning('iMip message event could not be processed because sender must be the ORGANIZER of this event');
return false;
}
@@ -434,14 +496,7 @@ class Manager implements IManager {
/** @var DateTime $eventTime */
$eventTime = $vEvent->{'DTSTART'};
if ($eventTime->getDateTime()->getTimeStamp() < $this->timeFactory->getTime()) { // this might cause issues with recurrences
- $this->logger->warning('Only events in the future are processed');
- return false;
- }
-
- // Check if we have a calendar to work with
- $calendars = $this->getCalendarsForPrincipal($principalUri);
- if (empty($calendars)) {
- $this->logger->warning('Could not find any calendars for principal ' . $principalUri);
+ $this->logger->warning('iMip message event could not be processed because the event is in the past');
return false;
}
@@ -463,17 +518,15 @@ class Manager implements IManager {
}
if (empty($found)) {
- $this->logger->info('Event not found in any calendar for principal ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
- // this is a safe operation
- // we can ignore events that have been cancelled but were not in the calendar anyway
- return true;
+ $this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
+ return false;
}
try {
$found->handleIMipMessage($name, $calendarData); // sabre will handle the scheduling behind the scenes
return true;
} catch (CalendarException $e) {
- $this->logger->error('Could not update calendar for iMIP processing', ['exception' => $e]);
+ $this->logger->error('An error occurred while processing the iMip message event', ['exception' => $e]);
return false;
}
}
diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php
index 8f1b8e6d75f..edd8c1bf023 100644
--- a/lib/private/DB/Adapter.php
+++ b/lib/private/DB/Adapter.php
@@ -28,11 +28,25 @@ class Adapter {
/**
* @param string $table name
*
- * @return int id of last insert statement
+ * @return int id of last insert statement, 0 in case there was no INSERT before or it failed to get the ID
* @throws Exception
*/
- public function lastInsertId($table) {
- return (int)$this->conn->realLastInsertId($table);
+ public function lastInsertId($table, bool $allowRetry = true): int {
+ $return = $this->conn->realLastInsertId($table);
+ if ($return === 0 && $allowRetry) {
+ /**
+ * During a reconnect we are losing the connection and when the
+ * realLastInsertId call is the one triggering the reconnect, it
+ * does not return the ID. But inside the reconnect, we were able
+ * to save the last insert id, so calling it a second time is going
+ * to be successful.
+ * We can not return the result on the initial call, as we are already
+ * way deeper in the stack performing the actual database query on
+ * the doctrine driver.
+ */
+ return $this->lastInsertId($table, false);
+ }
+ return $return;
}
/**
diff --git a/lib/private/DB/AdapterOCI8.php b/lib/private/DB/AdapterOCI8.php
index 0a509090bca..f5ad9f7c934 100644
--- a/lib/private/DB/AdapterOCI8.php
+++ b/lib/private/DB/AdapterOCI8.php
@@ -8,7 +8,7 @@
namespace OC\DB;
class AdapterOCI8 extends Adapter {
- public function lastInsertId($table) {
+ public function lastInsertId($table, bool $allowRetry = true): int {
if (is_null($table)) {
throw new \InvalidArgumentException('Oracle requires a table name to be passed into lastInsertId()');
}
diff --git a/lib/private/DB/AdapterPgSql.php b/lib/private/DB/AdapterPgSql.php
index db48c81c2c5..b321fcf4715 100644
--- a/lib/private/DB/AdapterPgSql.php
+++ b/lib/private/DB/AdapterPgSql.php
@@ -9,7 +9,7 @@ namespace OC\DB;
class AdapterPgSql extends Adapter {
- public function lastInsertId($table) {
+ public function lastInsertId($table, bool $allowRetry = true): int {
$result = $this->conn->executeQuery('SELECT lastval()');
$val = $result->fetchOne();
$result->free();
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php
index 96dd578b2ef..4ba2d2a341d 100644
--- a/lib/private/DB/Connection.php
+++ b/lib/private/DB/Connection.php
@@ -92,6 +92,8 @@ class Connection extends PrimaryReadReplicaConnection {
protected ShardConnectionManager $shardConnectionManager;
protected AutoIncrementHandler $autoIncrementHandler;
protected bool $isShardingEnabled;
+ protected bool $disableReconnect = false;
+ protected int $lastInsertId = 0;
public const SHARD_PRESETS = [
'filecache' => [
@@ -510,9 +512,9 @@ class Connection extends PrimaryReadReplicaConnection {
* because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
* columns or sequences.
*
- * @param string $seqName Name of the sequence object from which the ID should be returned.
+ * @param ?string $name Name of the sequence object from which the ID should be returned.
*
- * @return int the last inserted ID.
+ * @return int the last inserted ID, 0 in case there was no INSERT before or it failed to get the ID
* @throws Exception
*/
public function lastInsertId($name = null): int {
@@ -526,8 +528,13 @@ class Connection extends PrimaryReadReplicaConnection {
* @internal
* @throws Exception
*/
- public function realLastInsertId($seqName = null) {
- return parent::lastInsertId($seqName);
+ public function realLastInsertId($seqName = null): int {
+ if ($this->lastInsertId !== 0) {
+ $lastInsertId = $this->lastInsertId;
+ $this->lastInsertId = 0;
+ return $lastInsertId;
+ }
+ return (int)parent::lastInsertId($seqName);
}
/**
@@ -896,11 +903,23 @@ class Connection extends PrimaryReadReplicaConnection {
if (
!isset($this->lastConnectionCheck[$this->getConnectionName()]) ||
time() <= $this->lastConnectionCheck[$this->getConnectionName()] + 30 ||
- $this->isTransactionActive()
+ $this->isTransactionActive() ||
+ $this->disableReconnect
) {
return;
}
+ if ($this->getDatabaseProvider() === IDBConnection::PLATFORM_MYSQL) {
+ /**
+ * Before reconnecting we save the lastInsertId, so that if the reconnect
+ * happens between the INSERT executeStatement() and the getLastInsertId call
+ * we are able to return the correct result after all.
+ */
+ $this->disableReconnect = true;
+ $this->lastInsertId = (int)parent::lastInsertId();
+ $this->disableReconnect = false;
+ }
+
try {
$this->_conn->query($this->getDriver()->getDatabasePlatform()->getDummySelectSQL());
$this->lastConnectionCheck[$this->getConnectionName()] = time();
diff --git a/lib/private/Encryption/EncryptionEventListener.php b/lib/private/Encryption/EncryptionEventListener.php
new file mode 100644
index 00000000000..59ac0dea932
--- /dev/null
+++ b/lib/private/Encryption/EncryptionEventListener.php
@@ -0,0 +1,93 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace OC\Encryption;
+
+use OC\Files\SetupManager;
+use OC\Files\View;
+use OCA\Files_Trashbin\Events\NodeRestoredEvent;
+use OCP\Encryption\IFile;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Files\Events\Node\NodeRenamedEvent;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Share\Events\ShareCreatedEvent;
+use OCP\Share\Events\ShareDeletedEvent;
+use Psr\Log\LoggerInterface;
+
+/** @template-implements IEventListener<NodeRenamedEvent|ShareCreatedEvent|ShareDeletedEvent|NodeRestoredEvent> */
+class EncryptionEventListener implements IEventListener {
+ private ?Update $updater = null;
+
+ public function __construct(
+ private IUserSession $userSession,
+ private SetupManager $setupManager,
+ private Manager $encryptionManager,
+ ) {
+ }
+
+ public static function register(IEventDispatcher $dispatcher): void {
+ $dispatcher->addServiceListener(NodeRenamedEvent::class, static::class);
+ $dispatcher->addServiceListener(ShareCreatedEvent::class, static::class);
+ $dispatcher->addServiceListener(ShareDeletedEvent::class, static::class);
+ $dispatcher->addServiceListener(NodeRestoredEvent::class, static::class);
+ }
+
+ public function handle(Event $event): void {
+ if (!$this->encryptionManager->isEnabled()) {
+ return;
+ }
+ if ($event instanceof NodeRenamedEvent) {
+ $this->getUpdate()->postRename($event->getSource(), $event->getTarget());
+ } elseif ($event instanceof ShareCreatedEvent) {
+ $this->getUpdate()->postShared($event->getShare()->getNode());
+ } elseif ($event instanceof ShareDeletedEvent) {
+ // In case the unsharing happens in a background job, we don't have
+ // a session and we load instead the user from the UserManager
+ $owner = $event->getShare()->getNode()->getOwner();
+ $this->getUpdate($owner)->postUnshared($event->getShare()->getNode());
+ } elseif ($event instanceof NodeRestoredEvent) {
+ $this->getUpdate()->postRestore($event->getTarget());
+ }
+ }
+
+ private function getUpdate(?IUser $owner = null): Update {
+ if (is_null($this->updater)) {
+ $user = $this->userSession->getUser();
+ if (!$user && ($owner !== null)) {
+ $user = $owner;
+ }
+ if (!$user) {
+ throw new \Exception('Inconsistent data, File unshared, but owner not found. Should not happen');
+ }
+
+ $uid = $user->getUID();
+
+ if (!$this->setupManager->isSetupComplete($user)) {
+ $this->setupManager->setupForUser($user);
+ }
+
+ $this->updater = new Update(
+ new Util(
+ new View(),
+ \OC::$server->getUserManager(),
+ \OC::$server->getGroupManager(),
+ \OC::$server->getConfig()),
+ \OC::$server->getEncryptionManager(),
+ \OC::$server->get(IFile::class),
+ \OC::$server->get(LoggerInterface::class),
+ $uid
+ );
+ }
+
+ return $this->updater;
+ }
+}
diff --git a/lib/private/Encryption/EncryptionWrapper.php b/lib/private/Encryption/EncryptionWrapper.php
index 7f355b603d6..b9db9616538 100644
--- a/lib/private/Encryption/EncryptionWrapper.php
+++ b/lib/private/Encryption/EncryptionWrapper.php
@@ -75,15 +75,6 @@ class EncryptionWrapper {
\OC::$server->getGroupManager(),
\OC::$server->getConfig()
);
- $update = new Update(
- new View(),
- $util,
- Filesystem::getMountManager(),
- $this->manager,
- $fileHelper,
- $this->logger,
- $uid
- );
return new Encryption(
$parameters,
$this->manager,
@@ -92,7 +83,6 @@ class EncryptionWrapper {
$fileHelper,
$uid,
$keyStorage,
- $update,
$mountManager,
$this->arrayCache
);
diff --git a/lib/private/Encryption/HookManager.php b/lib/private/Encryption/HookManager.php
deleted file mode 100644
index 39e7edabb95..00000000000
--- a/lib/private/Encryption/HookManager.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/**
- * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-namespace OC\Encryption;
-
-use OC\Files\Filesystem;
-use OC\Files\SetupManager;
-use OC\Files\View;
-use OCP\Encryption\IFile;
-use Psr\Log\LoggerInterface;
-
-class HookManager {
- private static ?Update $updater = null;
-
- public static function postShared($params): void {
- self::getUpdate()->postShared($params);
- }
- public static function postUnshared($params): void {
- // In case the unsharing happens in a background job, we don't have
- // a session and we load instead the user from the UserManager
- $path = Filesystem::getPath($params['fileSource']);
- $owner = Filesystem::getOwner($path);
- self::getUpdate($owner)->postUnshared($params);
- }
-
- public static function postRename($params): void {
- self::getUpdate()->postRename($params);
- }
-
- public static function postRestore($params): void {
- self::getUpdate()->postRestore($params);
- }
-
- private static function getUpdate(?string $owner = null): Update {
- if (is_null(self::$updater)) {
- $user = \OC::$server->getUserSession()->getUser();
- if (!$user && $owner) {
- $user = \OC::$server->getUserManager()->get($owner);
- }
- if (!$user) {
- throw new \Exception('Inconsistent data, File unshared, but owner not found. Should not happen');
- }
-
- $uid = '';
- if ($user) {
- $uid = $user->getUID();
- }
-
- $setupManager = \OC::$server->get(SetupManager::class);
- if (!$setupManager->isSetupComplete($user)) {
- $setupManager->setupForUser($user);
- }
-
- self::$updater = new Update(
- new View(),
- new Util(
- new View(),
- \OC::$server->getUserManager(),
- \OC::$server->getGroupManager(),
- \OC::$server->getConfig()),
- Filesystem::getMountManager(),
- \OC::$server->getEncryptionManager(),
- \OC::$server->get(IFile::class),
- \OC::$server->get(LoggerInterface::class),
- $uid
- );
- }
-
- return self::$updater;
- }
-}
diff --git a/lib/private/Encryption/Update.php b/lib/private/Encryption/Update.php
index 0b27d63c19a..293a1ce653c 100644
--- a/lib/private/Encryption/Update.php
+++ b/lib/private/Encryption/Update.php
@@ -1,146 +1,85 @@
<?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
*/
+
namespace OC\Encryption;
use InvalidArgumentException;
-use OC\Files\Filesystem;
-use OC\Files\Mount;
use OC\Files\View;
use OCP\Encryption\Exceptions\GenericEncryptionException;
+use OCP\Files\File as OCPFile;
+use OCP\Files\Folder;
+use OCP\Files\NotFoundException;
use Psr\Log\LoggerInterface;
/**
* update encrypted files, e.g. because a file was shared
*/
class Update {
- /** @var View */
- protected $view;
-
- /** @var Util */
- protected $util;
-
- /** @var \OC\Files\Mount\Manager */
- protected $mountManager;
-
- /** @var Manager */
- protected $encryptionManager;
-
- /** @var string */
- protected $uid;
-
- /** @var File */
- protected $file;
-
- /** @var LoggerInterface */
- protected $logger;
-
- /**
- * @param string $uid
- */
public function __construct(
- View $view,
- Util $util,
- Mount\Manager $mountManager,
- Manager $encryptionManager,
- File $file,
- LoggerInterface $logger,
- $uid,
+ protected Util $util,
+ protected Manager $encryptionManager,
+ protected File $file,
+ protected LoggerInterface $logger,
+ protected string $uid,
) {
- $this->view = $view;
- $this->util = $util;
- $this->mountManager = $mountManager;
- $this->encryptionManager = $encryptionManager;
- $this->file = $file;
- $this->logger = $logger;
- $this->uid = $uid;
}
/**
* hook after file was shared
- *
- * @param array $params
*/
- public function postShared($params) {
- if ($this->encryptionManager->isEnabled()) {
- if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
- $path = Filesystem::getPath($params['fileSource']);
- [$owner, $ownerPath] = $this->getOwnerPath($path);
- $absPath = '/' . $owner . '/files/' . $ownerPath;
- $this->update($absPath);
- }
- }
+ public function postShared(OCPFile|Folder $node): void {
+ $this->update($node);
}
/**
* hook after file was unshared
- *
- * @param array $params
*/
- public function postUnshared($params) {
- if ($this->encryptionManager->isEnabled()) {
- if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
- $path = Filesystem::getPath($params['fileSource']);
- [$owner, $ownerPath] = $this->getOwnerPath($path);
- $absPath = '/' . $owner . '/files/' . $ownerPath;
- $this->update($absPath);
- }
- }
+ public function postUnshared(OCPFile|Folder $node): void {
+ $this->update($node);
}
/**
* inform encryption module that a file was restored from the trash bin,
* e.g. to update the encryption keys
- *
- * @param array $params
*/
- public function postRestore($params) {
- if ($this->encryptionManager->isEnabled()) {
- $path = Filesystem::normalizePath('/' . $this->uid . '/files/' . $params['filePath']);
- $this->update($path);
- }
+ public function postRestore(OCPFile|Folder $node): void {
+ $this->update($node);
}
/**
* inform encryption module that a file was renamed,
* e.g. to update the encryption keys
- *
- * @param array $params
*/
- public function postRename($params) {
- $source = $params['oldpath'];
- $target = $params['newpath'];
- if (
- $this->encryptionManager->isEnabled() &&
- dirname($source) !== dirname($target)
- ) {
- [$owner, $ownerPath] = $this->getOwnerPath($target);
- $absPath = '/' . $owner . '/files/' . $ownerPath;
- $this->update($absPath);
+ public function postRename(OCPFile|Folder $source, OCPFile|Folder $target): void {
+ if (dirname($source->getPath()) !== dirname($target->getPath())) {
+ $this->update($target);
}
}
/**
- * get owner and path relative to data/<owner>/files
+ * get owner and path relative to data/
*
- * @param string $path path to file for current user
- * @return array ['owner' => $owner, 'path' => $path]
* @throws \InvalidArgumentException
*/
- protected function getOwnerPath($path) {
- $info = Filesystem::getFileInfo($path);
- $owner = Filesystem::getOwner($path);
+ protected function getOwnerPath(OCPFile|Folder $node): string {
+ $owner = $node->getOwner()?->getUID();
+ if ($owner === null) {
+ throw new InvalidArgumentException('No owner found for ' . $node->getId());
+ }
$view = new View('/' . $owner . '/files');
- $path = $view->getPath($info->getId());
- if ($path === null) {
- throw new InvalidArgumentException('No file found for ' . $info->getId());
+ try {
+ $path = $view->getPath($node->getId());
+ } catch (NotFoundException $e) {
+ throw new InvalidArgumentException('No file found for ' . $node->getId(), previous:$e);
}
-
- return [$owner, $path];
+ return '/' . $owner . '/files/' . $path;
}
/**
@@ -149,7 +88,7 @@ class Update {
* @param string $path relative to data/
* @throws Exceptions\ModuleDoesNotExistsException
*/
- public function update($path) {
+ public function update(OCPFile|Folder $node): void {
$encryptionModule = $this->encryptionManager->getEncryptionModule();
// if the encryption module doesn't encrypt the files on a per-user basis
@@ -158,15 +97,14 @@ class Update {
return;
}
+ $path = $this->getOwnerPath($node);
// if a folder was shared, get a list of all (sub-)folders
- if ($this->view->is_dir($path)) {
+ if ($node instanceof Folder) {
$allFiles = $this->util->getAllFiles($path);
} else {
$allFiles = [$path];
}
-
-
foreach ($allFiles as $file) {
$usersSharing = $this->file->getAccessList($file);
try {
diff --git a/lib/private/Encryption/Util.php b/lib/private/Encryption/Util.php
index 1fb08b15696..0566ab9a760 100644
--- a/lib/private/Encryption/Util.php
+++ b/lib/private/Encryption/Util.php
@@ -304,7 +304,7 @@ class Util {
// detect user specific folders
if ($this->userManager->userExists($root[1])
- && in_array($root[2], $this->excludedPaths)) {
+ && in_array($root[2] ?? '', $this->excludedPaths)) {
return true;
}
}
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index 2c190720c23..cb160115851 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -663,7 +663,7 @@ class Cache implements ICache {
$sourceData = $sourceCache->get($sourcePath);
if (!$sourceData) {
- throw new \Exception('Invalid source storage path: ' . $sourcePath);
+ throw new \Exception('Source path not found in cache: ' . $sourcePath);
}
$shardDefinition = $this->connection->getShardDefinition('filecache');
diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php
index 5c7bd4334f3..5bc4ee8529d 100644
--- a/lib/private/Files/Cache/Wrapper/CacheJail.php
+++ b/lib/private/Files/Cache/Wrapper/CacheJail.php
@@ -31,10 +31,13 @@ class CacheJail extends CacheWrapper {
) {
parent::__construct($cache, $dependencies);
- if ($cache instanceof CacheJail) {
- $this->unjailedRoot = $cache->getSourcePath($root);
- } else {
- $this->unjailedRoot = $root;
+ $this->unjailedRoot = $root;
+ $parent = $cache;
+ while ($parent instanceof CacheWrapper) {
+ if ($parent instanceof CacheJail) {
+ $this->unjailedRoot = $parent->getSourcePath($this->unjailedRoot);
+ }
+ $parent = $parent->getCache();
}
}
@@ -50,7 +53,7 @@ class CacheJail extends CacheWrapper {
*
* @return string
*/
- protected function getGetUnjailedRoot() {
+ public function getGetUnjailedRoot() {
return $this->unjailedRoot;
}
diff --git a/lib/private/Files/FilenameValidator.php b/lib/private/Files/FilenameValidator.php
index b1979789ec8..57a62b0b219 100644
--- a/lib/private/Files/FilenameValidator.php
+++ b/lib/private/Files/FilenameValidator.php
@@ -228,6 +228,43 @@ class FilenameValidator implements IFilenameValidator {
return false;
}
+ public function sanitizeFilename(string $name, ?string $charReplacement = null): string {
+ $forbiddenCharacters = $this->getForbiddenCharacters();
+
+ if ($charReplacement === null) {
+ $charReplacement = array_diff([' ', '_', '-'], $forbiddenCharacters);
+ $charReplacement = reset($charReplacement) ?: '';
+ }
+ if (mb_strlen($charReplacement) !== 1) {
+ throw new \InvalidArgumentException('No or invalid character replacement given');
+ }
+
+ $nameLowercase = mb_strtolower($name);
+ foreach ($this->getForbiddenExtensions() as $extension) {
+ if (str_ends_with($nameLowercase, $extension)) {
+ $name = substr($name, 0, strlen($name) - strlen($extension));
+ }
+ }
+
+ $basename = strlen($name) > 1
+ ? substr($name, 0, strpos($name, '.', 1) ?: null)
+ : $name;
+ if (in_array(mb_strtolower($basename), $this->getForbiddenBasenames())) {
+ $name = str_replace($basename, $this->l10n->t('%1$s (renamed)', [$basename]), $name);
+ }
+
+ if ($name === '') {
+ $name = $this->l10n->t('renamed file');
+ }
+
+ if (in_array(mb_strtolower($name), $this->getForbiddenFilenames())) {
+ $name = $this->l10n->t('%1$s (renamed)', [$name]);
+ }
+
+ $name = str_replace($forbiddenCharacters, $charReplacement, $name);
+ return $name;
+ }
+
protected function checkForbiddenName(string $filename): void {
$filename = mb_strtolower($filename);
if ($this->isForbidden($filename)) {
diff --git a/lib/private/Files/SimpleFS/SimpleFile.php b/lib/private/Files/SimpleFS/SimpleFile.php
index cbb3af4db29..0bfaea21788 100644
--- a/lib/private/Files/SimpleFS/SimpleFile.php
+++ b/lib/private/Files/SimpleFS/SimpleFile.php
@@ -6,9 +6,11 @@
namespace OC\Files\SimpleFS;
use OCP\Files\File;
+use OCP\Files\GenericFileException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\Lock\LockedException;
class SimpleFile implements ISimpleFile {
private File $file;
@@ -48,8 +50,10 @@ class SimpleFile implements ISimpleFile {
/**
* Get the content
*
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
*/
public function getContent(): string {
$result = $this->file->getContent();
@@ -65,8 +69,10 @@ class SimpleFile implements ISimpleFile {
* Overwrite the file
*
* @param string|resource $data
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
*/
public function putContent($data): void {
try {
diff --git a/lib/private/Files/Storage/Temporary.php b/lib/private/Files/Storage/Temporary.php
index ff7a816930d..ecf8a1315a9 100644
--- a/lib/private/Files/Storage/Temporary.php
+++ b/lib/private/Files/Storage/Temporary.php
@@ -7,16 +7,20 @@
*/
namespace OC\Files\Storage;
+use OCP\Files;
+use OCP\ITempManager;
+use OCP\Server;
+
/**
* local storage backend in temporary folder for testing purpose
*/
class Temporary extends Local {
public function __construct(array $parameters = []) {
- parent::__construct(['datadir' => \OC::$server->getTempManager()->getTemporaryFolder()]);
+ parent::__construct(['datadir' => Server::get(ITempManager::class)->getTemporaryFolder()]);
}
public function cleanUp(): void {
- \OC_Helper::rmdirr($this->datadir);
+ Files::rmdirr($this->datadir);
}
public function __destruct() {
diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php
index bdaba57687a..f4ab4754cff 100644
--- a/lib/private/Files/Storage/Wrapper/Encryption.php
+++ b/lib/private/Files/Storage/Wrapper/Encryption.php
@@ -8,7 +8,6 @@
namespace OC\Files\Storage\Wrapper;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
-use OC\Encryption\Update;
use OC\Encryption\Util;
use OC\Files\Cache\CacheEntry;
use OC\Files\Filesystem;
@@ -50,7 +49,6 @@ class Encryption extends Wrapper {
private IFile $fileHelper,
private ?string $uid,
private IStorage $keyStorage,
- private Update $update,
private Manager $mountManager,
private ArrayCache $arrayCache,
) {
@@ -65,7 +63,8 @@ class Encryption extends Wrapper {
$info = $this->getCache()->get($path);
if ($info === false) {
- return false;
+ /* Pass call to wrapped storage, it may be a special file like a part file */
+ return $this->storage->filesize($path);
}
if (isset($this->unencryptedSize[$fullPath])) {
$size = $this->unencryptedSize[$fullPath];
@@ -319,7 +318,7 @@ class Encryption extends Wrapper {
if (!empty($encryptionModuleId)) {
$encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
$shouldEncrypt = true;
- } elseif (empty($encryptionModuleId) && $info['encrypted'] === true) {
+ } elseif ($info !== false && $info['encrypted'] === true) {
// we come from a old installation. No header and/or no module defined
// but the file is encrypted. In this case we need to use the
// OC_DEFAULT_MODULE to read the file
@@ -537,10 +536,22 @@ class Encryption extends Wrapper {
$result = $this->copyBetweenStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, true);
if ($result) {
- if ($sourceStorage->is_dir($sourceInternalPath)) {
- $result = $sourceStorage->rmdir($sourceInternalPath);
- } else {
- $result = $sourceStorage->unlink($sourceInternalPath);
+ $setPreserveCacheOnDelete = $sourceStorage->instanceOfStorage(ObjectStoreStorage::class) && !$this->instanceOfStorage(ObjectStoreStorage::class);
+ if ($setPreserveCacheOnDelete) {
+ /** @var ObjectStoreStorage $sourceStorage */
+ $sourceStorage->setPreserveCacheOnDelete(true);
+ }
+ try {
+ if ($sourceStorage->is_dir($sourceInternalPath)) {
+ $result = $sourceStorage->rmdir($sourceInternalPath);
+ } else {
+ $result = $sourceStorage->unlink($sourceInternalPath);
+ }
+ } finally {
+ if ($setPreserveCacheOnDelete) {
+ /** @var ObjectStoreStorage $sourceStorage */
+ $sourceStorage->setPreserveCacheOnDelete(false);
+ }
}
}
return $result;
@@ -665,7 +676,7 @@ class Encryption extends Wrapper {
if (is_resource($dh)) {
while ($result && ($file = readdir($dh)) !== false) {
if (!Filesystem::isIgnoredDir($file)) {
- $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, false, $isRename);
+ $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, $preserveMtime, $isRename);
}
}
}
diff --git a/lib/private/Files/Type/Detection.php b/lib/private/Files/Type/Detection.php
index 42315247dbf..d5810a90868 100644
--- a/lib/private/Files/Type/Detection.php
+++ b/lib/private/Files/Type/Detection.php
@@ -9,6 +9,7 @@ declare(strict_types=1);
namespace OC\Files\Type;
use OCP\Files\IMimeTypeDetector;
+use OCP\IBinaryFinder;
use OCP\ITempManager;
use OCP\IURLGenerator;
use Psr\Log\LoggerInterface;
@@ -23,6 +24,7 @@ use Psr\Log\LoggerInterface;
class Detection implements IMimeTypeDetector {
private const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json';
private const CUSTOM_MIMETYPEALIASES = 'mimetypealiases.json';
+ private const CUSTOM_MIMETYPENAMES = 'mimetypenames.json';
/** @var array<list{string, string|null}> */
protected array $mimeTypes = [];
@@ -31,6 +33,8 @@ class Detection implements IMimeTypeDetector {
protected array $mimeTypeIcons = [];
/** @var array<string,string> */
protected array $mimeTypeAlias = [];
+ /** @var array<string,string> */
+ protected array $mimeTypesNames = [];
public function __construct(
private IURLGenerator $urlGenerator,
@@ -148,6 +152,25 @@ class Detection implements IMimeTypeDetector {
return $this->mimeTypes;
}
+ private function loadNamings(): void {
+ if (!empty($this->mimeTypesNames)) {
+ return;
+ }
+
+ $mimeTypeMapping = json_decode(file_get_contents($this->defaultConfigDir . '/mimetypenames.dist.json'), true);
+ $mimeTypeMapping = $this->loadCustomDefinitions(self::CUSTOM_MIMETYPENAMES, $mimeTypeMapping);
+
+ $this->mimeTypesNames = $mimeTypeMapping;
+ }
+
+ /**
+ * @return array<string,string>
+ */
+ public function getAllNamings(): array {
+ $this->loadNamings();
+ return $this->mimeTypesNames;
+ }
+
/**
* detect MIME type only based on filename, content of file is not used
*
@@ -225,11 +248,13 @@ class Detection implements IMimeTypeDetector {
}
}
- if (\OC_Helper::canExecute('file')) {
+ $binaryFinder = \OCP\Server::get(IBinaryFinder::class);
+ $program = $binaryFinder->findBinaryPath('file');
+ if ($program !== false) {
// it looks like we have a 'file' command,
// lets see if it does have mime support
$path = escapeshellarg($path);
- $fp = popen("test -f $path && file -b --mime-type $path", 'r');
+ $fp = popen("test -f $path && $program -b --mime-type $path", 'r');
if ($fp !== false) {
$mimeType = fgets($fp);
pclose($fp);
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 00fdd84c1bc..a1d27c9255b 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -19,6 +19,7 @@ use OC\DB\MigrationService;
use OC_App;
use OC_Helper;
use OCP\App\IAppManager;
+use OCP\Files;
use OCP\HintException;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
@@ -324,14 +325,14 @@ class Installer {
$baseDir = OC_App::getInstallPath() . '/' . $appId;
// Remove old app with the ID if existent
- OC_Helper::rmdirr($baseDir);
+ Files::rmdirr($baseDir);
// Move to app folder
if (@mkdir($baseDir)) {
$extractDir .= '/' . $folders[0];
OC_Helper::copyr($extractDir, $baseDir);
}
OC_Helper::copyr($extractDir, $baseDir);
- OC_Helper::rmdirr($extractDir);
+ Files::rmdirr($extractDir);
return;
}
// Signature does not match
@@ -450,7 +451,7 @@ class Installer {
return false;
}
$appDir = OC_App::getInstallPath() . '/' . $appId;
- OC_Helper::rmdirr($appDir);
+ Files::rmdirr($appDir);
return true;
} else {
$this->logger->error('can\'t remove app ' . $appId . '. It is not installed.');
diff --git a/lib/private/IntegrityCheck/Checker.php b/lib/private/IntegrityCheck/Checker.php
index 361fe8e9b2d..2bd6e426b79 100644
--- a/lib/private/IntegrityCheck/Checker.php
+++ b/lib/private/IntegrityCheck/Checker.php
@@ -148,10 +148,10 @@ class Checker {
}
if ($filename === $this->environmentHelper->getServerRoot() . '/core/js/mimetypelist.js') {
$oldMimetypeList = new GenerateMimetypeFileBuilder();
- $newFile = $oldMimetypeList->generateFile($this->mimeTypeDetector->getAllAliases());
+ $newFile = $oldMimetypeList->generateFile($this->mimeTypeDetector->getAllAliases(), $this->mimeTypeDetector->getAllNamings());
$oldFile = $this->fileAccessHelper->file_get_contents($filename);
if ($newFile === $oldFile) {
- $hashes[$relativeFileName] = hash('sha512', $oldMimetypeList->generateFile($this->mimeTypeDetector->getOnlyDefaultAliases()));
+ $hashes[$relativeFileName] = hash('sha512', $oldMimetypeList->generateFile($this->mimeTypeDetector->getOnlyDefaultAliases(), $this->mimeTypeDetector->getAllNamings()));
continue;
}
}
diff --git a/lib/private/Log/LogDetails.php b/lib/private/Log/LogDetails.php
index b3ae23a3770..8c1efaea20d 100644
--- a/lib/private/Log/LogDetails.php
+++ b/lib/private/Log/LogDetails.php
@@ -59,6 +59,10 @@ abstract class LogDetails {
'userAgent',
'version'
);
+ $clientReqId = $request->getHeader('X-Request-Id');
+ if ($clientReqId !== '') {
+ $entry['clientReqId'] = $clientReqId;
+ }
if (is_array($message)) {
// Exception messages are extracted and the exception is put into a separate field
diff --git a/lib/private/Repair/MoveUpdaterStepFile.php b/lib/private/Repair/MoveUpdaterStepFile.php
index c9b51b308c4..eb9f78b0a39 100644
--- a/lib/private/Repair/MoveUpdaterStepFile.php
+++ b/lib/private/Repair/MoveUpdaterStepFile.php
@@ -5,6 +5,7 @@
*/
namespace OC\Repair;
+use OCP\Files;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
@@ -40,7 +41,7 @@ class MoveUpdaterStepFile implements IRepairStep {
// cleanup
if (file_exists($previousStepFile)) {
- if (\OC_Helper::rmdirr($previousStepFile)) {
+ if (Files::rmdirr($previousStepFile)) {
$output->info('.step-previous-update removed');
} else {
$output->info('.step-previous-update can\'t be removed - abort move of .step file');
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index d073132516d..376852a1b6e 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -54,9 +54,9 @@ class Router implements IRouter {
protected LoggerInterface $logger,
IRequest $request,
private IConfig $config,
- private IEventLogger $eventLogger,
+ protected IEventLogger $eventLogger,
private ContainerInterface $container,
- private IAppManager $appManager,
+ protected IAppManager $appManager,
) {
$baseUrl = \OC::$WEBROOT;
if (!($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
@@ -116,9 +116,11 @@ class Router implements IRouter {
$this->loaded = true;
$routingFiles = $this->getRoutingFiles();
+ $this->eventLogger->start('route:load:attributes', 'Loading Routes from attributes');
foreach (\OC_App::getEnabledApps() as $enabledApp) {
$this->loadAttributeRoutes($enabledApp);
}
+ $this->eventLogger->end('route:load:attributes');
} else {
if (isset($this->loadedApps[$app])) {
return;
@@ -140,6 +142,7 @@ class Router implements IRouter {
}
}
+ $this->eventLogger->start('route:load:files', 'Loading Routes from files');
foreach ($routingFiles as $app => $file) {
if (!isset($this->loadedApps[$app])) {
if (!$this->appManager->isAppLoaded($app)) {
@@ -160,12 +163,13 @@ class Router implements IRouter {
$this->root->addCollection($collection);
}
}
+ $this->eventLogger->end('route:load:files');
if (!isset($this->loadedApps['core'])) {
$this->loadedApps['core'] = true;
$this->useCollection('root');
$this->setupRoutes($this->getAttributeRoutes('core'), 'core');
- require __DIR__ . '/../../../core/routes.php';
+ $this->requireRouteFile(__DIR__ . '/../../../core/routes.php', 'core');
// Also add the OCS collection
$collection = $this->getCollection('root.ocs');
@@ -265,6 +269,7 @@ class Router implements IRouter {
$this->loadRoutes();
}
+ $this->eventLogger->start('route:url:match', 'Symfony url matcher call');
$matcher = new UrlMatcher($this->root, $this->context);
try {
$parameters = $matcher->match($url);
@@ -283,6 +288,7 @@ class Router implements IRouter {
throw $e;
}
}
+ $this->eventLogger->end('route:url:match');
$this->eventLogger->end('route:match');
return $parameters;
diff --git a/lib/private/Security/RateLimiting/Limiter.php b/lib/private/Security/RateLimiting/Limiter.php
index b7ac26d9132..316becfa009 100644
--- a/lib/private/Security/RateLimiting/Limiter.php
+++ b/lib/private/Security/RateLimiting/Limiter.php
@@ -13,10 +13,12 @@ use OC\Security\RateLimiting\Backend\IBackend;
use OC\Security\RateLimiting\Exception\RateLimitExceededException;
use OCP\IUser;
use OCP\Security\RateLimiting\ILimiter;
+use Psr\Log\LoggerInterface;
class Limiter implements ILimiter {
public function __construct(
private IBackend $backend,
+ private LoggerInterface $logger,
) {
}
@@ -32,6 +34,11 @@ class Limiter implements ILimiter {
): void {
$existingAttempts = $this->backend->getAttempts($methodIdentifier, $userIdentifier);
if ($existingAttempts >= $limit) {
+ $this->logger->info('Request blocked because it exceeds the rate limit [method: {method}, limit: {limit}, period: {period}]', [
+ 'method' => $methodIdentifier,
+ 'limit' => $limit,
+ 'period' => $period,
+ ]);
throw new RateLimitExceededException();
}
diff --git a/lib/private/ServerContainer.php b/lib/private/ServerContainer.php
index 9f887b2d48a..b5bcbdaeb6f 100644
--- a/lib/private/ServerContainer.php
+++ b/lib/private/ServerContainer.php
@@ -128,18 +128,17 @@ class ServerContainer extends SimpleContainer {
} catch (QueryException $e) {
// Continue with general autoloading then
}
- }
-
- // In case the service starts with OCA\ we try to find the service in
- // the apps container first.
- if (($appContainer = $this->getAppContainerForService($name)) !== null) {
- try {
- return $appContainer->queryNoFallback($name);
- } catch (QueryException $e) {
- // Didn't find the service or the respective app container
- // In this case the service won't be part of the core container,
- // so we can throw directly
- throw $e;
+ // In case the service starts with OCA\ we try to find the service in
+ // the apps container first.
+ if (($appContainer = $this->getAppContainerForService($name)) !== null) {
+ try {
+ return $appContainer->queryNoFallback($name);
+ } catch (QueryException $e) {
+ // Didn't find the service or the respective app container
+ // In this case the service won't be part of the core container,
+ // so we can throw directly
+ throw $e;
+ }
}
} elseif (str_starts_with($name, 'OC\\Settings\\') && substr_count($name, '\\') >= 3) {
$segments = explode('\\', $name);
diff --git a/lib/private/Support/CrashReport/Registry.php b/lib/private/Support/CrashReport/Registry.php
index 93969a81265..77dd8163174 100644
--- a/lib/private/Support/CrashReport/Registry.php
+++ b/lib/private/Support/CrashReport/Registry.php
@@ -110,6 +110,7 @@ class Registry implements IRegistry {
\OC::$server->get(LoggerInterface::class)->critical('Could not load lazy crash reporter: ' . $e->getMessage(), [
'exception' => $e,
]);
+ return;
}
/**
* Try to register the loaded reporter. Theoretically it could be of a wrong
diff --git a/lib/private/TempManager.php b/lib/private/TempManager.php
index b7dccad3f95..4c0ffcf43d7 100644
--- a/lib/private/TempManager.php
+++ b/lib/private/TempManager.php
@@ -8,6 +8,7 @@
namespace OC;
use bantu\IniGetWrapper\IniGetWrapper;
+use OCP\Files;
use OCP\IConfig;
use OCP\ITempManager;
use OCP\Security\ISecureRandom;
@@ -99,7 +100,7 @@ class TempManager implements ITempManager {
foreach ($files as $file) {
if (file_exists($file)) {
try {
- \OC_Helper::rmdirr($file);
+ Files::rmdirr($file);
} catch (\UnexpectedValueException $ex) {
$this->log->warning(
'Error deleting temporary file/folder: {file} - Reason: {error}',
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index f04977314e2..8e01a15695c 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -11,7 +11,6 @@ use InvalidArgumentException;
use OC\Accounts\AccountManager;
use OC\Avatar\AvatarManager;
use OC\Hooks\Emitter;
-use OC_Helper;
use OCP\Accounts\IAccountManager;
use OCP\Comments\ICommentsManager;
use OCP\EventDispatcher\IEventDispatcher;
@@ -570,11 +569,11 @@ class User implements IUser {
public function setQuota($quota) {
$oldQuota = $this->config->getUserValue($this->uid, 'files', 'quota', '');
if ($quota !== 'none' and $quota !== 'default') {
- $bytesQuota = OC_Helper::computerFileSize($quota);
+ $bytesQuota = \OCP\Util::computerFileSize($quota);
if ($bytesQuota === false) {
throw new InvalidArgumentException('Failed to set quota to invalid value ' . $quota);
}
- $quota = OC_Helper::humanFileSize($bytesQuota);
+ $quota = \OCP\Util::humanFileSize($bytesQuota);
}
if ($quota !== $oldQuota) {
$this->config->setUserValue($this->uid, 'files', 'quota', $quota);
diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php
index ecceafa65b3..abac0d2635e 100644
--- a/lib/private/legacy/OC_App.php
+++ b/lib/private/legacy/OC_App.php
@@ -768,28 +768,6 @@ class OC_App {
}
}
- /**
- * @param string $appId
- * @return \OC\Files\View|false
- */
- public static function getStorage(string $appId) {
- if (\OC::$server->getAppManager()->isEnabledForUser($appId)) { //sanity check
- if (\OC::$server->getUserSession()->isLoggedIn()) {
- $view = new \OC\Files\View('/' . OC_User::getUser());
- if (!$view->file_exists($appId)) {
- $view->mkdir($appId);
- }
- return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
- } else {
- \OCP\Server::get(LoggerInterface::class)->error('Can\'t get app storage, app ' . $appId . ', user not logged in', ['app' => 'core']);
- return false;
- }
- } else {
- \OCP\Server::get(LoggerInterface::class)->error('Can\'t get app storage, app ' . $appId . ' not enabled', ['app' => 'core']);
- return false;
- }
- }
-
protected static function findBestL10NOption(array $options, string $lang): string {
// only a single option
if (isset($options['@value'])) {
diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php
index a89cbe1bb3a..172c865364c 100644
--- a/lib/private/legacy/OC_Helper.php
+++ b/lib/private/legacy/OC_Helper.php
@@ -39,75 +39,26 @@ class OC_Helper {
* Make a human file size
* @param int|float $bytes file size in bytes
* @return string a human readable file size
+ * @deprecated 4.0.0 replaced with \OCP\Util::humanFileSize
*
* Makes 2048 to 2 kB.
*/
public static function humanFileSize(int|float $bytes): string {
- if ($bytes < 0) {
- return '?';
- }
- if ($bytes < 1024) {
- return "$bytes B";
- }
- $bytes = round($bytes / 1024, 0);
- if ($bytes < 1024) {
- return "$bytes KB";
- }
- $bytes = round($bytes / 1024, 1);
- if ($bytes < 1024) {
- return "$bytes MB";
- }
- $bytes = round($bytes / 1024, 1);
- if ($bytes < 1024) {
- return "$bytes GB";
- }
- $bytes = round($bytes / 1024, 1);
- if ($bytes < 1024) {
- return "$bytes TB";
- }
-
- $bytes = round($bytes / 1024, 1);
- return "$bytes PB";
+ return \OCP\Util::humanFileSize($bytes);
}
/**
* Make a computer file size
* @param string $str file size in human readable format
* @return false|int|float a file size in bytes
+ * @deprecated 4.0.0 Use \OCP\Util::computerFileSize
*
* Makes 2kB to 2048.
*
* Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
*/
public static function computerFileSize(string $str): false|int|float {
- $str = strtolower($str);
- if (is_numeric($str)) {
- return Util::numericToNumber($str);
- }
-
- $bytes_array = [
- 'b' => 1,
- 'k' => 1024,
- 'kb' => 1024,
- 'mb' => 1024 * 1024,
- 'm' => 1024 * 1024,
- 'gb' => 1024 * 1024 * 1024,
- 'g' => 1024 * 1024 * 1024,
- 'tb' => 1024 * 1024 * 1024 * 1024,
- 't' => 1024 * 1024 * 1024 * 1024,
- 'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
- 'p' => 1024 * 1024 * 1024 * 1024 * 1024,
- ];
-
- $bytes = (float)$str;
-
- if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && isset($bytes_array[$matches[1]])) {
- $bytes *= $bytes_array[$matches[1]];
- } else {
- return false;
- }
-
- return Util::numericToNumber(round($bytes));
+ return \OCP\Util::computerFileSize($str);
}
/**
@@ -144,37 +95,10 @@ class OC_Helper {
* @param string $dir path to the folder
* @param bool $deleteSelf if set to false only the content of the folder will be deleted
* @return bool
+ * @deprecated 5.0.0 use \OCP\Files::rmdirr instead
*/
public static function rmdirr($dir, $deleteSelf = true) {
- if (is_dir($dir)) {
- $files = new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
- RecursiveIteratorIterator::CHILD_FIRST
- );
-
- foreach ($files as $fileInfo) {
- /** @var SplFileInfo $fileInfo */
- if ($fileInfo->isLink()) {
- unlink($fileInfo->getPathname());
- } elseif ($fileInfo->isDir()) {
- rmdir($fileInfo->getRealPath());
- } else {
- unlink($fileInfo->getRealPath());
- }
- }
- if ($deleteSelf) {
- rmdir($dir);
- }
- } elseif (file_exists($dir)) {
- if ($deleteSelf) {
- unlink($dir);
- }
- }
- if (!$deleteSelf) {
- return true;
- }
-
- return !file_exists($dir);
+ return \OCP\Files::rmdirr($dir, $deleteSelf);
}
/**
@@ -196,6 +120,7 @@ class OC_Helper {
* @internal param string $program name
* @internal param string $optional search path, defaults to $PATH
* @return bool true if executable program found in path
+ * @deprecated 32.0.0 use the \OCP\IBinaryFinder
*/
public static function canExecute($name, $path = false) {
// path defaults to PATH from environment if not set
diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php
index 580fec7b5b3..895cfba35c5 100644
--- a/lib/private/legacy/OC_Util.php
+++ b/lib/private/legacy/OC_Util.php
@@ -107,7 +107,7 @@ class OC_Util {
if ($userQuota === 'none') {
return \OCP\Files\FileInfo::SPACE_UNLIMITED;
}
- return OC_Helper::computerFileSize($userQuota);
+ return \OCP\Util::computerFileSize($userQuota);
}
/**
diff --git a/lib/public/Accounts/IAccountManager.php b/lib/public/Accounts/IAccountManager.php
index a15651eb5e6..92fc0002674 100644
--- a/lib/public/Accounts/IAccountManager.php
+++ b/lib/public/Accounts/IAccountManager.php
@@ -48,30 +48,6 @@ interface IAccountManager {
public const SCOPE_PUBLISHED = 'v2-published';
/**
- * Contact details only visible locally
- *
- * @since 15.0.0
- * @deprecated 21.0.1
- */
- public const VISIBILITY_PRIVATE = 'private';
-
- /**
- * Contact details visible on trusted federated servers.
- *
- * @since 15.0.0
- * @deprecated 21.0.1
- */
- public const VISIBILITY_CONTACTS_ONLY = 'contacts';
-
- /**
- * Contact details visible on trusted federated servers and in the public lookup server.
- *
- * @since 15.0.0
- * @deprecated 21.0.1
- */
- public const VISIBILITY_PUBLIC = 'public';
-
- /**
* The list of allowed scopes
*
* @since 25.0.0
@@ -81,9 +57,6 @@ interface IAccountManager {
self::SCOPE_LOCAL,
self::SCOPE_FEDERATED,
self::SCOPE_PUBLISHED,
- self::VISIBILITY_PRIVATE,
- self::VISIBILITY_CONTACTS_ONLY,
- self::VISIBILITY_PUBLIC,
];
/**
@@ -98,6 +71,7 @@ interface IAccountManager {
/**
* @since 27.0.0
+ * @deprecated 27.0.0 only added for backwards compatibility with provisioning_api UsersController::getCurrentUser
*/
public const PROPERTY_DISPLAYNAME_LEGACY = 'display-name';
diff --git a/lib/public/AppFramework/ApiController.php b/lib/public/AppFramework/ApiController.php
index dae80456e26..729582c8505 100644
--- a/lib/public/AppFramework/ApiController.php
+++ b/lib/public/AppFramework/ApiController.php
@@ -58,9 +58,8 @@ abstract class ApiController extends Controller {
#[PublicPage]
#[NoAdminRequired]
public function preflightedCors() {
- if (isset($this->request->server['HTTP_ORIGIN'])) {
- $origin = $this->request->server['HTTP_ORIGIN'];
- } else {
+ $origin = $this->request->getHeader('origin');
+ if ($origin === '') {
$origin = '*';
}
diff --git a/lib/public/AppFramework/App.php b/lib/public/AppFramework/App.php
index 06404baea70..6860de7c324 100644
--- a/lib/public/AppFramework/App.php
+++ b/lib/public/AppFramework/App.php
@@ -9,10 +9,9 @@ declare(strict_types=1);
*/
namespace OCP\AppFramework;
-use OC\AppFramework\Routing\RouteConfig;
-use OC\Route\Router;
use OC\ServerContainer;
-use OCP\Route\IRouter;
+use OCP\IConfig;
+use OCP\Server;
use Psr\Log\LoggerInterface;
/**
@@ -47,7 +46,7 @@ class App {
* @since 6.0.0
*/
public function __construct(string $appName, array $urlParams = []) {
- $runIsSetupDirectly = \OC::$server->getConfig()->getSystemValueBool('debug')
+ $runIsSetupDirectly = Server::get(IConfig::class)->getSystemValueBool('debug')
&& !ini_get('zend.exception_ignore_args');
if ($runIsSetupDirectly) {
@@ -74,7 +73,7 @@ class App {
}
if (!$setUpViaQuery && $applicationClassName !== \OCP\AppFramework\App::class) {
- \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), [
+ Server::get(LoggerInterface::class)->error($e->getMessage(), [
'app' => $appName,
'exception' => $e,
]);
@@ -97,35 +96,6 @@ class App {
}
/**
- * This function is to be called to create single routes and restful routes based on the given $routes array.
- *
- * Example code in routes.php of tasks app (it will register two restful resources):
- * $routes = array(
- * 'resources' => array(
- * 'lists' => array('url' => '/tasklists'),
- * 'tasks' => array('url' => '/tasklists/{listId}/tasks')
- * )
- * );
- *
- * $a = new TasksApp();
- * $a->registerRoutes($this, $routes);
- *
- * @param \OCP\Route\IRouter $router
- * @param array $routes
- * @since 6.0.0
- * @suppress PhanAccessMethodInternal
- * @deprecated 20.0.0 Just return an array from your routes.php
- */
- public function registerRoutes(IRouter $router, array $routes) {
- if (!($router instanceof Router)) {
- throw new \RuntimeException('Can only setup routes with real router');
- }
-
- $routeConfig = new RouteConfig($this->container, $router, $routes);
- $routeConfig->register();
- }
-
- /**
* This function is called by the routing component to fire up the frameworks dispatch mechanism.
*
* Example code in routes.php of the task app:
diff --git a/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php b/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php
index 1681b39ce50..0a0c04f671d 100644
--- a/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php
+++ b/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php
@@ -30,8 +30,7 @@ class RedirectToDefaultAppResponse extends RedirectResponse {
* @deprecated 23.0.0 Use RedirectResponse() with IURLGenerator::linkToDefaultPageUrl() instead
*/
public function __construct(int $status = Http::STATUS_SEE_OTHER, array $headers = []) {
- /** @var IURLGenerator $urlGenerator */
- $urlGenerator = \OC::$server->get(IURLGenerator::class);
+ $urlGenerator = \OCP\Server::get(IURLGenerator::class);
parent::__construct($urlGenerator->linkToDefaultPageUrl(), $status, $headers);
}
}
diff --git a/lib/public/AppFramework/Http/Response.php b/lib/public/AppFramework/Http/Response.php
index 6fc3d4b98ea..8037243d7a4 100644
--- a/lib/public/AppFramework/Http/Response.php
+++ b/lib/public/AppFramework/Http/Response.php
@@ -93,7 +93,6 @@ class Response {
// Set expires header
$expires = new \DateTime();
- /** @var ITimeFactory $time */
$time = \OCP\Server::get(ITimeFactory::class);
$expires->setTimestamp($time->getTime());
$expires->add(new \DateInterval('PT' . $cacheSeconds . 'S'));
@@ -184,10 +183,10 @@ class Response {
if ($this->status === Http::STATUS_NOT_MODIFIED
&& stripos($name, 'x-') === 0) {
/** @var IConfig $config */
- $config = \OC::$server->get(IConfig::class);
+ $config = \OCP\Server::get(IConfig::class);
if ($config->getSystemValueBool('debug', false)) {
- \OC::$server->get(LoggerInterface::class)->error('Setting custom header on a 304 is not supported (Header: {header})', [
+ \OCP\Server::get(LoggerInterface::class)->error('Setting custom header on a 304 is not supported (Header: {header})', [
'header' => $name,
]);
}
@@ -229,7 +228,7 @@ class Response {
/**
* @psalm-suppress UndefinedClass
*/
- $request = \OC::$server->get(IRequest::class);
+ $request = \OCP\Server::get(IRequest::class);
$mergeWith = [
'X-Request-Id' => $request->getId(),
'Cache-Control' => 'no-cache, no-store, must-revalidate',
diff --git a/lib/public/Defaults.php b/lib/public/Defaults.php
index 9242a230024..6de22caa41e 100644
--- a/lib/public/Defaults.php
+++ b/lib/public/Defaults.php
@@ -29,7 +29,7 @@ class Defaults {
*/
public function __construct(?\OC_Defaults $defaults = null) {
if ($defaults === null) {
- $defaults = \OC::$server->get('ThemingDefaults');
+ $defaults = \OCP\Server::get('ThemingDefaults');
}
$this->defaults = $defaults;
}
diff --git a/lib/public/Diagnostics/IQueryLogger.php b/lib/public/Diagnostics/IQueryLogger.php
index 1973168803d..07c999023da 100644
--- a/lib/public/Diagnostics/IQueryLogger.php
+++ b/lib/public/Diagnostics/IQueryLogger.php
@@ -31,7 +31,7 @@ interface IQueryLogger extends SQLLogger {
* Mark the end of the current active query. Ending query should store \OCP\Diagnostics\IQuery to
* be returned with getQueries() method.
*
- * @return mixed
+ * @return void
* @since 8.0.0
*/
public function stopQuery();
diff --git a/lib/public/EventDispatcher/GenericEvent.php b/lib/public/EventDispatcher/GenericEvent.php
index fb0a7677672..7e646c4d6a7 100644
--- a/lib/public/EventDispatcher/GenericEvent.php
+++ b/lib/public/EventDispatcher/GenericEvent.php
@@ -18,10 +18,12 @@ use function array_key_exists;
/**
* Class GenericEvent
*
- * convenience reimplementation of \Symfony\Component\GenericEvent against
+ * convenience re-implementation of \Symfony\Component\GenericEvent against
* \OCP\EventDispatcher\Event
*
* @since 18.0.0
+ * @template-implements ArrayAccess<array-key, mixed>
+ * @template-implements IteratorAggregate<array-key, mixed>
* @deprecated 22.0.0 use \OCP\EventDispatcher\Event
*/
class GenericEvent extends Event implements ArrayAccess, IteratorAggregate {
diff --git a/lib/public/Files.php b/lib/public/Files.php
index 62c41c4ada1..b12aa463f1a 100644
--- a/lib/public/Files.php
+++ b/lib/public/Files.php
@@ -9,6 +9,8 @@
namespace OCP;
+use OCP\Files\IMimeTypeDetector;
+
/**
* This class provides access to the internal filesystem abstraction layer. Use
* this class exclusively if you want to access files
@@ -18,12 +20,44 @@ namespace OCP;
class Files {
/**
* Recursive deletion of folders
+ *
+ * @param string $dir path to the folder
+ * @param bool $deleteSelf if set to false only the content of the folder will be deleted
* @return bool
* @since 5.0.0
+ * @since 32.0.0 added the $deleteSelf parameter
* @deprecated 14.0.0
*/
- public static function rmdirr($dir) {
- return \OC_Helper::rmdirr($dir);
+ public static function rmdirr($dir, bool $deleteSelf = true) {
+ if (is_dir($dir)) {
+ $files = new \RecursiveIteratorIterator(
+ new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
+ \RecursiveIteratorIterator::CHILD_FIRST
+ );
+
+ foreach ($files as $fileInfo) {
+ /** @var \SplFileInfo $fileInfo */
+ if ($fileInfo->isLink()) {
+ unlink($fileInfo->getPathname());
+ } elseif ($fileInfo->isDir()) {
+ rmdir($fileInfo->getRealPath());
+ } else {
+ unlink($fileInfo->getRealPath());
+ }
+ }
+ if ($deleteSelf) {
+ rmdir($dir);
+ }
+ } elseif (file_exists($dir)) {
+ if ($deleteSelf) {
+ unlink($dir);
+ }
+ }
+ if (!$deleteSelf) {
+ return true;
+ }
+
+ return !file_exists($dir);
}
/**
@@ -35,7 +69,7 @@ class Files {
* @deprecated 14.0.0
*/
public static function getMimeType($path) {
- return \OC::$server->getMimeTypeDetector()->detect($path);
+ return Server::get(IMimeTypeDetector::class)->detect($path);
}
/**
@@ -73,16 +107,4 @@ class Files {
public static function buildNotExistingFileName($path, $filename) {
return \OC_Helper::buildNotExistingFileName($path, $filename);
}
-
- /**
- * Gets the Storage for an app - creates the needed folder if they are not
- * existent
- * @param string $app
- * @return \OC\Files\View
- * @since 5.0.0
- * @deprecated 14.0.0 use IAppData instead
- */
- public static function getStorage($app) {
- return \OC_App::getStorage($app);
- }
}
diff --git a/lib/public/Files/IFilenameValidator.php b/lib/public/Files/IFilenameValidator.php
index 2bd3bb945dc..d8bd06d179d 100644
--- a/lib/public/Files/IFilenameValidator.php
+++ b/lib/public/Files/IFilenameValidator.php
@@ -36,4 +36,17 @@ interface IFilenameValidator {
* @since 30.0.0
*/
public function validateFilename(string $filename): void;
+
+ /**
+ * Sanitize a give filename to comply with admin setup naming constrains.
+ *
+ * If no sanitizing is needed the same name is returned.
+ *
+ * @param string $name The filename to sanitize
+ * @param null|string $charReplacement Character to use for replacing forbidden ones - by default space, dash or underscore is used if allowed.
+ * @throws \InvalidArgumentException if no character replacement was given (and the default could not be applied) or the replacement is not valid.
+ * @since 32.0.0
+ */
+ public function sanitizeFilename(string $name, ?string $charReplacement = null): string;
+
}
diff --git a/lib/public/Files/IMimeTypeDetector.php b/lib/public/Files/IMimeTypeDetector.php
index 1bc9c514610..1e87cf932ce 100644
--- a/lib/public/Files/IMimeTypeDetector.php
+++ b/lib/public/Files/IMimeTypeDetector.php
@@ -87,4 +87,12 @@ interface IMimeTypeDetector {
* @since 32.0.0
*/
public function getAllMappings(): array;
+
+ /**
+ * Get all human readable mime names
+ *
+ * @return array<string,string>
+ * @since 32.0.0
+ */
+ public function getAllNamings(): array;
}
diff --git a/lib/public/Files/SimpleFS/ISimpleFile.php b/lib/public/Files/SimpleFS/ISimpleFile.php
index 2682c22580d..10cdc0a919d 100644
--- a/lib/public/Files/SimpleFS/ISimpleFile.php
+++ b/lib/public/Files/SimpleFS/ISimpleFile.php
@@ -5,8 +5,10 @@
*/
namespace OCP\Files\SimpleFS;
+use OCP\Files\GenericFileException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\Lock\LockedException;
/**
* This interface allows to manage simple files.
@@ -49,8 +51,10 @@ interface ISimpleFile {
/**
* Get the content
*
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
* @since 11.0.0
*/
public function getContent(): string;
@@ -59,8 +63,10 @@ interface ISimpleFile {
* Overwrite the file
*
* @param string|resource $data
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
* @since 11.0.0
*/
public function putContent($data): void;
diff --git a/lib/public/Files_FullTextSearch/Model/AFilesDocument.php b/lib/public/Files_FullTextSearch/Model/AFilesDocument.php
index ba5f504fccf..297d6bc6ffc 100644
--- a/lib/public/Files_FullTextSearch/Model/AFilesDocument.php
+++ b/lib/public/Files_FullTextSearch/Model/AFilesDocument.php
@@ -16,7 +16,7 @@ use OCP\FullTextSearch\Model\IIndexDocument;
* This is mostly used by 3rd party apps that want to complete the IIndexDocument
* with more information about a file before its index:
*
- * \OC::$server->getEventDispatcher()->addListener(
+ * \OCP\Server::get(IEventDispatcher::class)->addListener(
* '\OCA\Files_FullTextSearch::onFileIndexing',
* function(GenericEvent $e) {
* //@var \OCP\Files\Node $file
diff --git a/lib/public/L10N/ILanguageIterator.php b/lib/public/L10N/ILanguageIterator.php
index cba0feefdcf..27f850d4235 100644
--- a/lib/public/L10N/ILanguageIterator.php
+++ b/lib/public/L10N/ILanguageIterator.php
@@ -21,7 +21,7 @@ namespace OCP\L10N;
* if settings are not present or truncating is not applicable, the iterator
* skips to the next valid item itself
*
- *
+ * @template-extends \Iterator<int, string>
* @since 14.0.0
*/
interface ILanguageIterator extends \Iterator {
@@ -36,22 +36,20 @@ interface ILanguageIterator extends \Iterator {
* Move forward to next element
*
* @since 14.0.0
- * @return void
*/
- #[\ReturnTypeWillChange]
- public function next();
+ public function next(): void;
/**
* Return the key of the current element
*
* @since 14.0.0
*/
- public function key():int;
+ public function key(): int;
/**
* Checks if current position is valid
*
* @since 14.0.0
*/
- public function valid():bool;
+ public function valid(): bool;
}
diff --git a/lib/public/Mail/IMailer.php b/lib/public/Mail/IMailer.php
index 18eaef541c0..277f7863184 100644
--- a/lib/public/Mail/IMailer.php
+++ b/lib/public/Mail/IMailer.php
@@ -14,7 +14,7 @@ namespace OCP\Mail;
*
* Example usage:
*
- * $mailer = \OC::$server->get(\OCP\Mail\IMailer::class);
+ * $mailer = \OCP\Server::get(\OCP\Mail\IMailer::class);
* $message = $mailer->createMessage();
* $message->setSubject('Your Subject');
* $message->setFrom(['cloud@domain.org' => 'Nextcloud Notifier']);
diff --git a/lib/public/Profiler/IProfile.php b/lib/public/Profiler/IProfile.php
index ddbad4b4388..89eb709d061 100644
--- a/lib/public/Profiler/IProfile.php
+++ b/lib/public/Profiler/IProfile.php
@@ -17,7 +17,7 @@ use OCP\DataCollector\IDataCollector;
*
* ```php
* <?php
- * $profiler = \OC::$server->get(IProfiler::class);
+ * $profiler = \OCP\Server::get(IProfiler::class);
* $profiles = $profiler->find('/settings/users', 10);
* ```
*
diff --git a/lib/public/Security/ICrypto.php b/lib/public/Security/ICrypto.php
index c2ba4cc9c97..78b0fc14d6d 100644
--- a/lib/public/Security/ICrypto.php
+++ b/lib/public/Security/ICrypto.php
@@ -13,8 +13,8 @@ namespace OCP\Security;
* it will use the secret defined in config.php as key. Additionally the message will be HMAC'd.
*
* Usage:
- * $encryptWithDefaultPassword = \OC::$server->getCrypto()->encrypt('EncryptedText');
- * $encryptWithCustomPassword = \OC::$server->getCrypto()->encrypt('EncryptedText', 'password');
+ * $encryptWithDefaultPassword = \OCP\Server::get(ICrypto::class)->encrypt('EncryptedText');
+ * $encryptWithCustomPassword = \OCP\Server::get(ICrypto::class)->encrypt('EncryptedText', 'password');
*
* @since 8.0.0
*/
diff --git a/lib/public/Security/IHasher.php b/lib/public/Security/IHasher.php
index d985ffe48ab..d0d6e4e9028 100644
--- a/lib/public/Security/IHasher.php
+++ b/lib/public/Security/IHasher.php
@@ -19,10 +19,10 @@ namespace OCP\Security;
*
* Usage:
* // Hashing a message
- * $hash = \OC::$server->get(\OCP\Security\IHasher::class)->hash('MessageToHash');
+ * $hash = \OCP\Server::get(\OCP\Security\IHasher::class)->hash('MessageToHash');
* // Verifying a message - $newHash will contain the newly calculated hash
* $newHash = null;
- * var_dump(\OC::$server->get(\OCP\Security\IHasher::class)->verify('a', '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', $newHash));
+ * var_dump(\OCP\Server::get(\OCP\Security\IHasher::class)->verify('a', '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', $newHash));
* var_dump($newHash);
*
* @since 8.0.0
diff --git a/lib/public/Security/ISecureRandom.php b/lib/public/Security/ISecureRandom.php
index aa191ca348f..0f4a79e08e0 100644
--- a/lib/public/Security/ISecureRandom.php
+++ b/lib/public/Security/ISecureRandom.php
@@ -14,7 +14,7 @@ namespace OCP\Security;
* use a fallback.
*
* Usage:
- * \OC::$server->get(ISecureRandom::class)->generate(10);
+ * \OCP\Server::get(ISecureRandom::class)->generate(10);
*
* @since 8.0.0
*/
diff --git a/lib/public/Template.php b/lib/public/Template.php
index 3b31ee10a54..715115bc635 100644
--- a/lib/public/Template.php
+++ b/lib/public/Template.php
@@ -77,7 +77,7 @@ class Template extends \OC_Template implements ITemplate {
}
/**
- * Make OC_Helper::humanFileSize available as a simple function
+ * Make \OCP\Util::humanFileSize available as a simple function
* Example: 2048 to 2 kB.
*
* @param int $bytes in bytes
diff --git a/lib/public/Util.php b/lib/public/Util.php
index 14663abd62f..979e7abe609 100644
--- a/lib/public/Util.php
+++ b/lib/public/Util.php
@@ -51,7 +51,7 @@ class Util {
return $subscriptionRegistry->delegateHasExtendedSupport();
} catch (ContainerExceptionInterface $e) {
}
- return \OC::$server->getConfig()->getSystemValueBool('extendedSupport', false);
+ return \OCP\Server::get(IConfig::class)->getSystemValueBool('extendedSupport', false);
}
/**
@@ -60,7 +60,7 @@ class Util {
* @since 8.1.0
*/
public static function setChannel($channel) {
- \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel);
+ \OCP\Server::get(IConfig::class)->setSystemValue('updater.release.channel', $channel);
}
/**
@@ -182,7 +182,7 @@ class Util {
*/
public static function getScripts(): array {
// Sort scriptDeps into sortedScriptDeps
- $scriptSort = \OC::$server->get(AppScriptSort::class);
+ $scriptSort = \OCP\Server::get(AppScriptSort::class);
$sortedScripts = $scriptSort->sort(self::$scripts, self::$scriptDeps);
// Flatten array and remove duplicates
@@ -209,7 +209,7 @@ class Util {
*/
public static function addTranslations($application, $languageCode = null, $init = false) {
if (is_null($languageCode)) {
- $languageCode = \OC::$server->get(IFactory::class)->findLanguage($application);
+ $languageCode = \OCP\Server::get(IFactory::class)->findLanguage($application);
}
if (!empty($application)) {
$path = "$application/l10n/$languageCode";
@@ -247,7 +247,7 @@ class Util {
* @since 4.0.0 - parameter $args was added in 4.5.0
*/
public static function linkToAbsolute($app, $file, $args = []) {
- $urlGenerator = \OC::$server->getURLGenerator();
+ $urlGenerator = \OCP\Server::get(IURLGenerator::class);
return $urlGenerator->getAbsoluteURL(
$urlGenerator->linkTo($app, $file, $args)
);
@@ -260,7 +260,7 @@ class Util {
* @since 4.0.0
*/
public static function linkToRemote($service) {
- $urlGenerator = \OC::$server->getURLGenerator();
+ $urlGenerator = \OCP\Server::get(IURLGenerator::class);
$remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service;
return $urlGenerator->getAbsoluteURL(
$remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '')
@@ -273,7 +273,7 @@ class Util {
* @since 5.0.0
*/
public static function getServerHostName() {
- $host_name = \OC::$server->getRequest()->getServerHost();
+ $host_name = \OCP\Server::get(IRequest::class)->getServerHost();
// strip away port number (if existing)
$colon_pos = strpos($host_name, ':');
if ($colon_pos != false) {
@@ -299,13 +299,13 @@ class Util {
* @since 5.0.0
*/
public static function getDefaultEmailAddress(string $user_part): string {
- $config = \OC::$server->getConfig();
+ $config = \OCP\Server::get(IConfig::class);
$user_part = $config->getSystemValueString('mail_from_address', $user_part);
$host_name = self::getServerHostName();
$host_name = $config->getSystemValueString('mail_domain', $host_name);
$defaultEmailAddress = $user_part . '@' . $host_name;
- $mailer = \OC::$server->get(IMailer::class);
+ $mailer = \OCP\Server::get(IMailer::class);
if ($mailer->validateMailAddress($defaultEmailAddress)) {
return $defaultEmailAddress;
}
@@ -332,19 +332,70 @@ class Util {
* @since 4.0.0
*/
public static function humanFileSize(int|float $bytes): string {
- return \OC_Helper::humanFileSize($bytes);
+ if ($bytes < 0) {
+ return '?';
+ }
+ if ($bytes < 1024) {
+ return "$bytes B";
+ }
+ $bytes = round($bytes / 1024, 0);
+ if ($bytes < 1024) {
+ return "$bytes KB";
+ }
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes MB";
+ }
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes GB";
+ }
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes TB";
+ }
+
+ $bytes = round($bytes / 1024, 1);
+ return "$bytes PB";
}
/**
* Make a computer file size (2 kB to 2048)
+ * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
+ *
* @param string $str file size in a fancy format
* @return false|int|float a file size in bytes
- *
- * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
* @since 4.0.0
*/
public static function computerFileSize(string $str): false|int|float {
- return \OC_Helper::computerFileSize($str);
+ $str = strtolower($str);
+ if (is_numeric($str)) {
+ return Util::numericToNumber($str);
+ }
+
+ $bytes_array = [
+ 'b' => 1,
+ 'k' => 1024,
+ 'kb' => 1024,
+ 'mb' => 1024 * 1024,
+ 'm' => 1024 * 1024,
+ 'gb' => 1024 * 1024 * 1024,
+ 'g' => 1024 * 1024 * 1024,
+ 'tb' => 1024 * 1024 * 1024 * 1024,
+ 't' => 1024 * 1024 * 1024 * 1024,
+ 'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
+ 'p' => 1024 * 1024 * 1024 * 1024 * 1024,
+ ];
+
+ $bytes = (float)$str;
+
+ if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && isset($bytes_array[$matches[1]])) {
+ $bytes *= $bytes_array[$matches[1]];
+ } else {
+ return false;
+ }
+
+ return Util::numericToNumber(round($bytes));
}
/**
@@ -396,7 +447,7 @@ class Util {
*/
public static function callRegister() {
if (self::$token === '') {
- self::$token = \OC::$server->get(CsrfTokenManager::class)->getToken()->getEncryptedValue();
+ self::$token = \OCP\Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue();
}
return self::$token;
}
@@ -531,7 +582,7 @@ class Util {
*/
public static function needUpgrade() {
if (!isset(self::$needUpgradeCache)) {
- self::$needUpgradeCache = \OC_Util::needUpgrade(\OC::$server->getSystemConfig());
+ self::$needUpgradeCache = \OC_Util::needUpgrade(\OCP\Server::get(\OC\SystemConfig::class));
}
return self::$needUpgradeCache;
}