Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d7b891a

Browse files
committed
[String] Add support for emoji in AsciiSlugger
1 parent 68fe153 commit d7b891a

File tree

4 files changed

+84
-3
lines changed

4 files changed

+84
-3
lines changed

src/Symfony/Component/String/CHANGELOG.md

+5
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

+25
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|string $emoji = false;
6163

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

93+
/**
94+
* @param bool|string $emoji true will use the same locale,
95+
* false will disable emoji,
96+
* and a string to use a specific locale
97+
*/
98+
public function withEmoji(bool|string $emoji = true): static
99+
{
100+
if (false !== $emoji && !class_exists(EmojiTransliterator::class)) {
101+
throw new \LogicException(sprintf('You cannot use the "%s()" method as the "symfony/intl" package is not installed. Try running "composer require symfony/intl".', __METHOD__));
102+
}
103+
104+
$new = clone $this;
105+
$new->emoji = $emoji;
106+
107+
return $new;
108+
}
109+
91110
/**
92111
* {@inheritdoc}
93112
*/
@@ -103,6 +122,12 @@ public function slug(string $string, string $separator = '-', string $locale = n
103122
$transliterator = (array) $this->createTransliterator($locale);
104123
}
105124

125+
if (\is_string($this->emoji)) {
126+
$transliterator[] = EmojiTransliterator::create("emoji-{$this->emoji}");
127+
} elseif (true === $this->emoji && null !== $locale) {
128+
$transliterator[] = EmojiTransliterator::create("emoji-{$locale}");
129+
}
130+
106131
if ($this->symbolsMap instanceof \Closure) {
107132
// If the symbols map is passed as a closure, there is no need to fallback to the parent locale
108133
// as the closure can just provide substitutions for all locales of interest.

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

+53-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@
1616

1717
class AsciiSluggerTest extends TestCase
1818
{
19+
/**
20+
* @dataProvider provideSlugTests
21+
*/
22+
public function testSlug(string $expected, string $string, string $separator = '-', string $locale = null)
23+
{
24+
$slugger = new AsciiSlugger();
25+
26+
$this->assertSame($expected, (string) $slugger->slug($string, $separator, $locale));
27+
}
28+
1929
public function provideSlugTests(): iterable
2030
{
2131
yield ['', ''];
@@ -37,11 +47,51 @@ public function provideSlugTests(): iterable
3747
yield [\function_exists('transliterator_transliterate') ? 'gh' : '', 'ғ', '-', 'uz_fr']; // Ensure we get the parent locale
3848
}
3949

40-
/** @dataProvider provideSlugTests */
41-
public function testSlug(string $expected, string $string, string $separator = '-', string $locale = null)
50+
/**
51+
* @dataProvider provideSlugEmojiTests
52+
*/
53+
public function testSlugEmoji(string $expected, string $string, ?string $locale, string|bool $emoji = true)
4254
{
4355
$slugger = new AsciiSlugger();
56+
$slugger = $slugger->withEmoji($emoji);
4457

45-
$this->assertSame($expected, (string) $slugger->slug($string, $separator, $locale));
58+
$this->assertSame($expected, (string) $slugger->slug($string, '-', $locale));
59+
}
60+
61+
public function provideSlugEmojiTests(): iterable
62+
{
63+
yield [
64+
'un-chat-qui-sourit-chat-noir-et-un-tete-de-lion-vont-au-parc-national',
65+
'un 😺, 🐈‍⬛, et un 🦁 vont au 🏞️',
66+
'fr',
67+
];
68+
yield [
69+
'a-grinning-cat-black-cat-and-a-lion-go-to-national-park-smiling-face-with-heart-eyes-party-popper-yellow-heart',
70+
'a 😺, 🐈‍⬛, and a 🦁 go to 🏞️... 😍 🎉 💛',
71+
'en',
72+
];
73+
yield [
74+
'a-and-a-go-to',
75+
'a 😺, 🐈‍⬛, and a 🦁 go to 🏞️... 😍 🎉 💛',
76+
null,
77+
];
78+
yield [
79+
'a-smiley-cat-black-cat-and-a-lion-face-go-to-national-park-heart-eyes-tada-yellow-heart',
80+
'a 😺, 🐈‍⬛, and a 🦁 go to 🏞️... 😍 🎉 💛',
81+
null,
82+
'slack',
83+
];
84+
yield [
85+
'a-smiley-cat-black-cat-and-a-lion-go-to-national-park-heart-eyes-tada-yellow-heart',
86+
'a 😺, 🐈‍⬛, and a 🦁 go to 🏞️... 😍 🎉 💛',
87+
null,
88+
'github',
89+
];
90+
yield [
91+
'a-smiley-cat-black-cat-and-a-lion-go-to-national-park-heart-eyes-tada-yellow-heart',
92+
'a 😺, 🐈‍⬛, and a 🦁 go to 🏞️... 😍 🎉 💛',
93+
'en',
94+
'github',
95+
];
4696
}
4797
}

src/Symfony/Component/String/composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
},
2525
"require-dev": {
2626
"symfony/error-handler": "^5.4|^6.0",
27+
"symfony/intl": "^6.2",
2728
"symfony/http-client": "^5.4|^6.0",
2829
"symfony/translation-contracts": "^2.0|^3.0",
2930
"symfony/var-exporter": "^5.4|^6.0"

0 commit comments

Comments
 (0)