From 5f320e52c22f9c04b04119792b4e6f7d95f2595b Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Tue, 29 Nov 2022 19:49:19 +0100 Subject: [PATCH] [String] Fix AsciiSlugger with emojis --- .../Component/String/Slugger/AsciiSlugger.php | 25 ++++++++++++++++--- .../String/Tests/Slugger/AsciiSluggerTest.php | 11 ++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/String/Slugger/AsciiSlugger.php b/src/Symfony/Component/String/Slugger/AsciiSlugger.php index f4b44d3ac432b..826d07ca09e0c 100644 --- a/src/Symfony/Component/String/Slugger/AsciiSlugger.php +++ b/src/Symfony/Component/String/Slugger/AsciiSlugger.php @@ -113,10 +113,8 @@ public function slug(string $string, string $separator = '-', string $locale = n $transliterator = (array) $this->createTransliterator($locale); } - if (\is_string($this->emoji)) { - $transliterator[] = EmojiTransliterator::create("emoji-{$this->emoji}"); - } elseif ($this->emoji && null !== $locale) { - $transliterator[] = EmojiTransliterator::create("emoji-{$locale}"); + if ($emojiTransliterator = $this->createEmojiTransliterator($locale)) { + $transliterator[] = $emojiTransliterator; } if ($this->symbolsMap instanceof \Closure) { @@ -177,6 +175,25 @@ private function createTransliterator(string $locale): ?\Transliterator return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null; } + private function createEmojiTransliterator(?string $locale): ?EmojiTransliterator + { + if (\is_string($this->emoji)) { + $locale = $this->emoji; + } elseif (!$this->emoji) { + return null; + } + + while (null !== $locale) { + try { + return EmojiTransliterator::create("emoji-$locale"); + } catch (\IntlException) { + $locale = self::getParentLocale($locale); + } + } + + return null; + } + private static function getParentLocale(?string $locale): ?string { if (!$locale) { diff --git a/src/Symfony/Component/String/Tests/Slugger/AsciiSluggerTest.php b/src/Symfony/Component/String/Tests/Slugger/AsciiSluggerTest.php index 37eba92b60e14..163be0e7cadf3 100644 --- a/src/Symfony/Component/String/Tests/Slugger/AsciiSluggerTest.php +++ b/src/Symfony/Component/String/Tests/Slugger/AsciiSluggerTest.php @@ -49,6 +49,7 @@ public function provideSlugTests(): iterable /** * @dataProvider provideSlugEmojiTests + * * @requires extension intl */ public function testSlugEmoji(string $expected, string $string, ?string $locale, string|bool $emoji = true) @@ -94,5 +95,15 @@ public function provideSlugEmojiTests(): iterable 'en', 'github', ]; + yield [ + 'un-chat-qui-sourit-chat-noir-et-un-tete-de-lion-vont-au-parc-national', + 'un 😺, 🐈‍⬛, et un 🦁 vont au 🏞️', + 'fr_XX', // Fallback on parent locale + ]; + yield [ + 'un-et-un-vont-au', + 'un 😺, 🐈‍⬛, et un 🦁 vont au 🏞️', + 'undefined_locale', // Behaves the same as if emoji support is disabled + ]; } }