Обнаружение изменений в модели; php yii фреймворк

Я создаю модуль контрольного журнала, который помещу в более крупную систему; и я создал таблицу для хранения записей следа, как «аудитор», что я хочу видеть вошедшего в систему пользователя, страницу, на которой он / она находится, какое действие он / она сделал и каковы были изменения и когда...

это в основном то, что я хочу видеть; моя таблица контрольного журнала выглядит так:

Пользователь| Отметка времени| Имя модуля| Действие| Старое значение| Новое значение| Описание

у меня в принципе не было проблем с получением пользователя,

Yii::app()->session['username'];

страницу/модуль и действие, получив контроллер:

$this->module->getName();
$this->action->id;

Моя проблема заключается в изменении старого значения на новое, правках, сделанных пользователем. я мог бы как бы «понюхать», какие правки / изменения он / она сделал, буквально скопировав переменные и передав их через мою функцию, где я создаю журнал.. Как мне сделать это динамически?

я как бы хочу определить, были ли изменены свойства или атрибуты определенной модели, и посмотреть, какие изменения были внесены, чтобы я мог получить подробный журнал ... Спасибо! Извините, я действительно пытаюсь объяснить это.


person muffin    schedule 22.05.2013    source источник


Ответы (3)


В каждой модели, которую вы хотите наблюдать, вы можете написать метод afterFind(), в котором вы сохраняете текущие атрибуты БД в некоторой частной переменной, например. _dbValues. Затем в beforeSave() вы сверяете текущие атрибуты с теми, что в _dbValues, и создаете контрольную запись, если произошли изменения.

После того, как вы это заработаете, вы можете сделать еще один шаг и создать из него behavior. Вы бы поместили туда приватную переменную, метод afterFind() и метод beforeSave(). Затем вы можете прикрепить это поведение ко многим записям.

person Michael Härtl    schedule 22.05.2013
comment
afterFind будет оцениваться после каждой находки, как и в сетке, верно? Возможно, сценарии можно было бы использовать для сохранения атрибутов в _dbValues только при обновлении. - person ; 22.05.2013
comment
Спасибо! это полезно :D - person muffin; 23.05.2013

Быстрый пример:

class Book extends CActiveRecord
{
    private $oldAttrs = array();

    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public function tableName()
    {
        return 'book';
    }

    protected function afterSave()
    {
        // store history
        if (!$this->isNewRecord) {
            $newAttrs = $this->getAttributes();
            $oldAttrs = $this->getOldAttributes();

            // your code
        }

        return parent::afterSave();
    }

    protected function afterFind()
    {
        // Save old values
        $this->setOldAttributes($this->getAttributes());

        return parent::afterFind();
    }

    public function getOldAttributes()
    {
        return $this->oldAttrs;
    }

    public function setOldAttributes($attrs)
    {
        $this->oldAttrs = $attrs;
    }
}
person Valery Viktorovsky    schedule 22.05.2013
comment
Спасибо .. попробую этот - person muffin; 23.05.2013

Ваше решение хорошее, но что, если есть два потока, которые одновременно вызывают ->save()?

Предположим, что:

  1. 1-й поток находит запись, сохраняет статус A.
  2. 2-й поток находит запись, сохраняет статус A.
  3. затем 1-й поток меняет запись на B, вызывает ->save(). Система будет регистрировать A-> B
  4. затем 2-й поток меняет запись на C, вызывает ->save(). Система будет регистрировать A-> C

Итого, есть 2 лога: A->B, A->C. Если это не проблема для вас, просто проигнорируйте это и выполните указанное выше решение.

person Tarzan    schedule 23.05.2013