Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 916a8cf

Browse filesBrowse files
jontjsnicolas-grekas
authored andcommitted
[String] Make AsciiSlugger fallback to parent locale's symbolsMap
1 parent c335e07 commit 916a8cf
Copy full SHA for 916a8cf

File tree

3 files changed

+66
-6
lines changed
Filter options

3 files changed

+66
-6
lines changed

‎src/Symfony/Component/String/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/String/CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.3
5+
---
6+
7+
* Made `AsciiSlugger` fallback to parent locale's symbolsMap
8+
49
5.2.0
510
-----
611

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/String/Slugger/AsciiSlugger.php
+30-6Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ public function slug(string $string, string $separator = '-', string $locale = n
111111
}
112112

113113
if ($this->symbolsMap instanceof \Closure) {
114+
// If the symbols map is passed as a closure, there is no need to fallback to the parent locale
115+
// as the closure can just provide substitutions for all locales of interest.
114116
$symbolsMap = $this->symbolsMap;
115117
array_unshift($transliterator, static function ($s) use ($symbolsMap, $locale) {
116118
return $symbolsMap($s, $locale);
@@ -119,9 +121,20 @@ public function slug(string $string, string $separator = '-', string $locale = n
119121

120122
$unicodeString = (new UnicodeString($string))->ascii($transliterator);
121123

122-
if (\is_array($this->symbolsMap) && isset($this->symbolsMap[$locale])) {
123-
foreach ($this->symbolsMap[$locale] as $char => $replace) {
124-
$unicodeString = $unicodeString->replace($char, ' '.$replace.' ');
124+
if (\is_array($this->symbolsMap)) {
125+
$map = null;
126+
if (isset($this->symbolsMap[$locale])) {
127+
$map = $this->symbolsMap[$locale];
128+
} else {
129+
$parent = self::getParentLocale($locale);
130+
if ($parent && isset($this->symbolsMap[$parent])) {
131+
$map = $this->symbolsMap[$parent];
132+
}
133+
}
134+
if ($map) {
135+
foreach ($map as $char => $replace) {
136+
$unicodeString = $unicodeString->replace($char, ' '.$replace.' ');
137+
}
125138
}
126139
}
127140

@@ -143,17 +156,28 @@ private function createTransliterator(string $locale): ?\Transliterator
143156
}
144157

145158
// Locale not supported and no parent, fallback to any-latin
146-
if (false === $str = strrchr($locale, '_')) {
159+
if (!$parent = self::getParentLocale($locale)) {
147160
return $this->transliterators[$locale] = null;
148161
}
149162

150163
// Try to use the parent locale (ie. try "de" for "de_AT") and cache both locales
151-
$parent = substr($locale, 0, -\strlen($str));
152-
153164
if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$parent] ?? null) {
154165
$transliterator = \Transliterator::create($id.'/BGN') ?? \Transliterator::create($id);
155166
}
156167

157168
return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null;
158169
}
170+
171+
private static function getParentLocale(?string $locale): ?string
172+
{
173+
if (!$locale) {
174+
return null;
175+
}
176+
if (false === $str = strrchr($locale, '_')) {
177+
// no parent locale
178+
return null;
179+
}
180+
181+
return substr($locale, 0, -\strlen($str));
182+
}
159183
}

‎src/Symfony/Component/String/Tests/SluggerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/String/Tests/SluggerTest.php
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,37 @@ public function testSlugCharReplacementLocaleMethod()
6565
$this->assertSame('yo_y_tu_a_esta_direccion_slug_en_senal_test_es', $slug);
6666
}
6767

68+
public function testSlugCharReplacementLocaleConstructWithoutSymbolsMap()
69+
{
70+
$slugger = new AsciiSlugger('en');
71+
$slug = (string) $slugger->slug('you & me with this address slug@test.uk', '_');
72+
73+
$this->assertSame('you_and_me_with_this_address_slug_at_test_uk', $slug);
74+
}
75+
76+
public function testSlugCharReplacementParentLocaleConstructWithoutSymbolsMap()
77+
{
78+
$slugger = new AsciiSlugger('en_GB');
79+
$slug = (string) $slugger->slug('you & me with this address slug@test.uk', '_');
80+
81+
$this->assertSame('you_and_me_with_this_address_slug_at_test_uk', $slug);
82+
}
83+
84+
public function testSlugCharReplacementParentLocaleConstruct()
85+
{
86+
$slugger = new AsciiSlugger('fr_FR', ['fr' => ['&' => 'et', '@' => 'chez']]);
87+
$slug = (string) $slugger->slug('toi & moi avec cette adresse slug@test.fr', '_');
88+
89+
$this->assertSame('toi_et_moi_avec_cette_adresse_slug_chez_test_fr', $slug);
90+
}
91+
92+
public function testSlugCharReplacementParentLocaleMethod()
93+
{
94+
$slugger = new AsciiSlugger(null, ['es' => ['&' => 'y', '@' => 'en senal']]);
95+
$slug = (string) $slugger->slug('yo & tu a esta dirección slug@test.es', '_', 'es_ES');
96+
$this->assertSame('yo_y_tu_a_esta_direccion_slug_en_senal_test_es', $slug);
97+
}
98+
6899
public function testSlugClosure()
69100
{
70101
$slugger = new AsciiSlugger(null, function ($s, $locale) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.