diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index 5fe9f93d8b5..d883bae450b 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -89,7 +89,7 @@ $server->httpRequest->setUrl(Server::get(IRequest::class)->getRequestUri()); /** @var string $baseuri defined in remote.php */ $server->setBaseUri($baseuri); // Add plugins -$server->addPlugin(new MaintenancePlugin(Server::get(IConfig::class), \OCP\Server::get(IL10nFactory::class)->get('dav'))); +$server->addPlugin(new MaintenancePlugin(Server::get(IConfig::class), Server::get(IL10nFactory::class)->get('dav'))); $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend)); $server->addPlugin(new Plugin()); diff --git a/apps/dav/lib/CalDAV/Federation/FederatedCalendarEntity.php b/apps/dav/lib/CalDAV/Federation/FederatedCalendarEntity.php index e6d869fec88..80cf5570d65 100644 --- a/apps/dav/lib/CalDAV/Federation/FederatedCalendarEntity.php +++ b/apps/dav/lib/CalDAV/Federation/FederatedCalendarEntity.php @@ -11,6 +11,7 @@ namespace OCA\DAV\CalDAV\Federation; use OCA\DAV\DAV\RemoteUserPrincipalBackend; use OCP\AppFramework\Db\Entity; +use OCP\Constants; use OCP\DB\Types; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; @@ -94,7 +95,7 @@ class FederatedCalendarEntity extends Entity { '{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => $this->getSyncTokenForSabre(), '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => $this->getSupportedCalendarComponentSet(), '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->getSharedByPrincipal(), - '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => ($this->getPermissions() & \OCP\Constants::PERMISSION_UPDATE) === 0 ? 1 : 0, + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => ($this->getPermissions() & Constants::PERMISSION_UPDATE) === 0 ? 1 : 0, '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}permissions' => $this->getPermissions(), ]; } diff --git a/apps/dav/lib/Connector/Sabre/Directory.php b/apps/dav/lib/Connector/Sabre/Directory.php index f4e8ee1d99a..d0bde46e96d 100644 --- a/apps/dav/lib/Connector/Sabre/Directory.php +++ b/apps/dav/lib/Connector/Sabre/Directory.php @@ -532,7 +532,7 @@ class Directory extends Node implements } if ($info->getMimeType() === FileInfo::MIMETYPE_FOLDER) { - $node = new \OCA\DAV\Connector\Sabre\Directory($this->fileView, $info, $this->tree, $this->shareManager); + $node = new Directory($this->fileView, $info, $this->tree, $this->shareManager); } else { // In case reading a directory was allowed but it turns out the node was a not a directory, reject it now. if (!$this->info->isReadable()) { diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index 622264065cc..f200838ba6b 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -480,11 +480,15 @@ class File extends Node implements IFile { } } + $logger = Server::get(LoggerInterface::class); // comparing current file size with the one in DB // if different, fix DB and refresh cache. + // $fsSize = $this->fileView->filesize($this->getPath()); - if ($this->getSize() !== $fsSize) { - $logger = Server::get(LoggerInterface::class); + if ($fsSize === false) { + $logger->warning('file not found on storage after successfully opening it'); + throw new ServiceUnavailable($this->l10n->t('Failed to get size for : %1$s', [$this->getPath()])); + } elseif ($this->getSize() !== $fsSize) { $logger->warning('fixing cached size of file id=' . $this->getId() . ', cached size was ' . $this->getSize() . ', but the filesystem reported a size of ' . $fsSize); $this->getFileInfo()->getStorage()->getUpdater()->update($this->getFileInfo()->getInternalPath()); diff --git a/apps/dav/lib/Search/EventsSearchProvider.php b/apps/dav/lib/Search/EventsSearchProvider.php index 5dd4a753b56..9d57586fd84 100644 --- a/apps/dav/lib/Search/EventsSearchProvider.php +++ b/apps/dav/lib/Search/EventsSearchProvider.php @@ -150,13 +150,13 @@ class EventsSearchProvider extends ACalendarSearchProvider implements IFiltering $formattedResults = \array_map(function (array $eventRow) use ($calendarsById, $subscriptionsById): SearchResultEntry { $component = $this->getPrimaryComponent($eventRow['calendardata'], self::$componentType); $title = (string)($component->SUMMARY ?? $this->l10n->t('Untitled event')); - $subline = $this->generateSubline($component); if ($eventRow['calendartype'] === CalDavBackend::CALENDAR_TYPE_CALENDAR) { $calendar = $calendarsById[$eventRow['calendarid']]; } else { $calendar = $subscriptionsById[$eventRow['calendarid']]; } + $subline = $this->generateSubline($component, $calendar); $resourceUrl = $this->getDeepLinkToCalendarApp($calendar['principaluri'], $calendar['uri'], $eventRow['uri']); $result = new SearchResultEntry('', $title, $subline, $resourceUrl, 'icon-calendar-dark', false); @@ -204,7 +204,7 @@ class EventsSearchProvider extends ACalendarSearchProvider implements IFiltering . $calendarObjectUri; } - protected function generateSubline(Component $eventComponent): string { + protected function generateSubline(Component $eventComponent, array $calendarInfo): string { $dtStart = $eventComponent->DTSTART; $dtEnd = $this->getDTEndForEvent($eventComponent); $isAllDayEvent = $dtStart instanceof Property\ICalendar\Date; @@ -214,24 +214,31 @@ class EventsSearchProvider extends ACalendarSearchProvider implements IFiltering if ($isAllDayEvent) { $endDateTime->modify('-1 day'); if ($this->isDayEqual($startDateTime, $endDateTime)) { - return $this->l10n->l('date', $startDateTime, ['width' => 'medium']); + $formattedSubline = $this->l10n->l('date', $startDateTime, ['width' => 'medium']); + } else { + $formattedStart = $this->l10n->l('date', $startDateTime, ['width' => 'medium']); + $formattedEnd = $this->l10n->l('date', $endDateTime, ['width' => 'medium']); + $formattedSubline = "$formattedStart - $formattedEnd"; } + } else { + $formattedStartDate = $this->l10n->l('date', $startDateTime, ['width' => 'medium']); + $formattedEndDate = $this->l10n->l('date', $endDateTime, ['width' => 'medium']); + $formattedStartTime = $this->l10n->l('time', $startDateTime, ['width' => 'short']); + $formattedEndTime = $this->l10n->l('time', $endDateTime, ['width' => 'short']); - $formattedStart = $this->l10n->l('date', $startDateTime, ['width' => 'medium']); - $formattedEnd = $this->l10n->l('date', $endDateTime, ['width' => 'medium']); - return "$formattedStart - $formattedEnd"; + if ($this->isDayEqual($startDateTime, $endDateTime)) { + $formattedSubline = "$formattedStartDate $formattedStartTime - $formattedEndTime"; + } else { + $formattedSubline = "$formattedStartDate $formattedStartTime - $formattedEndDate $formattedEndTime"; + } } - $formattedStartDate = $this->l10n->l('date', $startDateTime, ['width' => 'medium']); - $formattedEndDate = $this->l10n->l('date', $endDateTime, ['width' => 'medium']); - $formattedStartTime = $this->l10n->l('time', $startDateTime, ['width' => 'short']); - $formattedEndTime = $this->l10n->l('time', $endDateTime, ['width' => 'short']); - - if ($this->isDayEqual($startDateTime, $endDateTime)) { - return "$formattedStartDate $formattedStartTime - $formattedEndTime"; + if (isset($calendarInfo['{DAV:}displayname']) && !empty($calendarInfo['{DAV:}displayname'])) { + $formattedSubline = $formattedSubline . " ({$calendarInfo['{DAV:}displayname']})"; } - return "$formattedStartDate $formattedStartTime - $formattedEndDate $formattedEndTime"; + // string cast is just to make psalm happy + return (string)$formattedSubline; } protected function getDTEndForEvent(Component $eventComponent):Property { diff --git a/apps/dav/lib/Search/TasksSearchProvider.php b/apps/dav/lib/Search/TasksSearchProvider.php index 15baf070e81..46063cce16d 100644 --- a/apps/dav/lib/Search/TasksSearchProvider.php +++ b/apps/dav/lib/Search/TasksSearchProvider.php @@ -96,13 +96,13 @@ class TasksSearchProvider extends ACalendarSearchProvider { $formattedResults = \array_map(function (array $taskRow) use ($calendarsById, $subscriptionsById):SearchResultEntry { $component = $this->getPrimaryComponent($taskRow['calendardata'], self::$componentType); $title = (string)($component->SUMMARY ?? $this->l10n->t('Untitled task')); - $subline = $this->generateSubline($component); if ($taskRow['calendartype'] === CalDavBackend::CALENDAR_TYPE_CALENDAR) { $calendar = $calendarsById[$taskRow['calendarid']]; } else { $calendar = $subscriptionsById[$taskRow['calendarid']]; } + $subline = $this->generateSubline($component, $calendar); $resourceUrl = $this->getDeepLinkToTasksApp($calendar['uri'], $taskRow['uri']); return new SearchResultEntry('', $title, $subline, $resourceUrl, 'icon-checkmark', false); @@ -128,25 +128,29 @@ class TasksSearchProvider extends ACalendarSearchProvider { ); } - protected function generateSubline(Component $taskComponent): string { + protected function generateSubline(Component $taskComponent, array $calendarInfo): string { if ($taskComponent->COMPLETED) { $completedDateTime = new \DateTime($taskComponent->COMPLETED->getDateTime()->format(\DateTimeInterface::ATOM)); $formattedDate = $this->l10n->l('date', $completedDateTime, ['width' => 'medium']); - return $this->l10n->t('Completed on %s', [$formattedDate]); - } - - if ($taskComponent->DUE) { + $formattedSubline = $this->l10n->t('Completed on %s', [$formattedDate]); + } elseif ($taskComponent->DUE) { $dueDateTime = new \DateTime($taskComponent->DUE->getDateTime()->format(\DateTimeInterface::ATOM)); $formattedDate = $this->l10n->l('date', $dueDateTime, ['width' => 'medium']); if ($taskComponent->DUE->hasTime()) { $formattedTime = $this->l10n->l('time', $dueDateTime, ['width' => 'short']); - return $this->l10n->t('Due on %s by %s', [$formattedDate, $formattedTime]); + $formattedSubline = $this->l10n->t('Due on %s by %s', [$formattedDate, $formattedTime]); + } else { + $formattedSubline = $this->l10n->t('Due on %s', [$formattedDate]); } - - return $this->l10n->t('Due on %s', [$formattedDate]); + } else { + $formattedSubline = ''; } - return ''; + if (isset($calendarInfo['{DAV:}displayname']) && !empty($calendarInfo['{DAV:}displayname'])) { + $formattedSubline = $formattedSubline . (!empty($formattedSubline) ? ' ' : '') . "({$calendarInfo['{DAV:}displayname']})"; + } + + return $formattedSubline; } } diff --git a/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php b/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php index 7d58930f070..5f9d6adfa73 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php @@ -17,6 +17,7 @@ use OCP\Config\IUserConfig; use OCP\IAppConfig; use OCP\IDBConnection; use OCP\IL10N; +use OCP\IUser; use OCP\IUserManager; use OCP\L10N\IFactory; use OCP\Security\ISecureRandom; @@ -163,7 +164,7 @@ class IMipServiceTest extends TestCase { public function testIsSystemUserWhenUserExists(): void { $email = 'user@example.com'; - $user = $this->createMock(\OCP\IUser::class); + $user = $this->createMock(IUser::class); $this->userManager->expects(self::once()) ->method('getByEmail') diff --git a/apps/dav/tests/unit/Search/EventsSearchProviderTest.php b/apps/dav/tests/unit/Search/EventsSearchProviderTest.php index 463f8c4efc0..63139fbd9ac 100644 --- a/apps/dav/tests/unit/Search/EventsSearchProviderTest.php +++ b/apps/dav/tests/unit/Search/EventsSearchProviderTest.php @@ -436,7 +436,7 @@ class EventsSearchProviderTest extends TestCase { } #[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'generateSublineDataProvider')] - public function testGenerateSubline(string $ics, string $expectedSubline): void { + public function testGenerateSubline(string $ics, string $expectedSubline, array $calendarInfo = []): void { $vCalendar = Reader::read($ics, Reader::OPTION_FORGIVING); $eventComponent = $vCalendar->VEVENT; @@ -449,19 +449,23 @@ class EventsSearchProviderTest extends TestCase { return $date->format('m-d'); }); - $actual = self::invokePrivate($this->provider, 'generateSubline', [$eventComponent]); + $actual = self::invokePrivate($this->provider, 'generateSubline', [$eventComponent, $calendarInfo]); $this->assertEquals($expectedSubline, $actual); } public static function generateSublineDataProvider(): array { return [ - [self::$vEvent1, '08-16 09:00 - 10:00'], - [self::$vEvent2, '08-16 09:00 - 08-17 10:00'], - [self::$vEvent3, '10-05'], - [self::$vEvent4, '10-05 - 10-07'], - [self::$vEvent5, '10-05 - 10-09'], - [self::$vEvent6, '10-05'], - [self::$vEvent7, '08-16 09:00 - 09:00'], + [self::$vEvent1, '08-16 09:00 - 10:00', []], + [self::$vEvent2, '08-16 09:00 - 08-17 10:00', []], + [self::$vEvent3, '10-05', []], + [self::$vEvent4, '10-05 - 10-07', []], + [self::$vEvent5, '10-05 - 10-09', []], + [self::$vEvent6, '10-05', []], + [self::$vEvent7, '08-16 09:00 - 09:00', []], + [self::$vEvent1, '08-16 09:00 - 10:00 (My Calendar)', ['{DAV:}displayname' => 'My Calendar']], + [self::$vEvent3, '10-05 (My Calendar)', ['{DAV:}displayname' => 'My Calendar']], + [self::$vEvent2, '08-16 09:00 - 08-17 10:00 (My Calendar)', ['{DAV:}displayname' => 'My Calendar']], + [self::$vEvent1, '08-16 09:00 - 10:00', ['{DAV:}displayname' => '']], ]; } } diff --git a/apps/dav/tests/unit/Search/TasksSearchProviderTest.php b/apps/dav/tests/unit/Search/TasksSearchProviderTest.php index dcb35c624d4..fda96b5b229 100644 --- a/apps/dav/tests/unit/Search/TasksSearchProviderTest.php +++ b/apps/dav/tests/unit/Search/TasksSearchProviderTest.php @@ -290,24 +290,29 @@ class TasksSearchProviderTest extends TestCase { } #[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'generateSublineDataProvider')] - public function testGenerateSubline(string $ics, string $expectedSubline): void { + public function testGenerateSubline(string $ics, string $expectedSubline, array $calendarInfo = []): void { $vCalendar = Reader::read($ics, Reader::OPTION_FORGIVING); $taskComponent = $vCalendar->VTODO; $this->l10n->method('t')->willReturnArgument(0); $this->l10n->method('l')->willReturnArgument(0); - $actual = self::invokePrivate($this->provider, 'generateSubline', [$taskComponent]); + $actual = self::invokePrivate($this->provider, 'generateSubline', [$taskComponent, $calendarInfo]); $this->assertEquals($expectedSubline, $actual); } public static function generateSublineDataProvider(): array { return [ - [self::$vTodo0, ''], - [self::$vTodo1, 'Completed on %s'], - [self::$vTodo2, 'Completed on %s'], - [self::$vTodo3, 'Due on %s'], - [self::$vTodo4, 'Due on %s by %s'], + [self::$vTodo0, '', []], + [self::$vTodo1, 'Completed on %s', []], + [self::$vTodo2, 'Completed on %s', []], + [self::$vTodo3, 'Due on %s', []], + [self::$vTodo4, 'Due on %s by %s', []], + [self::$vTodo0, '(My Tasks)', ['{DAV:}displayname' => 'My Tasks']], + [self::$vTodo1, 'Completed on %s (My Tasks)', ['{DAV:}displayname' => 'My Tasks']], + [self::$vTodo3, 'Due on %s (My Tasks)', ['{DAV:}displayname' => 'My Tasks']], + [self::$vTodo4, 'Due on %s by %s (My Tasks)', ['{DAV:}displayname' => 'My Tasks']], + [self::$vTodo1, 'Completed on %s', ['{DAV:}displayname' => '']], ]; } } diff --git a/apps/encryption/l10n/es.js b/apps/encryption/l10n/es.js index f338f4fd550..314788fa479 100644 --- a/apps/encryption/l10n/es.js +++ b/apps/encryption/l10n/es.js @@ -33,21 +33,31 @@ OC.L10N.register( "Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Por favor ingrese en la interfaz web, vaya a la sección \"Seguridad\" de sus ajustes personales y actualice su contraseña de cifrado ingresando esta contraseña en el campo \"Contraseña de inicio de sesión antigua\" y su contraseña actual.", "Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "No se puede descifrar este archivo, probablemente se trate de un archivo compartido. Por favor, pida al propietario del archivo que vuelva a compartirlo con usted.", "Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "No se puede leer este archivo, probablemente se trate de un archivo compartido. Por favor, pida al propietario del archivo que vuelva a compartirlo con usted.", + "Default Encryption Module" : "Módulo de cifrado predeterminado", + "Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Módulo de cifrado predeterminado para el cifrado del lado del servidor (SSE) de Nextcloud", "Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Al activar esta opción se encriptarán todos los archivos almacenados en la memoria principal, de lo contrario, serán cifrados sólo los archivos de almacenamiento externo", "Encrypt the home storage" : "Encriptar el almacenamiento personal", "Disable recovery key" : "Desactiva la clave de recuperación", "Enable recovery key" : "Activa la clave de recuperación", "The recovery key is an additional encryption key used to encrypt files. It is used to recover files from an account if the password is forgotten." : "La llave de recuperación es una llave de cifrado adicional utilizada para cifrar archivos. Es utilizada para recuperar los archivos de una cuenta si la contraseña fuese olvidada.", "Recovery key password" : "Contraseña de clave de recuperación", + "Passwords fields do not match" : "Las contraseñas no coinciden", "Repeat recovery key password" : "Repita la contraseña de recuperación", + "An error occurred while updating the recovery key settings. Please try again." : "Se produjo un error al actualizar la configuración de la clave de recuperación. Por favor, inténtelo de nuevo.", + "Change recovery key password" : "Cambiar la contraseña de la clave de recuperación", "Old recovery key password" : "Antigua contraseña de recuperación", "New recovery key password" : "Nueva contraseña de recuperación", "Repeat new recovery key password" : "Repita la nueva contraseña de recuperación", + "An error occurred while changing the recovery key password. Please try again." : "Se produjo un error al cambiar la contraseña de la clave de recuperación. Por favor, inténtelo de nuevo.", + "Update private key password" : "Actualizar la contraseña de la clave privada", + "Your private key password no longer matches your log-in password. Set your old private key password to your current log-in password." : "Tu contraseña de clave privada ya no coincide con tu contraseña de inicio de sesión. Cambia tu contraseña de clave privada anterior a tu contraseña de inicio de sesión actual.", "If you do not remember your old password you can ask your administrator to recover your files." : "Si no recuerda su antigua contraseña, puede pedir a su administrador que recupere sus archivos.", "Old log-in password" : "Contraseña de acceso antigua", "Current log-in password" : "Contraseña de acceso actual", "Update" : "Actualizar", + "Updating recovery keys. This can take some time…" : "Actualizando las claves de recuperación. Esto puede tardar algún tiempo …", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Habilitar esta opción le permitirá volver a tener acceso a sus archivos cifrados en caso de pérdida de contraseña", + "Enable password recovery" : "Habilitar la contraseña de recuperación", "Default encryption module" : "Módulo de cifrado por defecto", "Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "La app de cifrado está habilitada pero sus claves no se han inicializado, por favor, cierre la sesión y vuelva a iniciarla de nuevo.", "Basic encryption module" : "Módulo de cifrado básico", diff --git a/apps/encryption/l10n/es.json b/apps/encryption/l10n/es.json index 97e65e8142e..2a7b796fb53 100644 --- a/apps/encryption/l10n/es.json +++ b/apps/encryption/l10n/es.json @@ -31,21 +31,31 @@ "Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Por favor ingrese en la interfaz web, vaya a la sección \"Seguridad\" de sus ajustes personales y actualice su contraseña de cifrado ingresando esta contraseña en el campo \"Contraseña de inicio de sesión antigua\" y su contraseña actual.", "Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "No se puede descifrar este archivo, probablemente se trate de un archivo compartido. Por favor, pida al propietario del archivo que vuelva a compartirlo con usted.", "Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "No se puede leer este archivo, probablemente se trate de un archivo compartido. Por favor, pida al propietario del archivo que vuelva a compartirlo con usted.", + "Default Encryption Module" : "Módulo de cifrado predeterminado", + "Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Módulo de cifrado predeterminado para el cifrado del lado del servidor (SSE) de Nextcloud", "Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Al activar esta opción se encriptarán todos los archivos almacenados en la memoria principal, de lo contrario, serán cifrados sólo los archivos de almacenamiento externo", "Encrypt the home storage" : "Encriptar el almacenamiento personal", "Disable recovery key" : "Desactiva la clave de recuperación", "Enable recovery key" : "Activa la clave de recuperación", "The recovery key is an additional encryption key used to encrypt files. It is used to recover files from an account if the password is forgotten." : "La llave de recuperación es una llave de cifrado adicional utilizada para cifrar archivos. Es utilizada para recuperar los archivos de una cuenta si la contraseña fuese olvidada.", "Recovery key password" : "Contraseña de clave de recuperación", + "Passwords fields do not match" : "Las contraseñas no coinciden", "Repeat recovery key password" : "Repita la contraseña de recuperación", + "An error occurred while updating the recovery key settings. Please try again." : "Se produjo un error al actualizar la configuración de la clave de recuperación. Por favor, inténtelo de nuevo.", + "Change recovery key password" : "Cambiar la contraseña de la clave de recuperación", "Old recovery key password" : "Antigua contraseña de recuperación", "New recovery key password" : "Nueva contraseña de recuperación", "Repeat new recovery key password" : "Repita la nueva contraseña de recuperación", + "An error occurred while changing the recovery key password. Please try again." : "Se produjo un error al cambiar la contraseña de la clave de recuperación. Por favor, inténtelo de nuevo.", + "Update private key password" : "Actualizar la contraseña de la clave privada", + "Your private key password no longer matches your log-in password. Set your old private key password to your current log-in password." : "Tu contraseña de clave privada ya no coincide con tu contraseña de inicio de sesión. Cambia tu contraseña de clave privada anterior a tu contraseña de inicio de sesión actual.", "If you do not remember your old password you can ask your administrator to recover your files." : "Si no recuerda su antigua contraseña, puede pedir a su administrador que recupere sus archivos.", "Old log-in password" : "Contraseña de acceso antigua", "Current log-in password" : "Contraseña de acceso actual", "Update" : "Actualizar", + "Updating recovery keys. This can take some time…" : "Actualizando las claves de recuperación. Esto puede tardar algún tiempo …", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Habilitar esta opción le permitirá volver a tener acceso a sus archivos cifrados en caso de pérdida de contraseña", + "Enable password recovery" : "Habilitar la contraseña de recuperación", "Default encryption module" : "Módulo de cifrado por defecto", "Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "La app de cifrado está habilitada pero sus claves no se han inicializado, por favor, cierre la sesión y vuelva a iniciarla de nuevo.", "Basic encryption module" : "Módulo de cifrado básico", diff --git a/apps/federatedfilesharing/lib/AppInfo/Application.php b/apps/federatedfilesharing/lib/AppInfo/Application.php index b77c76acf5a..ca22ce2cbc6 100644 --- a/apps/federatedfilesharing/lib/AppInfo/Application.php +++ b/apps/federatedfilesharing/lib/AppInfo/Application.php @@ -17,6 +17,7 @@ use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\Federation\ICloudFederationProviderManager; +use OCP\Server; class Application extends App implements IBootstrap { @@ -41,7 +42,7 @@ class Application extends App implements IBootstrap { $manager->addCloudFederationProvider($type, 'Federated Files Sharing', function (): CloudFederationProviderFiles { - return \OCP\Server::get(CloudFederationProviderFiles::class); + return Server::get(CloudFederationProviderFiles::class); }); } } diff --git a/apps/federatedfilesharing/lib/Settings/Admin.php b/apps/federatedfilesharing/lib/Settings/Admin.php index e66f1a1e417..20b7ca62ad0 100644 --- a/apps/federatedfilesharing/lib/Settings/Admin.php +++ b/apps/federatedfilesharing/lib/Settings/Admin.php @@ -14,6 +14,7 @@ use OCP\GlobalScale\IConfig; use OCP\IL10N; use OCP\IURLGenerator; use OCP\Settings\IDelegatedSettings; +use OCP\Util; class Admin implements IDelegatedSettings { /** @@ -44,8 +45,8 @@ class Admin implements IDelegatedSettings { $this->initialState->provideInitialState('lookupServerUploadEnabled', $this->fedShareProvider->isLookupServerUploadEnabled()); $this->initialState->provideInitialState('federatedTrustedShareAutoAccept', $this->fedShareProvider->isFederatedTrustedShareAutoAccept()); - \OCP\Util::addStyle(Application::APP_ID, 'settings-admin'); - \OCP\Util::addScript(Application::APP_ID, 'settings-admin'); + Util::addStyle(Application::APP_ID, 'settings-admin'); + Util::addScript(Application::APP_ID, 'settings-admin'); return new TemplateResponse(Application::APP_ID, 'settings-admin', renderAs: ''); } diff --git a/apps/federatedfilesharing/lib/Settings/Personal.php b/apps/federatedfilesharing/lib/Settings/Personal.php index fc401c404d4..01239fbe140 100644 --- a/apps/federatedfilesharing/lib/Settings/Personal.php +++ b/apps/federatedfilesharing/lib/Settings/Personal.php @@ -16,6 +16,7 @@ use OCP\Defaults; use OCP\IURLGenerator; use OCP\IUserSession; use OCP\Settings\ISettings; +use OCP\Util; class Personal implements ISettings { public function __construct( @@ -42,8 +43,8 @@ class Personal implements ISettings { $this->initialState->provideInitialState('cloudId', $cloudID); $this->initialState->provideInitialState('docUrlFederated', $this->urlGenerator->linkToDocs('user-sharing-federated')); - \OCP\Util::addStyle(Application::APP_ID, 'settings-personal'); - \OCP\Util::addScript(Application::APP_ID, 'settings-personal'); + Util::addStyle(Application::APP_ID, 'settings-personal'); + Util::addScript(Application::APP_ID, 'settings-personal'); return new TemplateResponse(Application::APP_ID, 'settings-personal', renderAs: TemplateResponse::RENDER_AS_BLANK); } diff --git a/apps/files/l10n/de.js b/apps/files/l10n/de.js index f30140668a9..b67eb79af7c 100644 --- a/apps/files/l10n/de.js +++ b/apps/files/l10n/de.js @@ -95,6 +95,7 @@ OC.L10N.register( "Another entry with the same name already exists." : "Ein anderer Eintrag mit diesem Namen existiert bereits.", "Invalid filename." : "Ungültiger Dateiname.", "Rename file" : "Datei umbenennen", + "Recently created" : "Zuletzt erstellt", "Folder" : "Ordner", "Unknown file type" : "Unbekannter Dateityp", "{ext} image" : "{ext}-Bild", diff --git a/apps/files/l10n/de.json b/apps/files/l10n/de.json index 2d7a576fd13..6565258200c 100644 --- a/apps/files/l10n/de.json +++ b/apps/files/l10n/de.json @@ -93,6 +93,7 @@ "Another entry with the same name already exists." : "Ein anderer Eintrag mit diesem Namen existiert bereits.", "Invalid filename." : "Ungültiger Dateiname.", "Rename file" : "Datei umbenennen", + "Recently created" : "Zuletzt erstellt", "Folder" : "Ordner", "Unknown file type" : "Unbekannter Dateityp", "{ext} image" : "{ext}-Bild", diff --git a/apps/files/l10n/de_DE.js b/apps/files/l10n/de_DE.js index b9743727a70..36411b3e1b5 100644 --- a/apps/files/l10n/de_DE.js +++ b/apps/files/l10n/de_DE.js @@ -95,6 +95,7 @@ OC.L10N.register( "Another entry with the same name already exists." : "Ein anderer Eintrag mit diesem Namen existiert bereits.", "Invalid filename." : "Ungültiger Dateiname.", "Rename file" : "Datei umbenennen", + "Recently created" : "Zuletzt erstellt", "Folder" : "Ordner", "Unknown file type" : "Unbekannter Dateityp", "{ext} image" : "{ext}-Bild", diff --git a/apps/files/l10n/de_DE.json b/apps/files/l10n/de_DE.json index 01ef3dae86b..29183c8b6a0 100644 --- a/apps/files/l10n/de_DE.json +++ b/apps/files/l10n/de_DE.json @@ -93,6 +93,7 @@ "Another entry with the same name already exists." : "Ein anderer Eintrag mit diesem Namen existiert bereits.", "Invalid filename." : "Ungültiger Dateiname.", "Rename file" : "Datei umbenennen", + "Recently created" : "Zuletzt erstellt", "Folder" : "Ordner", "Unknown file type" : "Unbekannter Dateityp", "{ext} image" : "{ext}-Bild", diff --git a/apps/files/l10n/et_EE.js b/apps/files/l10n/et_EE.js index db68f525edc..6f5505f5aad 100644 --- a/apps/files/l10n/et_EE.js +++ b/apps/files/l10n/et_EE.js @@ -95,6 +95,7 @@ OC.L10N.register( "Another entry with the same name already exists." : "Selle nimega kirje on juba olemas.", "Invalid filename." : "Vigane failinimi.", "Rename file" : "Muuda failinime", + "Recently created" : "Loodud hiljuti", "Folder" : "Kaust", "Unknown file type" : "Tundmatu failitüüp", "{ext} image" : "{ext} pilt", @@ -366,7 +367,7 @@ OC.L10N.register( "The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "„{newName}“ nimi on juba „{dir}“ kaustas kasutusel. Palun vali teine nimi.", "Could not rename \"{oldName}\"" : "„{oldName}“ faili nime muutmine ei õnnestunud", "This operation is forbidden" : "See toiming on keelatud", - "This folder is unavailable, please try again later or contact the administration" : "See kaust pole saadaval, palun proovi hiljem uuesti või võta ühendust haldajaaga", + "This folder is unavailable, please try again later or contact the administration" : "See kaust pole saadaval, palun proovi hiljem uuesti või võta ühendust haldajaga", "Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav", "Unexpected error: {error}" : "Tundmatu viga: {error}", "_%n file_::_%n files_" : ["%n fail","%n faili"], @@ -390,7 +391,7 @@ OC.L10N.register( "No recently modified files" : "Hiljuti muudetud faile pole.", "Files and folders you recently modified will show up here." : "Failid ja kaustad, mida oled hiljuti muutnud, ilmuvad siia.", "Search" : "Otsi", - "Search results within your files." : "Otsingutulemusd sinu failide seast.", + "Search results within your files." : "Otsingutulemused sinu failide seast.", "No entries found in this folder" : "Selles kaustast ei leitud kirjeid", "Select all" : "Vali kõik", "Upload too large" : "Üleslaadimine on liiga suur", diff --git a/apps/files/l10n/et_EE.json b/apps/files/l10n/et_EE.json index 230dddefed3..2eb7f421f1f 100644 --- a/apps/files/l10n/et_EE.json +++ b/apps/files/l10n/et_EE.json @@ -93,6 +93,7 @@ "Another entry with the same name already exists." : "Selle nimega kirje on juba olemas.", "Invalid filename." : "Vigane failinimi.", "Rename file" : "Muuda failinime", + "Recently created" : "Loodud hiljuti", "Folder" : "Kaust", "Unknown file type" : "Tundmatu failitüüp", "{ext} image" : "{ext} pilt", @@ -364,7 +365,7 @@ "The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "„{newName}“ nimi on juba „{dir}“ kaustas kasutusel. Palun vali teine nimi.", "Could not rename \"{oldName}\"" : "„{oldName}“ faili nime muutmine ei õnnestunud", "This operation is forbidden" : "See toiming on keelatud", - "This folder is unavailable, please try again later or contact the administration" : "See kaust pole saadaval, palun proovi hiljem uuesti või võta ühendust haldajaaga", + "This folder is unavailable, please try again later or contact the administration" : "See kaust pole saadaval, palun proovi hiljem uuesti või võta ühendust haldajaga", "Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav", "Unexpected error: {error}" : "Tundmatu viga: {error}", "_%n file_::_%n files_" : ["%n fail","%n faili"], @@ -388,7 +389,7 @@ "No recently modified files" : "Hiljuti muudetud faile pole.", "Files and folders you recently modified will show up here." : "Failid ja kaustad, mida oled hiljuti muutnud, ilmuvad siia.", "Search" : "Otsi", - "Search results within your files." : "Otsingutulemusd sinu failide seast.", + "Search results within your files." : "Otsingutulemused sinu failide seast.", "No entries found in this folder" : "Selles kaustast ei leitud kirjeid", "Select all" : "Vali kõik", "Upload too large" : "Üleslaadimine on liiga suur", diff --git a/apps/files/l10n/pt_BR.js b/apps/files/l10n/pt_BR.js index 708ac7c4fae..4104dc40c02 100644 --- a/apps/files/l10n/pt_BR.js +++ b/apps/files/l10n/pt_BR.js @@ -95,6 +95,7 @@ OC.L10N.register( "Another entry with the same name already exists." : "Outra entrada com o mesmo nome já existe.", "Invalid filename." : "Nome de arquivo inválido.", "Rename file" : "Renomear arquivo", + "Recently created" : "Criado recentemente", "Folder" : "Pasta", "Unknown file type" : "Tipo de arquivo desconhecido", "{ext} image" : "imagem {ext}", diff --git a/apps/files/l10n/pt_BR.json b/apps/files/l10n/pt_BR.json index 2a758cf6371..7c58d625fd2 100644 --- a/apps/files/l10n/pt_BR.json +++ b/apps/files/l10n/pt_BR.json @@ -93,6 +93,7 @@ "Another entry with the same name already exists." : "Outra entrada com o mesmo nome já existe.", "Invalid filename." : "Nome de arquivo inválido.", "Rename file" : "Renomear arquivo", + "Recently created" : "Criado recentemente", "Folder" : "Pasta", "Unknown file type" : "Tipo de arquivo desconhecido", "{ext} image" : "imagem {ext}", diff --git a/apps/files/l10n/zh_TW.js b/apps/files/l10n/zh_TW.js index eee1afedf5f..8a954c7cc7c 100644 --- a/apps/files/l10n/zh_TW.js +++ b/apps/files/l10n/zh_TW.js @@ -95,6 +95,7 @@ OC.L10N.register( "Another entry with the same name already exists." : "已存在另一個同名條目。", "Invalid filename." : "無效的檔案名稱。", "Rename file" : "重新命名檔案", + "Recently created" : "最近建立", "Folder" : "資料夾", "Unknown file type" : "未知檔案類型", "{ext} image" : "{ext} 影像", diff --git a/apps/files/l10n/zh_TW.json b/apps/files/l10n/zh_TW.json index fcb90644d14..88466e6a20e 100644 --- a/apps/files/l10n/zh_TW.json +++ b/apps/files/l10n/zh_TW.json @@ -93,6 +93,7 @@ "Another entry with the same name already exists." : "已存在另一個同名條目。", "Invalid filename." : "無效的檔案名稱。", "Rename file" : "重新命名檔案", + "Recently created" : "最近建立", "Folder" : "資料夾", "Unknown file type" : "未知檔案類型", "{ext} image" : "{ext} 影像", diff --git a/apps/files/tests/Command/ScanAppDataTest.php b/apps/files/tests/Command/ScanAppDataTest.php index cdba710c2c8..a0fc5b18afe 100644 --- a/apps/files/tests/Command/ScanAppDataTest.php +++ b/apps/files/tests/Command/ScanAppDataTest.php @@ -69,7 +69,7 @@ class ScanAppDataTest extends TestCase { $this->scanner->method('getScanner')->willReturn($this->internalScanner); $this->scanner->method('initTools') - ->willReturnCallback(function () {}); + ->willReturnCallback(function (): void {}); try { $this->rootFolder->get($this->rootFolder->getAppDataDirectoryName() . '/preview')->delete(); } catch (NotFoundException) { @@ -103,7 +103,7 @@ class ScanAppDataTest extends TestCase { } $this->input->method('getArgument')->with('folder')->willReturn(''); - $this->internalScanner->method('scan')->willReturnCallback(function () { + $this->internalScanner->method('scan')->willReturnCallback(function (): void { $this->internalScanner->emit('\OC\Files\Utils\Scanner', 'scanFile', ['path42']); $this->internalScanner->emit('\OC\Files\Utils\Scanner', 'scanFolder', ['path42']); $this->internalScanner->emit('\OC\Files\Utils\Scanner', 'scanFolder', ['path42']); diff --git a/apps/files_external/l10n/es.js b/apps/files_external/l10n/es.js index 2a06e4eecf5..e09367c5ba7 100644 --- a/apps/files_external/l10n/es.js +++ b/apps/files_external/l10n/es.js @@ -41,6 +41,7 @@ OC.L10N.register( "Kerberos default realm, defaults to \"WORKGROUP\"" : "El ámbito por defecto de Kerberos es \"WORKGROUP\".", "Kerberos ticket Apache mode" : "Ticket Kerberos Modo Apache", "Kerberos ticket" : "Ticket de Kerberos", + "S3 Storage" : "Almacenamiento S3", "Bucket" : "Bucket", "Hostname" : "Dirección del servidor", "Port" : "Puerto", @@ -51,6 +52,7 @@ OC.L10N.register( "Enable Path Style" : "Habilitar Estilo de Ruta", "Legacy (v2) authentication" : "Autenticación heredada (v2)", "Enable multipart copy" : "Activa a copia multiparte", + "Use presigned S3 url" : "Utilice la URL S3 pre-firmada", "SSE-C encryption key" : "Llave de cifrado SSE-C", "WebDAV" : "WebDAV", "URL" : "URL", @@ -82,15 +84,20 @@ OC.L10N.register( "External storage support" : "Soporte de almacenamiento externo", "Adds basic external storage support" : "Añade soporte básico de almacenamiento externo", "This application enables administrators to configure connections to external storage providers, such as FTP servers, S3 or SWIFT object stores, other Nextcloud servers, WebDAV servers, and more. Administration can choose which types of storage to enable and can mount these storage locations for an account, a group, or the entire system. Users will see a new folder appear in their root Nextcloud directory, which they can access and use like any other Nextcloud folder. External storage also allows people to share files stored in these external locations. In these cases, the credentials for the owner of the file are used when the recipient requests the file from external storage, thereby ensuring that the recipient can access the shared file.\n\nExternal storage can be configured using the GUI or at the command line. This second option provides the administration with more flexibility for configuring bulk external storage mounts and setting mount priorities. More information is available in the external storage GUI documentation and the external storage Configuration File documentation." : "Esta aplicación permite a los administradores configurar conexiones con proveedores de almacenamiento externos, como servidores FTP, almacenes de objetos S3 o SWIFT, otros servidores Nextcloud, servidores WebDAV y mucho más. La administración puede escoger qué tipos de almacenamiento activar y puede montar estas localizaciones de almacenamiento para una cuenta, un grupo o todo el sistema. Los usuarios verán aparecer una nueva carpeta en su directorio raíz de Nextcloud. Pueden acceder a ella o usarla como cualquiera otra carpeta. El almacenamiento externo también permite que las personas compartan ficheros almacenados en estas localizaciones externas. En estos casos, se utilizan las credenciales del propietario cuando el destinatario solicita el fichero desde el almacenamiento externo, garantizando así que el destinatario pueda acceder al fichero compartido.\n\nSe puede configurar el almacenamiento externo mediante la GUI o la línea de comandos. Esta segunda opción proporciona al administrador más flexibilidad para configurar montajes de almacenamiento externo masivo y establecer prioridades de montaje. Hay más información disponible en la documentación de la GUI del almacenamiento externo y en la documentación del fichero de configuración del almacenamiento externo.", + "Edit storage" : "Editar almacenamiento", "Add storage" : "Añadir almacenamiento", "Folder name" : "Nombre de la carpeta", "Authentication" : "Autentificación", "Cancel" : "Cancelar", "Edit" : "Editar", "Create" : "Crear", + "Restrict to" : "Restringir a", + "Storage configuration" : "Configuración de almacenamiento", "Never" : "Nunca", "Once every direct access" : "Una vez en cada acceso", "Always" : "Siempre", + "Mount options" : "Opciones de montaje", + "Check filesystem changes" : "Comprobar cambios en el sistema de archivos", "Read only" : "Solo lectura", "Enable previews" : "Habilitar previsualizaciones", "Enable sharing" : "Habilitar el uso compartido", @@ -98,11 +105,19 @@ OC.L10N.register( "Compatibility with Mac NFD encoding (slow)" : "Compatibilidad con codificación Mac MFD (lento)", "External storages" : "Almacenamiento externo", "Status" : "Estado", + "Restricted to" : "Restringido a", "Actions" : "Acciones", + "Checking …" : "Comprobando ...", + "Recheck status" : "Volver a comprobar el estado", "Delete" : "Eliminar", + "System provided storage" : "Almacenamiento proporcionado por el sistema", "Saved" : "Guardado", "Error while saving" : "Error al guardar", + "Saved allowed backends" : "Backends permitidos guardados", + "Failed to save allowed backends" : "No se pudieron guardar los backends permitidos", + "Advanced options for external storage mounts" : "Opciones avanzadas para almacenamiento externo", "Allow people to mount external storage" : "Permite que as persoas monten almacenamento externo", + "External storage backends people are allowed to mount" : "Las personas pueden montar los backends de almacenamiento externo", "Error generating key pair" : "Error al generar el par de claves", "Key size" : "Tamaño de llave", "Generate keys" : "Generar claves", @@ -111,6 +126,16 @@ OC.L10N.register( "To access the storage, you need to provide the authentication credentials." : "Para acceder al almacenamiento, debe proporcionar las credenciales de autenticación.", "Enter the storage login" : "Ingrese el inicio de sesión de almacenamiento", "Enter the storage password" : "Ingrese la contraseña de almacenamiento", + "External storage enables you to mount external storage services and devices as secondary Nextcloud storage devices." : "El almacenamiento externo le permite montar servicios y dispositivos de almacenamiento externo como dispositivos de almacenamiento secundarios de Nextcloud.", + "You may also allow people to mount their own external storage services." : "También puede permitir que las personas monten sus propios servicios de almacenamiento externo.", + "The cURL support in PHP is not enabled or installed." : "El soporte de cURL en PHP no está habilitado o instalado.", + "The FTP support in PHP is not enabled or installed." : "El soporte FTP en PHP no está habilitado o instalado.", + "{module} is not installed." : "{module} no está instalado.", + "Dependant backends" : "Backends dependientes", + "No external storage configured or you do not have the permission to configure them" : "No hay almacenamiento externo configurado o no tienes permiso para configurarlo", + "Add external storage" : "Agregar almacenamiento externo", + "Global credentials saved" : "Credenciales globales guardadas", + "Could not save global credentials" : "No se pudieron guardar las credenciales globales", "Global credentials can be used to authenticate with multiple external storages that have the same credentials." : "Se pueden usar credenciales globales para autenticar con múltiples almacenamientos externos que tengan las mismas credenciales.", "Saving …" : "Guardando …", "Save" : "Guardar", @@ -119,6 +144,7 @@ OC.L10N.register( "Enter missing credentials" : "Introduzca las credenciales requeridas", "Credentials successfully set" : "Se han establecido las credenciales exitosamente", "Error while setting credentials: {error}" : "Error al establecer credenciales: {error}", + "Checking storage …" : "Comprobando almacenamiento …", "There was an error with this external storage." : "Se presentó un problema con este almacenamiento externo.", "We were unable to check the external storage {basename}" : "No nos fue posible chequear el almacenamiento externo {basename}", "Examine this faulty external storage configuration" : "Examinar la configuración de este almacenamiento externo con fallas", @@ -138,6 +164,8 @@ OC.L10N.register( "System" : "Sistema", "Connected" : "Conectado", "Error" : "Error", + "Indeterminate" : "Indeterminado", + "Incomplete configuration" : "Configuración incompleta", "Unauthorized" : "Desautorizado", "Network error" : "Error de red", "Grant access" : "Conceder acceso", diff --git a/apps/files_external/l10n/es.json b/apps/files_external/l10n/es.json index 2b51f7cc370..6d8523c8f22 100644 --- a/apps/files_external/l10n/es.json +++ b/apps/files_external/l10n/es.json @@ -39,6 +39,7 @@ "Kerberos default realm, defaults to \"WORKGROUP\"" : "El ámbito por defecto de Kerberos es \"WORKGROUP\".", "Kerberos ticket Apache mode" : "Ticket Kerberos Modo Apache", "Kerberos ticket" : "Ticket de Kerberos", + "S3 Storage" : "Almacenamiento S3", "Bucket" : "Bucket", "Hostname" : "Dirección del servidor", "Port" : "Puerto", @@ -49,6 +50,7 @@ "Enable Path Style" : "Habilitar Estilo de Ruta", "Legacy (v2) authentication" : "Autenticación heredada (v2)", "Enable multipart copy" : "Activa a copia multiparte", + "Use presigned S3 url" : "Utilice la URL S3 pre-firmada", "SSE-C encryption key" : "Llave de cifrado SSE-C", "WebDAV" : "WebDAV", "URL" : "URL", @@ -80,15 +82,20 @@ "External storage support" : "Soporte de almacenamiento externo", "Adds basic external storage support" : "Añade soporte básico de almacenamiento externo", "This application enables administrators to configure connections to external storage providers, such as FTP servers, S3 or SWIFT object stores, other Nextcloud servers, WebDAV servers, and more. Administration can choose which types of storage to enable and can mount these storage locations for an account, a group, or the entire system. Users will see a new folder appear in their root Nextcloud directory, which they can access and use like any other Nextcloud folder. External storage also allows people to share files stored in these external locations. In these cases, the credentials for the owner of the file are used when the recipient requests the file from external storage, thereby ensuring that the recipient can access the shared file.\n\nExternal storage can be configured using the GUI or at the command line. This second option provides the administration with more flexibility for configuring bulk external storage mounts and setting mount priorities. More information is available in the external storage GUI documentation and the external storage Configuration File documentation." : "Esta aplicación permite a los administradores configurar conexiones con proveedores de almacenamiento externos, como servidores FTP, almacenes de objetos S3 o SWIFT, otros servidores Nextcloud, servidores WebDAV y mucho más. La administración puede escoger qué tipos de almacenamiento activar y puede montar estas localizaciones de almacenamiento para una cuenta, un grupo o todo el sistema. Los usuarios verán aparecer una nueva carpeta en su directorio raíz de Nextcloud. Pueden acceder a ella o usarla como cualquiera otra carpeta. El almacenamiento externo también permite que las personas compartan ficheros almacenados en estas localizaciones externas. En estos casos, se utilizan las credenciales del propietario cuando el destinatario solicita el fichero desde el almacenamiento externo, garantizando así que el destinatario pueda acceder al fichero compartido.\n\nSe puede configurar el almacenamiento externo mediante la GUI o la línea de comandos. Esta segunda opción proporciona al administrador más flexibilidad para configurar montajes de almacenamiento externo masivo y establecer prioridades de montaje. Hay más información disponible en la documentación de la GUI del almacenamiento externo y en la documentación del fichero de configuración del almacenamiento externo.", + "Edit storage" : "Editar almacenamiento", "Add storage" : "Añadir almacenamiento", "Folder name" : "Nombre de la carpeta", "Authentication" : "Autentificación", "Cancel" : "Cancelar", "Edit" : "Editar", "Create" : "Crear", + "Restrict to" : "Restringir a", + "Storage configuration" : "Configuración de almacenamiento", "Never" : "Nunca", "Once every direct access" : "Una vez en cada acceso", "Always" : "Siempre", + "Mount options" : "Opciones de montaje", + "Check filesystem changes" : "Comprobar cambios en el sistema de archivos", "Read only" : "Solo lectura", "Enable previews" : "Habilitar previsualizaciones", "Enable sharing" : "Habilitar el uso compartido", @@ -96,11 +103,19 @@ "Compatibility with Mac NFD encoding (slow)" : "Compatibilidad con codificación Mac MFD (lento)", "External storages" : "Almacenamiento externo", "Status" : "Estado", + "Restricted to" : "Restringido a", "Actions" : "Acciones", + "Checking …" : "Comprobando ...", + "Recheck status" : "Volver a comprobar el estado", "Delete" : "Eliminar", + "System provided storage" : "Almacenamiento proporcionado por el sistema", "Saved" : "Guardado", "Error while saving" : "Error al guardar", + "Saved allowed backends" : "Backends permitidos guardados", + "Failed to save allowed backends" : "No se pudieron guardar los backends permitidos", + "Advanced options for external storage mounts" : "Opciones avanzadas para almacenamiento externo", "Allow people to mount external storage" : "Permite que as persoas monten almacenamento externo", + "External storage backends people are allowed to mount" : "Las personas pueden montar los backends de almacenamiento externo", "Error generating key pair" : "Error al generar el par de claves", "Key size" : "Tamaño de llave", "Generate keys" : "Generar claves", @@ -109,6 +124,16 @@ "To access the storage, you need to provide the authentication credentials." : "Para acceder al almacenamiento, debe proporcionar las credenciales de autenticación.", "Enter the storage login" : "Ingrese el inicio de sesión de almacenamiento", "Enter the storage password" : "Ingrese la contraseña de almacenamiento", + "External storage enables you to mount external storage services and devices as secondary Nextcloud storage devices." : "El almacenamiento externo le permite montar servicios y dispositivos de almacenamiento externo como dispositivos de almacenamiento secundarios de Nextcloud.", + "You may also allow people to mount their own external storage services." : "También puede permitir que las personas monten sus propios servicios de almacenamiento externo.", + "The cURL support in PHP is not enabled or installed." : "El soporte de cURL en PHP no está habilitado o instalado.", + "The FTP support in PHP is not enabled or installed." : "El soporte FTP en PHP no está habilitado o instalado.", + "{module} is not installed." : "{module} no está instalado.", + "Dependant backends" : "Backends dependientes", + "No external storage configured or you do not have the permission to configure them" : "No hay almacenamiento externo configurado o no tienes permiso para configurarlo", + "Add external storage" : "Agregar almacenamiento externo", + "Global credentials saved" : "Credenciales globales guardadas", + "Could not save global credentials" : "No se pudieron guardar las credenciales globales", "Global credentials can be used to authenticate with multiple external storages that have the same credentials." : "Se pueden usar credenciales globales para autenticar con múltiples almacenamientos externos que tengan las mismas credenciales.", "Saving …" : "Guardando …", "Save" : "Guardar", @@ -117,6 +142,7 @@ "Enter missing credentials" : "Introduzca las credenciales requeridas", "Credentials successfully set" : "Se han establecido las credenciales exitosamente", "Error while setting credentials: {error}" : "Error al establecer credenciales: {error}", + "Checking storage …" : "Comprobando almacenamiento …", "There was an error with this external storage." : "Se presentó un problema con este almacenamiento externo.", "We were unable to check the external storage {basename}" : "No nos fue posible chequear el almacenamiento externo {basename}", "Examine this faulty external storage configuration" : "Examinar la configuración de este almacenamiento externo con fallas", @@ -136,6 +162,8 @@ "System" : "Sistema", "Connected" : "Conectado", "Error" : "Error", + "Indeterminate" : "Indeterminado", + "Incomplete configuration" : "Configuración incompleta", "Unauthorized" : "Desautorizado", "Network error" : "Error de red", "Grant access" : "Conceder acceso", diff --git a/apps/files_external/tests/Settings/AdminTest.php b/apps/files_external/tests/Settings/AdminTest.php index b8524b5fc2a..07f4e2df2b4 100644 --- a/apps/files_external/tests/Settings/AdminTest.php +++ b/apps/files_external/tests/Settings/AdminTest.php @@ -85,7 +85,7 @@ class AdminTest extends TestCase { $this->initialState ->expects($this->atLeastOnce()) ->method('provideInitialState') - ->willReturnCallback(function () use (&$initialState) { + ->willReturnCallback(function () use (&$initialState): void { $args = func_get_args(); $initialState[$args[0]] = $args[1]; }); diff --git a/apps/files_sharing/lib/Controller/DeletedShareAPIController.php b/apps/files_sharing/lib/Controller/DeletedShareAPIController.php index e7ddab8a40b..42105dca133 100644 --- a/apps/files_sharing/lib/Controller/DeletedShareAPIController.php +++ b/apps/files_sharing/lib/Controller/DeletedShareAPIController.php @@ -8,6 +8,7 @@ declare(strict_types=1); */ namespace OCA\Files_Sharing\Controller; +use OCA\Deck\Sharing\ShareAPIHelper; use OCA\Files_Sharing\ResponseDefinitions; use OCP\App\IAppManager; use OCP\AppFramework\Http; @@ -204,12 +205,12 @@ class DeletedShareAPIController extends OCSController { * @psalm-suppress UndefinedClass * @throws ContainerExceptionInterface */ - private function getDeckShareHelper(): \OCA\Deck\Sharing\ShareAPIHelper { + private function getDeckShareHelper(): ShareAPIHelper { if (!$this->appManager->isEnabledForUser('deck')) { throw new QueryException(); } /** @psalm-suppress UndefinedClass */ - return Server::get(\OCA\Deck\Sharing\ShareAPIHelper::class); + return Server::get(ShareAPIHelper::class); } } diff --git a/apps/files_sharing/tests/ShareTargetValidatorTest.php b/apps/files_sharing/tests/ShareTargetValidatorTest.php index 7589c32285d..7bc5820d39e 100644 --- a/apps/files_sharing/tests/ShareTargetValidatorTest.php +++ b/apps/files_sharing/tests/ShareTargetValidatorTest.php @@ -178,7 +178,7 @@ class ShareTargetValidatorTest extends TestCase { $share = $this->shareManager->getShareById($share->getFullId()); $this->assertSame('/foo/bar' . $this->folder, $share->getTarget()); - $this->eventDispatcher->addListener(VerifyMountPointEvent::class, function (VerifyMountPointEvent $event) { + $this->eventDispatcher->addListener(VerifyMountPointEvent::class, function (VerifyMountPointEvent $event): void { $event->setCreateParent(true); }); $this->targetValidator->verifyMountPoint($this->user2, $share, [], [$share]); diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php index 8d1e13556e9..d578e142386 100644 --- a/apps/files_trashbin/lib/Trashbin.php +++ b/apps/files_trashbin/lib/Trashbin.php @@ -16,6 +16,7 @@ use OC\Files\Node\NonExistingFolder; use OC\Files\View; use OC\User\NoUserException; use OC_User; +use OCA\FederatedFileSharing\FederatedShareProvider; use OCA\Files_Trashbin\Command\Expire; use OCA\Files_Trashbin\Events\BeforeNodeRestoredEvent; use OCA\Files_Trashbin\Events\NodeRestoredEvent; @@ -1194,7 +1195,7 @@ class Trashbin implements IEventListener { return $user; } - $federatedShareProvider = Server::get(\OCA\FederatedFileSharing\FederatedShareProvider::class); + $federatedShareProvider = Server::get(FederatedShareProvider::class); $share = $federatedShareProvider->getShareByToken($token); return $share->getSharedWith(); diff --git a/apps/oauth2/lib/Settings/Admin.php b/apps/oauth2/lib/Settings/Admin.php index e707a263b40..b843b31af17 100644 --- a/apps/oauth2/lib/Settings/Admin.php +++ b/apps/oauth2/lib/Settings/Admin.php @@ -13,6 +13,7 @@ use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\IURLGenerator; use OCP\Settings\ISettings; +use OCP\Util; use Psr\Log\LoggerInterface; class Admin implements ISettings { @@ -45,8 +46,8 @@ class Admin implements ISettings { $this->initialState->provideInitialState('clients', $result); $this->initialState->provideInitialState('oauth2-doc-link', $this->urlGenerator->linkToDocs('admin-oauth2')); - \OCP\Util::addStyle('oauth2', 'settings-admin'); - \OCP\Util::addScript('oauth2', 'settings-admin', 'core'); + Util::addStyle('oauth2', 'settings-admin'); + Util::addScript('oauth2', 'settings-admin', 'core'); return new TemplateResponse( 'oauth2', 'admin', diff --git a/apps/settings/tests/Controller/AdminSettingsControllerTest.php b/apps/settings/tests/Controller/AdminSettingsControllerTest.php index 7ac0b73e37a..ce4f983bbbd 100644 --- a/apps/settings/tests/Controller/AdminSettingsControllerTest.php +++ b/apps/settings/tests/Controller/AdminSettingsControllerTest.php @@ -125,7 +125,7 @@ class AdminSettingsControllerTest extends TestCase { $initialState = []; $this->initialState->expects(self::atLeastOnce()) ->method('provideInitialState') - ->willReturnCallback(function () use (&$initialState) { + ->willReturnCallback(function () use (&$initialState): void { $initialState[] = func_get_args(); }); diff --git a/apps/settings/tests/Integration/DuplicateAssignmentIntegrationTest.php b/apps/settings/tests/Integration/DuplicateAssignmentIntegrationTest.php index 281e6335ee9..43ba37c5d07 100644 --- a/apps/settings/tests/Integration/DuplicateAssignmentIntegrationTest.php +++ b/apps/settings/tests/Integration/DuplicateAssignmentIntegrationTest.php @@ -10,7 +10,9 @@ use OC\Settings\AuthorizedGroup; use OC\Settings\AuthorizedGroupMapper; use OCA\Settings\Service\AuthorizedGroupService; use OCA\Settings\Service\ConflictException; +use OCA\Settings\Service\NotFoundException; use OCP\AppFramework\Db\DoesNotExistException; +use OCP\Server; use Test\TestCase; /** @@ -27,7 +29,7 @@ class DuplicateAssignmentIntegrationTest extends TestCase { parent::setUp(); // Use real mapper for integration testing - $this->mapper = \OCP\Server::get(AuthorizedGroupMapper::class); + $this->mapper = Server::get(AuthorizedGroupMapper::class); $this->service = new AuthorizedGroupService($this->mapper); } @@ -109,10 +111,10 @@ class DuplicateAssignmentIntegrationTest extends TestCase { $this->service->delete($initialId); // Verify it's deleted by trying to find it - $this->expectException(\OCP\AppFramework\Db\DoesNotExistException::class); + $this->expectException(DoesNotExistException::class); try { $this->service->find($initialId); - } catch (\OCA\Settings\Service\NotFoundException $e) { + } catch (NotFoundException $e) { // Expected - now create the same assignment again, which should succeed $result2 = $this->service->create($groupId, $class); diff --git a/apps/settings/tests/Service/AuthorizedGroupServiceTest.php b/apps/settings/tests/Service/AuthorizedGroupServiceTest.php index f8a3c5c0e47..9d8ca16f94e 100644 --- a/apps/settings/tests/Service/AuthorizedGroupServiceTest.php +++ b/apps/settings/tests/Service/AuthorizedGroupServiceTest.php @@ -88,7 +88,7 @@ class AuthorizedGroupServiceTest extends TestCase { // Mock that no duplicate exists for group1 $this->mapper->expects($this->exactly(2)) ->method('findByGroupIdAndClass') - ->willReturnCallback(function ($groupId, $classArg) use ($groupId1, $groupId2, $class) { + ->willReturnCallback(function ($groupId, $classArg) use ($groupId1, $groupId2, $class): void { $this->assertContains($groupId, [$groupId1, $groupId2]); $this->assertEquals($class, $classArg); throw new DoesNotExistException('Not found'); @@ -126,7 +126,7 @@ class AuthorizedGroupServiceTest extends TestCase { // Mock that no duplicate exists for either class $this->mapper->expects($this->exactly(2)) ->method('findByGroupIdAndClass') - ->willReturnCallback(function ($groupIdArg, $class) use ($groupId, $class1, $class2) { + ->willReturnCallback(function ($groupIdArg, $class) use ($groupId, $class1, $class2): void { $this->assertEquals($groupId, $groupIdArg); $this->assertContains($class, [$class1, $class2]); throw new DoesNotExistException('Not found'); diff --git a/apps/user_ldap/lib/Settings/Admin.php b/apps/user_ldap/lib/Settings/Admin.php index e1410441292..aab8fcfeccf 100644 --- a/apps/user_ldap/lib/Settings/Admin.php +++ b/apps/user_ldap/lib/Settings/Admin.php @@ -15,6 +15,7 @@ use OCP\IL10N; use OCP\Server; use OCP\Settings\IDelegatedSettings; use OCP\Template\ITemplateManager; +use OCP\Util; class Admin implements IDelegatedSettings { public function __construct( @@ -60,8 +61,8 @@ class Admin implements IDelegatedSettings { $this->initialState->provideInitialState('ldapConfigs', $ldapConfigs); $this->initialState->provideInitialState('ldapModuleInstalled', function_exists('ldap_connect')); - \OCP\Util::addStyle(Application::APP_ID, 'settings-admin'); - \OCP\Util::addScript(Application::APP_ID, 'settings-admin'); + Util::addStyle(Application::APP_ID, 'settings-admin'); + Util::addScript(Application::APP_ID, 'settings-admin'); return new TemplateResponse(Application::APP_ID, 'settings', $parameters); } diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php index 061188b3648..e426f96ac4a 100644 --- a/apps/workflowengine/lib/Manager.php +++ b/apps/workflowengine/lib/Manager.php @@ -616,9 +616,8 @@ class Manager implements IManager { public function formatOperation(array $operation): array { $checkIds = json_decode($operation['checks'], true); - /** @var list $checks */ $checks = $this->getChecks($checkIds); - $operation['checks'] = $checks; + $operation['checks'] = array_values($checks); /** @var list> $events */ $events = json_decode($operation['events'], true) ?? []; diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index d2be62c1b17..cbe08c0b2b4 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -839,9 +839,6 @@ - - l10n->l('date', $startDateTime, ['width' => 'medium'])]]> - getCursor()]]> @@ -851,12 +848,6 @@ 'ORGANIZER' => ['CN'], ]]]> - - l10n->l('date', $startDateTime, ['width' => 'medium'])]]> - - - - @@ -3597,22 +3588,6 @@ fileInfo]]> - - - - mountManager->findByNumericId($numericId)]]> - mountManager->findByStorageId($storageId)]]> - mountManager->findIn($mountPoint)]]> - - - - - - - - - - diff --git a/composer.lock b/composer.lock index 2218fd6fad2..7301359b758 100644 --- a/composer.lock +++ b/composer.lock @@ -96,5 +96,5 @@ "platform-overrides": { "php": "8.2" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/config/config.sample.php b/config/config.sample.php index ee06ea72deb..bad9aa86d8b 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1758,6 +1758,16 @@ $CONFIG = [ */ 'memcache.distributed' => '\\OC\\Memcache\\Memcached', + /** + * Cache Key Prefix for Redis or Memcached + * + * * Used for avoiding collisions in the cache system + * * May be used for ACL restrictions in Redis + * + * Defaults to ``''`` (empty string) + */ + 'memcache_customprefix' => 'mycustomprefix', + /** * Connection details for Redis to use for memory caching in a single server configuration. * @@ -2473,20 +2483,53 @@ $CONFIG = [ 'filesystem_check_changes' => 0, /** - * Store part files created during upload in the same storage as the upload - * target. Setting this to false stores part files in the root of the user's - * folder, which may be necessary for external storage with limited rename - * capabilities. + * Control where temporary ".part" files are written during direct (non-chunked) + * uploads. * - * Defaults to ``true`` + * While an upload is in progress, Nextcloud writes data to a temporary ".part" + * file and renames it to the final filename when the upload completes. + * + * - true: create the temporary ".part" file in the destination storage/path. + * This typically avoids cross-storage moves and can improve reliability and + * performance on backends where rename within the same storage is cheap/atomic. + * - false: create the temporary ".part" file in the user's root folder first. + * This may help with some external storages that have limited rename/move + * behavior, but can add extra copy/move overhead. + * + * Note: This setting applies to direct (non-chunked) uploads only. Chunked/ + * resumable uploads use a separate uploads staging mechanism and are not + * controlled by this option. + * + * Defaults to ``true``. */ 'part_file_in_storage' => true, /** - * Prevent Nextcloud from updating the cache due to filesystem changes for all - * storage. + * Read-only mode for scan/detection reconciliation writes to filecache. * - * Defaults to ``false`` + * When true, Nextcloud does not store filecache metadata changes that are + * identified through scanner/change-detection reconciliation paths (global: + * all storages). + * + * Scope note: + * + * - Nextcloud-originated operations (UI/WebDAV/clients) are generally + * handled through normal application write paths and thus will still + * update filecache even when this is set to true. + * - Reconciliation/refresh paths are prevented from writing back discovered + * metadata deltas while this is enabled. + * + * Practical effect: + * + * - Changes made directly on storage outside Nextcloud are generally not + * reflected while enabled. + * - Some metadata-dependent behavior can appear stale until this parameter + * is disabled (permitting reconciliation writes again). + * + * Warning: This is an expert/global setting for specialized environments and + * is intentionally not default-safe for general deployments. + * + * Defaults to ``false``. */ 'filesystem_cache_readonly' => false, diff --git a/core/Controller/ContactsMenuController.php b/core/Controller/ContactsMenuController.php index b3cb7de7881..7224b124122 100644 --- a/core/Controller/ContactsMenuController.php +++ b/core/Controller/ContactsMenuController.php @@ -8,6 +8,7 @@ namespace OC\Core\Controller; use Exception; use OC\Contacts\ContactsMenu\Manager; +use OC\Teams\TeamManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\FrontpageRoute; @@ -37,7 +38,7 @@ class ContactsMenuController extends Controller { public function index(?string $filter = null, ?string $teamId = null): array { $entries = $this->manager->getEntries($this->userSession->getUser(), $filter); if ($teamId !== null) { - /** @var \OC\Teams\TeamManager */ + /** @var TeamManager */ $teamManager = $this->teamManager; $memberIds = $teamManager->getMembersOfTeam($teamId, $this->userSession->getUser()->getUID()); $entries['contacts'] = array_filter( diff --git a/core/Controller/OpenMetricsController.php b/core/Controller/OpenMetricsController.php index 8c57eb1a663..c6e6c1673aa 100644 --- a/core/Controller/OpenMetricsController.php +++ b/core/Controller/OpenMetricsController.php @@ -15,6 +15,8 @@ use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\FrontpageRoute; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\Attribute\PublicPage; +use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Http\StreamTraversableResponse; use OCP\IConfig; use OCP\IRequest; use OCP\OpenMetrics\IMetricFamily; @@ -44,12 +46,12 @@ class OpenMetricsController extends Controller { #[NoCSRFRequired] #[PublicPage] #[FrontpageRoute(verb: 'GET', url: '/metrics')] - public function export(): Http\Response { + public function export(): Response { if (!$this->isRemoteAddressAllowed()) { - return new Http\Response(Http::STATUS_FORBIDDEN); + return new Response(Http::STATUS_FORBIDDEN); } - return new Http\StreamTraversableResponse( + return new StreamTraversableResponse( $this->generate(), Http::STATUS_OK, [ diff --git a/lib/composer/composer/installed.php b/lib/composer/composer/installed.php index ab3dd57b356..87357f5e32f 100644 --- a/lib/composer/composer/installed.php +++ b/lib/composer/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '8c12590cf6f93ce7aa41f17817b3791e524da39e', + 'reference' => '671cec33f134e670bb21c5e3c49c685bd78fc339', 'type' => 'library', 'install_path' => __DIR__ . '/../../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '8c12590cf6f93ce7aa41f17817b3791e524da39e', + 'reference' => '671cec33f134e670bb21c5e3c49c685bd78fc339', 'type' => 'library', 'install_path' => __DIR__ . '/../../../', 'aliases' => array(), diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index c316bdab6ac..7527d249586 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -38,6 +38,7 @@ use OC\AppFramework\Services\AppConfig; use OC\AppFramework\Services\InitialState; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\AppFramework\Utility\SimpleContainer; +use OC\CapabilitiesManager; use OC\Core\Middleware\TwoFactorMiddleware; use OC\Diagnostics\EventLogger; use OC\Log\PsrLoggerAdapter; @@ -305,7 +306,7 @@ class DIContainer extends SimpleContainer implements IAppContainer { * @param string $serviceName e.g. 'OCA\Files\Capabilities' */ public function registerCapability($serviceName) { - $this->query(\OC\CapabilitiesManager::class)->registerCapability(function () use ($serviceName) { + $this->query(CapabilitiesManager::class)->registerCapability(function () use ($serviceName) { return $this->query($serviceName); }); } diff --git a/lib/private/Cache/File.php b/lib/private/Cache/File.php index 82afdd4ce3e..d9a3e5e8b63 100644 --- a/lib/private/Cache/File.php +++ b/lib/private/Cache/File.php @@ -13,6 +13,7 @@ use OC\ForbiddenException; use OC\User\NoUserException; use OCP\Files\LockNotAcquiredException; use OCP\ICache; +use OCP\IConfig; use OCP\IUserSession; use OCP\Lock\LockedException; use OCP\Security\ISecureRandom; @@ -161,7 +162,7 @@ class File implements ICache { public function gc() { $storage = $this->getStorage(); if ($storage) { - $ttl = \OC::$server->getConfig()->getSystemValueInt('cache_chunk_gc_ttl', 60 * 60 * 24); + $ttl = Server::get(IConfig::class)->getSystemValueInt('cache_chunk_gc_ttl', 60 * 60 * 24); $now = time() - $ttl; $dh = $storage->opendir('/'); diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index b9de944b834..6a546f78711 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -27,6 +27,7 @@ use OCP\Files\Cache\CacheInsertEvent; use OCP\Files\Cache\CacheUpdateEvent; use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICacheEntry; +use OCP\Files\Config\IUserMountCache; use OCP\Files\FileInfo; use OCP\Files\IMimeTypeLoader; use OCP\Files\Search\ISearchComparison; @@ -831,7 +832,7 @@ class Cache implements ICache { $this->connection->commit(); if ($sourceCache->getNumericStorageId() !== $this->getNumericStorageId()) { - \OCP\Server::get(\OCP\Files\Config\IUserMountCache::class)->clear(); + Server::get(IUserMountCache::class)->clear(); $event = new CacheEntryRemovedEvent($this->storage, $sourcePath, $sourceId, $sourceCache->getNumericStorageId()); $this->eventDispatcher->dispatchTyped($event); diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php index ebdfc64d83e..281ab429904 100644 --- a/lib/private/Files/Config/UserMountCache.php +++ b/lib/private/Files/Config/UserMountCache.php @@ -194,15 +194,15 @@ class UserMountCache implements IUserMountCache { private function updateCachedMount(ICachedMountInfo $mount) { $builder = $this->connection->getQueryBuilder(); + $hash = hash('xxh128', $mount->getMountPoint()); $query = $builder->update('mounts') ->set('storage_id', $builder->createNamedParameter($mount->getStorageId())) - ->set('mount_point', $builder->createNamedParameter($mount->getMountPoint())) - ->set('mount_point_hash', $builder->createNamedParameter(hash('xxh128', $mount->getMountPoint()))) ->set('mount_id', $builder->createNamedParameter($mount->getMountId(), IQueryBuilder::PARAM_INT)) ->set('mount_provider_class', $builder->createNamedParameter($mount->getMountProvider())) ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID()))) - ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT))); + ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT))) + ->andWhere($builder->expr()->eq('mount_point_hash', $builder->createNamedParameter($hash))); $query->executeStatement(); } diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php index 967d404b8a4..d864ebe2a09 100644 --- a/lib/private/Files/FileInfo.php +++ b/lib/private/Files/FileInfo.php @@ -10,6 +10,7 @@ namespace OC\Files; use OC\Files\Mount\HomeMountPoint; use OCA\Files_Sharing\External\Mount; use OCA\Files_Sharing\ISharedMountPoint; +use OCP\Constants; use OCP\Files\Cache\ICacheEntry; use OCP\Files\Mount\IMountPoint; use OCP\IUser; @@ -18,29 +19,11 @@ use OCP\IUser; * @template-implements \ArrayAccess */ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { - private array|ICacheEntry $data; - /** - * @var string - */ - private $path; - - /** - * @var \OC\Files\Storage\Storage $storage - */ - private $storage; - - /** - * @var string - */ - private $internalPath; - /** * @var \OCP\Files\Mount\IMountPoint */ private $mount; - private ?IUser $owner; - /** * @var string[] */ @@ -59,20 +42,22 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { private int|float $rawSize = 0; /** - * @param string|boolean $path + * @param string $path * @param Storage\Storage $storage * @param string $internalPath * @param array|ICacheEntry $data * @param IMountPoint $mount * @param ?IUser $owner */ - public function __construct($path, $storage, $internalPath, $data, $mount, $owner = null) { - $this->path = $path; - $this->storage = $storage; - $this->internalPath = $internalPath; - $this->data = $data; + public function __construct( + private $path, + private $storage, + private $internalPath, + private array|ICacheEntry $data, + $mount, + private ?IUser $owner = null, + ) { $this->mount = $mount; - $this->owner = $owner; if (isset($this->data['unencrypted_size']) && $this->data['unencrypted_size'] !== 0) { $this->rawSize = $this->data['unencrypted_size']; } else { @@ -239,14 +224,14 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return bool */ public function isReadable() { - return $this->checkPermissions(\OCP\Constants::PERMISSION_READ); + return $this->checkPermissions(Constants::PERMISSION_READ); } /** * @return bool */ public function isUpdateable() { - return $this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE); + return $this->checkPermissions(Constants::PERMISSION_UPDATE); } /** @@ -255,21 +240,21 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return bool */ public function isCreatable() { - return $this->checkPermissions(\OCP\Constants::PERMISSION_CREATE); + return $this->checkPermissions(Constants::PERMISSION_CREATE); } /** * @return bool */ public function isDeletable() { - return $this->checkPermissions(\OCP\Constants::PERMISSION_DELETE); + return $this->checkPermissions(Constants::PERMISSION_DELETE); } /** * @return bool */ public function isShareable() { - return $this->checkPermissions(\OCP\Constants::PERMISSION_SHARE); + return $this->checkPermissions(Constants::PERMISSION_SHARE); } /** diff --git a/lib/private/Files/Node/File.php b/lib/private/Files/Node/File.php index eb6411d7d13..4e8aad1cfb1 100644 --- a/lib/private/Files/Node/File.php +++ b/lib/private/Files/Node/File.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Node; +use OCP\Constants; use OCP\Files\GenericFileException; use OCP\Files\NotPermittedException; use OCP\Lock\LockedException; @@ -29,7 +30,7 @@ class File extends Node implements \OCP\Files\File { * @throws LockedException */ public function getContent() { - if ($this->checkPermissions(\OCP\Constants::PERMISSION_READ)) { + if ($this->checkPermissions(Constants::PERMISSION_READ)) { $content = $this->view->file_get_contents($this->path); if ($content === false) { throw new GenericFileException(); @@ -47,7 +48,7 @@ class File extends Node implements \OCP\Files\File { * @throws LockedException */ public function putContent($data) { - if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) { + if ($this->checkPermissions(Constants::PERMISSION_UPDATE)) { $this->sendHooks(['preWrite']); if ($this->view->file_put_contents($this->path, $data) === false) { throw new GenericFileException('file_put_contents failed'); @@ -68,7 +69,7 @@ class File extends Node implements \OCP\Files\File { public function fopen($mode) { $preHooks = []; $postHooks = []; - $requiredPermissions = \OCP\Constants::PERMISSION_READ; + $requiredPermissions = Constants::PERMISSION_READ; switch ($mode) { case 'r+': case 'rb+': @@ -86,7 +87,7 @@ class File extends Node implements \OCP\Files\File { case 'ab': $preHooks[] = 'preWrite'; $postHooks[] = 'postWrite'; - $requiredPermissions |= \OCP\Constants::PERMISSION_UPDATE; + $requiredPermissions |= Constants::PERMISSION_UPDATE; break; } @@ -106,7 +107,7 @@ class File extends Node implements \OCP\Files\File { * @throws \OCP\Files\NotFoundException */ public function delete() { - if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) { + if ($this->checkPermissions(Constants::PERMISSION_DELETE)) { $this->sendHooks(['preDelete']); $fileInfo = $this->getFileInfo(); $this->view->unlink($this->path); diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php index 14350fc435e..f103a34c9e9 100644 --- a/lib/private/Files/Node/Folder.php +++ b/lib/private/Files/Node/Folder.php @@ -14,6 +14,7 @@ use OC\Files\Search\SearchOrder; use OC\Files\Search\SearchQuery; use OC\Files\Utils\PathHelper; use OC\User\LazyUser; +use OCP\Constants; use OCP\Files\Cache\ICacheEntry; use OCP\Files\FileInfo; use OCP\Files\Folder as IFolder; @@ -26,7 +27,9 @@ use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchOperator; use OCP\Files\Search\ISearchOrder; use OCP\Files\Search\ISearchQuery; +use OCP\IConfig; use OCP\IUserManager; +use OCP\Server; use Override; class Folder extends Node implements IFolder { @@ -122,7 +125,7 @@ class Folder extends Node implements IFolder { * @throws \OCP\Files\NotPermittedException */ public function newFolder($path) { - if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) { + if ($this->checkPermissions(Constants::PERMISSION_CREATE)) { $fullPath = $this->getFullPath($path); $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath); $this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]); @@ -154,7 +157,7 @@ class Folder extends Node implements IFolder { /** * @param string $path * @param string | resource | null $content - * @return \OC\Files\Node\File + * @return File * @throws \OCP\Files\NotPermittedException */ public function newFile($path, $content = null) { @@ -162,7 +165,7 @@ class Folder extends Node implements IFolder { throw new NotPermittedException('Could not create as provided path is empty'); } $this->recreateIfNeeded(); - if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) { + if ($this->checkPermissions(Constants::PERMISSION_CREATE)) { $fullPath = $this->getFullPath($path); $nonExisting = new NonExistingFile($this->root, $this->view, $fullPath); $this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]); @@ -187,7 +190,7 @@ class Folder extends Node implements IFolder { $user = null; } else { /** @var IUserManager $userManager */ - $userManager = \OCP\Server::get(IUserManager::class); + $userManager = Server::get(IUserManager::class); $user = $userManager->get($uid); } return new SearchQuery($operator, $limit, $offset, [], $user); @@ -213,7 +216,7 @@ class Folder extends Node implements IFolder { } /** @var QuerySearchHelper $searchHelper */ - $searchHelper = \OC::$server->get(QuerySearchHelper::class); + $searchHelper = Server::get(QuerySearchHelper::class); [$caches, $mountByMountPoint] = $searchHelper->getCachesAndMountPointsForSearch($this->root, $this->path, $limitToHome); $resultsPerCache = $searchHelper->searchInCaches($query, $caches); @@ -260,7 +263,7 @@ class Folder extends Node implements IFolder { if ($ownerId !== false) { // Cache the user manager (for performance) if ($this->userManager === null) { - $this->userManager = \OCP\Server::get(IUserManager::class); + $this->userManager = Server::get(IUserManager::class); } $owner = new LazyUser($ownerId, $this->userManager); } @@ -315,12 +318,12 @@ class Folder extends Node implements IFolder { return $this->root->getByIdInPath((int)$id, $this->getPath()); } - public function getFirstNodeById(int $id): ?\OCP\Files\Node { + public function getFirstNodeById(int $id): ?INode { return $this->root->getFirstNodeByIdInPath($id, $this->getPath()); } public function getAppDataDirectoryName(): string { - $instanceId = \OC::$server->getConfig()->getSystemValueString('instanceid'); + $instanceId = Server::get(IConfig::class)->getSystemValueString('instanceid'); return 'appdata_' . $instanceId; } @@ -372,7 +375,7 @@ class Folder extends Node implements IFolder { } public function delete() { - if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) { + if ($this->checkPermissions(Constants::PERMISSION_DELETE)) { $this->sendHooks(['preDelete']); $fileInfo = $this->getFileInfo(); $this->view->rmdir($this->path); diff --git a/lib/private/Files/Node/LazyFolder.php b/lib/private/Files/Node/LazyFolder.php index d04c8aefb7e..23858bb0679 100644 --- a/lib/private/Files/Node/LazyFolder.php +++ b/lib/private/Files/Node/LazyFolder.php @@ -13,6 +13,7 @@ use OCP\Constants; use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountPoint; +use OCP\Files\Node; use OCP\Files\NotPermittedException; use Override; @@ -25,21 +26,20 @@ use Override; * @package OC\Files\Node */ class LazyFolder implements Folder { - /** @var \Closure(): Folder */ - private \Closure $folderClosure; protected ?Folder $folder = null; protected IRootFolder $rootFolder; - protected array $data; /** * @param IRootFolder $rootFolder * @param \Closure(): Folder $folderClosure * @param array $data */ - public function __construct(IRootFolder $rootFolder, \Closure $folderClosure, array $data = []) { + public function __construct( + IRootFolder $rootFolder, + private \Closure $folderClosure, + protected array $data = [], + ) { $this->rootFolder = $rootFolder; - $this->folderClosure = $folderClosure; - $this->data = $data; } protected function getRootFolder(): IRootFolder { @@ -470,7 +470,7 @@ class LazyFolder implements Folder { return $this->getRootFolder()->getByIdInPath((int)$id, $this->getPath()); } - public function getFirstNodeById(int $id): ?\OCP\Files\Node { + public function getFirstNodeById(int $id): ?Node { return $this->getRootFolder()->getFirstNodeByIdInPath($id, $this->getPath()); } diff --git a/lib/private/Files/Node/LazyRoot.php b/lib/private/Files/Node/LazyRoot.php index bc3f3a2e80f..8920a2f68f6 100644 --- a/lib/private/Files/Node/LazyRoot.php +++ b/lib/private/Files/Node/LazyRoot.php @@ -10,7 +10,6 @@ namespace OC\Files\Node; use OCP\Files\Cache\ICacheEntry; use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountPoint; -use OCP\Files\Node; use OCP\Files\Node as INode; /** @@ -42,7 +41,7 @@ class LazyRoot extends LazyFolder implements IRootFolder { return $this->__call(__FUNCTION__, func_get_args()); } - public function getFirstNodeByIdInPath(int $id, string $path): ?Node { + public function getFirstNodeByIdInPath(int $id, string $path): ?INode { return $this->__call(__FUNCTION__, func_get_args()); } diff --git a/lib/private/Files/Node/LazyUserFolder.php b/lib/private/Files/Node/LazyUserFolder.php index d7afb199b91..5ac74e2705e 100644 --- a/lib/private/Files/Node/LazyUserFolder.php +++ b/lib/private/Files/Node/LazyUserFolder.php @@ -16,6 +16,7 @@ use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountManager; use OCP\Files\NotFoundException; use OCP\IUser; +use OCP\Server; use Psr\Log\LoggerInterface; class LazyUserFolder extends LazyFolder { @@ -48,7 +49,7 @@ class LazyUserFolder extends LazyFolder { $node = $this->getRootFolder()->get($this->path); if ($node instanceof File) { $e = new \RuntimeException(); - \OCP\Server::get(LoggerInterface::class)->error('User root storage is not a folder: ' . $this->path, [ + Server::get(LoggerInterface::class)->error('User root storage is not a folder: ' . $this->path, [ 'exception' => $e, ]); throw $e; diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php index fd8d84883d9..38e83984390 100644 --- a/lib/private/Files/Node/Node.php +++ b/lib/private/Files/Node/Node.php @@ -10,6 +10,8 @@ namespace OC\Files\Node; use OC\Files\Filesystem; use OC\Files\Mount\MoveableMount; use OC\Files\Utils\PathHelper; +use OC\Files\View; +use OCP\Constants; use OCP\EventDispatcher\GenericEvent; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\FileInfo; @@ -20,43 +22,36 @@ use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Lock\LockedException; use OCP\PreConditionNotMetException; +use OCP\Server; // FIXME: this class really should be abstract (+1) class Node implements INode { /** - * @var \OC\Files\View $view + * @var View $view */ protected $view; protected IRootFolder $root; /** - * @var string $path Absolute path to the node (e.g. /admin/files/folder/file) - */ - protected $path; - - protected ?FileInfo $fileInfo; - - protected ?INode $parent; - - private bool $infoHasSubMountsIncluded; - - /** - * @param \OC\Files\View $view + * @param View $view * @param \OCP\Files\IRootFolder $root * @param string $path * @param FileInfo $fileInfo */ - public function __construct(IRootFolder $root, $view, $path, $fileInfo = null, ?INode $parent = null, bool $infoHasSubMountsIncluded = true) { + public function __construct( + IRootFolder $root, + $view, + protected $path, + protected ?FileInfo $fileInfo = null, + protected ?INode $parent = null, + private bool $infoHasSubMountsIncluded = true, + ) { if (Filesystem::normalizePath($view->getRoot()) !== '/') { throw new PreConditionNotMetException('The view passed to the node should not have any fake root set'); } $this->view = $view; $this->root = $root; - $this->path = $path; - $this->fileInfo = $fileInfo; - $this->parent = $parent; - $this->infoHasSubMountsIncluded = $infoHasSubMountsIncluded; } /** @@ -104,7 +99,7 @@ class Node implements INode { protected function sendHooks($hooks, ?array $args = null) { $args = !empty($args) ? $args : [$this]; /** @var IEventDispatcher $dispatcher */ - $dispatcher = \OC::$server->get(IEventDispatcher::class); + $dispatcher = Server::get(IEventDispatcher::class); foreach ($hooks as $hook) { if (method_exists($this->root, 'emit')) { $this->root->emit('\OC\Files', $hook, $args); @@ -140,7 +135,7 @@ class Node implements INode { * @throws NotPermittedException */ public function touch($mtime = null) { - if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) { + if ($this->checkPermissions(Constants::PERMISSION_UPDATE)) { $this->sendHooks(['preTouch']); $this->view->touch($this->path, $mtime); $this->sendHooks(['postTouch']); diff --git a/lib/private/Files/Node/NonExistingFolder.php b/lib/private/Files/Node/NonExistingFolder.php index ee07e53bedd..9e6638376cd 100644 --- a/lib/private/Files/Node/NonExistingFolder.php +++ b/lib/private/Files/Node/NonExistingFolder.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Node; +use OCP\Files\Node; use OCP\Files\NotFoundException; use Override; @@ -156,7 +157,7 @@ class NonExistingFolder extends Folder { throw new NotFoundException(); } - public function getFirstNodeById(int $id): ?\OCP\Files\Node { + public function getFirstNodeById(int $id): ?Node { throw new NotFoundException(); } diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php index 8354f382aa3..0c121dc8b05 100644 --- a/lib/private/Files/Node/Root.php +++ b/lib/private/Files/Node/Root.php @@ -11,6 +11,7 @@ namespace OC\Files\Node; use OC\Files\FileInfo; use OC\Files\Mount\Manager; use OC\Files\Mount\MountPoint; +use OC\Files\Storage\Storage; use OC\Files\Utils\PathHelper; use OC\Files\View; use OC\Hooks\PublicEmitter; @@ -18,6 +19,7 @@ use OC\User\NoUserException; use OCA\Files\AppInfo\Application; use OCA\Files\ConfigLexicon; use OCP\Cache\CappedMemoryCache; +use OCP\Constants; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Cache\ICacheEntry; use OCP\Files\Config\ICachedMountFileInfo; @@ -76,7 +78,7 @@ class Root extends Folder implements IRootFolder { parent::__construct($this, $view, ''); $this->emitter = new PublicEmitter(); $this->userFolderCache = new CappedMemoryCache(); - $eventDispatcher->addListener(FilesystemTornDownEvent::class, function () { + $eventDispatcher->addListener(FilesystemTornDownEvent::class, function (): void { $this->userFolderCache = new CappedMemoryCache(); }); $this->pathByIdCache = $cacheFactory->createLocal('path-by-id'); @@ -118,7 +120,7 @@ class Root extends Folder implements IRootFolder { } /** - * @param \OC\Files\Storage\Storage $storage + * @param Storage $storage * @param string $mountPoint * @param array $arguments */ @@ -133,35 +135,12 @@ class Root extends Folder implements IRootFolder { /** * @param string $mountPoint - * @return \OC\Files\Mount\MountPoint[] + * @return IMountPoint[] */ public function getMountsIn(string $mountPoint): array { return $this->mountManager->findIn($mountPoint); } - /** - * @param string $storageId - * @return \OC\Files\Mount\MountPoint[] - */ - public function getMountByStorageId($storageId) { - return $this->mountManager->findByStorageId($storageId); - } - - /** - * @param int $numericId - * @return MountPoint[] - */ - public function getMountByNumericStorageId($numericId) { - return $this->mountManager->findByNumericId($numericId); - } - - /** - * @param \OC\Files\Mount\MountPoint $mount - */ - public function unMount($mount) { - $this->mountManager->remove($mount); - } - public function get($path) { $path = $this->normalizePath($path); if ($this->isValidPath($path)) { @@ -210,7 +189,7 @@ class Root extends Folder implements IRootFolder { } /** - * @return \OC\Files\Storage\Storage + * @return Storage * @throws \OCP\Files\NotFoundException */ public function getStorage() { @@ -271,7 +250,7 @@ class Root extends Folder implements IRootFolder { * @return int */ public function getPermissions() { - return \OCP\Constants::PERMISSION_CREATE; + return Constants::PERMISSION_CREATE; } /** @@ -401,8 +380,7 @@ class Root extends Folder implements IRootFolder { } /** - * @param int $id - * @return Node[] + * @return INode[] */ public function getByIdInPath(int $id, string $path): array { $mountCache = $this->getUserMountCache(); @@ -510,9 +488,7 @@ class Root extends Folder implements IRootFolder { $folders = array_filter($nodes, function (Node $node) use ($path) { return PathHelper::getRelativePath($path, $node->getPath()) !== null; }); - usort($folders, function ($a, $b) { - return $b->getPath() <=> $a->getPath(); - }); + usort($folders, static fn (Node $a, Node $b): int => $b->getPath() <=> $a->getPath()); return $folders; } diff --git a/lib/private/Files/Notify/RenameChange.php b/lib/private/Files/Notify/RenameChange.php index 47e89fe9e16..bb5c17d7cbc 100644 --- a/lib/private/Files/Notify/RenameChange.php +++ b/lib/private/Files/Notify/RenameChange.php @@ -1,5 +1,7 @@ registerMounts($user, $fullProviderMounts, $currentProviders); } - $this->setupForUserWith($user, function () use ($fullProviderMounts, $authoritativeMounts) { + $this->setupForUserWith($user, function () use ($fullProviderMounts, $authoritativeMounts): void { $allMounts = [...$fullProviderMounts, ...$authoritativeMounts]; array_walk($allMounts, $this->mountManager->addMount(...)); }); @@ -778,7 +778,7 @@ class SetupManager implements ISetupManager { $this->eventDispatcher->addListener(ShareCreatedEvent::class, function (ShareCreatedEvent $event): void { $this->cache->remove($event->getShare()->getSharedWith()); }); - $this->eventDispatcher->addListener(BeforeNodeRenamedEvent::class, function (BeforeNodeRenamedEvent $event) { + $this->eventDispatcher->addListener(BeforeNodeRenamedEvent::class, function (BeforeNodeRenamedEvent $event): void { // update cache information that is cached by mount point $from = rtrim($event->getSource()->getPath(), '/') . '/'; $to = rtrim($event->getTarget()->getPath(), '/') . '/'; diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 8e35f1b3072..5e728d0a8d0 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -1526,8 +1526,8 @@ class View { $folderId = $data->getId(); $contents = $cache->getFolderContentsById($folderId, $mimeTypeFilter); - $sharingDisabled = \OCP\Util::isSharingDisabledForUser(); - $permissionsMask = ~\OCP\Constants::PERMISSION_SHARE; + $sharingDisabled = Util::isSharingDisabledForUser(); + $permissionsMask = ~Constants::PERMISSION_SHARE; $files = []; foreach ($contents as $content) { diff --git a/lib/private/FilesMetadata/FilesMetadataManager.php b/lib/private/FilesMetadata/FilesMetadataManager.php index 188cb09e53a..9282513109b 100644 --- a/lib/private/FilesMetadata/FilesMetadataManager.php +++ b/lib/private/FilesMetadata/FilesMetadataManager.php @@ -203,13 +203,13 @@ class FilesMetadataManager implements IFilesMetadataManager { public function deleteMetadata(int $fileId): void { try { $this->metadataRequestService->dropMetadata($fileId); - } catch (Exception $e) { + } catch (DBException $e) { $this->logger->warning('issue while deleteMetadata', ['exception' => $e, 'fileId' => $fileId]); } try { $this->indexRequestService->dropIndex($fileId); - } catch (Exception $e) { + } catch (DBException $e) { $this->logger->warning('issue while deleteMetadata', ['exception' => $e, 'fileId' => $fileId]); } } @@ -217,13 +217,13 @@ class FilesMetadataManager implements IFilesMetadataManager { public function deleteMetadataForFiles(int $storage, array $fileIds): void { try { $this->metadataRequestService->dropMetadataForFiles($storage, $fileIds); - } catch (Exception $e) { + } catch (DBException $e) { $this->logger->warning('issue while deleteMetadata', ['exception' => $e, 'fileIds' => $fileIds]); } try { $this->indexRequestService->dropIndexForFiles($fileIds); - } catch (Exception $e) { + } catch (DBException $e) { $this->logger->warning('issue while deleteMetadata', ['exception' => $e, 'fileIds' => $fileIds]); } } diff --git a/lib/private/FilesMetadata/MetadataQuery.php b/lib/private/FilesMetadata/MetadataQuery.php index deae433e2fc..19495c38e5e 100644 --- a/lib/private/FilesMetadata/MetadataQuery.php +++ b/lib/private/FilesMetadata/MetadataQuery.php @@ -18,6 +18,7 @@ use OCP\FilesMetadata\IFilesMetadataManager; use OCP\FilesMetadata\IMetadataQuery; use OCP\FilesMetadata\Model\IFilesMetadata; use OCP\FilesMetadata\Model\IMetadataValueWrapper; +use OCP\Server; use Psr\Log\LoggerInterface; /** @@ -42,7 +43,7 @@ class MetadataQuery implements IMetadataQuery { * * FIXME: remove support for IFilesMetadata */ - $logger = \OCP\Server::get(LoggerInterface::class); + $logger = Server::get(LoggerInterface::class); $logger->debug('It is deprecated to use IFilesMetadata as second parameter when calling MetadataQuery::__construct()'); } } diff --git a/lib/private/FilesMetadata/Model/MetadataValueWrapper.php b/lib/private/FilesMetadata/Model/MetadataValueWrapper.php index 710a8129340..606f3b5acec 100644 --- a/lib/private/FilesMetadata/Model/MetadataValueWrapper.php +++ b/lib/private/FilesMetadata/Model/MetadataValueWrapper.php @@ -18,7 +18,6 @@ use OCP\FilesMetadata\Model\IMetadataValueWrapper; * @since 28.0.0 */ class MetadataValueWrapper implements IMetadataValueWrapper { - private string $type; /** @var string|int|float|bool|array|string[]|int[] */ private mixed $value = null; private string $etag = ''; @@ -38,8 +37,9 @@ class MetadataValueWrapper implements IMetadataValueWrapper { * @see self::TYPE_STRING * @since 28.0.0 */ - public function __construct(string $type = '') { - $this->type = $type; + public function __construct( + private string $type = '', + ) { } /** diff --git a/lib/private/Memcache/Factory.php b/lib/private/Memcache/Factory.php index e083a357cba..940813536c5 100644 --- a/lib/private/Memcache/Factory.php +++ b/lib/private/Memcache/Factory.php @@ -115,6 +115,7 @@ class Factory implements ICacheFactory { protected function getGlobalPrefix(): string { if ($this->globalPrefix === null) { $config = Server::get(SystemConfig::class); + $customprefix = $config->getValue('memcache_customprefix', ''); $maintenanceMode = $config->getValue('maintenance', false); $versions = []; if ($config->getValue('installed', false) && !$maintenanceMode) { @@ -131,7 +132,7 @@ class Factory implements ICacheFactory { // Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool) $instanceid = $config->getValue('instanceid'); $installedApps = implode(',', array_keys($versions)) . implode(',', array_values($versions)); - $this->globalPrefix = hash('xxh128', $instanceid . $installedApps); + $this->globalPrefix = $customprefix . hash('xxh128', $instanceid . $installedApps); } return $this->globalPrefix; } @@ -145,9 +146,11 @@ class Factory implements ICacheFactory { public function withServerVersionPrefix(\Closure $closure): void { $backupPrefix = $this->globalPrefix; + $config = Server::get(SystemConfig::class); + $customprefix = $config->getValue('memcache_customprefix', ''); // Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool) - $instanceid = Server::get(SystemConfig::class)->getValue('instanceid'); - $this->globalPrefix = hash('xxh128', $instanceid . implode('.', $this->serverVersion->getVersion())); + $instanceid = $config->getValue('instanceid'); + $this->globalPrefix = $customprefix . hash('xxh128', $instanceid . implode('.', $this->serverVersion->getVersion())); $closure($this); $this->globalPrefix = $backupPrefix; } diff --git a/lib/private/OpenMetrics/ExporterManager.php b/lib/private/OpenMetrics/ExporterManager.php index 5bf8e59786a..0b984fb382e 100644 --- a/lib/private/OpenMetrics/ExporterManager.php +++ b/lib/private/OpenMetrics/ExporterManager.php @@ -10,6 +10,16 @@ declare(strict_types=1); namespace OC\OpenMetrics; use Generator; +use OC\OpenMetrics\Exporters\ActiveSessions; +use OC\OpenMetrics\Exporters\ActiveUsers; +use OC\OpenMetrics\Exporters\AppsCount; +use OC\OpenMetrics\Exporters\AppsInfo; +use OC\OpenMetrics\Exporters\FilesByType; +use OC\OpenMetrics\Exporters\InstanceInfo; +use OC\OpenMetrics\Exporters\LogLevel; +use OC\OpenMetrics\Exporters\Maintenance; +use OC\OpenMetrics\Exporters\RunningJobs; +use OC\OpenMetrics\Exporters\UsersByBackend; use OCP\App\IAppManager; use OCP\IConfig; use OCP\OpenMetrics\IMetricFamily; @@ -33,22 +43,22 @@ class ExporterManager { // Core exporters $exporters = [ // Basic exporters - Exporters\InstanceInfo::class, - Exporters\AppsInfo::class, - Exporters\AppsCount::class, - Exporters\Maintenance::class, - Exporters\LogLevel::class, + InstanceInfo::class, + AppsInfo::class, + AppsCount::class, + Maintenance::class, + LogLevel::class, // File exporters - Exporters\FilesByType::class, + FilesByType::class, // Users exporters - Exporters\ActiveUsers::class, - Exporters\ActiveSessions::class, - Exporters\UsersByBackend::class, + ActiveUsers::class, + ActiveSessions::class, + UsersByBackend::class, // Jobs - Exporters\RunningJobs::class, + RunningJobs::class, ]; $exporters = array_filter($exporters, fn ($classname) => !isset($this->skippedClasses[$classname])); foreach ($exporters as $classname) { diff --git a/lib/private/Profiler/FileProfilerStorage.php b/lib/private/Profiler/FileProfilerStorage.php index 1636b9d6065..14aaf1b9069 100644 --- a/lib/private/Profiler/FileProfilerStorage.php +++ b/lib/private/Profiler/FileProfilerStorage.php @@ -8,6 +8,12 @@ declare(strict_types = 1); namespace OC\Profiler; +use OC\DB\DbDataCollector; +use OC\Memcache\ProfilerWrapperCache; +use OCA\Profiler\DataCollector\EventLoggerDataProvider; +use OCA\Profiler\DataCollector\HttpDataCollector; +use OCA\Profiler\DataCollector\MemoryDataCollector; +use OCA\User_LDAP\DataCollector\LdapDataCollector; use OCP\Profiler\IProfile; /** @@ -16,13 +22,13 @@ use OCP\Profiler\IProfile; class FileProfilerStorage { /** @psalm-suppress UndefinedClass */ public const allowedClasses = [ - \OCA\Profiler\DataCollector\EventLoggerDataProvider::class, - \OCA\Profiler\DataCollector\HttpDataCollector::class, - \OCA\Profiler\DataCollector\MemoryDataCollector::class, - \OCA\User_LDAP\DataCollector\LdapDataCollector::class, - \OC\Memcache\ProfilerWrapperCache::class, - \OC\Profiler\RoutingDataCollector::class, - \OC\DB\DbDataCollector::class, + EventLoggerDataProvider::class, + HttpDataCollector::class, + MemoryDataCollector::class, + LdapDataCollector::class, + ProfilerWrapperCache::class, + RoutingDataCollector::class, + DbDataCollector::class, ]; /** diff --git a/lib/private/Server.php b/lib/private/Server.php index f608d3ee26d..532ac3887c4 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -9,6 +9,7 @@ namespace OC; use bantu\IniGetWrapper\IniGetWrapper; use OC\Accounts\AccountManager; +use OC\Activity\EventMerger; use OC\App\AppManager; use OC\App\AppStore\Bundles\BundleFetcher; use OC\AppFramework\Bootstrap\Coordinator; @@ -30,6 +31,8 @@ use OC\Collaboration\Collaborators\GroupPlugin; use OC\Collaboration\Collaborators\MailByMailPlugin; use OC\Collaboration\Collaborators\RemoteGroupPlugin; use OC\Collaboration\Collaborators\RemotePlugin; +use OC\Collaboration\Collaborators\Search; +use OC\Collaboration\Collaborators\SearchResult; use OC\Collaboration\Collaborators\UserByMailPlugin; use OC\Collaboration\Collaborators\UserPlugin; use OC\Collaboration\Reference\ReferenceManager; @@ -39,6 +42,7 @@ use OC\Comments\ManagerFactory as CommentsManagerFactory; use OC\Config\UserConfig; use OC\Contacts\ContactsMenu\ActionFactory; use OC\Contacts\ContactsMenu\ContactsStore; +use OC\ContextChat\ContentManager; use OC\DB\Connection; use OC\DB\ConnectionAdapter; use OC\DB\ConnectionFactory; @@ -123,6 +127,9 @@ use OC\Security\CSRF\CsrfTokenManager; use OC\Security\CSRF\TokenStorage\SessionStorage; use OC\Security\Hasher; use OC\Security\Ip\RemoteAddress; +use OC\Security\RateLimiting\Backend\DatabaseBackend; +use OC\Security\RateLimiting\Backend\IBackend; +use OC\Security\RateLimiting\Backend\MemoryCacheBackend; use OC\Security\RateLimiting\Limiter; use OC\Security\RemoteHostValidator; use OC\Security\SecureRandom; @@ -159,6 +166,7 @@ use OCA\Theming\Service\BackgroundService; use OCA\Theming\ThemingDefaults; use OCA\Theming\Util; use OCP\Accounts\IAccountManager; +use OCP\Activity\IEventMerger; use OCP\App\IAppManager; use OCP\AppFramework\Utility\IControllerMethodReflector; use OCP\AppFramework\Utility\ITimeFactory; @@ -167,13 +175,17 @@ use OCP\Authentication\Token\IProvider as OCPIProvider; use OCP\Authentication\TwoFactorAuth\IRegistry; use OCP\AutoloadNotAllowedException; use OCP\BackgroundJob\IJobList; +use OCP\Collaboration\Collaborators\ISearch; +use OCP\Collaboration\Collaborators\ISearchResult; use OCP\Collaboration\Reference\IReferenceManager; +use OCP\Collaboration\Resources\IProviderManager; use OCP\Command\IBus; use OCP\Comments\ICommentsManager; use OCP\Comments\ICommentsManagerFactory; use OCP\Config\IUserConfig; use OCP\Contacts\ContactsMenu\IActionFactory; use OCP\Contacts\ContactsMenu\IContactsStore; +use OCP\ContextChat\IContentManager; use OCP\Defaults; use OCP\Diagnostics\IEventLogger; use OCP\Diagnostics\IQueryLogger; @@ -194,6 +206,7 @@ use OCP\Files\IFilenameValidator; use OCP\Files\IMimeTypeDetector; use OCP\Files\IMimeTypeLoader; use OCP\Files\IRootFolder; +use OCP\Files\ISetupManager; use OCP\Files\Lock\ILockManager; use OCP\Files\Mount\IMountManager; use OCP\Files\Storage\IStorageFactory; @@ -237,7 +250,10 @@ use OCP\Lockdown\ILockdownManager; use OCP\Log\ILogFactory; use OCP\Mail\IEmailValidator; use OCP\Mail\IMailer; +use OCP\OCM\ICapabilityAwareOCMProvider; use OCP\OCM\IOCMDiscoveryService; +use OCP\OCM\IOCMProvider; +use OCP\OCS\IDiscoveryService; use OCP\Preview\IMimeIconProvider; use OCP\Profile\IProfileManager; use OCP\Profiler\IProfiler; @@ -247,10 +263,12 @@ use OCP\RichObjectStrings\IRichTextFormatter; use OCP\RichObjectStrings\IValidator; use OCP\Route\IRouter; use OCP\Security\Bruteforce\IThrottler; +use OCP\Security\IContentSecurityPolicyManager; use OCP\Security\ICredentialsManager; use OCP\Security\ICrypto; use OCP\Security\IHasher; use OCP\Security\Ip\IRemoteAddress; +use OCP\Security\IRemoteHostValidator; use OCP\Security\ISecureRandom; use OCP\Security\ITrustedDomainHelper; use OCP\Security\RateLimiting\ILimiter; @@ -260,10 +278,12 @@ use OCP\ServerVersion; use OCP\Settings\IDeclarativeManager; use OCP\SetupCheck\ISetupCheckManager; use OCP\Share\IProviderFactory; +use OCP\Share\IPublicShareTemplateFactory; use OCP\Share\IShareHelper; use OCP\Snowflake\ISnowflakeDecoder; use OCP\Snowflake\ISnowflakeGenerator; use OCP\SpeechToText\ISpeechToTextManager; +use OCP\Support\Subscription\IAssertion; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\Talk\IBroker; @@ -313,8 +333,8 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(\OCP\Contacts\IManager::class, ContactsManager::class); - $this->registerAlias(\OCP\ContextChat\IContentManager::class, \OC\ContextChat\ContentManager::class); - $this->registerAlias(\OCP\Files\ISetupManager::class, \OC\Files\SetupManager::class); + $this->registerAlias(IContentManager::class, ContentManager::class); + $this->registerAlias(ISetupManager::class, SetupManager::class); $this->registerAlias(\OCP\DirectEditing\IManager::class, \OC\DirectEditing\Manager::class); $this->registerAlias(ITemplateManager::class, TemplateManager::class); @@ -671,8 +691,8 @@ class Server extends ServerContainer implements IServerContainer { ); }); - $this->registerService(\OCP\Activity\IEventMerger::class, function (Server $c) { - return new \OC\Activity\EventMerger( + $this->registerService(IEventMerger::class, function (Server $c) { + return new EventMerger( $c->getL10N('lib') ); }); @@ -695,7 +715,7 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(\OCP\Support\CrashReport\IRegistry::class, \OC\Support\CrashReport\Registry::class); $this->registerAlias(\OCP\Support\Subscription\IRegistry::class, \OC\Support\Subscription\Registry::class); - $this->registerAlias(\OCP\Support\Subscription\IAssertion::class, Assertion::class); + $this->registerAlias(IAssertion::class, Assertion::class); /** Only used by the PsrLoggerAdapter should not be used by apps */ $this->registerService(Log::class, function (Server $c) { @@ -726,16 +746,16 @@ class Server extends ServerContainer implements IServerContainer { }); $this->registerAlias(IRouter::class, Router::class); - $this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function ($c) { + $this->registerService(IBackend::class, function ($c) { $config = $c->get(IConfig::class); if (ltrim($config->getSystemValueString('memcache.distributed', ''), '\\') === Redis::class) { - $backend = new \OC\Security\RateLimiting\Backend\MemoryCacheBackend( + $backend = new MemoryCacheBackend( $c->get(AllConfig::class), $this->get(ICacheFactory::class), new TimeFactory() ); } else { - $backend = new \OC\Security\RateLimiting\Backend\DatabaseBackend( + $backend = new DatabaseBackend( $c->get(AllConfig::class), $c->get(IDBConnection::class), new TimeFactory() @@ -746,7 +766,7 @@ class Server extends ServerContainer implements IServerContainer { }); $this->registerAlias(ISecureRandom::class, SecureRandom::class); - $this->registerAlias(\OCP\Security\IRemoteHostValidator::class, RemoteHostValidator::class); + $this->registerAlias(IRemoteHostValidator::class, RemoteHostValidator::class); $this->registerAlias(IVerificationToken::class, VerificationToken::class); $this->registerAlias(ICrypto::class, Crypto::class); @@ -1127,7 +1147,7 @@ class Server extends ServerContainer implements IServerContainer { $this->registerService(SessionStorage::class, function (ContainerInterface $c) { return new SessionStorage($c->get(ISession::class)); }); - $this->registerAlias(\OCP\Security\IContentSecurityPolicyManager::class, ContentSecurityPolicyManager::class); + $this->registerAlias(IContentSecurityPolicyManager::class, ContentSecurityPolicyManager::class); $this->registerService(IProviderFactory::class, function (ContainerInterface $c) { $config = $c->get(IConfig::class); @@ -1138,8 +1158,8 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(\OCP\Share\IManager::class, \OC\Share20\Manager::class); - $this->registerService(\OCP\Collaboration\Collaborators\ISearch::class, function (Server $c): \OCP\Collaboration\Collaborators\ISearch { - $instance = new \OC\Collaboration\Collaborators\Search($c); + $this->registerService(ISearch::class, function (Server $c): ISearch { + $instance = new Search($c); // register default plugins $instance->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => UserPlugin::class]); @@ -1151,11 +1171,11 @@ class Server extends ServerContainer implements IServerContainer { return $instance; }); - $this->registerAlias(\OCP\Collaboration\Collaborators\ISearchResult::class, \OC\Collaboration\Collaborators\SearchResult::class); + $this->registerAlias(ISearchResult::class, SearchResult::class); $this->registerAlias(\OCP\Collaboration\AutoComplete\IManager::class, \OC\Collaboration\AutoComplete\Manager::class); - $this->registerAlias(\OCP\Collaboration\Resources\IProviderManager::class, ProviderManager::class); + $this->registerAlias(IProviderManager::class, ProviderManager::class); $this->registerAlias(\OCP\Collaboration\Resources\IManager::class, \OC\Collaboration\Resources\Manager::class); $this->registerAlias(IReferenceManager::class, ReferenceManager::class); @@ -1176,7 +1196,7 @@ class Server extends ServerContainer implements IServerContainer { }); }); - $this->registerService(\OCP\OCS\IDiscoveryService::class, function (ContainerInterface $c): \OCP\OCS\IDiscoveryService { + $this->registerService(IDiscoveryService::class, function (ContainerInterface $c): IDiscoveryService { return new DiscoveryService( $c->get(ICacheFactory::class), $c->get(IClientService::class) @@ -1258,7 +1278,7 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(IBinaryFinder::class, BinaryFinder::class); - $this->registerAlias(\OCP\Share\IPublicShareTemplateFactory::class, PublicShareTemplateFactory::class); + $this->registerAlias(IPublicShareTemplateFactory::class, PublicShareTemplateFactory::class); $this->registerAlias(ITranslationManager::class, TranslationManager::class); @@ -1277,8 +1297,8 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(IPhoneNumberUtil::class, PhoneNumberUtil::class); // there is no reason for having OCMProvider as a Service (marked as deprecated since 32.0.0) - $this->registerDeprecatedAlias(\OCP\OCM\ICapabilityAwareOCMProvider::class, OCMProvider::class); - $this->registerDeprecatedAlias(\OCP\OCM\IOCMProvider::class, OCMProvider::class); + $this->registerDeprecatedAlias(ICapabilityAwareOCMProvider::class, OCMProvider::class); + $this->registerDeprecatedAlias(IOCMProvider::class, OCMProvider::class); $this->registerAlias(ISetupCheckManager::class, SetupCheckManager::class); diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 9f8dc929361..db5fcf5ae94 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -60,6 +60,7 @@ use OCP\Share\IPartialShareProvider; use OCP\Share\IProviderFactory; use OCP\Share\IShare; use OCP\Share\IShareProvider; +use OCP\Share\IShareProviderGetUsers; use OCP\Share\IShareProviderSupportsAccept; use OCP\Share\IShareProviderSupportsAllSharesInFolder; use OCP\Share\IShareProviderWithNotification; @@ -1591,7 +1592,7 @@ class Manager implements IManager { } #[\Override] - public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false): array { + public function getAccessList(Node $path, $recursive = true, $currentAccess = false): array { $owner = $path->getOwner(); if ($owner === null) { @@ -1986,7 +1987,7 @@ class Manager implements IManager { public function getUsersForShare(IShare $share): iterable { $provider = $this->factory->getProviderForType($share->getShareType()); - if ($provider instanceof Share\IShareProviderGetUsers) { + if ($provider instanceof IShareProviderGetUsers) { return $provider->getUsersForShare($share); } else { return []; diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 36b9f80dd99..5c899b7892f 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -664,7 +664,7 @@ class Manager extends PublicEmitter implements IUserManager { * @internal Only for mocks it in unit tests. */ public function getUserConfig(): IUserConfig { - return \OCP\Server::get(IUserConfig::class); + return Server::get(IUserConfig::class); } /** diff --git a/lib/private/legacy/OC_User.php b/lib/private/legacy/OC_User.php index abdb37b737c..ddd426da942 100644 --- a/lib/private/legacy/OC_User.php +++ b/lib/private/legacy/OC_User.php @@ -9,6 +9,7 @@ use OC\Authentication\Token\IProvider; use OC\SystemConfig; use OC\User\Database; use OC\User\DisabledUserException; +use OC\User\Session; use OCP\Authentication\Exceptions\InvalidTokenException; use OCP\Authentication\Exceptions\WipeTokenException; use OCP\Authentication\IApacheBackend; @@ -151,7 +152,7 @@ class OC_User { if ($uid) { if (self::getUser() !== $uid) { self::setUserId($uid); - /** @var \OC\User\Session $userSession */ + /** @var Session $userSession */ $userSession = Server::get(IUserSession::class); /** @var IEventDispatcher $dispatcher */ @@ -234,7 +235,7 @@ class OC_User { //setup extra user backends self::setupBackends(); - /** @var \OC\User\Session $session */ + /** @var Session $session */ $session = Server::get(IUserSession::class); $session->unsetMagicInCookie(); diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index 0a38062e553..b3b0f4e3e20 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -12,6 +12,7 @@ use OC\Files\Filesystem; use OC\Files\SetupManager; use OC\Setup; use OC\SystemConfig; +use OCP\App\IAppManager; use OCP\Files\FileInfo; use OCP\Files\Folder; use OCP\Files\NotFoundException; @@ -787,14 +788,14 @@ class OC_Util { * @deprecated 32.0.0 Use \OCP\Util::needUpgrade() instead. * @see \OCP\Util::needUpgrade */ - public static function needUpgrade(\OC\SystemConfig $config): bool { + public static function needUpgrade(SystemConfig $config): bool { if (!$config->getValue('installed', false)) { // not installed (nothing to do) return false; } $installedVersion = (string)$config->getValue('version', '0.0.0'); - $codeVersion = implode('.', \OCP\Util::getVersion()); + $codeVersion = implode('.', Util::getVersion()); // codebase newer: upgrade needed if (version_compare($codeVersion, $installedVersion, '>')) { @@ -815,12 +816,12 @@ class OC_Util { // disallow downgrade (not in debug mode or major.minor mismatch) /** @var \Psr\Log\LoggerInterface $logger */ - $logger = \OCP\Server::get(LoggerInterface::class); + $logger = Server::get(LoggerInterface::class); $logger->error( 'Detected downgrade attempt from installed {installed} to code {code}', [ 'installed' => $installedVersion, 'code' => $codeVersion, 'app' => 'core', ] ); - throw new \OCP\HintException(sprintf( + throw new HintException(sprintf( 'Downgrading Nextcloud from %s to %s is not supported and may corrupt your instance (database and data directory). ' . 'Restore a full backup (code, database, and data directory) taken before the change, ' . 'or restore the previous codebase so that it matches the installed version (version %s).', @@ -829,7 +830,7 @@ class OC_Util { } // versions are equal: check whether any enabled apps need upgrading - $appManager = \OCP\Server::get(\OCP\App\IAppManager::class); + $appManager = Server::get(IAppManager::class); $apps = $appManager->getEnabledApps(); foreach ($apps as $app) { if ($appManager->isUpgradeRequired($app)) { diff --git a/tests/Core/Controller/ClientFlowLoginControllerTest.php b/tests/Core/Controller/ClientFlowLoginControllerTest.php index 7a5bbbec82d..39d915e04bc 100644 --- a/tests/Core/Controller/ClientFlowLoginControllerTest.php +++ b/tests/Core/Controller/ClientFlowLoginControllerTest.php @@ -161,7 +161,7 @@ class ClientFlowLoginControllerTest extends TestCase { $initialState = []; $this->initialState->expects($this->exactly(2)) ->method('provideInitialState') - ->willReturnCallback(function () use (&$initialState) { + ->willReturnCallback(function () use (&$initialState): void { $initialState[] = func_get_args(); }); @@ -240,7 +240,7 @@ class ClientFlowLoginControllerTest extends TestCase { $initialState = []; $this->initialState->expects($this->exactly(2)) ->method('provideInitialState') - ->willReturnCallback(function () use (&$initialState) { + ->willReturnCallback(function () use (&$initialState): void { $initialState[] = func_get_args(); }); diff --git a/tests/Core/Controller/OpenMetricsControllerTest.php b/tests/Core/Controller/OpenMetricsControllerTest.php index 56e40cdf7d7..fdc81ad5d2c 100644 --- a/tests/Core/Controller/OpenMetricsControllerTest.php +++ b/tests/Core/Controller/OpenMetricsControllerTest.php @@ -59,7 +59,7 @@ class OpenMetricsControllerTest extends TestCase { $output = $this->createMock(IOutput::class); $fullOutput = ''; $output->method('setOutput') - ->willReturnCallback(function ($output) use (&$fullOutput) { + ->willReturnCallback(function ($output) use (&$fullOutput): void { $fullOutput .= $output; }); $this->config->expects($this->once()) diff --git a/tests/lib/Collaboration/Collaborators/MailPluginTest.php b/tests/lib/Collaboration/Collaborators/MailPluginTest.php index cf39642280c..9a0928a82e9 100644 --- a/tests/lib/Collaboration/Collaborators/MailPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/MailPluginTest.php @@ -970,7 +970,7 @@ class MailPluginTest extends TestCase { $this->instantiatePlugin(IShare::TYPE_USER); - $currentUser = $this->createMock(\OCP\IUser::class); + $currentUser = $this->createMock(IUser::class); $currentUser->expects($this->any()) ->method('getUID') diff --git a/tests/lib/DB/MigrationServiceTest.php b/tests/lib/DB/MigrationServiceTest.php index c2c8cdc03cc..0142c36ee26 100644 --- a/tests/lib/DB/MigrationServiceTest.php +++ b/tests/lib/DB/MigrationServiceTest.php @@ -224,7 +224,7 @@ class MigrationServiceTest extends \Test\TestCase { $migrationService ->expects($this->exactly(2)) ->method('executeStep') - ->willReturnCallback(function (string $migration) use (&$calls) { + ->willReturnCallback(function (string $migration) use (&$calls): void { $calls[] = $migration; }); diff --git a/tests/lib/Files/Config/UserMountCacheTest.php b/tests/lib/Files/Config/UserMountCacheTest.php index c0a419aaa08..6e6630b5be3 100644 --- a/tests/lib/Files/Config/UserMountCacheTest.php +++ b/tests/lib/Files/Config/UserMountCacheTest.php @@ -184,7 +184,7 @@ class UserMountCacheTest extends TestCase { ->expects($this->exactly(2)) ->method('dispatchTyped') ->with($this->callback(function (UserMountAddedEvent|UserMountRemovedEvent $event) use (&$operation) { - return match(++$operation) { + return match (++$operation) { 1 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/asd/', 2 => $event instanceof UserMountRemovedEvent && $event->mountPoint->getMountPoint() === '/asd/', default => false, @@ -215,7 +215,7 @@ class UserMountCacheTest extends TestCase { ->expects($this->exactly(3)) ->method('dispatchTyped') ->with($this->callback(function (UserMountAddedEvent|UserMountRemovedEvent $event) use (&$operation) { - return match(++$operation) { + return match (++$operation) { 1 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/bar/', 2 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/foo/', 3 => $event instanceof UserMountRemovedEvent && $event->mountPoint->getMountPoint() === '/bar/', @@ -251,7 +251,7 @@ class UserMountCacheTest extends TestCase { ->expects($this->exactly(2)) ->method('dispatchTyped') ->with($this->callback(function (UserMountAddedEvent|UserMountUpdatedEvent $event) use (&$operation) { - return match(++$operation) { + return match (++$operation) { 1 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/foo/', 2 => $event instanceof UserMountUpdatedEvent && $event->oldMountPoint->getMountId() === null && $event->newMountPoint->getMountId() === 1, default => false, @@ -596,4 +596,27 @@ class UserMountCacheTest extends TestCase { $this->assertCount(1, $cachedMounts); $this->assertEquals('dummy', $cachedMounts[$this->keyForMount($mount1)]->getMountProvider()); } + + public function testChangedSameRootId(): void { + $user = $this->userManager->get('u1'); + + [$storage] = $this->getStorage(10); + $mount1 = new MountPoint($storage, '/asd/'); + $mount2 = new MountPoint($storage, '/asd2/'); + + $this->cache->registerMounts($user, [$mount1, $mount2]); + + $mount2 = new MountPoint($storage, '/asd2/', null, null, null, 1); + $this->cache->registerMounts($user, [$mount1, $mount2]); + + $this->cache->flush(); + $cached = $this->cache->getMountsForUser($user); + usort($cached, fn (ICachedMountInfo $a, ICachedMountInfo $b) => $a->getMountPoint() <=> $b->getMountPoint()); + + $mountPoints = array_map(fn (ICachedMountInfo $mountInfo) => $mountInfo->getMountPoint(), $cached); + $this->assertEquals(['/asd/', '/asd2/'], $mountPoints); + + $mountIds = array_map(fn (ICachedMountInfo $mountInfo) => $mountInfo->getMountId(), $cached); + $this->assertEquals([null, 1], $mountIds); + } } diff --git a/tests/lib/Files/SetupManagerTest.php b/tests/lib/Files/SetupManagerTest.php index 673b0fc738c..f70358691cd 100644 --- a/tests/lib/Files/SetupManagerTest.php +++ b/tests/lib/Files/SetupManagerTest.php @@ -633,7 +633,7 @@ class SetupManagerTest extends TestCase { } private function getAddMountCheckCallback(InvokedCount $invokedCount, $expectations): \Closure { - return function (IMountPoint $actualMount) use ($invokedCount, $expectations) { + return function (IMountPoint $actualMount) use ($invokedCount, $expectations): void { $expectedMount = $expectations[$invokedCount->numberOfInvocations()] ?? null; $this->assertSame($expectedMount, $actualMount); }; diff --git a/tests/lib/Files/Template/TemplateManagerTest.php b/tests/lib/Files/Template/TemplateManagerTest.php index 7b3f0beff42..431b032594c 100644 --- a/tests/lib/Files/Template/TemplateManagerTest.php +++ b/tests/lib/Files/Template/TemplateManagerTest.php @@ -24,6 +24,8 @@ use OCP\IL10N; use OCP\IPreview; use OCP\IServerContainer; use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; use OCP\L10N\IFactory; use Psr\Log\NullLogger; use Test\TestCase; @@ -64,10 +66,10 @@ class TemplateManagerTest extends TestCase { $this->rootFolder = $this->createMock(IRootFolder::class); $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('user1'); - $userSession = $this->createMock(\OCP\IUserSession::class); + $userSession = $this->createMock(IUserSession::class); $userSession->method('getUser') ->willReturn($user); - $userManager = $this->createMock(\OCP\IUserManager::class); + $userManager = $this->createMock(IUserManager::class); $previewManager = $this->createMock(IPreview::class); $this->templateManager = new TemplateManager( diff --git a/tests/lib/OCM/Listeners/LocalOCMDiscoveryTestEvent.php b/tests/lib/OCM/Listeners/LocalOCMDiscoveryTestEvent.php index 7553d9f1b74..b2d0e7d09f6 100644 --- a/tests/lib/OCM/Listeners/LocalOCMDiscoveryTestEvent.php +++ b/tests/lib/OCM/Listeners/LocalOCMDiscoveryTestEvent.php @@ -10,6 +10,7 @@ namespace Test\OCM\Listeners; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\OCM\Events\LocalOCMDiscoveryEvent; /** @template-implements IEventListener<\OCP\OCM\Events\LocalOCMDiscoveryEvent> */ class LocalOCMDiscoveryTestEvent implements IEventListener { @@ -18,7 +19,7 @@ class LocalOCMDiscoveryTestEvent implements IEventListener { } public function handle(Event $event): void { - if (!($event instanceof \OCP\OCM\Events\LocalOCMDiscoveryEvent)) { + if (!($event instanceof LocalOCMDiscoveryEvent)) { return; } diff --git a/tests/lib/OCM/Listeners/OCMEndpointRequestTestEvent.php b/tests/lib/OCM/Listeners/OCMEndpointRequestTestEvent.php index f0b706fe39b..bbe36a529fd 100644 --- a/tests/lib/OCM/Listeners/OCMEndpointRequestTestEvent.php +++ b/tests/lib/OCM/Listeners/OCMEndpointRequestTestEvent.php @@ -12,6 +12,8 @@ use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\Response; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\OCM\Enum\ParamType; +use OCP\OCM\Events\OCMEndpointRequestEvent; /** @template-implements IEventListener<\OCP\OCM\Events\OCMEndpointRequestEvent> */ class OCMEndpointRequestTestEvent implements IEventListener { @@ -20,7 +22,7 @@ class OCMEndpointRequestTestEvent implements IEventListener { } public function handle(Event $event): void { - if (!($event instanceof \OCP\OCM\Events\OCMEndpointRequestEvent)) { + if (!($event instanceof OCMEndpointRequestEvent)) { return; } @@ -36,11 +38,11 @@ class OCMEndpointRequestTestEvent implements IEventListener { 'args' => $event->getArgs(), 'totalArgs' => $event->getArgsCount(), 'typedArgs' => $event->getArgs( - \OCP\OCM\Enum\ParamType::STRING, - \OCP\OCM\Enum\ParamType::STRING, - \OCP\OCM\Enum\ParamType::INT, - \OCP\OCM\Enum\ParamType::BOOL, - \OCP\OCM\Enum\ParamType::INT + ParamType::STRING, + ParamType::STRING, + ParamType::INT, + ParamType::BOOL, + ParamType::INT ) ] )); diff --git a/tests/lib/Preview/PostscriptTest.php b/tests/lib/Preview/PostscriptTest.php index 5fb7abc5201..e5cc15ee7f4 100644 --- a/tests/lib/Preview/PostscriptTest.php +++ b/tests/lib/Preview/PostscriptTest.php @@ -10,6 +10,7 @@ namespace Test\Preview; use OC\BinaryFinder; use OC\Preview\Postscript; +use OCP\Server; #[\PHPUnit\Framework\Attributes\Group('DB')] #[\PHPUnit\Framework\Attributes\RequiresPhpExtension('imagick')] @@ -19,7 +20,7 @@ class PostscriptTest extends Provider { if (\Imagick::queryFormats('EPS') === false || \Imagick::queryFormats('PS') === false) { $this->markTestSkipped('Imagick does not support postscript.'); } - if (\OCP\Server::get(BinaryFinder::class)->findBinaryPath('gs') === false) { + if (Server::get(BinaryFinder::class)->findBinaryPath('gs') === false) { // Imagick forwards postscript rendering to Ghostscript but does not report this in queryFormats $this->markTestSkipped('Ghostscript is not installed.'); } diff --git a/tests/lib/TestCase.php b/tests/lib/TestCase.php index 551c1024e0b..c40c05b3de7 100644 --- a/tests/lib/TestCase.php +++ b/tests/lib/TestCase.php @@ -23,6 +23,7 @@ use OC\Files\SetupManager; use OC\Files\View; use OC\Installer; use OC\Updater; +use OC\User\Session; use OCP\Command\IBus; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\IRootFolder; @@ -442,7 +443,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { */ protected static function logout(): void { Server::get(SetupManager::class)->tearDown(); - $userSession = Server::get(\OC\User\Session::class); + $userSession = Server::get(Session::class); $userSession->getSession()->set('user_id', ''); // needed for fully logout $userSession->setUser(null);