1 |
efrain |
1 |
<?php
|
497 |
ariadna |
2 |
|
1 |
efrain |
3 |
use core_completion\progress;
|
497 |
ariadna |
4 |
|
1 |
efrain |
5 |
require_once $CFG->libdir . '/badgeslib.php';
|
|
|
6 |
|
497 |
ariadna |
7 |
class block_progreso_detalles_renderer extends plugin_renderer_base
|
|
|
8 |
{
|
1 |
efrain |
9 |
|
497 |
ariadna |
10 |
public function procesar($instance_id)
|
|
|
11 |
{
|
|
|
12 |
|
1 |
efrain |
13 |
global $USER, $CFG, $DB, $PAGE, $OUTPUT;
|
497 |
ariadna |
14 |
|
1 |
efrain |
15 |
require_once $CFG->libdir . '/completionlib.php';
|
497 |
ariadna |
16 |
require_once $CFG->dirroot . '/completion/classes/progress.php';
|
1 |
efrain |
17 |
require_once $CFG->dirroot . '/course/classes/category.php';
|
|
|
18 |
require_once $CFG->libdir . '/gradelib.php';
|
|
|
19 |
require_once $CFG->dirroot . '/grade/querylib.php';
|
497 |
ariadna |
20 |
|
1 |
efrain |
21 |
//require_once $CFG->libdir . '/coursecatlib.php';
|
|
|
22 |
$url_noimage = $CFG->wwwroot . '/theme/' . $PAGE->theme->name . '/pix/coursenoimage.jpg';
|
497 |
ariadna |
23 |
|
|
|
24 |
if (!file_exists($CFG->dirroot . '/cesa/progreso_detalles/')) {
|
|
|
25 |
mkdir($CFG->dirroot . '/cesa/progreso_detalles/', 0755, true);
|
1 |
efrain |
26 |
}
|
497 |
ariadna |
27 |
if (!file_exists($CFG->dirroot . '/cesa/progreso_detalles/' . $USER->id)) {
|
|
|
28 |
mkdir($CFG->dirroot . '/cesa/progreso_detalles/' . $USER->id, 0755, true);
|
1 |
efrain |
29 |
}
|
497 |
ariadna |
30 |
$oldfiles = glob($CFG->dirroot . '/cesa/progreso_detalles/' . $USER->id . '/*');
|
1 |
efrain |
31 |
foreach ($oldfiles as $file) {
|
|
|
32 |
if (is_file($file)) {
|
|
|
33 |
unlink($file);
|
|
|
34 |
}
|
|
|
35 |
}
|
|
|
36 |
/** Inicio del seteo de las variables para el area del cuadro de progreso */
|
|
|
37 |
$dedication = 0;
|
|
|
38 |
$completed = 0;
|
|
|
39 |
$inprogress = 0;
|
|
|
40 |
$grades = 0;
|
|
|
41 |
$points = 0;
|
|
|
42 |
$badges = 0;
|
|
|
43 |
$content = '';
|
|
|
44 |
/** Inicio de las variables para el area de */
|
497 |
ariadna |
45 |
|
|
|
46 |
$user = $DB->get_record('user', array('id' => $USER->id));
|
1 |
efrain |
47 |
$mycourses = enrol_get_users_courses($USER->id);
|
|
|
48 |
$max_time = time();
|
|
|
49 |
$min_time = strtotime('-1 YEAR');
|
|
|
50 |
$limit = 3600;
|
|
|
51 |
|
|
|
52 |
$data = [
|
497 |
ariadna |
53 |
'user_name' => $user->firstname . ' ' . $user->lastname,
|
1 |
efrain |
54 |
'user_image' => $OUTPUT->user_picture($user, array('size' => 100, 'link' => false, 'alttext' => false)),
|
|
|
55 |
'user_email' => $user->email,
|
|
|
56 |
'graph_dedication' => '',
|
|
|
57 |
'completed' => 0,
|
|
|
58 |
'inprogress' => 0,
|
|
|
59 |
'total_dedication' => '',
|
|
|
60 |
'courses' => []
|
|
|
61 |
];
|
|
|
62 |
|
|
|
63 |
|
497 |
ariadna |
64 |
|
|
|
65 |
|
1 |
efrain |
66 |
$graph_percentage = [];
|
|
|
67 |
$graph_dedication = [];
|
|
|
68 |
$graph_labels = [];
|
497 |
ariadna |
69 |
|
|
|
70 |
|
1 |
efrain |
71 |
$completed = 0;
|
|
|
72 |
$inprogress = 0;
|
497 |
ariadna |
73 |
$dedication = 0;
|
1 |
efrain |
74 |
$total_dedication = 0;
|
|
|
75 |
|
497 |
ariadna |
76 |
|
|
|
77 |
foreach ($mycourses as $key => $val) {
|
1 |
efrain |
78 |
$course = get_course($val->id);
|
|
|
79 |
$modules = get_fast_modinfo($val->id)->get_cms();
|
|
|
80 |
$linkurl = '';
|
|
|
81 |
|
|
|
82 |
$first_section = 0;
|
|
|
83 |
$sections = $DB->get_records('course_sections', ['course' => $course->id], 'section ASC', 'id,name,section,sequence,visible');
|
|
|
84 |
|
497 |
ariadna |
85 |
foreach ($sections as $section) {
|
|
|
86 |
if (!empty($section->section)) {
|
|
|
87 |
$first_section = $section->id;
|
|
|
88 |
break;
|
|
|
89 |
}
|
|
|
90 |
}
|
1 |
efrain |
91 |
|
497 |
ariadna |
92 |
foreach ($modules as $module) {
|
|
|
93 |
if (!$module->uservisible || $module->is_stealth() || empty($module->url) || empty($module->section)) {
|
|
|
94 |
continue;
|
|
|
95 |
}
|
1 |
efrain |
96 |
|
497 |
ariadna |
97 |
if ($module->section == $first_section) {
|
|
|
98 |
$linkurl = new moodle_url($module->url, array('forceview' => 1));
|
|
|
99 |
|
|
|
100 |
break;
|
|
|
101 |
}
|
|
|
102 |
}
|
|
|
103 |
|
1 |
efrain |
104 |
if ($course instanceof stdClass) {
|
|
|
105 |
$courseInList = new core_course_list_element($course);
|
|
|
106 |
}
|
|
|
107 |
$image = $url_noimage;
|
497 |
ariadna |
108 |
foreach ($courseInList->get_course_overviewfiles() as $file) {
|
1 |
efrain |
109 |
$isimage = $file->is_valid_image();
|
|
|
110 |
$image = file_encode_url("{$CFG->wwwroot}/pluginfile.php", '/' . $file->get_contextid() . '/' . $file->get_component() . '/' . $file->get_filearea() . $file->get_filepath() . $file->get_filename(), !$isimage);
|
|
|
111 |
if (!$isimage) {
|
|
|
112 |
$image = $url_noimage;
|
|
|
113 |
}
|
|
|
114 |
}
|
497 |
ariadna |
115 |
|
1 |
efrain |
116 |
$lastaccess = null;
|
|
|
117 |
$sql = "select timecreated from {logstore_standard_log} where courseid = :courseid and userid = :userid " .
|
|
|
118 |
" and eventname = '\\\\core\\\\event\\\\course_viewed' order by id desc limit 1 ";
|
497 |
ariadna |
119 |
|
1 |
efrain |
120 |
$timecreated = $DB->get_field_sql($sql, array('courseid' => $course->id, 'userid' => $USER->id));
|
497 |
ariadna |
121 |
if ($timecreated) {
|
|
|
122 |
|
1 |
efrain |
123 |
$lastaccess = date('d/m/Y h:i a', $timecreated);
|
|
|
124 |
}
|
497 |
ariadna |
125 |
|
|
|
126 |
$category = $DB->get_record('course_categories', array('id' => $course->category));
|
|
|
127 |
|
|
|
128 |
|
1 |
efrain |
129 |
$completion = new \completion_info($course);
|
497 |
ariadna |
130 |
$percentage = progress::get_course_progress_percentage($course, $USER->id);
|
1 |
efrain |
131 |
// echo 'course->fullname = '.$course->fullname."% = [$percentage]<br>";
|
|
|
132 |
if ($completion->is_enabled()) {
|
|
|
133 |
$percentage = progress::get_course_progress_percentage($course);
|
|
|
134 |
$percentage = floatval(!$percentage ? 0 : $percentage);
|
|
|
135 |
} else {
|
|
|
136 |
$percentage = 0;
|
|
|
137 |
}
|
497 |
ariadna |
138 |
|
|
|
139 |
|
|
|
140 |
if ($percentage >= 100) {
|
1 |
efrain |
141 |
$completed++;
|
|
|
142 |
} else {
|
|
|
143 |
$inprogress++;
|
|
|
144 |
}
|
497 |
ariadna |
145 |
|
1 |
efrain |
146 |
$resultkrb = grade_get_course_grades($course->id, $USER->id);
|
497 |
ariadna |
147 |
|
|
|
148 |
|
1 |
efrain |
149 |
$grd = $resultkrb->grades[$USER->id];
|
|
|
150 |
$dedication = $this->get_students_dedication($USER->id, $course->id, $min_time, $max_time, $limit);
|
497 |
ariadna |
151 |
|
1 |
efrain |
152 |
$total_dedication = $total_dedication + $dedication;
|
497 |
ariadna |
153 |
|
1 |
efrain |
154 |
$graph_percentage[] = number_format($percentage, 2);
|
|
|
155 |
$graph_labels[] = $course->shortname;
|
497 |
ariadna |
156 |
|
|
|
157 |
|
1 |
efrain |
158 |
$data['courses'][] = [
|
497 |
ariadna |
159 |
|
1 |
efrain |
160 |
'coursecategory' => $category->name,
|
|
|
161 |
'courseimage' => $image,
|
|
|
162 |
'enddate' => $course->enddate,
|
|
|
163 |
'shortname' => $course->shortname,
|
|
|
164 |
'fullname' => $course->fullname,
|
|
|
165 |
'fullnamedisplay' => get_course_display_name_for_list($course),
|
|
|
166 |
'hasprogress' => $percentage > 0,
|
|
|
167 |
'hidden' => false,
|
|
|
168 |
'id' => $course->id,
|
|
|
169 |
'idnumber' => $course->idnumber,
|
|
|
170 |
'isfavourite' => false,
|
|
|
171 |
'progress' => number_format($percentage, 2),
|
|
|
172 |
'shortname' => $course->shortname,
|
|
|
173 |
'showshortname' => false,
|
|
|
174 |
'startdate' => $course->startdate,
|
|
|
175 |
'summary' => $course->summary,
|
|
|
176 |
'summaryformat' => $course->summaryformat,
|
|
|
177 |
'timeaccess' => $lastaccess,
|
|
|
178 |
// 'viewurl' => $CFG->wwwroot . '/course/view.php?id=' . $course->id,
|
|
|
179 |
'viewurl' => $linkurl,
|
|
|
180 |
'visible' => true,
|
|
|
181 |
'grade' => $grd->str_grade,
|
|
|
182 |
'dedication' => $dedication,
|
|
|
183 |
'percentage' => number_format($percentage, 2),
|
|
|
184 |
];
|
|
|
185 |
}
|
|
|
186 |
|
497 |
ariadna |
187 |
$dedication = 0;
|
|
|
188 |
for ($i = 0, $max = count($data['courses']); $i < $max; $i++) {
|
|
|
189 |
$dedication = ($data['courses'][$i]['dedication'] * 100) / $total_dedication;
|
|
|
190 |
|
|
|
191 |
$data['courses'][$i]['dedication'] = $this->format_dedication($data['courses'][$i]['dedication']);
|
1 |
efrain |
192 |
array_push($graph_dedication, number_format($dedication, 2));
|
|
|
193 |
}
|
|
|
194 |
|
497 |
ariadna |
195 |
|
|
|
196 |
|
1 |
efrain |
197 |
$serie_dedication = new core\chart_series('Dedicación', $graph_dedication);
|
|
|
198 |
$serie_percentage = new core\chart_series('Progreso', $graph_percentage);
|
|
|
199 |
|
|
|
200 |
|
497 |
ariadna |
201 |
|
1 |
efrain |
202 |
$chart = new core\chart_bar();
|
|
|
203 |
|
497 |
ariadna |
204 |
|
|
|
205 |
|
1 |
efrain |
206 |
$chart->set_title('Dedicación/Progreso en %');
|
|
|
207 |
$chart->set_horizontal(true); // Calling set_horizontal() passing true as parameter will display horizontal bar charts.
|
497 |
ariadna |
208 |
$chart->add_series($serie_dedication);
|
|
|
209 |
$chart->add_series($serie_percentage);
|
1 |
efrain |
210 |
$chart->set_labels($graph_labels);
|
|
|
211 |
|
|
|
212 |
$data['graph_dedication'] = $OUTPUT->render_chart($chart, true); //true muesta tabla de datos, false no
|
497 |
ariadna |
213 |
|
|
|
214 |
|
1 |
efrain |
215 |
$data['completed'] = $completed;
|
|
|
216 |
$data['inprogress'] = $inprogress;
|
|
|
217 |
$data['total_dedication'] = $this->format_dedication($total_dedication);
|
|
|
218 |
|
|
|
219 |
// Inicio de agregado de cuadro curso
|
497 |
ariadna |
220 |
$records = badges_get_user_badges($USER->id, null, null, null, null, true);
|
1 |
efrain |
221 |
$badges = count($records);
|
497 |
ariadna |
222 |
if (0 != $completed || 0 != $inprogress) {
|
1 |
efrain |
223 |
$points = (int) ($points / ($completed + $inprogress));
|
|
|
224 |
}
|
497 |
ariadna |
225 |
|
1 |
efrain |
226 |
$data['dedication'] = $this->format_dedication($total_dedication);
|
|
|
227 |
$data['grades'] = $badges;
|
|
|
228 |
$data['points'] = $points;
|
497 |
ariadna |
229 |
|
|
|
230 |
$imgUser = new moodle_url('/user/pix.php/' . $USER->id . '/f1.jpg');
|
1 |
efrain |
231 |
$data['user_username'] = $USER->username;
|
|
|
232 |
$data['user_profile_picture'] = $imgUser;
|
497 |
ariadna |
233 |
|
1 |
efrain |
234 |
$div_cuadro_inf = $OUTPUT->render_from_template('block_progreso_sinopsis/full', $data); //true muesta tabla de datos, false no
|
497 |
ariadna |
235 |
|
1 |
efrain |
236 |
$data['div_cuadro_inf'] = $div_cuadro_inf;
|
|
|
237 |
// Fin de agregado de cuadro curso
|
497 |
ariadna |
238 |
|
1 |
efrain |
239 |
$content .= html_writer::start_tag('div', array('class' => 'container')); //'d-flex flex-row bd-highlight mb-3'));
|
497 |
ariadna |
240 |
$content .= $this->render_from_template('block_progreso_detalles/full', $data);
|
|
|
241 |
$content .= html_writer::end_tag('div');
|
1 |
efrain |
242 |
$content = str_replace('<!--USER-IMAGE-->', $data['user_image'], $content);
|
|
|
243 |
$content = str_replace('<!--GRAPH-DEDICATION-->', $data['graph_dedication'], $content);
|
497 |
ariadna |
244 |
|
|
|
245 |
|
1 |
efrain |
246 |
return $content;
|
|
|
247 |
}
|
497 |
ariadna |
248 |
|
|
|
249 |
public static function format_dedication($totalsecs)
|
|
|
250 |
{
|
1 |
efrain |
251 |
$totalsecs = abs($totalsecs);
|
497 |
ariadna |
252 |
|
1 |
efrain |
253 |
$str = new stdClass();
|
|
|
254 |
$str->hour = get_string('hour');
|
|
|
255 |
$str->hours = get_string('hours');
|
|
|
256 |
$str->min = get_string('min');
|
|
|
257 |
$str->mins = get_string('mins');
|
|
|
258 |
$str->sec = get_string('sec');
|
|
|
259 |
$str->secs = get_string('secs');
|
497 |
ariadna |
260 |
|
1 |
efrain |
261 |
$hours = floor($totalsecs / HOURSECS);
|
|
|
262 |
$remainder = $totalsecs - ($hours * HOURSECS);
|
|
|
263 |
$mins = floor($remainder / MINSECS);
|
|
|
264 |
$secs = round($remainder - ($mins * MINSECS), 2);
|
497 |
ariadna |
265 |
|
1 |
efrain |
266 |
$ss = ($secs == 1) ? $str->sec : $str->secs;
|
|
|
267 |
$sm = ($mins == 1) ? $str->min : $str->mins;
|
|
|
268 |
$sh = ($hours == 1) ? $str->hour : $str->hours;
|
497 |
ariadna |
269 |
|
1 |
efrain |
270 |
$ohours = '';
|
|
|
271 |
$omins = '';
|
|
|
272 |
$osecs = '';
|
497 |
ariadna |
273 |
|
1 |
efrain |
274 |
if ($hours) {
|
|
|
275 |
// $ohours = $hours . ' ' . $sh;
|
497 |
ariadna |
276 |
$ohours = $hours . ' ' . 'h';
|
|
|
277 |
}
|
|
|
278 |
if ($mins) {
|
1 |
efrain |
279 |
// $omins = $mins . ' ' . $sm;
|
497 |
ariadna |
280 |
$omins = $mins . ' ' . 'm';
|
|
|
281 |
}
|
|
|
282 |
if ($secs) {
|
1 |
efrain |
283 |
// $osecs = $secs . ' ' . $ss;
|
497 |
ariadna |
284 |
$osecs = $secs . ' ' . 's';
|
|
|
285 |
}
|
|
|
286 |
|
1 |
efrain |
287 |
if ($hours) {
|
|
|
288 |
return trim($ohours . ' ' . $omins);
|
|
|
289 |
}
|
|
|
290 |
if ($mins) {
|
|
|
291 |
return trim($omins . ' ' . $osecs);
|
|
|
292 |
}
|
|
|
293 |
if ($secs) {
|
|
|
294 |
return $osecs;
|
|
|
295 |
}
|
|
|
296 |
return get_string('none');
|
|
|
297 |
}
|
497 |
ariadna |
298 |
|
1 |
efrain |
299 |
public function get_events_select($selectwhere, array $params)
|
|
|
300 |
{
|
|
|
301 |
$logstores = ['logstore_standard', 'logstore_legacy'];
|
|
|
302 |
$return = [];
|
497 |
ariadna |
303 |
|
1 |
efrain |
304 |
static $allreaders = null;
|
497 |
ariadna |
305 |
|
1 |
efrain |
306 |
if (is_null($allreaders)) {
|
|
|
307 |
$allreaders = get_log_manager()->get_readers();
|
|
|
308 |
}
|
497 |
ariadna |
309 |
|
1 |
efrain |
310 |
$processedreaders = 0;
|
497 |
ariadna |
311 |
|
1 |
efrain |
312 |
foreach ($logstores as $name) {
|
|
|
313 |
if (isset($allreaders[$name])) {
|
|
|
314 |
$reader = $allreaders[$name];
|
|
|
315 |
$events = $reader->get_events_select($selectwhere, $params, 'timecreated ASC', 0, 0);
|
|
|
316 |
foreach ($events as $event) {
|
|
|
317 |
// Note: see \core\event\base to view base class of event.
|
|
|
318 |
$obj = new stdClass();
|
|
|
319 |
$obj->time = $event->timecreated;
|
|
|
320 |
$obj->ip = $event->get_logextra()['ip'];
|
|
|
321 |
$return[] = $obj;
|
|
|
322 |
}
|
|
|
323 |
if (!empty($events)) {
|
|
|
324 |
$processedreaders++;
|
|
|
325 |
}
|
|
|
326 |
}
|
|
|
327 |
}
|
497 |
ariadna |
328 |
|
1 |
efrain |
329 |
// Sort mixed array by time ascending again only when more of a reader has added events to return array.
|
|
|
330 |
if ($processedreaders > 1) {
|
497 |
ariadna |
331 |
usort($return, function ($a, $b) {
|
1 |
efrain |
332 |
return $a->time > $b->time;
|
|
|
333 |
});
|
|
|
334 |
}
|
497 |
ariadna |
335 |
|
1 |
efrain |
336 |
return $return;
|
|
|
337 |
}
|
497 |
ariadna |
338 |
|
1 |
efrain |
339 |
public function get_students_dedication($user_id, $course_id, $min_time, $max_time, $limit)
|
|
|
340 |
{
|
497 |
ariadna |
341 |
|
1 |
efrain |
342 |
$where = 'courseid = :courseid AND userid = :userid AND timecreated >= :mintime AND timecreated <= :maxtime';
|
|
|
343 |
$params = array(
|
|
|
344 |
'courseid' => $course_id,
|
|
|
345 |
'userid' => $user_id,
|
|
|
346 |
'mintime' => $min_time,
|
|
|
347 |
'maxtime' => $max_time
|
|
|
348 |
);
|
497 |
ariadna |
349 |
|
|
|
350 |
|
1 |
efrain |
351 |
$logs = $this->get_events_select($where, $params);
|
|
|
352 |
if ($logs) {
|
|
|
353 |
$previouslog = array_shift($logs);
|
|
|
354 |
$previouslogtime = $previouslog->time;
|
|
|
355 |
$sessionstart = $previouslog->time;
|
|
|
356 |
$dedication = 0;
|
497 |
ariadna |
357 |
|
1 |
efrain |
358 |
foreach ($logs as $log) {
|
|
|
359 |
if (($log->time - $previouslogtime) > $limit) {
|
|
|
360 |
$dedication += $previouslogtime - $sessionstart;
|
|
|
361 |
$sessionstart = $log->time;
|
|
|
362 |
}
|
|
|
363 |
$previouslogtime = $log->time;
|
|
|
364 |
}
|
|
|
365 |
$dedication += $previouslogtime - $sessionstart;
|
|
|
366 |
} else {
|
|
|
367 |
$dedication = 0;
|
|
|
368 |
}
|
|
|
369 |
return $dedication;
|
|
|
370 |
}
|
|
|
371 |
}
|