/** * Output the lesson meta for the given lesson * * @since 1.9.0 * @param $lesson_id */ public static function the_lesson_meta($lesson_id) { global $wp_query; $loop_lesson_number = $wp_query->current_post + 1; $course_id = Sensei()->lesson->get_course_id($lesson_id); $single_lesson_complete = false; $is_user_taking_course = Sensei_Utils::user_started_course($course_id, get_current_user_id()); // Get Lesson data $complexity_array = Sensei()->lesson->lesson_complexities(); $lesson_complexity = get_post_meta($lesson_id, '_lesson_complexity', true); if ('' != $lesson_complexity) { $lesson_complexity = $complexity_array[$lesson_complexity]; } $user_info = get_userdata(absint(get_post()->post_author)); $is_preview = Sensei_Utils::is_preview_lesson($lesson_id); $preview_label = ''; if ($is_preview && !$is_user_taking_course) { $preview_label = Sensei()->frontend->sensei_lesson_preview_title_text($lesson_id); $preview_label = '<span class="preview-heading">' . $preview_label . '</span>'; } $count_markup = ''; /** * Filter for if you want the $lesson_count to show next to the lesson. * * @since 1.0 * @param bool default false. */ if (apply_filters('sensei_show_lesson_numbers', false)) { $count_markup = '<span class="lesson-number">' . $loop_lesson_number . '</span>'; } $heading_link_title = sprintf(__('Start %s', 'woothemes-sensei'), get_the_title($lesson_id)); ?> <header> <h2> <a href="<?php echo esc_url_raw(get_permalink($lesson_id)); ?> " title="<?php esc_attr_e($heading_link_title); ?> " > <?php echo $count_markup . get_the_title($lesson_id) . $preview_label; ?> </a> </h2> <p class="lesson-meta"> <?php $meta_html = ''; $user_lesson_status = Sensei_Utils::user_lesson_status(get_the_ID(), get_current_user_id()); $lesson_length = get_post_meta($lesson_id, '_lesson_length', true); if ('' != $lesson_length) { $meta_html .= '<span class="lesson-length">' . __('Length: ', 'woothemes-sensei') . $lesson_length . __(' minutes', 'woothemes-sensei') . '</span>'; } if (Sensei()->settings->get('lesson_author')) { $meta_html .= '<span class="lesson-author">' . __('Author: ', 'woothemes-sensei') . '<a href="' . get_author_posts_url(absint(get_post()->post_author)) . '" title="' . esc_attr($user_info->display_name) . '">' . esc_html($user_info->display_name) . '</a></span>'; } // End If Statement if ('' != $lesson_complexity) { $meta_html .= '<span class="lesson-complexity">' . __('Complexity: ', 'woothemes-sensei') . $lesson_complexity . '</span>'; } if ($single_lesson_complete) { $meta_html .= '<span class="lesson-status complete">' . __('Complete', 'woothemes-sensei') . '</span>'; } elseif ($user_lesson_status) { $meta_html .= '<span class="lesson-status in-progress">' . __('In Progress', 'woothemes-sensei') . '</span>'; } // End If Statement echo $meta_html; ?> </p> <!-- lesson meta --> </header> <?php }
public static function user_passed_quiz($quiz_id = 0, $user_id = 0) { if (!$quiz_id) { return false; } if (!$user_id) { $user_id = get_current_user_id(); } $lesson_id = get_post_meta($quiz_id, '_quiz_lesson', true); // Quiz Grade $lesson_status = Sensei_Utils::user_lesson_status($lesson_id, $user_id); $quiz_grade = get_comment_meta($lesson_status->comment_ID, 'grade', true); // Check if Grade is greater than or equal to pass percentage $quiz_passmark = abs(round(doubleval(get_post_meta($quiz_id, '_quiz_passmark', true)), 2)); if ($quiz_passmark <= intval($quiz_grade)) { return true; } return false; }
<?php _e('Other Lessons', 'woothemes-sensei'); ?> </h3> <?php foreach ($lessons as $lesson) { ?> <?php $lesson_grade = 'n/a'; $has_questions = get_post_meta($lesson->ID, '_quiz_has_questions', true); if ($has_questions) { $lesson_status = Sensei_Utils::user_lesson_status($lesson->ID, get_current_user_id()); // Get user quiz grade $lesson_grade = get_comment_meta($lesson_status->comment_ID, 'grade', true); if ($lesson_grade) { $lesson_grade .= '%'; } } ?> <h2> <a href="<?php esc_url_raw(get_permalink($lesson->ID)); ?> " title="<?php esc_attr_e(sprintf(__('Start %s', 'woothemes-sensei'), $lesson->post_title));
/** * This function can only be run withing the single quiz question loop * * @since 1.9.0 * @param $question_id */ public static function answer_feedback_notes($question_id) { //IDS $quiz_id = get_the_ID(); $lesson_id = Sensei()->quiz->get_lesson_id($quiz_id); // Data to check before showing feedback $user_lesson_status = Sensei_Utils::user_lesson_status($lesson_id, get_current_user_id()); $user_quiz_grade = Sensei_Quiz::get_user_quiz_grade($lesson_id, get_current_user_id()); $not_empty_user_quiz_grade = !empty($user_quiz_grade); $reset_quiz_allowed = Sensei_Quiz::is_reset_allowed($lesson_id); $lesson_completed = Sensei_Utils::user_completed_lesson($lesson_id); $quiz_grade_type = get_post_meta($quiz_id, '_quiz_grade_type', true); if ($lesson_completed && $not_empty_user_quiz_grade || $lesson_completed && !$reset_quiz_allowed && 'auto' == $quiz_grade_type || 'auto' == $quiz_grade_type && !$reset_quiz_allowed && $not_empty_user_quiz_grade) { $answer_notes = Sensei()->quiz->get_user_question_feedback($lesson_id, $question_id, get_current_user_id()); if ($answer_notes) { ?> <div class="sensei-message info info-special answer-feedback"> <?php /** * Filter the answer feedback * Since 1.9.0 * * @param string $answer_notes * @param string $question_id * @param string $lesson_id */ echo apply_filters('sensei_question_answer_notes', $answer_notes, $question_id, $lesson_id); ?> </div> <?php } } // end if we can show answer feedback }
/** * Fetch the quiz grade * * @since 1.9.0 * * @param int $lesson_id * @param int $user_id * * @return double $user_quiz_grade */ public static function get_user_quiz_grade($lesson_id, $user_id) { // get the quiz grade $user_lesson_status = Sensei_Utils::user_lesson_status($lesson_id, $user_id); $user_quiz_grade = 0; if (isset($user_lesson_status->comment_ID)) { $user_quiz_grade = get_comment_meta($user_lesson_status->comment_ID, 'grade', true); } return (double) $user_quiz_grade; }
/** * This tests Sensei()->quiz->save_user_answers_feedback */ public function testSaveUserAnswersFeedback() { // setup the data and objects needed for this test $test_user_id = wp_create_user('studentFeedbackSave', 'studentFeedbackSave', '*****@*****.**'); $test_lesson_id = $this->factory->get_random_lesson_id(); $test_quiz_id = Sensei()->lesson->lesson_quizzes($test_lesson_id); // does the save_user_answers function exist? $this->assertTrue(method_exists(Sensei()->quiz, 'save_user_answers_feedback'), 'The quiz class function `save_user_answers_feedback` does not exist '); // does this save_user_answers return false for bogus data $this->assertFalse(Sensei()->quiz->save_user_answers_feedback(array(), array(), -1000, -200), 'save_user_answers_feedback does not return false for no existent users and lesson '); $this->assertFalse(Sensei()->quiz->save_user_answers_feedback('', array(), '', ''), 'save_user_answers_feedback does not return false for empty parameters'); // does the function return the correct information when a user doesn't exist? $this->assertFalse(Sensei()->quiz->save_user_answers_feedback('', array(), '', $test_lesson_id), 'save_user_answers_feedback does not return false for empty user'); $this->assertFalse(Sensei()->quiz->save_user_answers_feedback('', array(), -500, $test_lesson_id), 'save_user_answers_feedback does not return false for a non existant user'); // Test the answers_array parameter $this->assertFalse(Sensei()->quiz->save_user_answers_feedback('Answers Text', array(), $test_lesson_id, $test_user_id), 'save_user_answers_feedback does not return false if answers is not passed in as an array'); $this->assertFalse(Sensei()->quiz->save_user_answers_feedback('', array(), $test_lesson_id, $test_user_id), 'save_user_answers_feedback does not return false for empty answer array'); $this->assertFalse(Sensei()->quiz->save_user_answers_feedback('', array(), '', ''), 'save_user_answers_feedback does not return false incorrectly formatted answers'); // Test a case that is setup correctly which should return a positive result $test_user_answers_feedback = $this->factory->generate_user_answers_feedback($test_quiz_id); Sensei_Utils::sensei_start_lesson($test_lesson_id, $test_user_id); $lesson_data_saved = Sensei()->quiz->save_user_answers_feedback($test_user_answers_feedback, $test_lesson_id, $test_user_id); // did the correct data return a valid comment id on the lesson as a result? $this->assertTrue(intval($lesson_data_saved) > 0, 'The comment id returned after saving the quiz feedback does not represent a valid comment '); //setup for the next group of assertions $sensei_activity_logged = Sensei_Utils::sensei_check_for_activity(array('post_id' => $test_lesson_id, 'user_id' => $test_user_id)); $status_comment = Sensei_Utils::user_lesson_status($test_lesson_id, $test_user_id); $saved_feedback = get_comment_meta($status_comment->comment_ID, 'quiz_answers_feedback', true); // was the data that was just stored stored correctly ? Check the comment meta on the lesson id $this->assertTrue((bool) $sensei_activity_logged, 'The saved answers feedback was not stored correctly on the Lesson'); $this->assertFalse(empty($saved_feedback), 'The saved feedback was not stored correctly on the Quiz'); $this->assertTrue(is_array(maybe_unserialize($saved_feedback)), 'The saved feedback was not stored correctly on the Lesson'); // can you retrieve data and is it the same as what was stored? //compare every single answer $retrieved_feedback_array = maybe_unserialize($saved_feedback); foreach ($test_user_answers_feedback as $question_id => $feedback) { $saved_single_answer = $retrieved_feedback_array[$question_id]; $assert_message = 'The saved feedback does not correspond to what was passed into the save_user_answers_feedback function '; $this->assertEquals($feedback, base64_decode($saved_single_answer), $assert_message); } // end for each }