public function process_grading() { // NEEDS REFACTOR/OPTIMISING, such as combining the various meta data stored against the sensei_user_answer entry if (isset($_POST['sensei_manual_grade']) && isset($_GET['quiz_id'])) { // error_log( __CLASS__ . ':' . __FUNCTION__ . ':' . print_r($_POST, true)); $quiz_id = $_GET['quiz_id']; $user_id = $_GET['user']; $verify_nonce = wp_verify_nonce($_POST['_wp_sensei_manual_grading_nonce'], 'sensei_manual_grading'); if ($verify_nonce && $quiz_id == $_POST['sensei_manual_grade']) { $questions = WooThemes_Sensei_Utils::sensei_get_quiz_questions($quiz_id); $quiz_grade = 0; $count = 0; $quiz_grade_total = $_POST['quiz_grade_total']; foreach ($questions as $question) { ++$count; $question_id = $question->ID; if (isset($_POST['question_' . $question_id])) { $correct = false; $question_grade = 0; $question_total_grade = $_POST['question_total_grade']; if ($_POST['question_' . $question_id] == 'right') { $correct = true; $question_grade = $_POST['question_' . $question_id . '_grade']; } $activity_logged = WooThemes_Sensei_Utils::sensei_grade_question($question_id, $question_grade, $user_id); $quiz_grade += $question_grade; } else { WooThemes_Sensei_Utils::sensei_delete_question_grade($question_id); } // WP slashes all incoming data regardless of Magic Quotes setting (see wp_magic_quotes()), but // as an answer note is not direct post_content it won't have slashes removed, so we need to do it $answer_notes = wp_unslash($_POST['question_' . $question_id . '_notes']); if (!$answer_notes || $answer_notes == '') { $answer_notes = ''; } WooThemes_Sensei_Utils::sensei_add_answer_notes($question_id, $user_id, $answer_notes); } if ($_POST['all_questions_graded'] == 'yes') { $grade = abs(round(doubleval($quiz_grade) * 100 / $quiz_grade_total, 2)); $activity_logged = WooThemes_Sensei_Utils::sensei_grade_quiz($quiz_id, $grade, $user_id); // Duplicating what Frontend->sensei_complete_quiz() does $quiz_lesson_id = absint(get_post_meta($quiz_id, '_quiz_lesson', true)); $pass_required = get_post_meta($quiz_id, '_pass_required', true); $quiz_passmark = abs(round(doubleval(get_post_meta($quiz_id, '_quiz_passmark', true)), 2)); $lesson_metadata = array(); if ($pass_required) { // Student has reached the pass mark and lesson is complete if ($quiz_passmark <= $grade) { $lesson_status = 'passed'; } else { $lesson_status = 'failed'; } // End If Statement } else { $lesson_status = 'graded'; } $lesson_metadata['grade'] = $grade; // Technically already set as part of "WooThemes_Sensei_Utils::sensei_grade_quiz()" above WooThemes_Sensei_Utils::update_lesson_status($user_id, $quiz_lesson_id, $lesson_status, $lesson_metadata); switch ($lesson_status) { case 'passed': case 'graded': do_action('sensei_user_lesson_end', $user_id, $quiz_lesson_id); break; } } if (isset($_POST['sensei_grade_next_learner']) && strlen($_POST['sensei_grade_next_learner']) > 0) { $load_url = add_query_arg(array('message' => 'graded')); } elseif (isset($_POST['_wp_http_referer'])) { $load_url = add_query_arg(array('message' => 'graded'), $_POST['_wp_http_referer']); } else { $load_url = add_query_arg(array('message' => 'graded')); } wp_safe_redirect($load_url); exit; } } }
/** * Grade question automatically * @param integer $question_id ID of question * @param string $answer User's answer * @return integer User's grade for question */ public static function sensei_grade_question_auto($question_id = 0, $question_type = '', $answer = '', $user_id = 0) { if (intval($user_id) == 0) { $user_id = get_current_user_id(); } $question_grade = false; if (intval($question_id) > 0) { if (empty($question_type)) { $question_type = get_the_terms($question_id, 'question-type'); // Set default question type if one does not exist - prevents errors when grading if (!$question_type || is_wp_error($question_type) || !is_array($question_type)) { $question_type = 'multiple-choice'; } else { $question_type = array_shift($question_type)->slug; } } // Allow full override of autograding $question_grade = apply_filters('sensei_pre_grade_question_auto', $question_grade, $question_id, $question_type, $answer); if (false === $question_grade) { switch ($question_type) { case 'multiple-choice': case 'boolean': $right_answer = (array) get_post_meta($question_id, '_question_right_answer', true); if (0 == get_magic_quotes_gpc()) { $answer = wp_unslash($answer); } $answer = (array) $answer; if (is_array($right_answer) && count($right_answer) == count($answer)) { // Loop through all answers ensure none are 'missing' $all_correct = true; foreach ($answer as $check_answer) { if (!in_array($check_answer, $right_answer)) { $all_correct = false; } } // If all correct then grade if ($all_correct) { $question_grade = get_post_meta($question_id, '_question_grade', true); if (!$question_grade || $question_grade == '') { $question_grade = 1; } } } break; case 'gap-fill': $right_answer = get_post_meta($question_id, '_question_right_answer', true); if (0 == get_magic_quotes_gpc()) { $answer = wp_unslash($answer); } $gapfill_array = explode('||', $right_answer); // Check that the 'gap' is "exactly" equal to the given answer if (trim(strtolower($gapfill_array[1])) == trim(strtolower($answer))) { $question_grade = get_post_meta($question_id, '_question_grade', true); if (empty($question_grade)) { $question_grade = 1; } } else { if (@preg_match('/' . $gapfill_array[1] . '/i', null) !== FALSE) { if (preg_match('/' . $gapfill_array[1] . '/i', $answer)) { $question_grade = get_post_meta($question_id, '_question_grade', true); if (empty($question_grade)) { $question_grade = 1; } } } } break; default: // Allow autograding of any other question type $question_grade = apply_filters('sensei_grade_question_auto', $question_grade, $question_id, $question_type, $answer); break; } // switch question_type } $activity_logged = WooThemes_Sensei_Utils::sensei_grade_question($question_id, $question_grade, $user_id); } return $question_grade; }