/** * @return array */ public static function methodFilter() { $methods = AuditEntry::getDb()->cache(function () { return AuditEntry::find()->distinct(true)->select('request_method')->where(['is not', 'request_method', null])->groupBy('request_method')->orderBy('request_method ASC')->column(); }, 240); return array_combine($methods, $methods); }
public function actionLog() { \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $data = \yii\helpers\Json::decode(\Yii::$app->request->post('data')); $entry = null; if (isset($data['auditEntry'])) { $entry = models\AuditEntry::findOne($data['auditEntry']); } else { return ['result' => 'error', 'message' => 'No audit entry to attach to']; } // Convert data into the loggable object $javascript = new models\AuditJavascript(); $map = ['auditEntry' => 'audit_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']; } return ['result' => 'error', 'errors' => $javascript->getErrors()]; }
public static function routeFilter() { $routes = AuditEntry::getDb()->cache(function ($db) { return AuditEntry::find()->distinct(true)->select('route')->where(['is not', 'route', null])->groupBy('route')->orderBy('route ASC')->column(); }, 30); return array_combine($routes, $routes); }
/** * Displays a single AuditEntry model. * @param integer $id * @return mixed * @throws \HttpInvalidParamException */ public function actionView($id) { $model = AuditEntry::findOne($id); if (!$model) { throw new \HttpInvalidParamException('Invalid request number specified'); } return $this->render('view', ['model' => $model]); }
/** * Displays a single AuditEntry model. * @param integer $id * @return mixed */ public function actionView($id) { $entry = AuditEntry::findOne($id); if ($entry) { return $this->render('view', ['entry' => $entry]); } else { throw new \HttpInvalidParamException('Invalid request number specified'); } $this->redirect(['index']); }
public function safeUp() { $this->addColumn(self::TABLE, 'request_method', 'varchar(255) NULL AFTER memory_max'); $this->createIndex('idx_audit_entry_request_method', self::TABLE, ['request_method']); echo " > filling 'request_method' from data ..."; $time = microtime(true); foreach (\bedezign\yii2\audit\models\AuditEntry::find()->batch() as $auditEntries) { foreach ($auditEntries as $auditEntry) { $auditEntry->request_method = \yii\helpers\ArrayHelper::getValue($auditEntry->data, 'env.REQUEST_METHOD'); if (!$auditEntry->request_method) { $auditEntry->request_method = 'CLI'; } $auditEntry->save(false, ['request_method']); } } echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; }
/** * Clean up the audit data according to the settings. */ public function actionCleanup() { /** @var Audit $audit */ $audit = Yii::$app->getModule('audit'); if ($audit->maxAge === null) { return; } $entry = AuditEntry::tableName(); $errors = AuditError::tableName(); $data = AuditData::tableName(); $javascript = AuditJavascript::tableName(); $threshold = time() - $audit->maxAge * 86400; AuditEntry::getDb()->createCommand(<<<SQL DELETE FROM {$entry}, {$errors}, {$data}, {$javascript} 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 WHERE {$entry}.created < FROM_UNIXTIME({$threshold}) SQL )->execute(); }
/** * @param $id * @return [AuditEntry, Panel[]] * @throws NotFoundHttpException */ public function loadData($id) { /** @var AuditEntry $model */ $model = AuditEntry::findOne($id); if (!$model) { throw new NotFoundHttpException('The requested entry does not exist.'); } // Why the separate panel list here? // Because we don't want to interfere with the modules' regular configuration. // We might as well be viewing an entry that has data for more panels than those who are currently active. // Updating the actual module panels would mean that for all audit viewing that panel would become active again $panels = $this->module->loadPanels($this->module->panelIdentifiers); $activePanels = []; $data = \yii\helpers\ArrayHelper::getColumn($model->data, 'data'); foreach ($panels as $panelId => $panel) { if ($panel->hasEntryData($model)) { $panel->tag = $id; $panel->model = $model; $panel->load(isset($data[$panelId]) ? $data[$panelId] : null); $activePanels[$panelId] = $panel; } } return [$model, $activePanels]; }
use dosamigos\chartjs\ChartJs; 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; // } // } //} ?>
/** * @return \yii\db\ActiveQuery */ public function getEntry() { return $this->hasOne(AuditEntry::className(), ['id' => 'entry_id']); }
/** * Clean up the audit data according to the settings. * Can be handy if you are offloading the data somewhere and want to keep only the most recent entries readily available */ public function truncate() { if ($this->maxAge === null) { return; } $entry = models\AuditEntry::tableName(); $errors = models\AuditError::tableName(); $data = models\AuditData::tableName(); $javascript = models\AuditJavascript::tableName(); $threshold = time() - $this->maxAge * 86400; models\AuditEntry::getDb()->createCommand(<<<SQL DELETE FROM {$entry}, {$errors}, {$data}, {$javascript} USING {$entry} INNER JOIN {$errors} ON {$errors}.audit_id = {$entry}.id INNER JOIN {$data} ON {$data}.audit_id = {$entry}.id INNER JOIN {$javascript} ON {$javascript}.audit_id = {$entry}.id WHERE {$entry}.created < FROM_UNIXTIME({$threshold}) SQL )->execute(); }
/** * @param bool $create * @param bool $new * @return AuditEntry|static */ public function getEntry($create = false, $new = false) { if (!$this->_entry && $create || $new) { $this->_entry = AuditEntry::create(true); } return $this->_entry; }
/** * @param bool $create * @return models\AuditEntry|static */ public function getEntry($create = false) { if (!$this->_entry && $create) { $this->_entry = models\AuditEntry::create(true); $this->callProviderQueue('record'); } return $this->_entry; }
/** * Cleans the AuditEntry data * * @param $maxAge * @return bool */ protected function cleanupEntry($maxAge) { $maxAge = $maxAge !== null ? $maxAge : Audit::getInstance()->maxAge; if ($maxAge === null) { $this->stdout("\n*** skipped AuditEntry\n", Console::FG_PURPLE); return true; } $date = date('Y-m-d 23:59:59', strtotime("-{$maxAge} days")); $this->stdout("\n*** cleaning AuditEntry", Console::FG_YELLOW); $start = microtime(true); $count = AuditEntry::deleteAll(['<=', 'created', $date]); if ($count !== false) { $time = microtime(true) - $start; $this->stdout("\n*** cleaned AuditEntry (records: " . $count . ",time: " . sprintf("%.3f", $time) . "s)\n", Console::FG_GREEN); return true; } $time = microtime(true) - $start; $this->stdout("\n*** failed to clean AuditEntry (time: " . sprintf("%.3f", $time) . "s)\n", Console::FG_RED); return false; }
/** * @param bool $create * @param bool $new * @return AuditEntry|static */ public function getEntry($create = false, $new = false) { $entry = new AuditEntry(); $tableSchema = $entry->getDb()->schema->getTableSchema($entry->tableName()); if ($tableSchema) { if (!$this->_entry && $create || $new) { $this->_entry = AuditEntry::create(true); } } return $this->_entry; }
/** * @return mixed * @throws \Exception */ protected static function filterData() { return AuditEntry::getDb()->cache(function () { return AuditError::find()->distinct(true)->select(['hash', 'message', 'file'])->asArray()->all(); }, 30); }