Skip to content

Commit

Permalink
[String] allow translit rules to be given as closure
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-grekas committed Sep 15, 2020
1 parent 82a2cb8 commit 15b391c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
4 changes: 3 additions & 1 deletion AbstractUnicodeString.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static function fromCodePoints(int ...$codes): self
*
* Install the intl extension for best results.
*
* @param string[]|\Transliterator[] $rules See "*-Latin" rules from Transliterator::listIDs()
* @param string[]|\Transliterator[]|\Closure[] $rules See "*-Latin" rules from Transliterator::listIDs()
*/
public function ascii(array $rules = []): self
{
Expand Down Expand Up @@ -107,6 +107,8 @@ public function ascii(array $rules = []): self

if ($rule instanceof \Transliterator) {
$s = $rule->transliterate($s);
} elseif ($rule instanceof \Closure) {
$s = $rule($s);
} elseif ($rule) {
if ('nfd' === $rule = strtolower($rule)) {
normalizer_is_normalized($s, self::NFD) ?: $s = normalizer_normalize($s, self::NFD);
Expand Down
18 changes: 16 additions & 2 deletions Slugger/AsciiSlugger.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,15 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
*/
private $transliterators = [];

public function __construct(string $defaultLocale = null, array $symbolsMap = null)
/**
* @param array|\Closure|null $symbolsMap
*/
public function __construct(string $defaultLocale = null, $symbolsMap = null)
{
if (null !== $symbolsMap && !\is_array($symbolsMap) && !$symbolsMap instanceof \Closure) {
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be array, Closure or null, "%s" given.', __METHOD__, \gettype($symbolMap)));
}

$this->defaultLocale = $defaultLocale;
$this->symbolsMap = $symbolsMap ?? $this->symbolsMap;
}
Expand Down Expand Up @@ -103,9 +110,16 @@ public function slug(string $string, string $separator = '-', string $locale = n
$transliterator = (array) $this->createTransliterator($locale);
}

if ($this->symbolsMap instanceof \Closure) {
$symbolsMap = $this->symbolsMap;
array_unshift($transliterator, static function ($s) use ($symbolsMap, $locale) {
return $symbolsMap($s, $locale);
});
}

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

if (isset($this->symbolsMap[$locale])) {
if (\is_array($this->symbolsMap) && isset($this->symbolsMap[$locale])) {
foreach ($this->symbolsMap[$locale] as $char => $replace) {
$unicodeString = $unicodeString->replace($char, ' '.$replace.' ');
}
Expand Down
10 changes: 10 additions & 0 deletions Tests/AbstractUnicodeTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ public function testAscii()
$this->assertSame('Dieser Wert sollte groesser oder gleich', (string) $s->ascii(['de-ASCII']));
}

public function testAsciiClosureRule()
{
$rule = function ($c) {
return str_replace('', 'OE', $c);
};

$s = static::createFromString('Dieser Wert sollte größer oder gleich');
$this->assertSame('Dieser Wert sollte grOEsser oder gleich', (string) $s->ascii([$rule]));
}

public function provideCreateFromCodePoint(): array
{
return [
Expand Down
11 changes: 11 additions & 0 deletions Tests/SluggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,15 @@ public function testSlugCharReplacementLocaleMethod()
$slug = (string) $slugger->slug('yo & tu a esta dirección [email protected]', '_', 'es');
$this->assertSame('yo_y_tu_a_esta_direccion_slug_en_senal_test_es', $slug);
}

public function testSlugClosure()
{
$slugger = new AsciiSlugger(null, function ($s, $locale) {
$this->assertSame('foo', $locale);

return str_replace('❤️', 'love', $s);
});

$this->assertSame('love', (string) $slugger->slug('❤️', '-', 'foo'));
}
}

0 comments on commit 15b391c

Please sign in to comment.