public function validateAnswers($attribute) { if ($attribute !== 'answers') { return true; } $answers = $this->{$attribute}; $questionnaire = Questionnaire::findByPk($this->questionnaireId); $answeredQuestions = []; foreach ($answers as &$answer) { $answer['questionId'] = new MongoId($answer['questionId']); if (!isset($answer['questionId']) || !isset($answer['type']) || !isset($answer['value'])) { throw new BadRequestHttpException(Yii::t('content', 'invalid_answer')); } if (!in_array($answer['questionId'], $questionnaire->questions)) { throw new BadRequestHttpException(Yii::t('content', 'invalid_answer')); } if ($answer['type'] === Question::TYPE_CHECKBOX && !is_array($answer['value'])) { throw new BadRequestHttpException(Yii::t('content', 'invalid_answer')); } $answeredQuestions[] = $answer['questionId']; } //check if questionnaire has un answered question $noAnswerQuestions = array_diff($questionnaire->questions, $answeredQuestions); if (!empty($noAnswerQuestions)) { throw new InvalidParameterException(Yii::t('content', 'no_answer_error')); } $this->{$attribute} = $answers; }
/** * @args {"description": "Delay: Stats of questionnaire answer"} */ public function perform() { $args = $this->args; //Get date from args or today $date = empty($args['date']) ? '' : $args['date']; $datetime = TimeUtil::getDatetime($date); $dateStr = date('Y-m-d', $datetime); //in case of too much data, get stats by questionnaire $skip = 0; $limit = 100; $query = Questionnaire::find()->orderBy(['_id' => SORT_ASC]); $query = $query->offset($skip)->limit($limit); $questionnaires = $query->all(); while (!empty($questionnaires)) { $statsRows = []; foreach ($questionnaires as $questionnaire) { $stats = QuestionnaireLog::getAnswerStats($questionnaire->_id, $dateStr); //group stats by questionId $rows = []; foreach ($stats as $stat) { $questionIdStr = (string) $stat['_id']['questionId']; $optionValue = $stat['_id']['value']; $rows[$questionIdStr][] = ['option' => $optionValue, 'count' => $stat['count']]; } //format stats data, and save it foreach ($rows as $questionIdStr => $answerStats) { $questionId = new MongoId($questionIdStr); $statsAnswerDaily = ModelStatsQuestionnaireAnswerDaily::getByQuestionIdAndDate($questionId, $dateStr); if (empty($statsAnswerDaily)) { $statsRows[] = ['questionId' => $questionId, 'stats' => $answerStats, 'date' => $dateStr, 'accountId' => $questionnaire->accountId]; } else { $statsAnswerDaily->stats = $answerStats; try { $statsAnswerDaily->save(); } catch (Exception $e) { ResqueUtil::log(['Update StatsQuestionnaireAnswerDaily error' => $e->getMessage(), 'StatsQuestionnaireAnswerDaily' => $statsAnswerDaily]); continue; } } } } ModelStatsQuestionnaireAnswerDaily::batchInsert($statsRows); $skip += $limit; $query = $query->offset($skip)->limit($limit); //free $questionnaires unset($questionnaires); $questionnaires = $query->all(); } return true; }
/** * View Questionnaire by questionnaire. * * <b>Request Type</b>: GET<br/><br/> * <b>Request Endpoint</b>:http://{server-domain}/api/questionnaire/{questionnaireId}&channelId={channelId}&openId={openId}br/><br/> * <b>Response Content-type</b>: application/json<br/><br/> * <b>Summary</b>: This api is used for viewing questionnaire. * <br/><br/> * * <b>Request Params</b>:<br/> * id, string<br/> * channelId, string<br/> * openId, string<br/> * * <b>Response Example:</b><br/> * { * "_id": "55d6cb8be9c2fb022c8b4579", * "name": "name", * "startTime": "1429000112193", * "endTime": "1429000116193", * "description": "good", * "question": [ * { * "id": "55d6cb8be9c2fb022c8b4577", * "title": "math", * "type": "radio", * "order": 0, * "options": [ * { * "icon": "support", * "content": "A option" * }, * { * "icon": "support", * "content": "B option" * } * ] * }, * { * "id": "55d6cb8be9c2fb022c8b4577", * "type": "input", * "title": "This is a problem", * "order": 1 * } * ], * "isPublished": false, * "answerTime": "2015-08-26 10:28:55", * "isAnswered": false * } * <pre> * </pre> */ public function actionView($id) { $channelId = $this->getQuery('channelId'); $openId = $this->getQuery('openId'); $isAnswered = false; $question = []; $answerTime = ''; $questionnaire = []; $user = ["channelId" => $channelId, "openId" => $openId]; $questionnaireInfo = Questionnaire::getById(new MongoId($id)); if (empty($questionnaireInfo)) { throw new InvalidParameterException(Yii::t('content', 'questionnaire_no_exist')); } if (!empty($channelId) && !empty($openId)) { $questionnaireLogInfo = QuestionnaireLog::getByQuestionnaireAndUser(new MongoId($id), $user); if (!empty($questionnaireLogInfo)) { $answerTime = MongodbUtil::MongoDate2String($questionnaireLogInfo->createdAt, 'Y-m-d H:i:s'); $isAnswered = true; } } $questionnaire = $questionnaireInfo->toArray(); $questionnaire['answerTime'] = $answerTime; $questionnaire['isAnswered'] = $isAnswered; return $questionnaire; }
public function actionUnexpiredQuestionnaire() { $now = new MongoDate(); $accountId = $this->getAccountId(); return Questionnaire::find()->where(['endTime' => ['$gte' => $now], 'isPublished' => true, 'accountId' => $accountId])->orderBy(['createdAt' => SORT_DESC])->all(); }