+ * Sniff browser language to set the locale automatically.
+ * Note that is may not work on your server if the corresponding locale is not installed.
+ *
+ * @param string $headerLocale Locale send in HTTP headers (e.g. "fr,fr-fr;q=0.8,en;q=0.5,en-us;q=0.3").
+ **/
+function autoLocale($headerLocale)
+{
+ // Default if browser does not send HTTP_ACCEPT_LANGUAGE
+ $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.