/** * Handle's the page request * */ public function handle_request() { global $DB, $USER, $PAGE; // first check if there are questions or not. If there are no questions display that message instead, // regardless of action. if (count($this->RTQ->get_questionmanager()->get_questions()) === 0) { $this->pagevars['action'] = 'noquestions'; $this->pageurl->param('action', ''); // remove the action } switch ($this->pagevars['action']) { case 'noquestions': $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->no_questions($this->RTQ->is_instructor()); $this->RTQ->get_renderer()->view_footer(); break; case 'quizstart': // case for the quiz start landing page // set the quiz view page to the base layout for 1 column layout $PAGE->set_pagelayout('base'); if ($this->session->get_session() === false) { // redirect them to the default page with a quick message first $redirurl = clone $this->pageurl; $redirurl->remove_params('action'); redirect($redirurl, get_string('nosession', 'activequiz'), 5); } else { // this is here to help prevent race conditions for multiple group members trying to take the // quiz at the same time $cantakequiz = false; if ($this->RTQ->group_mode()) { if (!$this->RTQ->is_instructor() && $this->pagevars['group'] == 0) { print_error('invalidgroupid', 'mod_activequiz'); } // check if the user can take the quiz for the group if ($this->session->can_take_quiz_for_group($this->pagevars['group'])) { $cantakequiz = true; } } else { // if no group mode, user will always be able to take quiz $cantakequiz = true; } if ($cantakequiz) { if (!$this->session->init_attempts($this->RTQ->is_instructor(), $this->pagevars['group'], $this->pagevars['groupmembers'])) { print_error('cantinitattempts', 'activequiz'); } // set the session as running if ($this->RTQ->is_instructor() && $this->session->get_session()->status == 'notrunning') { $this->session->set_status('running'); } // get the current attempt an initialize the head contributions $attempt = $this->session->get_open_attempt(); $attempt->get_html_head_contributions(); $attempt->setStatus('inprogress'); // now show the quiz start landing page $this->RTQ->get_renderer()->view_header(true); $this->RTQ->get_renderer()->render_quiz($attempt, $this->session); $this->RTQ->get_renderer()->view_footer(); } else { $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->group_session_started(); $this->RTQ->get_renderer()->view_footer(); } } break; case 'selectgroupmembers': if (empty($this->pagevars['group'])) { $viewhome = clone $this->pageurl; $viewhome->remove_params('action'); redirect($viewhome, get_string('invalid_group_selected', 'activequiz'), 5); } else { $this->pageurl->param('group', $this->pagevars['group']); $groupselectform = new \mod_activequiz\forms\view\groupselectmembers($this->pageurl, array('rtq' => $this->RTQ, 'selectedgroup' => $this->pagevars['group'])); if ($data = $groupselectform->get_data()) { // basically we want to get all gm* fields $gmemnum = 1; $groupmembers = array(); $data = get_object_vars($data); while (isset($data['gm' . $gmemnum])) { if ($data['gm' . $gmemnum] != 0) { $groupmembers[] = $data['gm' . $gmemnum]; } $gmemnum++; } $this->pageurl->param('groupmembers', implode(',', $groupmembers)); $this->pageurl->param('action', 'quizstart'); // redirect to the quiz start page redirect($this->pageurl, null, 0); } else { $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->group_member_select($groupselectform); $this->RTQ->get_renderer()->view_footer(); } } break; default: // default is to show view to start quiz (for instructors/quiz controllers) or join quiz (for everyone else) // trigger event for course module viewed $event = \mod_activequiz\event\course_module_viewed::create(array('objectid' => $PAGE->cm->instance, 'context' => $PAGE->context)); $event->add_record_snapshot('course', $this->RTQ->getCourse()); $event->add_record_snapshot($PAGE->cm->modname, $this->RTQ->getRTQ()); $event->trigger(); // determine home display based on role if ($this->RTQ->is_instructor()) { $startsessionform = new \mod_activequiz\forms\view\start_session($this->pageurl); if ($data = $startsessionform->get_data()) { // create a new quiz session // first check to see if there are any open sessions // this shouldn't occur, but never hurts to check $sessions = $DB->get_records('activequiz_sessions', array('activequizid' => $this->RTQ->getRTQ()->id, 'sessionopen' => 1)); if (!empty($sessions)) { // error out with that there are existing sessions $this->RTQ->get_renderer()->setMessage(get_string('alreadyexisting_sessions', 'activequiz'), 'error'); $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->view_inst_home($startsessionform, $this->session->get_session()); $this->RTQ->get_renderer()->view_footer(); break; } else { if (!$this->session->create_session($data->sessionname)) { // error handling $this->RTQ->get_renderer()->setMessage(get_string('unabletocreate_session', 'activequiz'), 'error'); $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->view_inst_home($startsessionform, $this->session->get_session()); $this->RTQ->get_renderer()->view_footer(); break; // break out of the switch } } // redirect to the quiz start $quizstarturl = clone $this->pageurl; $quizstarturl->param('action', 'quizstart'); redirect($quizstarturl, null, 0); } else { $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->view_inst_home($startsessionform, $this->session->get_session()); $this->RTQ->get_renderer()->view_footer(); } } else { // check to see if the group already started a quiz $validgroups = array(); if ($this->RTQ->group_mode()) { // if there is already an attempt for this session for this group for this user don't allow them to start another $validgroups = $this->session->check_attempt_for_group(); if (empty($validgroups) && $validgroups !== false) { $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->group_session_started(); $this->RTQ->get_renderer()->view_footer(); break; } else { if ($validgroups === false) { $validgroups = array(); } } } $studentstartformparams = array('rtq' => $this->RTQ, 'validgroups' => $validgroups); $studentstartform = new \mod_activequiz\forms\view\student_start_form($this->pageurl, $studentstartformparams); if ($data = $studentstartform->get_data()) { $quizstarturl = clone $this->pageurl; $quizstarturl->param('action', 'quizstart'); // if data redirect to the quiz start url with the group selected if we're in group mode if ($this->RTQ->group_mode()) { $groupid = $data->group; $quizstarturl->param('group', $groupid); // check if the group attendance feature is enabled // if so redirect to the group member select form // don't send to group attendance form if an attempt is already started if ($this->RTQ->getRTQ()->groupattendance == 1 && !$this->session->get_open_attempt_for_current_user()) { $quizstarturl->param('action', 'selectgroupmembers'); } redirect($quizstarturl, null, 0); } else { redirect($quizstarturl, null, 0); } } else { // display student home. (form will display only if there is an active session $this->RTQ->get_renderer()->view_header(); $this->RTQ->get_renderer()->view_student_home($studentstartform, $this->session); $this->RTQ->get_renderer()->view_footer(); } } break; } }
/** * Handles the incoming request * */ public function handle_request() { global $USER; switch ($this->action) { case 'startquiz': // only allow instructors to perform this action if ($this->RTQ->is_instructor()) { $firstquestion = $this->session->start_quiz(); $this->jsonlib->set('status', 'startedquiz'); $this->jsonlib->set('questionid', $firstquestion->get_slot()); $this->jsonlib->set('nextstarttime', $this->session->get_session()->nextstarttime); $this->jsonlib->set('notime', $firstquestion->getNoTime()); if ($firstquestion->getNoTime() == 0) { // this question has a time limit if ($firstquestion->getQuestionTime() == 0) { $questiontime = $this->RTQ->getRTQ()->defaultquestiontime; } else { $questiontime = $firstquestion->getQuestionTime(); } $this->jsonlib->set('questiontime', $questiontime); } else { $this->jsonlib->set('questiontime', 0); } $delay = $this->session->get_session()->nextstarttime - time(); $this->jsonlib->set('delay', $delay); $qattempt = $this->session->get_open_attempt(); $this->jsonlib->set('lastquestion', $qattempt->lastquestion ? 'true' : 'false'); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'savequestion': // check if we're working on the current question for the session $currentquestion = $this->session->get_session()->currentquestion; $jscurrentquestion = required_param('questionid', PARAM_INT); if ($currentquestion != $jscurrentquestion) { $this->jsonlib->send_error('invalid question'); } // if we pass attempt to save the question $qattempt = $this->session->get_open_attempt(); // make sure the attempt belongs to the current user if ($qattempt->userid != $USER->id) { $this->jsonlib->send_error('invalid user'); } if ($qattempt->save_question()) { $this->jsonlib->set('status', 'success'); $this->jsonlib->set('feedback', $qattempt->get_question_feedback()); // next we need to send back the updated sequence check for javascript to update // the sequence check on the question form. this allows the question to be resubmitted again list($seqname, $seqvalue) = $qattempt->get_sequence_check($this->session->get_session()->currentqnum); $this->jsonlib->set('seqcheckname', $seqname); $this->jsonlib->set('seqcheckval', $seqvalue); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('unable to save question'); } break; case 'getresults': // only allow instructors to perform this action if ($this->RTQ->is_instructor()) { $this->session->set_status('reviewing'); // get the current question results $responses = $this->session->get_question_results(); $this->jsonlib->set('responses', $responses); $this->jsonlib->set('status', 'success'); $this->jsonlib->set('qtype', $this->RTQ->get_questionmanager()->get_questiontype_byqnum($this->session->get_session()->currentqnum)); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'getcurrentresults': // case to get the results of the question currently going if ($this->RTQ->is_instructor()) { $responses = $this->session->get_question_results(); $this->jsonlib->set('responses', $responses); $this->jsonlib->set('status', 'success'); $this->jsonlib->set('qtype', $this->RTQ->get_questionmanager()->get_questiontype_byqnum($this->session->get_session()->currentqnum)); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'getnotresponded': // only allow instructors to perform this action if ($this->RTQ->is_instructor()) { $notrespondedHTML = $this->session->get_not_responded(); $this->jsonlib->set('notresponded', $notrespondedHTML); $this->jsonlib->set('status', 'success'); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'nextquestion': // only allow instructors to perform this action if ($this->RTQ->is_instructor()) { $nextquestion = $this->session->next_question(); $this->session->set_status('running'); $this->jsonlib->set('status', 'startedquestion'); $qattempt = $this->session->get_open_attempt(); $this->jsonlib->set('lastquestion', $qattempt->lastquestion ? 'true' : 'false'); $this->jsonlib->set('questionid', $nextquestion->get_slot()); $this->jsonlib->set('nextstarttime', $this->session->get_session()->nextstarttime); $this->jsonlib->set('notime', $nextquestion->getNoTime()); if ($nextquestion->getNoTime() == 0) { // this question has a time limit if ($nextquestion->getQuestionTime() == 0) { $questiontime = $this->RTQ->getRTQ()->defaultquestiontime; } else { $questiontime = $nextquestion->getQuestionTime(); } $this->jsonlib->set('questiontime', $questiontime); } else { $this->jsonlib->set('questiontime', 0); } $delay = $this->session->get_session()->nextstarttime - time(); $this->jsonlib->set('delay', $delay); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'repollquestion': if ($this->RTQ->is_instructor()) { $repollquestion = $this->session->repoll_question(); $this->session->set_status('running'); $this->jsonlib->set('status', 'startedquestion'); $qattempt = $this->session->get_open_attempt(); $this->jsonlib->set('lastquestion', $qattempt->lastquestion ? 'true' : 'false'); $this->jsonlib->set('questionid', $repollquestion->get_slot()); $this->jsonlib->set('nextstarttime', $this->session->get_session()->nextstarttime); $this->jsonlib->set('notime', $repollquestion->getNoTime()); if ($repollquestion->getNoTime() == 0) { // this question has a time limit if ($repollquestion->getQuestionTime() == 0) { $questiontime = $this->RTQ->getRTQ()->defaultquestiontime; } else { $questiontime = $repollquestion->getQuestionTime(); } $this->jsonlib->set('questiontime', $questiontime); } else { $this->jsonlib->set('questiontime', 0); } $delay = $this->session->get_session()->nextstarttime - time(); $this->jsonlib->set('delay', $delay); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'gotoquestion': if ($this->RTQ->is_instructor()) { $qnum = optional_param('qnum', '', PARAM_INT); if (empty($qnum)) { $this->jsonlib->send_error('invalid question number'); } if (!($question = $this->session->goto_question($qnum))) { $this->jsonlib->send_error('invalid question number'); } $this->session->set_status('running'); $this->jsonlib->set('status', 'startedquestion'); $qattempt = $this->session->get_open_attempt(); $this->jsonlib->set('lastquestion', $qattempt->lastquestion ? 'true' : 'false'); $this->jsonlib->set('questionid', $question->get_slot()); $this->jsonlib->set('nextstarttime', $this->session->get_session()->nextstarttime); $this->jsonlib->set('notime', $question->getNoTime()); if ($question->getNoTime() == 0) { // this question has a time limit if ($question->getQuestionTime() == 0) { $questiontime = $this->RTQ->getRTQ()->defaultquestiontime; } else { $questiontime = $question->getQuestionTime(); } $this->jsonlib->set('questiontime', $questiontime); } else { $this->jsonlib->set('questiontime', 0); } $delay = $this->session->get_session()->nextstarttime - time(); $this->jsonlib->set('delay', $delay); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'endquestion': // update the session status to say that we're ending the question (this will in turn update students if ($this->RTQ->is_instructor()) { $this->session->end_question(); $this->jsonlib->set('status', 'success'); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'getrightresponse': if ($this->RTQ->is_instructor()) { $rightresponsequestion = $this->session->get_question_right_response(); $this->jsonlib->set('rightanswer', $rightresponsequestion); $this->jsonlib->set('status', 'success'); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; case 'closesession': // only allow instructors to perform this action if ($this->RTQ->is_instructor()) { $this->session->end_session(); // next calculate and save grades if (!$this->RTQ->get_grader()->save_all_grades()) { $this->jsonlib->send_error('can\'t save grades'); } $this->jsonlib->set('status', 'success'); $this->jsonlib->send_response(); } else { $this->jsonlib->send_error('invalidaction'); } break; default: $this->jsonlib->send_error('invalidaction'); break; } }