From 98d27a3d29a20127dbf065e9daebaf679d68cb76 Mon Sep 17 00:00:00 2001
From: Tim van Dijen <tvdijen@gmail.com>
Date: Mon, 12 Aug 2019 23:07:44 +0200
Subject: [PATCH] Fully typehint lib/Locale/*.php

---
 lib/SimpleSAML/Locale/Language.php     | 27 +++++++-------
 lib/SimpleSAML/Locale/Localization.php | 25 +++++++------
 lib/SimpleSAML/Locale/Translate.php    | 50 ++++++++++++++------------
 3 files changed, 54 insertions(+), 48 deletions(-)

diff --git a/lib/SimpleSAML/Locale/Language.php b/lib/SimpleSAML/Locale/Language.php
index 13cba995b..aa8133e65 100644
--- a/lib/SimpleSAML/Locale/Language.php
+++ b/lib/SimpleSAML/Locale/Language.php
@@ -19,7 +19,6 @@ use Webmozart\Assert\Assert;
 
 class Language
 {
-
     /**
      * This is the default language map. It is used to map languages codes from the user agent to other language codes.
      */
@@ -188,7 +187,7 @@ class Language
      *
      * @return string The language code.
      */
-    public function getPosixLanguage($language)
+    public function getPosixLanguage(string $language): string
     {
         if (isset($this->languagePosixMapping[$language])) {
             return $this->languagePosixMapping[$language];
@@ -204,7 +203,7 @@ class Language
      * @param boolean $setLanguageCookie Whether to set the language cookie or not. Defaults to true.
      * @return void
      */
-    public function setLanguage($language, $setLanguageCookie = true)
+    public function setLanguage(string $language, bool $setLanguageCookie = true): void
     {
         $language = strtolower($language);
         if (in_array($language, $this->availableLanguages, true)) {
@@ -224,7 +223,7 @@ class Language
      * @return string The language selected by the user according to the processing rules specified, or the default
      * language in any other case.
      */
-    public function getLanguage()
+    public function getLanguage(): string
     {
         // language is set in object
         if (isset($this->language)) {
@@ -264,7 +263,7 @@ class Language
      *
      * @return string|null The localized name of the language.
      */
-    public function getLanguageLocalizedName($code)
+    public function getLanguageLocalizedName(string $code): ?string
     {
         if (array_key_exists($code, self::$language_names) && isset(self::$language_names[$code])) {
             return self::$language_names[$code];
@@ -279,7 +278,7 @@ class Language
      *
      * @return string The language parameter name.
      */
-    public function getLanguageParameterName()
+    public function getLanguageParameterName(): string
     {
         return $this->languageParameterName;
     }
@@ -291,7 +290,7 @@ class Language
      * @return string|null The preferred language based on the Accept-Language HTTP header,
      * or null if none of the languages in the header is available.
      */
-    private function getHTTPLanguage()
+    private function getHTTPLanguage(): ?string
     {
         $languageScore = Utils\HTTP::getAcceptLanguage();
 
@@ -332,7 +331,7 @@ class Language
      *
      * @return string The default language that has been configured. Defaults to english if not configured.
      */
-    public function getDefaultLanguage()
+    public function getDefaultLanguage(): string
     {
         return $this->defaultLanguage;
     }
@@ -344,7 +343,7 @@ class Language
      * @param string $langcode
      * @return string|null The alias, or null if the alias was not found.
      */
-    public function getLanguageCodeAlias($langcode)
+    public function getLanguageCodeAlias(string $langcode): ?string
     {
         if (isset(self::$defaultLanguageMap[$langcode])) {
             return self::$defaultLanguageMap[$langcode];
@@ -360,7 +359,7 @@ class Language
      * @return array An array holding all the languages available as the keys of the array. The value for each key is
      * true in case that the language specified by that key is currently active, or false otherwise.
      */
-    public function getLanguageList()
+    public function getLanguageList(): array
     {
         $current = $this->getLanguage();
         $list = array_fill_keys($this->availableLanguages, false);
@@ -374,7 +373,7 @@ class Language
      *
      * @return boolean True if the language is right-to-left, false otherwise.
      */
-    public function isLanguageRTL()
+    public function isLanguageRTL(): bool
     {
         return in_array($this->getLanguage(), $this->rtlLanguages, true);
     }
@@ -385,7 +384,7 @@ class Language
      *
      * @return string|null The selected language or null if unset.
      */
-    public static function getLanguageCookie()
+    public static function getLanguageCookie(): ?string
     {
         $config = Configuration::getInstance();
         $availableLanguages = $config->getArray('language.available', ['en']);
@@ -409,10 +408,8 @@ class Language
      * @param string $language The language set by the user.
      * @return void
      */
-    public static function setLanguageCookie($language)
+    public static function setLanguageCookie(string $language): void
     {
-        Assert::string($language);
-
         $language = strtolower($language);
         $config = Configuration::getInstance();
         $availableLanguages = $config->getArray('language.available', ['en']);
diff --git a/lib/SimpleSAML/Locale/Localization.php b/lib/SimpleSAML/Locale/Localization.php
index a61d37010..03b8a6d83 100644
--- a/lib/SimpleSAML/Locale/Localization.php
+++ b/lib/SimpleSAML/Locale/Localization.php
@@ -116,7 +116,7 @@ class Localization
      *
      * @return string
      */
-    public function getLocaleDir()
+    public function getLocaleDir(): string
     {
         return $this->localeDir;
     }
@@ -129,7 +129,7 @@ class Localization
      *
      * @return string
      */
-    public function getDomainLocaleDir($domain)
+    public function getDomainLocaleDir(string $domain): string
     {
         /** @var string $base */
         $base = $this->configuration->resolvePath('modules');
@@ -146,7 +146,7 @@ class Localization
      * @param string $localeDir Absolute path if the module is housed elsewhere
      * @return void
      */
-    public function addModuleDomain($module, $localeDir = null)
+    public function addModuleDomain(string $module, string $localeDir = null): void
     {
         if (!$localeDir) {
             $localeDir = $this->getDomainLocaleDir($module);
@@ -163,13 +163,14 @@ class Localization
      * @param string $domain Domain at location
      * @return void
      */
-    public function addDomain($localeDir, $domain)
+    public function addDomain(string $localeDir, string $domain): void
     {
         $this->localeDomainMap[$domain] = $localeDir;
         Logger::debug("Localization: load domain '$domain' at '$localeDir'");
         $this->loadGettextGettextFromPO($domain);
     }
 
+
     /**
      * Get and check path of localization file
      *
@@ -178,7 +179,7 @@ class Localization
      *
      * @return string
      */
-    public function getLangPath($domain = self::DEFAULT_DOMAIN)
+    public function getLangPath(string $domain = self::DEFAULT_DOMAIN): string
     {
         $langcode = explode('_', $this->langcode);
         $langcode = $langcode[0];
@@ -221,7 +222,7 @@ class Localization
      * Setup the translator
      * @return void
      */
-    private function setupTranslator()
+    private function setupTranslator(): void
     {
         $this->translator = new Translator();
         $this->translator->register();
@@ -240,8 +241,10 @@ class Localization
      *
      * @throws \Exception If something is wrong with the locale file for the domain and activated language
      */
-    private function loadGettextGettextFromPO(string $domain = self::DEFAULT_DOMAIN, bool $catchException = true)
-    {
+    private function loadGettextGettextFromPO(
+        string $domain = self::DEFAULT_DOMAIN,
+         bool $catchException = true
+    ): void {
         try {
             $langPath = $this->getLangPath($domain);
         } catch (\Exception $e) {
@@ -273,7 +276,7 @@ class Localization
      *
      * @return bool
      */
-    public function isI18NBackendDefault()
+    public function isI18NBackendDefault(): bool
     {
         if ($this->i18nBackend === $this::SSP_I18N_BACKEND) {
             return true;
@@ -286,7 +289,7 @@ class Localization
      * Set up L18N if configured or fallback to old system
      * @return void
      */
-    private function setupL10N()
+    private function setupL10N(): void
     {
         if ($this->i18nBackend === self::SSP_I18N_BACKEND) {
             Logger::debug("Localization: using old system");
@@ -303,7 +306,7 @@ class Localization
      *
      * @return array
      */
-    public function getRegisteredDomains()
+    public function getRegisteredDomains(): array
     {
         return $this->localeDomainMap;
     }
diff --git a/lib/SimpleSAML/Locale/Translate.php b/lib/SimpleSAML/Locale/Translate.php
index d8a77a749..b706b99c8 100644
--- a/lib/SimpleSAML/Locale/Translate.php
+++ b/lib/SimpleSAML/Locale/Translate.php
@@ -61,7 +61,7 @@ class Translate
      * @param \SimpleSAML\Configuration $configuration Configuration object
      * @param string|null               $defaultDictionary The default dictionary where tags will come from.
      */
-    public function __construct(Configuration $configuration, $defaultDictionary = null)
+    public function __construct(Configuration $configuration, ?string $defaultDictionary = null)
     {
         $this->configuration = $configuration;
         $this->language = new Language($configuration);
@@ -82,16 +82,18 @@ class Translate
         }
     }
 
+
     /**
      * Return the internal language object used by this translator.
      *
      * @return \SimpleSAML\Locale\Language
      */
-    public function getLanguage()
+    public function getLanguage(): Language
     {
         return $this->language;
     }
 
+
     /**
      * This method retrieves a dictionary with the name given.
      *
@@ -119,6 +121,7 @@ class Translate
         return $this->dictionaries[$name];
     }
 
+
     /**
      * This method retrieves a tag as an array with language => string mappings.
      *
@@ -127,10 +130,8 @@ class Translate
      *
      * @return array|null An associative array with language => string mappings, or null if the tag wasn't found.
      */
-    public function getTag($tag)
+    public function getTag(string $tag): ?array
     {
-        Assert::string($tag);
-
         // first check translations loaded by the includeInlineTranslation and includeLanguageFile methods
         if (array_key_exists($tag, $this->langtext)) {
             return $this->langtext[$tag];
@@ -156,6 +157,7 @@ class Translate
         return $dictionary[$tag];
     }
 
+
     /**
      * Retrieve the preferred translation of a given text.
      *
@@ -165,10 +167,8 @@ class Translate
      *
      * @throws \Exception If there's no suitable translation.
      */
-    public function getPreferredTranslation($translations)
+    public function getPreferredTranslation(array $translations): string
     {
-        Assert::isArray($translations);
-
         // look up translation of tag in the selected language
         $selected_language = $this->language->getLanguage();
         if (array_key_exists($selected_language, $translations)) {
@@ -196,6 +196,7 @@ class Translate
         throw new \Exception('Nothing to return from translation.');
     }
 
+
     /**
      * Translate the name of an attribute.
      *
@@ -203,7 +204,7 @@ class Translate
      *
      * @return string The translated attribute name, or the original attribute name if no translation was found.
      */
-    public function getAttributeTranslation($name)
+    public function getAttributeTranslation(string $name): string
     {
         // normalize attribute name
         $normName = strtolower($name);
@@ -228,6 +229,7 @@ class Translate
         return $name;
     }
 
+
     /**
      * Mark a string for translation without translating it.
      *
@@ -235,7 +237,7 @@ class Translate
      *
      * @return string The tag, unchanged.
      */
-    public static function noop($tag)
+    public static function noop(string $tag): string
     {
         return $tag;
     }
@@ -250,7 +252,7 @@ class Translate
      *
      * @return string The string that should be used, or the tag name if $fallbacktag is set to false.
      */
-    private function getStringNotTranslated(string $tag, bool $fallbacktag)
+    private function getStringNotTranslated(string $tag, bool $fallbacktag): string
     {
         if ($fallbacktag) {
             return 'not translated (' . $tag . ')';
@@ -259,6 +261,7 @@ class Translate
         }
     }
 
+
     /**
      * Include a translation inline instead of putting translations in dictionaries. This function is recommended to be
      * used ONLY for variable data, or when the translation is already provided by an external source, as a database
@@ -270,7 +273,7 @@ class Translate
      * @throws \Exception If $translation is neither a string nor an array.
      * @return void
      */
-    public function includeInlineTranslation($tag, $translation)
+    public function includeInlineTranslation(string $tag, $translation): void
     {
         if (is_string($translation)) {
             $translation = ['en' => $translation];
@@ -284,6 +287,7 @@ class Translate
         $this->langtext[$tag] = $translation;
     }
 
+
     /**
      * Include a language file from the dictionaries directory.
      *
@@ -294,7 +298,7 @@ class Translate
      * null.
      * @return void
      */
-    public function includeLanguageFile($file, $otherConfig = null)
+    public function includeLanguageFile(string $file, Configuration $otherConfig = null): void
     {
         if (!empty($otherConfig)) {
             $filebase = $otherConfig->getPathValue('dictionarydir', 'dictionaries/');
@@ -308,6 +312,7 @@ class Translate
         $this->langtext = array_merge($this->langtext, $lang);
     }
 
+
     /**
      * Read a dictionary file in JSON format.
      *
@@ -340,6 +345,7 @@ class Translate
         return $lang;
     }
 
+
     /**
      * Read a dictionary file in PHP format.
      *
@@ -361,6 +367,7 @@ class Translate
         return [];
     }
 
+
     /**
      * Read a dictionary file.
      *
@@ -388,6 +395,7 @@ class Translate
         return [];
     }
 
+
     /**
      * Translate a singular text.
      *
@@ -395,7 +403,7 @@ class Translate
      *
      * @return string The translated string.
      */
-    public static function translateSingularGettext($original)
+    public static function translateSingularGettext(string $original): string
     {
         $text = BaseTranslator::$current->gettext($original);
 
@@ -408,6 +416,7 @@ class Translate
         return strtr($text, is_array($args[0]) ? $args[0] : $args);
     }
 
+
     /**
      * Translate a plural text.
      *
@@ -417,7 +426,7 @@ class Translate
      *
      * @return string The translated string.
      */
-    public static function translatePluralGettext($original, $plural, $value)
+    public static function translatePluralGettext(string $original, string $plural, string $value): string
     {
         $text = BaseTranslator::$current->ngettext($original, $plural, $value);
 
@@ -430,6 +439,7 @@ class Translate
         return strtr($text, is_array($args[0]) ? $args[0] : $args);
     }
 
+
     /**
      * Pick a translation from a given array of translations for the current language.
      *
@@ -441,17 +451,13 @@ class Translate
      * @return null|string The translation appropriate for the current language, or null if none found. If the
      * $context or $translations arrays are null, or $context['currentLanguage'] is not defined, null is also returned.
      */
-    public static function translateFromArray($context, $translations)
+    public static function translateFromArray(?array $context, ?array $translations): ?string
     {
         if (!is_array($translations)) {
             return null;
-        }
-
-        if (!is_array($context) || !isset($context['currentLanguage'])) {
+        } elseif (!is_array($context) || !isset($context['currentLanguage'])) {
             return null;
-        }
-
-        if (isset($translations[$context['currentLanguage']])) {
+        } elseif (isset($translations[$context['currentLanguage']])) {
             return $translations[$context['currentLanguage']];
         }
 
-- 
GitLab