From 767e2daa96d93692db2271aeee682cde1b2fc70c Mon Sep 17 00:00:00 2001 From: xhon-pelushi Date: Thu, 13 Aug 2026 23:48:42 -0400 Subject: [PATCH] fix: pass language to file conversions Fixes #5165 Signed-off-by: xhon-pelushi --- lib/Conversion/ConversionProvider.php | 13 ++- lib/Service/RemoteService.php | 22 ++++- .../lib/Conversion/ConversionProviderTest.php | 70 +++++++++++++++ tests/lib/Service/RemoteServiceTest.php | 87 +++++++++++++++++++ 4 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 tests/lib/Conversion/ConversionProviderTest.php create mode 100644 tests/lib/Service/RemoteServiceTest.php diff --git a/lib/Conversion/ConversionProvider.php b/lib/Conversion/ConversionProvider.php index f2096d222f..75c38bb423 100644 --- a/lib/Conversion/ConversionProvider.php +++ b/lib/Conversion/ConversionProvider.php @@ -165,7 +165,18 @@ public function convertFile(File $file, string $targetMimeType): mixed { } } - return $this->remoteService->convertFileTo($file, $targetFileExtension); + return $this->remoteService->convertFileTo( + $file, + $targetFileExtension, + conversionOptions: ['lang' => $this->getConversionLanguage()] + ); + } + + private function getConversionLanguage(): string { + $locale = $this->l10n->getLocaleCode(); + $language = $locale !== '' ? $locale : $this->l10n->getLanguageCode(); + + return str_replace('_', '-', $language); } private function getMimeProvidersFor(array $inputMimeTypes, string $outputMimeType): array { diff --git a/lib/Service/RemoteService.php b/lib/Service/RemoteService.php index 0b63e97af0..ca21b15f04 100644 --- a/lib/Service/RemoteService.php +++ b/lib/Service/RemoteService.php @@ -58,9 +58,15 @@ public function fetchTargetThumbnail(File $file, string $target): ?string { } /** + * @param array $conversionOptions * @return resource|string */ - public function convertFileTo(File $file, string $format, int $timeout = RemoteOptionsService::REMOTE_TIMEOUT_DEFAULT) { + public function convertFileTo( + File $file, + string $format, + int $timeout = RemoteOptionsService::REMOTE_TIMEOUT_DEFAULT, + array $conversionOptions = [], + ) { $fileName = $file->getStorage()->getLocalFile($file->getInternalPath()); $stream = fopen($fileName, 'rb'); @@ -68,11 +74,12 @@ public function convertFileTo(File $file, string $format, int $timeout = RemoteO throw new Exception('Failed to open stream'); } - return $this->convertTo($file->getName(), $stream, $format, [], $timeout); + return $this->convertTo($file->getName(), $stream, $format, $conversionOptions, $timeout); } /** * @param resource $stream + * @param array|null $conversionOptions * @return resource|string */ public function convertTo(string $filename, $stream, string $format, ?array $conversionOptions = [], int $timeout = RemoteOptionsService::REMOTE_TIMEOUT_DEFAULT) { @@ -86,13 +93,20 @@ public function convertTo(string $filename, $stream, string $format, ?array $con } $options['multipart'] = [ - array_merge([ + [ 'name' => $filename, 'filename' => $filename, 'contents' => $stream - ], $conversionOptions), + ], ]; + foreach ($conversionOptions ?? [] as $name => $contents) { + $options['multipart'][] = [ + 'name' => (string)$name, + 'contents' => $contents, + ]; + } + try { $response = $client->post($this->appConfig->getCollaboraUrlInternal() . '/cool/convert-to/' . $format, $options); $body = $response->getBody(); diff --git a/tests/lib/Conversion/ConversionProviderTest.php b/tests/lib/Conversion/ConversionProviderTest.php new file mode 100644 index 0000000000..ddf87b29d8 --- /dev/null +++ b/tests/lib/Conversion/ConversionProviderTest.php @@ -0,0 +1,70 @@ +remoteService = $this->createMock(RemoteService::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->l10nFactory = $this->createMock(IFactory::class); + $this->l10n = $this->createMock(IL10N::class); + $this->secureViewService = $this->createMock(SecureViewService::class); + + $this->l10n->method('t')->willReturnCallback(static fn (string $text): string => $text); + $this->l10nFactory->method('get') + ->with('richdocuments') + ->willReturn($this->l10n); + + $this->provider = new ConversionProvider( + $this->remoteService, + $this->logger, + $this->l10nFactory, + $this->secureViewService, + ); + } + + public function testConvertFilePassesCurrentLocaleToCollabora(): void { + $file = $this->createMock(File::class); + + $this->l10n->expects($this->once()) + ->method('getLocaleCode') + ->willReturn('de_DE'); + $this->secureViewService->method('isEnabled') + ->willReturn(false); + $this->remoteService->expects($this->once()) + ->method('convertFileTo') + ->with($file, 'pdf', RemoteOptionsService::REMOTE_TIMEOUT_DEFAULT, ['lang' => 'de-DE']) + ->willReturn('pdf-content'); + + $result = $this->provider->convertFile($file, 'application/pdf'); + + $this->assertSame('pdf-content', $result); + } +} diff --git a/tests/lib/Service/RemoteServiceTest.php b/tests/lib/Service/RemoteServiceTest.php new file mode 100644 index 0000000000..13f986e575 --- /dev/null +++ b/tests/lib/Service/RemoteServiceTest.php @@ -0,0 +1,87 @@ +appConfig = $this->createMock(AppConfig::class); + $this->clientService = $this->createMock(IClientService::class); + $this->client = $this->createMock(IClient::class); + $this->capabilitiesService = $this->createMock(CapabilitiesService::class); + $this->logger = $this->createMock(LoggerInterface::class); + + $this->clientService->method('newClient') + ->willReturn($this->client); + + $this->service = new RemoteService( + $this->appConfig, + $this->clientService, + $this->capabilitiesService, + $this->logger, + ); + } + + public function testConvertToSendsConversionOptionsAsMultipartFields(): void { + $stream = fopen('php://memory', 'r+'); + $response = $this->createMock(IResponse::class); + + $this->appConfig->method('getCollaboraUrlInternal') + ->willReturn('http://cool.example'); + $this->appConfig->method('getDisableCertificateValidation') + ->willReturn(false); + $response->method('getBody') + ->willReturn('converted-content'); + + $this->client->expects($this->once()) + ->method('post') + ->with( + 'http://cool.example/cool/convert-to/pdf', + $this->callback(function (array $options) use ($stream): bool { + $this->assertSame([ + [ + 'name' => 'document.xlsx', + 'filename' => 'document.xlsx', + 'contents' => $stream, + ], + [ + 'name' => 'lang', + 'contents' => 'de-DE', + ], + ], $options['multipart']); + + return true; + }) + ) + ->willReturn($response); + + $result = $this->service->convertTo('document.xlsx', $stream, 'pdf', ['lang' => 'de-DE']); + + $this->assertSame('converted-content', $result); + } +}