Made Inclector unicode-safe

This commit is contained in:
SilverFire - Dmitry Naumenko
2018-05-01 12:32:16 +03:00
parent 5a87dd2bfa
commit 629a33fd0e
2 changed files with 48 additions and 12 deletions

View File

@ -342,7 +342,7 @@ class BaseInflector
{
$words = static::humanize(static::underscore($words), $ucAll);
return $ucAll ? ucwords($words) : ucfirst($words);
return $ucAll ? mb_convert_case($words, MB_CASE_TITLE, self::encoding()) : self::mb_ucfirst($words, self::encoding());
}
/**
@ -357,7 +357,7 @@ class BaseInflector
*/
public static function camelize($word)
{
return str_replace(' ', '', ucwords(preg_replace('/[^A-Za-z0-9]+/', ' ', $word)));
return str_replace(' ', '', mb_convert_case(preg_replace('/[^\pL\pN]+/u', ' ', $word), MB_CASE_TITLE, self::encoding()));
}
/**
@ -373,9 +373,9 @@ class BaseInflector
'-',
'_',
'.',
], ' ', preg_replace('/(\p{Lu})/u', ' \0', $name))));
], ' ', preg_replace('/(\p{Lu})/u', ' \0', $name))), self::encoding());
return $ucwords ? mb_convert_case($label, MB_CASE_TITLE, 'UTF-8') : $label;
return $ucwords ? mb_convert_case($label, MB_CASE_TITLE, self::encoding()) : $label;
}
/**
@ -389,12 +389,12 @@ class BaseInflector
*/
public static function camel2id($name, $separator = '-', $strict = false)
{
$regex = $strict ? '/[A-Z]/' : '/(?<![A-Z])[A-Z]/';
$regex = $strict ? '/\p{Lu}/u' : '/(?<!\p{Lu})\p{Lu}/u';
if ($separator === '_') {
return strtolower(trim(preg_replace($regex, '_\0', $name), '_'));
return mb_strtolower(trim(preg_replace($regex, '_\0', $name), '_'), self::encoding());
}
return strtolower(trim(str_replace('_', $separator, preg_replace($regex, $separator . '\0', $name)), $separator));
return mb_strtolower(trim(str_replace('_', $separator, preg_replace($regex, $separator . '\0', $name)), $separator), self::encoding());
}
/**
@ -407,7 +407,7 @@ class BaseInflector
*/
public static function id2camel($id, $separator = '-')
{
return str_replace(' ', '', ucwords(str_replace($separator, ' ', $id)));
return str_replace(' ', '', mb_convert_case(str_replace($separator, ' ', $id), MB_CASE_TITLE, self::encoding()));
}
/**
@ -417,7 +417,7 @@ class BaseInflector
*/
public static function underscore($words)
{
return strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $words));
return mb_strtolower(preg_replace('/(?<=\\pL)(\\p{Lu})/u', '_\\1', $words), self::encoding());
}
/**
@ -429,8 +429,9 @@ class BaseInflector
public static function humanize($word, $ucAll = false)
{
$word = str_replace('_', ' ', preg_replace('/_id$/', '', $word));
$encoding = self::encoding();
return $ucAll ? ucwords($word) : ucfirst($word);
return $ucAll ? mb_convert_case($word, MB_CASE_TITLE, $encoding) : self::mb_ucfirst($word, $encoding);
}
/**
@ -446,7 +447,7 @@ class BaseInflector
{
$word = static::camelize($word);
return strtolower($word[0]) . substr($word, 1);
return mb_strtolower(mb_substr($word, 0, 1, self::encoding())) . mb_substr($word, 1, null, self::encoding());
}
/**
@ -599,4 +600,27 @@ class BaseInflector
return implode($connector, array_slice($words, 0, -1)) . $lastWordConnector . end($words);
}
}
/**
* @return string
*/
private static function encoding()
{
return isset(Yii::$app) ? Yii::$app->charset : 'UTF-8';
}
/**
* The same as built-in `ucfirst`, but unicode-safe
*
* @param $string
* @param $encoding
* @return string
*/
private static function mb_ucfirst($string, $encoding)
{
$firstChar = mb_substr($string, 0, 1, $encoding);
$rest = mb_substr($string, 1, null, $encoding);
return mb_strtoupper($firstChar, $encoding) . $rest;
}
}

