Skip to content

Commit 3eb8b35

Browse files
authored
feat(support): add slug, ascii and isAscii to string utils (#1040)
1 parent 1d4f563 commit 3eb8b35

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"symfony/var-dumper": "^7.1",
3535
"symfony/var-exporter": "^7.1",
3636
"tempest/highlight": "^2.11.2",
37-
"vlucas/phpdotenv": "^5.6"
37+
"vlucas/phpdotenv": "^5.6",
38+
"voku/portable-ascii": "^2.0.3"
3839
},
3940
"require-dev": {
4041
"aidan-casey/mock-client": "dev-master",

src/Tempest/Support/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"php": "^8.4",
88
"doctrine/inflector": "^2.0",
99
"tempest/container": "dev-main",
10-
"tempest/highlight": "^2.11.2"
10+
"tempest/highlight": "^2.11.2",
11+
"voku/portable-ascii": "^2.0.3"
1112
},
1213
"autoload": {
1314
"psr-4": {

src/Tempest/Support/src/Str/ManipulatesString.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,34 @@ public function camel(): static
177177
return $this->createOrModify(to_camel_case($this->value));
178178
}
179179

180+
/**
181+
* Converts the current string to an URL-safe slug.
182+
*
183+
* @param bool $replaceSymbols Adds some more replacements e.g. "£" with "pound".
184+
*/
185+
public function slug(Stringable|string $separator = '-', array $replacements = [], bool $replaceSymbols = true): static
186+
{
187+
return $this->createOrModify(to_slug($this->value, $separator, $replacements, $replaceSymbols));
188+
}
189+
190+
/**
191+
* Transliterates the current string to ASCII. Invalid characters are replaced with their closest counterpart.
192+
*
193+
* @param string $language Language of the source string. Defaults to english.
194+
*/
195+
public function ascii(Stringable|string $language = 'en'): static
196+
{
197+
return $this->createOrModify(to_ascii($this->value, $language));
198+
}
199+
200+
/**
201+
* Asserts whether the instance is an ASCII string.
202+
*/
203+
public function isAscii(): bool
204+
{
205+
return is_ascii($this->value);
206+
}
207+
180208
/**
181209
* Replaces consecutive instances of a given character with a single character.
182210
*/

src/Tempest/Support/src/Str/functions.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Countable;
88
use Stringable;
99
use Tempest\Support\Language;
10+
use voku\helper\ASCII;
1011

1112
use function levenshtein as php_levenshtein;
1213
use function metaphone as php_metaphone;
@@ -89,6 +90,34 @@ function to_camel_case(Stringable|string $string): string
8990
return lcfirst(to_pascal_case((string) $string));
9091
}
9192

93+
/**
94+
* Converts the given string to an URL-safe slug.
95+
*
96+
* @param bool $replaceSymbols Adds some more replacements e.g. "£" with "pound".
97+
*/
98+
function to_slug(Stringable|string $string, Stringable|string $separator = '-', array $replacements = [], bool $replaceSymbols = true): string
99+
{
100+
return ASCII::to_slugify((string) $string, (string) $separator, replacements: $replacements, replace_extra_symbols: $replaceSymbols);
101+
}
102+
103+
/**
104+
* Transliterates the given string to ASCII.
105+
*
106+
* @param string $language Language of the source string. Defaults to english.
107+
*/
108+
function to_ascii(Stringable|string $string, Stringable|string $language = 'en'): string
109+
{
110+
return ASCII::to_ascii((string) $string, (string) $language, replace_single_chars_only: false);
111+
}
112+
113+
/**
114+
* Checks whether the given string is valid ASCII.
115+
*/
116+
function is_ascii(Stringable|string $string): bool
117+
{
118+
return ASCII::is_ascii((string) $string);
119+
}
120+
92121
/**
93122
* Converts the given string to its English plural form.
94123
*/

src/Tempest/Support/tests/Str/ManipulatesStringTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,4 +663,41 @@ public function test_basename(): void
663663
$this->assertSame('file', str('file.txt')->basename('.txt')->toString());
664664
$this->assertSame('', str()->basename()->toString());
665665
}
666+
667+
public function test_ascii(): void
668+
{
669+
$this->assertSame('@', str('@')->ascii()->toString());
670+
$this->assertSame('u', str('ü')->ascii()->toString());
671+
$this->assertSame('', str('')->ascii()->toString());
672+
$this->assertSame('a!2e', str('a!2ë')->ascii()->toString());
673+
}
674+
675+
public function test_slug(): void
676+
{
677+
$this->assertSame('hello-world', str('hello world')->slug()->toString());
678+
$this->assertSame('hello-world', str('hello-world')->slug()->toString());
679+
$this->assertSame('hello-world', str('hello_world')->slug()->toString());
680+
$this->assertSame('hello_world', str('hello_world')->slug(separator: '_')->toString());
681+
$this->assertSame('user-at-host', str('user@host')->slug()->toString());
682+
$this->assertSame('slam-dnya', str('سلام دنیا')->slug(separator: '-')->toString());
683+
$this->assertSame('sometext', str('some text')->slug(separator: '')->toString());
684+
$this->assertSame('', str()->slug(separator: '')->toString());
685+
$this->assertSame('bsm-allh', str('بسم الله')->slug(separator: '-', replacements: ['allh' => 'allah'])->toString());
686+
$this->assertSame('500-dollar-bill', str('500$ bill')->slug('-', replaceSymbols: true)->toString());
687+
$this->assertSame('500-bill', str('500$ bill')->slug('-', replaceSymbols: false)->toString());
688+
$this->assertSame('500-dollar-bill', str('500--$----bill')->slug(separator: '-')->toString());
689+
$this->assertSame('500-dollar-bill', str('500-$-bill')->slug(separator: '-')->toString());
690+
$this->assertSame('500-dollar-bill', str('500$--bill')->slug(separator: '-')->toString());
691+
$this->assertSame('500-dollar-bill', str('500-$--bill')->slug(separator: '-')->toString());
692+
$this->assertSame('ahmdfyalmdrs', str('أحمد@المدرسة')->slug(separator: '-', replacements: ['@' => 'في'])->toString());
693+
}
694+
695+
public function test_is_ascii(): void
696+
{
697+
$this->assertTrue(str('hello')->isAscii());
698+
$this->assertTrue(str()->isAscii());
699+
700+
$this->assertFalse(str('helloü')->isAscii());
701+
$this->assertFalse(str('بسم الله')->isAscii());
702+
}
666703
}

0 commit comments

Comments
 (0)