@lolrofl01

Как формируются slug в laravel?

Необходимо в админке при вводе тайтла сразу формировать слаг. Таких страниц несколько, потому что типы разные (категории, страницы, записи, товары, юзеры и тд). Вроде ничего сложного, слаги делаю через Str:slug. Но, одно и то же писать в каждом контроллере\модели я не хочу. Поэтому создаю отдельный класс - слаг генератор. Структура класса:
class SlugController extends Controller
{
    public function generate($phrase, $limit = 255)
    {
        $slug = Str::slug($phrase);
        if( strlen($slug) > $limit ) return Str::substr($slug, 0, $limit);
        else return $slug;
    }

    public function isUniq($table, $field, $slug)
    {
        $result = $table->where($field, $slug)->first();
        if(! $result ) return true;

        return false;
    }

    public function generateUniqSlug($table, $phrase, $limit)
    {
        $slug = $this->generate($phrase, $limit);
        if( $this->isUniq($table, $field, $slug) ) return $slug;
        else {
            for($i = 1; $i < 200; $i++) {
                $newSlug = $slug . '-' . $i;
                if( $this->isUniq($table, $field, $slug) ) return $newSlug;
            }
        }
    }

}


Почему-то есть ощущение, что это жуткий гавнокод, изобретение велосипеда и вообще не туда пошел. Но вот что надо:
1) Генерация слага на лету, только ввел тайтл - сразу пришел слаг. Этот слаг обязательно должен быть уникальным
2) Пользователь может поменять слаг, это желательно сразу же проверить благодаря аякс запросу, и оповестить, если слаг не уникальный
3) Не хочется в каждом контроллере писать одни и те же проверки, поэтому выделил в отдельный класс, но не нравится, что в функции надо обязательно передавать модель (таблицу) и поле, по которому надо искать уникальный слаг или нет.

Сейчас скажут - есть Laravel sluggable. Есть, но он вроде как работает в моделях при сохранении\апдейте. Выбора он не дает, если слаг не уникальный, сразу сохранит его как slug-1 и не спросит. Плюс не уверен, что к нему можно обратиться просто для формирования слага по аяксу. Может и можно, но смысл, если есть Str::slug().

В общем подскажите, люди добрые, кто чем сможет))
  • Вопрос задан
  • 2162 просмотра
Решения вопроса 1
Вы можете валидировать данные, которые приходят в контроллер через кастомные Request-классы. Там вы можете указать такую конструкцию:
public function rules()
    {
        return [
            'slug' => [
                'string',
                'unique:posts,slug'
            ],
        ];
    }


Если при проверке Slug он уже есть в базе, то выводится ошибка валидации.

Чтобы слаг генерировался на лету, можете в том же кастомном Request реализовать метод:
protected function prepareForValidation() :void
    {
        $this->merge([
            'slug' => ($this->slug) ?? \Str::slug($this->title, '-')
        ]);
    }


То есть перед самой валидацией ваших данных к этим данным добавится сгенерированный из заголовка слаг, если поле осталось пустым, либо тот слаг, что вы указали
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы