Example #1
0
 /**
  * Mark a lesson as started for user
  *
  * Will also start the lesson course for the user if the user hans't started taking it already.
  *
  * @since 1.6.0
  *
  * @param  integer $lesson_id ID of lesson
  * @param int| string $user_id default 0
  * @param bool $complete default false
  *
  * @return mixed boolean or comment_ID
  */
 public static function sensei_start_lesson($lesson_id = 0, $user_id = 0, $complete = false)
 {
     if (intval($user_id) == 0) {
         $user_id = get_current_user_id();
     }
     $activity_logged = false;
     if (intval($lesson_id) > 0) {
         $course_id = get_post_meta($lesson_id, '_lesson_course', true);
         if ($course_id) {
             $is_user_taking_course = Sensei_Utils::user_started_course($course_id, $user_id);
             if (!$is_user_taking_course) {
                 Sensei_Utils::user_start_course($user_id, $course_id);
             }
         }
         $metadata = array();
         $status = 'in-progress';
         // Note: When this action runs the lesson status may not yet exist
         do_action('sensei_user_lesson_start', $user_id, $lesson_id);
         if ($complete) {
             $has_questions = get_post_meta($lesson_id, '_quiz_has_questions', true);
             if ($has_questions) {
                 $status = 'passed';
                 // Force a pass
                 $metadata['grade'] = 0;
             } else {
                 $status = 'complete';
             }
         }
         // Check if user is already taking the lesson
         $activity_logged = Sensei_Utils::user_started_lesson($lesson_id, $user_id);
         if (!$activity_logged) {
             $metadata['start'] = current_time('mysql');
             $activity_logged = Sensei_Utils::update_lesson_status($user_id, $lesson_id, $status, $metadata);
         } else {
             // if users is already taking the lesson  and the status changes to complete update it
             $current_user_activity = get_comment($activity_logged);
             if ($status == 'complete' && $status != $current_user_activity->comment_approved) {
                 $comment = array();
                 $comment['comment_ID'] = $activity_logged;
                 $comment['comment_approved'] = $status;
                 wp_update_comment($comment);
             }
         }
         if ($complete) {
             // Run this *after* the lesson status has been created/updated
             do_action('sensei_user_lesson_end', $user_id, $lesson_id);
         }
     }
     return $activity_logged;
 }
 /**
  * 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'];
     $questions = Sensei_Utils::sensei_get_quiz_questions($quiz_id);
     $quiz_lesson_id = 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
     Sensei()->quiz->set_user_grades($all_question_grades, $quiz_lesson_id, $user_id);
     //store the feedback from grading
     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;
         }
         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
         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;
 }
Example #3
0
 /**
  * Submit the users quiz answers for grading
  *
  * This function accepts users answers and stores it but also initiates the grading
  * if a quiz can be graded automatically it will, if not the answers can be graded by the teacher.
  *
  * @since 1.7.4
  * @access public
  *
  * @param array $quiz_answers
  * @param array $files from $_FILES
  * @param int $user_id
  * @param int $lesson_id
  *
  * @return bool $answers_submitted
  */
 public static function submit_answers_for_grading($quiz_answers, $files = array(), $lesson_id, $user_id = 0)
 {
     $answers_submitted = false;
     // get the user_id if none was passed in use the current logged in user
     if (!intval($user_id) > 0) {
         $user_id = get_current_user_id();
     }
     // make sure the parameters are valid before continuing
     if (empty($lesson_id) || empty($user_id) || 'lesson' != get_post_type($lesson_id) || !get_userdata($user_id) || !is_array($quiz_answers)) {
         return false;
     }
     // Default grade
     $grade = 0;
     // Get Quiz ID
     $quiz_id = Sensei()->lesson->lesson_quizzes($lesson_id);
     // Get quiz grade type
     $quiz_grade_type = get_post_meta($quiz_id, '_quiz_grade_type', true);
     // Get quiz pass setting
     $pass_required = get_post_meta($quiz_id, '_pass_required', true);
     // Get the minimum percentage need to pass this quiz
     $quiz_pass_percentage = abs(round(doubleval(get_post_meta($quiz_id, '_quiz_passmark', true)), 2));
     // Handle Quiz Questions asked
     // This is to ensure we save the questions that we've asked this user and that this can't be change unless
     // the quiz is reset by admin or user( user: only if the setting is enabled ).
     // get the questions asked when when the quiz questions were generated for the user : Sensei_Lesson::lesson_quiz_questions
     $user_lesson_status = Sensei_Utils::user_lesson_status($lesson_id, $user_id);
     $questions_asked = get_comment_meta($user_lesson_status->comment_ID, 'questions_asked', true);
     if (empty($questions_asked)) {
         $questions_asked = array_keys($quiz_answers);
         $questions_asked_string = implode(',', $questions_asked);
         // Save questions that were asked in this quiz
         update_comment_meta($user_lesson_status->comment_ID, 'questions_asked', $questions_asked_string);
     }
     // Save Quiz Answers for grading, the save function also calls the sensei_start_lesson
     self::save_user_answers($quiz_answers, $files, $lesson_id, $user_id);
     // Grade quiz
     $grade = Sensei_Grading::grade_quiz_auto($quiz_id, $quiz_answers, 0, $quiz_grade_type);
     // Get Lesson Grading Setting
     $lesson_metadata = array();
     $lesson_status = 'ungraded';
     // Default when completing a quiz
     // At this point the answers have been submitted
     $answers_submitted = true;
     // if this condition is false the quiz should manually be graded by admin
     if ('auto' == $quiz_grade_type && !is_wp_error($grade)) {
         // Quiz has been automatically Graded
         if ('on' == $pass_required) {
             // Student has reached the pass mark and lesson is complete
             if ($quiz_pass_percentage <= $grade) {
                 $lesson_status = 'passed';
             } else {
                 $lesson_status = 'failed';
             }
             // End If Statement
         } else {
             // Student only has to partake the quiz
             $lesson_status = 'graded';
         }
         $lesson_metadata['grade'] = $grade;
         // Technically already set as part of "WooThemes_Sensei_Utils::sensei_grade_quiz_auto()" above
     }
     // end if ! is_wp_error( $grade ...
     Sensei_Utils::update_lesson_status($user_id, $lesson_id, $lesson_status, $lesson_metadata);
     if ('passed' == $lesson_status || 'graded' == $lesson_status) {
         /**
          * Lesson end action hook
          *
          * This hook is fired after a lesson quiz has been graded and the lesson status is 'passed' OR 'graded'
          *
          * @param int $user_id
          * @param int $lesson_id
          */
         do_action('sensei_user_lesson_end', $user_id, $lesson_id);
     }
     /**
      * User quiz has been submitted
      *
      * Fires the end of the submit_answers_for_grading function. It will fire irrespective of the submission
      * results.
      *
      * @param int $user_id
      * @param int $quiz_id
      * @param string $grade
      * @param string $quiz_pass_percentage
      * @param string $quiz_grade_type
      */
     do_action('sensei_user_quiz_submitted', $user_id, $quiz_id, $grade, $quiz_pass_percentage, $quiz_grade_type);
     return $answers_submitted;
 }