SluggableBehavior

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

Loveorigami писал(а): спасибо. посмотрел код, настройки, но так и не понял каким образом могу получить, скажем, для 30250 записи slug
30250-origami-heart.

Код: Выделить всё

Slug may be generated from multiple and related attributes:

public function behaviors()
{
    return [
        'slug' => [
            ...
            'attribute' => ['name', 'language.username'],
            ...
        ]
    ];
} 
Аватара пользователя
r3verser
Сообщения: 195
Зарегистрирован: 2012.04.01, 17:29
Откуда: Киев

Re: SluggableBehavior

Сообщение r3verser »

Loveorigami писал(а):Спасибо. Теперь все работает, как надо!

У меня есть еще один интересный момент. В codeIgniter я реализовывал через составной alias. А именно:
- Имеется база с более 40 000 записей (rss новости с фликра по оригами).
- При добавлении новой очень большая вероятность, что похожая уже есть, причем не одна. (например "origami heart" встречается более 50 раз)
- Это означает, что при добавлении следующей записи "origami heart", поведение, как я понял, будет генерировать уникальный slug, поочередно перебирая свободные от origami-heart1 до origami-heart50, т.е. делать 50 запросов в базу...

- есть идея, для такого случая генерировать slug вида id-записи + slug.
- т.е. в данное поведение добавить следующий функционал (suffix и prefix)...
Словом, хранение aliasa в виде id+slug в одном поле намного облегчит работу с таблицей, где title может встречаться многократно.
Так ведь в Yii'шном SluggableBehavior уже есть callable параметр 'uniqueSlugGenerator' https://github.com/yiisoft/yii2/blob/ma ... r.php#L104 , в который и можно прописать нужную логику.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

r3verser писал(а):
Loveorigami писал(а):Спасибо. Теперь все работает, как надо!

У меня есть еще один интересный момент. В codeIgniter я реализовывал через составной alias. А именно:
- Имеется база с более 40 000 записей (rss новости с фликра по оригами).
- При добавлении новой очень большая вероятность, что похожая уже есть, причем не одна. (например "origami heart" встречается более 50 раз)
- Это означает, что при добавлении следующей записи "origami heart", поведение, как я понял, будет генерировать уникальный slug, поочередно перебирая свободные от origami-heart1 до origami-heart50, т.е. делать 50 запросов в базу...

- есть идея, для такого случая генерировать slug вида id-записи + slug.
- т.е. в данное поведение добавить следующий функционал (suffix и prefix)...
Словом, хранение aliasa в виде id+slug в одном поле намного облегчит работу с таблицей, где title может встречаться многократно.
Так ведь в Yii'шном SluggableBehavior уже есть callable параметр 'uniqueSlugGenerator' https://github.com/yiisoft/yii2/blob/ma ... r.php#L104 , в который и можно прописать нужную логику.
верно. мой вариант удобнее для определенного кейса.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: SluggableBehavior

Сообщение Loveorigami »

@zelenin
потестил ваше поведение.
при таких настройках -

Код: Выделить всё

            [
                'class' => 'Zelenin\yii\behaviors\Slug',
                'attribute'=>['id','title'],
                'ensureUnique' => true,
                'translit' => true,
                'replacement' => '-',
                'lowercase' => true
            ] 
нужный alias (30250-origami-heart) получается только при обновлении. При добавлении - получаю просто - 'origami-heart'.

@r3verser
чтоб получить действительно уникальный - нужно slug обновлять после создания записи (об этом писал выше).
В общем - задать логику для id, который еще не существует - через uniqueSlugGenerator проблематично
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

Loveorigami писал(а): нужный alias (30250-origami-heart) получается только при обновлении. При добавлении - получаю просто - 'origami-heart'.
считаете это неправильное поведение? id при создании не существует. Slug создается ДО валидации, т.к. slug может присутствовать в правилах валидации.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

zelenin писал(а):
Loveorigami писал(а): нужный alias (30250-origami-heart) получается только при обновлении. При добавлении - получаю просто - 'origami-heart'.
считаете это неправильное поведение? id при создании не существует. Slug создается ДО валидации, т.к. slug может присутствовать в правилах валидации.
да, кстати. можно доработать. создам issue.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: SluggableBehavior

Сообщение Loveorigami »

поведение правильное. результат, который нужен - "неправильный"...
- Я получаю новости через rss и соответственно, в цикле их добавляю. значит, тот вариант генерации уникального slug, который я определил в настройках, должен работать, как при создании, так и при обновлении. Иначе, когда пойдет поток rss с 50 одинаковыми титлами - при добавлении получу 50+ запросов в базу на генерацию последнего уникального.

- как я думаю
-- добавляем функционал "prefix"
-- получаем slug, проходим валидацию, записываем в базу
-- если определен prefix, используем метод afterSave
-- получаем последний id. генерируем уникальный alias (id+slug) и обновляем.

вот тогда, мне кажется, логика работы поведения будет полной
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

Loveorigami писал(а):поведение правильное. результат, который нужен - "неправильный"...
- Я получаю новости через rss и соответственно, в цикле их добавляю. значит, тот вариант генерации уникального slug, который я определил в настройках, должен работать, как при создании, так и при обновлении. Иначе, когда пойдет поток rss с 50 одинаковыми титлами - при добавлении получу 50+ запросов в базу на генерацию последнего уникального.

- как я думаю
-- добавляем функционал "prefix"
-- получаем slug, проходим валидацию, записываем в базу
-- если определен prefix, используем метод afterSave
-- получаем последний id. генерируем уникальный alias (id+slug) и обновляем.

