Skip to content

Commit f78a0a4

Browse files
committed
[String] Add support for emoji in AsciiSlugger
1 parent 2e87d30 commit f78a0a4

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

src/Symfony/Component/String/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.2
5+
---
6+
7+
* Add support for emoji in `AsciiSlugger`
8+
49
5.4
510
---
611

src/Symfony/Component/String/Slugger/AsciiSlugger.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\String\Slugger;
1313

14+
use Symfony\Component\Intl\Transliterator\EmojiTransliterator;
1415
use Symfony\Component\String\AbstractUnicodeString;
1516
use Symfony\Component\String\UnicodeString;
1617
use Symfony\Contracts\Translation\LocaleAwareInterface;
@@ -58,6 +59,7 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
5859
private \Closure|array $symbolsMap = [
5960
'en' => ['@' => 'at', '&' => 'and'],
6061
];
62+
private bool $enableEmoji = false;
6163

6264
/**
6365
* Cache of transliterators per locale.
@@ -88,6 +90,14 @@ public function getLocale(): string
8890
return $this->defaultLocale;
8991
}
9092

93+
public function enableEmoji(bool $enableEmoji = true): void
94+
{
95+
if (!class_exists(EmojiTransliterator::class)) {
96+
throw new \LogicException(sprintf('You cannot use the "%s()" as the "symfony/intl" package is not installed. Try running "composer require symfony/intl".', __METHOD__));
97+
}
98+
$this->enableEmoji = $enableEmoji;
99+
}
100+
91101
/**
92102
* {@inheritdoc}
93103
*/
@@ -103,6 +113,10 @@ public function slug(string $string, string $separator = '-', string $locale = n
103113
$transliterator = (array) $this->createTransliterator($locale);
104114
}
105115

116+
if ($this->enableEmoji) {
117+
$transliterator[] = EmojiTransliterator::create($locale);
118+
}
119+
106120
if ($this->symbolsMap instanceof \Closure) {
107121
// If the symbols map is passed as a closure, there is no need to fallback to the parent locale
108122
// as the closure can just provide substitutions for all locales of interest.

src/Symfony/Component/String/Tests/Slugger/AsciiSluggerTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,27 @@ public function testSlug(string $expected, string $string, string $separator = '
4444

4545
$this->assertSame($expected, (string) $slugger->slug($string, $separator, $locale));
4646
}
47+
48+
public function provideSlugEmojiTests(): iterable
49+
{
50+
yield [
51+
'un-chat-qui-sourit-chat-noir-et-un-tete-de-lion-vont-au-parc-national',
52+
'un 😺, 🐈‍⬛, et un 🦁 vont au 🏞️',
53+
'fr',
54+
];
55+
yield [
56+
'a-grinning-cat-black-cat-and-a-lion-go-to-national-park-smiling-face-with-heart-eyes-party-popper-yellow-heart',
57+
'a 😺, 🐈‍⬛, and a 🦁 go to 🏞️... 😍 🎉 💛',
58+
'en',
59+
];
60+
}
61+
62+
/** @dataProvider provideSlugEmojiTests */
63+
public function testSlugEmoji(string $expected, string $string, string $locale)
64+
{
65+
$slugger = new AsciiSlugger();
66+
$slugger->enableEmoji();
67+
68+
$this->assertSame($expected, (string) $slugger->slug($string, '-', $locale));
69+
}
4770
}

0 commit comments

Comments
 (0)