Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
// This file is part of Moodle - http://moodle.org/
4
//
5
// Moodle is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// Moodle is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
/**
19
 * Displays the lesson statistics.
20
 *
21
 * @package mod_lesson
22
 * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
24
 **/
25
 
26
require_once('../../config.php');
27
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
28
 
29
$id     = required_param('id', PARAM_INT);    // Course Module ID
30
$pageid = optional_param('pageid', null, PARAM_INT);    // Lesson Page ID
31
$action = optional_param('action', 'reportoverview', PARAM_ALPHA);  // action to take
32
$nothingtodisplay = false;
33
 
34
$cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);
35
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
36
$lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
37
 
38
require_login($course, false, $cm);
39
 
40
$currentgroup = groups_get_activity_group($cm, true);
41
 
42
$context = context_module::instance($cm->id);
43
require_capability('mod/lesson:viewreports', $context);
44
 
45
$url = new moodle_url('/mod/lesson/report.php', array('id'=>$id));
46
$url->param('action', $action);
47
if ($pageid !== null) {
48
    $url->param('pageid', $pageid);
49
}
50
$PAGE->set_url($url);
51
if ($action == 'reportdetail') {
52
    $PAGE->navbar->add(get_string('report', 'lesson'), $url);
53
}
54
 
55
$lessonoutput = $PAGE->get_renderer('mod_lesson');
56
$PAGE->activityheader->set_description('');
57
$reportactionmenu = new \mod_lesson\output\report_action_menu($id, $url);
58
$reportactionarea = $lessonoutput->render($reportactionmenu);
59
 
60
if ($action === 'delete') {
61
    /// Process any form data before fetching attempts, grades and times
62
    if (has_capability('mod/lesson:edit', $context) and $form = data_submitted() and confirm_sesskey()) {
63
    /// Cycle through array of userids with nested arrays of tries
64
        if (!empty($form->attempts)) {
65
            foreach ($form->attempts as $userid => $tries) {
66
                // Modifier IS VERY IMPORTANT!  What does it do?
67
                //      Well, it is for when you delete multiple attempts for the same user.
68
                //      If you delete try 1 and 3 for a user, then after deleting try 1, try 3 then
69
                //      becomes try 2 (because try 1 is gone and all tries after try 1 get decremented).
70
                //      So, the modifier makes sure that the submitted try refers to the current try in the
71
                //      database - hope this all makes sense :)
72
                $modifier = 0;
73
 
74
                foreach ($tries as $try => $junk) {
75
                    $try -= $modifier;
76
 
77
                /// Clean up the timer table by removing using the order - this is silly, it should be linked to specific attempt (skodak)
78
                    $timers = $lesson->get_user_timers($userid, 'starttime', 'id', $try, 1);
79
                    if ($timers) {
80
                        $timer = reset($timers);
81
                        $DB->delete_records('lesson_timer', array('id' => $timer->id));
82
                    }
83
 
84
                    $params = array ("userid" => $userid, "lessonid" => $lesson->id);
85
                    // Remove the grade from the grades tables - this is silly, it should be linked to specific attempt (skodak).
86
                    $grades = $DB->get_records_sql("SELECT id FROM {lesson_grades}
87
                                                     WHERE userid = :userid AND lessonid = :lessonid
88
                                                  ORDER BY completed", $params, $try, 1);
89
 
90
                    if ($grades) {
91
                        $grade = reset($grades);
92
                        $DB->delete_records('lesson_grades', array('id' => $grade->id));
93
                    }
94
 
95
                /// Remove attempts and update the retry number
96
                    $DB->delete_records('lesson_attempts', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try));
97
                    $DB->execute("UPDATE {lesson_attempts} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try));
98
 
99
                /// Remove seen branches and update the retry number
100
                    $DB->delete_records('lesson_branch', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try));
101
                    $DB->execute("UPDATE {lesson_branch} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try));
102
 
103
                /// update central gradebook
104
                    lesson_update_grades($lesson, $userid);
105
 
106
                    $modifier++;
107
                }
108
            }
109
        }
110
    }
111
    redirect(new moodle_url($PAGE->url, array('action'=>'reportoverview')));
112
 
113
} else if ($action === 'reportoverview') {
114
    /**************************************************************************
115
    this action is for default view and overview view
116
    **************************************************************************/
117
 
118
    // Get the table and data for build statistics.
119
    list($table, $data) = lesson_get_overview_report_table_and_data($lesson, $currentgroup);
120
 
121
    if ($table === false) {
122
        echo $lessonoutput->header($lesson, $cm, $action, false, null, get_string('nolessonattempts', 'lesson'));
123
        echo $reportactionarea;
124
 
125
        if (!empty($currentgroup)) {
126
            $groupname = groups_get_group_name($currentgroup);
127
            echo $OUTPUT->notification(get_string('nolessonattemptsgroup', 'lesson', $groupname));
128
        } else {
129
            echo $OUTPUT->notification(get_string('nolessonattempts', 'lesson'));
130
        }
131
        groups_print_activity_menu($cm, $url);
132
        echo $OUTPUT->footer();
133
        exit();
134
    }
135
 
136
    echo $lessonoutput->header($lesson, $cm, $action, false, null, get_string('overview', 'lesson'));
137
    echo $reportactionarea;
138
 
139
    groups_print_activity_menu($cm, $url);
140
 
141
    $course_context = context_course::instance($course->id);
142
    if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
143
        $seeallgradeslink = new moodle_url('/grade/report/grader/index.php', array('id'=>$course->id));
144
        $seeallgradeslink = html_writer::link($seeallgradeslink, get_string('seeallcoursegrades', 'grades'));
145
        echo $OUTPUT->box($seeallgradeslink, 'allcoursegrades');
146
    }
147
 
148
    // The attempts table.
149
    $attemptstable = html_writer::table($table);
150
 
151
    // The HTML that we will be displaying which includes the attempts table and bulk actions menu, if necessary.
152
    $attemptshtml = $attemptstable;
153
 
154
    // Show bulk actions when user has capability to edit the lesson.
155
    if (has_capability('mod/lesson:edit', $context)) {
156
        $reporturl = new moodle_url('/mod/lesson/report.php');
157
        $formid  = 'mod-lesson-report-form';
158
 
159
        // Sesskey hidden input.
160
        $formcontents = html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()]);
