2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
18 * Getting the minimum grade to pass target.
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();
31 * Getting the minimum grade to pass target.
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
{
40 * Courses grades to pass.
43 protected $coursesgradetopass = array();
49 protected $coursesgrades = array();
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);
65 $ci['courseitemid'] = $courseitem->id
;
67 if ($courseitem->gradetype
== GRADE_TYPE_VALUE
&& grade_floats_different($courseitem->gradepass
, 0.0)) {
68 $ci['gradetopass'] = $courseitem->gradepass
;
70 $ci['gradetopass'] = null;
72 $this->coursesgradetopass
[$courseid] = $ci;
75 return $this->coursesgradetopass
[$courseid];
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));
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];
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.
125 protected static function classes_description() {
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)) {
148 $courseitem = $this->get_course_gradetopass ($course->get_id());
149 if (is_null($courseitem['gradetopass'])) {
150 return get_string('gradetopassnotset', 'course');
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']) {