/** * Recursively check locale fallbacks for cycles. * * @param map<string, PhutilLocale> Map of locales. * @param PhutilLocale Current locale. * @param map<string, string> Map of visited locales. * @return void */ private static function checkLocaleFallback(array $map, PhutilLocale $locale, array $seen) { $fallback_code = $locale->getFallbackLocaleCode(); if ($fallback_code === null) { return; } if (isset($seen[$fallback_code])) { $seen[] = get_class($locale); $seen[] = pht('...'); throw new Exception(pht('Locale "%s" is part of a cycle of locales which fall back on ' . 'one another in a loop (%s). Locales which fall back on other ' . 'locales must not loop.', get_class($locale), implode(' -> ', $seen))); } $seen[$fallback_code] = get_class($locale); self::checkLocaleFallback($map, $map[$fallback_code], $seen); }