161
 
162
        // CMID hidden input.
163
        $formcontents .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'id', 'value' => $cm->id]);
164
 
165
        // Attempts table.
166
        $formcontents .= $attemptstable;
167
 
168
        // Bulk actions menu.
169
        $attemptsactions = [
170
            'delete' => get_string('deleteselected')
171
        ];
172
        $bulkactions = new single_select($reporturl, 'action', $attemptsactions, '', ['' => 'choosedots'], $formid);
173
        $bulkactions->set_label(get_string('withselectedattempts', 'lesson'));
174
        $bulkactions->disabled = true;
175
        $bulkactions->attributes = [
176
            'data-action' => 'toggle',
177
            'data-togglegroup' => 'lesson-attempts',
178
            'data-toggle' => 'action',
179
        ];
180
        $bulkactionshtml = $OUTPUT->render($bulkactions);
181
        $formcontents .= $OUTPUT->box($bulkactionshtml, 'center');
182
 
183
        // Build the attempts form.
184
        $formattributes = [
185
            'id' => $formid,
186
            'method' => 'post',
187
        ];
188
        $attemptshtml = html_writer::tag('form', $formcontents, $formattributes);
189
    }
190
 
191
    // Show the attempts HTML.
192
    echo $attemptshtml;
193
 
194
    // Calculate the Statistics.
195
    if ($data->avetime == null) {
196
        $data->avetime = get_string("notcompleted", "lesson");
197
    } else {
198
        $data->avetime = format_float($data->avetime / $data->numofattempts, 0);
199
        $data->avetime = format_time($data->avetime);
200
    }
201
    if ($data->hightime == null) {
202
        $data->hightime = get_string("notcompleted", "lesson");
203
    } else {
204
        $data->hightime = format_time($data->hightime);
205
    }
