LLMS_Grades
Contents
Source Source
File: includes/class-llms-grades.php
class LLMS_Grades { use LLMS_Trait_Singleton; /** * Determines the rounding precision used by grading functions * * @var int */ private $rounding_precision = 2; /** * Private constructor * * @since 3.24.0 * @version 3.24.0 */ private function __construct() { $this->rounding_precision = apply_filters( 'llms_grade_rounding_precision', $this->rounding_precision ); } /** * Calculates the grades for elements that have a list of children which are averaged / weighted to come up with the total grade * * @param array $children list of child objects * @param LLMS_Student $student A LLMS_Student object. * @return float|null * @since 3.24.0 * @version 3.24.0 */ private function calculate_grade_from_children( $children, $student ) { $grade = null; $grades = array(); // Loop through all the children and compile the overall grade & points data. foreach ( $children as $child_id ) { $child = llms_get_post( $child_id ); $grade = $this->get_grade( $child_id, $student, false ); // Non numeric grade (null) hasn't been taken yet or no gradable elements exist on the child. if ( ! is_numeric( $grade ) ) { continue; } $points = $child->get( 'points' ); // If no points assigned to the child, the grade doesn't count towards the overall grade. if ( ! $points ) { continue; } // Add the grade & points for further processing after we have all the data. $grades[] = array( 'grade' => $grade, 'points' => $points, ); } // If we have at least one grade. if ( count( $grades ) ) { // Get the total available points for all children with a numeric grade & a points value. $total_points = array_sum( wp_list_pluck( $grades, 'points' ) ); // If we don't have any points this element can't have an overall grade. if ( $total_points ) { // Sum up the adjusted grade. $grade = 0; foreach ( $grades as $data ) { // Calculate the adjusted the grade. // Grade multiplied by available points over total points. $grade += $data['grade'] * ( $data['points'] / $total_points ); } } } return $grade; } /** * Calculate the grade for a course * * @param LLMS_Course $course A LLMS_Course object. * @param LLMS_Student $student A LLMS_Student object. * @return float|null * @since 3.24.0 * @version 3.24.0 */ private function calculate_course_grade( $course, $student ) { return apply_filters( 'llms_calculate_course_grade', $this->calculate_grade_from_children( $course->get_lessons( 'ids' ), $student ), $course, $student ); } /** * Main grade calculation function * Calculates the grade for a gradable post model * DOES NOT CACHE RESULTS! * See get_grade() for a function which uses caching * * @param LLMS_Post_Model $post A LLMS_Post_Model object. * @param LLMS_Student $student A LLMS_Student object. * @return float|null * @since 3.24.0 * @version 3.24.0 */ public function calculate_grade( $post, $student ) { $grade = null; $post_type = $post->get( 'type' ); switch ( $post_type ) { case 'course': /** @var LLMS_Course $post */ $grade = $this->calculate_course_grade( $post, $student ); break; case 'lesson': /** @var LLMS_Lesson $post */ $grade = $this->calculate_lesson_grade( $post, $student ); break; case 'llms_quiz': $attempt = $student->quizzes()->get_best_attempt( $post->get( 'id' ) ); if ( $attempt ) { $grade = $attempt->get( 'grade' ); } break; // 3rd party / custom element grading. default: $grade = apply_filters( 'llms_calculate_' . $post_type . '_grade', $grade, $post, $student ); } // Round numeric results. if ( is_numeric( $grade ) ) { $grade = $this->round( $grade ); } return apply_filters( 'llms_calculate_grade', $grade, $post, $student ); } /** * Calculates the grade for a lesson * * @param LLMS_Lesson $lesson A LLMS_Lesson object. * @param LLMS_Student $student A LLMS_Student object. * @return float|null * @since 3.24.0 * @version 3.24.0 */ private function calculate_lesson_grade( $lesson, $student ) { $grade = null; if ( $lesson->is_quiz_enabled() ) { $grade = $this->get_grade( $lesson->get( 'quiz' ), $student, false ); } return apply_filters( 'llms_calculate_lesson_grade', $grade, $lesson, $student ); } /** * Main grade getter function * * Uses caching by default and can bypass cache when requested * * @since 3.24.0 * @since 4.4.4 Don't pass the `$use_cache` parameter to the `calculate_grade()` method. * * @param WP_Post|int $post_id An instance of WP_Post or a WP Post ID. * @param LLMS_Student $student A LLMS_Student object. * @param bool $use_cache when true, retrieves from cache if available * @return float|null */ public function get_grade( $post_id, $student, $use_cache = true ) { $post = llms_get_post( $post_id ); $student = llms_get_student( $student ); $grade = $use_cache ? $this->get_grade_from_cache( $post, $student ) : false; // Grade not found in cache or we're not using the cache. if ( false === $grade ) { $grade = $this->calculate_grade( $post, $student ); // Store in the cache. wp_cache_set( sprintf( '%d_grade', $post->get( 'id' ) ), $grade, sprintf( 'student_%d', $student->get( 'id' ) ) ); } return apply_filters( 'llms_get_grade', $grade, $post, $student ); } /** * Retrieve a grade from the wp_cache * * @param LLMS_Post_Model $post A LLMS_Post_Model object. * @param LLMS_Student $student A LLMS_Student object. * @return mixed grade as a float * null if there's no grade for the post * false if the grade wasn't found in the cache * @since 3.24.0 * @version 3.24.0 */ private function get_grade_from_cache( $post, $student ) { return wp_cache_get( sprintf( '%d_grade', $post->get( 'id' ) ), sprintf( 'student_%d', $student->get( 'id' ) ) ); } /** * Round grades according to filterable rounding options set during construction * * @param float $grade Grade to round * @return float * @since 3.24.0 * @version 3.24.0 */ public function round( $grade ) { return round( $grade, $this->rounding_precision ); } }
Expand full source code Collapse full source code View on GitHub
Methods Methods
- __construct — Private constructor
- calculate_course_grade — Calculate the grade for a course
- calculate_grade — Main grade calculation function Calculates the grade for a gradable post model DOES NOT CACHE RESULTS! See get_grade() for a function which uses caching
- calculate_grade_from_children — Calculates the grades for elements that have a list of children which are averaged / weighted to come up with the total grade
- calculate_lesson_grade — Calculates the grade for a lesson
- get_grade — Main grade getter function
- get_grade_from_cache — Retrieve a grade from the wp_cache
- instance — Get Main Singleton Instance
- round — Round grades according to filterable rounding options set during construction
Changelog Changelog
Version | Description |
---|---|
6.0.0 | Removed the deprecated LLMS_Grades::$_instance property. |
5.3.0 | Replace singleton code with LLMS_Trait_Singleton . |
3.24.0 | Introduced. |