/**
  * The process grading function handles admin grading submissions.
  *
  * This function is hooked on to admin_init. It simply accepts
  * the grades as the Grader selected theme and saves the total grade and
  * individual question grades.
  *
  * @return bool
  */
 public function admin_process_grading_submission()
 {
     // NEEDS REFACTOR/OPTIMISING, such as combining the various meta data stored against the sensei_user_answer entry
     if (!isset($_POST['sensei_manual_grade']) || !wp_verify_nonce($_POST['_wp_sensei_manual_grading_nonce'], 'sensei_manual_grading') || !isset($_GET['quiz_id']) || $_GET['quiz_id'] != $_POST['sensei_manual_grade']) {
         return false;
         //exit and do not grade
     }
     $quiz_id = $_GET['quiz_id'];
     $user_id = $_GET['user'];
     global $woothemes_sensei;
     $questions = WooThemes_Sensei_Utils::sensei_get_quiz_questions($quiz_id);
     $quiz_lesson_id = $woothemes_sensei->quiz->get_lesson_id($quiz_id);
     $quiz_grade = 0;
     $count = 0;
     $quiz_grade_total = $_POST['quiz_grade_total'];
     $all_question_grades = array();
     $all_answers_feedback = array();
     foreach ($questions as $question) {
         ++$count;
         $question_id = $question->ID;
         if (isset($_POST['question_' . $question_id])) {
             $question_grade = 0;
             if ($_POST['question_' . $question_id] == 'right') {
                 $question_grade = $_POST['question_' . $question_id . '_grade'];
             }
             // add data to the array that will, after the loop, be stored on the lesson status
             $all_question_grades[$question_id] = $question_grade;
             // tally up the total quiz grade
             $quiz_grade += $question_grade;
         }
         // endif
         // Question answer feedback / notes
         $question_feedback = '';
         if (isset($_POST['questions_feedback'][$question_id])) {
             $question_feedback = wp_unslash($_POST['questions_feedback'][$question_id]);
         }
         $all_answers_feedback[$question_id] = $question_feedback;
     }
     // end for each $questions
     //store all question grades on the lesson status
     $woothemes_sensei->quiz->set_user_grades($all_question_grades, $quiz_lesson_id, $user_id);
     //store the feedback from grading
     $woothemes_sensei->quiz->save_user_answers_feedback($all_answers_feedback, $quiz_lesson_id, $user_id);
     // $_POST['all_questions_graded'] is set when all questions have been graded
     // in the class sensei grading user quiz -> display()
     if ($_POST['all_questions_graded'] == 'yes') {
         // set the users total quiz grade
         if (0 < intval($quiz_grade_total)) {
             $grade = abs(round(doubleval($quiz_grade) * 100 / $quiz_grade_total, 2));
         } else {
             $grade = 0;
         }
         WooThemes_Sensei_Utils::sensei_grade_quiz($quiz_id, $grade, $user_id);
         // Duplicating what Frontend->sensei_complete_quiz() does
         $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);
         if (in_array($lesson_status, array('passed', 'graded'))) {
             /**
              * Summary.
              *
              * Description.
              *
              * @since 1.7.0
              *
              * @param int  $user_id
              * @param int $quiz_lesson_id
              */
             do_action('sensei_user_lesson_end', $user_id, $quiz_lesson_id);
         }
         // end if in_array
     }
     // end if $_POST['all_que...
     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(esc_url_raw($load_url));
     exit;
 }
 /**
  * build_data_array builds the data for use on the page
  * Overloads the parent method
  * @since  1.3.0
  * @return array
  */
 public function build_data_array()
 {
     $data_array = WooThemes_Sensei_Utils::sensei_get_quiz_questions($this->quiz_id);
     return $data_array;
 }
 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;
         }
     }
 }
 public function calculate_user_module_progress_custom($user_id, $module_id, $course_id)
 {
     $lessons = Sensei_Core_Modules::get_lessons($course_id, $module_id);
     //if (is_wp_error($lessons) || 0 >= count($lessons)) return 0;
     $completed = false;
     $lesson_count = 0;
     $completed_count = 0;
     $strcom = '';
     foreach ($lessons as $lesson) {
         $lesson_id = $lesson->ID;
         $lesson_id = (int) $lesson_id;
         $quiz_id = WooThemes_Sensei_Lesson::lesson_quizzes($lesson_id, $post_status = 'any');
         $quiz_id = (int) $quiz_id;
         $lesson_quiz_questions = WooThemes_Sensei_Utils::sensei_get_quiz_questions($quiz_id);
         if (count($lesson_quiz_questions) > 0) {
             $lesson_status = WooThemes_Sensei_Utils::user_lesson_status($lesson_id, $user_id);
             $lesson_status = $lesson_status->comment_approved;
             ++$lesson_count;
             if ($lesson_status == 'passed') {
                 ++$completed_count;
             } else {
                 $question = $lesson_quiz_questions[0];
                 $question_title = $question->post_title;
                 if ($question_title == 'Offline Upload') {
                     ++$completed_count;
                 }
                 //$strcom = $strcom.' -- Lesson ID: '.$lesson_id.' '.print_r($lesson_quiz_questions, true);
             }
         }
         //$strcom = $strcom.' -- '.$user_id.' '.$lesson_id.' '.$lesson_status. ' '.print_r($lesson_quizzes, true);
     }
     $module_progress = $completed_count / $lesson_count * 100;
     return (double) $module_progress;
     //return $strcom;
 }
 /**
  * Update question answers to use new data structure
  *
  * @since 1.3.0
  * @access public
  * @return void
  */
 public function update_question_answer_data($n = 50, $offset = 0)
 {
     // Get Total Number of Updates to run
     $quiz_count_object = wp_count_posts('quiz');
     $quiz_count_published = $quiz_count_object->publish;
     // Calculate if this is the last page
     if (0 == $offset) {
         $current_page = 1;
     } else {
         $current_page = intval($offset / $n);
     }
     // End If Statement
     $total_pages = intval($quiz_count_published / $n);
     $args = array('post_type' => 'quiz', 'numberposts' => $n, 'offset' => $offset, 'post_status' => 'publish', 'suppress_filters' => 0);
     $quizzes = get_posts($args);
     $old_answers = array();
     $right_answers = array();
     $old_user_answers = array();
     if (is_array($quizzes)) {
         foreach ($quizzes as $quiz) {
             $quiz_id = $quiz->ID;
             // Get current user answers
             $comments = WooThemes_Sensei_Utils::sensei_check_for_activity(array('post_id' => $quiz_id, 'type' => 'sensei_quiz_answers'), true);
             // Need to always return an array, even with only 1 item
             if (!is_array($comments)) {
                 $comments = array($comments);
             }
             foreach ($comments as $comment) {
                 $user_id = $comment->user_id;
                 $content = maybe_unserialize(base64_decode($comment->comment_content));
                 $old_user_answers[$quiz_id][$user_id] = $content;
             }
             // Get correct answers
             $questions = WooThemes_Sensei_Utils::sensei_get_quiz_questions($quiz_id);
             if (is_array($questions)) {
                 foreach ($questions as $question) {
                     $right_answer = get_post_meta($question->ID, '_question_right_answer', true);
                     $right_answers[$quiz_id][$question->ID] = $right_answer;
                 }
             }
         }
     }
     if (is_array($right_answers)) {
         foreach ($right_answers as $quiz_id => $question) {
             $count = 0;
             if (is_array($question)) {
                 foreach ($question as $question_id => $answer) {
                     ++$count;
                     if (isset($old_user_answers[$quiz_id])) {
                         $answers_linkup[$quiz_id][$count] = $question_id;
                     }
                 }
             }
         }
     }
     if (is_array($old_user_answers)) {
         foreach ($old_user_answers as $quiz_id => $user_answers) {
             foreach ($user_answers as $user_id => $answers) {
                 foreach ($answers as $answer_id => $user_answer) {
                     $question_id = $answers_linkup[$quiz_id][$answer_id];
                     $new_user_answers[$question_id] = $user_answer;
                     WooThemes_Sensei_Utils::sensei_grade_question_auto($question_id, '', $user_answer, $user_id);
                 }
                 $lesson_id = get_post_meta($quiz_id, '_quiz_lesson', true);
                 WooThemes_Sensei_Utils::sensei_start_lesson($lesson_id, $user_id);
                 WooThemes_Sensei_Utils::sensei_save_quiz_answers($new_user_answers, $user_id);
             }
         }
     }
     if ($current_page == $total_pages) {
         return true;
     } else {
         return false;
     }
     // End If Statement
 }
 public static function sensei_delete_quiz_answers($quiz_id = 0, $user_id = 0)
 {
     if (intval($user_id) == 0) {
         $user_id = get_current_user_id();
     }
     $delete_answers = false;
     if (intval($quiz_id) > 0) {
         $questions = WooThemes_Sensei_Utils::sensei_get_quiz_questions($quiz_id);
         foreach ($questions as $question) {
             $delete_answers = WooThemes_Sensei_Utils::sensei_delete_activities(array('post_id' => $question->ID, 'user_id' => $user_id, 'type' => 'sensei_user_answer'));
         }
     }
     return $delete_answers;
 }