206
    if ($data->lowtime == null) {
207
        $data->lowtime = get_string("notcompleted", "lesson");
208
    } else {
209
        $data->lowtime = format_time($data->lowtime);
210
    }
211
 
212
    if ($data->lessonscored) {
213
        if ($data->numofattempts == 0) {
214
            $data->avescore = get_string("notcompleted", "lesson");
215
        } else {
216
            $data->avescore = format_float($data->avescore, 2) . '%';
217
        }
218
        if ($data->highscore === null) {
219
            $data->highscore = get_string("notcompleted", "lesson");
220
        } else {
221
            $data->highscore .= '%';
222
        }
223
        if ($data->lowscore === null) {
224
            $data->lowscore = get_string("notcompleted", "lesson");
225
        } else {
226
            $data->lowscore .= '%';
227
        }
228
 
229
        // Display the full stats for the lesson.
230
        echo $OUTPUT->heading(get_string('lessonstats', 'lesson'), 3);
231
        $stattable = new html_table();
232
        $stattable->head = array(get_string('averagescore', 'lesson'), get_string('averagetime', 'lesson'),
233
                                get_string('highscore', 'lesson'), get_string('lowscore', 'lesson'),
234
                                get_string('hightime', 'lesson'), get_string('lowtime', 'lesson'));
235
        $stattable->align = array('center', 'center', 'center', 'center', 'center', 'center');
236
        $stattable->attributes['class'] = 'standardtable generaltable';
237
        $stattable->data[] = array($data->avescore, $data->avetime, $data->highscore, $data->lowscore, $data->hightime, $data->lowtime);
238
 
239
    } else {
240
        // Display simple stats for the lesson.
241
        echo $OUTPUT->heading(get_string('lessonstats', 'lesson'), 3);
242
        $stattable = new html_table();
243
        $stattable->head = array(get_string('averagetime', 'lesson'), get_string('hightime', 'lesson'),
244
                                get_string('lowtime', 'lesson'));
245
        $stattable->align = array('center', 'center', 'center');
246
        $stattable->attributes['class'] = 'standardtable generaltable';
247
        $stattable->data[] = array($data->avetime, $data->hightime, $data->lowtime);
248
    }
249
 
250
    echo html_writer::table($stattable);
251
} else if ($action === 'reportdetail') {
252
    /**************************************************************************
253
    this action is for a student detailed view and for the general detailed view
254
 
255
    General flow of this section of the code
256
    1.  Generate a object which holds values for the statistics for each question/answer
257
    2.  Cycle through all the pages to create a object.  Foreach page, see if the student actually answered
258
        the page.  Then process the page appropriatly.  Display all info about the question,
259
        Highlight correct answers, show how the user answered the question, and display statistics
260
        about each page
261
    3.  Print out info about the try (if needed)
262
    4.  Print out the object which contains all the try info
263
 
264
**************************************************************************/
265
    echo $lessonoutput->header($lesson, $cm, $action, false, null, get_string('detailedstats', 'lesson'));
266
    echo $reportactionarea;
267
 
268
    groups_print_activity_menu($cm, $url);
269
 
270
    $course_context = context_course::instance($course->id);
271
    if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
272
        $seeallgradeslink = new moodle_url('/grade/report/grader/index.php', array('id'=>$course->id));
273
        $seeallgradeslink = html_writer::link($seeallgradeslink, get_string('seeallcoursegrades', 'grades'));
274
        echo $OUTPUT->box($seeallgradeslink, 'allcoursegrades');
275
    }
276
 
277
    $formattextdefoptions = new stdClass;
278
    $formattextdefoptions->para = false;  //I'll use it widely in this page
279
    $formattextdefoptions->overflowdiv = true;
280
 
281
    $userid = optional_param('userid', null, PARAM_INT); // if empty, then will display the general detailed view
282
    $try    = optional_param('try', null, PARAM_INT);
283
 
284
    list($answerpages, $userstats) = lesson_get_user_detailed_report_data($lesson, $userid, $try);
