/** * Displays a single AuditTrail model. * @param integer $id * @return mixed * @throws \HttpInvalidParamException */ public function actionView($id) { $model = AuditTrail::findOne($id); if (!$model) { throw new \HttpInvalidParamException('Invalid request number specified'); } return $this->render('view', ['model' => $model]); }
/** * Displays a single AuditTrail model. * @param integer $id * @return mixed * @throws NotFoundHttpException */ public function actionView($id) { $model = AuditTrail::findOne($id); if (!$model) { throw new NotFoundHttpException('The requested trail does not exist.'); } return $this->render('view', ['model' => $model]); }
/** * @inheritdoc */ public function cleanup($maxAge = null) { $maxAge = $maxAge !== null ? $maxAge : $this->maxAge; if ($maxAge === null) { return false; } return AuditTrail::deleteAll(['<=', 'created', date('Y-m-d 23:59:59', strtotime("-{$maxAge} days"))]); }
/** * Clean up the audit data according to the settings. */ public function actionCleanup() { $audit = Audit::getInstance(); if ($audit->maxAge === null) { return; } $entry = AuditEntry::tableName(); $errors = AuditError::tableName(); $data = AuditData::tableName(); $javascript = AuditJavascript::tableName(); $trail = AuditTrail::tableName(); $threshold = time() - $audit->maxAge * 86400; AuditEntry::getDb()->createCommand(<<<SQL DELETE FROM {$entry}, {$errors}, {$data}, {$javascript}, {$trail} USING {$entry} INNER JOIN {$errors} ON {$errors}.entry_id = {$entry}.id INNER JOIN {$data} ON {$data}.entry_id = {$entry}.id INNER JOIN {$javascript} ON {$javascript}.entry_id = {$entry}.id INNER JOIN {$trail} ON {$trail}.entry_id = {$entry}.id WHERE {$entry}.created < FROM_UNIXTIME({$threshold}) SQL )->execute(); }
use yii\helpers\ArrayHelper; use yii\helpers\Html; /* @var $this yii\web\View */ /* @var $dataProvider yii\data\ActiveDataProvider */ $this->title = Yii::t('audit', 'Audit Module'); $this->params['breadcrumbs'][] = $this->title; $this->registerCss('canvas {width: 100% !important;height: 400px;}'); $dataSet = ['fillColor' => "rgba(151,187,205,0.5)", 'strokeColor' => "rgba(151,187,205,1)", 'pointColor' => "rgba(151,187,205,1)", 'pointStrokeColor' => "#fff"]; $options = ['height' => 400, 'width' => 400]; $days = []; $count = ['entry' => [], 'trail' => [], 'javascript' => [], 'error' => []]; foreach (range(-6, 0) as $day) { $date = strtotime($day . 'days'); $days[] = date('D: Y-m-d', $date); $count['entry'][] = AuditEntry::find()->where(['between', 'created', date('Y-m-d 00:00:00', $date), date('Y-m-d 23:59:59', $date)])->count(); $count['trail'][] = AuditTrail::find()->where(['between', 'created', date('Y-m-d 00:00:00', $date), date('Y-m-d 23:59:59', $date)])->count(); $count['mail'][] = AuditMail::find()->where(['between', 'created', date('Y-m-d 00:00:00', $date), date('Y-m-d 23:59:59', $date)])->count(); $count['javascript'][] = AuditJavascript::find()->where(['between', 'created', date('Y-m-d 00:00:00', $date), date('Y-m-d 23:59:59', $date)])->count(); $count['error'][] = AuditError::find()->where(['between', 'created', date('Y-m-d 00:00:00', $date), date('Y-m-d 23:59:59', $date)])->count(); } //fake data //foreach ($count as $type => $data) { // foreach ($data as $k => $v) { // if (!$v) { // $v = $type == 'entry' ? rand(100, 1000) : rand(0, 100); // $count[$type][$k] = $v; // } // } //} ?> <div class="audit-index">
/** * Returns all linked AuditError instances * @return AuditError[] */ public function getTrail() { return static::hasMany(AuditTrail::className(), ['audit_id' => 'id']); }
/** * @param $action * @param $newAttributes * @param array $oldAttributes * @throws \yii\db\Exception */ public function auditAttributes($action, $newAttributes, $oldAttributes = []) { // If we are not active the get out of here if (!$this->active) { return; } // Setup values outside loop $audit_id = $this->getAuditEntryId(); $user_id = $this->getUserId(); $model = $this->owner->className(); $model_id = $this->getNormalizedPk(); $stamp = date($this->dateFormat); // Build a list of fields to log $rows = array(); foreach ($newAttributes as $name => $new) { $old = isset($oldAttributes[$name]) ? $oldAttributes[$name] : ''; // If we are skipping nulls then lets see if both sides are null if ($this->skipNulls && empty($old) && empty($new)) { continue; } // If they are not the same lets write an audit log if ($new != $old) { $rows[] = [$audit_id, $user_id, $old, $new, $action, $model, $model_id, $name, $stamp]; } } // Record the field changes with a batch insert if ($rows) { $columns = ['audit_id', 'user_id', 'old_value', 'new_value', 'action', 'model', 'model_id', 'field', 'stamp']; Yii::$app->db->createCommand()->batchInsert(AuditTrail::tableName(), $columns, $rows)->execute(); } }
<div class="row"> <div class="col-md-10"> <?php echo Html::tag('h2', Yii::t('audit', 'Request'), ['id' => 'entry', 'class' => 'hashtag']); echo DetailView::widget(['model' => $entry, 'attributes' => ['id', ['label' => $entry->getAttributeLabel('user_id'), 'value' => intval($entry->user_id) ? $entry->user_id : Yii::t('audit', 'Guest')], 'ip', 'created', ['attribute' => 'start_time', 'format' => 'datetime'], ['attribute' => 'end_time', 'format' => 'datetime'], ['attribute' => 'duration', 'format' => 'decimal'], 'referrer', 'redirect', 'url', 'route', ['attribute' => 'memory', 'format' => 'shortsize'], ['attribute' => 'memory_max', 'format' => 'shortsize']]]); foreach ($entry->extraData as $data) { $attributes = []; foreach ($data->data as $name => $value) { $attributes[] = ['label' => $name, 'value' => Helper::formatValue($value), 'format' => 'raw']; } echo Html::tag('h2', $data->name . ' (' . count($attributes) . ')', ['id' => $data->type, 'class' => 'hashtag']); echo DetailView::widget(['model' => $data, 'attributes' => $attributes, 'template' => '<tr><th>{label}</th><td style="word-break:break-word;">{value}</td></tr>']); } if (count($entry->trail)) { $dataProvider = new ActiveDataProvider(['query' => AuditTrail::find()->where(['audit_id' => $entry->id]), 'pagination' => ['pageSize' => 1000]]); echo Html::tag('h2', Yii::t('audit', 'Trail ({i})', ['i' => count($entry->trail)]), ['id' => 'trail', 'class' => 'hashtag']); echo GridView::widget(['dataProvider' => $dataProvider, 'columns' => ['id', 'action', 'model', 'model_id', 'field', ['label' => Yii::t('audit', 'Diff'), 'value' => function ($model) { /** @var AuditTrail $model */ return $model->getDiffHtml(); }, 'format' => 'raw'], 'stamp', ['class' => 'yii\\grid\\ActionColumn', 'template' => '{view}', 'buttons' => ['view' => function ($url, $model, $key) { return Html::a(Html::tag('span', '', ['class' => 'glyphicon glyphicon-eye-open']), ['diff', 'id' => $model->id], ['class' => '', 'data' => ['toggle' => 'modal']]); }]]]]); } if (count($entry->linkedErrors)) { echo Html::tag('h2', Yii::t('audit', 'Errors ({i})', ['i' => count($entry->linkedErrors)]), ['id' => 'errors', 'class' => 'hashtag']); foreach ($entry->linkedErrors as $i => $error) { echo Html::tag('h3', Yii::t('audit', 'Error #{i}', ['i' => $i + 1])); echo DetailView::widget(['model' => $error, 'attributes' => ['message', 'code', ['label' => Yii::t('audit', 'Location'), 'value' => $error->file . '(' . $error->line . ')']]]); } }
public static function actionFilter() { return \yii\helpers\ArrayHelper::map(parent::find()->select('action')->groupBy('action')->orderBy('action ASC')->all(), 'action', 'action'); }
/** * Save the audit trails for a delete action */ protected function saveAuditTrailDelete() { $audit = Audit::getInstance(); $audit->getDb()->createCommand()->insert(AuditTrail::tableName(), ['action' => 'DELETE', 'entry_id' => $this->getAuditEntryId(), 'user_id' => $this->getUserId(), 'model' => $this->owner->className(), 'model_id' => $this->getNormalizedPk(), 'created' => date($this->dateFormat)])->execute(); }
/** * ($this) getAuditTrails : get trails for this model * @return $this */ public function getAuditTrails() { return $this->hasMany(AuditTrail::className(), ['model_id' => 'mid'])->andOnCondition(['REGEXP', 'field', '^\\[(.)*\\]$'])->andOnCondition(['model' => get_class($this)]); }
/** * Displays a single AuditEntry model. * @param integer $id * @return mixed */ public function actionDiff($id) { $model = AuditTrail::findOne($id); return $this->render('diff', ['model' => $model]); }
/** * (string) actionHistory : 删除的历史数据 * @param string $pid personal_id * @return string */ public function actionHistory($pid) { return $this->render('@bedezign/yii2/audit/views/_audit_trails', ['query' => \bedezign\yii2\audit\models\AuditTrail::find()->andFilterWhere(['like', 'old_value', $pid]), 'params' => ['AuditTrailSearch' => []], 'columns' => ['user_id', 'entry_id', 'action', 'old_value', 'created'], 'filter' => false]); }
/** * Find an attribute from a version. * * @param $class * @param $id * @param $attribute * @param $version * @return null|integer|float|string */ public static function findAttribute($class, $id, $attribute, $version) { /** @var AuditTrail $trail */ $trail = AuditTrail::find()->andWhere(['model' => $class, 'model_id' => $id, 'field' => $attribute])->andWhere(['<=', 'entry_id', $version])->orderBy(['id' => SORT_DESC])->one(); return $trail ? $trail->new_value : null; }
public function actionRevertir($id) { // buscamos los modelos $post1 = AuditTrail::findOne($id); $post = AccionCentralizada::findOne($post1->model_id); //si esta vacio el modelo es por que fue borrado if ($post != null) { //buscamos la ultima version $attributes = Version::lastVersion($post->className(), $post->id); //cargamos los datos de la ultima version $post = Version::find($post->className(), $post->id, $attributes); //solo para el caso de modelos que tenga fecha, formatear la fecha $post->fecha_inicio = date_create($post->fecha_inicio); $post->fecha_fin = date_create($post->fecha_fin); $post->fecha_inicio = date_format($post->fecha_inicio, 'd/m/Y'); $post->fecha_fin = date_format($post->fecha_fin, 'd/m/Y'); } else { //en que caso que fue borrado se busca la ultima version por medio del id almacenado en el modelo trail $attributes = Version::lastVersion(AccionCentralizada::className(), $post1->model_id); //cargamos los datos $post = Version::find(AccionCentralizada::className(), $post1->model_id, $attributes); //solo en caso de modelos q tengan fecha $post->fecha_inicio = date_create($post->fecha_inicio); $post->fecha_fin = date_create($post->fecha_fin); $post->fecha_inicio = date_format($post->fecha_inicio, 'Y-m-d'); $post->fecha_fin = date_format($post->fecha_fin, 'Y-m-d'); } //se almacena y redirecciona. if ($post->save()) { return $this->redirect('index.php?r=audit/trail'); } else { //print_r($post->getErrors()); return $this->redirect('index.php?r=audit/trail'); } }
/** * @inheritDoc */ protected function saveAuditTrail($action, $newAttributes, $oldAttributes, $entry_id, $user_id, $model, $model_id, $created) { // Build a list of fields to log $rows = array(); $fields = array(); //字段 $newVal = array(); //新值 $oldVal = array(); //旧值 foreach ($newAttributes as $field => $new) { $old = isset($oldAttributes[$field]) ? $oldAttributes[$field] : ''; // If they are not the same lets write an audit log if ($new != $old) { $fields[] = $field; $newVal[] = $new; $oldVal[] = $old; $rows[] = [$entry_id, $user_id, $old, $new, $action, $model, $model_id, $field, $created]; } } //保存一条单独的记录 $rows[] = [$entry_id, $user_id, Json::encode($oldVal), Json::encode($newVal), $action, $model, $model_id, Json::encode($fields), $created]; // Record the field changes with a batch insert if (!empty($rows)) { $columns = ['entry_id', 'user_id', 'old_value', 'new_value', 'action', 'model', 'model_id', 'field', 'created']; $audit = Audit::getInstance(); $audit->getDb()->createCommand()->batchInsert(AuditTrail::tableName(), $columns, $rows)->execute(); } }