diff --git a/Modules/Tag/Tests/Integration/TaggableTraitTest.php b/Modules/Tag/Tests/Integration/TaggableTraitTest.php index 5c9624416..ccee276ea 100644 --- a/Modules/Tag/Tests/Integration/TaggableTraitTest.php +++ b/Modules/Tag/Tests/Integration/TaggableTraitTest.php @@ -3,6 +3,7 @@ namespace Modules\Tag\Tests\Integration; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Str; use Modules\Page\Entities\Page; use Modules\Page\Repositories\PageRepository; use Modules\Tag\Repositories\TagRepository; @@ -132,6 +133,26 @@ public function it_gets_all_tags_for_a_namespace() $this->assertCount(3, Page::allTags()->get()); } + /** @test */ + public function it_generates_slug_like_original_str_slug() + { + $page = $this->createPage(); + + $this->assertEquals(Str::slug('hello world'), $page->generateTagSlug('hello world')); + $this->assertEquals(Str::slug('hello world'), $page->generateTagSlug('hello-world')); + $this->assertEquals(Str::slug('hello_world'), $page->generateTagSlug('hello_world')); + $this->assertEquals(Str::slug('hello_world', '_'), $page->generateTagSlug('hello_world', '_')); + $this->assertEquals(Str::slug('user@host'), $page->generateTagSlug('user@host')); + } + + /** @test */ + public function it_gets_pages_with_non_latin_tags() + { + $this->createPage(['한글 태그']); + + $this->assertCount(1, Page::whereTag(['한글-태그'])->get()); + } + private function createPage(array $tags = []) { return $this->page->create([ diff --git a/Modules/Tag/Traits/TaggableTrait.php b/Modules/Tag/Traits/TaggableTrait.php index 7d735d485..2c6df68e2 100644 --- a/Modules/Tag/Traits/TaggableTrait.php +++ b/Modules/Tag/Traits/TaggableTrait.php @@ -204,8 +204,22 @@ protected function getEntityClassName() /** * {@inheritdoc} */ - protected function generateTagSlug($name) + public function generateTagSlug($name, $separator = '-') { - return str_slug($name); + // Convert all dashes/underscores into separator + $flip = $separator == '-' ? '_' : '-'; + + $name = preg_replace('!['.preg_quote($flip).']+!u', $separator, $name); + + // Replace @ with the word 'at' + $name = str_replace('@', $separator.'at'.$separator, $name); + + // Remove all characters that are not the separator, letters, numbers, or whitespace. + $name = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', mb_strtolower($name)); + + // Replace all separator characters and whitespace by a single separator + $name = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $name); + + return trim($name, $separator); } }