285
 
286
    /// actually start printing something
287
    $table = new html_table();
288
    $table->wrap = array();
289
    $table->width = "60%";
290
    if (!empty($userid)) {
291
        // if looking at a students try, print out some basic stats at the top
292
 
293
            // print out users name
294
            //$headingobject->lastname = $students[$userid]->lastname;
295
            //$headingobject->firstname = $students[$userid]->firstname;
296
            //$headingobject->attempt = $try + 1;
297
            //print_heading(get_string("studentattemptlesson", "lesson", $headingobject));
298
        echo $OUTPUT->heading(get_string('attempt', 'lesson', $try+1), 3);
299
 
300
        $table->head = array();
301
        $table->align = array('right', 'left');
302
        $table->attributes['class'] = 'table table-striped';
303
 
304
        if (empty($userstats->gradeinfo)) {
305
            $table->align = array("center");
306
 
307
            $table->data[] = array(get_string("notcompleted", "lesson"));
308
        } else {
309
            $user = $DB->get_record('user', array('id' => $userid));
310
 
311
            $gradeinfo = lesson_grade($lesson, $try, $user->id);
312
 
313
            $table->data[] = array(get_string('name').':', $OUTPUT->user_picture($user, array('courseid'=>$course->id)).fullname($user, true));
314
            $table->data[] = array(get_string("timetaken", "lesson").":", format_time($userstats->timetotake));
315
            $table->data[] = array(get_string("completed", "lesson").":", userdate($userstats->completed));
316
            $table->data[] = array(get_string('rawgrade', 'lesson').':', $userstats->gradeinfo->earned.'/'.$userstats->gradeinfo->total);
317
            $table->data[] = array(get_string("gradenoun").":", $userstats->grade."%");
318
        }
319
        echo html_writer::table($table);
320
 
321
        // Don't want this class for later tables
322
        $table->attributes['class'] = '';
323
    }
324
 
325
    foreach ($answerpages as $page) {
326
        $table->align = array('left', 'left');
327
        $table->size = array('70%', null);
328
        $table->attributes['class'] = 'table table-striped';
329
        unset($table->data);
330
        if ($page->grayout) { // set the color of text
331
            $fontstart = html_writer::start_tag('span', array('class' => 'dimmed_text'));
332
            $fontend = html_writer::end_tag('span');
333
            $fontstart2 = $fontstart;
334
            $fontend2 = $fontend;
335
        } else {
336
            $fontstart = '';
337
            $fontend = '';
338
            $fontstart2 = '';
339
            $fontend2 = '';
340
        }
341
 
342
        $table->head = array($fontstart2.$page->qtype.": ".format_string($page->title).$fontend2, $fontstart2.get_string("classstats", "lesson").$fontend2);
343
        $table->data[] = array($fontstart.get_string("question", "lesson").": <br />".$fontend.$fontstart2.$page->contents.$fontend2, " ");
344
        $table->data[] = array($fontstart.get_string("answer", "lesson").":".$fontend, ' ');
345
        // apply the font to each answer
346
        if (!empty($page->answerdata) && !empty($page->answerdata->answers)) {
347
            foreach ($page->answerdata->answers as $answer){
348
                $modified = array();
349
                foreach ($answer as $single) {
350
                    // need to apply a font to each one
351
                    $modified[] = $fontstart2.$single.$fontend2;
352
                }
353
                $table->data[] = $modified;
354
            }
355
            if (isset($page->answerdata->response)) {
356
                $table->data[] = array($fontstart.get_string("response", "lesson").": <br />".$fontend
357
                        .$fontstart2.$page->answerdata->response.$fontend2, " ");
358
            }
359
            $table->data[] = array($page->answerdata->score, " ");
360
        } else {
361
            $table->data[] = array(get_string('didnotanswerquestion', 'lesson'), " ");
362
        }
363
        echo html_writer::table($table);
364
    }
365
} else {
366
    throw new \moodle_exception('unknowaction');
367
}
368
 
369
/// Finish the page
370
echo $OUTPUT->footer();