[Intl] Add polyfill for Locale::canonicalize()
MODIFY
Locale/Locale.php
Locale/Locale.php
@@ -16,8 +16,8 @@ use Symfony\Component\Intl\Exception\MethodNotImplementedException;
/**
* Replacement for PHP's native {@link \Locale} class.
*
- * The only method supported in this class is {@link getDefault}. This method
- * will always return "en". All other methods will throw an exception when used.
+ * The only methods supported in this class are `getDefault` and `canonicalize`.
+ * All other methods will throw an exception when used.
*
* @author Eriksen Costa <eriksen.costa@infranology.com.br>
* @author Bernhard Schussek <bschussek@gmail.com>
@@ -57,6 +57,39 @@ class Locale
throw new MethodNotImplementedException(__METHOD__);
}
+ /**
+ * Returns a canonicalized locale string.
+ *
+ * This polyfill doesn't implement the full-spec algorithm. It only
+ * canonicalizes locale strings handled by the `LocaleBundle` class.
+ *
+ * @param string $locale
+ *
+ * @return string
+ */
+ public static function canonicalize($locale)
+ {
+ $locale = (string) $locale;
+
+ if ('' === $locale || '.' === $locale[0]) {
+ return self::getDefault();
+ }
+
+ if (!preg_match('/^([a-z]{2})[-_]([a-z]{2})(?:([a-z]{2})(?:[-_]([a-z]{2}))?)?(?:\..*)?$/i', $locale, $m)) {
+ return $locale;
+ }
+
+ if (!empty($m[4])) {
+ return strtolower($m[1]).'_'.ucfirst(strtolower($m[2].$m[3])).'_'.strtoupper($m[4]);
+ }
+
+ if (!empty($m[3])) {
+ return strtolower($m[1]).'_'.ucfirst(strtolower($m[2].$m[3]));
+ }
+
+ return strtolower($m[1]).'_'.strtoupper($m[2]);
+ }
+
/**
* Not supported. Returns a correctly ordered and delimited locale code.
*

MODIFY
Tests/Locale/LocaleTest.php
Tests/Locale/LocaleTest.php
@@ -21,6 +21,17 @@ class LocaleTest extends AbstractLocaleTest
$this->call('acceptFromHttp', 'pt-br,en-us;q=0.7,en;q=0.5');
}
+ public function testCanonicalize()
+ {
+ $this->assertSame('en', $this->call('canonicalize', ''));
+ $this->assertSame('en', $this->call('canonicalize', '.utf8'));
+ $this->assertSame('fr_FR', $this->call('canonicalize', 'FR-fr'));
+ $this->assertSame('fr_FR', $this->call('canonicalize', 'FR-fr.utf8'));
+ $this->assertSame('uz_Latn', $this->call('canonicalize', 'UZ-lATN'));
+ $this->assertSame('uz_Cyrl_UZ', $this->call('canonicalize', 'UZ-cYRL-uz'));
+ $this->assertSame('123', $this->call('canonicalize', 123));
+ }
+
/**
* @expectedException \Symfony\Component\Intl\Exception\MethodNotImplementedException
*/

[Intl] Add polyfill for Locale::canonicalize()