Skip to content
This repository has been archived by the owner on Feb 12, 2023. It is now read-only.

Commit

Permalink
feat: Slugifier added
Browse files Browse the repository at this point in the history
  • Loading branch information
mkorkmaz committed Aug 7, 2021
1 parent c4fcf2f commit 260ef51
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 2 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"psr/container": "^1.0"
},
"suggest": {
"ext-libxml": "TagAndAttributeRemover needs this extention"
"ext-libxml": "TagAndAttributeRemover needs this extention",
"ext-intl": "Slugify needs this extension"
},
"require-dev": {
"codeception/codeception": "^4.1",
Expand All @@ -38,7 +39,6 @@
}
},
"scripts": {

"cs-check": "vendor/bin/phpcs --standard=Doctrine",
"cs-fix": "vendor/bin/phpcbf --standard=Doctrine"

Expand Down
69 changes: 69 additions & 0 deletions src/Slugifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Selami\Stdlib;

use Selami\Stdlib\Exception\InvalidArgumentException;
use Transliterator;

class Slugifier
{
/**
* @var string|array $subject
*/
private $subject;

private Transliterator $transliterator;
/**
* @param string|iterable $subject
*/
private function __construct($subject)
{
$this->subject = $subject;
$this->transliterator = Transliterator::create('Any-Latin; Latin-ASCII');
}
/**
* @param mixed<string|iterable> $subject
* @return string|iterable<string>
*/
public static function slugify($subject)
{
return (new self($subject))
->getSlugifiedResult();
}
/**
* @return string|iterable<string>
*/
private function getSlugifiedResult()
{
if (is_iterable($this->subject)) {
return $this->getSlugifiedIterable($this->subject);
}
return $this->getSlugifiedString($this->subject);
}

private function getSlugifiedString($subject) : string
{

if (!is_string($subject)) {
throw new InvalidArgumentException(
sprintf('Only string or array of strings accepted but %s given', gettype($subject))
);
}
$stringWithRemovedDiacritics = $this->transliterator->transliterate($subject);
$stringWithRemovedWhite = preg_replace(['/\-/','/[\W]+/'], [' ','-'], $stringWithRemovedDiacritics);
return strtolower($stringWithRemovedWhite);
}

/**
* @param iterable $subject
* @return iterable<string>
*/
private function getSlugifiedIterable(iterable $subject) : iterable
{
foreach ($subject as $item) {
yield $this->getSlugifiedString($item);
}
}
}
65 changes: 65 additions & 0 deletions tests/unit/SlugifierTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace UnitTest;

use Codeception\Test\Unit;
use Selami\Stdlib\Exception\InvalidArgumentException;
use Selami\Stdlib\Slugifier;

class SlugifierTest extends Unit
{
protected $tester;

protected function _before(): void
{
}

protected function _after(): void
{
}

/**
* @test
* @dataProvider dataProvider
*/
public function shouldReturnSlugifySuccessfully($subjects, $expected): void
{
$actual = Slugifier::slugify($subjects);
$index = 0;
foreach ($actual as $item) {
$this->assertEquals($expected[$index], $item, 'Returning expected slugs failed');
$index++;
}
}
/**
* @test
*/
public function shouldThrowExceptionForInvalidInput(): void
{
$this->expectException(InvalidArgumentException::class);
Slugifier::slugify(1234);
}

public function dataProvider() : array
{
return [
[
[
'Meinung: Impfstoff-Mangel für die Ärmsten - eine moralische Bankrotterklärung',
'Türkiye\'nin İstanbul Sözleşmesi serüveni',
'Во Франции прошли протесты против ужесточения мер',
'1234'
],
[
'meinung-impfstoff-mangel-fur-die-armsten-eine-moralische-bankrotterklarung',
'turkiye-nin-istanbul-sozlesmesi-seruveni',
'vo-francii-prosli-protesty-protiv-uzestocenia-mer',
'1234'
],
]
];
}

}

0 comments on commit 260ef51

Please sign in to comment.