Skip to content

Commit

Permalink
add: String to slug capability
Browse files Browse the repository at this point in the history
  • Loading branch information
joshbruce committed May 19, 2023
1 parent 455ab25 commit 4d7bd08
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 2 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"php": "^8.1",
"8fold/php-xml-builder": "^2.0",
"psr/http-message": "^1.1",
"psr/log": "^3.0"
"psr/log": "^3.0",
"voku/portable-ascii": "^2.0"
},
"require-dev": {
"phpstan/phpstan": "^1.10",
Expand Down
76 changes: 75 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 82 additions & 0 deletions src/Php/StrToSlug.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);

namespace Eightfold\Amos\Php;

use voku\helper\ASCII;

class StrToSlug
{
/**
* @param array<string, string> $replacements
*/
public static function fromString(
string $string,
string $separator = '-',
string $language = 'en',
array $replacements = ['@' => 'at']
): string {
$instance = new self();
return $instance($string, $separator, $language, $replacements);
}

/**
* @param array<string, string> $replacements
*/
public function __invoke(
string $string,
string $separator = '-',
string $language = 'en',
array $replacements = ['@' => 'at']
): string {
$string = ASCII::to_ascii($string, $language); // @phpstan-ignore-line

// Convert all dashes/underscores into separator
$flip = $separator === '-' ? '_' : '-';

$string = preg_replace(
'![' . preg_quote($flip) . ']+!u',
$separator,
$string
);

if ($string == null) {
return '';
}

// Replace dictionary words
foreach ($replacements as $key => $value) {
$replacements[$key] = $separator . $value . $separator;
}

$string = str_replace(
array_keys($replacements),
array_values($replacements),
$string
);

// Remove all characters that are not the separator, letters, numbers, or whitespace
$string = preg_replace(
'![^' . preg_quote($separator) . '\pL\pN\s]+!u',
'',
mb_strtolower($string, 'UTF-8')
);

if ($string == null) {
return '';
}

// Replace all separator characters and whitespace by a single separator
$string = preg_replace(
'![' . preg_quote($separator) . '\s]+!u',
$separator,
$string
);

if ($string == null) {
return '';
}

return trim($string, $separator);
}
}
31 changes: 31 additions & 0 deletions tests/Php/StrToSlugTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);

namespace Eightfold\Amos\Tests\Php;

use Eightfold\Amos\Tests\TestCase as BaseTestCase;

use Eightfold\Amos\Php\StrToSlug;

class StrToSlugTest extends BaseTestCase
{
/**
* @test
*/
public function can_convert_string_to_slug(): void
{
$base = 'Hello, World!';

$expected = 'hello-world';

$result = StrToSlug::fromString($base);

$this->assertSame($expected, $result);

$obj = new StrToSlug();

$result = $obj($base);

$this->assertSame($expected, $result);
}
}

0 comments on commit 4d7bd08

Please sign in to comment.