diff options
Diffstat (limited to 'lib')
129 files changed, 1255 insertions, 1765 deletions
diff --git a/lib/base.php b/lib/base.php index cd9f4fc2478..82dcd5965aa 100644 --- a/lib/base.php +++ b/lib/base.php @@ -299,8 +299,8 @@ class OC { // render error page $template = new OC_Template('', 'update.user', 'guest'); - OC_Util::addScript('maintenance'); - OC_Util::addStyle('core', 'guest'); + \OCP\Util::addScript('core', 'maintenance'); + \OCP\Util::addStyle('core', 'guest'); $template->printPage(); die(); } @@ -597,12 +597,7 @@ class OC { $eventLogger = \OC::$server->getEventLogger(); $eventLogger->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd); - $eventLogger->start('request', 'Full request after autoloading'); - register_shutdown_function(function () use ($eventLogger) { - $eventLogger->end('request'); - }); $eventLogger->start('boot', 'Initialize'); - $eventLogger->start('runtime', 'Runtime (total - autoloader)'); // Override php.ini and log everything if we're troubleshooting if (self::$config->getValue('loglevel') === ILogger::DEBUG) { @@ -617,16 +612,23 @@ class OC { throw new \RuntimeException('Could not set timezone to UTC'); } + //try to configure php to enable big file uploads. - //this doesn´t work always depending on the web server and php configuration. - //Let´s try to overwrite some defaults anyway + //this doesn´t work always depending on the webserver and php configuration. + //Let´s try to overwrite some defaults if they are smaller than 1 hour + + if (intval(@ini_get('max_execution_time') ?? 0) < 3600) { + @ini_set('max_execution_time', strval(3600)); + } - //try to set the maximum execution time to 60min + if (intval(@ini_get('max_input_time') ?? 0) < 3600) { + @ini_set('max_input_time', strval(3600)); + } + + //try to set the maximum execution time to the largest time limit we have if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { - @set_time_limit(3600); + @set_time_limit(max(intval(@ini_get('max_execution_time')), intval(@ini_get('max_input_time')))); } - @ini_set('max_execution_time', '3600'); - @ini_set('max_input_time', '3600'); self::handleAuthHeaders(); $systemConfig = \OC::$server->get(\OC\SystemConfig::class); @@ -799,6 +801,11 @@ class OC { } $eventLogger->end('boot'); $eventLogger->log('init', 'OC::init', $loaderStart, microtime(true)); + $eventLogger->start('runtime', 'Runtime'); + $eventLogger->start('request', 'Full request after boot'); + register_shutdown_function(function () use ($eventLogger) { + $eventLogger->end('request'); + }); } /** diff --git a/lib/composer/autoload.php b/lib/composer/autoload.php index a3d144b1777..fe5311f43f1 100644 --- a/lib/composer/autoload.php +++ b/lib/composer/autoload.php @@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) { require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c::getLoader(); +return ComposerAutoloaderInit749170dad3f5e7f9ca158f5a9f04f6a2::getLoader(); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 96666ee6021..ae80dc78b03 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -161,6 +161,8 @@ return array( 'OCP\\Comments\\IllegalIDChangeException' => $baseDir . '/lib/public/Comments/IllegalIDChangeException.php', 'OCP\\Comments\\MessageTooLongException' => $baseDir . '/lib/public/Comments/MessageTooLongException.php', 'OCP\\Comments\\NotFoundException' => $baseDir . '/lib/public/Comments/NotFoundException.php', + 'OCP\\Config\\BeforePreferenceDeletedEvent' => $baseDir . '/lib/public/Config/BeforePreferenceDeletedEvent.php', + 'OCP\\Config\\BeforePreferenceSetEvent' => $baseDir . '/lib/public/Config/BeforePreferenceSetEvent.php', 'OCP\\Console\\ConsoleEvent' => $baseDir . '/lib/public/Console/ConsoleEvent.php', 'OCP\\Constants' => $baseDir . '/lib/public/Constants.php', 'OCP\\Contacts\\ContactsMenu\\IAction' => $baseDir . '/lib/public/Contacts/ContactsMenu/IAction.php', @@ -237,6 +239,7 @@ return array( 'OCP\\Federation\\ICloudIdManager' => $baseDir . '/lib/public/Federation/ICloudIdManager.php', 'OCP\\Files' => $baseDir . '/lib/public/Files.php', 'OCP\\Files\\AlreadyExistsException' => $baseDir . '/lib/public/Files/AlreadyExistsException.php', + 'OCP\\Files\\AppData\\IAppDataFactory' => $baseDir . '/lib/public/Files/AppData/IAppDataFactory.php', 'OCP\\Files\\Cache\\AbstractCacheEvent' => $baseDir . '/lib/public/Files/Cache/AbstractCacheEvent.php', 'OCP\\Files\\Cache\\CacheEntryInsertedEvent' => $baseDir . '/lib/public/Files/Cache/CacheEntryInsertedEvent.php', 'OCP\\Files\\Cache\\CacheEntryRemovedEvent' => $baseDir . '/lib/public/Files/Cache/CacheEntryRemovedEvent.php', @@ -1528,7 +1531,6 @@ return array( 'OC\\Template\\JSResourceLocator' => $baseDir . '/lib/private/Template/JSResourceLocator.php', 'OC\\Template\\ResourceLocator' => $baseDir . '/lib/private/Template/ResourceLocator.php', 'OC\\Template\\ResourceNotFoundException' => $baseDir . '/lib/private/Template/ResourceNotFoundException.php', - 'OC\\Template\\SCSSCacher' => $baseDir . '/lib/private/Template/SCSSCacher.php', 'OC\\Template\\TemplateFileLocator' => $baseDir . '/lib/private/Template/TemplateFileLocator.php', 'OC\\URLGenerator' => $baseDir . '/lib/private/URLGenerator.php', 'OC\\Updater' => $baseDir . '/lib/private/Updater.php', diff --git a/lib/composer/composer/autoload_real.php b/lib/composer/composer/autoload_real.php index eecff48bcf9..27e0b34bf5b 100644 --- a/lib/composer/composer/autoload_real.php +++ b/lib/composer/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c +class ComposerAutoloaderInit749170dad3f5e7f9ca158f5a9f04f6a2 { private static $loader; @@ -22,12 +22,12 @@ class ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit749170dad3f5e7f9ca158f5a9f04f6a2', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit53792487c5a8370acc0b06b1a864ff4c', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit749170dad3f5e7f9ca158f5a9f04f6a2', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2::getInitializer($loader)); $loader->register(true); diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index ddea8460724..327c44a739c 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c +class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 { public static $prefixLengthsPsr4 = array ( 'O' => @@ -190,6 +190,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Comments\\IllegalIDChangeException' => __DIR__ . '/../../..' . '/lib/public/Comments/IllegalIDChangeException.php', 'OCP\\Comments\\MessageTooLongException' => __DIR__ . '/../../..' . '/lib/public/Comments/MessageTooLongException.php', 'OCP\\Comments\\NotFoundException' => __DIR__ . '/../../..' . '/lib/public/Comments/NotFoundException.php', + 'OCP\\Config\\BeforePreferenceDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Config/BeforePreferenceDeletedEvent.php', + 'OCP\\Config\\BeforePreferenceSetEvent' => __DIR__ . '/../../..' . '/lib/public/Config/BeforePreferenceSetEvent.php', 'OCP\\Console\\ConsoleEvent' => __DIR__ . '/../../..' . '/lib/public/Console/ConsoleEvent.php', 'OCP\\Constants' => __DIR__ . '/../../..' . '/lib/public/Constants.php', 'OCP\\Contacts\\ContactsMenu\\IAction' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/IAction.php', @@ -266,6 +268,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Federation\\ICloudIdManager' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudIdManager.php', 'OCP\\Files' => __DIR__ . '/../../..' . '/lib/public/Files.php', 'OCP\\Files\\AlreadyExistsException' => __DIR__ . '/../../..' . '/lib/public/Files/AlreadyExistsException.php', + 'OCP\\Files\\AppData\\IAppDataFactory' => __DIR__ . '/../../..' . '/lib/public/Files/AppData/IAppDataFactory.php', 'OCP\\Files\\Cache\\AbstractCacheEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/AbstractCacheEvent.php', 'OCP\\Files\\Cache\\CacheEntryInsertedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/CacheEntryInsertedEvent.php', 'OCP\\Files\\Cache\\CacheEntryRemovedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/CacheEntryRemovedEvent.php', @@ -1557,7 +1560,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Template\\JSResourceLocator' => __DIR__ . '/../../..' . '/lib/private/Template/JSResourceLocator.php', 'OC\\Template\\ResourceLocator' => __DIR__ . '/../../..' . '/lib/private/Template/ResourceLocator.php', 'OC\\Template\\ResourceNotFoundException' => __DIR__ . '/../../..' . '/lib/private/Template/ResourceNotFoundException.php', - 'OC\\Template\\SCSSCacher' => __DIR__ . '/../../..' . '/lib/private/Template/SCSSCacher.php', 'OC\\Template\\TemplateFileLocator' => __DIR__ . '/../../..' . '/lib/private/Template/TemplateFileLocator.php', 'OC\\URLGenerator' => __DIR__ . '/../../..' . '/lib/private/URLGenerator.php', 'OC\\Updater' => __DIR__ . '/../../..' . '/lib/private/Updater.php', @@ -1597,10 +1599,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c::$prefixDirsPsr4; - $loader->fallbackDirsPsr4 = ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c::$fallbackDirsPsr4; - $loader->classMap = ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2::$prefixDirsPsr4; + $loader->fallbackDirsPsr4 = ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2::$fallbackDirsPsr4; + $loader->classMap = ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2::$classMap; }, null, ClassLoader::class); } diff --git a/lib/composer/composer/installed.php b/lib/composer/composer/installed.php index 02fc1718d41..1f382499aeb 100644 --- a/lib/composer/composer/installed.php +++ b/lib/composer/composer/installed.php @@ -1,22 +1,22 @@ <?php return array( 'root' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../../../', 'aliases' => array(), - 'reference' => '4f4f8cea83a31519e55b6305c6d9471896de42be', + 'reference' => NULL, 'name' => '__root__', 'dev' => false, ), 'versions' => array( '__root__' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../../../', 'aliases' => array(), - 'reference' => '4f4f8cea83a31519e55b6305c6d9471896de42be', + 'reference' => NULL, 'dev_requirement' => false, ), ), diff --git a/lib/l10n/es.js b/lib/l10n/es.js index 52b3902e16f..8506e617bf0 100644 --- a/lib/l10n/es.js +++ b/lib/l10n/es.js @@ -58,20 +58,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["dentro de %n dÃa","dentro de %n dÃas"], - "_%n day ago_::_%n days ago_" : ["Hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["dentro de %n dÃa","dentro de %n dÃas","dentro de %n dÃas"], + "_%n day ago_::_%n days ago_" : ["Hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "mes siguiente", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["dentro de %n mes","dentro de %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","hace %n meses"], + "_in %n month_::_in %n months_" : ["dentro de %n mes","dentro de %n meses","dentro de %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","hace %n meses","hace %n meses"], "next year" : "año que viene", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["dentro de %n año","dentro de %n años"], - "_%n year ago_::_%n years ago_" : ["Hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","hace %n minutos"], + "_in %n year_::_in %n years_" : ["dentro de %n año","dentro de %n años","dentro de %n años"], + "_%n year ago_::_%n years ago_" : ["Hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas","dentro de %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","hace %n horas","hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos","dentro de %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","hace %n minutos","hace %n minutos"], "in a few seconds" : "en unos segundos", "seconds ago" : "hace segundos", "Empty file" : "Archivo vacÃo", @@ -140,7 +140,7 @@ OC.L10N.register( "Files cannot be shared with delete permissions" : "Los archivos no se pueden compartir con permisos de borrado", "Files cannot be shared with create permissions" : "Los archivos no se pueden compartir con permisos de creación", "Expiration date is in the past" : "Ha pasado la fecha de caducidad", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["No se puede fijar la fecha de caducidad más de %n dÃa en el futuro.","No se puede fijar la fecha de caducidad más de %n dÃas en el futuro."], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["No se puede fijar la fecha de caducidad más de %n dÃa en el futuro.","No se puede fijar la fecha de caducidad más de %n dÃas en el futuro.","No se puede fijar la fecha de caducidad más de %n dÃas en el futuro."], "Sharing is only allowed with group members" : "Sólo está permitido compartir a los integrantes del grupo", "Sharing %s failed, because this item is already shared with user %s" : "No se pudo compartir %s, porque este elemento ya está compartido con el usuario %s", "%1$s shared »%2$s« with you" : "%1$s ha compartido «%2$s» contigo", @@ -273,4 +273,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Compruebe el valor de \"datadirectory\" en su configuración.", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es.json b/lib/l10n/es.json index ab972b7a7d4..988d95cc7e5 100644 --- a/lib/l10n/es.json +++ b/lib/l10n/es.json @@ -56,20 +56,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["dentro de %n dÃa","dentro de %n dÃas"], - "_%n day ago_::_%n days ago_" : ["Hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["dentro de %n dÃa","dentro de %n dÃas","dentro de %n dÃas"], + "_%n day ago_::_%n days ago_" : ["Hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "mes siguiente", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["dentro de %n mes","dentro de %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","hace %n meses"], + "_in %n month_::_in %n months_" : ["dentro de %n mes","dentro de %n meses","dentro de %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","hace %n meses","hace %n meses"], "next year" : "año que viene", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["dentro de %n año","dentro de %n años"], - "_%n year ago_::_%n years ago_" : ["Hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","hace %n minutos"], + "_in %n year_::_in %n years_" : ["dentro de %n año","dentro de %n años","dentro de %n años"], + "_%n year ago_::_%n years ago_" : ["Hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas","dentro de %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","hace %n horas","hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos","dentro de %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","hace %n minutos","hace %n minutos"], "in a few seconds" : "en unos segundos", "seconds ago" : "hace segundos", "Empty file" : "Archivo vacÃo", @@ -138,7 +138,7 @@ "Files cannot be shared with delete permissions" : "Los archivos no se pueden compartir con permisos de borrado", "Files cannot be shared with create permissions" : "Los archivos no se pueden compartir con permisos de creación", "Expiration date is in the past" : "Ha pasado la fecha de caducidad", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["No se puede fijar la fecha de caducidad más de %n dÃa en el futuro.","No se puede fijar la fecha de caducidad más de %n dÃas en el futuro."], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["No se puede fijar la fecha de caducidad más de %n dÃa en el futuro.","No se puede fijar la fecha de caducidad más de %n dÃas en el futuro.","No se puede fijar la fecha de caducidad más de %n dÃas en el futuro."], "Sharing is only allowed with group members" : "Sólo está permitido compartir a los integrantes del grupo", "Sharing %s failed, because this item is already shared with user %s" : "No se pudo compartir %s, porque este elemento ya está compartido con el usuario %s", "%1$s shared »%2$s« with you" : "%1$s ha compartido «%2$s» contigo", @@ -270,5 +270,5 @@ "Your data directory must be an absolute path" : "Su directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Compruebe el valor de \"datadirectory\" en su configuración.", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_419.js b/lib/l10n/es_419.js index 4dd8bd93c30..b483e623154 100644 --- a/lib/l10n/es_419.js +++ b/lib/l10n/es_419.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_419.json b/lib/l10n/es_419.json index 58e7959cca4..d05cc6895aa 100644 --- a/lib/l10n/es_419.json +++ b/lib/l10n/es_419.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_AR.js b/lib/l10n/es_AR.js index 2ac8cc15e4e..dd2a959c33b 100644 --- a/lib/l10n/es_AR.js +++ b/lib/l10n/es_AR.js @@ -25,13 +25,13 @@ OC.L10N.register( "Avatar image is not square" : "La imagen del avatar no es un cuadrado", "today" : "hoy", "yesterday" : "ayer", - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "last month" : "mes pasado", - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "last year" : "año pasado", - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Favor de habilitarlo en sus configuraciones de aplicación o contacte a su administrador. ", "File name is a reserved word" : "Nombre de archivo es una palabra reservada", @@ -175,4 +175,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifique el valor de \"datadirectory\" en su configuración", "Your data directory is invalid" : "Su directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_AR.json b/lib/l10n/es_AR.json index fd497701b36..4d7ea16672f 100644 --- a/lib/l10n/es_AR.json +++ b/lib/l10n/es_AR.json @@ -23,13 +23,13 @@ "Avatar image is not square" : "La imagen del avatar no es un cuadrado", "today" : "hoy", "yesterday" : "ayer", - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "last month" : "mes pasado", - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "last year" : "año pasado", - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Favor de habilitarlo en sus configuraciones de aplicación o contacte a su administrador. ", "File name is a reserved word" : "Nombre de archivo es una palabra reservada", @@ -172,5 +172,5 @@ "Your data directory must be an absolute path" : "Su direcctorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifique el valor de \"datadirectory\" en su configuración", "Your data directory is invalid" : "Su directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_CL.js b/lib/l10n/es_CL.js index ad95ed44897..3762954bc8f 100644 --- a/lib/l10n/es_CL.js +++ b/lib/l10n/es_CL.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_CL.json b/lib/l10n/es_CL.json index e996e30e807..5ba63a54295 100644 --- a/lib/l10n/es_CL.json +++ b/lib/l10n/es_CL.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_CO.js b/lib/l10n/es_CO.js index 8838bfab177..91ee8fedd38 100644 --- a/lib/l10n/es_CO.js +++ b/lib/l10n/es_CO.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_CO.json b/lib/l10n/es_CO.json index 99218d58628..ea7ef3ec112 100644 --- a/lib/l10n/es_CO.json +++ b/lib/l10n/es_CO.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_CR.js b/lib/l10n/es_CR.js index 0d8294160ef..c049eb26853 100644 --- a/lib/l10n/es_CR.js +++ b/lib/l10n/es_CR.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_CR.json b/lib/l10n/es_CR.json index 93d7c533a73..2a3bb425cfd 100644 --- a/lib/l10n/es_CR.json +++ b/lib/l10n/es_CR.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_DO.js b/lib/l10n/es_DO.js index 8dee29ff4cd..0aea42a6656 100644 --- a/lib/l10n/es_DO.js +++ b/lib/l10n/es_DO.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_DO.json b/lib/l10n/es_DO.json index 7e0dd5f06bd..08fda06066c 100644 --- a/lib/l10n/es_DO.json +++ b/lib/l10n/es_DO.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_EC.js b/lib/l10n/es_EC.js index 34b163fa9e2..5a2b63b9aff 100644 --- a/lib/l10n/es_EC.js +++ b/lib/l10n/es_EC.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_EC.json b/lib/l10n/es_EC.json index 903df1d2dda..6fcd9e0468e 100644 --- a/lib/l10n/es_EC.json +++ b/lib/l10n/es_EC.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_GT.js b/lib/l10n/es_GT.js index f029d14ad40..24d85bc24cd 100644 --- a/lib/l10n/es_GT.js +++ b/lib/l10n/es_GT.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_GT.json b/lib/l10n/es_GT.json index fe49e40a39f..de5c6d6638d 100644 --- a/lib/l10n/es_GT.json +++ b/lib/l10n/es_GT.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_HN.js b/lib/l10n/es_HN.js index bbc3e0bd6c1..e2af5b57461 100644 --- a/lib/l10n/es_HN.js +++ b/lib/l10n/es_HN.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_HN.json b/lib/l10n/es_HN.json index bd48a18b3c4..ebbdbdf588d 100644 --- a/lib/l10n/es_HN.json +++ b/lib/l10n/es_HN.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_MX.js b/lib/l10n/es_MX.js index d4156f349fa..2693ae01512 100644 --- a/lib/l10n/es_MX.js +++ b/lib/l10n/es_MX.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_MX.json b/lib/l10n/es_MX.json index 69b7d9014f5..2beebf60c3f 100644 --- a/lib/l10n/es_MX.json +++ b/lib/l10n/es_MX.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_NI.js b/lib/l10n/es_NI.js index 8fcf7aa15ad..051762ee07c 100644 --- a/lib/l10n/es_NI.js +++ b/lib/l10n/es_NI.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_NI.json b/lib/l10n/es_NI.json index 272097aea29..0095526e3a3 100644 --- a/lib/l10n/es_NI.json +++ b/lib/l10n/es_NI.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_PA.js b/lib/l10n/es_PA.js index 7bb2cd2cde7..6a97d9115ea 100644 --- a/lib/l10n/es_PA.js +++ b/lib/l10n/es_PA.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_PA.json b/lib/l10n/es_PA.json index 13b17f37b5f..cae1186af7b 100644 --- a/lib/l10n/es_PA.json +++ b/lib/l10n/es_PA.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_PE.js b/lib/l10n/es_PE.js index 217f458ecb4..67e7dc14095 100644 --- a/lib/l10n/es_PE.js +++ b/lib/l10n/es_PE.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_PE.json b/lib/l10n/es_PE.json index bdaaab523fa..737f934d10a 100644 --- a/lib/l10n/es_PE.json +++ b/lib/l10n/es_PE.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_PR.js b/lib/l10n/es_PR.js index 1526c425fb0..2af553a2f58 100644 --- a/lib/l10n/es_PR.js +++ b/lib/l10n/es_PR.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_PR.json b/lib/l10n/es_PR.json index f325d0c98b0..620eeb7c134 100644 --- a/lib/l10n/es_PR.json +++ b/lib/l10n/es_PR.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_PY.js b/lib/l10n/es_PY.js index f7bafd23ddc..26a1fdbfb3e 100644 --- a/lib/l10n/es_PY.js +++ b/lib/l10n/es_PY.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_PY.json b/lib/l10n/es_PY.json index 4f4378b9e2d..64b9486042c 100644 --- a/lib/l10n/es_PY.json +++ b/lib/l10n/es_PY.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_SV.js b/lib/l10n/es_SV.js index 2ac7487e946..bd67423a4f2 100644 --- a/lib/l10n/es_SV.js +++ b/lib/l10n/es_SV.js @@ -28,20 +28,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -190,4 +190,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=2; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_SV.json b/lib/l10n/es_SV.json index ff98ae2fd25..67f776a0276 100644 --- a/lib/l10n/es_SV.json +++ b/lib/l10n/es_SV.json @@ -26,20 +26,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -187,5 +187,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=2; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/es_UY.js b/lib/l10n/es_UY.js index ac274bd7964..dc99fd41307 100644 --- a/lib/l10n/es_UY.js +++ b/lib/l10n/es_UY.js @@ -27,20 +27,20 @@ OC.L10N.register( "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -189,4 +189,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/es_UY.json b/lib/l10n/es_UY.json index 57fe8a5fe94..47fed462c2f 100644 --- a/lib/l10n/es_UY.json +++ b/lib/l10n/es_UY.json @@ -25,20 +25,20 @@ "today" : "hoy", "tomorrow" : "mañana", "yesterday" : "ayer", - "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas"], - "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas"], + "_in %n day_::_in %n days_" : ["en %n dÃa","en %n dÃas","en %n dÃas"], + "_%n day ago_::_%n days ago_" : ["hace %n dÃa","hace %n dÃas","hace %n dÃas"], "next month" : "próximo mes", "last month" : "mes pasado", - "_in %n month_::_in %n months_" : ["en %n mes","en %n meses"], - "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses"], + "_in %n month_::_in %n months_" : ["en %n mes","en %n meses","en %n meses"], + "_%n month ago_::_%n months ago_" : ["Hace %n mes","Hace %n meses","Hace %n meses"], "next year" : "próximo año", "last year" : "año pasado", - "_in %n year_::_in %n years_" : ["en %n año","en %n años"], - "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años"], - "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas"], - "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas"], - "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"], + "_in %n year_::_in %n years_" : ["en %n año","en %n años","en %n años"], + "_%n year ago_::_%n years ago_" : ["hace %n año","hace %n años","hace %n años"], + "_in %n hour_::_in %n hours_" : ["en %n hora","en %n horas","en %n horas"], + "_%n hour ago_::_%n hours ago_" : ["Hace %n hora","Hace %n horas","Hace %n horas"], + "_in %n minute_::_in %n minutes_" : ["en %n minuto","en %n minutos","en %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos","Hace %n minutos"], "in a few seconds" : "en algunos segundos", "seconds ago" : "hace segundos", "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "El módulo con ID: %sno existe. Por favor hablÃitalo en tus configuraciones de aplicación o contacta a tu administrador. ", @@ -186,5 +186,5 @@ "Your data directory must be an absolute path" : "Tu directorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifica el valor de \"datadirectory\" en tu configuración", "Your data directory is invalid" : "Tu directorio de datos es inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/eu.js b/lib/l10n/eu.js index 232592ad6e3..ffe6d4d8808 100644 --- a/lib/l10n/eu.js +++ b/lib/l10n/eu.js @@ -235,6 +235,8 @@ OC.L10N.register( "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Hau ziur aski cache/accelerator batek eragin du, hala nola Zend OPcache edo eAccelerator.", "PHP modules have been installed, but they are still listed as missing?" : "PHP moduluak instalatu dira, baina oraindik faltan bezala markatuta daude?", "Please ask your server administrator to restart the web server." : "Mesedez eskatu zerbitzariaren kudeatzaileari web zerbitzaria berrabiarazteko.", + "The required %s config variable is not configured in the config.php file." : "Beharrezko %s config aldagaia ez dago konfiguratuta config.php fitxategian.", + "Please ask your server administrator to check the Nextcloud configuration." : "Mesedez, eskatu zure zerbitzari-administratzaileari Nextcloud-en konfigurazioa egiaztatzeko.", "PostgreSQL >= 9 required." : "PostgreSQL >= 9 behar da", "Please upgrade your database version." : "Mesedez eguneratu zure datu-basearen bertsioa.", "Your data directory is readable by other users." : "Zure datuen karpeta beste erabiltzaileek irakur dezakete.", diff --git a/lib/l10n/eu.json b/lib/l10n/eu.json index 3a5e2d9e84c..98461448e2d 100644 --- a/lib/l10n/eu.json +++ b/lib/l10n/eu.json @@ -233,6 +233,8 @@ "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Hau ziur aski cache/accelerator batek eragin du, hala nola Zend OPcache edo eAccelerator.", "PHP modules have been installed, but they are still listed as missing?" : "PHP moduluak instalatu dira, baina oraindik faltan bezala markatuta daude?", "Please ask your server administrator to restart the web server." : "Mesedez eskatu zerbitzariaren kudeatzaileari web zerbitzaria berrabiarazteko.", + "The required %s config variable is not configured in the config.php file." : "Beharrezko %s config aldagaia ez dago konfiguratuta config.php fitxategian.", + "Please ask your server administrator to check the Nextcloud configuration." : "Mesedez, eskatu zure zerbitzari-administratzaileari Nextcloud-en konfigurazioa egiaztatzeko.", "PostgreSQL >= 9 required." : "PostgreSQL >= 9 behar da", "Please upgrade your database version." : "Mesedez eguneratu zure datu-basearen bertsioa.", "Your data directory is readable by other users." : "Zure datuen karpeta beste erabiltzaileek irakur dezakete.", diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js index de641540de1..7a40ad0a772 100644 --- a/lib/l10n/fr.js +++ b/lib/l10n/fr.js @@ -58,20 +58,20 @@ OC.L10N.register( "today" : "aujourd'hui", "tomorrow" : "demain", "yesterday" : "hier", - "_in %n day_::_in %n days_" : ["dans %n jour","dans %n jours"], - "_%n day ago_::_%n days ago_" : ["il y a %n jour","il y a %n jours"], + "_in %n day_::_in %n days_" : ["dans %n jour","dans %n jours","dans %n jours"], + "_%n day ago_::_%n days ago_" : ["il y a %n jour","il y a %n jours","il y a %n jours"], "next month" : "mois suivant", "last month" : "le mois dernier", - "_in %n month_::_in %n months_" : ["dans %n mois","dans %n mois"], - "_%n month ago_::_%n months ago_" : ["Il y a %n mois","Il y a %n mois"], + "_in %n month_::_in %n months_" : ["dans %n mois","dans %n mois","dans %n mois"], + "_%n month ago_::_%n months ago_" : ["Il y a %n mois","Il y a %n mois","Il y a %n mois"], "next year" : "année suivante", "last year" : "l'année dernière", - "_in %n year_::_in %n years_" : ["dans %n an","dans %n ans"], - "_%n year ago_::_%n years ago_" : ["il y a %n an","il y a %n ans"], - "_in %n hour_::_in %n hours_" : ["dans %n heure","dans %n heures"], - "_%n hour ago_::_%n hours ago_" : ["Il y a %n heure","Il y a %n heures"], - "_in %n minute_::_in %n minutes_" : ["dans %n minute","dans %n minutes"], - "_%n minute ago_::_%n minutes ago_" : ["il y a %n minute","il y a %n minutes"], + "_in %n year_::_in %n years_" : ["dans %n an","dans %n ans","dans %n ans"], + "_%n year ago_::_%n years ago_" : ["il y a %n an","il y a %n ans","il y a %n ans"], + "_in %n hour_::_in %n hours_" : ["dans %n heure","dans %n heures","dans %n heures"], + "_%n hour ago_::_%n hours ago_" : ["Il y a %n heure","Il y a %n heures","Il y a %n heures"], + "_in %n minute_::_in %n minutes_" : ["dans %n minute","dans %n minutes","dans %n minutes"], + "_%n minute ago_::_%n minutes ago_" : ["il y a %n minute","il y a %n minutes","il y a %n minutes"], "in a few seconds" : "dans quelques secondes", "seconds ago" : "il y a quelques secondes", "Empty file" : "Fichier vide", @@ -140,7 +140,7 @@ OC.L10N.register( "Files cannot be shared with delete permissions" : "Les fichiers ne peuvent pas être partagés avec les autorisations de suppression", "Files cannot be shared with create permissions" : "Les fichiers ne peuvent pas être partagés avec les autorisations de création", "Expiration date is in the past" : "La date d'expiration est dans le passé", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossible de définir la date d'expiration à dans plus de %s jour","Impossible de définir la date d'expiration à dans plus de %s jours"], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossible de définir la date d'expiration à dans plus de %s jour","Impossible de définir la date d'expiration à dans plus de %s jours","Impossible de définir la date d'expiration à dans plus de %s jours"], "Sharing is only allowed with group members" : "Le partage n'est que possible qu'avec les membres du groupe", "Sharing %s failed, because this item is already shared with user %s" : "Impossible de partager %s car il est déjà partagé avec l'utilisateur %s", "%1$s shared »%2$s« with you" : "%1$s a partagé « %2$s » avec vous", @@ -275,4 +275,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifiez la valeur de \"datadirectory\" dans votre configuration", "Your data directory is invalid" : "Votre répertoire n'est pas valide" }, -"nplurals=2; plural=(n > 1);"); +"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json index 89e6fa76aea..39541e997cf 100644 --- a/lib/l10n/fr.json +++ b/lib/l10n/fr.json @@ -56,20 +56,20 @@ "today" : "aujourd'hui", "tomorrow" : "demain", "yesterday" : "hier", - "_in %n day_::_in %n days_" : ["dans %n jour","dans %n jours"], - "_%n day ago_::_%n days ago_" : ["il y a %n jour","il y a %n jours"], + "_in %n day_::_in %n days_" : ["dans %n jour","dans %n jours","dans %n jours"], + "_%n day ago_::_%n days ago_" : ["il y a %n jour","il y a %n jours","il y a %n jours"], "next month" : "mois suivant", "last month" : "le mois dernier", - "_in %n month_::_in %n months_" : ["dans %n mois","dans %n mois"], - "_%n month ago_::_%n months ago_" : ["Il y a %n mois","Il y a %n mois"], + "_in %n month_::_in %n months_" : ["dans %n mois","dans %n mois","dans %n mois"], + "_%n month ago_::_%n months ago_" : ["Il y a %n mois","Il y a %n mois","Il y a %n mois"], "next year" : "année suivante", "last year" : "l'année dernière", - "_in %n year_::_in %n years_" : ["dans %n an","dans %n ans"], - "_%n year ago_::_%n years ago_" : ["il y a %n an","il y a %n ans"], - "_in %n hour_::_in %n hours_" : ["dans %n heure","dans %n heures"], - "_%n hour ago_::_%n hours ago_" : ["Il y a %n heure","Il y a %n heures"], - "_in %n minute_::_in %n minutes_" : ["dans %n minute","dans %n minutes"], - "_%n minute ago_::_%n minutes ago_" : ["il y a %n minute","il y a %n minutes"], + "_in %n year_::_in %n years_" : ["dans %n an","dans %n ans","dans %n ans"], + "_%n year ago_::_%n years ago_" : ["il y a %n an","il y a %n ans","il y a %n ans"], + "_in %n hour_::_in %n hours_" : ["dans %n heure","dans %n heures","dans %n heures"], + "_%n hour ago_::_%n hours ago_" : ["Il y a %n heure","Il y a %n heures","Il y a %n heures"], + "_in %n minute_::_in %n minutes_" : ["dans %n minute","dans %n minutes","dans %n minutes"], + "_%n minute ago_::_%n minutes ago_" : ["il y a %n minute","il y a %n minutes","il y a %n minutes"], "in a few seconds" : "dans quelques secondes", "seconds ago" : "il y a quelques secondes", "Empty file" : "Fichier vide", @@ -138,7 +138,7 @@ "Files cannot be shared with delete permissions" : "Les fichiers ne peuvent pas être partagés avec les autorisations de suppression", "Files cannot be shared with create permissions" : "Les fichiers ne peuvent pas être partagés avec les autorisations de création", "Expiration date is in the past" : "La date d'expiration est dans le passé", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossible de définir la date d'expiration à dans plus de %s jour","Impossible de définir la date d'expiration à dans plus de %s jours"], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossible de définir la date d'expiration à dans plus de %s jour","Impossible de définir la date d'expiration à dans plus de %s jours","Impossible de définir la date d'expiration à dans plus de %s jours"], "Sharing is only allowed with group members" : "Le partage n'est que possible qu'avec les membres du groupe", "Sharing %s failed, because this item is already shared with user %s" : "Impossible de partager %s car il est déjà partagé avec l'utilisateur %s", "%1$s shared »%2$s« with you" : "%1$s a partagé « %2$s » avec vous", @@ -272,5 +272,5 @@ "Your data directory must be an absolute path" : "Le chemin de votre répertoire doit être un lien absolu", "Check the value of \"datadirectory\" in your configuration" : "Verifiez la valeur de \"datadirectory\" dans votre configuration", "Your data directory is invalid" : "Votre répertoire n'est pas valide" -},"pluralForm" :"nplurals=2; plural=(n > 1);" +},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/id.js b/lib/l10n/id.js index f1d50d6e98d..fe5faa7baba 100644 --- a/lib/l10n/id.js +++ b/lib/l10n/id.js @@ -36,7 +36,7 @@ OC.L10N.register( "App \"%s\" cannot be installed because it is not compatible with this version of the server." : "Aplikasi \"%s\" tidak dapat dipasang karena tidak kompatibel dengan versi server ini", "__language_name__" : "Bahasa Indonesia", "Help" : "Bantuan", - "Apps" : "aplikasi", + "Apps" : "Aplikasi", "Settings" : "Setelan", "Log out" : "Keluar", "Users" : "Pengguna", diff --git a/lib/l10n/id.json b/lib/l10n/id.json index 71ec29b073d..737bf890755 100644 --- a/lib/l10n/id.json +++ b/lib/l10n/id.json @@ -34,7 +34,7 @@ "App \"%s\" cannot be installed because it is not compatible with this version of the server." : "Aplikasi \"%s\" tidak dapat dipasang karena tidak kompatibel dengan versi server ini", "__language_name__" : "Bahasa Indonesia", "Help" : "Bantuan", - "Apps" : "aplikasi", + "Apps" : "Aplikasi", "Settings" : "Setelan", "Log out" : "Keluar", "Users" : "Pengguna", diff --git a/lib/l10n/it.js b/lib/l10n/it.js index 2b3f83e215c..608db04d9da 100644 --- a/lib/l10n/it.js +++ b/lib/l10n/it.js @@ -58,20 +58,20 @@ OC.L10N.register( "today" : "oggi", "tomorrow" : "domani", "yesterday" : "ieri", - "_in %n day_::_in %n days_" : ["tra %n giorno","tra %n giorni"], - "_%n day ago_::_%n days ago_" : ["%d giorno fa","%n giorni fa"], + "_in %n day_::_in %n days_" : ["tra %n giorno","tra %n giorni","tra %n giorni"], + "_%n day ago_::_%n days ago_" : ["%d giorno fa","%n giorni fa","%n giorni fa"], "next month" : "il prossimo mese", "last month" : "mese scorso", - "_in %n month_::_in %n months_" : ["tra %n mese","tra %n mesi"], - "_%n month ago_::_%n months ago_" : ["%n mese fa","%n mesi fa"], + "_in %n month_::_in %n months_" : ["tra %n mese","tra %n mesi","tra %n mesi"], + "_%n month ago_::_%n months ago_" : ["%n mese fa","%n mesi fa","%n mesi fa"], "next year" : "il prossimo anno", "last year" : "anno scorso", - "_in %n year_::_in %n years_" : ["tra %n anno","tra %n anni"], - "_%n year ago_::_%n years ago_" : ["%n anno fa","%n anni fa"], - "_in %n hour_::_in %n hours_" : ["tra %n ora","tra %n ore"], - "_%n hour ago_::_%n hours ago_" : ["%n ora fa","%n ore fa"], - "_in %n minute_::_in %n minutes_" : ["tra %n minuto","tra %n minuti"], - "_%n minute ago_::_%n minutes ago_" : ["%n minuto fa","%n minuti fa"], + "_in %n year_::_in %n years_" : ["tra %n anno","tra %n anni","tra %n anni"], + "_%n year ago_::_%n years ago_" : ["%n anno fa","%n anni fa","%n anni fa"], + "_in %n hour_::_in %n hours_" : ["tra %n ora","tra %n ore","tra %n ore"], + "_%n hour ago_::_%n hours ago_" : ["%n ora fa","%n ore fa","%n ore fa"], + "_in %n minute_::_in %n minutes_" : ["tra %n minuto","tra %n minuti","tra %n minuti"], + "_%n minute ago_::_%n minutes ago_" : ["%n minuto fa","%n minuti fa","%n minuti fa"], "in a few seconds" : "tra pochi secondi", "seconds ago" : "secondi fa", "Empty file" : "File vuoto", @@ -140,7 +140,7 @@ OC.L10N.register( "Files cannot be shared with delete permissions" : "I file non possono essere condivisi con permessi di eliminazione", "Files cannot be shared with create permissions" : "I file non possono essere condivisi con permessi di creazione", "Expiration date is in the past" : "La data di scadenza è nel passato", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossibile impostare la data di scadenza a più di %n giorni nel futuro","Impossibile impostare la data di scadenza a più di %n giorni nel futuro"], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossibile impostare la data di scadenza a più di %n giorni nel futuro","Impossibile impostare la data di scadenza a più di %n giorni nel futuro","Impossibile impostare la data di scadenza a più di %n giorni nel futuro"], "Sharing is only allowed with group members" : "La condivisione è consentita solo con i membri del gruppo", "Sharing %s failed, because this item is already shared with user %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con l'utente %s", "%1$s shared »%2$s« with you" : "%1$s ha condiviso «%2$s» con te", @@ -273,4 +273,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Controlla il valore di \"datadirectory\" nella tua configurazione", "Your data directory is invalid" : "La cartella dei dati non è valida" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/it.json b/lib/l10n/it.json index f0552dedebb..f7c10f383fc 100644 --- a/lib/l10n/it.json +++ b/lib/l10n/it.json @@ -56,20 +56,20 @@ "today" : "oggi", "tomorrow" : "domani", "yesterday" : "ieri", - "_in %n day_::_in %n days_" : ["tra %n giorno","tra %n giorni"], - "_%n day ago_::_%n days ago_" : ["%d giorno fa","%n giorni fa"], + "_in %n day_::_in %n days_" : ["tra %n giorno","tra %n giorni","tra %n giorni"], + "_%n day ago_::_%n days ago_" : ["%d giorno fa","%n giorni fa","%n giorni fa"], "next month" : "il prossimo mese", "last month" : "mese scorso", - "_in %n month_::_in %n months_" : ["tra %n mese","tra %n mesi"], - "_%n month ago_::_%n months ago_" : ["%n mese fa","%n mesi fa"], + "_in %n month_::_in %n months_" : ["tra %n mese","tra %n mesi","tra %n mesi"], + "_%n month ago_::_%n months ago_" : ["%n mese fa","%n mesi fa","%n mesi fa"], "next year" : "il prossimo anno", "last year" : "anno scorso", - "_in %n year_::_in %n years_" : ["tra %n anno","tra %n anni"], - "_%n year ago_::_%n years ago_" : ["%n anno fa","%n anni fa"], - "_in %n hour_::_in %n hours_" : ["tra %n ora","tra %n ore"], - "_%n hour ago_::_%n hours ago_" : ["%n ora fa","%n ore fa"], - "_in %n minute_::_in %n minutes_" : ["tra %n minuto","tra %n minuti"], - "_%n minute ago_::_%n minutes ago_" : ["%n minuto fa","%n minuti fa"], + "_in %n year_::_in %n years_" : ["tra %n anno","tra %n anni","tra %n anni"], + "_%n year ago_::_%n years ago_" : ["%n anno fa","%n anni fa","%n anni fa"], + "_in %n hour_::_in %n hours_" : ["tra %n ora","tra %n ore","tra %n ore"], + "_%n hour ago_::_%n hours ago_" : ["%n ora fa","%n ore fa","%n ore fa"], + "_in %n minute_::_in %n minutes_" : ["tra %n minuto","tra %n minuti","tra %n minuti"], + "_%n minute ago_::_%n minutes ago_" : ["%n minuto fa","%n minuti fa","%n minuti fa"], "in a few seconds" : "tra pochi secondi", "seconds ago" : "secondi fa", "Empty file" : "File vuoto", @@ -138,7 +138,7 @@ "Files cannot be shared with delete permissions" : "I file non possono essere condivisi con permessi di eliminazione", "Files cannot be shared with create permissions" : "I file non possono essere condivisi con permessi di creazione", "Expiration date is in the past" : "La data di scadenza è nel passato", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossibile impostare la data di scadenza a più di %n giorni nel futuro","Impossibile impostare la data di scadenza a più di %n giorni nel futuro"], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Impossibile impostare la data di scadenza a più di %n giorni nel futuro","Impossibile impostare la data di scadenza a più di %n giorni nel futuro","Impossibile impostare la data di scadenza a più di %n giorni nel futuro"], "Sharing is only allowed with group members" : "La condivisione è consentita solo con i membri del gruppo", "Sharing %s failed, because this item is already shared with user %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con l'utente %s", "%1$s shared »%2$s« with you" : "%1$s ha condiviso «%2$s» con te", @@ -270,5 +270,5 @@ "Your data directory must be an absolute path" : "La cartella dei dati deve essere un percorso assoluto", "Check the value of \"datadirectory\" in your configuration" : "Controlla il valore di \"datadirectory\" nella tua configurazione", "Your data directory is invalid" : "La cartella dei dati non è valida" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/pl.js b/lib/l10n/pl.js index 9958aa00fd6..1cea063ff4f 100644 --- a/lib/l10n/pl.js +++ b/lib/l10n/pl.js @@ -216,7 +216,7 @@ OC.L10N.register( "This can usually be fixed by giving the web server write access to the config directory. See %s" : "Zwykle można to naprawić, nadajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu config. Zobacz %s", "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "JeÅ›li, albo wolisz zachować plik config.php tylko do odczytu, ustaw w nim opcjÄ™ \"config_is_read_only\" na true. Zobacz %s", "Cannot write into \"apps\" directory." : "Nie można zapisać do katalogu \"apps\".", - "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "Zwykle można to naprawić, przyznajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu aplikacji lub wyłączajÄ…c sklep z aplikacjami w pliku konfiguracyjnym.", + "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "Zwykle można to naprawić, przyznajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu aplikacji lub wyłączajÄ…c Nextcloud App Store w pliku konfiguracyjnym.", "Cannot create \"data\" directory." : "Nie można utworzyć katalogu \"data\".", "This can usually be fixed by giving the web server write access to the root directory. See %s" : "Zwykle można to naprawić, nadajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu głównego. Zobacz %s", "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Uprawnienia można zazwyczaj naprawić, nadajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu głównego. Zobacz %s.", diff --git a/lib/l10n/pl.json b/lib/l10n/pl.json index de1893fdfe0..89ca47e5d33 100644 --- a/lib/l10n/pl.json +++ b/lib/l10n/pl.json @@ -214,7 +214,7 @@ "This can usually be fixed by giving the web server write access to the config directory. See %s" : "Zwykle można to naprawić, nadajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu config. Zobacz %s", "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "JeÅ›li, albo wolisz zachować plik config.php tylko do odczytu, ustaw w nim opcjÄ™ \"config_is_read_only\" na true. Zobacz %s", "Cannot write into \"apps\" directory." : "Nie można zapisać do katalogu \"apps\".", - "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "Zwykle można to naprawić, przyznajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu aplikacji lub wyłączajÄ…c sklep z aplikacjami w pliku konfiguracyjnym.", + "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "Zwykle można to naprawić, przyznajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu aplikacji lub wyłączajÄ…c Nextcloud App Store w pliku konfiguracyjnym.", "Cannot create \"data\" directory." : "Nie można utworzyć katalogu \"data\".", "This can usually be fixed by giving the web server write access to the root directory. See %s" : "Zwykle można to naprawić, nadajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu głównego. Zobacz %s", "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Uprawnienia można zazwyczaj naprawić, nadajÄ…c serwerowi WWW dostÄ™p do zapisu do katalogu głównego. Zobacz %s.", diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js index 59148b038fd..fa592b6cc4d 100644 --- a/lib/l10n/pt_BR.js +++ b/lib/l10n/pt_BR.js @@ -58,20 +58,20 @@ OC.L10N.register( "today" : "hoje", "tomorrow" : "amanhã", "yesterday" : "ontem", - "_in %n day_::_in %n days_" : ["em %n dia","em %n dias"], - "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"], + "_in %n day_::_in %n days_" : ["em %n dia","em %n dias","em %n dias"], + "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás","%n dias atrás"], "next month" : "Mês que vem", "last month" : "último mês", - "_in %n month_::_in %n months_" : ["em %n mês","em %n meses"], - "_%n month ago_::_%n months ago_" : ["há %n mês atrás","há %n meses"], + "_in %n month_::_in %n months_" : ["em %n mês","em %n meses","em %n meses"], + "_%n month ago_::_%n months ago_" : ["há %n mês atrás","há %n meses","há %n meses"], "next year" : "ano que vem", "last year" : "último ano", - "_in %n year_::_in %n years_" : ["em %n ano","em %n anos"], - "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"], - "_in %n hour_::_in %n hours_" : ["em %n hora","em %n horas"], - "_%n hour ago_::_%n hours ago_" : ["há %n hora atrás","há %n horas"], - "_in %n minute_::_in %n minutes_" : ["em %n minuto","em %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["há %n minuto atrás","há %n minutos"], + "_in %n year_::_in %n years_" : ["em %n ano","em %n anos","em %n anos"], + "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás","%n anos atrás"], + "_in %n hour_::_in %n hours_" : ["em %n hora","em %n horas","em %n horas"], + "_%n hour ago_::_%n hours ago_" : ["há %n hora atrás","há %n horas","há %n horas"], + "_in %n minute_::_in %n minutes_" : ["em %n minuto","em %n minutos","em %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["há %n minuto atrás","há %n minutos","há %n minutos"], "in a few seconds" : "Em alguns segundos", "seconds ago" : "segundos atrás", "Empty file" : "Arquivo vazio", @@ -140,7 +140,7 @@ OC.L10N.register( "Files cannot be shared with delete permissions" : "Arquivos não podem ser compartilhados com permissões de exclusão", "Files cannot be shared with create permissions" : "Arquivos não podem ser compartilhados com permissões de criação", "Expiration date is in the past" : "Data de expiração está no passado", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Não foi possÃvel definir a data de expiração superior que %n dias no futuro","Não foi possÃvel definir a data de expiração superior que %n dias no futuro"], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Não foi possÃvel definir a data de expiração superior que %n dias no futuro","Não foi possÃvel definir a data de expiração superior que %n dias no futuro","Não foi possÃvel definir a data de expiração superior que %n dias no futuro"], "Sharing is only allowed with group members" : "O compartilhamento só é permitido com membros do grupo ", "Sharing %s failed, because this item is already shared with user %s" : "Compartilhamento %s falhou, porque este item já está compartilhado com o usuário %s", "%1$s shared »%2$s« with you" : "%1$s compartilhou »%2$s« com você", @@ -275,4 +275,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifique o valor do \"datadirectory\" na sua configuração", "Your data directory is invalid" : "Seu diretório de dados é inválido" }, -"nplurals=2; plural=(n > 1);"); +"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json index 2ffa8eea954..206f786d991 100644 --- a/lib/l10n/pt_BR.json +++ b/lib/l10n/pt_BR.json @@ -56,20 +56,20 @@ "today" : "hoje", "tomorrow" : "amanhã", "yesterday" : "ontem", - "_in %n day_::_in %n days_" : ["em %n dia","em %n dias"], - "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"], + "_in %n day_::_in %n days_" : ["em %n dia","em %n dias","em %n dias"], + "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás","%n dias atrás"], "next month" : "Mês que vem", "last month" : "último mês", - "_in %n month_::_in %n months_" : ["em %n mês","em %n meses"], - "_%n month ago_::_%n months ago_" : ["há %n mês atrás","há %n meses"], + "_in %n month_::_in %n months_" : ["em %n mês","em %n meses","em %n meses"], + "_%n month ago_::_%n months ago_" : ["há %n mês atrás","há %n meses","há %n meses"], "next year" : "ano que vem", "last year" : "último ano", - "_in %n year_::_in %n years_" : ["em %n ano","em %n anos"], - "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"], - "_in %n hour_::_in %n hours_" : ["em %n hora","em %n horas"], - "_%n hour ago_::_%n hours ago_" : ["há %n hora atrás","há %n horas"], - "_in %n minute_::_in %n minutes_" : ["em %n minuto","em %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["há %n minuto atrás","há %n minutos"], + "_in %n year_::_in %n years_" : ["em %n ano","em %n anos","em %n anos"], + "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás","%n anos atrás"], + "_in %n hour_::_in %n hours_" : ["em %n hora","em %n horas","em %n horas"], + "_%n hour ago_::_%n hours ago_" : ["há %n hora atrás","há %n horas","há %n horas"], + "_in %n minute_::_in %n minutes_" : ["em %n minuto","em %n minutos","em %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["há %n minuto atrás","há %n minutos","há %n minutos"], "in a few seconds" : "Em alguns segundos", "seconds ago" : "segundos atrás", "Empty file" : "Arquivo vazio", @@ -138,7 +138,7 @@ "Files cannot be shared with delete permissions" : "Arquivos não podem ser compartilhados com permissões de exclusão", "Files cannot be shared with create permissions" : "Arquivos não podem ser compartilhados com permissões de criação", "Expiration date is in the past" : "Data de expiração está no passado", - "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Não foi possÃvel definir a data de expiração superior que %n dias no futuro","Não foi possÃvel definir a data de expiração superior que %n dias no futuro"], + "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Não foi possÃvel definir a data de expiração superior que %n dias no futuro","Não foi possÃvel definir a data de expiração superior que %n dias no futuro","Não foi possÃvel definir a data de expiração superior que %n dias no futuro"], "Sharing is only allowed with group members" : "O compartilhamento só é permitido com membros do grupo ", "Sharing %s failed, because this item is already shared with user %s" : "Compartilhamento %s falhou, porque este item já está compartilhado com o usuário %s", "%1$s shared »%2$s« with you" : "%1$s compartilhou »%2$s« com você", @@ -272,5 +272,5 @@ "Your data directory must be an absolute path" : "O diretório de dados deve ser um caminho absoluto", "Check the value of \"datadirectory\" in your configuration" : "Verifique o valor do \"datadirectory\" na sua configuração", "Your data directory is invalid" : "Seu diretório de dados é inválido" -},"pluralForm" :"nplurals=2; plural=(n > 1);" +},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/pt_PT.js b/lib/l10n/pt_PT.js index 35f3917cf43..651e0fe4b9e 100644 --- a/lib/l10n/pt_PT.js +++ b/lib/l10n/pt_PT.js @@ -38,20 +38,20 @@ OC.L10N.register( "today" : "hoje", "tomorrow" : "Amanhã", "yesterday" : "ontem", - "_in %n day_::_in %n days_" : ["em %n dia","em %n dias"], - "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"], + "_in %n day_::_in %n days_" : ["em %n dia","em %n dias","em %n dias"], + "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás","%n dias atrás"], "next month" : "Próximo mês", "last month" : "ultimo mês", - "_in %n month_::_in %n months_" : ["em %n mês","em %n meses"], - "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás"], + "_in %n month_::_in %n months_" : ["em %n mês","em %n meses","em %n meses"], + "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás","%n meses atrás"], "next year" : "Próximo ano", "last year" : "ano passado", - "_in %n year_::_in %n years_" : ["dentro de%n ano","dentro de %n anos"], - "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"], - "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas"], - "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás"], - "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás"], + "_in %n year_::_in %n years_" : ["dentro de%n ano","dentro de %n anos","dentro de %n anos"], + "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás","%n anos atrás"], + "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas","dentro de %n horas"], + "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás","%n horas atrás"], + "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos","dentro de %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás","%n minutos atrás"], "in a few seconds" : "em breves segundos", "seconds ago" : "Minutos atrás", "Empty file" : "Ficheiro vazio", @@ -224,4 +224,4 @@ OC.L10N.register( "Check the value of \"datadirectory\" in your configuration" : "Verifique o valor de \"datadirectory\" na sua configuração", "Your data directory is invalid" : "O seu directório de dados é inválido" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/lib/l10n/pt_PT.json b/lib/l10n/pt_PT.json index 9ca3e09f10e..8abe9f8c6a0 100644 --- a/lib/l10n/pt_PT.json +++ b/lib/l10n/pt_PT.json @@ -36,20 +36,20 @@ "today" : "hoje", "tomorrow" : "Amanhã", "yesterday" : "ontem", - "_in %n day_::_in %n days_" : ["em %n dia","em %n dias"], - "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"], + "_in %n day_::_in %n days_" : ["em %n dia","em %n dias","em %n dias"], + "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás","%n dias atrás"], "next month" : "Próximo mês", "last month" : "ultimo mês", - "_in %n month_::_in %n months_" : ["em %n mês","em %n meses"], - "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás"], + "_in %n month_::_in %n months_" : ["em %n mês","em %n meses","em %n meses"], + "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás","%n meses atrás"], "next year" : "Próximo ano", "last year" : "ano passado", - "_in %n year_::_in %n years_" : ["dentro de%n ano","dentro de %n anos"], - "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"], - "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas"], - "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás"], - "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos"], - "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás"], + "_in %n year_::_in %n years_" : ["dentro de%n ano","dentro de %n anos","dentro de %n anos"], + "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás","%n anos atrás"], + "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas","dentro de %n horas"], + "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás","%n horas atrás"], + "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos","dentro de %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás","%n minutos atrás"], "in a few seconds" : "em breves segundos", "seconds ago" : "Minutos atrás", "Empty file" : "Ficheiro vazio", @@ -221,5 +221,5 @@ "Your data directory must be an absolute path" : "O seu directório de dados deve ser um caminho absoluto", "Check the value of \"datadirectory\" in your configuration" : "Verifique o valor de \"datadirectory\" na sua configuração", "Your data directory is invalid" : "O seu directório de dados é inválido" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/l10n/tr.js b/lib/l10n/tr.js index e03728a80cb..f6262e13b40 100644 --- a/lib/l10n/tr.js +++ b/lib/l10n/tr.js @@ -97,7 +97,7 @@ OC.L10N.register( "Email" : "E-posta", "Mail %s" : "E-posta gönder: %s", "Phone" : "Telefon", - "Call %s" : "Ara: %s", + "Call %s" : "Çağrı gönder: %s", "Twitter" : "Twitter", "View %s on Twitter" : "Twitter üzerinde bak: %s", "Website" : "Web sitesi", diff --git a/lib/l10n/tr.json b/lib/l10n/tr.json index 84fb4177d06..894fca744d5 100644 --- a/lib/l10n/tr.json +++ b/lib/l10n/tr.json @@ -95,7 +95,7 @@ "Email" : "E-posta", "Mail %s" : "E-posta gönder: %s", "Phone" : "Telefon", - "Call %s" : "Ara: %s", + "Call %s" : "Çağrı gönder: %s", "Twitter" : "Twitter", "View %s on Twitter" : "Twitter üzerinde bak: %s", "Website" : "Web sitesi", diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php index 5792ba1dc5d..b80c7887591 100644 --- a/lib/private/Accounts/AccountManager.php +++ b/lib/private/Accounts/AccountManager.php @@ -14,6 +14,7 @@ * @author Lukas Reschke <lukas@statuscode.ch> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Vincent Petry <vincent@nextcloud.com> * * @license AGPL-3.0 @@ -119,6 +120,23 @@ class AccountManager implements IAccountManager { private $l10nfactory; private CappedMemoryCache $internalCache; + /** + * The list of default scopes for each property. + */ + public const DEFAULT_SCOPES = [ + self::PROPERTY_DISPLAYNAME => self::SCOPE_FEDERATED, + self::PROPERTY_ADDRESS => self::SCOPE_LOCAL, + self::PROPERTY_WEBSITE => self::SCOPE_LOCAL, + self::PROPERTY_EMAIL => self::SCOPE_FEDERATED, + self::PROPERTY_AVATAR => self::SCOPE_FEDERATED, + self::PROPERTY_PHONE => self::SCOPE_LOCAL, + self::PROPERTY_TWITTER => self::SCOPE_LOCAL, + self::PROPERTY_ORGANISATION => self::SCOPE_LOCAL, + self::PROPERTY_ROLE => self::SCOPE_LOCAL, + self::PROPERTY_HEADLINE => self::SCOPE_LOCAL, + self::PROPERTY_BIOGRAPHY => self::SCOPE_LOCAL, + ]; + public function __construct( IDBConnection $connection, IConfig $config, @@ -269,12 +287,15 @@ class AccountManager implements IAccountManager { } } - protected function updateUser(IUser $user, array $data, bool $throwOnData = false): array { - $oldUserData = $this->getUser($user, false); + protected function updateUser(IUser $user, array $data, ?array $oldUserData, bool $throwOnData = false): array { + if ($oldUserData === null) { + $oldUserData = $this->getUser($user, false); + } + $updated = true; if ($oldUserData !== $data) { - $this->updateExistingUser($user, $data); + $this->updateExistingUser($user, $data, $oldUserData); } else { // nothing needs to be done if new and old data set are the same $updated = false; @@ -601,12 +622,9 @@ class AccountManager implements IAccountManager { } /** - * update existing user in accounts table - * - * @param IUser $user - * @param array $data + * Update existing user in accounts table */ - protected function updateExistingUser(IUser $user, array $data): void { + protected function updateExistingUser(IUser $user, array $data, array $oldData): void { $uid = $user->getUID(); $jsonEncodedData = $this->prepareJson($data); $query = $this->connection->getQueryBuilder(); @@ -649,81 +667,84 @@ class AccountManager implements IAccountManager { /** * build default user record in case not data set exists yet - * - * @param IUser $user - * @return array */ - protected function buildDefaultUserRecord(IUser $user) { + protected function buildDefaultUserRecord(IUser $user): array { + $scopes = array_merge(self::DEFAULT_SCOPES, array_filter($this->config->getSystemValue('account_manager.default_property_scope', []), static function (string $scope, string $property) { + return in_array($property, self::ALLOWED_PROPERTIES, true) && in_array($scope, self::ALLOWED_SCOPES, true); + }, ARRAY_FILTER_USE_BOTH)); + return [ [ 'name' => self::PROPERTY_DISPLAYNAME, 'value' => $user->getDisplayName(), - 'scope' => self::SCOPE_FEDERATED, + // Display name must be at least SCOPE_LOCAL + 'scope' => $scopes[self::PROPERTY_DISPLAYNAME] === self::SCOPE_PRIVATE ? self::SCOPE_LOCAL : $scopes[self::PROPERTY_DISPLAYNAME], 'verified' => self::NOT_VERIFIED, ], [ 'name' => self::PROPERTY_ADDRESS, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_ADDRESS], 'verified' => self::NOT_VERIFIED, ], [ 'name' => self::PROPERTY_WEBSITE, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_WEBSITE], 'verified' => self::NOT_VERIFIED, ], [ 'name' => self::PROPERTY_EMAIL, 'value' => $user->getEMailAddress(), - 'scope' => self::SCOPE_FEDERATED, + // Email must be at least SCOPE_LOCAL + 'scope' => $scopes[self::PROPERTY_EMAIL] === self::SCOPE_PRIVATE ? self::SCOPE_LOCAL : $scopes[self::PROPERTY_EMAIL], 'verified' => self::NOT_VERIFIED, ], [ 'name' => self::PROPERTY_AVATAR, - 'scope' => self::SCOPE_FEDERATED + 'scope' => $scopes[self::PROPERTY_AVATAR], ], [ 'name' => self::PROPERTY_PHONE, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_PHONE], 'verified' => self::NOT_VERIFIED, ], [ 'name' => self::PROPERTY_TWITTER, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_TWITTER], 'verified' => self::NOT_VERIFIED, ], [ 'name' => self::PROPERTY_ORGANISATION, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_ORGANISATION], ], [ 'name' => self::PROPERTY_ROLE, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_ROLE], ], [ 'name' => self::PROPERTY_HEADLINE, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_HEADLINE], ], [ 'name' => self::PROPERTY_BIOGRAPHY, 'value' => '', - 'scope' => self::SCOPE_LOCAL, + 'scope' => $scopes[self::PROPERTY_BIOGRAPHY], ], [ @@ -790,17 +811,8 @@ class AccountManager implements IAccountManager { // valid case, nothing to do } - static $allowedScopes = [ - self::SCOPE_PRIVATE, - self::SCOPE_LOCAL, - self::SCOPE_FEDERATED, - self::SCOPE_PUBLISHED, - self::VISIBILITY_PRIVATE, - self::VISIBILITY_CONTACTS_ONLY, - self::VISIBILITY_PUBLIC, - ]; foreach ($account->getAllProperties() as $property) { - $this->testPropertyScope($property, $allowedScopes, true); + $this->testPropertyScope($property, self::ALLOWED_SCOPES, true); } $oldData = $this->getUser($account->getUser(), false); @@ -820,7 +832,7 @@ class AccountManager implements IAccountManager { ]; } - $this->updateUser($account->getUser(), $data, true); + $this->updateUser($account->getUser(), $data, $oldData, true); $this->internalCache->set($account->getUser()->getUID(), $account); } } diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php index 1324d7f3056..00e5dddc1f9 100644 --- a/lib/private/AppConfig.php +++ b/lib/private/AppConfig.php @@ -423,14 +423,4 @@ class AppConfig implements IAppConfig { $this->configLoaded = true; } - - /** - * Clear all the cached app config values - * - * WARNING: do not use this - this is only for usage with the SCSSCacher to - * clear the memory cache of the app config - */ - public function clearCachedConfig() { - $this->configLoaded = false; - } } diff --git a/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php b/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php index fa7459e10ff..2fb05159d09 100644 --- a/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php +++ b/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php @@ -26,6 +26,7 @@ declare(strict_types=1); namespace OC\Authentication\Listeners; use OC\Files\Cache\Cache; +use OC\Files\Storage\Wrapper\Wrapper; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\Files\Config\IMountProviderCollection; @@ -56,6 +57,13 @@ class UserDeletedFilesCleanupListener implements IEventListener { if (!$storage) { throw new \Exception("User has no home storage"); } + + // remove all wrappers, so we do the delete directly on the home storage bypassing any wrapper + while ($storage->instanceOfStorage(Wrapper::class)) { + /** @var Wrapper $storage */ + $storage = $storage->getWrapperStorage(); + } + $this->homeStorageCache[$event->getUser()->getUID()] = $storage; } if ($event instanceof UserDeletedEvent) { diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php index 26337029d77..a1d75828e27 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php +++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php @@ -85,7 +85,7 @@ class PublicKeyTokenProvider implements IProvider { int $type = IToken::TEMPORARY_TOKEN, int $remember = IToken::DO_NOT_REMEMBER): IToken { if (mb_strlen($name) > 128) { - throw new InvalidTokenException('The given name is too long'); + $name = mb_substr($name, 0, 120) . '…'; } $dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember); diff --git a/lib/private/Cache/CappedMemoryCache.php b/lib/private/Cache/CappedMemoryCache.php index 0a3300435eb..6063b5e7110 100644 --- a/lib/private/Cache/CappedMemoryCache.php +++ b/lib/private/Cache/CappedMemoryCache.php @@ -88,7 +88,7 @@ class CappedMemoryCache implements ICache, \ArrayAccess { } /** - * @param string $key + * @param string $offset * @param T $value * @return void */ diff --git a/lib/private/Contacts/ContactsMenu/ActionProviderStore.php b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php index 1db99497a21..c93879afa5b 100644 --- a/lib/private/Contacts/ContactsMenu/ActionProviderStore.php +++ b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php @@ -38,15 +38,9 @@ use OCP\IUser; use Psr\Log\LoggerInterface; class ActionProviderStore { - - /** @var IServerContainer */ - private $serverContainer; - - /** @var AppManager */ - private $appManager; - - /** @var LoggerInterface */ - private $logger; + private IServerContainer $serverContainer; + private AppManager $appManager; + private LoggerInterface $logger; public function __construct(IServerContainer $serverContainer, AppManager $appManager, LoggerInterface $logger) { $this->serverContainer = $serverContainer; @@ -67,7 +61,7 @@ class ActionProviderStore { foreach ($allClasses as $class) { try { - $providers[] = $this->serverContainer->query($class); + $providers[] = $this->serverContainer->get($class); } catch (QueryException $ex) { $this->logger->error( 'Could not load contacts menu action provider ' . $class, diff --git a/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php index 3f917854aac..a3054c9ee52 100644 --- a/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php +++ b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php @@ -25,73 +25,44 @@ namespace OC\Contacts\ContactsMenu\Actions; use OCP\Contacts\ContactsMenu\ILinkAction; class LinkAction implements ILinkAction { - - /** @var string */ - private $icon; - - /** @var string */ - private $name; - - /** @var string */ - private $href; - - /** @var int */ - private $priority = 10; - - /** @var string */ - private $appId; + private string $icon = ''; + private string $name = ''; + private string $href = ''; + private int $priority = 10; + private string $appId = ''; /** * @param string $icon absolute URI to an icon */ - public function setIcon($icon) { + public function setIcon(string $icon) { $this->icon = $icon; } - /** - * @param string $name - */ - public function setName($name) { + public function setName(string $name) { $this->name = $name; } - /** - * @return string - */ - public function getName() { + public function getName(): string { return $this->name; } - /** - * @param int $priority - */ - public function setPriority($priority) { + public function setPriority(int $priority) { $this->priority = $priority; } - /** - * @return int - */ - public function getPriority() { + public function getPriority(): int { return $this->priority; } - /** - * @param string $href - */ - public function setHref($href) { + public function setHref(string $href) { $this->href = $href; } - /** - * @return string - */ - public function getHref() { + public function getHref(): string { return $this->href; } /** - * @param string $appId * @since 23.0.0 */ public function setAppId(string $appId) { @@ -99,7 +70,6 @@ class LinkAction implements ILinkAction { } /** - * @return string * @since 23.0.0 */ public function getAppId(): string { diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php index 0ac388ce00a..020e8604910 100644 --- a/lib/private/Contacts/ContactsMenu/ContactsStore.php +++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php @@ -44,30 +44,14 @@ use OCP\IUserManager; use OCP\L10N\IFactory as IL10NFactory; class ContactsStore implements IContactsStore { - - /** @var IManager */ - private $contactsManager; - - /** @var IConfig */ - private $config; - - /** @var ProfileManager */ - private $profileManager; - - /** @var IUserManager */ - private $userManager; - - /** @var IURLGenerator */ - private $urlGenerator; - - /** @var IGroupManager */ - private $groupManager; - - /** @var KnownUserService */ - private $knownUserService; - - /** @var IL10NFactory */ - private $l10nFactory; + private IManager $contactsManager; + private IConfig $config; + private ProfileManager $profileManager; + private IUserManager $userManager; + private IURLGenerator $urlGenerator; + private IGroupManager $groupManager; + private KnownUserService $knownUserService; + private IL10NFactory $l10nFactory; public function __construct( IManager $contactsManager, @@ -90,11 +74,9 @@ class ContactsStore implements IContactsStore { } /** - * @param IUser $user - * @param string|null $filter * @return IEntry[] */ - public function getContacts(IUser $user, $filter, ?int $limit = null, ?int $offset = null) { + public function getContacts(IUser $user, ?string $filter, ?int $limit = null, ?int $offset = null): array { $options = [ 'enumeration' => $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes', 'fullmatch' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes', @@ -152,8 +134,8 @@ class ContactsStore implements IContactsStore { private function filterContacts( IUser $self, array $entries, - $filter - ) { + ?string $filter + ): array { $disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes'; $restrictEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes'; $restrictEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes'; @@ -168,7 +150,7 @@ class ContactsStore implements IContactsStore { $selfGroups = $this->groupManager->getUserGroupIds($self); if ($excludedGroups) { - $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', ''); + $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list'); $decodedExcludeGroups = json_decode($excludedGroups, true); $excludeGroupsList = $decodedExcludeGroups ?? []; @@ -253,13 +235,7 @@ class ContactsStore implements IContactsStore { })); } - /** - * @param IUser $user - * @param integer $shareType - * @param string $shareWith - * @return IEntry|null - */ - public function findOne(IUser $user, $shareType, $shareWith) { + public function findOne(IUser $user, int $shareType, string $shareWith): ?IEntry { switch ($shareType) { case 0: case 6: @@ -305,11 +281,7 @@ class ContactsStore implements IContactsStore { return $match; } - /** - * @param array $contact - * @return Entry - */ - private function contactArrayToEntry(array $contact) { + private function contactArrayToEntry(array $contact): Entry { $entry = new Entry(); if (isset($contact['id'])) { diff --git a/lib/private/Contacts/ContactsMenu/Entry.php b/lib/private/Contacts/ContactsMenu/Entry.php index 915a0434cc8..3bbe679e999 100644 --- a/lib/private/Contacts/ContactsMenu/Entry.php +++ b/lib/private/Contacts/ContactsMenu/Entry.php @@ -35,51 +35,34 @@ class Entry implements IEntry { /** @var string|int|null */ private $id = null; - /** @var string */ - private $fullName = ''; + private string $fullName = ''; /** @var string[] */ - private $emailAddresses = []; + private array $emailAddresses = []; - /** @var string|null */ - private $avatar; + private ?string $avatar = null; - /** @var string|null */ - private $profileTitle; + private ?string $profileTitle = null; - /** @var string|null */ - private $profileUrl; + private ?string $profileUrl = null; /** @var IAction[] */ - private $actions = []; + private array $actions = []; - /** @var array */ - private $properties = []; + private array $properties = []; - /** - * @param string $id - */ public function setId(string $id): void { $this->id = $id; } - /** - * @param string $displayName - */ public function setFullName(string $displayName): void { $this->fullName = $displayName; } - /** - * @return string - */ public function getFullName(): string { return $this->fullName; } - /** - * @param string $address - */ public function addEMailAddress(string $address): void { $this->emailAddresses[] = $address; } @@ -91,51 +74,30 @@ class Entry implements IEntry { return $this->emailAddresses; } - /** - * @param string $avatar - */ public function setAvatar(string $avatar): void { $this->avatar = $avatar; } - /** - * @return string - */ public function getAvatar(): ?string { return $this->avatar; } - /** - * @param string $profileTitle - */ public function setProfileTitle(string $profileTitle): void { $this->profileTitle = $profileTitle; } - /** - * @return string - */ public function getProfileTitle(): ?string { return $this->profileTitle; } - /** - * @param string $profileUrl - */ public function setProfileUrl(string $profileUrl): void { $this->profileUrl = $profileUrl; } - /** - * @return string - */ public function getProfileUrl(): ?string { return $this->profileUrl; } - /** - * @param IAction $action - */ public function addAction(IAction $action): void { $this->actions[] = $action; $this->sortActions(); diff --git a/lib/private/Contacts/ContactsMenu/Manager.php b/lib/private/Contacts/ContactsMenu/Manager.php index 73a5a475d85..5c3367a3d09 100644 --- a/lib/private/Contacts/ContactsMenu/Manager.php +++ b/lib/private/Contacts/ContactsMenu/Manager.php @@ -25,6 +25,7 @@ */ namespace OC\Contacts\ContactsMenu; +use Exception; use OCP\App\IAppManager; use OCP\Constants; use OCP\Contacts\ContactsMenu\IEntry; @@ -32,24 +33,11 @@ use OCP\IConfig; use OCP\IUser; class Manager { + private ContactsStore $store; + private ActionProviderStore $actionProviderStore; + private IAppManager $appManager; + private IConfig $config; - /** @var ContactsStore */ - private $store; - - /** @var ActionProviderStore */ - private $actionProviderStore; - - /** @var IAppManager */ - private $appManager; - - /** @var IConfig */ - private $config; - - /** - * @param ContactsStore $store - * @param ActionProviderStore $actionProviderStore - * @param IAppManager $appManager - */ public function __construct(ContactsStore $store, ActionProviderStore $actionProviderStore, IAppManager $appManager, IConfig $config) { $this->store = $store; $this->actionProviderStore = $actionProviderStore; @@ -61,10 +49,11 @@ class Manager { * @param IUser $user * @param string|null $filter * @return array + * @throws Exception */ - public function getEntries(IUser $user, $filter) { + public function getEntries(IUser $user, ?string $filter): array { $maxAutocompleteResults = max(0, $this->config->getSystemValueInt('sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT)); - $minSearchStringLength = $this->config->getSystemValueInt('sharing.minSearchStringLength', 0); + $minSearchStringLength = $this->config->getSystemValueInt('sharing.minSearchStringLength'); $topEntries = []; if (strlen($filter ?? '') >= $minSearchStringLength) { $entries = $this->store->getContacts($user, $filter, $maxAutocompleteResults); @@ -82,12 +71,9 @@ class Manager { } /** - * @param IUser $user - * @param integer $shareType - * @param string $shareWith - * @return IEntry + * @throws Exception */ - public function findOne(IUser $user, $shareType, $shareWith) { + public function findOne(IUser $user, int $shareType, string $shareWith): ?IEntry { $entry = $this->store->findOne($user, $shareType, $shareWith); if ($entry) { $this->processEntries([$entry], $user); @@ -100,7 +86,7 @@ class Manager { * @param IEntry[] $entries * @return IEntry[] */ - private function sortEntries(array $entries) { + private function sortEntries(array $entries): array { usort($entries, function (IEntry $entryA, IEntry $entryB) { return strcasecmp($entryA->getFullName(), $entryB->getFullName()); }); @@ -110,6 +96,7 @@ class Manager { /** * @param IEntry[] $entries * @param IUser $user + * @throws Exception */ private function processEntries(array $entries, IUser $user) { $providers = $this->actionProviderStore->getProviders($user); diff --git a/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php b/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php index d69f219e84c..b79052e1f5d 100644 --- a/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php +++ b/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php @@ -28,17 +28,9 @@ use OCP\Contacts\ContactsMenu\IProvider; use OCP\IURLGenerator; class EMailProvider implements IProvider { + private IActionFactory $actionFactory; + private IURLGenerator $urlGenerator; - /** @var IActionFactory */ - private $actionFactory; - - /** @var IURLGenerator */ - private $urlGenerator; - - /** - * @param IActionFactory $actionFactory - * @param IURLGenerator $urlGenerator - */ public function __construct(IActionFactory $actionFactory, IURLGenerator $urlGenerator) { $this->actionFactory = $actionFactory; $this->urlGenerator = $urlGenerator; diff --git a/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php b/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php index e654319c3fa..af941fd7fd1 100644 --- a/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php +++ b/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php @@ -33,29 +33,12 @@ use OCP\IUserManager; use OCP\L10N\IFactory as IL10NFactory; class ProfileProvider implements IProvider { + private IActionFactory $actionFactory; + private ProfileManager $profileManager; + private IL10NFactory $l10nFactory; + private IURLGenerator $urlGenerator; + private IUserManager $userManager; - /** @var IActionFactory */ - private $actionFactory; - - /** @var ProfileManager */ - private $profileManager; - - /** @var IL10NFactory */ - private $l10nFactory; - - /** @var IURLGenerator */ - private $urlGenerator; - - /** @var IUserManager */ - private $userManager; - - /** - * @param IActionFactory $actionFactory - * @param ProfileManager $profileManager - * @param IL10NFactory $l10nFactory - * @param IURLGenerator $urlGenerator - * @param IUserManager $userManager - */ public function __construct( IActionFactory $actionFactory, ProfileManager $profileManager, diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php index fc436383b04..71dd18fd68b 100644 --- a/lib/private/DB/QueryBuilder/QueryBuilder.php +++ b/lib/private/DB/QueryBuilder/QueryBuilder.php @@ -1096,7 +1096,7 @@ class QueryBuilder implements IQueryBuilder { * Specifies an ordering for the query results. * Replaces any previously specified orderings, if any. * - * @param string $sort The ordering expression. + * @param string|IQueryFunction|ILiteral|IParameter $sort The ordering expression. * @param string $order The ordering direction. * * @return $this This QueryBuilder instance. diff --git a/lib/private/Diagnostics/EventLogger.php b/lib/private/Diagnostics/EventLogger.php index c7b89002ea9..7b9bd9630ab 100644 --- a/lib/private/Diagnostics/EventLogger.php +++ b/lib/private/Diagnostics/EventLogger.php @@ -126,7 +126,7 @@ class EventLogger implements IEventLogger { $timeInMs = round($duration * 1000, 4); $loggingMinimum = (int)$this->config->getValue('diagnostics.logging.threshold', 0); - if ($loggingMinimum > 0 && $timeInMs < $loggingMinimum) { + if ($loggingMinimum === 0 || $timeInMs < $loggingMinimum) { return; } diff --git a/lib/private/Diagnostics/QueryLogger.php b/lib/private/Diagnostics/QueryLogger.php index 499947178a3..40d68d94ae3 100644 --- a/lib/private/Diagnostics/QueryLogger.php +++ b/lib/private/Diagnostics/QueryLogger.php @@ -28,15 +28,10 @@ use OC\Cache\CappedMemoryCache; use OCP\Diagnostics\IQueryLogger; class QueryLogger implements IQueryLogger { - /** - * @var \OC\Diagnostics\Query - */ - protected $activeQuery; - - /** - * @var CappedMemoryCache - */ - protected $queries; + protected int $index = 0; + protected ?Query $activeQuery = null; + /** @var CappedMemoryCache<Query> */ + protected CappedMemoryCache $queries; /** * QueryLogger constructor. @@ -74,7 +69,8 @@ class QueryLogger implements IQueryLogger { public function stopQuery() { if ($this->activated && $this->activeQuery) { $this->activeQuery->end(microtime(true)); - $this->queries[] = $this->activeQuery; + $this->queries[(string)$this->index] = $this->activeQuery; + $this->index++; $this->activeQuery = null; } } diff --git a/lib/private/Encryption/File.php b/lib/private/Encryption/File.php index 2c486dfade6..2d7e23a8883 100644 --- a/lib/private/Encryption/File.php +++ b/lib/private/Encryption/File.php @@ -47,9 +47,9 @@ class File implements \OCP\Encryption\IFile { /** * cache results of already checked folders * - * @var array + * @var CappedMemoryCache<array> */ - protected $cache; + protected CappedMemoryCache $cache; public function __construct(Util $util, IRootFolder $rootFolder, @@ -62,10 +62,10 @@ class File implements \OCP\Encryption\IFile { /** - * get list of users with access to the file + * Get list of users with access to the file * * @param string $path to the file - * @return array ['users' => $uniqueUserIds, 'public' => $public] + * @return array{users: string[], public: bool} */ public function getAccessList($path) { diff --git a/lib/private/Encryption/Util.php b/lib/private/Encryption/Util.php index dc878ba8fc1..693e24c4721 100644 --- a/lib/private/Encryption/Util.php +++ b/lib/private/Encryption/Util.php @@ -220,7 +220,7 @@ class Util { * get the owner and the path for the file relative to the owners files folder * * @param string $path - * @return array + * @return array{0: string, 1: string} * @throws \BadMethodCallException */ public function getUidAndFilename($path) { diff --git a/lib/private/Files/AppData/AppData.php b/lib/private/Files/AppData/AppData.php index 53f69be7127..471de799c2f 100644 --- a/lib/private/Files/AppData/AppData.php +++ b/lib/private/Files/AppData/AppData.php @@ -38,21 +38,12 @@ use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFolder; class AppData implements IAppData { - - /** @var IRootFolder */ - private $rootFolder; - - /** @var SystemConfig */ - private $config; - - /** @var string */ - private $appId; - - /** @var Folder */ - private $folder; - - /** @var (ISimpleFolder|NotFoundException)[]|CappedMemoryCache */ - private $folders; + private IRootFolder $rootFolder; + private SystemConfig $config; + private string $appId; + private ?Folder $folder = null; + /** @var CappedMemoryCache<ISimpleFolder|NotFoundException> */ + private CappedMemoryCache $folders; /** * AppData constructor. diff --git a/lib/private/Files/AppData/Factory.php b/lib/private/Files/AppData/Factory.php index 6d7483158f6..03f8fdedcbd 100644 --- a/lib/private/Files/AppData/Factory.php +++ b/lib/private/Files/AppData/Factory.php @@ -27,17 +27,16 @@ declare(strict_types=1); namespace OC\Files\AppData; use OC\SystemConfig; +use OCP\Files\AppData\IAppDataFactory; +use OCP\Files\IAppData; use OCP\Files\IRootFolder; -class Factory { +class Factory implements IAppDataFactory { + private IRootFolder $rootFolder; + private SystemConfig $config; - /** @var IRootFolder */ - private $rootFolder; - - /** @var SystemConfig */ - private $config; - - private $folders = []; + /** @var array<string, IAppData> */ + private array $folders = []; public function __construct(IRootFolder $rootFolder, SystemConfig $systemConfig) { @@ -45,11 +44,7 @@ class Factory { $this->config = $systemConfig; } - /** - * @param string $appId - * @return AppData - */ - public function get(string $appId): AppData { + public function get(string $appId): IAppData { if (!isset($this->folders[$appId])) { $this->folders[$appId] = new AppData($this->rootFolder, $this->config, $appId); } diff --git a/lib/private/Files/Cache/CacheQueryBuilder.php b/lib/private/Files/Cache/CacheQueryBuilder.php index b5a9101877c..b448424c1a8 100644 --- a/lib/private/Files/Cache/CacheQueryBuilder.php +++ b/lib/private/Files/Cache/CacheQueryBuilder.php @@ -43,7 +43,7 @@ class CacheQueryBuilder extends QueryBuilder { public function selectFileCache(string $alias = null) { $name = $alias ? $alias : 'filecache'; - $this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", 'name', 'mimetype', 'mimepart', 'size', 'mtime', + $this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", "$name.name", 'mimetype', 'mimepart', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum', 'metadata_etag', 'creation_time', 'upload_time') ->from('filecache', $name) ->leftJoin($name, 'filecache_extended', 'fe', $this->expr()->eq("$name.fileid", 'fe.fileid')); diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php index 3bf9abf3524..e7bccbf521c 100644 --- a/lib/private/Files/Cache/QuerySearchHelper.php +++ b/lib/private/Files/Cache/QuerySearchHelper.php @@ -28,6 +28,7 @@ namespace OC\Files\Cache; use OC\Files\Search\QueryOptimizer\QueryOptimizer; use OC\Files\Search\SearchBinaryOperator; use OC\SystemConfig; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICacheEntry; use OCP\Files\IMimeTypeLoader; @@ -110,13 +111,21 @@ class QuerySearchHelper { throw new \InvalidArgumentException("Searching by tag requires the user to be set in the query"); } $query - ->innerJoin('file', 'vcategory_to_object', 'tagmap', $builder->expr()->eq('file.fileid', 'tagmap.objid')) - ->innerJoin('tagmap', 'vcategory', 'tag', $builder->expr()->andX( + ->leftJoin('file', 'vcategory_to_object', 'tagmap', $builder->expr()->eq('file.fileid', 'tagmap.objid')) + ->leftJoin('tagmap', 'vcategory', 'tag', $builder->expr()->andX( $builder->expr()->eq('tagmap.type', 'tag.type'), - $builder->expr()->eq('tagmap.categoryid', 'tag.id') + $builder->expr()->eq('tagmap.categoryid', 'tag.id'), + $builder->expr()->eq('tag.type', $builder->createNamedParameter('files')), + $builder->expr()->eq('tag.uid', $builder->createNamedParameter($user->getUID())) )) - ->andWhere($builder->expr()->eq('tag.type', $builder->createNamedParameter('files'))) - ->andWhere($builder->expr()->eq('tag.uid', $builder->createNamedParameter($user->getUID()))); + ->leftJoin('file', 'systemtag_object_mapping', 'systemtagmap', $builder->expr()->andX( + $builder->expr()->eq('file.fileid', $builder->expr()->castColumn('systemtagmap.objectid', IQueryBuilder::PARAM_INT)), + $builder->expr()->eq('systemtagmap.objecttype', $builder->createNamedParameter('files')) + )) + ->leftJoin('systemtagmap', 'systemtag', 'systemtag', $builder->expr()->andX( + $builder->expr()->eq('systemtag.id', 'systemtagmap.systemtagid'), + $builder->expr()->eq('systemtag.visibility', $builder->createNamedParameter(true)) + )); } $storageFilters = array_values(array_map(function (ICache $cache) { diff --git a/lib/private/Files/Cache/SearchBuilder.php b/lib/private/Files/Cache/SearchBuilder.php index c8c442bcb8c..b5f548dd563 100644 --- a/lib/private/Files/Cache/SearchBuilder.php +++ b/lib/private/Files/Cache/SearchBuilder.php @@ -80,7 +80,7 @@ class SearchBuilder { return $shouldJoin || $this->shouldJoinTags($operator); }, false); } elseif ($operator instanceof ISearchComparison) { - return $operator->getField() === 'tagname' || $operator->getField() === 'favorite'; + return $operator->getField() === 'tagname' || $operator->getField() === 'favorite' || $operator->getField() === 'systemtag'; } return false; } @@ -163,8 +163,12 @@ class SearchBuilder { } elseif ($field === 'favorite') { $field = 'tag.category'; $value = self::TAG_FAVORITE; + } elseif ($field === 'name') { + $field = 'file.name'; } elseif ($field === 'tagname') { $field = 'tag.category'; + } elseif ($field === 'systemtag') { + $field = 'systemtag.name'; } elseif ($field === 'fileid') { $field = 'file.fileid'; } elseif ($field === 'path' && $type === ISearchComparison::COMPARE_EQUAL && $operator->getQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, true)) { @@ -182,6 +186,7 @@ class SearchBuilder { 'path' => 'string', 'size' => 'integer', 'tagname' => 'string', + 'systemtag' => 'string', 'favorite' => 'boolean', 'fileid' => 'integer', 'storage' => 'integer', @@ -193,6 +198,7 @@ class SearchBuilder { 'path' => ['eq', 'like', 'clike'], 'size' => ['eq', 'gt', 'lt', 'gte', 'lte'], 'tagname' => ['eq', 'like'], + 'systemtag' => ['eq', 'like'], 'favorite' => ['eq'], 'fileid' => ['eq'], 'storage' => ['eq'], diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php index a5fe04c2cac..c326eeb0b6c 100644 --- a/lib/private/Files/Config/UserMountCache.php +++ b/lib/private/Files/Config/UserMountCache.php @@ -36,7 +36,6 @@ use OCP\Files\Config\ICachedMountInfo; use OCP\Files\Config\IUserMountCache; use OCP\Files\Mount\IMountPoint; use OCP\Files\NotFoundException; -use OCP\ICache; use OCP\IDBConnection; use OCP\IUser; use OCP\IUserManager; @@ -46,30 +45,17 @@ use Psr\Log\LoggerInterface; * Cache mounts points per user in the cache so we can easilly look them up */ class UserMountCache implements IUserMountCache { - /** - * @var IDBConnection - */ - private $connection; - - /** - * @var IUserManager - */ - private $userManager; + private IDBConnection $connection; + private IUserManager $userManager; /** * Cached mount info. - * Map of $userId to ICachedMountInfo. - * - * @var ICache + * @var CappedMemoryCache<ICachedMountInfo[]> **/ - private $mountsForUsers; - + private CappedMemoryCache $mountsForUsers; private LoggerInterface $logger; - - /** - * @var ICache - */ - private $cacheInfoCache; + /** @var CappedMemoryCache<array> */ + private CappedMemoryCache $cacheInfoCache; /** * UserMountCache constructor. @@ -132,6 +118,7 @@ class UserMountCache implements IUserMountCache { foreach ($addedMounts as $mount) { $this->addToCache($mount); + /** @psalm-suppress InvalidArgument */ $this->mountsForUsers[$user->getUID()][] = $mount; } foreach ($removedMounts as $mount) { diff --git a/lib/private/Lock/AbstractLockingProvider.php b/lib/private/Lock/AbstractLockingProvider.php index f4899bbb2b2..6e8289db12e 100644 --- a/lib/private/Lock/AbstractLockingProvider.php +++ b/lib/private/Lock/AbstractLockingProvider.php @@ -30,24 +30,18 @@ use OCP\Lock\ILockingProvider; /** * Base locking provider that keeps track of locks acquired during the current request - * to release any left over locks at the end of the request + * to release any leftover locks at the end of the request */ abstract class AbstractLockingProvider implements ILockingProvider { - /** @var int $ttl */ - protected $ttl; // how long until we clear stray locks in seconds + /** how long until we clear stray locks in seconds */ + protected int $ttl; protected $acquiredLocks = [ 'shared' => [], 'exclusive' => [] ]; - /** - * Check if we've locally acquired a lock - * - * @param string $path - * @param int $type - * @return bool - */ + /** @inheritDoc */ protected function hasAcquiredLock(string $path, int $type): bool { if ($type === self::LOCK_SHARED) { return isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 0; @@ -56,14 +50,9 @@ abstract class AbstractLockingProvider implements ILockingProvider { } } - /** - * Mark a locally acquired lock - * - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - */ - protected function markAcquire(string $path, int $type) { - if ($type === self::LOCK_SHARED) { + /** @inheritDoc */ + protected function markAcquire(string $path, int $targetType): void { + if ($targetType === self::LOCK_SHARED) { if (!isset($this->acquiredLocks['shared'][$path])) { $this->acquiredLocks['shared'][$path] = 0; } @@ -73,13 +62,8 @@ abstract class AbstractLockingProvider implements ILockingProvider { } } - /** - * Mark a release of a locally acquired lock - * - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - */ - protected function markRelease(string $path, int $type) { + /** @inheritDoc */ + protected function markRelease(string $path, int $type): void { if ($type === self::LOCK_SHARED) { if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) { $this->acquiredLocks['shared'][$path]--; @@ -92,13 +76,8 @@ abstract class AbstractLockingProvider implements ILockingProvider { } } - /** - * Change the type of an existing tracked lock - * - * @param string $path - * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE - */ - protected function markChange(string $path, int $targetType) { + /** @inheritDoc */ + protected function markChange(string $path, int $targetType): void { if ($targetType === self::LOCK_SHARED) { unset($this->acquiredLocks['exclusive'][$path]); if (!isset($this->acquiredLocks['shared'][$path])) { @@ -111,10 +90,8 @@ abstract class AbstractLockingProvider implements ILockingProvider { } } - /** - * release all lock acquired by this instance which were marked using the mark* methods - */ - public function releaseAll() { + /** @inheritDoc */ + public function releaseAll(): void { foreach ($this->acquiredLocks['shared'] as $path => $count) { for ($i = 0; $i < $count; $i++) { $this->releaseLock($path, self::LOCK_SHARED); @@ -126,7 +103,7 @@ abstract class AbstractLockingProvider implements ILockingProvider { } } - protected function getOwnSharedLockCount(string $path) { - return isset($this->acquiredLocks['shared'][$path]) ? $this->acquiredLocks['shared'][$path] : 0; + protected function getOwnSharedLockCount(string $path): int { + return $this->acquiredLocks['shared'][$path] ?? 0; } } diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php index 5eb03ad856b..fb8af8ac55b 100644 --- a/lib/private/Lock/DBLockingProvider.php +++ b/lib/private/Lock/DBLockingProvider.php @@ -9,6 +9,7 @@ * @author Ole Ostergaard <ole.c.ostergaard@gmail.com> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Carl Schwan <carl@carlschwan.eu> * * @license AGPL-3.0 * @@ -33,51 +34,40 @@ use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; -use Psr\Log\LoggerInterface; /** * Locking provider that stores the locks in the database */ class DBLockingProvider extends AbstractLockingProvider { - /** - * @var \OCP\IDBConnection - */ - private $connection; - - private LoggerInterface $logger; - - /** - * @var \OCP\AppFramework\Utility\ITimeFactory - */ - private $timeFactory; - - private $sharedLocks = []; + private IDBConnection $connection; + private ITimeFactory $timeFactory; + private array $sharedLocks = []; + private bool $cacheSharedLocks; - /** - * @var bool - */ - private $cacheSharedLocks; + public function __construct( + IDBConnection $connection, + ITimeFactory $timeFactory, + int $ttl = 3600, + bool $cacheSharedLocks = true + ) { + $this->connection = $connection; + $this->timeFactory = $timeFactory; + $this->ttl = $ttl; + $this->cacheSharedLocks = $cacheSharedLocks; + } /** * Check if we have an open shared lock for a path - * - * @param string $path - * @return bool */ protected function isLocallyLocked(string $path): bool { return isset($this->sharedLocks[$path]) && $this->sharedLocks[$path]; } - /** - * Mark a locally acquired lock - * - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - */ - protected function markAcquire(string $path, int $type) { - parent::markAcquire($path, $type); + /** @inheritDoc */ + protected function markAcquire(string $path, int $targetType): void { + parent::markAcquire($path, $targetType); if ($this->cacheSharedLocks) { - if ($type === self::LOCK_SHARED) { + if ($targetType === self::LOCK_SHARED) { $this->sharedLocks[$path] = true; } } @@ -85,11 +75,8 @@ class DBLockingProvider extends AbstractLockingProvider { /** * Change the type of an existing tracked lock - * - * @param string $path - * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ - protected function markChange(string $path, int $targetType) { + protected function markChange(string $path, int $targetType): void { parent::markChange($path, $targetType); if ($this->cacheSharedLocks) { if ($targetType === self::LOCK_SHARED) { @@ -101,28 +88,7 @@ class DBLockingProvider extends AbstractLockingProvider { } /** - * @param bool $cacheSharedLocks - */ - public function __construct( - IDBConnection $connection, - LoggerInterface $logger, - ITimeFactory $timeFactory, - int $ttl = 3600, - $cacheSharedLocks = true - ) { - $this->connection = $connection; - $this->logger = $logger; - $this->timeFactory = $timeFactory; - $this->ttl = $ttl; - $this->cacheSharedLocks = $cacheSharedLocks; - } - - /** * Insert a file locking row if it does not exists. - * - * @param string $path - * @param int $lock - * @return int number of inserted rows */ protected function initLockField(string $path, int $lock = 0): int { $expire = $this->getExpireTime(); @@ -133,25 +99,21 @@ class DBLockingProvider extends AbstractLockingProvider { ]); } - /** - * @return int - */ protected function getExpireTime(): int { return $this->timeFactory->getTime() + $this->ttl; } - /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @return bool - */ + /** @inheritDoc */ public function isLocked(string $path, int $type): bool { if ($this->hasAcquiredLock($path, $type)) { return true; } - $query = $this->connection->prepare('SELECT `lock` from `*PREFIX*file_locks` WHERE `key` = ?'); - $query->execute([$path]); - $lockValue = (int)$query->fetchOne(); + $query = $this->connection->getQueryBuilder(); + $query->select('lock') + ->from('file_locks') + ->where($query->expr()->eq('key', $query->createNamedParameter($path))); + $result = $query->executeQuery(); + $lockValue = (int)$result->fetchOne(); if ($type === self::LOCK_SHARED) { if ($this->isLocallyLocked($path)) { // if we have a shared lock we kept open locally but it's released we always have at least 1 shared lock in the db @@ -166,21 +128,20 @@ class DBLockingProvider extends AbstractLockingProvider { } } - /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @throws \OCP\Lock\LockedException - */ - public function acquireLock(string $path, int $type, string $readablePath = null) { + /** @inheritDoc */ + public function acquireLock(string $path, int $type, ?string $readablePath = null): void { $expire = $this->getExpireTime(); if ($type === self::LOCK_SHARED) { if (!$this->isLocallyLocked($path)) { $result = $this->initLockField($path, 1); if ($result <= 0) { - $result = $this->connection->executeUpdate( - 'UPDATE `*PREFIX*file_locks` SET `lock` = `lock` + 1, `ttl` = ? WHERE `key` = ? AND `lock` >= 0', - [$expire, $path] - ); + $query = $this->connection->getQueryBuilder(); + $query->update('file_locks') + ->set('lock', $query->func()->add('lock', $query->createNamedParameter(1, IQueryBuilder::PARAM_INT))) + ->set('ttl', $query->createNamedParameter($expire)) + ->where($query->expr()->eq('key', $query->createNamedParameter($path))) + ->andWhere($query->expr()->gte('lock', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT))); + $result = $query->executeStatement(); } } else { $result = 1; @@ -192,10 +153,13 @@ class DBLockingProvider extends AbstractLockingProvider { } $result = $this->initLockField($path, -1); if ($result <= 0) { - $result = $this->connection->executeUpdate( - 'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = ?', - [$expire, $path, $existing] - ); + $query = $this->connection->getQueryBuilder(); + $query->update('file_locks') + ->set('lock', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT)) + ->set('ttl', $query->createNamedParameter($expire, IQueryBuilder::PARAM_INT)) + ->where($query->expr()->eq('key', $query->createNamedParameter($path))) + ->andWhere($query->expr()->eq('lock', $query->createNamedParameter($existing))); + $result = $query->executeStatement(); } } if ($result !== 1) { @@ -204,52 +168,53 @@ class DBLockingProvider extends AbstractLockingProvider { $this->markAcquire($path, $type); } - /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - */ - public function releaseLock(string $path, int $type) { + /** @inheritDoc */ + public function releaseLock(string $path, int $type): void { $this->markRelease($path, $type); // we keep shared locks till the end of the request so we can re-use them if ($type === self::LOCK_EXCLUSIVE) { - $this->connection->executeUpdate( - 'UPDATE `*PREFIX*file_locks` SET `lock` = 0 WHERE `key` = ? AND `lock` = -1', - [$path] - ); + $qb = $this->connection->getQueryBuilder(); + $qb->update('file_locks') + ->set('lock', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)) + ->where($qb->expr()->eq('key', $qb->createNamedParameter($path))) + ->andWhere($qb->expr()->eq('lock', $qb->createNamedParameter(-1, IQueryBuilder::PARAM_INT))); + $qb->executeStatement(); } elseif (!$this->cacheSharedLocks) { - $query = $this->connection->getQueryBuilder(); - $query->update('file_locks') - ->set('lock', $query->func()->subtract('lock', $query->createNamedParameter(1))) - ->where($query->expr()->eq('key', $query->createNamedParameter($path))) - ->andWhere($query->expr()->gt('lock', $query->createNamedParameter(0))); - $query->execute(); + $qb = $this->connection->getQueryBuilder(); + $qb->update('file_locks') + ->set('lock', $qb->func()->subtract('lock', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT))) + ->where($qb->expr()->eq('key', $qb->createNamedParameter($path))) + ->andWhere($qb->expr()->gt('lock', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))); + $qb->executeStatement(); } } - /** - * Change the type of an existing lock - * - * @param string $path - * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @throws \OCP\Lock\LockedException - */ - public function changeLock(string $path, int $targetType) { + /** @inheritDoc */ + public function changeLock(string $path, int $targetType): void { $expire = $this->getExpireTime(); if ($targetType === self::LOCK_SHARED) { - $result = $this->connection->executeUpdate( - 'UPDATE `*PREFIX*file_locks` SET `lock` = 1, `ttl` = ? WHERE `key` = ? AND `lock` = -1', - [$expire, $path] - ); + $qb = $this->connection->getQueryBuilder(); + $result = $qb->update('file_locks') + ->set('lock', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT)) + ->set('ttl', $qb->createNamedParameter($expire, IQueryBuilder::PARAM_INT)) + ->where($qb->expr()->andX( + $qb->expr()->eq('key', $qb->createNamedParameter($path)), + $qb->expr()->eq('lock', $qb->createNamedParameter(-1, IQueryBuilder::PARAM_INT)) + ))->executeStatement(); } else { // since we only keep one shared lock in the db we need to check if we have more then one shared lock locally manually if (isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 1) { throw new LockedException($path); } - $result = $this->connection->executeUpdate( - 'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = 1', - [$expire, $path] - ); + $qb = $this->connection->getQueryBuilder(); + $result = $qb->update('file_locks') + ->set('lock', $qb->createNamedParameter(-1, IQueryBuilder::PARAM_INT)) + ->set('ttl', $qb->createNamedParameter($expire, IQueryBuilder::PARAM_INT)) + ->where($qb->expr()->andX( + $qb->expr()->eq('key', $qb->createNamedParameter($path)), + $qb->expr()->eq('lock', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT)) + ))->executeStatement(); } if ($result !== 1) { throw new LockedException($path); @@ -257,16 +222,14 @@ class DBLockingProvider extends AbstractLockingProvider { $this->markChange($path, $targetType); } - /** - * cleanup empty locks - */ - public function cleanExpiredLocks() { + /** @inheritDoc */ + public function cleanExpiredLocks(): void { $expire = $this->timeFactory->getTime(); try { - $this->connection->executeUpdate( - 'DELETE FROM `*PREFIX*file_locks` WHERE `ttl` < ?', - [$expire] - ); + $qb = $this->connection->getQueryBuilder(); + $qb->delete('file_locks') + ->where($qb->expr()->lt('ttl', $qb->createNamedParameter($expire, IQueryBuilder::PARAM_INT))) + ->executeStatement(); } catch (\Exception $e) { // If the table is missing, the clean up was successful if ($this->connection->tableExists('file_locks')) { @@ -275,10 +238,8 @@ class DBLockingProvider extends AbstractLockingProvider { } } - /** - * release all lock acquired by this instance which were marked using the mark* methods - */ - public function releaseAll() { + /** @inheritDoc */ + public function releaseAll(): void { parent::releaseAll(); if (!$this->cacheSharedLocks) { @@ -292,15 +253,15 @@ class DBLockingProvider extends AbstractLockingProvider { $chunkedPaths = array_chunk($lockedPaths, 100); - foreach ($chunkedPaths as $chunk) { - $builder = $this->connection->getQueryBuilder(); - - $query = $builder->update('file_locks') - ->set('lock', $builder->func()->subtract('lock', $builder->expr()->literal(1))) - ->where($builder->expr()->in('key', $builder->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY))) - ->andWhere($builder->expr()->gt('lock', new Literal(0))); + $qb = $this->connection->getQueryBuilder(); + $qb->update('file_locks') + ->set('lock', $qb->func()->subtract('lock', $qb->expr()->literal(1))) + ->where($qb->expr()->in('key', $qb->createParameter('chunk'))) + ->andWhere($qb->expr()->gt('lock', new Literal(0))); - $query->execute(); + foreach ($chunkedPaths as $chunk) { + $qb->setParameter('chunk', $chunk, IQueryBuilder::PARAM_STR_ARRAY); + $qb->executeStatement(); } } } diff --git a/lib/private/Lock/MemcacheLockingProvider.php b/lib/private/Lock/MemcacheLockingProvider.php index 008a7875d7e..d4eebd7c302 100644 --- a/lib/private/Lock/MemcacheLockingProvider.php +++ b/lib/private/Lock/MemcacheLockingProvider.php @@ -32,31 +32,19 @@ use OCP\IMemcacheTTL; use OCP\Lock\LockedException; class MemcacheLockingProvider extends AbstractLockingProvider { - /** - * @var \OCP\IMemcache - */ - private $memcache; + private IMemcache $memcache; - /** - * @param \OCP\IMemcache $memcache - * @param int $ttl - */ public function __construct(IMemcache $memcache, int $ttl = 3600) { $this->memcache = $memcache; $this->ttl = $ttl; } - private function setTTL(string $path) { + private function setTTL(string $path): void { if ($this->memcache instanceof IMemcacheTTL) { $this->memcache->setTTL($path, $this->ttl); } } - /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @return bool - */ public function isLocked(string $path, int $type): bool { $lockValue = $this->memcache->get($path); if ($type === self::LOCK_SHARED) { @@ -68,13 +56,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider { } } - /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @param string $readablePath human readable path to use in error messages - * @throws \OCP\Lock\LockedException - */ - public function acquireLock(string $path, int $type, string $readablePath = null) { + public function acquireLock(string $path, int $type, ?string $readablePath = null): void { if ($type === self::LOCK_SHARED) { if (!$this->memcache->inc($path)) { throw new LockedException($path, null, $this->getExistingLockForException($path), $readablePath); @@ -89,11 +71,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider { $this->markAcquire($path, $type); } - /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - */ - public function releaseLock(string $path, int $type) { + public function releaseLock(string $path, int $type): void { if ($type === self::LOCK_SHARED) { $ownSharedLockCount = $this->getOwnSharedLockCount($path); $newValue = 0; @@ -120,14 +98,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider { $this->markRelease($path, $type); } - /** - * Change the type of an existing lock - * - * @param string $path - * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @throws \OCP\Lock\LockedException - */ - public function changeLock(string $path, int $targetType) { + public function changeLock(string $path, int $targetType): void { if ($targetType === self::LOCK_SHARED) { if (!$this->memcache->cas($path, 'exclusive', 1)) { throw new LockedException($path, null, $this->getExistingLockForException($path)); @@ -142,7 +113,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider { $this->markChange($path, $targetType); } - private function getExistingLockForException($path) { + private function getExistingLockForException(string $path): string { $existing = $this->memcache->get($path); if (!$existing) { return 'none'; diff --git a/lib/private/Lock/NoopLockingProvider.php b/lib/private/Lock/NoopLockingProvider.php index 95ae8cf0cda..ff56932a894 100644 --- a/lib/private/Lock/NoopLockingProvider.php +++ b/lib/private/Lock/NoopLockingProvider.php @@ -45,28 +45,28 @@ class NoopLockingProvider implements ILockingProvider { /** * {@inheritdoc} */ - public function acquireLock(string $path, int $type, string $readablePath = null) { + public function acquireLock(string $path, int $type, ?string $readablePath = null): void { // do nothing } /** * {@inheritdoc} */ - public function releaseLock(string $path, int $type) { + public function releaseLock(string $path, int $type): void { // do nothing } /**1 * {@inheritdoc} */ - public function releaseAll() { + public function releaseAll(): void { // do nothing } /** * {@inheritdoc} */ - public function changeLock(string $path, int $targetType) { + public function changeLock(string $path, int $targetType): void { // do nothing } } diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php index e058a15bfa5..d52191544f3 100644 --- a/lib/private/Preview/Generator.php +++ b/lib/private/Preview/Generator.php @@ -115,7 +115,7 @@ class Generator { * Generates previews of a file * * @param File $file - * @param array $specifications + * @param non-empty-array $specifications * @param string $mimeType * @return ISimpleFile the last preview that was generated * @throws NotFoundException @@ -213,6 +213,7 @@ class Generator { throw new NotFoundException('Cached preview size 0, invalid!'); } } + assert($preview !== null); // Free memory being used by the embedded image resource. Without this the image is kept in memory indefinitely. // Garbage Collection does NOT free this memory. We have to do it ourselves. @@ -226,15 +227,25 @@ class Generator { /** * Generate a small image straight away without generating a max preview first * Preview generated is 256x256 + * + * @throws NotFoundException */ - private function getSmallImagePreview(ISimpleFolder $previewFolder, File $file, string $mimeType, string $prefix, bool $crop) { + private function getSmallImagePreview(ISimpleFolder $previewFolder, File $file, string $mimeType, string $prefix, bool $crop): ISimpleFile { $nodes = $previewFolder->getDirectoryListing(); foreach ($nodes as $node) { $name = $node->getName(); - if (($prefix === '' || strpos($name, $prefix) === 0) - && (str_starts_with($name, '256-256-crop') && $crop || str_starts_with($name, '256-256') && !$crop)) { - return $node; + if (($prefix === '' || str_starts_with($name, $prefix))) { + // Prefix match + if (str_starts_with($name, $prefix . '256-256-crop') && $crop) { + // Cropped image + return $node; + } + + if (str_starts_with($name, $prefix . '256-256.') && !$crop) { + // Uncropped image + return $node; + } } } @@ -255,7 +266,7 @@ class Generator { continue; } - $preview = $this->helper->getThumbnail($provider, $file, 256, 256, true); + $preview = $this->helper->getThumbnail($provider, $file, 256, 256, $crop); if (!($preview instanceof IImage)) { continue; @@ -284,6 +295,8 @@ class Generator { return $file; } } + + throw new NotFoundException('No provider successfully handled the preview generation'); } /** diff --git a/lib/private/Repair.php b/lib/private/Repair.php index 91bfd47f5de..fb65789dd8a 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -72,7 +72,6 @@ use OC\Repair\RepairInvalidShares; use OC\Repair\RepairMimeTypes; use OC\Repair\SqliteAutoincrement; use OC\Template\JSCombiner; -use OC\Template\SCSSCacher; use OCP\AppFramework\QueryException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Collaboration\Resources\IManager; @@ -194,7 +193,7 @@ class Repair implements IOutput { \OC::$server->query(Installer::class) ), new AddLogRotateJob(\OC::$server->getJobList()), - new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(SCSSCacher::class), \OC::$server->query(JSCombiner::class)), + new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(JSCombiner::class)), new ClearGeneratedAvatarCache(\OC::$server->getConfig(), \OC::$server->query(AvatarManager::class)), new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()), new AddCleanupUpdaterBackupsJob(\OC::$server->getJobList()), diff --git a/lib/private/Repair/ClearFrontendCaches.php b/lib/private/Repair/ClearFrontendCaches.php index 96a7833fecc..47f037fd626 100644 --- a/lib/private/Repair/ClearFrontendCaches.php +++ b/lib/private/Repair/ClearFrontendCaches.php @@ -25,7 +25,6 @@ namespace OC\Repair; use OC\Template\JSCombiner; -use OC\Template\SCSSCacher; use OCP\ICacheFactory; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; @@ -35,17 +34,12 @@ class ClearFrontendCaches implements IRepairStep { /** @var ICacheFactory */ protected $cacheFactory; - /** @var SCSSCacher */ - protected $scssCacher; - /** @var JSCombiner */ protected $jsCombiner; public function __construct(ICacheFactory $cacheFactory, - SCSSCacher $SCSSCacher, JSCombiner $JSCombiner) { $this->cacheFactory = $cacheFactory; - $this->scssCacher = $SCSSCacher; $this->jsCombiner = $JSCombiner; } @@ -59,9 +53,6 @@ class ClearFrontendCaches implements IRepairStep { $c->clear(); $output->info('Image cache cleared'); - $this->scssCacher->resetCache(); - $output->info('SCSS cache cleared'); - $this->jsCombiner->resetCache(); $output->info('JS cache cleared'); } catch (\Exception $e) { diff --git a/lib/private/Security/SecureRandom.php b/lib/private/Security/SecureRandom.php index 4bf8995d737..cbd1dc8db6d 100644 --- a/lib/private/Security/SecureRandom.php +++ b/lib/private/Security/SecureRandom.php @@ -40,14 +40,19 @@ use OCP\Security\ISecureRandom; */ class SecureRandom implements ISecureRandom { /** - * Generate a random string of specified length. + * Generate a secure random string of specified length. * @param int $length The length of the generated string * @param string $characters An optional list of characters to use if no character list is * specified all valid base64 characters are used. * @return string + * @throws \LengthException if an invalid length is requested */ public function generate(int $length, string $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'): string { + if ($length <= 0) { + throw new \LengthException('Invalid length specified: ' . $length . ' must be bigger than 0'); + } + $maxCharIndex = \strlen($characters) - 1; $randomString = ''; diff --git a/lib/private/Server.php b/lib/private/Server.php index 5308de21f51..6e6fa430489 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -1109,7 +1109,6 @@ class Server extends ServerContainer implements IServerContainer { } return new DBLockingProvider( $c->get(IDBConnection::class), - $c->get(LoggerInterface::class), new TimeFactory(), $ttl, !\OC::$CLI @@ -1439,6 +1438,8 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(IMetadataManager::class, MetadataManager::class); + $this->registerAlias(\OCP\Files\AppData\IAppDataFactory::class, \OC\Files\AppData\Factory::class); + $this->connectDispatcher(); } @@ -2300,7 +2301,7 @@ class Server extends ServerContainer implements IServerContainer { /** * @return \OCP\Files\IAppData - * @deprecated 20.0.0 + * @deprecated 20.0.0 Use get(\OCP\Files\AppData\IAppDataFactory::class)->get($app) instead */ public function getAppDataDir($app) { /** @var \OC\Files\AppData\Factory $factory */ diff --git a/lib/private/Setup/AbstractDatabase.php b/lib/private/Setup/AbstractDatabase.php index 8690e7c1c66..5ee9548564c 100644 --- a/lib/private/Setup/AbstractDatabase.php +++ b/lib/private/Setup/AbstractDatabase.php @@ -141,9 +141,9 @@ abstract class AbstractDatabase { } /** - * @param string $userName + * @param string $username */ - abstract public function setupDatabase($userName); + abstract public function setupDatabase($username); public function runMigrations() { if (!is_dir(\OC::$SERVERROOT."/core/Migrations")) { diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php index 920baf3e4ee..7bd8fa7b1ec 100644 --- a/lib/private/Setup/MySQL.php +++ b/lib/private/Setup/MySQL.php @@ -135,9 +135,8 @@ class MySQL extends AbstractDatabase { /** * @param $username * @param IDBConnection $connection - * @return array */ - private function createSpecificUser($username, $connection) { + private function createSpecificUser($username, $connection): void { try { //user already specified in config $oldUser = $this->config->getValue('dbuser', false); diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index 9638706025b..520bd17d3cf 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -671,10 +671,10 @@ class DefaultShareProvider implements IShareProvider { } // todo? maybe get these from the oc_mounts table - $childMountNodes = array_filter($node->getDirectoryListing(), function (Node $node) { + $childMountNodes = array_filter($node->getDirectoryListing(), function (Node $node): bool { return $node->getInternalPath() === ''; }); - $childMountRootIds = array_map(function (Node $node) { + $childMountRootIds = array_map(function (Node $node): int { return $node->getId(); }, $childMountNodes); @@ -682,18 +682,29 @@ class DefaultShareProvider implements IShareProvider { $qb->andWhere( $qb->expr()->orX( $qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())), - $qb->expr()->in('f.fileid', $qb->createNamedParameter($childMountRootIds, IQueryBuilder::PARAM_INT_ARRAY)) + $qb->expr()->in('f.fileid', $qb->createParameter('chunk')) ) ); $qb->orderBy('id'); - $cursor = $qb->execute(); $shares = []; - while ($data = $cursor->fetch()) { - $shares[$data['fileid']][] = $this->createShare($data); + + $chunks = array_chunk($childMountRootIds, 1000); + + // Force the request to be run when there is 0 mount. + if (count($chunks) === 0) { + $chunks = [[]]; + } + + foreach ($chunks as $chunk) { + $qb->setParameter('chunk', $chunk, IQueryBuilder::PARAM_INT_ARRAY); + $cursor = $qb->executeQuery(); + while ($data = $cursor->fetch()) { + $shares[$data['fileid']][] = $this->createShare($data); + } + $cursor->closeCursor(); } - $cursor->closeCursor(); return $shares; } diff --git a/lib/private/Template/CSSResourceLocator.php b/lib/private/Template/CSSResourceLocator.php index a038ba7ce9b..2cbf12ce65d 100644 --- a/lib/private/Template/CSSResourceLocator.php +++ b/lib/private/Template/CSSResourceLocator.php @@ -35,18 +35,12 @@ use Psr\Log\LoggerInterface; class CSSResourceLocator extends ResourceLocator { - /** @var SCSSCacher */ - protected $scssCacher; - /** * @param string $theme * @param array $core_map * @param array $party_map - * @param SCSSCacher $scssCacher */ - public function __construct(LoggerInterface $logger, $theme, $core_map, $party_map, $scssCacher) { - $this->scssCacher = $scssCacher; - + public function __construct(LoggerInterface $logger, $theme, $core_map, $party_map) { parent::__construct($logger, $theme, $core_map, $party_map); } @@ -57,8 +51,6 @@ class CSSResourceLocator extends ResourceLocator { $app = substr($style, 0, strpos($style, '/')); if (strpos($style, '3rdparty') === 0 && $this->appendIfExist($this->thirdpartyroot, $style.'.css') - || $this->cacheAndAppendScssIfExist($this->serverroot, $style.'.scss', $app) - || $this->cacheAndAppendScssIfExist($this->serverroot, 'core/'.$style.'.scss') || $this->appendIfExist($this->serverroot, $style.'.css') || $this->appendIfExist($this->serverroot, 'core/'.$style.'.css') ) { @@ -81,9 +73,7 @@ class CSSResourceLocator extends ResourceLocator { // turned into cwd. $app_path = realpath($app_path); - if (!$this->cacheAndAppendScssIfExist($app_path, $style.'.scss', $app)) { - $this->append($app_path, $style.'.css', $app_url); - } + $this->append($app_path, $style.'.css', $app_url); } /** @@ -96,30 +86,6 @@ class CSSResourceLocator extends ResourceLocator { || $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$style.'.css'); } - /** - * cache and append the scss $file if exist at $root - * - * @param string $root path to check - * @param string $file the filename - * @return bool True if the resource was found and cached, false otherwise - */ - protected function cacheAndAppendScssIfExist($root, $file, $app = 'core') { - if (is_file($root.'/'.$file)) { - if ($this->scssCacher !== null) { - if ($this->scssCacher->process($root, $file, $app)) { - $this->append($this->serverroot, $this->scssCacher->getCachedSCSS($app, $file), \OC::$WEBROOT, true, true); - return true; - } else { - $this->logger->warning('Failed to compile and/or save '.$root.'/'.$file, ['app' => 'core']); - return false; - } - } else { - return true; - } - } - return false; - } - public function append($root, $file, $webRoot = null, $throw = true, $scss = false) { if (!$scss) { parent::append($root, $file, $webRoot, $throw); diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php deleted file mode 100644 index 9ea0ad22de8..00000000000 --- a/lib/private/Template/SCSSCacher.php +++ /dev/null @@ -1,498 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, John Molakvoæ (skjnldsv@protonmail.com) - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Julius Haertl <jus@bitgrid.net> - * @author Julius Härtl <jus@bitgrid.net> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Roland Tapken <roland@bitarbeiter.net> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ -namespace OC\Template; - -use OC\AppConfig; -use OC\Files\AppData\Factory; -use OC\Memcache\NullCache; -use OCP\AppFramework\Utility\ITimeFactory; -use OCP\Files\IAppData; -use OCP\Files\NotFoundException; -use OCP\Files\NotPermittedException; -use OCP\Files\SimpleFS\ISimpleFile; -use OCP\Files\SimpleFS\ISimpleFolder; -use OCP\ICache; -use OCP\ICacheFactory; -use OCP\IConfig; -use OCP\IMemcache; -use OCP\IURLGenerator; -use Psr\Log\LoggerInterface; -use ScssPhp\ScssPhp\Compiler; -use ScssPhp\ScssPhp\OutputStyle; - -class SCSSCacher { - protected LoggerInterface $logger; - - /** @var IAppData */ - protected $appData; - - /** @var IURLGenerator */ - protected $urlGenerator; - - /** @var IConfig */ - protected $config; - - /** @var \OC_Defaults */ - private $defaults; - - /** @var string */ - protected $serverRoot; - - /** @var ICache */ - protected $depsCache; - - /** @var null|string */ - private $injectedVariables; - - /** @var ICacheFactory */ - private $cacheFactory; - - /** @var ICache */ - private $isCachedCache; - - /** @var ITimeFactory */ - private $timeFactory; - - /** @var IMemcache */ - private $lockingCache; - /** @var AppConfig */ - private $appConfig; - - /** - * @param string $serverRoot - */ - public function __construct(LoggerInterface $logger, - Factory $appDataFactory, - IURLGenerator $urlGenerator, - IConfig $config, - \OC_Defaults $defaults, - $serverRoot, - ICacheFactory $cacheFactory, - ITimeFactory $timeFactory, - AppConfig $appConfig) { - $this->logger = $logger; - $this->appData = $appDataFactory->get('css'); - $this->urlGenerator = $urlGenerator; - $this->config = $config; - $this->defaults = $defaults; - $this->serverRoot = $serverRoot; - $this->cacheFactory = $cacheFactory; - $this->depsCache = $cacheFactory->createDistributed('SCSS-deps-' . md5($this->urlGenerator->getBaseUrl())); - $this->isCachedCache = $cacheFactory->createDistributed('SCSS-cached-' . md5($this->urlGenerator->getBaseUrl())); - $lockingCache = $cacheFactory->createDistributed('SCSS-locks-' . md5($this->urlGenerator->getBaseUrl())); - if (!($lockingCache instanceof IMemcache)) { - $lockingCache = new NullCache(); - } - $this->lockingCache = $lockingCache; - $this->timeFactory = $timeFactory; - $this->appConfig = $appConfig; - } - - /** - * Process the caching process if needed - * - * @param string $root Root path to the nextcloud installation - * @param string $file - * @param string $app The app name - * @return boolean - * @throws NotPermittedException - */ - public function process(string $root, string $file, string $app): bool { - $path = explode('/', $root . '/' . $file); - - $fileNameSCSS = array_pop($path); - $fileNameCSS = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS)), $app); - - $path = implode('/', $path); - $webDir = $this->getWebDir($path, $app, $this->serverRoot, \OC::$WEBROOT); - - $this->logger->debug('SCSSCacher::process ordinary check follows', ['app' => 'scss_cacher']); - - try { - $folder = $this->appData->getFolder($app); - } catch (NotFoundException $e) { - // creating css appdata folder - $folder = $this->appData->newFolder($app); - } - - $lockKey = $webDir . '/' . $fileNameSCSS; - - if (!$this->lockingCache->add($lockKey, 'locked!', 120)) { - $this->logger->debug('SCSSCacher::process could not get lock for ' . $lockKey . ' and will wait 10 seconds for cached file to be available', ['app' => 'scss_cacher']); - $retry = 0; - sleep(1); - while ($retry < 10) { - $this->appConfig->clearCachedConfig(); - $this->logger->debug('SCSSCacher::process check in while loop follows', ['app' => 'scss_cacher']); - if (!$this->variablesChanged() && $this->isCached($fileNameCSS, $app)) { - // Inject icons vars css if any - $this->logger->debug("SCSSCacher::process cached file for app '$app' and file '$fileNameCSS' is now available after $retry s. Moving on...", ['app' => 'scss_cacher']); - return true; - } - sleep(1); - $retry++; - } - $this->logger->debug('SCSSCacher::process Giving up scss caching for ' . $lockKey, ['app' => 'scss_cacher']); - return false; - } - - $this->logger->debug('SCSSCacher::process Lock acquired for ' . $lockKey, ['app' => 'scss_cacher']); - try { - $cached = $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir); - } catch (\Exception $e) { - $this->lockingCache->remove($lockKey); - throw $e; - } - - // Cleaning lock - $this->lockingCache->remove($lockKey); - $this->logger->debug('SCSSCacher::process Lock removed for ' . $lockKey, ['app' => 'scss_cacher']); - - return $cached; - } - - /** - * @param $appName - * @param $fileName - * @return ISimpleFile - */ - public function getCachedCSS(string $appName, string $fileName): ISimpleFile { - $folder = $this->appData->getFolder($appName); - $cachedFileName = $this->prependVersionPrefix($this->prependBaseurlPrefix($fileName), $appName); - - return $folder->getFile($cachedFileName); - } - - /** - * Check if the file is cached or not - * @param string $fileNameCSS - * @param string $app - * @return boolean - */ - private function isCached(string $fileNameCSS, string $app) { - $key = $this->config->getSystemValue('version') . '/' . $app . '/' . $fileNameCSS; - - // If the file mtime is more recent than our cached one, - // let's consider the file is properly cached - if ($cacheValue = $this->isCachedCache->get($key)) { - if ($cacheValue > $this->timeFactory->getTime()) { - return true; - } - } - $this->logger->debug("SCSSCacher::isCached $fileNameCSS isCachedCache is expired or unset", ['app' => 'scss_cacher']); - - // Creating file cache if none for further checks - try { - $folder = $this->appData->getFolder($app); - } catch (NotFoundException $e) { - $this->logger->debug("SCSSCacher::isCached app data folder for $app could not be fetched", ['app' => 'scss_cacher']); - return false; - } - - // Checking if file size is coherent - // and if one of the css dependency changed - try { - $cachedFile = $folder->getFile($fileNameCSS); - if ($cachedFile->getSize() > 0) { - $depFileName = $fileNameCSS . '.deps'; - $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName); - if ($deps === null) { - $depFile = $folder->getFile($depFileName); - $deps = $depFile->getContent(); - // Set to memcache for next run - $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps); - } - $deps = json_decode($deps, true); - - foreach ((array) $deps as $file => $mtime) { - if (!file_exists($file) || filemtime($file) > $mtime) { - $this->logger->debug("SCSSCacher::isCached $fileNameCSS is not considered as cached due to deps file $file", ['app' => 'scss_cacher']); - return false; - } - } - - $this->logger->debug("SCSSCacher::isCached $fileNameCSS dependencies successfully cached for 5 minutes", ['app' => 'scss_cacher']); - // It would probably make sense to adjust this timeout to something higher and see if that has some effect then - $this->isCachedCache->set($key, $this->timeFactory->getTime() + 5 * 60); - return true; - } - $this->logger->debug("SCSSCacher::isCached $fileNameCSS is not considered as cached cacheValue: $cacheValue", ['app' => 'scss_cacher']); - return false; - } catch (NotFoundException $e) { - $this->logger->debug("SCSSCacher::isCached NotFoundException " . $e->getMessage(), ['app' => 'scss_cacher']); - return false; - } - } - - /** - * Check if the variables file has changed - * @return bool - */ - private function variablesChanged(): bool { - $cachedVariables = $this->config->getAppValue('core', 'theming.variables', ''); - $injectedVariables = $this->getInjectedVariables($cachedVariables); - if ($cachedVariables !== md5($injectedVariables)) { - $this->logger->debug('SCSSCacher::variablesChanged storedVariables: ' . json_encode($this->config->getAppValue('core', 'theming.variables')) . ' currentInjectedVariables: ' . json_encode($injectedVariables), ['app' => 'scss_cacher']); - $this->config->setAppValue('core', 'theming.variables', md5($injectedVariables)); - $this->resetCache(); - return true; - } - return false; - } - - /** - * Cache the file with AppData - * - * @param string $path - * @param string $fileNameCSS - * @param string $fileNameSCSS - * @param ISimpleFolder $folder - * @param string $webDir - * @return boolean - * @throws NotPermittedException - */ - private function cache(string $path, string $fileNameCSS, string $fileNameSCSS, ISimpleFolder $folder, string $webDir) { - $scss = new Compiler(); - $scss->setImportPaths([ - $path, - $this->serverRoot . '/core/css/' - ]); - - // Continue after throw - if ($this->config->getSystemValue('debug')) { - // Debug mode - $scss->setOutputStyle(OutputStyle::EXPANDED); - } else { - // Compression - $scss->setOutputStyle(OutputStyle::COMPRESSED); - } - - try { - $cachedfile = $folder->getFile($fileNameCSS); - } catch (NotFoundException $e) { - $cachedfile = $folder->newFile($fileNameCSS); - } - - $depFileName = $fileNameCSS . '.deps'; - try { - $depFile = $folder->getFile($depFileName); - } catch (NotFoundException $e) { - $depFile = $folder->newFile($depFileName); - } - - // Compile - try { - $compiledScss = $scss->compile( - '$webroot: \'' . $this->getRoutePrefix() . '\';' . - $this->getInjectedVariables() . - '@import "variables.scss";' . - '@import "functions.scss";' . - '@import "' . $fileNameSCSS . '";'); - } catch (\Exception $e) { - $this->logger->error($e->getMessage(), ['app' => 'scss_cacher', 'exception' => $e]); - - return false; - } - - // Gzip file - try { - $gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz - } catch (NotFoundException $e) { - $gzipFile = $folder->newFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz - } - - try { - $data = $this->rebaseUrls($compiledScss, $webDir); - $cachedfile->putContent($data); - $deps = json_encode($scss->getParsedFiles()); - $depFile->putContent($deps); - $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps); - $gzipFile->putContent(gzencode($data, 9)); - $this->logger->debug('SCSSCacher::cache ' . $webDir . '/' . $fileNameSCSS . ' compiled and successfully cached', ['app' => 'scss_cacher']); - - return true; - } catch (NotPermittedException $e) { - $this->logger->error('SCSSCacher::cache unable to cache: ' . $fileNameSCSS, ['app' => 'scss_cacher']); - - return false; - } - } - - /** - * Reset scss cache by deleting all generated css files - * We need to regenerate all files when variables change - */ - public function resetCache() { - $this->logger->debug('SCSSCacher::resetCache', ['app' => 'scss_cacher']); - if (!$this->lockingCache->add('resetCache', 'locked!', 120)) { - $this->logger->debug('SCSSCacher::resetCache Locked', ['app' => 'scss_cacher']); - return; - } - $this->logger->debug('SCSSCacher::resetCache Lock acquired', ['app' => 'scss_cacher']); - $this->injectedVariables = null; - - // do not clear locks - $this->depsCache->clear(); - $this->isCachedCache->clear(); - - $appDirectory = $this->appData->getDirectoryListing(); - foreach ($appDirectory as $folder) { - foreach ($folder->getDirectoryListing() as $file) { - try { - $file->delete(); - } catch (NotPermittedException $e) { - $this->logger->error('SCSSCacher::resetCache unable to delete file: ' . $file->getName(), ['exception' => $e, 'app' => 'scss_cacher']); - } - } - } - $this->logger->debug('SCSSCacher::resetCache css cache cleared!', ['app' => 'scss_cacher']); - $this->lockingCache->remove('resetCache'); - $this->logger->debug('SCSSCacher::resetCache Locking removed', ['app' => 'scss_cacher']); - } - - /** - * @return string SCSS code for variables from OC_Defaults - */ - private function getInjectedVariables(string $cache = ''): string { - if ($this->injectedVariables !== null) { - return $this->injectedVariables; - } - $variables = ''; - foreach ($this->defaults->getScssVariables() as $key => $value) { - $variables .= '$' . $key . ': ' . $value . ' !default;'; - } - - /* - * If we are trying to return the same variables as that are cached - * Then there is no need to do the compile step - */ - if ($cache === md5($variables)) { - $this->injectedVariables = $variables; - return $variables; - } - - // check for valid variables / otherwise fall back to defaults - try { - $scss = new Compiler(); - $scss->compile($variables); - $this->injectedVariables = $variables; - } catch (\Exception $e) { - $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => 'scss_cacher']); - } - - return $variables; - } - - /** - * Add the correct uri prefix to make uri valid again - * @param string $css - * @param string $webDir - * @return string - */ - private function rebaseUrls(string $css, string $webDir): string { - $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x'; - $subst = 'url(\'' . $webDir . '/$1\')'; - - return preg_replace($re, $subst, $css); - } - - /** - * Return the cached css file uri - * @param string $appName the app name - * @param string $fileName - * @return string - */ - public function getCachedSCSS(string $appName, string $fileName): string { - $tmpfileLoc = explode('/', $fileName); - $fileName = array_pop($tmpfileLoc); - $fileName = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName)), $appName); - - return substr($this->urlGenerator->linkToRoute('core.Css.getCss', [ - 'fileName' => $fileName, - 'appName' => $appName, - 'v' => $this->config->getAppValue('core', 'theming.variables', '0') - ]), \strlen(\OC::$WEBROOT) + 1); - } - - /** - * Prepend hashed base url to the css file - * @param string $cssFile - * @return string - */ - private function prependBaseurlPrefix(string $cssFile): string { - return substr(md5($this->urlGenerator->getBaseUrl() . $this->getRoutePrefix()), 0, 4) . '-' . $cssFile; - } - - private function getRoutePrefix() { - $frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true'); - $prefix = \OC::$WEBROOT . '/index.php'; - if ($frontControllerActive) { - $prefix = \OC::$WEBROOT; - } - return $prefix; - } - - /** - * Prepend hashed app version hash - * @param string $cssFile - * @param string $appId - * @return string - */ - private function prependVersionPrefix(string $cssFile, string $appId): string { - $appVersion = \OC_App::getAppVersion($appId); - if ($appVersion !== '0') { - return substr(md5($appVersion), 0, 4) . '-' . $cssFile; - } - $coreVersion = \OC_Util::getVersionString(); - - return substr(md5($coreVersion), 0, 4) . '-' . $cssFile; - } - - /** - * Get WebDir root - * @param string $path the css file path - * @param string $appName the app name - * @param string $serverRoot the server root path - * @param string $webRoot the nextcloud installation root path - * @return string the webDir - */ - private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string { - // Detect if path is within server root AND if path is within an app path - if (strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) { - // Get the file path within the app directory - $appDirectoryPath = explode($appName, $path)[1]; - // Remove the webroot - - return str_replace($webRoot, '', $appWebPath . $appDirectoryPath); - } - - return $webRoot . substr($path, strlen($serverRoot)); - } -} diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index a25e23e9fc6..a5aabc04b61 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -46,7 +46,6 @@ use bantu\IniGetWrapper\IniGetWrapper; use OC\Search\SearchQuery; use OC\Template\JSCombiner; use OC\Template\JSConfigHelper; -use OC\Template\SCSSCacher; use OCP\AppFramework\Http\TemplateResponse; use OCP\Defaults; use OCP\IConfig; @@ -332,18 +331,11 @@ class TemplateLayout extends \OC_Template { // Read the selected theme from the config file $theme = \OC_Util::getTheme(); - if ($compileScss) { - $SCSSCacher = \OC::$server->query(SCSSCacher::class); - } else { - $SCSSCacher = null; - } - $locator = new \OC\Template\CSSResourceLocator( \OC::$server->get(LoggerInterface::class), $theme, [ \OC::$SERVERROOT => \OC::$WEBROOT ], [ \OC::$SERVERROOT => \OC::$WEBROOT ], - $SCSSCacher ); $locator->find($styles); return $locator->getResources(); diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index a9464c27085..4821a2fc632 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -275,7 +275,7 @@ class Database extends ABackend implements ->setMaxResults($limit) ->setFirstResult($offset); - $result = $query->execute(); + $result = $query->executeQuery(); $displayNames = []; while ($row = $result->fetch()) { $displayNames[(string)$row['uid']] = (string)$row['displayname']; diff --git a/lib/private/User/LazyUser.php b/lib/private/User/LazyUser.php index 8b98b112731..8e93d6481ab 100644 --- a/lib/private/User/LazyUser.php +++ b/lib/private/User/LazyUser.php @@ -25,6 +25,7 @@ namespace OC\User; use OCP\IUser; use OCP\IUserManager; +use OCP\UserInterface; class LazyUser implements IUser { private ?IUser $user = null; @@ -83,7 +84,7 @@ class LazyUser implements IUser { return $this->getUser()->getBackendClassName(); } - public function getBackend() { + public function getBackend(): ?UserInterface { return $this->getUser()->getBackend(); } diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index c59cbaa7b20..a6f56585325 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -48,6 +48,8 @@ use OCP\Notification\IManager; use OCP\Support\Subscription\IRegistry; use OCP\User\Backend\IGetRealUIDBackend; use OCP\User\Backend\ISearchKnownUsersBackend; +use OCP\User\Backend\ICheckPasswordBackend; +use OCP\User\Backend\ICountUsersBackend; use OCP\User\Events\BeforeUserCreatedEvent; use OCP\User\Events\UserCreatedEvent; use OCP\UserInterface; @@ -223,7 +225,7 @@ class Manager extends PublicEmitter implements IUserManager { * * @param string $loginName * @param string $password - * @return mixed the User object on success, false otherwise + * @return IUser|false the User object on success, false otherwise */ public function checkPassword($loginName, $password) { $result = $this->checkPasswordNoLogging($loginName, $password); @@ -254,7 +256,8 @@ class Manager extends PublicEmitter implements IUserManager { $backends = $this->backends; } foreach ($backends as $backend) { - if ($backend->implementsActions(Backend::CHECK_PASSWORD)) { + if ($backend instanceof ICheckPasswordBackend || $backend->implementsActions(Backend::CHECK_PASSWORD)) { + /** @var ICheckPasswordBackend $backend */ $uid = $backend->checkPassword($loginName, $password); if ($uid !== false) { return $this->getUserObject($uid, $backend); @@ -268,7 +271,8 @@ class Manager extends PublicEmitter implements IUserManager { $password = urldecode($password); foreach ($backends as $backend) { - if ($backend->implementsActions(Backend::CHECK_PASSWORD)) { + if ($backend instanceof ICheckPasswordBackend || $backend->implementsActions(Backend::CHECK_PASSWORD)) { + /** @var ICheckPasswordBackend|UserInterface $backend */ $uid = $backend->checkPassword($loginName, $password); if ($uid !== false) { return $this->getUserObject($uid, $backend); @@ -376,7 +380,7 @@ class Manager extends PublicEmitter implements IUserManager { * @param string $uid * @param string $password * @throws \InvalidArgumentException - * @return bool|IUser the created user or false + * @return false|IUser the created user or false */ public function createUser($uid, $password) { // DI injection is not used here as IRegistry needs the user manager itself for user count and thus it would create a cyclic dependency @@ -415,7 +419,7 @@ class Manager extends PublicEmitter implements IUserManager { * @param string $uid * @param string $password * @param UserInterface $backend - * @return IUser|null + * @return IUser|false * @throws \InvalidArgumentException */ public function createUserFromBackend($uid, $password, UserInterface $backend) { @@ -469,8 +473,9 @@ class Manager extends PublicEmitter implements IUserManager { /** @deprecated 21.0.0 use UserCreatedEvent event with the IEventDispatcher instead */ $this->emit('\OC\User', 'postCreateUser', [$user, $password]); $this->eventDispatcher->dispatchTyped(new UserCreatedEvent($user, $password)); + return $user; } - return $user; + return false; } /** @@ -478,16 +483,13 @@ class Manager extends PublicEmitter implements IUserManager { * * @param boolean $hasLoggedIn when true only users that have a lastLogin * entry in the preferences table will be affected - * @return array|int an array of backend class as key and count number as value - * if $hasLoggedIn is true only an int is returned + * @return array<string, int> an array of backend class as key and count number as value */ - public function countUsers($hasLoggedIn = false) { - if ($hasLoggedIn) { - return $this->countSeenUsers(); - } + public function countUsers() { $userCountStatistics = []; foreach ($this->backends as $backend) { - if ($backend->implementsActions(Backend::COUNT_USERS)) { + if ($backend instanceof ICountUsersBackend || $backend->implementsActions(Backend::COUNT_USERS)) { + /** @var ICountUsersBackend|IUserBackend $backend */ $backendUsers = $backend->countUsers(); if ($backendUsers !== false) { if ($backend instanceof IUserBackend) { @@ -528,7 +530,7 @@ class Manager extends PublicEmitter implements IUserManager { * The callback is executed for each user on each backend. * If the callback returns false no further users will be retrieved. * - * @param \Closure $callback + * @psalm-param \Closure(\OCP\IUser):?bool $callback * @param string $search * @param boolean $onlySeen when true only users that have a lastLogin entry * in the preferences table will be affected diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 365a01c4595..626ddca2dad 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -90,7 +90,7 @@ use Symfony\Component\EventDispatcher\GenericEvent; */ class Session implements IUserSession, Emitter { - /** @var Manager|PublicEmitter $manager */ + /** @var Manager $manager */ private $manager; /** @var ISession $session */ @@ -288,9 +288,9 @@ class Session implements IUserSession, Emitter { } /** - * get the login name of the current user + * Get the login name of the current user * - * @return string + * @return ?string */ public function getLoginName() { if ($this->activeUser) { @@ -870,7 +870,7 @@ class Session implements IUserSession, Emitter { // replace successfully used token with a new one $this->config->deleteUserValue($uid, 'login_token', $currentToken); $newToken = $this->random->generate(32); - $this->config->setUserValue($uid, 'login_token', $newToken, $this->timeFactory->getTime()); + $this->config->setUserValue($uid, 'login_token', $newToken, (string)$this->timeFactory->getTime()); try { $sessionId = $this->session->getId(); @@ -905,7 +905,7 @@ class Session implements IUserSession, Emitter { */ public function createRememberMeToken(IUser $user) { $token = $this->random->generate(32); - $this->config->setUserValue($user->getUID(), 'login_token', $token, $this->timeFactory->getTime()); + $this->config->setUserValue($user->getUID(), 'login_token', $token, (string)$this->timeFactory->getTime()); $this->setMagicInCookie($user->getUID(), $token); } diff --git a/lib/private/User/User.php b/lib/private/User/User.php index e7aa72fafba..de9af35f541 100644 --- a/lib/private/User/User.php +++ b/lib/private/User/User.php @@ -52,6 +52,10 @@ use OCP\IUserBackend; use OCP\User\Events\BeforeUserDeletedEvent; use OCP\User\Events\UserDeletedEvent; use OCP\User\GetQuotaEvent; +use OCP\User\Backend\ISetDisplayNameBackend; +use OCP\User\Backend\ISetPasswordBackend; +use OCP\User\Backend\IProvideAvatarBackend; +use OCP\User\Backend\IGetHomeBackend; use OCP\UserInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; @@ -155,7 +159,9 @@ class User implements IUser { $displayName = trim($displayName); $oldDisplayName = $this->getDisplayName(); if ($this->backend->implementsActions(Backend::SET_DISPLAYNAME) && !empty($displayName) && $displayName !== $oldDisplayName) { - $result = $this->backend->setDisplayName($this->uid, $displayName); + /** @var ISetDisplayNameBackend $backend */ + $backend = $this->backend; + $result = $backend->setDisplayName($this->uid, $displayName); if ($result) { $this->displayName = $displayName; $this->triggerChange('displayName', $displayName, $oldDisplayName); @@ -241,7 +247,7 @@ class User implements IUser { $firstTimeLogin = ($this->getLastLogin() === 0); $this->lastLogin = time(); $this->config->setUserValue( - $this->uid, 'login', 'lastLogin', $this->lastLogin); + $this->uid, 'login', 'lastLogin', (string)$this->lastLogin); return $firstTimeLogin; } @@ -280,7 +286,7 @@ class User implements IUser { \OC::$server->getCommentsManager()->deleteReferencesOfActor('users', $this->uid); \OC::$server->getCommentsManager()->deleteReadMarksFromUser($this); - /** @var IAvatarManager $avatarManager */ + /** @var AvatarManager $avatarManager */ $avatarManager = \OC::$server->query(AvatarManager::class); $avatarManager->deleteUserAvatar($this->uid); @@ -319,7 +325,9 @@ class User implements IUser { $this->emitter->emit('\OC\User', 'preSetPassword', [$this, $password, $recoveryPassword]); } if ($this->backend->implementsActions(Backend::SET_PASSWORD)) { - $result = $this->backend->setPassword($this->uid, $password); + /** @var ISetPasswordBackend $backend */ + $backend = $this->backend; + $result = $backend->setPassword($this->uid, $password); if ($result !== false) { $this->legacyDispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($this, [ @@ -344,7 +352,8 @@ class User implements IUser { */ public function getHome() { if (!$this->home) { - if ($this->backend->implementsActions(Backend::GET_HOME) and $home = $this->backend->getHome($this->uid)) { + /** @psalm-suppress UndefinedInterfaceMethod Once we get rid of the legacy implementsActions, psalm won't complain anymore */ + if (($this->backend instanceof IGetHomeBackend || $this->backend->implementsActions(Backend::GET_HOME)) && $home = $this->backend->getHome($this->uid)) { $this->home = $home; } elseif ($this->config) { $this->home = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $this->uid; @@ -367,18 +376,20 @@ class User implements IUser { return get_class($this->backend); } - public function getBackend() { + public function getBackend(): ?UserInterface { return $this->backend; } /** - * check if the backend allows the user to change his avatar on Personal page + * Check if the backend allows the user to change his avatar on Personal page * * @return bool */ public function canChangeAvatar() { - if ($this->backend->implementsActions(Backend::PROVIDE_AVATAR)) { - return $this->backend->canChangeAvatar($this->uid); + if ($this->backend instanceof IProvideAvatarBackend || $this->backend->implementsActions(Backend::PROVIDE_AVATAR)) { + /** @var IProvideAvatarBackend $backend */ + $backend = $this->backend; + return $backend->canChangeAvatar($this->uid); } return true; } @@ -501,7 +512,7 @@ class User implements IUser { $oldQuota = $this->config->getUserValue($this->uid, 'files', 'quota', ''); if ($quota !== 'none' and $quota !== 'default') { $quota = OC_Helper::computerFileSize($quota); - $quota = OC_Helper::humanFileSize($quota); + $quota = OC_Helper::humanFileSize((int)$quota); } if ($quota !== $oldQuota) { $this->config->setUserValue($this->uid, 'files', 'quota', $quota); diff --git a/lib/private/legacy/OC_Files.php b/lib/private/legacy/OC_Files.php index 41ac20577b2..02e15fd08d5 100644 --- a/lib/private/legacy/OC_Files.php +++ b/lib/private/legacy/OC_Files.php @@ -145,21 +145,26 @@ class OC_Files { } self::lockFiles($view, $dir, $files); + $numberOfFiles = 0; + $fileSize = 0; /* Calculate filesize and number of files */ if ($getType === self::ZIP_FILES) { $fileInfos = []; - $fileSize = 0; foreach ($files as $file) { $fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $file); - $fileSize += $fileInfo->getSize(); - $fileInfos[] = $fileInfo; + if ($fileInfo) { + $fileSize += $fileInfo->getSize(); + $fileInfos[] = $fileInfo; + } } $numberOfFiles = self::getNumberOfFiles($fileInfos); } elseif ($getType === self::ZIP_DIR) { $fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $files); - $fileSize = $fileInfo->getSize(); - $numberOfFiles = self::getNumberOfFiles([$fileInfo]); + if ($fileInfo) { + $fileSize = $fileInfo->getSize(); + $numberOfFiles = self::getNumberOfFiles([$fileInfo]); + } } $streamer = new Streamer(\OC::$server->getRequest(), $fileSize, $numberOfFiles); diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php index 0d1903007c2..226f73a0711 100644 --- a/lib/private/legacy/OC_Helper.php +++ b/lib/private/legacy/OC_Helper.php @@ -95,7 +95,7 @@ class OC_Helper { /** * Make a computer file size * @param string $str file size in human readable format - * @return float|bool a file size in bytes + * @return float|false a file size in bytes * * Makes 2kB to 2048. * @@ -420,11 +420,11 @@ class OC_Helper { */ public static function uploadLimit() { $ini = \OC::$server->get(IniGetWrapper::class); - $upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize')); - $post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size')); - if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) { + $upload_max_filesize = (int)OCP\Util::computerFileSize($ini->get('upload_max_filesize')); + $post_max_size = (int)OCP\Util::computerFileSize($ini->get('post_max_size')); + if ($upload_max_filesize === 0 && $post_max_size === 0) { return INF; - } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) { + } elseif ($upload_max_filesize === 0 || $post_max_size === 0) { return max($upload_max_filesize, $post_max_size); //only the non 0 value counts } else { return min($upload_max_filesize, $post_max_size); @@ -519,9 +519,6 @@ class OC_Helper { $sourceStorage = $storage; if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) { $includeExtStorage = false; - $internalPath = $storage->getUnjailedPath($rootInfo->getInternalPath()); - } else { - $internalPath = $rootInfo->getInternalPath(); } if ($includeExtStorage) { if ($storage->instanceOfStorage('\OC\Files\Storage\Home') @@ -545,7 +542,7 @@ class OC_Helper { $quota = $sourceStorage->getQuota(); } try { - $free = $sourceStorage->free_space($internalPath); + $free = $sourceStorage->free_space($rootInfo->getInternalPath()); } catch (\Exception $e) { if ($path === "") { throw $e; diff --git a/lib/private/legacy/OC_Image.php b/lib/private/legacy/OC_Image.php index 3988eb8eaa5..a212d639084 100644 --- a/lib/private/legacy/OC_Image.php +++ b/lib/private/legacy/OC_Image.php @@ -103,10 +103,8 @@ class OC_Image implements \OCP\IImage { * @return bool */ public function valid() { - if (is_resource($this->resource)) { - return true; - } - if (is_object($this->resource) && get_class($this->resource) === \GdImage::class) { + if ((is_resource($this->resource) && get_resource_type($this->resource) === 'gd') || + (is_object($this->resource) && get_class($this->resource) === \GdImage::class)) { return true; } @@ -486,7 +484,7 @@ class OC_Image implements \OCP\IImage { */ public function fixOrientation() { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $o = $this->getOrientation(); @@ -994,7 +992,7 @@ class OC_Image implements \OCP\IImage { */ public function resize($maxSize) { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $result = $this->resizeNew($maxSize); @@ -1009,7 +1007,7 @@ class OC_Image implements \OCP\IImage { */ private function resizeNew($maxSize) { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $widthOrig = imagesx($this->resource); @@ -1034,7 +1032,7 @@ class OC_Image implements \OCP\IImage { */ public function preciseResize(int $width, int $height): bool { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $result = $this->preciseResizeNew($width, $height); @@ -1055,14 +1053,14 @@ class OC_Image implements \OCP\IImage { return false; } if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $widthOrig = imagesx($this->resource); $heightOrig = imagesy($this->resource); $process = imagecreatetruecolor($width, $height); if ($process === false) { - $this->logger->error(__METHOD__ . '(): Error creating true color image', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): Error creating true color image', ['app' => 'core']); return false; } @@ -1075,7 +1073,7 @@ class OC_Image implements \OCP\IImage { $res = imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $widthOrig, $heightOrig); if ($res === false) { - $this->logger->error(__METHOD__ . '(): Error re-sampling process image', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): Error re-sampling process image', ['app' => 'core']); imagedestroy($process); return false; } @@ -1090,7 +1088,7 @@ class OC_Image implements \OCP\IImage { */ public function centerCrop($size = 0) { if (!$this->valid()) { - $this->logger->error('OC_Image->centerCrop, No image loaded', ['app' => 'core']); + $this->logger->debug('OC_Image->centerCrop, No image loaded', ['app' => 'core']); return false; } $widthOrig = imagesx($this->resource); @@ -1117,7 +1115,7 @@ class OC_Image implements \OCP\IImage { } $process = imagecreatetruecolor($targetWidth, $targetHeight); if ($process === false) { - $this->logger->error('OC_Image->centerCrop, Error creating true color image', ['app' => 'core']); + $this->logger->debug('OC_Image->centerCrop, Error creating true color image', ['app' => 'core']); return false; } @@ -1130,7 +1128,7 @@ class OC_Image implements \OCP\IImage { imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height); if ($process === false) { - $this->logger->error('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, ['app' => 'core']); + $this->logger->debug('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, ['app' => 'core']); return false; } imagedestroy($this->resource); @@ -1149,7 +1147,7 @@ class OC_Image implements \OCP\IImage { */ public function crop(int $x, int $y, int $w, int $h): bool { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $result = $this->cropNew($x, $y, $w, $h); @@ -1169,12 +1167,12 @@ class OC_Image implements \OCP\IImage { */ public function cropNew(int $x, int $y, int $w, int $h) { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $process = imagecreatetruecolor($w, $h); if ($process === false) { - $this->logger->error(__METHOD__ . '(): Error creating true color image', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): Error creating true color image', ['app' => 'core']); return false; } @@ -1187,7 +1185,7 @@ class OC_Image implements \OCP\IImage { imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $w, $h, $w, $h); if ($process === false) { - $this->logger->error(__METHOD__ . '(): Error re-sampling process image ' . $w . 'x' . $h, ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): Error re-sampling process image ' . $w . 'x' . $h, ['app' => 'core']); return false; } return $process; @@ -1204,7 +1202,7 @@ class OC_Image implements \OCP\IImage { */ public function fitIn($maxWidth, $maxHeight) { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $widthOrig = imagesx($this->resource); @@ -1227,7 +1225,7 @@ class OC_Image implements \OCP\IImage { */ public function scaleDownToFit($maxWidth, $maxHeight) { if (!$this->valid()) { - $this->logger->error(__METHOD__ . '(): No image loaded', ['app' => 'core']); + $this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']); return false; } $widthOrig = imagesx($this->resource); diff --git a/lib/private/legacy/OC_User.php b/lib/private/legacy/OC_User.php index bc47359dafc..b7547be5e82 100644 --- a/lib/private/legacy/OC_User.php +++ b/lib/private/legacy/OC_User.php @@ -179,6 +179,7 @@ class OC_User { $userSession->setLoginName($uid); $request = OC::$server->getRequest(); $userSession->createSessionToken($request, $uid, $uid); + $userSession->createRememberMeToken($userSession->getUser()); // setup the filesystem OC_Util::setupFS($uid); // first call the post_login hooks, the login-process needs to be diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index ee7fb517d98..516ccc8283c 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -158,7 +158,7 @@ class OC_Util { * Get the quota of a user * * @param IUser|null $user - * @return float Quota bytes + * @return float|\OCP\Files\FileInfo::SPACE_UNLIMITED|false Quota bytes */ public static function getUserQuota(?IUser $user) { if (is_null($user)) { @@ -657,20 +657,8 @@ class OC_Util { } } foreach ($dependencies['ini'] as $setting => $expected) { - if (is_bool($expected)) { - if ($iniWrapper->getBool($setting) !== $expected) { - $invalidIniSettings[] = [$setting, $expected]; - } - } - if (is_int($expected)) { - if ($iniWrapper->getNumeric($setting) !== $expected) { - $invalidIniSettings[] = [$setting, $expected]; - } - } - if (is_string($expected)) { - if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) { - $invalidIniSettings[] = [$setting, $expected]; - } + if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) { + $invalidIniSettings[] = [$setting, $expected]; } } @@ -682,9 +670,6 @@ class OC_Util { $webServerRestart = true; } foreach ($invalidIniSettings as $setting) { - if (is_bool($setting[1])) { - $setting[1] = $setting[1] ? 'on' : 'off'; - } $errors[] = [ 'error' => $l->t('PHP setting "%s" is not set to "%s".', [$setting[0], var_export($setting[1], true)]), 'hint' => $l->t('Adjusting this setting in php.ini will make Nextcloud run again') diff --git a/lib/public/Accounts/IAccountManager.php b/lib/public/Accounts/IAccountManager.php index ae5f6b1e542..e41327171b4 100644 --- a/lib/public/Accounts/IAccountManager.php +++ b/lib/public/Accounts/IAccountManager.php @@ -8,6 +8,7 @@ declare(strict_types=1); * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> * @author Julius Härtl <jus@bitgrid.net> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Vincent Petry <vincent@nextcloud.com> * * @license GNU AGPL version 3 or any later version @@ -89,6 +90,21 @@ interface IAccountManager { */ public const VISIBILITY_PUBLIC = 'public'; + /** + * The list of allowed scopes + * + * @since 25.0.0 + */ + public const ALLOWED_SCOPES = [ + self::SCOPE_PRIVATE, + self::SCOPE_LOCAL, + self::SCOPE_FEDERATED, + self::SCOPE_PUBLISHED, + self::VISIBILITY_PRIVATE, + self::VISIBILITY_CONTACTS_ONLY, + self::VISIBILITY_PUBLIC, + ]; + public const PROPERTY_AVATAR = 'avatar'; public const PROPERTY_DISPLAYNAME = 'displayname'; public const PROPERTY_PHONE = 'phone'; @@ -122,6 +138,26 @@ interface IAccountManager { */ public const PROPERTY_PROFILE_ENABLED = 'profile_enabled'; + /** + * The list of allowed properties + * + * @since 25.0.0 + */ + public const ALLOWED_PROPERTIES = [ + self::PROPERTY_AVATAR, + self::PROPERTY_DISPLAYNAME, + self::PROPERTY_PHONE, + self::PROPERTY_EMAIL, + self::PROPERTY_WEBSITE, + self::PROPERTY_ADDRESS, + self::PROPERTY_TWITTER, + self::PROPERTY_ORGANISATION, + self::PROPERTY_ROLE, + self::PROPERTY_HEADLINE, + self::PROPERTY_BIOGRAPHY, + self::PROPERTY_PROFILE_ENABLED, + ]; + public const COLLECTION_EMAIL = 'additional_mail'; public const NOT_VERIFIED = '0'; diff --git a/lib/public/AppFramework/Db/QBMapper.php b/lib/public/AppFramework/Db/QBMapper.php index fa753a09dcf..2491fd83f4a 100644 --- a/lib/public/AppFramework/Db/QBMapper.php +++ b/lib/public/AppFramework/Db/QBMapper.php @@ -334,16 +334,15 @@ abstract class QBMapper { */ protected function findEntities(IQueryBuilder $query): array { $result = $query->executeQuery(); - - $entities = []; - - while ($row = $result->fetch()) { - $entities[] = $this->mapRowToEntity($row); + try { + $entities = []; + while ($row = $result->fetch()) { + $entities[] = $this->mapRowToEntity($row); + } + return $entities; + } finally { + $result->closeCursor(); } - - $result->closeCursor(); - - return $entities; } diff --git a/lib/public/AppFramework/Http/TemplateResponse.php b/lib/public/AppFramework/Http/TemplateResponse.php index 9b010d38bae..23843cd21d1 100644 --- a/lib/public/AppFramework/Http/TemplateResponse.php +++ b/lib/public/AppFramework/Http/TemplateResponse.php @@ -139,6 +139,15 @@ class TemplateResponse extends Response { /** + * @return string the app id of the used template + * @since 25.0.0 + */ + public function getApp(): string { + return $this->appName; + } + + + /** * Used for accessing the name of the set template * @return string the name of the used template * @since 6.0.0 diff --git a/lib/public/AppFramework/Http/ZipResponse.php b/lib/public/AppFramework/Http/ZipResponse.php index c3a7e089bdc..7495583ae12 100644 --- a/lib/public/AppFramework/Http/ZipResponse.php +++ b/lib/public/AppFramework/Http/ZipResponse.php @@ -37,11 +37,11 @@ use OCP\IRequest; * @since 15.0.0 */ class ZipResponse extends Response implements ICallbackResponse { - /** @var resource[] Files to be added to the zip response */ - private $resources = []; + /** @var array{internalName: string, resource: string, size: int, time: int}[] Files to be added to the zip response */ + private array $resources = []; /** @var string Filename that the zip file should have */ - private $name; - private $request; + private string $name; + private IRequest $request; /** * @since 15.0.0 diff --git a/lib/public/Config/BeforePreferenceDeletedEvent.php b/lib/public/Config/BeforePreferenceDeletedEvent.php new file mode 100644 index 00000000000..a2d1dad7034 --- /dev/null +++ b/lib/public/Config/BeforePreferenceDeletedEvent.php @@ -0,0 +1,83 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\Config; + +use OCP\EventDispatcher\Event; + +/** + * @since 25.0.0 + */ +class BeforePreferenceDeletedEvent extends Event { + protected string $userId; + protected string $appId; + protected string $configKey; + protected bool $valid = false; + + /** + * @since 25.0.0 + */ + public function __construct(string $userId, string $appId, string $configKey) { + parent::__construct(); + $this->userId = $userId; + $this->appId = $appId; + $this->configKey = $configKey; + } + + /** + * @since 25.0.0 + */ + public function getUserId(): string { + return $this->userId; + } + + /** + * @since 25.0.0 + */ + public function getAppId(): string { + return $this->appId; + } + + /** + * @since 25.0.0 + */ + public function getConfigKey(): string { + return $this->configKey; + } + + /** + * @since 25.0.0 + */ + public function isValid(): bool { + return $this->valid; + } + + /** + * @since 25.0.0 + */ + public function setValid(bool $valid): void { + $this->valid = $valid; + } +} diff --git a/lib/public/Config/BeforePreferenceSetEvent.php b/lib/public/Config/BeforePreferenceSetEvent.php new file mode 100644 index 00000000000..31681405a47 --- /dev/null +++ b/lib/public/Config/BeforePreferenceSetEvent.php @@ -0,0 +1,92 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\Config; + +use OCP\EventDispatcher\Event; + +/** + * @since 25.0.0 + */ +class BeforePreferenceSetEvent extends Event { + protected string $userId; + protected string $appId; + protected string $configKey; + protected string $configValue; + protected bool $valid = false; + + /** + * @since 25.0.0 + */ + public function __construct(string $userId, string $appId, string $configKey, string $configValue) { + parent::__construct(); + $this->userId = $userId; + $this->appId = $appId; + $this->configKey = $configKey; + $this->configValue = $configValue; + } + + /** + * @since 25.0.0 + */ + public function getUserId(): string { + return $this->userId; + } + + /** + * @since 25.0.0 + */ + public function getAppId(): string { + return $this->appId; + } + + /** + * @since 25.0.0 + */ + public function getConfigKey(): string { + return $this->configKey; + } + + /** + * @since 25.0.0 + */ + public function getConfigValue(): string { + return $this->configValue; + } + + /** + * @since 25.0.0 + */ + public function isValid(): bool { + return $this->valid; + } + + /** + * @since 25.0.0 + */ + public function setValid(bool $valid): void { + $this->valid = $valid; + } +} diff --git a/lib/public/Contacts/ContactsMenu/IAction.php b/lib/public/Contacts/ContactsMenu/IAction.php index 9b08bbbf04b..f6022fefac3 100644 --- a/lib/public/Contacts/ContactsMenu/IAction.php +++ b/lib/public/Contacts/ContactsMenu/IAction.php @@ -35,31 +35,31 @@ interface IAction extends JsonSerializable { * @param string $icon absolute URI to an icon * @since 12.0 */ - public function setIcon($icon); + public function setIcon(string $icon); /** * @return string localized action name, e.g. 'Call' * @since 12.0 */ - public function getName(); + public function getName(): string; /** * @param string $name localized action name, e.g. 'Call' * @since 12.0 */ - public function setName($name); + public function setName(string $name); /** * @param int $priority priorize actions, high order ones are shown on top * @since 12.0 */ - public function setPriority($priority); + public function setPriority(int $priority); /** * @return int priority to priorize actions, high order ones are shown on top * @since 12.0 */ - public function getPriority(); + public function getPriority(): int; /** * @param string $appId diff --git a/lib/public/Contacts/ContactsMenu/IContactsStore.php b/lib/public/Contacts/ContactsMenu/IContactsStore.php index 3aa51888450..8b36f9cde5c 100644 --- a/lib/public/Contacts/ContactsMenu/IContactsStore.php +++ b/lib/public/Contacts/ContactsMenu/IContactsStore.php @@ -34,21 +34,17 @@ interface IContactsStore { /** * @param IUser $user - * @param string $filter - * @param int $limit added 19.0.2 - * @param int $offset added 19.0.2 + * @param string|null $filter + * @param int|null $limit added 19.0.2 + * @param int|null $offset added 19.0.2 * @return IEntry[] * @since 13.0.0 */ - public function getContacts(IUser $user, $filter, ?int $limit = null, ?int $offset = null); + public function getContacts(IUser $user, ?string $filter, ?int $limit = null, ?int $offset = null): array; /** * @brief finds a contact by specifying the property to search on ($shareType) and the value ($shareWith) - * @param IUser $user - * @param integer $shareType - * @param string $shareWith - * @return IEntry|null * @since 13.0.0 */ - public function findOne(IUser $user, $shareType, $shareWith); + public function findOne(IUser $user, int $shareType, string $shareWith): ?IEntry; } diff --git a/lib/public/Contacts/ContactsMenu/ILinkAction.php b/lib/public/Contacts/ContactsMenu/ILinkAction.php index 63e77f5446f..936dd22bcf2 100644 --- a/lib/public/Contacts/ContactsMenu/ILinkAction.php +++ b/lib/public/Contacts/ContactsMenu/ILinkAction.php @@ -28,14 +28,14 @@ namespace OCP\Contacts\ContactsMenu; interface ILinkAction extends IAction { /** - * @since 12.0 * @param string $href the target URL of the action + * @since 12.0 */ - public function setHref($href); + public function setHref(string $href); /** * @since 12.0 * @return string */ - public function getHref(); + public function getHref(): string; } diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php index e3257e82bca..218b7d8cb2d 100644 --- a/lib/public/DB/QueryBuilder/IQueryBuilder.php +++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php @@ -820,7 +820,7 @@ interface IQueryBuilder { * Specifies an ordering for the query results. * Replaces any previously specified orderings, if any. * - * @param string $sort The ordering expression. + * @param string|IQueryFunction|ILiteral|IParameter $sort The ordering expression. * @param string $order The ordering direction. * * @return $this This QueryBuilder instance. diff --git a/lib/public/Files/AppData/IAppDataFactory.php b/lib/public/Files/AppData/IAppDataFactory.php new file mode 100644 index 00000000000..b689da36b83 --- /dev/null +++ b/lib/public/Files/AppData/IAppDataFactory.php @@ -0,0 +1,21 @@ +<?php + +namespace OCP\Files\AppData; + +use OCP\Files\IAppData; + +/** + * A factory allows you to get the AppData folder for an application. + * + * @since 25.0.0 + */ +interface IAppDataFactory { + + /** + * Get the AppData folder for the specified $appId + * @param string $appId + * @return IAppData + * @since 25.0.0 + */ + public function get(string $appId): IAppData; +} diff --git a/lib/public/FullTextSearch/Model/ISearchRequest.php b/lib/public/FullTextSearch/Model/ISearchRequest.php index be93b2d9970..76fc3b18b02 100644 --- a/lib/public/FullTextSearch/Model/ISearchRequest.php +++ b/lib/public/FullTextSearch/Model/ISearchRequest.php @@ -193,7 +193,7 @@ interface ISearchRequest { * * @return ISearchRequest */ - public function setMetaTags(array $tags): IsearchRequest; + public function setMetaTags(array $tags): ISearchRequest; /** diff --git a/lib/public/IAddressBook.php b/lib/public/IAddressBook.php index 4bb632ae070..ee57dbceb71 100644 --- a/lib/public/IAddressBook.php +++ b/lib/public/IAddressBook.php @@ -47,7 +47,6 @@ namespace OCP { /** * @return string defining the unique uri * @since 16.0.0 - * @return string */ public function getUri(): string; diff --git a/lib/public/IAvatar.php b/lib/public/IAvatar.php index 8a1bc792450..218ef258250 100644 --- a/lib/public/IAvatar.php +++ b/lib/public/IAvatar.php @@ -38,7 +38,7 @@ interface IAvatar { /** * get the users avatar * @param int $size size in px of the avatar, avatars are square, defaults to 64, -1 can be used to not scale the image - * @return boolean|\OCP\IImage containing the avatar or false if there's no image + * @return false|\OCP\IImage containing the avatar or false if there's no image * @since 6.0.0 - size of -1 was added in 9.0.0 */ public function get($size = 64); diff --git a/lib/public/IDBConnection.php b/lib/public/IDBConnection.php index d12baa400c0..69ede2c8438 100644 --- a/lib/public/IDBConnection.php +++ b/lib/public/IDBConnection.php @@ -199,7 +199,7 @@ interface IDBConnection { * @param array $updatePreconditionValues ensure values match preconditions (column name => value) * @return int number of new rows * @throws Exception used to be the removed dbal exception, since 21.0.0 it's \OCP\DB\Exception - * @throws PreconditionNotMetException + * @throws PreConditionNotMetException * @since 9.0.0 */ public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int; diff --git a/lib/public/IUser.php b/lib/public/IUser.php index 1a1d1e44d8a..daf993df6cd 100644 --- a/lib/public/IUser.php +++ b/lib/public/IUser.php @@ -112,8 +112,7 @@ interface IUser { /** * Get the backend for the current user object - * - * @return UserInterface + * @return ?UserInterface * @since 15.0.0 */ public function getBackend(); diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index e5c220af40c..77e2fc21a22 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -98,7 +98,7 @@ interface IUserManager { * * @param string $loginName * @param string $password - * @return mixed the User object on success, false otherwise + * @return IUser|false the User object on success, false otherwise * @since 8.0.0 */ public function checkPassword($loginName, $password); @@ -141,7 +141,7 @@ interface IUserManager { * @param string $uid * @param string $password * @throws \InvalidArgumentException - * @return bool|\OCP\IUser the created user or false + * @return false|\OCP\IUser the created user or false * @since 8.0.0 */ public function createUser($uid, $password); @@ -157,9 +157,9 @@ interface IUserManager { public function createUserFromBackend($uid, $password, UserInterface $backend); /** - * returns how many users per backend exist (if supported by backend) + * Get how many users per backend exist (if supported by backend) * - * @return array an array of backend class as key and count number as value + * @return array<string, int> an array of backend class name as key and count number as value * @since 8.0.0 */ public function countUsers(); diff --git a/lib/public/Lock/ILockingProvider.php b/lib/public/Lock/ILockingProvider.php index 3dc7c73b6eb..a2015d42f47 100644 --- a/lib/public/Lock/ILockingProvider.php +++ b/lib/public/Lock/ILockingProvider.php @@ -28,7 +28,10 @@ declare(strict_types=1); namespace OCP\Lock; /** - * Interface ILockingProvider + * This interface allows locking and unlocking filesystem paths + * + * This interface should be used directly and not implemented by an application. + * The implementation is provided by the server. * * @since 8.1.0 */ @@ -43,42 +46,37 @@ interface ILockingProvider { public const LOCK_EXCLUSIVE = 2; /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @return bool + * @psalm-param self::LOCK_SHARED|self::LOCK_EXCLUSIVE $type * @since 8.1.0 */ public function isLocked(string $path, int $type): bool; /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @param string $readablePath human readable path to use in error messages, since 20.0.0 - * @throws \OCP\Lock\LockedException + * @psalm-param self::LOCK_SHARED|self::LOCK_EXCLUSIVE $type + * @param ?string $readablePath A human-readable path to use in error messages, since 20.0.0 + * @throws LockedException * @since 8.1.0 */ - public function acquireLock(string $path, int $type, string $readablePath = null); + public function acquireLock(string $path, int $type, ?string $readablePath = null): void; /** - * @param string $path - * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE + * @psalm-param self::LOCK_SHARED|self::LOCK_EXCLUSIVE $type * @since 8.1.0 */ - public function releaseLock(string $path, int $type); + public function releaseLock(string $path, int $type): void; /** - * Change the type of an existing lock + * Change the target type of an existing lock * - * @param string $path - * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE - * @throws \OCP\Lock\LockedException + * @psalm-param self::LOCK_SHARED|self::LOCK_EXCLUSIVE $targetType + * @throws LockedException * @since 8.1.0 */ - public function changeLock(string $path, int $targetType); + public function changeLock(string $path, int $targetType): void; /** - * release all lock acquired by this instance + * Release all lock acquired by this instance * @since 8.1.0 */ - public function releaseAll(); + public function releaseAll(): void; } diff --git a/lib/public/Search/SearchResult.php b/lib/public/Search/SearchResult.php index 685dad0f0ca..5371b77ef0a 100644 --- a/lib/public/Search/SearchResult.php +++ b/lib/public/Search/SearchResult.php @@ -50,7 +50,7 @@ final class SearchResult implements JsonSerializable { * @param string $name the translated name of the result section or group, e.g. "Mail" * @param bool $isPaginated * @param SearchResultEntry[] $entries - * @param null $cursor + * @param ?int|?string $cursor * * @since 20.0.0 */ diff --git a/lib/public/Server.php b/lib/public/Server.php index be6b6a49236..f4522e8ae10 100644 --- a/lib/public/Server.php +++ b/lib/public/Server.php @@ -41,8 +41,9 @@ use Psr\Container\NotFoundExceptionInterface; final class Server { /** * @template T - * @param class-string<T>|string $serviceName - * @return T|mixed + * @template S as class-string<T>|string + * @param S $serviceName + * @return (S is class-string<T> ? T : mixed) * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @since 25.0.0 diff --git a/lib/public/Share.php b/lib/public/Share.php index 6aeadb3a6ed..cb6b145bcfb 100644 --- a/lib/public/Share.php +++ b/lib/public/Share.php @@ -64,7 +64,7 @@ class Share extends \OC\Share\Constants { * @param int $format (optional) Format type must be defined by the backend * @param mixed $parameters * @param bool $includeCollections - * @return array + * @return void * @since 5.0.0 * @deprecated 17.0.0 */ @@ -77,7 +77,7 @@ class Share extends \OC\Share\Constants { * Based on the given token the share information will be returned - password protected shares will be verified * @param string $token * @param bool $checkPasswordProtection - * @return array|bool false will be returned in case the token is unknown or unauthorized + * @return void * @since 5.0.0 - parameter $checkPasswordProtection was added in 7.0.0 * @deprecated 17.0.0 */ @@ -93,7 +93,7 @@ class Share extends \OC\Share\Constants { * @param mixed $parameters * @param int $limit Number of items to return (optional) Returns all by default * @param bool $includeCollections - * @return mixed Return depends on format + * @return void * @since 5.0.0 * @deprecated 17.0.0 */ diff --git a/lib/public/User/Backend/ICheckPasswordBackend.php b/lib/public/User/Backend/ICheckPasswordBackend.php index b3eaf7cedb0..0d4026be859 100644 --- a/lib/public/User/Backend/ICheckPasswordBackend.php +++ b/lib/public/User/Backend/ICheckPasswordBackend.php @@ -35,7 +35,7 @@ interface ICheckPasswordBackend { * * @param string $loginName The loginname * @param string $password The password - * @return string|bool The uid on success false on failure + * @return string|false The uid on success false on failure */ public function checkPassword(string $loginName, string $password); } diff --git a/lib/public/Util.php b/lib/public/Util.php index c8b55bb10e2..e5bb2a955ae 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -372,7 +372,7 @@ class Util { /** * Make a computer file size (2 kB to 2048) * @param string $str file size in a fancy format - * @return float a file size in bytes + * @return float|false a file size in bytes * * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418 * @since 4.0.0 |