/cms/modules/quiz/simplequiz.php
PHP | 841 lines | 599 code | 94 blank | 148 comment | 135 complexity | fb5da0b6fd86a32fdea5696ccac7fa76 MD5 | raw file
- <?php
- if(!defined('__PRAGYAN_CMS'))
- {
- header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
- echo "<h1>403 Forbidden<h1><h4>You are not authorized to access the page.</h4>";
- echo '<hr/>'.$_SERVER['SERVER_SIGNATURE'];
- exit(1);
- }
- /*
- * Created on Jan 15, 2009
- */
- // SSO: optAnswer{SectionId}_{QuestionId} => value (OptionId)
- // MSO: chkAnswer{SectionId}_{QuestionId}_{OptionId}
- // Subj: txtAnswer{SectionId}_{QuestionId}
- define('QUIZ_COMPLETED', 1);
- define('QUIZ_SUBMISSIONFAILED', false);
- define('QUIZ_SUBMISSIONSUCCESSFUL', true);
- define('QUIZ_TIMEOUT_ERRORMSG', 'You have run out of time for this quiz. Your test will be evaluated only for the answers you have submitted previously.');
- define('QUIZ_SECTION_TIMEOUT_ERRORMSG', 'You have run out of time for this section. Only the answers that you have submitted previously will be evaluated. You can still view sections for which you have time left from the <a href="./+view">Quiz main page</a>.');
- class SimpleQuiz implements IQuiz {
- private $quizId;
- private $quizRow;
- public function __construct($quizId) {
- $this->quizId = $quizId;
- $this->quizRow = getQuizRow($quizId);
- }
-
- /**
- * function getPropertiesForm:
- * will be called from quiz edit, here no quiz specific properties
- */
- public function getPropertiesForm($dataSource) {
- return 'No quiz specific properties.';
- }
- public function submitPropertiesForm() {
- return true;
- }
-
- /**
- * function getSectionStartForm:
- * return HTML Section start form
- * form with a button and a hidden field specifying section id
- */
- private function getSectionStartForm($sectionId) {
- return <<<SECTIONSTARTFORM
- <form name="sectionstartform" method="POST" action="./+view" style="padding:0;margin:0;display:inline">
- <input type="hidden" name="hdnSectionId" id="hdnSectionId" value="$sectionId" />
- <input type="submit" name="btnStartSection" id="btnStartSection" value="Start" />
- </form>
- SECTIONSTARTFORM;
- }
-
- /**
- * function getFrontPage:
- * if random access is set, front page displays list of available sections and lets user select section
- */
- public function getFrontPage($userId) {
- $frontPage = "<h2>{$this->quizRow['quiz_title']}</h2>\n";
- $frontPage .= "<div class=\"quiz_headertext\">{$this->quizRow['quiz_headertext']}</div><br /><br />\n";
- if ($this->quizRow['quiz_allowsectionrandomaccess']) {
- $sectionList = getSectionList($this->quizId);
- for ($i = 0; $i < count($sectionList); ++$i) {
- $frontPage .= '<strong>' . $sectionList[$i]['quiz_sectiontitle'] . '</strong> ';
- $attemptRow = getAttemptRow($this->quizId, $sectionList[$i]['quiz_sectionid'], $userId);
- if (!$attemptRow || is_null($attemptRow['quiz_attemptstarttime'])) {
- // User hasn't started this section yet.
- $frontPage .= $this->getSectionStartForm($sectionList[$i]['quiz_sectionid']);
- }
- elseif (is_null($attemptRow['quiz_submissiontime'])) {
- // User hasn't finished this section yet.
- $frontPage .= ' <a href="./+view§ionid=' . $sectionList[$i]['quiz_sectionid'] . '">Go to questions</a>';
- }
- else {
- // User has finished the section already.
- $frontPage .= " Section Completed.";
- }
- $frontPage .= '<br /><br />';
- }
- }
- else {
- $frontPage .= <<<QUIZSTARTFORM
- <form name="quizstartform" method="POST" action="./+view" style="padding:0;margin:0;display:inline">
- <input type="submit" name="btnStartQuiz" id="btnStartQuiz" value="Start" />
- </form>
- QUIZSTARTFORM;
- }
- return $frontPage;
- }
- /**
- * function getQuizPage:
- * Retrieves the next page for the user.
- * Use this function from outside the class.
- * @param Integer $userId User ID.
- * @return String HTML for the next page.
- */
- public function getQuizPage($userId) {
- if ($this->checkQuizCompleted($userId)) {
- displayinfo('You seem to have completed this quiz already. You can only take this quiz once.');
- return '';
- }
- if ($this->quizRow['quiz_allowsectionrandomaccess']) {
- // if btnStartSection and hdnSectionId are set
- if (isset($_POST['btnStartSection']) && $this->isValidId($_POST['hdnSectionId']) && sectionBelongsToQuiz($this->quizId, $_POST['hdnSectionId']))
- $sectionId = intval($_POST['hdnSectionId']);
- elseif (isset($_GET['sectionid']) && $this->isValidId($_GET['sectionid']))
- $sectionId = intval($_GET['sectionid']);
- if (!isset($sectionId))
- return $this->getFrontPage($userId);
- $attemptRow = getAttemptRow($this->quizId, $sectionId, $userId);
- $sectionStarted = $attemptRow ? true : false;
- $sectionCompleted = !is_null($attemptRow['quiz_submissiontime']);
- if (!$sectionStarted) {
- if (!isset($_POST['btnStartSection'])) {
- displayerror('Error. You have not started this section yet. Please go to the quiz main page, and click on the Start Section button to view this section.');
- return '';
- }
- if (!startSection($this->quizId, $sectionId, $userId))
- return '';
- }
- elseif ($sectionCompleted) {
- displayinfo("You have completed this section.");
- return '';
- }
- if (isset($_POST['btnSubmit'])) {
- if ($this->submitQuizPage($userId) === true) {
- if ($this->markSectionCompleted($userId, $sectionId)) {
- // This section has been completed. See if the quiz also got completed
- if ($this->checkQuizCompleted($userId)) {
- return $this->quizRow['quiz_submittext'];
- }
- else {
- displayinfo('You have completed this section. You can move to another section.');
- return $this->getFrontPage($userId);
- }
- }
- else
- displayinfo('Your previous page was submitted successfully.');
- }
- }
- // TODO: Put in time check here
- if ($this->checkUserTimedOut($userId)) {
- displayerror(QUIZ_TIMEOUT_ERRORMSG);
- $this->forceQuizCompleted($userId);
- return '';
- }
- elseif ($this->checkUserTimedOut($userId, $sectionId)) {
- displayerror(QUIZ_SECTION_TIMEOUT_ERRORMSG);
- $this->forceQuizCompleted($userId, $sectionId);
- return '';
- }
- return $this->formatNextPage($userId, $sectionId);
- }
- else {
- // if quiz is already started, show next page
- // else, see if btnStartQuiz is set, if yes, mark quiz as started, and show next page
- // to mark a user's quiz as started, we insert one entry for each section in the quiz into user_attempts
- // to see if the user's quiz has been started, we see if there is a row in user_attempts with section id 1
- $minSectionId = getFirstSectionId($this->quizId);
- $attemptRow = getAttemptRow($this->quizId, $minSectionId, $userId);
- if (!$attemptRow) {
- if (!isset($_POST['btnStartQuiz']))
- return $this->getFrontPage($userId);
- // ok, btnStartQuiz was set, and the quiz wasn't started already,
- // start it by inserting a row for each section in the quiz into quiz_userattempts.
- $attemptQuery = "INSERT INTO `quiz_userattempts`(`page_modulecomponentid`, `quiz_sectionid`, `user_id`, `quiz_attemptstarttime`) " .
- "SELECT {$this->quizId}, `quiz_sectionid`, $userId, NOW() FROM `quiz_sections` WHERE `page_modulecomponentid` = '{$this->quizId}'";
- if (!mysql_query($attemptQuery)) {
- displayerror('Database Error. Could not update quiz information.');
- return '';
- }
- }
- if (isset($_POST['btnSubmit'])) {
- if ($this->submitQuizPage($userId) == true) {
- if ($this->markSectionCompleted($userId, -1)) {
- if ($this->checkQuizCompleted($userId))
- return $this->quizRow['quiz_submittext'];
- }
- else
- displayinfo('Your previous page was submitted successfully.');
- }
- }
- // TODO: Put in time check here
- if ($this->checkUserTimedOut($userId)) {
- displayerror(QUIZ_TIMEOUT_ERRORMSG);
- $this->forceQuizCompleted($userId);
- return '';
- }
- return $this->formatNextPage($userId);
- }
- }
- /**
- * function submitQuizPage:
- * Submits a page worth of questions.
- * @param Integer $userId User ID of the user taking the quiz.
- * @return Boolean True indicating successful submission, and false indicating errors.
- */
- public function submitQuizPage($userId) {
- // get all the questions that have been shown to the user
- // get the submitted answer for all of these questions, and insert them into the db
- $questionQuery = "SELECT `quiz_questions`.`quiz_sectionid` AS `quiz_sectionid`, " .
- "`quiz_questions`.`quiz_questionid` AS `quiz_questionid`, " .
- "`quiz_questions`.`quiz_questiontype` AS `quiz_questiontype`, " .
- "`quiz_questions`.`quiz_answermaxlength` AS `quiz_answermaxlength` " .
- "FROM `quiz_answersubmissions`, `quiz_questions` WHERE " .
- "`quiz_questions`.`page_modulecomponentid` = `quiz_answersubmissions`.`page_modulecomponentid` AND " .
- "`quiz_questions`.`quiz_sectionid` = `quiz_answersubmissions`.`quiz_sectionid` AND " .
- "`quiz_questions`.`quiz_questionid` = `quiz_answersubmissions`.`quiz_questionid` AND " .
- "`quiz_questions`.`page_modulecomponentid` = '{$this->quizId}' AND `user_id` = '$userId' AND " .
- "`quiz_questionviewtime` IS NOT NULL AND `quiz_answersubmittime` IS NULL ";
- if($this->quizRow['quiz_allowsectionrandomaccess'] == 1)
- $questionQuery .= "AND `quiz_answersubmissions`.`quiz_sectionid` = '".escape($_GET['sectionid']) ."'";
- $questionQuery .= "ORDER BY `quiz_answersubmissions`.`quiz_questionrank` LIMIT {$this->quizRow['quiz_questionsperpage']}";
- $questionResult = mysql_query($questionQuery);
- if (!$questionResult) {
- displayerror('Invalid query. ' . $questionQuery . ' ' . mysql_error());
- return false;
- }
- // Put in check about user's time elapsed here
- if ($this->checkUserTimedOut($userId, -1, '1 MINUTE')) {
- displayerror('Sorry, you have exceeded your time limit for the quiz. Your latest submission cannot be evaluated.');
- return false;
- }
-