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"; } }