Skip to content

Commit 1931e87

Browse files
feature #47264 [String] Add support for emoji in AsciiSlugger (lyrixx)
This PR was merged into the 6.2 branch. Discussion ---------- [String] Add support for emoji in AsciiSlugger | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | | License | MIT | Doc PR | Usage ```php use Symfony\Component\String\Slugger\AsciiSlugger; $slugger = new AsciiSlugger(); $slugger = $slugger->withEmoji(); $slugger->slug('a 😺, 🐈‍⬛, and a 🦁 go to 🏞️... 😍 🎉 💛', '-', 'en'); // a-grinning-cat-black-cat-and-a-lion-go-to-national-park-smiling-face-with-heart-eyes-party-popper-yellow-heart $slugger->slug('un 😺, 🐈‍⬛, et un 🦁 vont au 🏞️'); // un-chat-qui-sourit-chat-noir-et-un-tete-de-lion-vont-au-parc-national ``` Commits ------- ab20db7 [String] Add support for emoji in AsciiSlugger
2 parents 6aed124 + ab20db7 commit 1931e87

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
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: 25 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|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 ($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

Lines changed: 54 additions & 3 deletions
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,52 @@ 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+
* @requires extension intl
53+
*/
54+
public function testSlugEmoji(string $expected, string $string, ?string $locale, string|bool $emoji = true)
4255
{
4356
$slugger = new AsciiSlugger();
57+
$slugger = $slugger->withEmoji($emoji);
4458

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

src/Symfony/Component/String/composer.json

Lines changed: 1 addition & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy