Merge branch 'master' into jtr/docs-config-mount-file-drop

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
This commit is contained in:
Carl Schwan 2026-03-06 13:39:08 +01:00 committed by GitHub
commit bd8aff39f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
81 changed files with 488 additions and 308 deletions

View file

@ -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());

View file

@ -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(),
];
}

View file

@ -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()) {

View file

@ -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());

View file

@ -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 {

View file

@ -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;
}
}

View file

@ -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')

View file

@ -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' => '']],
];
}
}

View file

@ -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' => '']],
];
}
}

View file

@ -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",

View file

@ -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",

View file

@ -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);
});
}
}

View file

@ -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: '');
}

View file

@ -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);
}

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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}",

View file

@ -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}",

View file

@ -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} 影像",

View file

@ -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} 影像",

View file

@ -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']);

View file

@ -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",

View file

@ -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",

View file

@ -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];
});

View file

@ -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);
}
}

View file

@ -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]);

View file

@ -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();

View file

@ -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',

View file

@ -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();
});

View file

@ -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);

View file

@ -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');

View file

@ -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);
}

View file

@ -616,9 +616,8 @@ class Manager implements IManager {
public function formatOperation(array $operation): array {
$checkIds = json_decode($operation['checks'], true);
/** @var list<WorkflowEngineCheck> $checks */
$checks = $this->getChecks($checkIds);
$operation['checks'] = $checks;
$operation['checks'] = array_values($checks);
/** @var list<class-string<IEntityEvent>> $events */
$events = json_decode($operation['events'], true) ?? [];

View file

@ -839,9 +839,6 @@
</InvalidOperand>
</file>
<file src="apps/dav/lib/Search/EventsSearchProvider.php">
<FalsableReturnStatement>
<code><![CDATA[$this->l10n->l('date', $startDateTime, ['width' => 'medium'])]]></code>
</FalsableReturnStatement>
<InvalidOperand>
<code><![CDATA[$query->getCursor()]]></code>
</InvalidOperand>
@ -851,12 +848,6 @@
'ORGANIZER' => ['CN'],
]]]></code>
</InvalidPropertyAssignmentValue>
<InvalidReturnStatement>
<code><![CDATA[$this->l10n->l('date', $startDateTime, ['width' => 'medium'])]]></code>
</InvalidReturnStatement>
<InvalidReturnType>
<code><![CDATA[string]]></code>
</InvalidReturnType>
<UndefinedMethod>
<code><![CDATA[getDateTime]]></code>
<code><![CDATA[getDateTime]]></code>
@ -3597,22 +3588,6 @@
<code><![CDATA[$this->fileInfo]]></code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/private/Files/Node/Root.php">
<LessSpecificReturnStatement>
<code><![CDATA[$folders]]></code>
<code><![CDATA[$this->mountManager->findByNumericId($numericId)]]></code>
<code><![CDATA[$this->mountManager->findByStorageId($storageId)]]></code>
<code><![CDATA[$this->mountManager->findIn($mountPoint)]]></code>
</LessSpecificReturnStatement>
<MoreSpecificReturnType>
<code><![CDATA[MountPoint[]]]></code>
<code><![CDATA[\OC\Files\Mount\MountPoint[]]]></code>
<code><![CDATA[\OC\Files\Mount\MountPoint[]]]></code>
</MoreSpecificReturnType>
<UndefinedMethod>
<code><![CDATA[remove]]></code>
</UndefinedMethod>
</file>
<file src="lib/private/Files/ObjectStore/S3ConnectionTrait.php">
<InternalClass>
<code><![CDATA[ClientResolver::_default_signature_provider()]]></code>

2
composer.lock generated
View file

@ -96,5 +96,5 @@
"platform-overrides": {
"php": "8.2"
},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.9.0"
}

View file

@ -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,

View file

@ -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(

View file

@ -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,
[

View file

@ -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(),

View file

@ -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);
});
}

View file

@ -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('/');

View file

@ -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);

View file

@ -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();
}

View file

@ -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<string,mixed>
*/
class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
private array|ICacheEntry $data;
/**
* @var string
*/
private $path;
/**
* @var \OC\Files\Storage\Storage $storage
*/
private $storage;
/**
* @var string
*/
private $internalPath;
/**
* @var \OCP\Files\Mount\IMountPoint
*/
private $mount;
private ?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);
}
/**

View file

@ -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);

View file

@ -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);

View file

@ -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());
}

View file

@ -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());
}

View file

@ -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;

View file

@ -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']);

View file

@ -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();
}

View file

@ -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;
}

View file

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later

View file

@ -636,7 +636,7 @@ class SetupManager implements ISetupManager {
$this->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(), '/') . '/';

View file

@ -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) {

View file

@ -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]);
}
}

View file

@ -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()');
}
}

View file

@ -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 = '',
) {
}
/**

View file

@ -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;
}

View file

@ -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) {

View file

@ -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,
];
/**

View file

@ -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);

View file

@ -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 [];

View file

@ -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);
}
/**

View file

@ -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();

View file

@ -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)) {

View file

@ -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();
});

View file

@ -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())

View file

@ -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')

View file

@ -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;
});

View file

@ -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);
}
}

View file

@ -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);
};

View file

@ -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(

View file

@ -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;
}

View file

@ -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
)
]
));

View file

@ -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.');
}

View file

@ -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);