Заполнение полей авторства при создании или обновлении записи в бд
  • 497

BlameableBehavior в yii2 - метки авторства

Автор: admin | 02 мая (Ср.) 2018г. в 21ч.43м.

BlameableBehavior автоматически заполняет указанные атрибуты текущим идентификатором пользователя.
Для этого в обновляемой таблице должны быть поля id юзера как created_by и updated_by. Назвать их можно
как угодно, конечно. Главное, чтобы в них можно было хранить число int. И не плохо бы создать связь
по внешнему ключу с соответствующим полем в таблице User с полем уникальным полем id.

Чтобы использовать BlameableBehavior, вставьте следующий код в класс ActiveRecord:
use yii\behaviors\BlameableBehavior;

public function behaviors()
{
    return [
        BlameableBehavior::className(),
    ];
}​

По умолчанию BlameableBehavior будет заполнять атрибуты created_by и updated_by с
текущим идентификатором пользователя. Поэтому, если поля "кто создал" и "кто обновил" назвать
как установлено по умолчанию в классе поведения, то код будет выглядеть как в примере выше.
Если ваши имена атрибутов различны с теми, что оприделены по умолчанию, вы можете настроить
свойства $createdByAttribute и $updatedByAttribute следующим образом:

public function behaviors()
{
    return [
        [
            'class' => BlameableBehavior::className(),
            'createdByAttribute' => 'author_id',
            'updatedByAttribute' => 'updater_id',
        ],
    ];
}

Так как данный атрибут заполняется автоматически и не вводится пользователем, то нет
смысла валидировать этот атрибут. Поэтому, можно вынести его как безопасный safe.

public function rules()
    {
        return [
            [['message', 'created_at', 'updated_at'], 'required'],
            [['created_by'], 'safe'],

Если нужно как-то фиксировать гостей при создании материала, то можно добавить
этот функционал в качестве анонимной функции и там сделать всю работу:

public function behaviors()
{
    return [
        [
            'class' => BlameableBehavior::className(),
            'value' => function ($event) {
                return (Yii::$app->user->isGuest) ? 1 : Yii::$app->user->identity->id;
            }
        ],
    ];
}

В январе 2018 года был немного расширен функционал класса и появились новые возможности
такие как $defaultValue - значение по умолчанию для случаев, когда пользователь является гостевым.

public function behaviors()
{
    return [
        [
            'class' => BlameableBehavior::className(),
            'defaultValue' => 1;
            
        ],
    ];
}

Если заглянуть внуть класса, то можно посмотреть на реализацию подробнее, когда сробатывает
значение по умолчанию:
    /**
     * {@inheritdoc}
     *
     * In case, when the [[value]] property is `null`, the value of [[defaultValue]] will be used as the value.
     */
    protected function getValue($event)
    {
        if ($this->value === null && Yii::$app->has('user')) {
            $userId = Yii::$app->get('user')->id;
            if ($userId === null) {
                return $this->getDefaultValue($event);
            }

            return $userId; 
        }

        return parent::getValue($event);
    }​

Из кода следует, что если 'value' в поведении не устанавливалось, но при этом зарегестрирован
компонент user - Yii::$app->has('user') ,то проверяем далее .Если посетитель
авторизирован и вошел на сайт как пользователь - возвращаем его id. Если нет, то тут как раз
получаем значение по умолчанию $this->getDefaultValue($event) .
Вот как обрабатывается это свойство:

    /**
     * Get default value
     * @param \yii\base\Event $event
     * @return array|mixed
     * @since 2.0.14
     */
    protected function getDefaultValue($event)
    {
        if ($this->defaultValue instanceof \Closure || (is_array($this->defaultValue) && is_callable($this->defaultValue))) {
            return call_user_func($this->defaultValue, $event);
        }

        return $this->defaultValue;
    }

Из кода видно, что можно использовать не только какое-то значение, но и анонимную функцию или
callback-функцию, массив в качестве значения данного параметра.

callback-функции должны быть только в таком виде:
* - метод этого behavior: `[$this, 'handleClick']`
* - метод объекта: `[$object, 'handleClick']`
* - статический метод: `['Page', 'handleClick']`
* - ананимная функция: `function ($event) { ... }`

Также есть возможность не перезаписывать атрибут, когда он не пустой. Для этого нужно
установить preserveNonEmptyValues = true . По умолчанию назначено как false. Применяться может
такое свойство тогда, когда нужно единожды установить данные пользователя и более их
не перезаписывать для какой-нибудь своей тонкой настройки поведения.

skipUpdateOnClean - по умолчанию true . Данное свойство означает -
пропустить это поведение, когда владелец $owner не был изменен. Владелец тут означает
объект модели, в которой это поведение оприделено.

Еще можно прикрепить или отвязать поведение от модели, когда это нужно. Например:

В модели:
public function behaviors()
{
    return [
//устанавливаем ключь
        'myKey' =>[
            'class' => BlameableBehavior::className(),
            'value' => function ($event) {
                return (Yii::$app->user->isGuest) ? 1 : Yii::$app->user->identity->id;
            }
        ],
    ];
}


public function actionCreate() {
    $model = new Article();

    if ($model->load(Yii::$app->request->post())) {

        //используем ключ 
        $model->detach('myKey');​

На этом все. Удачи.

Приветствую!

Меня зовут Сергей. Я - автор этого блога.

Если Вам был полезен материал на моем сайте, поддержите пожалуйста мой проект, чтобы о нем узнали другие люди - кликните plizz :) на иконку в соц. сети, чтобы поделиться материалом с другими.