This module is also responsible for starting the audit process. To configure it you need to do 2 things: - add a module configuration entry: 'modules' => [ 'audit' => 'bedezign\yii2\audit\Audit', ] or optionally with configuration: 'modules' => [ 'audit' => [ 'class' => 'bedezign\yii2\audit\Audit', 'ignoreActions' => ['debug/*'] ] - If you want to auto track actions, be sure to add the module to the application bootstrapping: 'bootstrap' => ['audit'],
Inheritance: extends yii\base\Module
 protected function finalize()
 {
     $_panel = Audit::getInstance()->getPanel('audit/soap');
     if ($_panel) {
         $_panel->logSoapRequest($this->_data);
     }
 }
Exemple #2
0
 /**
  * Compress
  * @param mixed $data
  * @return string binary blob of data
  */
 public static function uncompress($data)
 {
     if (Audit::getInstance()->compressData) {
         $data = gzuncompress($data);
     }
     return $data;
 }
 /**
  * @param Exception $exception
  */
 public function logException($exception)
 {
     try {
         $isMemoryError = strncmp($exception->getMessage(), 'Allowed memory size of', 22) === 0;
         /** @var Audit $audit */
         $audit = Audit::getInstance();
         if (!$audit && !$isMemoryError) {
             // Only attempt to load the module if this isn't an out of memory error, not enough room otherwise
             $audit = \Yii::$app->getModule(Audit::findModuleIdentifier());
         }
         if (!$audit) {
             throw new \Exception('Audit module cannot be loaded');
         }
         $entry = $audit->getEntry(!$isMemoryError);
         if ($entry) {
             /** @var ErrorPanel $errorPanel */
             $errorPanel = $audit->getPanel($audit->findPanelIdentifier(ErrorPanel::className()));
             $errorPanel->log($entry->id, $exception);
             $entry->finalize();
         }
     } catch (\Exception $e) {
         // if we catch an exception here, let it slide, we don't want recursive errors killing the script
     }
     parent::logException($exception);
 }
Exemple #4
0
 /**
  * Re-inflates and unserializes a blob of compressed data
  * @param string $data
  * @return mixed            false if an error occurred
  */
 public static function unserialize($data)
 {
     if (Audit::current()->compressData) {
         $data = gzuncompress($data);
     }
     return unserialize($data);
 }
 /**
  * @return array
  */
 public function actionIndex()
 {
     Yii::$app->response->format = Response::FORMAT_JSON;
     $data = Json::decode(Yii::$app->request->post('data'));
     if (!isset($data['auditEntry'])) {
         $entry = Audit::getInstance()->getEntry(true);
         $data['auditEntry'] = $entry->id;
     }
     // Convert data into the loggable object
     $javascript = new models\AuditJavascript();
     $map = ['auditEntry' => 'entry_id', 'message' => 'message', 'type' => 'type', 'file' => 'origin', 'line' => function ($value) use($javascript) {
         $javascript->origin .= ':' . $value;
     }, 'col' => function ($value) use($javascript) {
         $javascript->origin .= ':' . $value;
     }, 'data' => function ($value) use($javascript) {
         if (count($value)) {
             $javascript->data = $value;
         }
     }];
     foreach ($map as $key => $target) {
         if (isset($data[$key])) {
             if (is_callable($target)) {
                 $target($data[$key]);
             } else {
                 $javascript->{$target} = $data[$key];
             }
         }
     }
     if ($javascript->save()) {
         return ['result' => 'ok', 'entry' => $data['auditEntry']];
     }
     return ['result' => 'error', 'errors' => $javascript->getErrors()];
 }
 /**
  * @param Event $event
  * @return null|static
  */
 public static function record($event)
 {
     /* @var $message MessageInterface */
     $message = $event->message;
     $entry = Audit::getInstance()->getEntry(true);
     $mail = new static();
     $mail->entry_id = $entry->id;
     $mail->successful = $event->isSuccessful;
     $mail->from = self::convertParams($message->getFrom());
     $mail->to = self::convertParams($message->getTo());
     $mail->reply = self::convertParams($message->getReplyTo());
     $mail->cc = self::convertParams($message->getCc());
     $mail->bcc = self::convertParams($message->getBcc());
     $mail->subject = $message->getSubject();
     // add more information when message is a SwiftMailer message
     if ($message instanceof Message) {
         /* @var $swiftMessage Swift_Message */
         $swiftMessage = $message->getSwiftMessage();
         foreach ($swiftMessage->getChildren() as $part) {
             /* @var $part Swift_Mime_MimePart */
             if ($part instanceof Swift_Mime_Attachment) {
                 continue;
             }
             $contentType = $part->getContentType();
             if ($contentType == 'text/plain') {
                 $mail->text = Helper::compress($part->getBody());
             } elseif ($contentType == 'text/html') {
                 $mail->html = Helper::compress($part->getBody());
             }
         }
     }
     $mail->data = Helper::compress($message->toString());
     return $mail->save(false) ? $mail : null;
 }
 public function publish($assetManager)
 {
     $module = \bedezign\yii2\audit\Audit::current();
     if ($module && $module->entry) {
         // We can't be sure that the actual logger was loaded already, so we fallback on the window object
         // to store the associated audit entry id
         \Yii::$app->view->registerJs("window.auditEntry = {$module->entry->id};", \yii\web\View::POS_HEAD);
     }
     return parent::publish($assetManager);
 }
 /**
  * @param $userId
  * @param ActiveQuery $query
  */
 protected function filterUserId($userId, $query)
 {
     if (strlen($this->user_id)) {
         if (!is_numeric($userId) && ($callback = Audit::getInstance()->userFilterCallback)) {
             $userId = call_user_func($callback, $userId);
         } else {
             $userId = intval($this->user_id) ?: 0;
         }
     }
     $query->andFilterWhere(['user_id' => $userId]);
 }
 public function finalize()
 {
     if (in_array('response', $this->logVars)) {
         $entry = Audit::current()->getEntry();
         if ($entry) {
             if (Yii::$app->response instanceof \yii\web\Response) {
                 $data = Helper::compact(Yii::$app->response->headers, true);
                 if ($data) {
                     $entry->addData('response_headers', $data);
                 }
             }
         }
     }
 }
 /**
  * @param \yii\web\AssetManager $assetManager
  */
 public function publish($assetManager)
 {
     $module = Audit::getInstance();
     // We can't be sure that the actual logger was loaded already, so we fallback on the window object
     // to store the associated audit url and entry id
     $url = Url::to(["/{$module->id}/js-log"]);
     $script = "window.auditUrl = '{$url}';";
     if ($module->entry) {
         $id = $module->getEntry()->id;
         $script .= "window.auditEntry = {$id};";
     }
     \Yii::$app->view->registerJs($script, View::POS_HEAD);
     parent::publish($assetManager);
 }
Exemple #11
0
 /**
  * Bootstrap method to be called during application bootstrap stage.
  *
  * @param Application $app the application currently running
  */
 public function bootstrap($app)
 {
     // Make sure to register the base folder as alias as well or things like assets won't work anymore
     \Yii::setAlias('@bedezign/yii2/audit', __DIR__);
     if ($app instanceof \yii\console\Application) {
         $app->controllerMap['audit'] = 'bedezign\\yii2\\audit\\commands\\AuditController';
     }
     $moduleName = Audit::findModuleIdentifier();
     if ($moduleName) {
         // The module was added in the configuration, make sure to add it to the application bootstrap so it gets loaded
         $app->bootstrap[] = $moduleName;
         $app->bootstrap = array_unique($app->bootstrap, SORT_REGULAR);
     }
     if ($app->has('i18n')) {
         $app->i18n->translations['audit'] = ['class' => 'yii\\i18n\\PhpMessageSource', 'sourceLanguage' => 'en', 'basePath' => '@bedezign/yii2/audit/messages'];
     }
 }
Exemple #12
0
 /**
  * Check if the current user has access to the audit functionality
  * @return bool
  */
 public static function checkAccess()
 {
     $audit = Audit::getInstance();
     if ($audit->accessIps === null && $audit->accessRoles === null && $audit->accessUsers === null) {
         return true;
     }
     if (self::checkAccessIps($audit->accessIps)) {
         return true;
     }
     if (self::checkAccessRoles($audit->accessRoles)) {
         return true;
     }
     if (self::checkAccessUsers($audit->accessUsers)) {
         return true;
     }
     return false;
 }
    /**
     * 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();
    }
 /**
  * @param Exception $exception
  */
 public function logException($exception)
 {
     try {
         $isMemoryError = strncmp($exception->getMessage(), 'Allowed memory size of', 22) === 0;
         $module = Audit::getInstance();
         if (!$module && !$isMemoryError) {
             // Only attempt to load the module if this isn't an out of memory error, not enough room otherwise
             $module = \Yii::$app->getModule(Audit::findModuleIdentifier());
         }
         if (!$module) {
             throw new \Exception('Audit module cannot be loaded');
         }
         $entry = $module->getEntry(!$isMemoryError);
         if ($entry) {
             AuditError::log($entry, $exception);
             $entry->finalize();
         }
     } catch (\Exception $e) {
         // if we catch an exception here, let it slide, we don't want recursive errors killing the script
     }
     parent::logException($exception);
 }
 public function record()
 {
     $dataMap = ['_GET' => $_GET, '_POST' => $_POST, '_COOKIE' => $_COOKIE, '_SERVER' => $_SERVER, '_FILES' => $_FILES];
     if (Yii::$app->request instanceof \yii\web\Request) {
         if (!empty($_SESSION)) {
             $dataMap['_SESSION'] = $_SESSION;
         }
     } else {
         if (Yii::$app->request instanceof \yii\console\Request) {
             $dataMap['_PARAMS'] = Yii::$app->request->params;
         }
     }
     $entry = Audit::current()->getEntry();
     if ($entry) {
         $batchData = [];
         foreach ($this->logVars as $type) {
             $data = ArrayHelper::getValue($dataMap, $type);
             if ($data) {
                 $batchData[$type] = $data;
             }
         }
         $entry->addBatchData($batchData);
     }
 }
 /**
  * @return models\AuditEntry|null|static
  * @throws \Exception
  */
 protected function getAuditEntryId()
 {
     $module = Audit::getInstance();
     if (!$module) {
         $module = \Yii::$app->getModule(Audit::findModuleIdentifier());
     }
     if (!$module) {
         throw new \Exception('Audit module cannot be loaded');
     }
     return Audit::getInstance()->getEntry(true)->id;
 }
Exemple #17
0
    <?php 
$this->registerCss('body{padding-top: 60px;} .navbar-brand { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABsElEQVRIS82UwU3DQBBF5+8lR5IO0gFQAaGD0EGoAF+yu0dy804OMRUAFUAH0AEpIXQQbsnFi75kR8Y4wREJwpJlybveN//PH0OOfOHI58v/AYzH4zNjzCyEcLmP6tYKvPeDGONLCAHOuRhjXAJ4BjBJ03SxDboBsEIA96p6Xt3snJsDSPiuBFhrXwGcicgJ3wO4TtP0oQmyAVQrrAFY7cQY81oCynXv/SjGmBEUY7xS1ec65FcAHlb05o2WqWrvG8A5t4wxjowxfJYes6p+CGFY+N2ooDzMOcf9N00qyoZ9OYAe82NVHbQBlPbSSlW9rar4E0AGgBKZkiSEkFhrh8aYLpNB+fX1us/W2gTArClNO+eA0vM8vzDGvG+LYZIk3U6n88aerdfrXpZlyy8W7ZrK4mP241REqO6uur9YfxIRDuGjqo62xnQbqIghIcz6XETKrHdFZASAT9rLFF5Op1Pu2VytfhXe+36e5w8ALmqFfHDQAAypsgnSClCZ3D69Lu7FarWa0/OqlXXIXoC2/apCDgYgvEnJQQFNkIMDKhD+vhdHAewd013N/Wnt6Ao+AURRX/2e7CxYAAAAAElFTkSuQmCC") no-repeat 10px; padding-left: 40px; }');
?>
    <?php 
$this->head();
?>
</head>
<body>
<?php 
$this->beginBody();
?>

<?php 
NavBar::begin(['brandLabel' => Yii::t('audit', 'Audit'), 'brandUrl' => ['default/index'], 'options' => ['class' => 'navbar-default navbar-fixed-top navbar-fluid'], 'innerContainerOptions' => ['class' => 'container-fluid']]);
$items = [['label' => Yii::t('audit', 'Entries'), 'url' => ['entry/index']]];
foreach (Audit::getInstance()->panels as $panel) {
    /** @var Panel $panel */
    $indexUrl = $panel->getIndexUrl();
    if (!$indexUrl) {
        continue;
    }
    $items[] = ['label' => $panel->getName(), 'url' => $indexUrl];
}
echo Nav::widget(['items' => $items, 'options' => ['class' => 'navbar-nav']]);
echo Nav::widget(['items' => [['label' => Yii::$app->name, 'url' => Yii::$app->getHomeUrl()]], 'options' => ['class' => 'navbar-nav navbar-right']]);
NavBar::end();
?>

<div class="container-fluid">
    <?php 
if (isset($this->params['breadcrumbs'])) {
Exemple #18
0
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('audit', 'Trails');
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Audit'), 'url' => ['default/index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="box box-primary">
    <div class="box-header" style="cursor: pointer;">
        <i class="fa fa-th-list"></i>
        <h3 class="box-title"><?php 
echo Html::encode($this->title);
?>
</h3>
    </div>
    <div class="box-body">
        <div class="audit-trail">


            <?php 
echo GridView::widget(['dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'columns' => [['class' => 'yii\\grid\\ActionColumn', 'template' => '{view}'], 'id', ['attribute' => 'entry_id', 'class' => 'yii\\grid\\DataColumn', 'value' => function ($data) {
    return $data->entry_id ? Html::a($data->entry_id, ['entry/view', 'id' => $data->entry_id]) : '';
}, 'format' => 'raw'], ['attribute' => 'user_id', 'label' => Yii::t('audit', 'User ID'), 'class' => 'yii\\grid\\DataColumn', 'value' => function ($data) {
    return Audit::getInstance()->getUserIdentifier($data->user_id);
}, 'format' => 'raw'], ['attribute' => 'action', 'filter' => AuditTrailSearch::actionFilter()], 'model', 'model_id', 'field', ['label' => Yii::t('audit', 'Diff'), 'value' => function ($model) {
    return $model->getDiffHtml();
}, 'format' => 'raw'], ['attribute' => 'created', 'options' => ['width' => '150px']]]]);
?>
        </div>
    </div>
