/** * Function to get all of the quiz details. * * @param Integer $quizID The ID of the quiz for which we want to get details. * @param Boolean $getQuestionsToo If true, get the questions for the quiz too. * @param Boolean $resolveRandomQuestions If true, convert any randomised questions to live questions. * @param Integer $userID The ID of the user to resolve the questions to. * * @return Object The details of the quiz as an object. */ function WPCW_quizzes_getQuizDetails($quizID, $getQuestionsToo = false, $resolveRandomQuestions = false, $userID) { if (!$quizID) { return false; } global $wpcwdb, $wpdb; $wpdb->show_errors(); $SQL = $wpdb->prepare("SELECT * \n\t\t\tFROM {$wpcwdb->quiz}\t\n\t\t\tWHERE quiz_id = %d \n\t\t\t", $quizID); $quizObj = $wpdb->get_row($SQL); // Nothing found if (!$quizObj) { return false; } // Add flag indicating if random questions are resolved or not. $quizObj->resolved_random_questions = $resolveRandomQuestions; if ($getQuestionsToo) { // Something found, so return the questions for this quiz too. $quizObj->questions = WPCW_quizzes_getListOfQuestions($quizObj->quiz_id); // Check if we need to expand any random questions if ($resolveRandomQuestions && $userID > 0 && !empty($quizObj->questions)) { $questionListToRender = array(); foreach ($quizObj->questions as $question) { switch ($question->question_type) { // Got a random selection - extract these questions case 'random_selection': $quObj = new WPCW_quiz_RandomSelection($question); $randList = $quObj->questionSelection_getLockedQuestionSelection($userID, $quizObj->parent_unit_id); // Append the random questions. if (!empty($randList)) { $questionListToRender += $randList; } break; // Got a standard question // Got a standard question case 'multi': case 'open': case 'upload': case 'truefalse': $questionListToRender[$question->question_id] = $question; break; // Not expecting anything here... so not handling the error case. // Not expecting anything here... so not handling the error case. default: die(__('Unexpected question type, aborting.', 'wp_courseware')); break; } // end switch } // end foreach // Overwrite existing questions $quizObj->questions = $questionListToRender; } // end if we want to expand random questions } // Simple flag to see if we have open questions or not. $quizObj->has_open_questions = false; // Are we expecting any uploads? If so, set a flag to make answer processing faster. $quizObj->want_uploads = false; if (!empty($quizObj->questions)) { foreach ($quizObj->questions as $quizID => $quizItem) { // We're searching for an upload anyway, so check for an open question if ('upload' == $quizItem->question_type) { $quizObj->want_uploads = true; $quizObj->has_open_questions = true; break; } } // Not found an open question yet even though we checked for uploads. if (!$quizObj->has_open_questions) { foreach ($quizObj->questions as $quizID => $quizItem) { // Look for an open question (already checked uploads). This s // saves some computation time. if ('open' == $quizItem->question_type) { $quizObj->has_open_questions = true; break; } } } } return $quizObj; }
/** * Show the forms where the quiz answers can be edited. * * @param Integer $quizID the ID of the quiz to be edited. * @param Object $page The associated page object for showing messages. */ function WPCW_showPage_ModifyQuiz_showQuestionEntryForms($quizID, $page) { global $wpdb, $wpcwdb; $wpdb->show_errors(); // Work out if we need correct answers or not. And what the pass mark is. $quizDetails = WPCW_quizzes_getQuizDetails($quizID, true, false, false); $needCorrectAnswers = 'survey' != $quizDetails->quiz_type; // Show the existing quiz questions as a series of forms. $quizItems = WPCW_quizzes_getListOfQuestions($quizID); // Show the number of correct answers the user must get in order to pass. if ('quiz_block' == $quizDetails->quiz_type) { $totalQs = WPCW_quizzes_calculateActualQuestionCount($quizID); $passQs = ceil($quizDetails->quiz_pass_mark / 100 * $totalQs); printf('<div class="wpcw_msg wpcw_msg_info">'); printf(__('The trainee will be required to correctly answer at least <b>%d of the %d</b> following questions (<b>at least %d%%</b>) to progress.', 'wp_courseware'), $passQs, $totalQs, $quizDetails->quiz_pass_mark); printf('</div>'); } // Got a quiz, and trainer is requiring to show answers. Tell them we can't show answers // as this quiz contains open-ended questions that need grading. if ($needCorrectAnswers && 'show_answers' == $quizDetails->quiz_show_answers && WPCW_quizzes_containsQuestionsNeedingManualGrading($quizItems)) { printf('<div class="wpcw_msg wpcw_msg_error">'); printf(__('This quiz contains questions that need <b>manual grading</b>, and you\'ve selected \'<b>Show Answers</b>\' when the user completes this quiz. ', 'wp_courseware') . '<br/><br/>' . __('Since answers cannot be shown to the user because they are not known at that stage, <b>answers cannot be shown</b>. To hide this message, select \'<b>No Answers</b>\' above.', 'wp_courseware')); printf('</div>'); } $errorCount = 0; global $errorCount; // Wrapper for questions printf('<ol class="wpcw_dragable_question_holder">'); if ($quizItems) { // Render edit form for each of the quizzes that already exist foreach ($quizItems as $quizItem) { switch ($quizItem->question_type) { case 'multi': $quizObj = new WPCW_quiz_MultipleChoice($quizItem); break; case 'truefalse': $quizObj = new WPCW_quiz_TrueFalse($quizItem); break; case 'open': $quizObj = new WPCW_quiz_OpenEntry($quizItem); break; case 'upload': $quizObj = new WPCW_quiz_FileUpload($quizItem); break; case 'random_selection': $quizObj = new WPCW_quiz_RandomSelection($quizItem); break; default: die(__('Unknown quiz type: ', 'wp_courseware') . $quizItem->question_type); break; } $quizObj->showErrors = true; $quizObj->needCorrectAnswers = $needCorrectAnswers; // Keep track of errors if ($quizObj && $quizObj->gotError) { $errorCount++; } echo $quizObj->editForm_toString(); } } printf('</ol>'); // Do any of the questions have residual errors? Tell the user. if ($errorCount > 0) { $page->showMessage(sprintf(__('%d of the questions below have errors. Please make corrections and then save the changes.', 'wp_courseware'), $errorCount), true); } $page->showPageMiddle('35%'); // Show the menu for saving and adding new items. WPCW_showPage_ModifyQuiz_FloatMenu($page); // Flag to indicate that questions have been updated. printf('<input type="hidden" name="survey_updated" value="survey_updated" />'); printf('<a name="new_question"></a>'); // The empty forms for adding a new question $quizItemDummy = new stdClass(); $quizItemDummy->question_question = ''; $quizItemDummy->question_correct_answer = false; $quizItemDummy->question_order = 0; $quizItemDummy->question_answer_type = false; $quizItemDummy->question_answer_hint = false; $quizItemDummy->question_answer_explanation = false; $quizItemDummy->question_answer_file_types = 'doc, pdf, jpg, png, jpeg, gif'; $quizItemDummy->question_image = false; $quizItemDummy->question_usage_count = 0; $quizItemDummy->question_multi_random_enable = 0; $quizItemDummy->question_multi_random_count = 5; // Create some dummy answers. $quizItemDummy->question_data_answers = serialize(array(1 => array('answer' => ''), 2 => array('answer' => ''), 3 => array('answer' => ''))); $quizFormsToCreate = array('new_multi' => 'WPCW_quiz_MultipleChoice', 'new_tf' => 'WPCW_quiz_TrueFalse', 'new_open' => 'WPCW_quiz_OpenEntry', 'new_upload' => 'WPCW_quiz_FileUpload', 'new_random_selection' => 'WPCW_quiz_RandomSelection'); // Create the dummy quiz objects foreach ($quizFormsToCreate as $dummyid => $objClass) { // Set placeholder class $quizItemDummy->question_id = $dummyid; // Create new object and set it up with defaults $quizObj = new $objClass($quizItemDummy); $quizObj->cssClasses .= ' wpcw_question_template'; $quizObj->showErrors = false; $quizObj->needCorrectAnswers = $needCorrectAnswers; $quizObj->editForm_questionNotSavedYet = true; echo $quizObj->editForm_toString(); } }
/** * Get the associated quiz for a unit. * @param Integer $unitID The ID of the unit to get the associated quiz for. * @return Object The Object of the associated quiz, or false if no quiz found. */ function WPCW_quizzes_getAssociatedQuizForUnit($unitID) { if (!$unitID) { return false; } global $wpcwdb, $wpdb; $wpdb->show_errors(); $SQL = $wpdb->prepare("SELECT * \n\t\t\tFROM {$wpcwdb->quiz}\t\n\t\t\tWHERE parent_unit_id = %d \n\t\t\t", $unitID); $quizObj = $wpdb->get_row($SQL); // Nothing found if (!$quizObj) { return false; } // Something found, so return the questions for this quiz too. $quizObj->questions = WPCW_quizzes_getListOfQuestions($quizObj->quiz_id); return $quizObj; }