Skip to content

Commit

Permalink
Add Text::slug().
Browse files Browse the repository at this point in the history
  • Loading branch information
ADmad committed Mar 14, 2016
1 parent d6aa467 commit acc48a3
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 3 deletions.
27 changes: 27 additions & 0 deletions src/Utility/Text.php
Expand Up @@ -852,4 +852,31 @@ public static function parseFileSize($size, $default = false)
}
throw new InvalidArgumentException('No unit type.');
}

/**
* Returns a string with all spaces converted to dashes (by default), accented
* characters converted to non-accented characters, and non word characters removed.
*
* @param string $string the string you want to slug
* @param array $options Options
* @return string
*/
public static function slug($string, $options = [])
{
$options += [
'replacement' => '-',
'transliteratorId' => 'Any-Latin; Latin-ASCII'
];

$quotedReplacement = preg_quote($options['replacement'], '/');
$map = [
'/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
'/[\s\p{Zs}]+/mu' => $options['replacement'],
sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
];

$string = preg_replace(array_keys($map), array_values($map), $string);

return transliterator_transliterate($options['transliteratorId'], $string);
}
}
9 changes: 6 additions & 3 deletions src/Utility/composer.json
Expand Up @@ -4,10 +4,13 @@
"license": "MIT",
"authors": [
{
"name": "CakePHP Community",
"homepage": "http://cakephp.org"
}
"name": "CakePHP Community",
"homepage": "http://cakephp.org"
}
],
"suggest": {
"ext-intl": "To use Text::slug()."
},
"autoload": {
"psr-4": {
"Cake\\Utility\\": "."
Expand Down
81 changes: 81 additions & 0 deletions tests/TestCase/Utility/TextTest.php
Expand Up @@ -1588,4 +1588,85 @@ public function filesizes()
[['size' => '2VB', 'default' => 'Unknown type'], 'Unknown type']
];
}

public function slugInputProvider()
{
return [
[
'Foo Bar: Not just for breakfast any-more', [],
'Foo-Bar-Not-just-for-breakfast-any-more'
],
[
'Foo Bar: Not just for breakfast any-more', ['replacement' => '_'],
'Foo_Bar_Not_just_for_breakfast_any_more'
],
[
'Foo Bar: Not just for breakfast any-more', ['replacement' => '+'],
'Foo+Bar+Not+just+for+breakfast+any+more'
],
[
'Äpfel Über Öl grün ärgert groß öko', [],
'Aepfel-Ueber-Oel-gruen-aergert-gross-oeko'
],
[
'The truth - and- more- news', [],
'The-truth-and-more-news'
],
[
'The truth: and more news', [],
'The-truth-and-more-news'
],
[
'La langue française est un attribut de souveraineté en France', [],
'La-langue-francaise-est-un-attribut-de-souverainete-en-France'
],
[
'!@$#exciting stuff! - what !@-# was that?', [],
'exciting-stuff-what-was-that'
],
[
'20% of profits went to me!', [],
'20-of-profits-went-to-me'
],
[
'#this melts your face1#2#3', [],
'this-melts-your-face1-2-3'
],
[
'controller/action/りんご/1', [],
'controller-action-りんご-1'
],
[
'の話が出たので大丈夫かなあと', [],
'の話が出たので大丈夫かなあと'
],
[
'posts/view/한국어/page:1/sort:asc', [],
'posts-view-한국어-page-1-sort-asc'
],
[
"non\xc2\xa0breaking\xc2\xa0space", [],
'non-breaking-space'
],
[
'Foo Bar: Not just for breakfast any-more', ['replacement' => ''],
'FooBarNotjustforbreakfastanymore'
],
];
}

/**
* testSlug method
*
* @param string $string String
* @param array $options Options
* @param String $expected Exepected string
* @return void
* @dataProvider slugInputProvider
*/
public function testSlug($string, $options, $expected)
{
$result = Text::slug($string, $options);
$this->assertEquals($expected, $result);
}
}

0 comments on commit acc48a3

Please sign in to comment.