diff --git a/src/components/panels/RendersSummaryChartTrait.php b/src/components/panels/RendersSummaryChartTrait.php index 83ef4bd4..9334dc72 100644 --- a/src/components/panels/RendersSummaryChartTrait.php +++ b/src/components/panels/RendersSummaryChartTrait.php @@ -31,21 +31,31 @@ protected function getChartModel() * * @return array */ - protected function getChartData() + protected function getChartData($start = null, $end = null) { //initialise defaults (0 entries) for each day $defaults = []; - $startDate = strtotime('-6 days'); - foreach (range(-6, 0) as $day) { - $defaults[date('D: Y-m-d', strtotime($day . 'days'))] = 0; + if(!$start && !$end) { + $startDate = date('Y-m-d 00:00:00', strtotime('-6 days')); + $endDate = date('Y-m-d 23:59:59'); + foreach (range(-6, 0) as $day) { + $defaults[date('D: Y-m-d', strtotime($day . 'days'))] = 0; + } + } else { + $startDate = date('Y-m-d 00:00:00', strtotime($start)); + $endDate = date('Y-m-d 23:59:59', strtotime($end)); + $days = round(((strtotime($endDate) - strtotime($startDate))/ (60 * 60 * 24))-1); + foreach (range(0, $days) as $day) { + $defaults[date('D: Y-m-d', strtotime($startDate.'+' .$day . 'days'))] = 0; + } } $panelModel = $this->getChartModel(); $results = $panelModel::find() ->select(["COUNT(DISTINCT id) as count", "created AS day"]) ->where(['between', 'created', - date('Y-m-d 00:00:00', $startDate), - date('Y-m-d 23:59:59')]) + $startDate, + $endDate]) ->groupBy("created")->indexBy('day')->column(); // replace defaults with data from db where available diff --git a/src/controllers/DefaultController.php b/src/controllers/DefaultController.php index b53dcd15..447b06f0 100644 --- a/src/controllers/DefaultController.php +++ b/src/controllers/DefaultController.php @@ -5,6 +5,8 @@ use bedezign\yii2\audit\components\panels\RendersSummaryChartTrait; use bedezign\yii2\audit\components\web\Controller; use bedezign\yii2\audit\models\AuditEntry; +use bedezign\yii2\audit\models\AuditEntrySearch; +use bedezign\yii2\audit\models\AuditTrailSearch; use Yii; /** @@ -21,8 +23,15 @@ class DefaultController extends Controller */ public function actionIndex() { - $chartData = $this->getChartData(); - return $this->render('index', ['chartData' => $chartData]); + $startDate = $endDate = null; + $searchModel = new AuditEntrySearch(); + if(isset(Yii::$app->request->queryParams['AuditEntrySearch'])){ + $startDate = Yii::$app->request->queryParams['AuditEntrySearch']['start_date']; + $endDate = Yii::$app->request->queryParams['AuditEntrySearch']['end_date']; + } + $chartData = $this->getChartData($startDate, $endDate); + $searchTrailModel = new AuditTrailSearch(); + return $this->render('index', ['model' => $searchModel, 'chartData' => $chartData, 'trailModel' => $searchTrailModel]); } protected function getChartModel() diff --git a/src/models/AuditEntrySearch.php b/src/models/AuditEntrySearch.php index 69e8ae08..16e71658 100644 --- a/src/models/AuditEntrySearch.php +++ b/src/models/AuditEntrySearch.php @@ -13,6 +13,7 @@ */ class AuditEntrySearch extends AuditEntry { + public $start_date, $end_date; /** * @return array */ @@ -20,7 +21,9 @@ public function rules() { // only fields in rules() are searchable return [ - [['id', 'user_id', 'ip', 'created', 'duration', 'memory_max', 'route', 'request_method', 'ajax'], 'safe'], + [['id', 'user_id', 'ip', 'created', 'duration', 'memory_max', 'route', 'request_method', 'ajax', 'start_date', 'end_date'], 'safe'], + ['start_date', 'validateDate'], + ['end_date', 'validateDate'] ]; } @@ -39,7 +42,9 @@ public function scenarios() */ public function search($params) { - $query = AuditEntry::find()->where(['NOT LIKE', 'route', 'site/login']); + $query = AuditEntry::find() + ->where(['NOT LIKE', 'route', 'site/login']) + ->andWhere(['NOT LIKE', 'request_method', 'CLI']); $dataProvider = new ActiveDataProvider([ 'query' => $query, @@ -103,6 +108,15 @@ public function searchAccessLog($params) return $dataProvider; } + public function validateDate($attribute) + { + $dateTime = DateTime::createFromFormat('Y/m/d', $this->$attribute); + $errors = DateTime::getLastErrors(); + if (!empty($errors['warning_count'])) { + $this->addError($attribute, 'Invalid date'); + } + } + /** * @return array */ @@ -125,6 +139,7 @@ static public function methodFilter() $methods = AuditEntry::getDb()->cache(function () { return AuditEntry::find()->distinct(true) ->select('request_method')->where(['is not', 'request_method', null]) + ->where(['NOT LIKE', 'request_method', 'CLI']) ->groupBy('request_method')->orderBy('request_method ASC')->column(); }, 240); return array_combine($methods, $methods); diff --git a/src/models/AuditTrailSearch.php b/src/models/AuditTrailSearch.php index b2391cfb..9495f841 100644 --- a/src/models/AuditTrailSearch.php +++ b/src/models/AuditTrailSearch.php @@ -2,7 +2,7 @@ namespace bedezign\yii2\audit\models; - +use bedezign\yii2\audit\Audit; use yii\base\Model; use yii\data\ActiveDataProvider; @@ -12,6 +12,7 @@ */ class AuditTrailSearch extends AuditTrail { + public $start_date, $end_date; /** * @return array */ @@ -19,7 +20,7 @@ public function rules() { // Note: The model is used by both the entry and the trail index pages, hence the separate use of `id` and `entry_id` return [ - [['id', 'user_id', 'entry_id', 'action', 'model', 'model_id', 'field', 'created'], 'safe'], + [['id', 'user_id', 'entry_id', 'action', 'model', 'model_id', 'field', 'created', 'start_date', 'end_date'], 'safe'], ]; } @@ -56,13 +57,14 @@ public function search($params, $query = null) } // adjust the query by adding the filters - $userId = $this->user_id; - if (strlen($this->user_id)) - $userId = intval($this->user_id) ?: 0; + // $userId = $this->user_id; + // if (strlen($this->user_id)) + // $userId = intval($this->user_id) ?: 0; $query->andFilterWhere(['id' => $this->id]); + $this->filterUserId($this->user_id, $query); $query->andFilterWhere(['entry_id' => $this->entry_id]); - $query->andFilterWhere(['user_id' => $userId]); + // $query->andFilterWhere(['user_id' => $userId]); $query->andFilterWhere(['action' => $this->action]); $query->andFilterWhere(['like', 'model', $this->model]); $query->andFilterWhere(['model_id' => $this->model_id]); @@ -87,4 +89,20 @@ static public function actionFilter() 'action' ); } + + /** + * @param $userId + * @param ActiveQuery $query + */ + protected function filterUserId($userId, $query) + { + if (strlen($userId)) { + if (!is_numeric($userId) && $callback = Audit::getInstance()->userFilterCallback) { + $userId = call_user_func($callback, $userId); + } else { + $userId = intval($userId) ?: 0; + } + $query->andWhere(['user_id' => $userId]); + } + } } diff --git a/src/panels/TrailPanel.php b/src/panels/TrailPanel.php index 32c44589..d28a4361 100644 --- a/src/panels/TrailPanel.php +++ b/src/panels/TrailPanel.php @@ -80,11 +80,17 @@ protected function getChartModel() /** * @inheritdoc */ - public function getChart() + public function getChart($request = null) { + $start = $end = null; + if($request){ + $start = Yii::$app->request->queryParams['AuditTrailSearch']['start_date']; + $end = Yii::$app->request->queryParams['AuditTrailSearch']['end_date']; + } + return \Yii::$app->view->render('panels/trail/chart', [ - 'panel' => $this, - 'chartData' => $this->getChartData() + 'start' => $start, + 'end' => $end, ]); } diff --git a/src/views/default/index.php b/src/views/default/index.php index b559c2b9..1862c28f 100644 --- a/src/views/default/index.php +++ b/src/views/default/index.php @@ -4,11 +4,13 @@ use bedezign\yii2\audit\components\panels\Panel; use dosamigos\chartjs\ChartJs; use yii\helpers\Html; +use yii\widgets\ActiveForm; +use yii\web\View; /* @var $this yii\web\View */ /* @var $dataProvider yii\data\ActiveDataProvider */ -$this->title = Yii::t('audit', 'Audit Module'); +$this->title = Yii::t('audit', 'Summary'); $this->params['breadcrumbs'][] = $this->title; $this->registerCss('canvas {width: 100% !important;height: 400px;}'); @@ -19,8 +21,35 @@