</div>

Exemple #19
0
 /**
  * @param string $className
  * @return bool|string
  */
 public static function findPanelIdentifier($className)
 {
     $audit = Audit::getInstance();
     foreach ($audit->panels as $panel) {
         if ($panel->className() == $className) {
             return $panel->id;
         }
     }
     return false;
 }
Exemple #20
0
use bedezign\yii2\audit\models\AuditTrail;
$this->title = Yii::t('audit', 'Entry #{id}', ['id' => $model->id]);
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Audit'), 'url' => ['default/index']];
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Entries'), 'url' => ['index']];
$this->params['breadcrumbs'][] = '#' . $model->id;
?>

<?php 
echo Html::tag('h1', $this->title);
?>

<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' => $model, 'attributes' => ['id', ['label' => $model->getAttributeLabel('user_id'), 'value' => Audit::current()->getUsername($model->user_id)], '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 ($model->extraData as $data) {
    $attributes = [];
    foreach ($data->data as $name => $value) {
        $attributes[] = ['label' => $name, 'value' => Helper::formatValue($value), 'format' => 'raw'];
    }
    echo Html::tag('h2', $data->type . ' (' . 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($model->trail)) {
    $dataProvider = new ActiveDataProvider(['query' => AuditTrail::find()->where(['entry_id' => $model->id]), 'pagination' => ['pageSize' => 1000]]);
    echo Html::tag('h2', Yii::t('audit', 'Trail ({i})', ['i' => count($model->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) {
Exemple #21
0
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Entries'), 'url' => ['index']];
$this->params['breadcrumbs'][] = '#' . $model->id;
?>

<?php 
echo Html::tag('h1', $this->title);
?>

    <div class="row">
        <div class="col-md-6">
            <?php 
echo Html::tag('h2', Yii::t('audit', 'Request'), ['id' => 'entry', 'class' => 'hashtag']);
if ($model->request_method == 'CLI') {
    $attributes = ['route', 'request_method'];
} else {
    $attributes = [['label' => $model->getAttributeLabel('user_id'), 'value' => Audit::getInstance()->getUserIdentifier($model->user_id), 'format' => 'raw'], 'ip', 'route', 'request_method', ['label' => $model->getAttributeLabel('ajax'), 'value' => $model->ajax ? Yii::t('audit', 'Yes') : Yii::t('audit', 'No')]];
}
echo DetailView::widget(['model' => $model, 'attributes' => $attributes]);
?>
        </div>
        <div class="col-md-6">
            <?php 
echo Html::tag('h2', Yii::t('audit', 'Profiling'), ['id' => 'entry', 'class' => 'hashtag']);
$attributes = [['attribute' => 'duration', 'format' => 'decimal'], ['attribute' => 'memory_max', 'format' => 'shortsize'], 'created'];
echo DetailView::widget(['model' => $model, 'attributes' => $attributes]);
?>
        </div>
    </div>

<?php 
Pjax::begin(['id' => 'audit-panels', 'timeout' => 0]);
Exemple #22
0
<?php

use bedezign\yii2\audit\Audit;
use yii\helpers\Html;
use yii\grid\GridView;
use yii\web\View;
use bedezign\yii2\audit\models\AuditTrailSearch;
/* @var $this yii\web\View */
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('audit', 'Trails');
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Audit'), 'url' => ['default/index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="audit-trail">

    <h1><?php 
echo Html::encode($this->title);
?>
</h1>

    <?php 
echo GridView::widget(['dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'columns' => [['class' => 'yii\\grid\\ActionColumn', 'template' => '{view}'], 'id', ['attribute' => 'entry_id', 'class' => 'yii\\grid\\DataColumn', 'value' => function ($data) {
    return $data->entry_id ? Html::a($data->entry_id, ['default/view', 'id' => $data->entry_id]) : '';
}, 'format' => 'raw'], ['attribute' => 'user_id', 'label' => Yii::t('audit', 'User ID'), 'class' => 'yii\\grid\\DataColumn', 'value' => function ($data) {
    return Audit::current()->getUsername($data->user_id);
}], ['attribute' => 'action', 'filter' => AuditTrailSearch::actionFilter()], 'model', 'model_id', 'field', ['label' => Yii::t('audit', 'Diff'), 'value' => function ($model) {
    return $model->getDiffHtml();
}, 'format' => 'raw'], 'stamp']]);
?>
</div>
<?php

use bedezign\yii2\audit\Audit;
use bedezign\yii2\audit\components\Access;
use yii\helpers\Html;
/** @var yii\web\View $this */
/** @var bedezign\yii2\audit\models\AuditEntry $entry */
if ($auditEntry = Audit::getInstance()->getEntry()) {
    if (!isset($style)) {
        $style = YII_DEBUG ? '' : 'color:transparent;';
    }
    if (Access::checkAccess()) {
        echo Html::a('audit-' . $auditEntry->id, ['/audit/entry/view', 'id' => $auditEntry->id], ['style' => $style]);
    } else {
        echo Html::tag('span', 'audit-' . $auditEntry->id, ['style' => $style]);
    }
}
Exemple #24
0
<?php

/** @var yii\web\View $this */
/** @var bedezign\yii2\audit\models\AuditTrail $model */
use bedezign\yii2\audit\Audit;
use yii\helpers\Html;
use yii\widgets\DetailView;
$this->title = Yii::t('audit', 'Trail #{id}', ['id' => $model->id]);
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Audit'), 'url' => ['default/index']];
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Trails'), 'url' => ['trail/index']];
$this->params['breadcrumbs'][] = '#' . $model->id;
echo Html::tag('h1', $this->title);
echo DetailView::widget(['model' => $model, 'attributes' => ['id', ['label' => $model->getAttributeLabel('user_id'), 'value' => Audit::current()->getUsername($model->user_id)], 'action', 'model', 'model_id', 'field', 'stamp']]);
echo Html::tag('h2', Yii::t('audit', 'Difference'));
echo $model->getDiffHtml();
 /**
  * Cleans the Panel data
  *
  * @param $id
  * @param $maxAge
  * @return bool
  */
 protected function cleanupPanel($id, $maxAge)
 {
     /** @var Panel $panel */
     $panel = Audit::getInstance()->getPanel($id);
     $age = $maxAge !== null ? $maxAge : $panel->maxAge;
     if ($age === null) {
         $this->stdout("\n*** skipped {$id}\n", Console::FG_PURPLE);
         return true;
     }
     $this->stdout("\n*** cleaning {$id}", Console::FG_YELLOW);
     $start = microtime(true);
     $count = $panel->cleanup($maxAge);
     if ($count !== false) {
         $time = microtime(true) - $start;
         $this->stdout("\n*** cleaned {$id} (records: " . $count . ", time: " . sprintf("%.3f", $time) . "s)\n", Console::FG_GREEN);
         return true;
     }
     $time = microtime(true) - $start;
     $this->stdout("\n*** failed to clean {$id} (time: " . sprintf("%.3f", $time) . "s)\n", Console::FG_RED);
     return false;
 }
 public static function getDb()
 {
     return Audit::current() ? Audit::current()->getDb() : parent::getDb();
 }
Exemple #27
0
<?php

/** @var yii\web\View $this */
/** @var bedezign\yii2\audit\models\AuditTrail $model */
use bedezign\yii2\audit\Audit;
use yii\helpers\Html;
use yii\widgets\DetailView;
$this->title = Yii::t('audit', 'Trail #{id}', ['id' => $model->id]);
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Audit'), 'url' => ['default/index']];
$this->params['breadcrumbs'][] = ['label' => Yii::t('audit', 'Trails'), 'url' => ['trail/index']];
$this->params['breadcrumbs'][] = '#' . $model->id;
?>
<div class="box box-primary">
    <div class="box-header" style="cursor: pointer;">
        <i class="fa fa-info-circle"></i>
        <h3 class="box-title"><?php 
echo Html::encode($this->title);
?>
</h3>
    </div>
    <div class="box-body">
    <?php 
echo DetailView::widget(['model' => $model, 'attributes' => ['id', ['label' => $model->getAttributeLabel('user_id'), 'value' => Audit::getInstance()->getUserIdentifier($model->user_id), 'format' => 'raw'], ['attribute' => 'entry_id', 'value' => $model->entry_id ? Html::a($model->entry_id, ['entry/view', 'id' => $model->entry_id]) : '', 'format' => 'raw'], 'action', 'model', 'model_id', 'field', 'created']]);
echo Html::tag('h2', Yii::t('audit', 'Difference'));
echo $model->getDiffHtml();
?>
    </div>
</div>

 /**
  * @return \yii\db\Connection
  */
 public static function getDb()
 {
     return Audit::getInstance()->getDb();
 }
<?php

use bedezign\yii2\audit\Audit;
use yii\helpers\Html;
use Yii;
/** @var yii\web\View $this */
/** @var bedezign\yii2\audit\models\AuditEntry $entry */
if ($auditEntry = Audit::current()->getEntry()) {
    $style = YII_DEBUG ? '' : 'color:transparent;';
    if (Yii::$app->audit->checkAccess()) {
        echo Html::a('audit-' . $auditEntry->id, ['/audit/default/view', 'id' => $auditEntry->id], ['style' => $style]);
    } else {
        echo Html::tag('span', 'audit-' . $auditEntry->id, ['style' => $style]);
    }
}
Exemple #30
0
 /**
  * @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();
     }
 }