Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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";
    }
}
Exemplo n.º 3
0
 function process($_watu, $qct, $question_content, $ques, $ansArr, $correct, $points)
 {
     $original_answer = "";
     // this var is used only for textareas
     $answer_text = "";
     // answers as text
     $unresolved_text = "";
     $compact_class = $ques->compact_format ? ' watupro-compact ' : '';
     $question_number = empty(self::$advanced_settings['dont_display_question_numbers']) ? "<span class='watupro_num'>Question {$qct} </span>" : '';
     $enumerator = self::define_enumerator();
     if ($ques->answer_type == 'gaps') {
         // gaps are displayed in different way to avoid repeating the question
         $current_text = "<div class='show-question [[watupro-resolvedclass]]'><div class='show-question-content'>" . $question_number;
     } else {
         $current_text = "<div class='show-question [[watupro-resolvedclass]]" . $compact_class . "'><div class='show-question-content'>" . $question_number . stripslashes($question_content) . "</div>\n";
         $current_text .= "<div class='show-question-choices'>";
         $current_text .= "<ul>";
     }
     // replace the {{{ID}}} mask
     $current_text = str_replace('{{{ID}}}', $ques->ID, $current_text);
     $class = 'answer';
     $any_answers = false;
     // this is for textareas -is there any answer provided at all?
     foreach ($ques->q_answers as $ans) {
         if ($ques->answer_type == 'matrix') {
             continue;
         }
         $user_answer_class = ($ques->is_survey or $_watu->this_quiz->is_personality_quiz) ? 'user-answer-unrevealed' : 'user-answer';
         $class = 'answer';
         if (in_array($ans->ID, $ansArr)) {
             $class .= ' ' . $user_answer_class;
         }
         if ($ans->correct == 1 and $ques->answer_type != 'textarea' and !$ques->is_survey) {
             $class .= ' correct-answer';
         }
         if ($enumerator) {
             $enumerator_visible = $enumerator . '. ';
             $enumerator++;
         } else {
             $enumerator_visible = '';
         }
         if ($ques->answer_type == 'textarea') {
             // textarea answers have only 1 element. Make comparison case insensitive
             $original_answer = @$ansArr[0];
             $ansArr[0] = strtolower(strip_tags(trim($ansArr[0])));
             $compare = strtolower($ans->answer);
             if (!empty($compare)) {
                 $any_answers = true;
             }
         } else {
             $compare = $ans->ID;
             $current_text .= "<li class='{$class}'><span class='answer'><!--WATUEMAIL" . $class . "WATUEMAIL-->" . stripslashes($enumerator_visible . $ans->answer) . "</span></li>\n";
         }
     }
     // end foreach choice;
     // open end will be displayed here
     if ($ques->answer_type == 'textarea') {
         $user_answer_class = $ques->is_survey ? 'user-answer-unrevealed' : 'user-answer';
         // repeat this line in case there were no answers to compare
         $answer_text = empty($original_answer) ? $ansArr[0] : $original_answer;
         $ansArr[0] = strtolower($ansArr[0]);
         $class .= ' ' . $user_answer_class;
         if ($correct) {
             $class .= ' correct-answer';
         }
         $current_text .= "<li class='{$class}'><span class='answer'>" . nl2br(stripslashes($answer_text)) . "</span></li>\n";
         // uploaded file?
         if (!empty($_FILES['file-answer-' . $ques->ID]['tmp_name'])) {
             $current_text .= '<!--watupro-uploaded-file-' . $ques->ID . '-->';
         }
     }
     if (($ques->answer_type == 'gaps' or $ques->answer_type == 'sort' or $ques->answer_type == 'matrix') and watupro_intel()) {
         list($points, $answer_text) = WatuPROIQuestion::process($ques, $ansArr);
         $current_text .= $answer_text;
     }
     if (empty($answer_text)) {
         $answer_text = $_watu->answer_text($ques->q_answers, $ansArr);
     }
     if ($ques->answer_type != 'gaps') {
         $current_text .= "</ul>";
     }
     // close the ul for answers
     if (empty($_POST["answer-" . $ques->ID])) {
         $current_text .= "<p class='unanswered'>" . __('Question was not answered', 'watupro') . "</p>";
     }
     if (!$correct) {
         $unresolved_text = $this->display_unresolved($current_text) . "</div>";
     }
     // close question-choices
     $current_text .= "</div>";
     $unresolved_text .= "</div>";
     // if there is user's feedback, display it too
     if ($ques->accept_feedback and !empty($_POST['feedback-' . $ques->ID])) {
         $current_text .= "<p><b>" . stripslashes($ques->feedback_label) . "</b><br>" . stripslashes($_POST['feedback-' . $ques->ID]) . "</p>";
     }
     // if explain_answer, display it
     $current_text .= $this->answer_feedback($ques, $correct, $ansArr, $points);
     $current_text .= "</div>";
     $current_text = wpautop($current_text);
     // apply filter to allow 3rd party changes.
     $current_text = apply_filters('watu_filter_current_question_text', $current_text, $qct, $question_content, $correct);
     // if question is survey, unresolved should be empty
     if ($ques->is_survey) {
         $unresolved_text = '';
     }
     return array($answer_text, $current_text, $unresolved_text);
 }
