From aceb4d776c48dbe46cf066c4688a190b153ed046 Mon Sep 17 00:00:00 2001 From: "Misha M.-Kupriyanov" Date: Fri, 15 Mar 2024 10:40:54 +0100 Subject: [PATCH] feat: reduce available languages per config value "reduce_to_languages" Example: restrict to en, de, es, fr, it' languages ./occ config:system:set reduce_to_languages 0 --value en ./occ config:system:set reduce_to_languages 1 --value de ./occ config:system:set reduce_to_languages 2 --value es ./occ config:system:set reduce_to_languages 3 --value fr ./occ config:system:set reduce_to_languages 4 --value it Signed-off-by: Misha M.-Kupriyanov --- config/config.sample.php | 11 +++++++- lib/private/L10N/Factory.php | 4 +++ tests/lib/L10N/FactoryTest.php | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/config/config.sample.php b/config/config.sample.php index 288ea7e4a9b2f..77fd2490a1498 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -5,7 +5,7 @@ * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ - + /** * This configuration file is only provided to document the different * configuration options and their usage. @@ -228,6 +228,15 @@ */ 'default_locale' => 'en_US', +/** + * With this setting is possible to reduce the languages available in the + * language chooser. The languages have to be set as array values using ISO_639-1 + * language codes such as ``en`` for English, ``de`` for German etc. + * + * For example: Set to ['de', 'fr'] to only allow German and French languages. + */ +'reduce_to_languages' => [], + /** * This sets the default region for phone numbers on your Nextcloud server, * using ISO 3166-1 country codes such as ``DE`` for Germany, ``FR`` for France, … diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php index 1825719fb750f..6b6dc5d3b4084 100644 --- a/lib/private/L10N/Factory.php +++ b/lib/private/L10N/Factory.php @@ -576,6 +576,10 @@ public function getLanguages(): array { } $languageCodes = $this->findAvailableLanguages(); + $reduceToLanguages = $this->config->getSystemValue('reduce_to_languages', []); + if (!empty($reduceToLanguages)) { + $languageCodes = array_intersect($languageCodes, $reduceToLanguages); + } $commonLanguages = []; $otherLanguages = []; diff --git a/tests/lib/L10N/FactoryTest.php b/tests/lib/L10N/FactoryTest.php index 771ce75d3e910..16113c0972f73 100644 --- a/tests/lib/L10N/FactoryTest.php +++ b/tests/lib/L10N/FactoryTest.php @@ -700,6 +700,53 @@ public function testRespectDefaultLanguage($lang, $defaultLanguage, $langExists, self::assertSame($expected, $result); } + public static function dataTestReduceToLanguages(): array { + return [ + ['en', ['en', 'de', 'fr', 'it', 'es'], ['en', 'fr', 'de'], ['en', 'fr', 'de']], + ['en', ['en', 'de', 'fr', 'it', 'es'], ['en', 'de'], ['en', 'de']], + ['en', ['en', 'de', 'fr', 'it', 'es'], [], ['de', 'en', 'es', 'fr', 'it']], + ]; + } + + /** + * test + * - if available languages set can be reduced by configuration + * - if available languages set is not reduced to an empty set if + * the reduce config is an empty set + * + * @dataProvider dataTestReduceToLanguages + * + * @param string $lang + * @param array $availableLanguages + * @param array $reducedLanguageSet + * @param array $expected + */ + public function testReduceLanguagesByConfiguration(string $lang, array $availableLanguages, array $reducedLanguageSet, array $expected): void { + $factory = $this->getFactory(['findAvailableLanguages', 'languageExists']); + $factory->expects(self::any()) + ->method('languageExists')->willReturn(true); + $factory->expects(self::any()) + ->method('findAvailableLanguages') + ->willReturnCallback(function ($app) use ($availableLanguages) { + return $availableLanguages; + }); + + $this->config + ->method('getSystemValue') + ->willReturnMap([ + ['force_language', false, false], + ['default_language', false, $lang], + ['reduce_to_languages', [], $reducedLanguageSet] + ]); + + $result = $this->invokePrivate($factory, 'getLanguages'); + $commonLanguagesCodes = array_map(function ($lang) { + return $lang['code']; + }, $result['commonLanguages']); + + self::assertEqualsCanonicalizing($expected, $commonLanguagesCodes); + } + public function languageIteratorRequestProvider():array { return [ [ true, $this->createMock(IUser::class)],