function watupro_liveresult() { global $wpdb, $user_ID; $_watu = new WatuPRO(); $_question = new WTPQuestion(); // select exam $exam = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . WATUPRO_EXAMS . " WHERE ID=%d", $_POST['quiz_id'])); $_watu->this_quiz = $exam; $advanced_settings = unserialize(stripslashes($exam->advanced_settings)); if (watupro_intel()) { WatuPROIQuestion::$advanced_settings = $advanced_settings; WTPQuestion::$advanced_settings = $advanced_settings; } $questions = watupro_unserialize_questions($_POST['watupro_questions']); // find current question $ques = null; foreach ($questions as $question) { if ($question->ID == $_POST['question_id']) { $ques = $question; } } if (!is_object($ques)) { die(__("Sorry, we couldn't retrieve the answer", 'watupro')); } $ansArr = is_array($_POST["answer-" . $ques->ID]) ? $_POST["answer-" . $ques->ID] : array(); list($points, $correct) = WTPQuestion::calc_answer($ques, $ansArr, $ques->q_answers); list($answer_text, $current_text, $unresolved_text) = $_question->process($_watu, $_POST['question_num'], $ques->question, $ques, $ansArr, $correct, $points); $current_text = apply_filters('watupro_content', $current_text); echo $current_text; // now save it in the user answers details if user is logged in if (is_user_logged_in()) { $taking_id = $_watu->add_taking($exam->ID, 1); $answer = serialize($_POST['answer-' . $_POST['question_id']]); // we need to store the serialized answer here $_watu->store_details($exam->ID, $taking_id, $ques->ID, $answer, $points, $ques->question, $correct, $current_text); } exit; }
function watupro_questions() { global $wpdb, $user_ID; $multiuser_access = 'all'; if (watupro_intel()) { $multiuser_access = WatuPROIMultiUser::check_access('exams_access'); } if ($multiuser_access == 'own') { // make sure this is my quiz $quiz = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . WATUPRO_EXAMS . " WHERE ID=%d", $_GET['quiz'])); if ($quiz->editor_id != $user_ID) { wp_die(__('You can only manage the questions on your own quizzes.', 'watupro')); } } if (!empty($_GET['export'])) { watupro_export_questions(); } if (!empty($_POST['watupro_import'])) { watupro_import_questions(); } $action = 'new'; if (!empty($_GET['action']) and $_GET['action'] == 'edit') { $action = 'edit'; } if (isset($_POST['ok'])) { // add new category? if (!empty($_POST['new_cat'])) { $wpdb->query($wpdb->prepare("INSERT INTO " . WATUPRO_QCATS . " (name, editor_id) VALUES (%s, %d) ", $_POST['new_cat'], $user_ID)); $_POST['cat_id'] = $wpdb->insert_id; } // only 'radio' questuons can be truefalse if ($_POST['answer_type'] != 'radio') { $_POST['truefalse'] = 0; } if ($action == 'edit') { WTPQuestion::edit($_POST, $_POST['question']); } else { $_POST['question'] = WTPQuestion::add($_POST); $action = 'edit'; } // when we have selected "exact" feedback we need to match feedback/explanation to answers $explanations = array(); if (!empty($_POST['explain_answer']) and !empty($_POST['do_elaborate_explanation']) and @$_POST['elaborate_explanation'] == 'exact') { $explanations = explode("{{{split}}}", $_POST['explain_answer']); } // adding answers $question_id = $_POST['question']; if ($question_id > 0) { // select old answers $old_answers = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . WATUPRO_ANSWERS . " WHERE question_id=%d ORDER BY ID", $question_id)); // handle matrix if (watupro_intel() and $_POST['answer_type'] == 'matrix') { WatuPROIQuestion::save_matrix($question_id, $old_answers); } // the $counter will skip over empty answers, $sort_order_counter will track the provided answers order. $counter = 1; $sort_order_counter = 1; $correctArry = @$_POST['correct_answer']; $pointArry = @$_POST['point']; if (!empty($_POST['answer']) and is_array($_POST['answer'])) { foreach ($_POST['answer'] as $key => $answer_text) { $correct = 0; if (@in_array($counter, $correctArry)) { $correct = 1; } $point = $pointArry[$key]; $grade_id_key = $key + 1; // correct answers must always have positive number of points if ($correct and $point <= 0) { $point = 1; } // actually add or save the answer if ($answer_text !== "") { if (empty($point)) { $point = 0; } // is there old answer? if (isset($old_answers[$counter - 1])) { $wpdb->query($wpdb->prepare("UPDATE " . WATUPRO_ANSWERS . " SET \n\t\t\t\t\t\t\t\tanswer=%s, correct=%s, point=%s, sort_order=%d, explanation=%s, grade_id=%s\n\t\t\t\t\t\t\t\tWHERE ID=%d", $answer_text, $correct, $point, $sort_order_counter, @$explanations[$key], @implode('|', $_POST['grade_id_' . $grade_id_key]), $old_answers[$counter - 1]->ID)); } else { $wpdb->query($wpdb->prepare("INSERT INTO " . WATUPRO_ANSWERS . " (question_id, answer, correct, point, sort_order, explanation, grade_id)\n\t\t\t\t\t\t\t\tVALUES(%d, %s, %s, %s, %d, %s, %s)", $question_id, $answer_text, $correct, $point, $sort_order_counter, @$explanations[$key], @implode('|', $_POST['grade_id_' . $grade_id_key]))); } $sort_order_counter++; // for truefalse questions don't save more than 2 answers if (!empty($_POST['truefalse']) and $sort_order_counter > 2) { break; } // break the foreach } $counter++; } // end foreach $_POST['answer'] // any old answers to cleanup? if ($sort_order_counter <= sizeof($old_answers)) { $answers_to_del = array_slice($old_answers, $sort_order_counter - 1); $ans_del_ids = array(0); foreach ($answers_to_del as $a) { $ans_del_ids[] = $a->ID; } $wpdb->query($wpdb->prepare("DELETE FROM " . WATUPRO_ANSWERS . " WHERE ID IN (" . implode(',', $ans_del_ids) . ") AND question_id=%d", $question_id)); } } // end if $_POST['answer'] do_action('watupro_saved_question', $question_id); // should I redirect to edit a choice in rich text editor? if (!empty($_POST['goto_rich_text'])) { watupro_redirect("admin.php?page=watupro_edit_choice&id=" . $_POST['goto_rich_text']); } } // end if $question_id } // end adding/saving question // delete question if (!empty($_GET['action']) and $_GET['action'] == 'delete') { $wpdb->query($wpdb->prepare("DELETE FROM " . WATUPRO_ANSWERS . " WHERE question_id=%d", $_REQUEST['question'])); $wpdb->query($wpdb->prepare("DELETE FROM " . WATUPRO_QUESTIONS . " WHERE ID=%d", $_REQUEST['question'])); $wpdb->query($wpdb->prepare("DELETE FROM " . WATUPRO_STUDENT_ANSWERS . " WHERE question_id=%d", $_REQUEST['question'])); } // mass delete questions if (!empty($_POST['mass_delete'])) { $qids = is_array($_POST['qids']) ? $_POST['qids'] : array(0); $qid_sql = implode(", ", $qids); $wpdb->query("DELETE FROM " . WATUPRO_QUESTIONS . " WHERE ID IN ({$qid_sql})"); $wpdb->query("DELETE FROM " . WATUPRO_ANSWERS . " WHERE question_id IN ({$qid_sql})"); $wpdb->query("DELETE FROM " . WATUPRO_STUDENT_ANSWERS . " WHERE question_id IN ({$qid_sql})"); } // save question hints settings if (!empty($_POST['hints_settings'])) { if (empty($_POST['enable_question_hints'])) { $wpdb->query($wpdb->prepare("UPDATE " . WATUPRO_EXAMS . " SET question_hints='' WHERE ID=%d", $_GET['quiz'])); } else { $per_quiz = intval($_POST['hints_per_quiz']); $per_question = intval($_POST['hints_per_question']); $wpdb->query($wpdb->prepare("UPDATE " . WATUPRO_EXAMS . " SET question_hints='{$per_quiz}|{$per_question}' WHERE ID=%d", $_GET['quiz'])); } } // mass change question category if (!empty($_POST['mass_change_category'])) { $qids = is_array($_POST['qids']) ? $_POST['qids'] : array(0); $qid_sql = implode(", ", $qids); $wpdb->query($wpdb->prepare("UPDATE " . WATUPRO_QUESTIONS . " SET cat_id=%d \n\t\t\tWHERE ID IN ({$qid_sql}) AND exam_id=%d", $_POST['mass_cat_id'], $_GET['quiz'])); } // select exam $exam = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . WATUPRO_EXAMS . " WHERE ID=%d", $_GET['quiz'])); $exam_name = stripslashes($exam->name); // reorder questions if (!empty($_GET['move'])) { WTPQuestion::reorder($_GET['move'], $_GET['quiz'], $_GET['dir']); watupro_redirect("admin.php?page=watupro_questions&quiz=" . $_GET['quiz']); } // filter by category SQL $filter_sql = ""; if (!empty($_GET['filter_cat_id'])) { if ($_GET['filter_cat_id'] == -1) { $filter_sql .= " AND Q.cat_id = 0 "; } else { $filter_sql .= $wpdb->prepare(" AND Q.cat_id = %d ", $_GET['filter_cat_id']); } } // filter by tag if (!empty($_GET['filter_tag'])) { $tags = explode(",", $_GET['filter_tag']); foreach ($tags as $tag) { $tag = trim($tag); $filter_sql .= " AND Q.tags LIKE '%|" . $tag . "|%'"; } } // filter by ID if (!empty($_GET['filter_id'])) { // cleanup everything that is not comma or number $_GET['filter_id'] = preg_replace('/[^0-9\\s\\,]/', '', $_GET['filter_id']); if (!empty($_GET['filter_id'])) { $filter_sql .= " AND Q.ID IN ({$_GET['filter_id']}) "; } } // Retrieve the questions $all_question = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS Q.ID, Q.question, C.name as cat, \n\t\tQ.answer_type as answer_type, Q.is_inactive as is_inactive, \n\t\tQ.importance as importance, Q.truefalse as truefalse,\n\t\t(SELECT COUNT(*) FROM " . WATUPRO_ANSWERS . " WHERE question_id=Q.ID) AS answer_count\n\t\t\t\tFROM `" . WATUPRO_QUESTIONS . "` AS Q\n\t\t\t\tLEFT JOIN " . WATUPRO_QCATS . " AS C ON C.ID=Q.cat_id \n\t\t\t\tWHERE Q.exam_id=" . intval($_GET['quiz']) . " {$filter_sql} ORDER BY Q.sort_order, Q.ID"); $num_questions = sizeof($all_question); if (empty($filter_sql)) { WTPQuestion::fix_sort_order($all_question); } // strip per page. We have good reasons to NOT use SQL limit here (the fix_sort_order function is the reason) $page_limit = 50; $offset = empty($_GET['offset']) ? 0 : intval($_GET['offset']); $all_question = array_slice($all_question, $offset, $page_limit); // select question categories $qcats = $wpdb->get_results("SELECT * FROM " . WATUPRO_QCATS . " ORDER BY name"); // hints related stuff $enable_question_hints = $hints_per_quiz = $hints_per_question = 0; if (!empty($exam->question_hints)) { $enable_question_hints = true; list($hints_per_quiz, $hints_per_question) = explode("|", $exam->question_hints); } if (@file_exists(get_stylesheet_directory() . '/watupro/questions.php')) { require get_stylesheet_directory() . '/watupro/questions.php'; } else { require WATUPRO_PATH . "/views/questions.php"; } }
function watupro_import_question($data, &$cats) { global $wpdb; if ($_POST['file_type'] == 'new') { $cat_id = WTPCategory::discover(@$data[3], $cats); // handle true/false subtype $truefalse = 0; if ($data[1] == 'true/false') { $truefalse = 1; $data[1] = 'radio'; } // only new questions and answers $stripfrom = 6; $question_array = array("content" => $data[0], "answer_type" => $data[1], "sort_order" => $data[2], "cat_id" => $cat_id, "explain_answer" => $data[4], "is_required" => $data[5], "quiz" => $_GET['quiz']); $stripfrom = 13; $question_array['correct_condition'] = $data[6]; $gapdata = explode("/", $data[7]); // handle both gap & sort $question_array['correct_gap_points'] = $question_array['correct_sort_points'] = @$gapdata[0]; $question_array['incorrect_gap_points'] = $question_array['incorrect_sort_points'] = @$gapdata[1]; $question_array['sorting_answers'] = $data[8]; $question_array['max_selections'] = $data[9]; $question_array['is_inactive'] = $data[10]; $question_array['is_survey'] = $data[11]; $question_array['elaborate_explanation'] = $data[12]; $question_array['truefalse'] = $truefalse; $question_array['feedback_label'] = ''; // temp as it's not yet included in export // sorting answers may contain ||| or |||||| for new lines separator $question_array['sorting_answers'] = str_replace('||||||', "\n", $question_array['sorting_answers']); $question_array['sorting_answers'] = str_replace('|||', "\n", $question_array['sorting_answers']); $qid = WTPQuestion::add($question_array); // extract answers $data = array_slice($data, $stripfrom); $answers = array(); $step = 1; foreach ($data as $cnt => $d) { if ($step == 1) { $answer = array(); $answer['answer'] = $d; $answer['is_correct'] = 0; $step = 2; } else { $answer['points'] = $d; $step = 1; $answers[] = $answer; } } // now we have the answers in the array, let's identify which ones are correct if ($data[1] == 'radio') { // for 'single answer' it's the one with most points $top_points = 0; foreach ($answers as $answer) { if ($answer['points'] > $top_points) { $top_points = $answer['points']; } } // once again foreach ($answers as $cnt => $answer) { if ($answer['points'] == $top_points) { $answers[$cnt]['is_correct'] = 1; break; } } } else { // for other types answer with positive points is correct foreach ($answers as $cnt => $answer) { if ($answer['points'] > 0) { $answers[$cnt]['is_correct'] = 1; } } } // finally insert them $vals = array(); foreach ($answers as $cnt => $answer) { if ($answer['answer'] === '') { continue; } $cnt++; $vals[] = $wpdb->prepare("(%d, %s, %s, %s, %d)", $qid, $answer['answer'], $answer['is_correct'], $answer['points'], $cnt); } $values_sql = implode(",", $vals); if (sizeof($answers)) { $wpdb->query("INSERT INTO " . WATUPRO_ANSWERS . " (question_id,answer,correct,point, sort_order) \n\t\t\tVALUES {$values_sql}"); } } else { // for old files import if ($row == 1 or empty($data[1])) { continue; } // skip first line $cat_id = WTPCategory::discover($data[4], $cats); $stripfrom = 14; $gapdata = explode("/", $data[8]); if (empty($data[0])) { $question_array = array("content" => $data[1], "answer_type" => $data[2], "sort_order" => $data[3], "cat_id" => $cat_id, "explain_answer" => $data[5], "is_required" => $data[6], "quiz" => $_GET['quiz']); $question_array['correct_condition'] = $data[7]; $question_array['correct_gap_points'] = $gapdata[0]; $question_array['incorrect_gap_points'] = $gapdata[1]; $question_array['sorting_answers'] = $data[9]; $question_array['max_selections'] = $data[10]; $question_array['is_inactive'] = $data[11]; $question_array['is_survey'] = $data[12]; $question_array['elaborate_explanation'] = $data[13]; $question_array['feedback_label'] = ''; // temp as it's not yet included in export // sorting answers may contain ||| or |||||| for new lines separator $question_array['sorting_answers'] = str_replace('||||||', "\n", $question_array['sorting_answers']); $question_array['sorting_answers'] = str_replace('|||', "\n", $question_array['sorting_answers']); $qid = WTPQuestion::add($question_array); } else { $wpdb->query($wpdb->prepare("UPDATE " . WATUPRO_QUESTIONS . " SET question=%s, answer_type=%s,\n \t\t\t\tsort_order=%d, cat_id=%d, explain_answer=%s, is_required=%d, correct_condition=%s,\n \t\t\t\tcorrect_gap_points=%s, incorrect_gap_points=%s, sorting_answers = %s, max_selections = %d,\n \t\t\t\tis_inactive=%d, is_survey = %d, elaborate_explanation = %s\n \t\t\t\tWHERE ID=%d", $data[1], $data[2], $data[3], $cat_id, $data[5], $data[6], $data[7], $gapdata[0], $gapdata[1], $data[9], $data[10], $data[11], $data[12], $data[13], $data[0])); $qid = $data[0]; } // now answers, first extract them similar to the "new file" option $data = array_slice($data, $stripfrom); $answers = array(); $step = 1; foreach ($data as $cnt => $d) { switch ($step) { case 1: $answer = array(); $answer['id'] = $d; $step = 2; break; case 2: $answer['answer'] = $d; $step = 3; break; case 3: $answer['points'] = $d; $step = 1; $answers[] = $answer; break; } } // end foreach // now insert or update foreach ($answers as $cnt => $answer) { if ($answer['answer'] === '') { continue; } $cnt++; // assume 1st is correct if ($cnt == 1) { $correct = 1; } else { $correct = 0; } if ($answer['id']) { $wpdb->query($wpdb->prepare("UPDATE " . WATUPRO_ANSWERS . " SET answer=%s, point=%d WHERE ID=%d", $answer['answer'], $answer['points'], $answer['id'])); } else { $wpdb->query($wpdb->prepare("INSERT INTO " . WATUPRO_ANSWERS . "\n \t\t\t\t\t\t(question_id,answer,correct,point, sort_order) VALUES (%d, %s, %s, %s, %d) ", $qid, $answer['answer'], $correct, $answer['points'], $cnt)); } } // end foreach } // end else pf $_POST['file_type']=='new' }
function display($ques, $qct, $question_count, $in_progress, $exam = null) { global $wpdb, $question_catids; // should we display category header? (when quiz is paginated 1 category per page this is handled by watupro_cat_header()) if (!empty($exam) and $exam->group_by_cat and !in_array($ques->cat_id, $question_catids) and $exam->single_page != WATUPRO_PAGINATE_PAGE_PER_CATEGORY) { echo "<h3>" . $ques->cat . "</h3>"; if (!empty($ques->cat_description)) { echo "<div>" . apply_filters('watupro_content', stripslashes(wpautop($ques->cat_description))) . "</div>"; } $question_catids[] = $ques->cat_id; } // fill in_progress once to avoid running multiple qiueries if (!empty($in_progress)) { // check if we already fetched the answers. if not, fetch // this is to avoid queries on every question WTPQuestion::$in_progress = $in_progress; if (empty($this->inprogress_details)) { $answers = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . WATUPRO_STUDENT_ANSWERS . " \n\t \t\t\t\tWHERE taking_id=%d AND exam_id=%d", $in_progress->ID, $in_progress->exam_id)); $this->inprogress_details = $this->inprogress_hints = $this->inprogress_snapshots = array(); $this->num_hints_total = 0; foreach ($answers as $answer) { $this->inprogress_details[$answer->question_id] = unserialize($answer->answer); $this->inprogress_hints[$answer->question_id] = stripslashes($answer->hints_used); $this->inprogress_snapshots[$answer->question_id] = stripslashes($answer->snapshot); if (!empty($answer->feedback)) { $this->inprogress_feedbacks[$answer->question_id] = $answer->feedback; } $this->num_hints_total += $answer->num_hints_used; } } } // if there is snapshot, means we have called 'see answer'. In this case we should make the div below invisible $nodisplay = ''; if (!empty($this->inprogress_snapshots[$ques->ID]) and $exam->live_result) { $nodisplay = 'style="display:none;"'; } $compact_class = $ques->compact_format ? "watupro-compact" : ""; $question_number = empty(self::$advanced_settings['dont_display_question_numbers']) ? "<span class='watupro_num'>Question {$qct} </span>" : ''; echo "<div id='questionWrap-{$question_count}' {$nodisplay} class='{$compact_class}'>\n\t\t\t<div class='question-content' " . @$display_style . ">"; // replace {{{ID}}} if any $ques->question = str_replace('{{{ID}}}', $ques->ID, $ques->question); if (watupro_intel() and ($ques->answer_type == 'gaps' or $ques->answer_type == 'sort' or $ques->answer_type == 'matrix')) { require_once WATUPRO_PATH . "/i/models/question.php"; WatuPROIQuestion::display($ques, $qct, $question_count, @$this->inprogress_details); } else { echo wpautop(self::flag_review($ques, $qct) . $question_number . stripslashes($ques->question)); } echo "<input type='hidden' name='question_id[]' id='qID_{$question_count}' value='{$ques->ID}' />"; echo "<input type='hidden' id='answerType{$ques->ID}' value='{$ques->answer_type}'>"; if ($ques->is_required) { echo "<input type='hidden' id='watupro-required-question-" . $ques->ID . "'>"; } if (!empty($exam->question_hints)) { $this->display_hints($ques, $in_progress); } if ($ques->answer_type != 'sort') { echo "<!-- end question-content--></div>"; } // end question-content $this->display_choices($ques, $in_progress); // accept feedback? if ($ques->accept_feedback) { $feedback = empty($this->inprogress_feedbacks[$ques->ID]) ? '' : stripslashes($this->inprogress_feedbacks[$ques->ID]); echo "<p>" . stripslashes($ques->feedback_label) . "<br>\n \t\t\t<textarea name='feedback-{$ques->ID}' rows='3' cols='30' class='watupro-user-feedback' id='watuproUserFeedback{$ques->ID}'>{$feedback}</textarea></p>"; } echo '<!-- end questionWrap--></div>'; // end questionWrap }
<?php // called when exam is submitted $_question = new WTPQuestion(); global $user_email, $user_identity, $question_catids, $post; if (!is_user_logged_in()) { $user_email = @$_POST['taker_email']; } if (watupro_intel()) { require_once WATUPRO_PATH . "/i/models/question.php"; } $taking_id = $_watu->add_taking($exam->ID); $_POST['watupro_current_taking_id'] = $GLOBALS['watupro_taking_id'] = $taking_id; // needed in personality quizzes and shortcodes $_watu->this_quiz = $exam; $total = $score = $achieved = $max_points = 0; $result = $unresolved_questions = $current_text = ''; $user_grade_ids = array(); // used in personality quizzes (Intelligence module) $question_catids = array(); // used for category based pagination foreach ($all_question as $qct => $ques) { if (empty($ques->is_survey)) { $total++; } // the two rows below are about the category headers if (!$ques->exclude_on_final_screen) { $result .= watupro_cat_header($exam, $qct, $ques, 'submit'); if (!in_array($ques->cat_id, $question_catids)) { $question_catids[] = $ques->cat_id; }
} if (!is_singular() and !empty($GLOBALS['watupro_client_includes_loaded'])) { #If this is in the listing page - and a quiz is already shown, don't show another. printf(__("Please go to <a href='%s'>%s</a> to view this test", 'watupro'), get_permalink(), get_the_title()); return false; } // now select and display questions $answer_display = $exam->show_answers == "" ? get_option('watupro_show_answers') : $exam->show_answers; // loading serialized questions or questions coming by POST if (!empty($_POST['action']) or !empty($in_progress->serialized_questions)) { $serialized_questions = empty($_REQUEST['watupro_questions']) ? @$in_progress->serialized_questions : $_REQUEST['watupro_questions']; $all_question = watupro_unserialize_questions($serialized_questions); } // this happens either at the beginning or if for some reason $all_question is empty on submitting if (empty($all_question)) { $all_question = WTPQuestion::select_all($exam); // regroup by cats? if (empty($passed_question_ids)) { $all_question = $_watu->group_by_cat($all_question, $exam); } // now match answers to non-textarea questions $_watu->match_answers($all_question, $exam); } $cnt_questions = sizeof($all_question); // get required question ids as string $rids = array(0); foreach ($all_question as $q) { if ($q->is_required) { $rids[] = $q->ID; } }
static function import_questions_aiken($quiz, $handle) { global $wpdb; $start_question = true; $qid = 0; // question ID $answers = array(); while (($aiken_line = fgets($handle, 10000)) !== FALSE) { $aiken_line = trim($aiken_line); if (empty($aiken_line)) { continue; } if ($start_question) { // let's import the question and get its ID for the answers $question_array = array("content" => $aiken_line, "answer_type" => 'radio', "quiz" => $quiz->ID, "cat_id" => 0, 'explain_answer' => '', 'is_required' => 0, 'max_selections' => 0); $qid = WTPQuestion::add($question_array); $start_question = false; continue; } // import answers if (!$start_question) { // the correct answer is here: let's find it, assign it, and set start_question to true if (preg_match("/^ANSWER/", $aiken_line)) { $correct_letter = preg_replace("/^ANSWER\\:/", '', $aiken_line); $correct_letter = trim($correct_letter); foreach ($answers as $key => $answer) { $correct = $key == $correct_letter ? 1 : 0; $points = $correct; $wpdb->query($wpdb->prepare("INSERT INTO " . WATUPRO_ANSWERS . " SET\n\t\t\t\t\t\t\tquestion_id=%d, answer=%s, correct=%s, point=%s", $qid, $answer, $correct, $points)); } $start_question = true; $answers = array(); } else { // fill into the answers array $answer_text = substr($aiken_line, 2); $answer_letter = substr($aiken_line, 0, 1); $answers[$answer_letter] = $answer_text; } } } // end while }
function watupro_unserialize_answer($answer) { global $wpdb; $answer_arr = unserialize(stripslashes($answer->answer)); $question = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . WATUPRO_QUESTIONS . " WHERE ID=%d", $answer->question_id)); $answer_value = $answer_arr[0]; list($points, $is_correct) = WTPQuestion::calc_answer($question, $answer_value); $answer->answer = $answer_value; $answer->is_correct = $is_correct; $answer->points = $points; return $answer; }
static function copy($id, $copy_to = 0) { global $wpdb; // select exam $exam = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . WATUPRO_EXAMS . " WHERE id=%d", $id)); if (empty($exam->ID)) { throw new Exception(__("Invalid exam ID", 'watupro')); } // select grades $grades = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . WATUPRO_GRADES . " WHERE exam_id=%d ORDER BY ID", $id)); // copy only some grades? if (!empty($_POST['copy_select'])) { foreach ($grades as $cnt => $grade) { if (!@in_array($grade->ID, @$_POST['grade_ids'])) { unset($grades[$cnt]); } } } // select questions and choices $questions = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . WATUPRO_QUESTIONS . " WHERE exam_id=%d \n\t\t\tORDER BY sort_order, ID", $id), ARRAY_A); // copy only some questions? if (!empty($_POST['copy_select'])) { foreach ($questions as $cnt => $question) { if (!@in_array($question['ID'], @$_POST['question_ids'])) { unset($questions[$cnt]); } } } $qids = array(0); foreach ($questions as $question) { $qids[] = $question['ID']; } $choices = $wpdb->get_results("SELECT * FROM " . WATUPRO_ANSWERS . " WHERE question_id IN (" . implode(",", $qids) . ") \n\t\t\tORDER BY sort_order, ID"); // match choices to questions foreach ($questions as $cnt => $question) { $questions[$cnt]['choices'] = array(); foreach ($choices as $choice) { if ($choice->question_id == $question['ID']) { $questions[$cnt]['choices'][] = $choice; } } } // insert/copy exam if (empty($copy_to)) { $new_exam_id = self::add(array("name" => stripslashes($exam->name) . " " . __("(Copy)", 'watupro'), "description" => stripslashes($exam->description), "content" => stripslashes($exam->final_screen), "require_login" => $exam->require_login, "take_again" => $exam->take_again, "email_taker" => $exam->email_taker, "email_admin" => $exam->email_admin, "admin_email" => $exam->admin_email, "randomize_questions" => $exam->randomize_questions, "login_mode" => $exam->login_mode, "time_limit" => $exam->time_limit, "pull_random" => $exam->pull_random, "show_answers" => $exam->show_answers, "group_by_cat" => $exam->group_by_cat, "num_answers" => $exam->num_answers, "single_page" => $exam->single_page, "cat_id" => $exam->cat_id, "times_to_take" => $exam->times_to_take, "mode" => $exam->mode, "require_captcha" => $exam->require_captcha, "grades_by_percent" => $exam->grades_by_percent, "disallow_previous_button" => $exam->disallow_previous_button, "random_per_category" => $exam->random_per_category, "email_output" => $exam->email_output, "live_result" => $exam->live_result, "fee" => $exam->fee, "is_scheduled" => $exam->is_scheduled, "schedule_from" => $exam->schedule_from, "schedule_to" => $exam->schedule_to, "submit_always_visible" => $exam->submit_always_visible, "retake_after" => $exam->retake_after, "reuse_questions_from" => $exam->reuse_questions_from, "show_pagination" => $exam->show_pagination, "advanced_settings" => $exam->advanced_settings, "enable_save_button" => $exam->enable_save_button, "shareable_final_screen" => $exam->shareable_final_screen, "redirect_final_screen" => $exam->redirect_final_screen, "question_hints" => $exam->question_hints, "takings_by_ip" => $exam->takings_by_ip, "reuse_default_grades" => $exam->reuse_default_grades, "store_progress" => $exam->store_progress, "custom_per_page" => $exam->custom_per_page, "is_active" => $exam->is_active, "randomize_cats" => $exam->randomize_cats, "email_subject" => $exam->email_subject, "pay_always" => $exam->pay_always, "published_odd" => $exam->published_odd, "published_odd_url" => $exam->published_odd_url, "retake_grades" => "")); } else { $new_exam_id = $copy_to; } // insert grades foreach ($grades as $grade) { $wpdb->query($wpdb->prepare("INSERT INTO " . WATUPRO_GRADES . " SET\n\t\t\t\t\texam_id=%d, gtitle=%s, gdescription=%s, gfrom=%s, gto=%s, cat_id=%d, certificate_id=%d", $new_exam_id, stripcslashes($grade->gtitle), stripcslashes($grade->gdescription), $grade->gfrom, $grade->gto, $grade->cat_id, $grade->certificate_id)); } // insert questions and choices foreach ($questions as $question) { $to_copy = array("quiz" => $new_exam_id, "content" => $question['question'], "answer_type" => $question['answer_type'], "cat_id" => $question['cat_id'], "explain_answer" => $question['explain_answer'], "is_required" => $question['is_required'], "sort_order" => $question['sort_order'], "correct_gap_points" => $question['correct_gap_points'], "incorrect_gap_points" => $question['incorrect_gap_points'], "correct_sort_points" => $question['correct_gap_points'], "incorrect_sort_points" => $question['incorrect_gap_points'], "max_selections" => $question['max_selections'], "sorting_answers" => $question['sorting_answers'], "is_inactive" => $question['is_inactive'], "is_survey" => $question['is_survey'], "elaborate_explanation" => $question['elaborate_explanation'], "open_end_mode" => $question['open_end_mode'], "correct_condition" => $question['correct_condition'], "tags" => $question['tags'], "open_end_display" => $question['open_end_display'], "exclude_on_final_screen" => $question['exclude_on_final_screen'], "hints" => $question['hints'], "importance" => $question['importance'], "unanswered_penalty" => $question['unanswered_penalty'], "truefalse" => $question['truefalse'], "accept_feedback" => $question['accept_feedback'], "feedback_label" => $question['feedback_label']); if (!empty($question['elaborate_explanation'])) { $to_copy['do_elaborate_explanation'] = true; } $new_question_id = WTPQuestion::add($to_copy); foreach ($question['choices'] as $choice) { $wpdb->query($wpdb->prepare("INSERT INTO " . WATUPRO_ANSWERS . " (question_id,answer,correct,point, sort_order)\n\t\t\t\t\tVALUES(%d, %s, %s, %s, %d)", $new_question_id, $choice->answer, $choice->correct, $choice->point, $choice->sort_order)); } } }