2026-09-29 16:59:07 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace Domain\Models\ValueObjects;
|
|
|
|
|
|
2026-10-05 12:59:08 +02:00
|
|
|
use Shared\Helpers\StringHelper;
|
2026-09-29 16:59:07 +02:00
|
|
|
use Webmozart\Assert\Assert;
|
|
|
|
|
|
2026-10-02 12:14:48 +02:00
|
|
|
final readonly class Slug implements \Stringable
|
2026-09-29 16:59:07 +02:00
|
|
|
{
|
|
|
|
|
public function __construct(public string $value)
|
|
|
|
|
{
|
|
|
|
|
Assert::stringNotEmpty(trim($value), 'Slug cannot be empty.');
|
|
|
|
|
Assert::maxLength($value, 255, 'Slug cannot exceed 255 characters.');
|
|
|
|
|
Assert::regex($value, '/^[a-z0-9]+(?:-[a-z0-9]+)*$/', 'Slug format is invalid.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function fromString(string $string): self
|
|
|
|
|
{
|
2026-10-05 12:59:08 +02:00
|
|
|
$cleanString = StringHelper::transliterate($string);
|
2026-09-29 16:59:07 +02:00
|
|
|
|
|
|
|
|
$slug = strtolower(trim($cleanString));
|
|
|
|
|
$slug = preg_replace('/[^a-z0-9]+/i', '-', $slug) ?? '';
|
|
|
|
|
$slug = trim($slug, '-');
|
|
|
|
|
$slug = preg_replace('/-+/', '-', $slug) ?? '';
|
|
|
|
|
|
|
|
|
|
Assert::stringNotEmpty($slug, 'Cannot generate a valid slug from given string.');
|
|
|
|
|
|
|
|
|
|
return new self($slug);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[\Override]
|
|
|
|
|
public function __toString(): string
|
|
|
|
|
{
|
|
|
|
|
return $this->value;
|
|
|
|
|
}
|
|
|
|
|
}
|