diff --git a/composer.json b/composer.json index a85f901f..ecf58a9c 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "laravelcollective/html": "^6.0", "nunomaduro/collision": "^5.0", "symfony/yaml": "^5.4", - "ext-json": "*" + "ext-json": "*", + "ext-intl": "*" }, "require-dev": { "filp/whoops": "~2.0", diff --git a/database/seeders/SettingsSeeder.php b/database/seeders/SettingsSeeder.php index 913ad112..f9e1046d 100644 --- a/database/seeders/SettingsSeeder.php +++ b/database/seeders/SettingsSeeder.php @@ -7,9 +7,45 @@ use App\SettingGroup; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; +use Locale; class SettingsSeeder extends Seeder { + + /** + * @return false|string + */ + public static function getSupportedLanguageMap() + { + if (! class_exists('Locale')) { + Log::info('PHP Extension Intl not found. Falling back to English language support only.'); + return json_encode(['en' => 'English']); + } + + $languageDirectories = array_filter(glob(resource_path().'/lang/*'), 'is_dir'); + $result = []; + + foreach ($languageDirectories as $languageDirectory) { + $language = self::getLanguageFromDirectory($languageDirectory); + $resultNative = mb_convert_case(Locale::getDisplayLanguage($language.'-', $language), MB_CASE_TITLE, 'UTF-8'); + $resultEn = ucfirst(Locale::getDisplayLanguage($language, 'en')); + $result[$language] = "$resultNative ($resultEn)"; + } + + return json_encode($result); + } + + /** + * @param $languageDirectory + * @return false|string[] + */ + public static function getLanguageFromDirectory($languageDirectory) + { + $directories = explode('/', $languageDirectory); + + return $directories[array_key_last($directories)]; + } + /** * Run the database seeds. * @@ -124,20 +160,8 @@ class SettingsSeeder extends Seeder $setting->save(); } - $language_options = json_encode([ - 'de' => 'Deutsch (German)', - 'en' => 'English', - 'cn' => '简体中文 (Simplified Chinese)', - 'fi' => 'Suomi (Finnish)', - 'fr' => 'Français (French)', - 'el' => 'Ελληνικά (Greek)', - 'it' => 'Italiano (Italian)', - 'no' => 'Norsk (Norwegian)', - 'pl' => 'Polski (Polish)', - 'sv' => 'Svenska (Swedish)', - 'es' => 'Español (Spanish)', - 'tr' => 'Türkçe (Turkish)', - ]); + $language_options = SettingsSeeder::getSupportedLanguageMap(); + if ($languages = Setting::find(5)) { $languages->options = $language_options; $languages->save(); diff --git a/readme.md b/readme.md index e7af1249..8e9d8edd 100644 --- a/readme.md +++ b/readme.md @@ -34,7 +34,7 @@ Supported applications are recognized by the title of the application as entered [![foundationapps](https://img.shields.io/badge/dynamic/json.svg?label=Foundation%20Apps&url=https%3A%2F%2Fapps.heimdall.site%2Fstats&query=foundation_apps&colorB=3f8483&style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAjCAMAAACw/5reAAAAnFBMVEUAAADu7u7u7u7u7u7u7u7x8fHu7u7u7u7u7u7u7u7u7u7u7u7r6+vu7u7v7+/u7u7t7e3v7+/v7+/u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7+/u7u7p6ent7e3v7+/v7+/v7+/u7u7u7u7u7u7u7u7t7e3////u7u7u7u7u7u7u7u7w8PDw8PDt7e3u7u7t7e3s7Ozu7u7t7e3u7u4TnCP6AAAAM3RSTlMA+9n3phHw3czC088M5Y5zG6mflWdJFumyfj4sB2NeTi7hiWlDOQPGt5lsMiG9hFQntpFqxQJtAAABnElEQVQoz2WRh3KrQAxFtYWO6ZhucItrynv6/3/LFnA24c6wurpnYBkJZvXduNix6+GXTo8qWnxUPU4m2w0O1ktTozPsftiZpejGlm7C2MWUnRcWOohIo36+PaKyDZdLUOgDXvqQfaT9kwkfvP3AN18E7Kl8hkJHMHSXSSadxaTtTNjJhMkfjFHKMqGlolg4T7mtCbcq8gBCotxkwklFLIQSlQoTHnVWQqzNxYQuzpfmqGVMc5ijHK5yAuIhxbZ5p/S92RZkjv5BKs6aosSIr0JrcXBo1FtICVINKRKK6u0GnraoN84O5KbhjRwYzxCJnQCMtotkdNxjq2F7dJ2RoGuXIBTvc3ROthdmat6hZ7cOyfcxKGV+wTxBkxQxTQTzWOFny/7qS2nzx37T7nbtZj9xu7zUr/323nVy0sQnhwMJktSZrl5v7CjgSQmWi+haUCY8sH4tyc/FGSKGouS+WqBJm8U2NIE/+nLu2tzpF/xVNGy02QzRClafC/ysVpDzQJuA8xXsKl8bv+pgpXz57H9Yy3J1lQNY62wUrW+mdzrylWS0QwAAAABJRU5ErkJggg==)](https://apps.heimdall.site/applications/foundation) ## Installing -Apart from the Laravel 8 dependencies, namely PHP >= 7.3.0, BCMath PHP Extension, Ctype PHP Extension, Fileinfo PHP extension, JSON PHP Extension, Mbstring PHP Extension, OpenSSL PHP Extension, PDO PHP Extension, Tokenizer PHP Extension, XML PHP Extension, the only other thing Heimdall needs is sqlite support and zip support (php-zip). +Apart from the Laravel 8 dependencies, namely PHP >= 7.3.0, BCMath PHP Extension, INTL PHP Extension, Ctype PHP Extension, Fileinfo PHP extension, JSON PHP Extension, Mbstring PHP Extension, OpenSSL PHP Extension, PDO PHP Extension, Tokenizer PHP Extension, XML PHP Extension, the only other thing Heimdall needs is sqlite support and zip support (php-zip). If you find you can't change the background make sure `php_fileinfo` is enabled in your php.ini. I believe it should be by default, but one user came across the issue on a windows system. @@ -84,15 +84,26 @@ When you are finished, create a pull request. Currently added languages are - English +- Breton +- Danish - German +- Greek +- Spanish - Finnish - French -- Swedish -- Spanish -- Turkish +- Hungarian +- Italian +- Korean +- Lombard +- Dutch +- Norwegian +- Polish +- Portuguese - Russian +- Slovenian +- Swedish +- Turkish - Chinese -- Português ## Web Server Configuration diff --git a/resources/lang/hu/app.php b/resources/lang/hu/app.php index 20d90d5f..dd745353 100644 --- a/resources/lang/hu/app.php +++ b/resources/lang/hu/app.php @@ -11,8 +11,10 @@ return [ 'settings.system' => 'Rendszer', 'settings.appearance' => 'Megjelenés', - 'settings.miscellaneous' => 'Miscellaneous', - 'settings.support' => 'Támogatás', + 'settings.miscellaneous' => 'Egyéb', + 'settings.advanced' => 'Haladó', + + 'settings.support' => 'Segítség', 'settings.donate' => 'Adomány', 'settings.version' => 'Verzió', @@ -22,7 +24,7 @@ return [ 'settings.window_target.one' => 'Azonos lapon', 'settings.window_target.new' => 'Új lapon', 'settings.homepage_search' => 'Kezdő oldal kereső', - 'settings.search_provider' => 'Alapértelmezett kereső motor ', + 'settings.search_provider' => 'Alapértelmezett kereső motor', 'settings.language' => 'Nyelv', 'settings.reset' => 'Alapértelmezetek visszaállítása', 'settings.remove' => 'Eltávolítás', @@ -34,6 +36,9 @@ return [ 'settings.edit' => 'Módosítás', 'settings.view' => 'Megtekintés', + 'settings.custom_css' => 'Egyéni CSS', + 'settings.custom_js' => 'Egyéni JavaScript', + 'options.none' => '- nincs beállítva -', 'options.google' => 'Google', 'options.ddg' => 'DuckDuckGo', @@ -45,13 +50,13 @@ return [ 'options.nzbhydra' => 'NZBHydra', 'options.jackett' => 'Jackett', - 'buttons.save' => 'Mentás', + 'buttons.save' => 'Mentés', 'buttons.cancel' => 'Mégsem', 'buttons.add' => 'Hozzáadás', 'buttons.upload' => 'Ikon feltöltése', 'buttons.downloadapps' => 'Alkalmazás lista frissítése', - 'dash.pin_item' => 'Kitőzés kezdő képernyőre', + 'dash.pin_item' => 'Kitűzés kezdő képernyőre', 'dash.no_apps' => 'Jelenleg nincsenek kitűzött alkalmazások, :link1 or :link2', 'dash.link1' => 'Alkalmazás hozzáadása', 'dash.link2' => 'Elem kitűzése kezdőképernyőre', @@ -78,6 +83,11 @@ return [ 'apps.override' => 'Eltérő URL alkaplazása.', 'apps.preview' => 'Előnézet', 'apps.apptype' => 'Alkalmazás Típus', + 'apps.website' => 'Weboldal', + 'apps.description' => 'Leírás', + 'apps.only_admin_account' => 'Csak admin hozzáféréssel!', + 'apps.autologin_url' => 'Autómatikus belépés URL', + 'apps.show_deleted' => 'Törölt alkalmazások mutatása', 'dashboard' => 'Kezdőképernyő', diff --git a/resources/lang/hu/auth.php b/resources/lang/hu/auth.php index fbbe13d7..0cd0c5a6 100644 --- a/resources/lang/hu/auth.php +++ b/resources/lang/hu/auth.php @@ -13,7 +13,7 @@ return [ | */ - 'failed' => 'Hitelesítő adat nem egyezik.', - 'throttle' => 'Túl sok hibás bejelentkezési kísérlet, Próbálja újra :seconds seconds.', + 'failed' => 'Belépési adatok nem egyeznek.', + 'throttle' => 'Túl sok hibás bejelentkezési kísérlet, Próbálja újra :seconds másodperc múlva.', ]; diff --git a/resources/lang/lmo/app.php b/resources/lang/lmo/app.php index 897d70c2..a72f6792 100644 --- a/resources/lang/lmo/app.php +++ b/resources/lang/lmo/app.php @@ -34,11 +34,11 @@ return [ 'settings.window_target.current' => 'In quella scheda chi', - 'settings.window_target.one' => 'In l'istessa scheda', + 'settings.window_target.one' => 'In l\'istessa scheda', - 'settings.window_target.new' => 'In d'una scheda noeuva', + 'settings.window_target.new' => 'In d\'una scheda noeuva', - 'settings.homepage_search' => 'Ricerca in l'home page', + 'settings.homepage_search' => 'Ricerca in l\'home page', 'settings.search_provider' => 'Provider de default', @@ -90,17 +90,17 @@ return [ 'buttons.add' => 'Sgionta', - 'buttons.upload' => 'Carega 'n icona', + 'buttons.upload' => 'Carega \'n icona', 'buttons.downloadapps' => 'Descarega la lista di app', - 'dash.pin_item' => 'Taca su l'oget', + 'dash.pin_item' => 'Taca su l\'oget', - 'dash.no_apps' => 'Ghe n'è minga de app tacade su, :link1 o :link2', + 'dash.no_apps' => 'Ghe n\'è minga de app tacade su, :link1 o :link2', - 'dash.link1' => 'Met 'n aplicazzion chi', + 'dash.link1' => 'Met \'n aplicazzion chi', - 'dash.link2' => 'Taca su 'n oget', + 'dash.link2' => 'Taca su \'n oget', 'dash.pinned_items' => 'Oget tacad su', @@ -110,7 +110,7 @@ return [ 'apps.add_application' => 'Sgionta aplicazzion', - 'apps.application_name' => 'Nom de l'aplicazzion', + 'apps.application_name' => 'Nom de l\'aplicazzion', 'apps.colour' => 'Color', @@ -140,7 +140,7 @@ return [ 'apps.tags' => 'Tag', - 'apps.override' => 'Se divers de l'url principal', + 'apps.override' => 'Se divers de l\'url principal', 'apps.preview' => 'Varda prima', @@ -150,7 +150,7 @@ return [ 'apps.description' => 'Descrizzion', - 'apps.only_admin_account' => 'Domà se te gh'heet un cunt admin!', + 'apps.only_admin_account' => 'Domà se te gh\'heet un cunt admin!', 'apps.autologin_url' => 'Auto login url', @@ -172,7 +172,7 @@ return [ 'user.secure_front' => 'Fà entra del front - El fonziona domà cont una password.', - 'user.autologin' => 'Permet el login de 'n ciar URL. Tucc quèi che ghe l'hann poden entrà.', + 'user.autologin' => 'Permet el login de \'n ciar URL. Tucc quèi che ghe l\'hann poden entrà.', 'url' => 'URL', @@ -202,9 +202,9 @@ return [ 'alert.success.tag_restored' => 'Tag ripescad', - 'alert.success.setting_updated' => 'L'impostazzion l'è stada mudada', + 'alert.success.setting_updated' => 'L\'impostazzion l\'è stada mudada', - 'alert.error.not_exist' => 'Quella impostazzion chi la gh'è no.', + 'alert.error.not_exist' => 'Quella impostazzion chi la gh\'è no.', 'alert.success.user_created' => 'Utent fad su', diff --git a/resources/lang/cn/app.php b/resources/lang/zh/app.php similarity index 100% rename from resources/lang/cn/app.php rename to resources/lang/zh/app.php diff --git a/resources/lang/cn/auth.php b/resources/lang/zh/auth.php similarity index 100% rename from resources/lang/cn/auth.php rename to resources/lang/zh/auth.php diff --git a/resources/lang/cn/pagination.php b/resources/lang/zh/pagination.php similarity index 100% rename from resources/lang/cn/pagination.php rename to resources/lang/zh/pagination.php diff --git a/resources/lang/cn/passwords.php b/resources/lang/zh/passwords.php similarity index 100% rename from resources/lang/cn/passwords.php rename to resources/lang/zh/passwords.php diff --git a/resources/lang/cn/validation.php b/resources/lang/zh/validation.php similarity index 100% rename from resources/lang/cn/validation.php rename to resources/lang/zh/validation.php diff --git a/tests/Unit/ExampleTest.php b/tests/Unit/ExampleTest.php deleted file mode 100644 index 266ef352..00000000 --- a/tests/Unit/ExampleTest.php +++ /dev/null @@ -1,19 +0,0 @@ -assertTrue(true); - } -} diff --git a/tests/Unit/database/seeders/SettingsSeederTest.php b/tests/Unit/database/seeders/SettingsSeederTest.php new file mode 100644 index 00000000..af054eed --- /dev/null +++ b/tests/Unit/database/seeders/SettingsSeederTest.php @@ -0,0 +1,23 @@ +assertTrue(count($languageMap) === count($languageDirectories)); + } +} diff --git a/tests/Unit/lang/LangTest.php b/tests/Unit/lang/LangTest.php new file mode 100644 index 00000000..671fba73 --- /dev/null +++ b/tests/Unit/lang/LangTest.php @@ -0,0 +1,48 @@ +markTestSkipped('2022-11-14 Lot of keys missing. Enable this test to see them all.'); + $languageDirectories = array_filter(glob(resource_path().'/lang/*'), 'is_dir'); + + $enLanguageDirectory = array_values(array_filter($languageDirectories, function($v) { + return substr($v, -2) === 'en'; + }))[0]; + $notENLanguageDirectories = array_filter($languageDirectories, function ($v) { + return substr($v, -2) !== 'en'; + }); + + $enLanguageKeys = require_once($enLanguageDirectory.'/app.php'); + $missingKeys = []; + + foreach ($notENLanguageDirectories as $langDirectory) { + $testingLangKeys = require_once($langDirectory . '/app.php'); + + foreach ($enLanguageKeys as $langKey => $langValue) { + if (!array_key_exists($langKey, $testingLangKeys)) { + if(!isset($missingKeys[$langDirectory])) { + $missingKeys[$langDirectory] = []; + } + $missingKeys[$langDirectory][] = $langKey; + } + } + } + + if (count($missingKeys) > 0) { + print_r(json_encode($missingKeys)); + } + + $this->assertEmpty($missingKeys); + } +}