/** * This action is the quiz shell. * It ensures permissions, creates new attempts etc etc. * * @author Ben Evans */ public function attemptAction() { Model_Shell_Debug::getInstance()->log("User Entered the Attempt Action"); $identity = Zend_Auth::getInstance()->getIdentity(); $username = $identity->username; $auth_model = Model_Auth_General::getAuthModel(); /* Before we do anything, test to make sure we've passed a VALID QUIZ which WE ARE ENTITLED to sit. */ $quiz_id = $this->_getParam("quiz"); if (is_null($quiz_id)) { throw new Exception("No quiz was passed. Cannot continue."); } $vQuiz = Model_Quiz_Quiz::fromID($quiz_id); if ($vQuiz == null) { throw new Exception("Quiz ID passed was invalid. Cannot continue."); } $mFinished = false; $mMarking = false; //Permissions if ($auth_model->userInGroup($username, $vQuiz->getPermissions_group()) && $vQuiz->getOpen_date() <= strtotime("now")) { //Have we run out of attempts? $vAttempts = Model_Quiz_QuizAttempt::getAllFromUser($username, $vQuiz); if (sizeof($vAttempts) >= $vQuiz->getMax_attempts()) { //It is possible that we're on our last attempt, and that it's "in progress"...check $bInProgress = false; foreach ($vAttempts as $vAttempt) { if ($vAttempt->getDate_finished() == null) { $bInProgress = true; } } if (!$bInProgress) { throw new Exception("You've exceeded your maximum attempts for this quiz. Cannot continue"); } } } else { if (!$this->view->is_admin) { throw new Exception("Insufficient Permissions to take this quiz / Quiz not open yet"); } $vAttempts = Model_Quiz_QuizAttempt::getAllFromUser($username, $vQuiz); } /* Ok. We're allowed to TAKE the quiz. Are we resuming, or starting a new one? */ $mQuizAttempt = null; if (is_array($vAttempts)) { foreach ($vAttempts as $vAttempt) { if ($vAttempt->getDate_finished() == null) { $mQuizAttempt = $vAttempt; break; } } //End Foreach } //End If if ($mQuizAttempt == null) { $mQuizAttempt = Model_Quiz_QuizAttempt::fromScratch(strtotime("now"), $vQuiz, $username); } /* Calculate the total questions needed for this quiz */ $vTCs = $vQuiz->getTestedConcepts(); $vTotalQuestions = 0; foreach ($vTCs as $vTC) { $vTotalQuestions = $vTotalQuestions + $vTC->getNumber_tested(); } /* We have our quizAttempt ready to go. Now we look to see if we're resuming a question or not */ $mQuestionAttempt = $mQuizAttempt->getLastIncompleteQuestion(); if (is_object($mQuestionAttempt) && !$mQuestionAttempt->isValid()) { $mQuestionAttempt->destroy(); // Remove the Question attempt (Database was reinitialised or something) $mQuestionAttempt = null; } if ($mQuestionAttempt != null) { /* Are we getting an ANSWER for this question? */ if (array_key_exists("marking", $_POST) && $_POST['marking'] == "1") { /* Mark it */ $mMarking = true; } /* If we reach here, the page has probably been refreshed. We just re-display the last question */ } else { /* Have we finished this quiz? */ if ($mQuizAttempt->getQuestionAttemptCount() >= $vTotalQuestions) { //Close this attempt and display a result later on down the page $mQuizAttempt->setDate_finished(strtotime("now")); //Calculate and store the final score $mQuizAttempt->setTotal_score($mQuizAttempt->getTotal_score()); $mFinished = true; } else { /* QuizAttempt isn't finished... Fetch a questionBase */ $vQuestionBase = Model_Shell_QuestionChooser::select_next_question($mQuizAttempt, true); /* Make a GeneratedQuestion */ $vCounter = 0; //Make sure we don't get any fluke no-text answers while ($vCounter < 3) { Model_Shell_Debug::getInstance()->log("vQuestionBase: " . isset($vQuestionBase)); Model_Shell_Debug::getInstance()->log("Generating... from " . $vQuestionBase->getXml()); $vGen = Model_Quiz_GeneratedQuestion::fromQuestionBase($vQuestionBase); if ($vGen->getCorrect_answer() != "" && $vGen->getCorrect_answer() != "\r\n") { break; } else { $vGen->remove(); } $vCounter++; } if ($vGen->getCorrect_answer() == "" || $vGen->getCorrect_answer() == "\r\n") { throw new Exception("Error. While generating a question for you, blank answers appeared > 3 times. This should never happen. Either try to refresh this page, or consult your lecturer..."); } /* Make a QuestionAttempt */ $mQuestionAttempt = Model_Quiz_QuestionAttempt::fromScratch($vQuestionBase, strtotime("now"), strtotime("now"), $mQuizAttempt, $vGen); } //End-if_finished_quizAttempt } // Pass all relevant information to the view $this->view->quiz = $vQuiz; $this->view->question_attempt = $mQuestionAttempt; $this->view->finished = $mFinished; $this->view->marking = $mMarking; $this->view->mQuizAttempt = $mQuizAttempt; $this->view->vTotalQuestions = $vTotalQuestions; }
/** * This action is the quiz shell. * It ensures permissions, creates new attempts etc etc. * * @author Ben Evans */ public function attemptAction() { Model_Shell_Debug::getInstance()->log("User Entered the Attempt Action"); $identity = Zend_Auth::getInstance()->getIdentity(); $username = $identity->username; $auth_model = Model_Auth_General::getAuthModel(); /* Before we do anything, test to make sure we've passed a VALID QUIZ which WE ARE ENTITLED to sit. */ $quiz = $this->findQuiz($this->_getParam("quiz")); $finished = false; $marking = false; $now = strtotime("now"); // Permissions $is_open = $quiz->getOpen_date() <= $now; if ($auth_model->userInGroup($username, $quiz->getPermissions_group()) && $is_open && !$quiz->hasPendingPrerequisite($username)) { // Have we run out of attempts? $quizAttempts = Model_Quiz_QuizAttempt::getAllFromUser($username, $quiz); if (sizeof($quizAttempts) >= $quiz->getMax_attempts()) { // It is possible that we're on our last attempt, and that it's "in progress"...check $quizAttempt = $this->findQuizAttemptInProgress($quizAttempts); if (!$quizAttempt) { throw new Exception("You've exceeded your maximum attempts for this quiz. Cannot continue"); } } } else { if (!$this->view->is_admin) { throw new Exception("Insufficient Permissions to take this quiz / Quiz not open yet / Prerequisites incomplete."); } $quizAttempts = Model_Quiz_QuizAttempt::getAllFromUser($username, $quiz); } /* Ok. We're allowed to TAKE the quiz. Are we resuming, or starting a new one? */ $quizAttempt = $this->findQuizAttemptInProgress($quizAttempts); if ($quizAttempt == null) { $quizAttempt = Model_Quiz_QuizAttempt::fromScratch($now, $quiz, $username); } $total_questions = $quiz->getTotalQuestions(); /* We have our quizAttempt ready to go. Now we look to see if we're resuming a question or not */ $questionAttempt = $quizAttempt->getLastIncompleteQuestion(); if (is_object($questionAttempt) && !$questionAttempt->isValid()) { $questionAttempt->destroy(); // Remove the Question attempt (Database was reinitialised or something) $questionAttempt = null; } if ($questionAttempt != null) { /* Are we getting an ANSWER for this question? */ //if (array_key_exists("marking", $_POST) && $_POST['marking'] == "1") { if (1 == $this->getRequest()->getPost('marking')) { /* Mark it */ $marking = true; } My_Logger::log("Marking is {$marking}"); /* If we reach here, the page has probably been refreshed. We just re-display the last question */ } else { /* Have we finished this quiz? */ if ($quizAttempt->getQuestionAttemptCount() >= $total_questions) { // Close this attempt and display a result later on down the page $quizAttempt->setDate_finished($now); // Calculate and store the final score $quizAttempt->setTotal_score($quizAttempt->getTotal_score()); $finished = true; } else { /* Make a QuestionAttempt */ $questionAttempt = $this->makeQuestionAttempt($quizAttempt, $now); } } // Pass all relevant information to the view $this->view->setEscape('htmlentities'); $this->view->quiz = $quiz; $this->view->question_attempt = $questionAttempt; $this->view->finished = $finished; $this->view->marking = $marking; $this->view->mQuizAttempt = $quizAttempt; $this->view->vTotalQuestions = $total_questions; $this->view->setEscape('htmlspecialchars_decode'); }