вот тогда, мне кажется, логика работы поведения будет полной
prefix излишен. я уже реализовываю необходимый функционал.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: SluggableBehavior

Сообщение Loveorigami »

slavcodev писал(а):Вот кажется можно настроить Inflector
https://github.com/yiisoft/yii2/blob/ma ... r.php#L239
Каким образом его можно настроить глобально для всего проекта.

В common/config.php пробовал по разному

Код: Выделить всё

    'helpers'=>[
        'inflector'=>[
            'transliterator' => 'Russian-Latin/BGN; NFKD'
        ],
    ], 
не работает.

Это все к вопросу о транслитерации русских символов, как в поведении от r3verser.
Если можно задать глобально, то доработка, вроде как и не нужна.

А если нет, то можно ли в поведение @zelenin добавить похожую настройку?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

Loveorigami писал(а): А если нет, то можно ли в поведение @zelenin добавить похожую настройку?
все реализовал.
Аватара пользователя
r3verser
Сообщения: 195
Зарегистрирован: 2012.04.01, 17:29
Откуда: Киев

Re: SluggableBehavior

Сообщение r3verser »

страсти)))
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: SluggableBehavior

Сообщение Loveorigami »

zelenin писал(а):
Loveorigami писал(а): А если нет, то можно ли в поведение @zelenin добавить похожую настройку?
все реализовал.
почему-то вышла ошибка.
2014-11-04_18-00-15.jpg
2014-11-04_18-00-15.jpg (116.34 КБ) 6594 просмотра
Подключение не менял.

Код: Выделить всё

            [
                'class' => 'Zelenin\yii\behaviors\Slug',
                'attribute'=>['id','title'],
                'ensureUnique' => true,
                'translit' => true,
                'replacement' => '-',
                'lowercase' => true,
            ] 
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

Loveorigami писал(а):почему-то вышла ошибка.
чувствовал что тут будет ошибка ) в php 5.6 такое разрешено, а в старых версиях нет. пофиксил.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: SluggableBehavior

Сообщение Loveorigami »

работает )
но...

Код: Выделить всё

                'class' => 'Zelenin\yii\behaviors\Slug',
                'attribute'=>['id','title'],
                'ensureUnique' => false, // пробовал и true   
если я хочу задать свой slug (не пустой), после сохранения он заменяется на "автоматический"
---------
новая запись - сохраняю

Код: Выделить всё

id=>2
title => привет
slug => 2-privet
редактирую, меняю slug => hello
получаю все равно 2-privet
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: SluggableBehavior

Сообщение Loveorigami »

Не дожидаясь вашего ответа по ошибке, написал

Код: Выделить всё

    public function attach($owner)
    {
  print_r($owner->primaryKey());
    } 
в гриде мне выдало массив из 12 значений (для 3 записей). В форме - всего одно. Как и должно быть.
2014-11-04_19-02-01.jpg
2014-11-04_19-02-01.jpg (172.59 КБ) 6568 просмотров

Разве поведение не должно срабатывать при вставке-редактировании записи?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

Loveorigami писал(а):работает )
но...

Код: Выделить всё

                'class' => 'Zelenin\yii\behaviors\Slug',
                'attribute'=>['id','title'],
                'ensureUnique' => false, // пробовал и true    
если я хочу задать свой slug (не пустой), после сохранения он заменяется на "автоматический"
---------
новая запись - сохраняю

Код: Выделить всё

id=>2
title => привет
slug => 2-privet
редактирую, меняю slug => hello
получаю все равно 2-privet
в rules описан атрибут?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

Loveorigami писал(а):Не дожидаясь вашего ответа по ошибке, написал

Код: Выделить всё

    public function attach($owner)
    {
  print_r($owner->primaryKey());
    }
в гриде мне выдало массив из 12 значений (для 3 записей). В форме - всего одно. Как и должно быть.
2014-11-04_19-02-01.jpg

Разве поведение не должно срабатывать при вставке-редактировании записи?
оно должно срабатывать на тех событиях, на которые мы его вешаем. А на какое событие вешаем, поведение решает именно в attach(). Так что оно не срабатывает там, а только аттачится к модели.

12 раз потому, что у вас 3 модели вызываются видимо 12 раз где-то.
у меня на гриде ничего не выводится.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: SluggableBehavior

Сообщение Loveorigami »

zelenin писал(а): в rules описан атрибут?
да -

Код: Выделить всё

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['title', 'text'], 'required'],
            [['slug'], 'unique'],
            [['slug'], 'string', 'max' => 1024],
            [['title'], 'string', 'max' => 512]
        ];
    } 
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: SluggableBehavior

Сообщение slavcodev »

Loveorigami писал(а):Каким образом его можно настроить глобально для всего проекта.
Чтоб настроить хелпер, его статическое свойство, нужно где-то в самом начале работы приложения написать

Код: Выделить всё

\yii\helpers\Inflector.php::$transliterator = 'Russian-Latin/BGN; NFKD';
 
Это можно сделать, например, в init() базового контролера
Жду Yii 3!
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: SluggableBehavior

Сообщение zelenin »

slavcodev писал(а):
Loveorigami писал(а):Каким образом его можно настроить глобально для всего проекта.
Чтоб настроить хелпер, его статическое свойство, нужно где-то в самом начале работы приложения написать

Код: Выделить всё

\yii\helpers\Inflector.php::$transliterator = 'Russian-Latin/BGN; NFKD';
Это можно сделать, например, в init() базового контролера
везде свои базовые контроллеры пихаете) нету никакого базового контроллера.
Ответить