-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathemailgrades.class.php
378 lines (325 loc) · 13 KB
/
emailgrades.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The local parents email grades class.
*
* @package local_parents
* @copyright 2016 Gilles-Philippe Leblanc <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/grade/export/lib.php');
/**
* The local parents email grades class.
*
* @copyright 2015 Gilles-Philippe Leblanc <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class local_parents_emailgrades extends grade_export {
/**
* @var string The plugin name;
*/
public $plugin = 'emailgrades';
/**
* @var string The email address of the sender of the email.
*/
private $from;
/**
* @var string The list of users who will receive the email.
*/
private $parentlist;
/**
* @var string The subject of the email.
*/
private $subject;
/**
* @var string The message prefix of the email.
*/
private $messageprefix;
/**
* @var string The signature of the sender of the email.
*/
private $signature;
/**
* @var boolean If we show the max possible grade for a grade item.
*/
private $showmaxgrade;
/**
* Constructor should set up all the private variables ready to be pulled.
*
* This constructor used to accept the individual parameters as separate arguments, in
* 2.8 this was simplified to just accept the data from the moodle form.
*
* @param object $course The course object containing the user grades to email.
* @param stdClass|null $formdata
*/
public function __construct($course, $formdata) {
parent::__construct($course, 0, $formdata);
}
/**
* Init object based using data from form
* @param object $formdata
*/
public function process_form($formdata) {
parent::process_form($formdata);
if (isset($formdata->from)) {
$this->from = $formdata->from;
}
if (isset($formdata->subject)) {
$this->subject = $formdata->subject;
}
if (isset($formdata->messageprefix)) {
$this->messageprefix = $formdata->messageprefix;
}
if (isset($formdata->signature)) {
$this->signature = $formdata->signature;
}
if (isset($formdata->parentlist)) {
$this->parentlist = $formdata->parentlist;
}
if (isset($formdata->showmaxgrade)) {
$this->showmaxgrade = $formdata->showmaxgrade;
}
// Redefine items if it comes from preview instead of edit form.
if (!empty($formdata->itemsids) && $formdata->itemsids != '-1' && !isset($formdata->itemids)) {
$this->columns = array();
$itemids = explode(',', $formdata->itemsids);
foreach ($itemids as $itemid) {
if (array_key_exists($itemid, $this->grade_items)) {
$this->columns[$itemid] =& $this->grade_items[$itemid];
}
}
}
}
/**
* This is an abstract method se we need to implement it but we will
* not use it since we email the grades instead of creating a file.
*/
public function print_grades() {
}
/**
* Compose and email the grades to all parents.
*/
public function email_grades() {
global $USER;
$parentsmessage = $this->get_parents_message();
$parents = $this->get_parents();
$result = true;
// For each parent, compose the message body and email it.
foreach ($parents as $parent) {
$htmlbody = $this->compose_complete_message($parentsmessage[$parent->id]);
$body = html_to_text($htmlbody);
if (!email_to_user($parent, $USER, $this->subject, $body, $htmlbody)) {
$result = false;
}
}
return $result;
}
/**
* Prints preview of exported grades for students of a given parent on screen.
*
* @param int $parentid The id of a parent for whom we want to find the users grades.
*/
public function display_message_preview($parentid) {
$parentsmessage = $this->get_parents_message($parentid);
return $this->compose_complete_message($parentsmessage[$parentid]);
}
/**
* Compose a message by adding a prefix and signature.
*
* @param string $message The message to be composed.
* @return string The composed message.
*/
private function compose_complete_message($message) {
$html = $this->messageprefix . "\n\n";
$html .= $message;
$html .= $this->signature;
return $html;
}
/**
* Prints preview of exported grades on screen as a feedback mechanism.
*
* @param int $parentid The id of a parent for whom we want to find the users.
* @return array The list of user with their specific parents/mentors/tutors.
*/
private function get_parents_message($parentid = null) {
$exporttracking = $this->track_exports();
$userswithparents = $this->get_course_users_by_parents_id();
$parentsmessage = array();
$showallgrades = $this->showmaxgrade && $this->displaytype != GRADE_DISPLAY_TYPE_LETTER;
$displaytypes = array(
GRADE_DISPLAY_TYPE_REAL => 'real',
GRADE_DISPLAY_TYPE_PERCENTAGE => 'percentage',
GRADE_DISPLAY_TYPE_LETTER => 'letter'
);
// Print all the lines of data.
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns);
$gui->init();
while ($userdata = $gui->next_user()) {
$user = $userdata->user;
// If the user have to parents on the course, we skip him.
if (!array_key_exists($user->id, $userswithparents)) {
continue;
}
$table = new html_table();
$head = array(get_string('gradeitem', 'grades'), get_string('grade', 'grades'));
if ($showallgrades) {
$head[] = get_string('maxgrade', 'grades');
}
if ($this->export_feedback) {
$head[] = get_string('feedback');
}
$table->head = $head;
$table->data = array();
foreach ($this->columns as $itemid => $gradeitem) {
$grade = new grade_grade(array('itemid' => $itemid, 'userid' => $user->id));
if ($exporttracking) {
$geub->track($grade);
}
$row = array();
$row[] = $this->format_column_name($gradeitem, false, $displaytypes[$this->displaytype]);
$row[] = $this->format_grade($userdata->grades[$itemid], $this->displaytype);
if ($showallgrades) {
$row[] = $this->format_max_grade($gradeitem);
}
if ($this->export_feedback) {
$row[] = $this->format_feedback($userdata->feedbacks[$itemid]);
}
$table->data[] = $row;
}
foreach ($userswithparents[$user->id] as $parentid) {
if (!array_key_exists($parentid, $parentsmessage)) {
$parentsmessage[$parentid] = '';
}
$firstname = html_writer::tag('b', $user->firstname);
$parentsmessage[$parentid] .= html_writer::tag('p', get_string('gradestablefor', 'local_parents',
$firstname));
$parentsmessage[$parentid] .= html_writer::table($table);
}
}
$gui->close();
$geub->close();
return $parentsmessage;
}
/**
* Get the select parents and their emails.
*
* @return object The parent list.
*/
private function get_parents() {
global $DB;
$list = explode(',', $this->parentlist);
return $DB->get_recordset_list('user', 'id', $list, '', 'id,email,deleted,auth,suspended');
}
/**
* Get all users of the current course who having a specified parents/mentors/tutors
* and their specific parents/mentors/tutors.
*
* @param int $parentid The id of a parent for whom we want to find the users.
* @return array The list of user with their specific parents/mentors/tutors.
*/
public function get_course_users_by_parents_id($parentid = null) {
global $DB;
$context = context_course::instance($this->course->id, MUST_EXIST);
list($esql, $params) = get_enrolled_sql($context, null, 0, true);
$joins = array("FROM {user} child");
$parentroleid = 10;
// Performance hacks - we preload user contexts together with accounts.
$ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
$ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = child.id AND ctx.contextlevel = :contextlevel)";
$params['contextlevel'] = CONTEXT_USER;
$joins[] = $ccjoin;
$select = "SELECT DISTINCT child.id id, u.id parentid";
$joins[] = "JOIN ($esql) e ON e.id = child.id";
$joins[] = "JOIN {user_enrolments} ue ON child.id = ue.userid";
$joins[] = "LEFT JOIN {role_assignments} ra ON (ra.contextid = ctx.id)";
$joins[] = "LEFT JOIN {role} r ON (ra.roleid = r.id) AND r.id = $parentroleid";
$joins[] = "JOIN {user} u ON (ra.userid = u.id) AND u.id ";
if (!empty($parentid)) {
$joins[] = "= " . $parentid;
} else {
$joins[] = "IN (" . $this->parentlist . ")";
}
$select .= $ccselect;
$from = implode("\n", $joins);
$users = array();
$userrecords = $DB->get_recordset_sql("$select $from", $params);
foreach ($userrecords as $user) {
if (!array_key_exists($user->id, $users)) {
$users[$user->id] = array();
}
$parentid = (int)$user->parentid;
$users[$user->id][$parentid] = $parentid;
}
return $users;
}
/**
* Returns string representation of final grade.
* Override completely this method to add the scale position if the scale is used.
*
* @param grade_grade $grade instance of grade_grade class
* @param integer $gradedisplayconst grade display type constant.
* @return string The formatted grade.
*/
public function format_grade($grade, $gradedisplayconst = null) {
$formattedgrade = parent::format_grade($grade, $gradedisplayconst);
$gradeitem = $this->grade_items[$grade->itemid];
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$formattedgrade = $this->format_with_scale_position($formattedgrade, $gradeitem);
}
return $formattedgrade;
}
/**
* Returns a string representing grademax for a grade item.
*
* @param grade_item $gradeitem The grade item.
* @return string The formatted max grade.
*/
public function format_max_grade(grade_item $gradeitem) {
if ($this->displaytype == GRADE_DISPLAY_TYPE_PERCENTAGE) {
$grademax = "100 %";
} else {
$grademax = grade_format_gradevalue($gradeitem->grademax, $gradeitem, true, $this->displaytype, $this->decimalpoints);
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$grademax = $this->format_with_scale_position($grademax, $gradeitem);
}
}
return $grademax;
}
/**
* Format a scale grade by adding its scale position.
* Ex: "quite acceptable (3)" instead of "quite acceptable".
*
* @param string $formattedgrade The formatted grade.
* @param grade_item $gradeitem The grade item.
* @return string The formatted grade with position.
*/
private function format_with_scale_position($formattedgrade, grade_item $gradeitem) {
global $DB;
$string = $formattedgrade;
if ($gradeitem->gradetype == GRADE_TYPE_SCALE && $formattedgrade != "-") {
$scale = $DB->get_record('scale', array('id' => $gradeitem->scaleid));
// If the item is using a scale that's not been removed.
if (!empty($scale)) {
$scaleitems = array_map('trim', explode(',', $scale->scale));
$key = array_search($formattedgrade, $scaleitems) + 1;
$string .= ' (' . $key . ')';
}
}
return $string;
}
}