MDL-65176 analytics: target for students who don't get the minimum grade
[moodle.git] / lib / classes / analytics / target / course_gradetopass.php
bloba530cd565a9e6f2efa27373b1d40815bdcb6cde5
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * Getting the minimum grade to pass target.
20 * @package core
21 * @copyright 2019 Victor Deniz <victor@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace core\analytics\target;
27 defined('MOODLE_INTERNAL') || die();
30 /**
31 * Getting the minimum grade to pass target.
33 * @package core
34 * @copyright 2019 Victor Deniz <victor@moodle.com>
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 class course_gradetopass extends \core\analytics\target\course_enrolments {
39 /**
40 * Courses grades to pass.
41 * @var mixed[]
43 protected $coursesgradetopass = array();
45 /**
46 * Courses grades.
47 * @var mixed[]
49 protected $coursesgrades = array();
51 /**
52 * Returns the grade to pass a course.
54 * Save the value in $coursesgradetopass array to prevent new accesses to the database.
56 * @param int $courseid The course id.
57 * @return array The courseitem id and the required grade to pass the course.
59 protected function get_course_gradetopass($courseid) {
60 if (!isset($this->coursesgradetopass[$courseid])) {
61 // Get course grade_item.
62 $courseitem = \grade_item::fetch_course_item($courseid);
64 $ci = array();
65 $ci['courseitemid'] = $courseitem->id;
67 if ($courseitem->gradetype == GRADE_TYPE_VALUE && grade_floats_different($courseitem->gradepass, 0.0)) {
68 $ci['gradetopass'] = $courseitem->gradepass;
69 } else {
70 $ci['gradetopass'] = null;
72 $this->coursesgradetopass[$courseid] = $ci;
75 return $this->coursesgradetopass[$courseid];
78 /**
79 * Returns the grade of a user in a course.
81 * Saves the grades of all course users in $coursesgrades array to prevent new accesses to the database.
83 * @param int $courseitemid The course item id.
84 * @param int $userid the user whose grade is requested.
85 * @return array The courseitem id and the required grade to pass the course.
87 protected function get_user_grade($courseitemid, $userid) {
88 // If the user grade for this course is not available, get all the grades for the course.
89 if (!isset($this->coursesgrades[$courseitemid])) {
90 // Ony a course is cached to avoid high memory usage.
91 unset($this->coursesgrades);
92 $gg = new \grade_grade(null, false);
93 $usersgrades = $gg->fetch_all(array('itemid' => $courseitemid));
95 if ($usersgrades) {
96 foreach ($usersgrades as $ug) {
97 $this->coursesgrades[$courseitemid][$ug->userid] = $ug->finalgrade;
102 if (!isset($this->coursesgrades[$courseitemid][$userid])) {
103 $this->coursesgrades[$courseitemid][$userid] = null;
106 return $this->coursesgrades[$courseitemid][$userid];
110 * Returns the name.
112 * If there is a corresponding '_help' string this will be shown as well.
114 * @return \lang_string
116 public static function get_name() : \lang_string {
117 return new \lang_string('target:coursegradetopass');
121 * Returns descriptions for each of the values the target calculation can return.
123 * @return string[]
125 protected static function classes_description() {
126 return array(
127 get_string('targetlabelstudentgradetopassno'),
128 get_string('targetlabelstudentgradetopassyes')
133 * Discards courses that are not yet ready to be used for training or prediction.
135 * Only courses with "value" grade type and grade to pass set are valid.
137 * @param \core_analytics\analysable $course
138 * @param bool $fortraining
139 * @return true|string
141 public function is_valid_analysable(\core_analytics\analysable $course, $fortraining = true) {
142 $isvalid = parent::is_valid_analysable($course, $fortraining);
144 if (is_string($isvalid)) {
145 return $isvalid;
148 $courseitem = $this->get_course_gradetopass ($course->get_id());
149 if (is_null($courseitem['gradetopass'])) {
150 return get_string('gradetopassnotset', 'course');
153 return true;
157 * The user's grade in the course sets the target value.
159 * @param int $sampleid
160 * @param \core_analytics\analysable $course
161 * @param int $starttime
162 * @param int $endtime
163 * @return float 0 -> course grade to pass achieved, 1 -> course grade to pass not achieved
165 protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) {
167 $userenrol = $this->retrieve('user_enrolments', $sampleid);
169 // Get course grade to pass.
170 $courseitem = $this->get_course_gradetopass($course->get_id());
172 // Get the user grade.
173 $usergrade = $this->get_user_grade($courseitem['courseitemid'], $userenrol->userid);
175 if ($usergrade >= $courseitem['gradetopass']) {
176 return 0;
179 return 1;