MDL-62218 analytics: Privacy API implementation
[moodle.git] / lib / classes / analytics / analyser / student_enrolments.php
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.
13 //
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  * Student enrolments analyser.
19  *
20  * @package   core
21  * @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace core\analytics\analyser;
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->dirroot . '/lib/enrollib.php');
31 /**
32  * Student enrolments analyser.
33  *
34  * It does return all student enrolments including the suspended ones.
35  *
36  * @package   core
37  * @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
38  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  */
40 class student_enrolments extends \core_analytics\local\analyser\by_course {
42     /**
43      * @var array Cache for user_enrolment id - course id relation.
44      */
45     protected $samplecourses = array();
47     /**
48      * Defines the origin of the samples in the database.
49      *
50      * @return string
51      */
52     public function get_samples_origin() {
53         return 'user_enrolments';
54     }
56     /**
57      * Returns the student enrolment course context.
58      *
59      * @param int $sampleid
60      * @return \context
61      */
62     public function sample_access_context($sampleid) {
63         return \context_course::instance($this->get_sample_courseid($sampleid));
64     }
66     /**
67      * Returns the student enrolment course.
68      *
69      * @param int $sampleid
70      * @return \core_analytics\analysable
71      */
72     public function get_sample_analysable($sampleid) {
73         $course = enrol_get_course_by_user_enrolment_id($sampleid);
74         return \core_analytics\course::instance($course);
75     }
77     /**
78      * Data provided by get_all_samples & get_samples.
79      *
80      * @return string[]
81      */
82     protected function provided_sample_data() {
83         return array('user_enrolments', 'context', 'course', 'user');
84     }
86     /**
87      * We need to delete associated data if a user requests his data to be deleted.
88      *
89      * @return bool
90      */
91     public function processes_user_data() {
92         return true;
93     }
95     /**
96      * Join the samples origin table with the user id table.
97      *
98      * @param string $sampletablealias
99      * @return string
100      */
101     public function join_sample_user($sampletablealias) {
102         return "JOIN {user_enrolments} ue ON {$sampletablealias}.sampleid = ue.id " .
103                "JOIN {user} u ON u.id = ue.userid";
104     }
106     /**
107      * All course student enrolments.
108      *
109      * It does return all student enrolments including the suspended ones.
110      *
111      * @param \core_analytics\analysable $course
112      * @return array
113      */
114     protected function get_all_samples(\core_analytics\analysable $course) {
116         $enrolments = enrol_get_course_users($course->get_id());
118         // We fetch all enrolments, but we are only interested in students.
119         $studentids = $course->get_students();
121         $samplesdata = array();
122         foreach ($enrolments as $userenrolmentid => $user) {
124             if (empty($studentids[$user->id])) {
125                 // Not a student.
126                 continue;
127             }
129             $sampleid = $userenrolmentid;
130             $samplesdata[$sampleid]['user_enrolments'] = (object)array(
131                 'id' => $user->ueid,
132                 'status' => $user->uestatus,
133                 'enrolid' => $user->ueenrolid,
134                 'userid' => $user->id,
135                 'timestart' => $user->uetimestart,
136                 'timeend' => $user->uetimeend,
137                 'modifierid' => $user->uemodifierid,
138                 'timecreated' => $user->uetimecreated,
139                 'timemodified' => $user->uetimemodified
140             );
141             unset($user->ueid);
142             unset($user->uestatus);
143             unset($user->ueenrolid);
144             unset($user->uetimestart);
145             unset($user->uetimeend);
146             unset($user->uemodifierid);
147             unset($user->uetimecreated);
148             unset($user->uetimemodified);
150             $samplesdata[$sampleid]['course'] = $course->get_course_data();
151             $samplesdata[$sampleid]['context'] = $course->get_context();
152             $samplesdata[$sampleid]['user'] = $user;
154             // Fill the cache.
155             $this->samplecourses[$sampleid] = $course->get_id();
156         }
158         $enrolids = array_keys($samplesdata);
159         return array(array_combine($enrolids, $enrolids), $samplesdata);
160     }
162     /**
163      * Returns all samples from the samples ids.
164      *
165      * @param int[] $sampleids
166      * @return array
167      */
168     public function get_samples($sampleids) {
169         global $DB;
171         $enrolments = enrol_get_course_users(false, false, array(), $sampleids);
173         // Some course enrolments.
174         list($enrolsql, $params) = $DB->get_in_or_equal($sampleids, SQL_PARAMS_NAMED);
176         $samplesdata = array();
177         foreach ($enrolments as $userenrolmentid => $user) {
179             $sampleid = $userenrolmentid;
180             $samplesdata[$sampleid]['user_enrolments'] = (object)array(
181                 'id' => $user->ueid,
182                 'status' => $user->uestatus,
183                 'enrolid' => $user->ueenrolid,
184                 'userid' => $user->id,
185                 'timestart' => $user->uetimestart,
186                 'timeend' => $user->uetimeend,
187                 'modifierid' => $user->uemodifierid,
188                 'timecreated' => $user->uetimecreated,
189                 'timemodified' => $user->uetimemodified
190             );
191             unset($user->ueid);
192             unset($user->uestatus);
193             unset($user->ueenrolid);
194             unset($user->uetimestart);
195             unset($user->uetimeend);
196             unset($user->uemodifierid);
197             unset($user->uetimecreated);
198             unset($user->uetimemodified);
200             // Enrolment samples are grouped by the course they belong to, so all $sampleids belong to the same
201             // course, $courseid and $coursemodinfo will only query the DB once and cache the course data in memory.
202             $courseid = $this->get_sample_courseid($sampleid);
203             $coursemodinfo = get_fast_modinfo($courseid);
204             $coursecontext = \context_course::instance($courseid);
206             $samplesdata[$sampleid]['course'] = $coursemodinfo->get_course();
207             $samplesdata[$sampleid]['context'] = $coursecontext;
208             $samplesdata[$sampleid]['user'] = $user;
210             // Fill the cache.
211             $this->samplecourses[$sampleid] = $coursemodinfo->get_course()->id;
212         }
214         $enrolids = array_keys($samplesdata);
215         return array(array_combine($enrolids, $enrolids), $samplesdata);
216     }
218     /**
219      * Returns the student enrolment course id.
220      *
221      * @param int $sampleid
222      * @return int
223      */
224     protected function get_sample_courseid($sampleid) {
225         global $DB;
227         if (empty($this->samplecourses[$sampleid])) {
228             $course = enrol_get_course_by_user_enrolment_id($sampleid);
229             $this->samplecourses[$sampleid] = $course->id;
230         }
232         return $this->samplecourses[$sampleid];
233     }
235     /**
236      * Returns the visible name of a sample + a renderable to display as sample picture.
237      *
238      * @param int $sampleid
239      * @param int $contextid
240      * @param array $sampledata
241      * @return array array(string, \renderable)
242      */
243     public function sample_description($sampleid, $contextid, $sampledata) {
244         $description = fullname($sampledata['user'], true, array('context' => $contextid));
245         return array($description, new \user_picture($sampledata['user']));
246     }