CheckinController::history()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 24
rs 9.4222
c 0
b 0
f 0
cc 5
nc 8
nop 1
1
<?php
2
3
namespace site\controllers;
4
5
use Yii;
6
use common\interfaces\UserInterface;
7
use common\interfaces\UserBehaviorInterface;
8
use common\interfaces\CategoryInterface;
9
use common\interfaces\BehaviorInterface;
10
use common\interfaces\TimeInterface;
11
use yii\di\Container;
12
use yii\base\InvalidParamException;
13
use yii\web\BadRequestHttpException;
14
use common\components\Controller;
15
use yii\filters\VerbFilter;
16
use common\components\AccessControl;
17
use yii\helpers\ArrayHelper as AH;
18
19
class CheckinController extends Controller
20
{
21
  public function behaviors()
22
  {
23
    return [
24
      'access' => [
25
        'class' => AccessControl::class,
26
        'only' => ['index', 'view', 'questions', 'report', 'history'],
27
        'rules' => [
28
          [
29
            'actions' => ['index', 'view', 'questions', 'report', 'history'],
30
            'allow' => true,
31
            'roles' => ['@'],
32
          ],
33
        ],
34
      ],
35
    ];
36
  }
37
  public function actionIndex() {
38
    $form = Yii::$container->get(\site\models\CheckinForm::class);
39
    if ($form->load(Yii::$app->request->post()) && $form->validate()) {
40
      if(!$form->compileBehaviors()) {
41
        return $this->redirect(['view']);
42
      }
43
44
      // we only store one data set per day, so wipe out previously saved ones
45
      $form->deleteToday();
46
      $form->save();
47
48
      return $this->redirect(['questions']);
49
    }
50
51
    $behaviors  = Yii::$container->get(BehaviorInterface::class)::$behaviors;
52
    $custom = \common\models\CustomBehavior::find()->where(['user_id' => Yii::$app->user->id])->asArray()->all();
53
    return $this->render('index', [
54
      'categories'    => Yii::$container->get(CategoryInterface::class)::$categories,
55
      'model'         => $form,
56
      'behaviorsList' => AH::index($behaviors, null, "category_id"),
57
      'customList' => AH::index($custom, null, "category_id")
58
    ]);
59
  }
60
61
  public function actionQuestions() {
62
    $user_behavior = Yii::$container->get(UserBehaviorInterface::class);
63
    $date = Yii::$container->get(TimeInterface::class)->getLocalDate();
64
65
    $user_behaviors = $user_behavior->getUserBehaviorsWithCategory($date);
66
    if(count($user_behaviors) === 0) {
67
      return $this->redirect(['view']);
68
    }
69
70
    $form = Yii::$container->get(\site\models\QuestionForm::class);
71
    if ($form->load(Yii::$app->request->post()) && $form->validate()) {
72
      // we only store one data set per day so clear out any previously saved ones
73
      $form->deleteToday(Yii::$app->user->id);
74
75
      $behaviors = $user_behavior->findAll($form->getUserBehaviorIds());
76
      if($result = $form->saveAnswers(Yii::$app->user->id, $behaviors)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
77
78
        if(Yii::$app->user->identity->send_email) {
0 ignored issues
show
Bug introduced by
Accessing send_email on the interface yii\web\IdentityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
79
          if(Yii::$app->user->identity->sendEmailReport($date)) {
0 ignored issues
show
Bug introduced by
The method sendEmailReport() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

79
          if(Yii::$app->user->identity->/** @scrutinizer ignore-call */ sendEmailReport($date)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
80
            Yii::$app->session->setFlash('success', 'Your check-in is complete. A notification has been sent to your report partners.');
0 ignored issues
show
Bug introduced by
The method setFlash() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

80
            Yii::$app->session->/** @scrutinizer ignore-call */ 
81
                                setFlash('success', 'Your check-in is complete. A notification has been sent to your report partners.');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
81
          } else {
82
            Yii::$app->session->setFlash('success', 'Your check-in is complete.');
83
          }
84
        }
85
86
        return $this->redirect(['view']);
87
      }
88
    }
89
90
    return $this->render('questions', [
91
      'model' => $form,
92
      'behaviors' => $user_behaviors
93
    ]);	
94
  }
95
96
  public function actionView(string $date = null) {
97
    $time = Yii::$container->get(\common\interfaces\TimeInterface::class);
98
    $date = $time->validate($date);
99
    $dt = $time->parse($date);
100
    list($start, $end) = $time->getUTCBookends($date);
0 ignored issues
show
Comprehensibility Best Practice introduced by
This list assign is not used and could be removed.
Loading history...
101
102
    $user          = Yii::$container->get(UserInterface::class);
0 ignored issues
show
Unused Code introduced by
The assignment to $user is dead and can be removed.
Loading history...
103
    $user_behavior = Yii::$container->get(UserBehaviorInterface::class);
104
    $categories    = Yii::$container->get(CategoryInterface::class)::$categories;
105
    $question      = Yii::$container->get(\common\interfaces\QuestionInterface::class);
106
107
    $user_behaviors = $user_behavior->getByDate(Yii::$app->user->id, $date);
108
    $form = Yii::$container->get(\site\models\CheckinForm::class);
109
110
    $form_behaviors = $form->mergeWithDefault($user_behaviors);
111
    $form->setBehaviors($user_behaviors);
112
113
    $raw_pie_data = $user_behavior::decorate($user_behavior->getBehaviorsWithCounts($dt));
114
    $answer_pie = $user_behavior->getBehaviorsByCategory($raw_pie_data);
115
116
    return $this->render('view', [
117
      'model'              => $form,
118
      'actual_date'        => $date,
119
      'categories'         => $categories,
120
      'behaviorsList'      => $form_behaviors,
121
      'past_checkin_dates' => $user_behavior->getPastCheckinDates(),
122
      'answer_pie'         => $answer_pie,
123
      'questions'          => $question->getByUser(Yii::$app->user->id, $date),
124
      'isToday'            => $time->getLocalDate() === $date,
125
    ]);
126
  }
127
128
  public function actionReport() {
129
    /* Pie Chart data */
130
    $user_behavior = Yii::$container->get(UserBehaviorInterface::class);
131
    $user_rows     = $user_behavior::decorate($user_behavior->getBehaviorsWithCounts(5));
132
    $raw_pie_data  = $user_behavior::decorate($user_behavior->getBehaviorsWithCounts());
133
    $answer_pie    = $user_behavior->getBehaviorsByCategory($raw_pie_data);
134
135
    $pie_data   = [
136
      "labels"   => array_column($answer_pie, "name"),
137
      "datasets" => [[
138
          "data"                 => array_map('intval', array_column($answer_pie, "count")),
139
          "backgroundColor"      => array_column($answer_pie, "color"),
140
          "hoverBackgroundColor" => array_column($answer_pie, "highlight"),
141
      ]]
142
    ];
143
144
    /* Bar Chart data */
145
    ['labels' => $labels, 'datasets' => $datasets] = $this->history(30);
146
147
    return $this->render('report', [
148
      'top_behaviors' => $user_rows,
149
      'pie_data' => $pie_data,
150
      'bar_dates' => $labels,
151
      'bar_datasets' => $datasets,
152
    ]);
153
  }
154
155
  public function actionHistory($period) {
156
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
157
    $period = intval($period);
158
    $whitelist_periods = [30, 90, 180];
159
    $period = in_array($period, $whitelist_periods) ? $period : 30;
160
    return $this->history($period);
161
  }
162
163
  private function history($period) {
164
    $user_behavior = Yii::$container->get(UserBehaviorInterface::class);
165
    $category      = Yii::$container->get(CategoryInterface::class);
166
167
    $checkins = $user_behavior->getCheckInBreakdown($period);
168
169
    $accum = [];
170
    foreach($checkins as $date => $cats) {
171
      for($i = 1; $i <= 7; $i ++) {
172
        $accum[$i][] = array_key_exists($i, $cats) ? $cats[$i]['count'] : [];
173
      }
174
    }
175
176
    $bar_datasets = [];
177
    foreach($accum as $idx => $data) {
178
      $bar_datasets[] = [
179
        'label' => ($category::getCategories())[$idx],
180
        'backgroundColor' => $category::$colors[$idx]['color'],
181
        'data' => $data
182
      ];
183
    }
184
    return [
185
      'labels' => array_keys($checkins),
186
      'datasets' => $bar_datasets,
187
    ];
188
  }
189
}
190