Exemplo n.º 4
0
         $question_catids[] = $ques->cat_id;
     }
 }
 $qct++;
 $question_content = $ques->question;
 // fill the gaps need to replace gaps
 if ($ques->answer_type == 'gaps') {
     $question_content = preg_replace("/{{{([^}}}])*}}}/", "_____", $question_content);
 }
 $ansArr = is_array(@$_POST["answer-" . $ques->ID]) ? $_POST["answer-" . $ques->ID] : array();
 // points and correct calculation
 list($points, $correct) = WTPQuestion::calc_answer($ques, $ansArr, $ques->q_answers, $user_grade_ids);
 $max_points += WTPQuestion::max_points($ques);
 // handle sorting personalities
 if ($exam->is_personality_quiz and $ques->answer_type == 'sort' and watupro_intel()) {
     WatuPROIQuestion::sort_question_personality($ques, $ansArr, $user_grade_ids);
 }
 // discard points?
 if ($points and !$correct and $ques->reward_only_correct) {
     $points = 0;
 }
 list($answer_text, $current_text, $unresolved_text) = $_question->process($_watu, $qct, $question_content, $ques, $ansArr, $correct, $points);
 $unresolved_questions .= str_replace('[[watupro-resolvedclass]]', '', $unresolved_text);
 // replace the resolved class
 if ($correct) {
     $current_text = str_replace('[[watupro-resolvedclass]]', 'watupro-resolved', $current_text);
 } else {
     $current_text = str_replace('[[watupro-resolvedclass]]', 'watupro-unresolved', $current_text);
 }
 if (empty($ques->exclude_on_final_screen)) {
     $result .= $current_text;
Exemplo n.º 5
0
// select exam
$exam = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . WATUPRO_EXAMS . " WHERE id=%d", $exam_id));
if (empty($exam->is_active)) {
    printf(__('This %s is currently inactive.', 'watupro'), __('quiz', 'watupro'));
    return true;
}
// passed question IDs in the shortcode?
if (!empty($passed_question_ids)) {
    $exam->passed_question_ids = $passed_question_ids;
}
$_question->exam = $exam;
do_action('watupro_select_show_exam', $exam);
// API Call
$advanced_settings = unserialize(stripslashes($exam->advanced_settings));
if (watupro_intel()) {
    WatuPROIQuestion::$advanced_settings = $advanced_settings;
    WTPQuestion::$advanced_settings = $advanced_settings;
}
// in progress taking of this exam?
$in_progress = null;
$exam->full_time_limit = $exam->time_limit;
// store this for the verify_timer calculations
if (is_user_logged_in()) {
    $in_progress = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . WATUPRO_TAKEN_EXAMS . " \n\t\tWHERE user_id=%d AND exam_id=%d AND in_progress=1 ORDER BY ID DESC LIMIT 1", $user_ID, $exam_id));
    if ($exam->time_limit) {
        $meta_start_time = get_user_meta($user_ID, "start_exam_" . $exam->ID, true);
    }
    if ($exam->time_limit > 0 and (!empty($in_progress->ID) or !empty($meta_start_time))) {
        // recalculate time limit
        $start_time = !empty($in_progress->ID) ? watupro_mktime($in_progress->start_time) : $meta_start_time;
        $limit_in_seconds = intval($exam->time_limit * 60);
Exemplo n.º 6
0
_e('To add this exam to your blog, insert the code ', 'watupro');
?>
 <b>[watupro <?php 
echo $_REQUEST['quiz'];
?>
]</b> <?php 
_e('into any post or page.', 'watupro');
?>
</p>
	
	<?php 
$intelligence_display = "";
// variable used to hide the div with own questions if required
if (watupro_intel()) {
    require_once WATUPRO_PATH . "/i/models/question.php";
    WatuPROIQuestion::reuse_questions($exam, $intelligence_display);
}
?>
	
<div id="watuProQuestions" <?php 
echo $intelligence_display;
?>
>
	<?php 
if (!empty($qcats) and sizeof($qcats)) {
    ?>
	<form method="get" action="admin.php">
		<input type="hidden" name="page" value="watupro_questions">
		<input type="hidden" name="quiz" value="<?php 
    echo $exam->ID;
    ?>