X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=application%2FUtils.php;h=5c077450e3a65016f55b0ede559dad4552b47e2b;hb=2008098574b2c5e308058414b426977068ade08d;hp=35d652241bb6a5a4c42c7ded7b7381be48dc7f15;hpb=a0df06517bada0f811b464017ce385290e02c2bf;p=github%2Fshaarli%2FShaarli.git diff --git a/application/Utils.php b/application/Utils.php index 35d65224..5c077450 100644 --- a/application/Utils.php +++ b/application/Utils.php @@ -216,20 +216,63 @@ function is_session_id_valid($sessionId) function autoLocale($headerLocale) { // Default if browser does not send HTTP_ACCEPT_LANGUAGE - $attempts = array('en_US'); - if (isset($headerLocale)) { - // (It's a bit crude, but it works very well. Preferred language is always presented first.) - if (preg_match('/([a-z]{2})-?([a-z]{2})?/i', $headerLocale, $matches)) { - $loc = $matches[1] . (!empty($matches[2]) ? '_' . strtoupper($matches[2]) : ''); - $attempts = array( - $loc.'.UTF-8', $loc, str_replace('_', '-', $loc).'.UTF-8', str_replace('_', '-', $loc), - $loc . '_' . strtoupper($loc).'.UTF-8', $loc . '_' . strtoupper($loc), - $loc . '_' . $loc.'.UTF-8', $loc . '_' . $loc, $loc . '-' . strtoupper($loc).'.UTF-8', - $loc . '-' . strtoupper($loc), $loc . '-' . $loc.'.UTF-8', $loc . '-' . $loc - ); + $locales = array('en_US', 'en_US.utf8', 'en_US.UTF-8'); + if (! empty($headerLocale)) { + if (preg_match_all('/([a-z]{2,3})[-_]?([a-z]{2})?,?/i', $headerLocale, $matches, PREG_SET_ORDER)) { + $attempts = []; + foreach ($matches as $match) { + $first = [strtolower($match[1]), strtoupper($match[1])]; + $separators = ['_', '-']; + $encodings = ['utf8', 'UTF-8']; + if (!empty($match[2])) { + $second = [strtoupper($match[2]), strtolower($match[2])]; + $items = [$first, $separators, $second, ['.'], $encodings]; + } else { + $items = [$first, $separators, $first, ['.'], $encodings]; + } + $attempts = array_merge($attempts, iterator_to_array(cartesian_product_generator($items))); + } + + if (! empty($attempts)) { + $locales = array_merge(array_map('implode', $attempts), $locales); + } + } + } + + setlocale(LC_ALL, $locales); +} + +/** + * Build a Generator object representing the cartesian product from given $items. + * + * Example: + * [['a'], ['b', 'c']] + * will generate: + * [ + * ['a', 'b'], + * ['a', 'c'], + * ] + * + * @param array $items array of array of string + * + * @return Generator representing the cartesian product of given array. + * + * @see https://en.wikipedia.org/wiki/Cartesian_product + */ +function cartesian_product_generator($items) +{ + if (empty($items)) { + yield []; + } + $subArray = array_pop($items); + if (empty($subArray)) { + return; + } + foreach (cartesian_product_generator($items) as $item) { + foreach ($subArray as $value) { + yield $item + [count($item) => $value]; } } - setlocale(LC_ALL, $attempts); } /** @@ -270,3 +313,33 @@ function normalize_spaces($string) { return preg_replace('/\s{2,}/', ' ', trim($string)); } + +/** + * Format the date according to the locale. + * + * Requires php-intl to display international datetimes, + * otherwise default format '%c' will be returned. + * + * @param DateTime $date to format. + * @param bool $intl Use international format if true. + * + * @return bool|string Formatted date, or false if the input is invalid. + */ +function format_date($date, $intl = true) +{ + if (! $date instanceof DateTime) { + return false; + } + + if (! $intl || ! class_exists('IntlDateFormatter')) { + return strftime('%c', $date->getTimestamp()); + } + + $formatter = new IntlDateFormatter( + setlocale(LC_TIME, 0), + IntlDateFormatter::LONG, + IntlDateFormatter::LONG + ); + + return $formatter->format($date); +}