public function actionAnswer() { if (Yii::$app->request->isAjax && ($data = Yii::$app->request->post('vote')) !== null) { $options = VoteOption::find()->where(['in', 'id', array_keys(Yii::$app->request->post('vote'))])->all(); if (empty($options)) { throw new BadRequestHttpException(Yii::t('f/vote', 'Request error')); } $voteId = false; foreach ($options as $option) { /** var VoteOption $option */ if ($voteId && $option->parent_id != $voteId) { throw new BadRequestHttpException(Yii::t('f/vote', 'Request error')); } elseif (!$voteId) { $voteId = $option->parent_id; } } if (!$voteId || ($vote = Vote::find()->active()->language()->where(['id' => $voteId])->one()) === null) { throw new BadRequestHttpException(Yii::t('f/vote', 'Request error')); } /** @var Vote $vote */ if ($vote->type == Vote::TYPE_SINGLE && count($options) > 1) { throw new BadRequestHttpException(Yii::t('f/vote', 'Request error')); } if ($vote->isVoted()) { throw new BadRequestHttpException(Yii::t('f/vote', 'Request error')); } $transaction = Yii::$app->db->beginTransaction(); try { foreach ($options as $option) { $voteLog = new VoteLog(); $voteLog->addAnswer($voteId, $option->id); } $vote->statistics(); $transaction->commit(); } catch (Exception $e) { $transaction->rollBack(); throw new BadRequestHttpException(Yii::t('f/vote', 'Request error')); } return $this->render('_vote', ['vote' => $vote, 'options' => $vote->voteOptions, 'isVoted' => true, 'maxPercent' => $vote->getMaxPercent()]); } else { throw new BadRequestHttpException(Yii::t('f/vote', 'Request error')); } }
public function statistics() { $statistics = []; $totalAnswers = 0; $rows = (new \yii\db\Query())->select('option_id, count(*) as cnt')->from(VoteLog::tableName())->where(['vote_id' => $this->id])->groupBy('option_id')->all(); foreach ($rows as $row) { $statistics[$row['option_id']] = $row['cnt']; $totalAnswers += $row['cnt']; } if ($this->type == self::TYPE_SINGLE) { $totalCnt = $totalAnswers; } else { $totalCnt = (new \yii\db\Query())->select('count(distinct(ip)) as cnt')->from(VoteLog::tableName())->where(['vote_id' => $this->id])->one(); } $this->setAttribute('total_votes', $totalCnt); $this->setAttribute('total_answers', $totalAnswers); if ($this->save() && !empty($this->voteOptions) > 0) { foreach ($this->voteOptions as $k => $voteOptions) { if ($totalAnswers > 0 && isset($statistics[$voteOptions->id])) { $this->voteOptions[$k]->setAttributes(['total_votes' => $statistics[$voteOptions->id], 'percent' => round($statistics[$voteOptions->id] / $totalAnswers * 100, 2)]); } else { $this->voteOptions[$k]->setAttributes(['total_votes' => 0, 'percent' => 0]); } $this->voteOptions[$k]->save(); } CacheHelper::set(Vote::VOTE_OPTIONS_CACHE_KEY . $this->id, $this->voteOptions, CacheHelper::getTag(Vote::className())); } }
/** * @return \yii\db\ActiveQuery */ public function getVoteLogs() { return $this->hasMany(VoteLog::className(), ['option_id' => 'id']); }