Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to make filters work with Unicode text #3376

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 54 additions & 23 deletions system/src/Grav/Common/Inflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,16 @@ public static function singularize($word, $count = 1)
*/
public static function titleize($word, $uppercase = '')
{
$uppercase = $uppercase === 'first' ? 'ucfirst' : 'ucwords';

return $uppercase(static::humanize(static::underscorize($word)));
$replacement = preg_replace('/(\p{Lu}\p{Ll})/u', ' \1', $word); /* Me -> Me */
$replacement = preg_replace('/(\p{Ll})(\p{Lu})/u', '\1 \2', $replacement); /* eM -> e M */
$replacement = preg_replace('/(\p{N})(\p{L})/u', '\1 \2', $replacement); /* 1a -> 1 a (any case) */
$replacement = preg_replace('/(\p{L})(\p{N})/u', '\1 \2', $replacement); /* a1 -> a 1 (any case) */
$replacement = preg_replace('/[^\p{L}\p{N}]/u', ' ', $replacement); /* if not a letter or a number replace with a space */
$replacement = preg_replace('/( )\1+/', ' ', $replacement); /* remove repeating spaces */
$replacement = trim($replacement, ' ');
$replacement = mb_convert_case($replacement, MB_CASE_TITLE, "UTF-8"); /* title case words */

return $replacement;
}

/**
Expand All @@ -180,7 +187,11 @@ public static function titleize($word, $uppercase = '')
*/
public static function camelize($word)
{
return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word)));
$replacement = preg_replace('/[^\p{L}\p{N}]+/u', ' ', $word); /* replace every non-alphanumeric character with a space */
$replacement = mb_convert_case($replacement, MB_CASE_TITLE, "UTF-8"); /* title case words */
$replacement = str_replace(' ', '', $replacement); /* remove spaces */

return $replacement;
}

/**
Expand All @@ -196,11 +207,16 @@ public static function camelize($word)
*/
public static function underscorize($word)
{
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $word);
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1_\2', $regex1);
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '_', $regex2);

return strtolower($regex3);
$replacement = preg_replace('/(\p{Lu}\p{Ll})/u', '_\1', $word); /* Me -> _Me */
$replacement = preg_replace('/(\p{Ll})(\p{Lu})/u', '\1_\2', $replacement); /* eM -> e_M */
$replacement = preg_replace('/(\p{N})(\p{L})/u', '\1_\2', $replacement); /* 1a -> 1_a (any case) */
$replacement = preg_replace('/(\p{L})(\p{N})/u', '\1_\2', $replacement); /* a1 -> a_1 (any case) */
$replacement = preg_replace('/[^\p{L}\p{N}]/u', '_', $replacement); /* if not a letter or a number replace with a '_' */
$replacement = preg_replace('/(_)\1+/', '_', $replacement); /* remove repeating '_'s */
$replacement = trim($replacement, '_');
$replacement = mb_strtolower ($replacement);

return $replacement;
}

/**
Expand All @@ -216,14 +232,16 @@ public static function underscorize($word)
*/
public static function hyphenize($word)
{
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word);
$regex2 = preg_replace('/([a-z])([A-Z])/', '\1-\2', $regex1);
$regex3 = preg_replace('/([0-9])([A-Z])/', '\1-\2', $regex2);
$regex4 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex3);

$regex4 = trim($regex4, '-');

return strtolower($regex4);
$replacement = preg_replace('/(\p{Lu}\p{Ll})/u', '-\1', $word); /* Me -> -Me */
$replacement = preg_replace('/(\p{Ll})(\p{Lu})/u', '\1-\2', $replacement); /* eM -> e-M */
$replacement = preg_replace('/(\p{N})(\p{L})/u', '\1-\2', $replacement); /* 1a -> 1-a (any case) */
$replacement = preg_replace('/(\p{L})(\p{N})/u', '\1-\2', $replacement); /* a1 -> a-1 (any case) */
$replacement = preg_replace('/[^\p{L}\p{N}]/u', '-', $replacement); /* if not a letter or a number replace with a '-' */
$replacement = preg_replace('/(-)\1+/', '-', $replacement); /* remove repeating '-'s */
$replacement = trim($replacement, '-');
$replacement = mb_strtolower ($replacement);

return $replacement;
}

/**
Expand All @@ -244,12 +262,20 @@ public static function hyphenize($word)
*/
public static function humanize($word, $uppercase = '')
{
$uppercase = $uppercase === 'all' ? 'ucwords' : 'ucfirst';

return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word)));
$replacement = preg_replace('/[^\p{L}\p{N}]/u', ' ', $word); /* if not a letter or a number replace with a space */
$strlen = mb_strlen($replacement);
$firstChar = mb_substr($replacement, 0, 1);
$then = mb_substr($replacement, 1, $strlen - 1);
$then = mb_strtolower ($then);
$replacement = mb_strtoupper($firstChar) . $then;

return $replacement;
}

/**
*
* WARNING: This function is currently not in use in Twig filters and is a candidate for removal
*
* Same as camelize but first char is underscored
*
* Converts a word like "send_email" to "sendEmail". It
Expand All @@ -263,9 +289,14 @@ public static function humanize($word, $uppercase = '')
*/
public static function variablize($word)
{
$word = static::camelize($word);

return strtolower($word[0]) . substr($word, 1);
$replacement = static::camelize($word);

$strlen = mb_strlen($replacement);
$firstChar = mb_substr($replacement, 0, 1);
$then = mb_substr($replacement, 1, $strlen - 1);
$replacement = mb_strtolower($firstChar) . $then;

return $replacement;
}

/**
Expand Down