View File

@ -84,17 +84,20 @@ class InflectorTest extends TestCase
{
$this->assertEquals('Me my self and i', Inflector::titleize('MeMySelfAndI'));
$this->assertEquals('Me My Self And I', Inflector::titleize('MeMySelfAndI', true));
$this->assertEquals('Треба Більше Тестів!', Inflector::titleize('ТребаБільшеТестів!', true));
}
public function testCamelize()
{
$this->assertEquals('MeMySelfAndI', Inflector::camelize('me my_self-andI'));
$this->assertEquals('MeMySelfAndi', Inflector::camelize('me my_self-andI'));
$this->assertEquals('QweQweEwq', Inflector::camelize('qwe qwe^ewq'));
$this->assertEquals('ВідомоЩоТестиЗберігатьНашіНерви', Inflector::camelize('Відомо, що тести зберігать наші НЕРВИ! 🙃'));
}
public function testUnderscore()
{
$this->assertEquals('me_my_self_and_i', Inflector::underscore('MeMySelfAndI'));
$this->assertEquals(ожний_тест_особливий', Inflector::underscore('КожнийТестОсобливий'));
}
public function testCamel2words()
@ -109,24 +112,31 @@ class InflectorTest extends TestCase
{
$this->assertEquals('post-tag', Inflector::camel2id('PostTag'));
$this->assertEquals('post_tag', Inflector::camel2id('PostTag', '_'));
$this->assertEquals('єдиний_код', Inflector::camel2id('ЄдинийКод', '_'));
$this->assertEquals('post-tag', Inflector::camel2id('postTag'));
$this->assertEquals('post_tag', Inflector::camel2id('postTag', '_'));
$this->assertEquals('єдиний_код', Inflector::camel2id('єдинийКод', '_'));
$this->assertEquals('foo-ybar', Inflector::camel2id('FooYBar', '-', false));
$this->assertEquals('foo_ybar', Inflector::camel2id('fooYBar', '_', false));
$this->assertEquals(евже_іце_працює', Inflector::camel2id('НевжеІЦеПрацює', '_', false));
$this->assertEquals('foo-y-bar', Inflector::camel2id('FooYBar', '-', true));
$this->assertEquals('foo_y_bar', Inflector::camel2id('fooYBar', '_', true));
$this->assertEquals('foo_y_bar', Inflector::camel2id('fooYBar', '_', true));
$this->assertEquals(евже_іе_працює', Inflector::camel2id('НевжеІЦеПрацює', '_', true));
}
public function testId2camel()
{
$this->assertEquals('PostTag', Inflector::id2camel('post-tag'));
$this->assertEquals('PostTag', Inflector::id2camel('post_tag', '_'));
$this->assertEquals('ЄдинийСвіт', Inflector::id2camel('єдиний_світ', '_'));
$this->assertEquals('PostTag', Inflector::id2camel('post-tag'));
$this->assertEquals('PostTag', Inflector::id2camel('post_tag', '_'));
$this->assertEquals('НевжеІЦеПрацює', Inflector::id2camel(евже_іе_працює', '_'));
$this->assertEquals('FooYBar', Inflector::id2camel('foo-y-bar'));
$this->assertEquals('FooYBar', Inflector::id2camel('foo_y_bar', '_'));
@ -136,11 +146,13 @@ class InflectorTest extends TestCase
{
$this->assertEquals('Me my self and i', Inflector::humanize('me_my_self_and_i'));
$this->assertEquals('Me My Self And I', Inflector::humanize('me_my_self_and_i', true));
$this->assertEquals('Але й веселі ці ваші тести', Inflector::humanize('але_й_веселііашіести'));
}
public function testVariablize()
{
$this->assertEquals('customerTable', Inflector::variablize('customer_table'));
$this->assertEquals('ひらがなHepimiz', Inflector::variablize('ひらがな_hepimiz'));
}
public function testTableize()