8000 feature #38198 [String] allow translit rules to be given as closure (… · symfony/symfony@9c8cd08 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9c8cd08

Browse files
committed
feature #38198 [String] allow translit rules to be given as closure (nicolas-grekas)
This PR was merged into the 5.2-dev branch. Discussion ---------- [String] allow translit rules to be given as closure | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #35061 | License | MIT | Doc PR | - Instead of trying to fix #35061 at our level, I propose to add a hook so that ppl can use a transliterator that fits their need (eg voku/portable-ascii or behat/transliterator) while still relying on the `SluggerInterface`. Commits ------- 0bb48df [String] allow translit rules to be given as closure
2 parents 2973d30 + 0bb48df commit 9c8cd08

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

src/Symfony/Component/String/AbstractUnicodeString.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public static function fromCodePoints(int ...$codes): self
7777
*
7878
* Install the intl extension for best results.
7979
*
80-
* @param string[]|\Transliterator[] $rules See "*-Latin" rules from Transliterator::listIDs()
80+
* @param string[]|\Transliterator[]|\Closure[] $rules See "*-Latin" rules from Transliterator::listIDs()
8181
*/
8282
public function ascii(array $rules = []): self
8383
{
@@ -107,6 +107,8 @@ public function ascii(array $rules = []): self
107107

108108
if ($rule instanceof \Transliterator) {
109109
$s = $rule->transliterate($s);
110+
} elseif ($rule instanceof \Closure) {
111+
$s = $rule($s);
110112
} elseif ($rule) {
111113
if ('nfd' === $rule = strtolower($rule)) {
112114
normalizer_is_normalized($s, self::NFD) ?: $s = normalizer_normalize($s, self::NFD);

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,15 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
6666
*/
6767
private $transliterators = [];
6868

69-
public function __construct(string $defaultLocale = null, array $symbolsMap = null)
69+
/**
70+
* @param array|\Closure|null $symbolsMap
71+
*/
72+
public function __construct(string $defaultLocale = null, $symbolsMap = null)
7073
{
74+
if (null !== $symbolsMap && !\is_array($symbolsMap) && !$symbolsMap instanceof \Closure) {
75+
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be array, Closure or null, "%s" given.', __METHOD__, \gettype($symbolMap)));
76+
}
77+
7178
$this->defaultLocale = $defaultLocale;
7279
$this->symbolsMap = $symbolsMap ?? $this->symbolsMap;
7380
}
@@ -103,9 +110,16 @@ public function slug(string $string, string $separator = '-', string $locale = n
103110
$transliterator = (array) $this->createTransliterator($locale);
104111
}
105112

113+
if ($this->symbolsMap instanceof \Closure) {
114+
$symbolsMap = $this->symbolsMap;
115+
array_unshift($transliterator, static function ($s) use ($symbolsMap, $locale) {
116+
return $symbolsMap($s, $locale);
117+
});
118+
}
119+
106120
$unicodeString = (new UnicodeString($string))->ascii($transliterator);
107121

108-
if (isset($this->symbolsMap[$locale])) {
122+
if (\is_array($this->symbolsMap) && isset($this->symbolsMap[$locale])) {
109123
foreach ($this->symbolsMap[$locale] as $char => $replace) {
110124
$unicodeString = $unicodeString->replace($char, ' '.$replace.' ');
111125
}

src/Symfony/Component/String/Tests/AbstractUnicodeTestCase.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ public function testAscii()
2020
$this->assertSame('Dieser Wert sollte groesser oder gleich', (string) $s->ascii(['de-ASCII']));
2121
}
2222

23+
public function testAsciiClosureRule()
24+
{
25+
$rule = function ($c) {
26+
return str_replace('', 'OE', $c);
27+
};
28+
29+
$s = static::createFromString('Dieser Wert sollte größer oder gleich');
30+
$this->assertSame('Dieser Wert sollte grOEsser oder gleich', (string) $s->ascii([$rule]));
31+
}
32+
2333
public function provideCreateFromCodePoint(): array
2434
{
2535
return [

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,15 @@ public function testSlugCharReplacementLocaleMethod()
6464
$slug = (string) $slugger->slug('yo & tu a esta dirección slug@test.es', '_', 'es');
6565
$this->assertSame('yo_y_tu_a_esta_direccion_slug_en_senal_test_es', $slug);
6666
}
67+
68+
public function testSlugClosure()
69+
{
70+
$slugger = new AsciiSlugger(null, function ($s, $locale) {
71+
$this->assertSame('foo', $locale);
72+
73+
return str_replace('❤️', 'love', $s);
74+
});
75+
76+
$this->assertSame('love', (string) $slugger->slug('❤️', '-', 'foo'));
77+
}
6778
}

0 commit comments

Comments
 (0)
0