Completed
Push — master ( 42d56d...da4528 )
by Corey
03:35
created

CheckinController::actionQuestions()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 32
rs 9.0111
c 0
b 0
f 0
cc 6
nc 5
nop 0
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
      $form->compiled_behaviors = $form->compileBehaviors();
41
42
      if(sizeof($form->compiled_behaviors) === 0) {
43
        return $this->redirect(['view']);
44
      }
45
46
      // we only store one data set per day, so wipe out previously saved ones
47
      $form->deleteToday();
48
      $form->save();
49
50
      return $this->redirect(['questions']);
51
    } else {
52
      $behaviors  = Yii::$container->get(BehaviorInterface::class)::$behaviors;
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
      ]);
58
    }
59
  }
60
61
  public function actionQuestions()
62
  {
63
    $user_behavior = Yii::$container->get(UserBehaviorInterface::class);
64
    $date = Yii::$container->get(TimeInterface::class)->getLocalDate();
65
66
    $user_behaviors = $user_behavior->getUserBehaviorsWithCategory($date);
67
    if(count($user_behaviors) === 0) {
68
      return $this->redirect(['view']);
69
    }
70
71
    $form = Yii::$container->get(\site\models\QuestionForm::class);
72
    if ($form->load(Yii::$app->request->post()) && $form->validate()) {
73
      // we only store one data set per day so clear out any previously saved ones
74
      $form->deleteToday();
75
76
      $behaviors = $user_behavior->findAll($form->getUserBehaviorIds());
77
      if($result = $form->saveAnswers($behaviors)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
78
79
        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...
80
          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

80
          Yii::$app->user->identity->/** @scrutinizer ignore-call */ 
81
                                     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...
Bug introduced by
The method sendEmailReport() does not exist on yii\web\IdentityInterface. It seems like you code against a sub-type of said class. However, the method does not exist in site\tests\_support\MockUser. Are you sure you never get one of those? ( 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->user->identity->/** @scrutinizer ignore-call */ 
81
                                     sendEmailReport($date);
Loading history...
81
          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

81
          Yii::$app->session->/** @scrutinizer ignore-call */ 
82
                              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...
82
        } else {
83
          Yii::$app->session->setFlash('success', 'Your check-in is complete.');
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
  {
98
    $time = Yii::$container->get(\common\interfaces\TimeInterface::class);
99
    $date = $time->validate($date);
100
    $dt = $time->parse($date);
101
    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...
102
103
    $user          = Yii::$container->get(UserInterface::class);
104
    $user_behavior = Yii::$container->get(UserBehaviorInterface::class);
105
    $categories    = Yii::$container->get(CategoryInterface::class)::$categories;
106
    $behaviors     = Yii::$container->get(BehaviorInterface::class)::$behaviors;
107
108
    $form = Yii::$container->get(\site\models\CheckinForm::class);
109
    $form->setBehaviors($user->getUserBehaviors($date));
110
111
    $raw_pie_data = $user_behavior::decorateWithCategory($user_behavior->getBehaviorsWithCounts($dt));
112
    $answer_pie = $user_behavior->getBehaviorsByCategory($raw_pie_data);
113
114
    return $this->render('view', [
115
      'model'              => $form,
116
      'actual_date'        => $date,
117
      'categories'         => $categories,
118
      'behaviorsList'      => AH::index($behaviors, 'name', "category_id"),
119
      'past_checkin_dates' => $user_behavior->getPastCheckinDates(),
120
      'answer_pie'         => $answer_pie,
121
      'questions'          => $user->getUserQuestions($date),
122
      'isToday'            => $time->getLocalDate() === $date,
123
    ]);
124
  }
125
126
  public function actionReport() {
127
    /* Pie Chart data */
128
    $user_behavior = Yii::$container->get(\common\interfaces\UserBehaviorInterface::class);
129
    $user_rows     = $user_behavior::decorateWithCategory($user_behavior->getBehaviorsWithCounts(5));
130
    $raw_pie_data  = $user_behavior::decorateWithCategory($user_behavior->getBehaviorsWithCounts());
131
    $answer_pie    = $user_behavior->getBehaviorsByCategory($raw_pie_data);
132
133
    $pie_data   = [
134
      "labels"   => array_column($answer_pie, "name"),
135
      "datasets" => [[
136
          "data"                 => array_map('intval', array_column($answer_pie, "count")),
137
          "backgroundColor"      => array_column($answer_pie, "color"),
138
          "hoverBackgroundColor" => array_column($answer_pie, "highlight"),
139
      ]]
140
    ];
141
142
    /* Bar Chart data */
143
    ['labels' => $labels, 'datasets' => $datasets] = $this->history(30);
144
145
    return $this->render('report', [
146
      'top_behaviors' => $user_rows,
147
      'pie_data' => $pie_data,
148
      'bar_dates' => $labels,
149
      'bar_datasets' => $datasets,
150
    ]);
151
  }
152
153
  public function actionHistory($period) {
154
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
155
    $period = intval($period);
156
    $whitelist_periods = [30, 90, 180];
157
    $period = in_array($period, $whitelist_periods) ? $period : 30;
158
    return $this->history($period);
159
  }
160
161
  private function history($period) {
162
    $user_behavior = Yii::$container->get(UserBehaviorInterface::class);
163
    $category      = Yii::$container->get(\common\interfaces\CategoryInterface::class);
164
165
    $checkins = $user_behavior->getCheckInBreakdown($period);
166
167
    $accum = [];
168
    foreach($checkins as $date => $cats) {
169
      for($i = 1; $i <= 7; $i ++) {
170
        $accum[$i][] = array_key_exists($i, $cats) ? $cats[$i]['count'] : [];
171
      }
172
    }
173
174
    $bar_datasets = [];
175
    foreach($accum as $idx => $data) {
176
      $bar_datasets[] = [
177
        'label' => ($category::getCategories())[$idx],
178
        'backgroundColor' => $category::$colors[$idx]['color'],
179
        'data' => $data
180
      ];
181
    }
182
    return [
183
      'labels' => array_keys($checkins),
184
      'datasets' => $bar_datasets,
185
    ];
186
  }
187
}
188