Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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/>.
16
 
17
/**
18
 * The main report page for a questionnaire.
19
 *
20
 * @package mod_questionnaire
21
 * @copyright  2016 Mike Churchward (mike.churchward@poetgroup.org)
22
 * @author     Mike Churchward
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 *
25
 */
26
require_once("../../config.php");
27
require_once($CFG->dirroot.'/mod/questionnaire/questionnaire.class.php');
28
 
29
$instance = optional_param('instance', false, PARAM_INT);   // Questionnaire ID.
30
$action = optional_param('action', 'vall', PARAM_ALPHA);
31
$sid = optional_param('sid', null, PARAM_INT);              // Survey id.
32
$rid = optional_param('rid', false, PARAM_INT);
33
$type = optional_param('type', '', PARAM_ALPHA);
34
$byresponse = optional_param('byresponse', false, PARAM_INT);
35
$individualresponse = optional_param('individualresponse', false, PARAM_INT);
36
$currentgroupid = optional_param('group', 0, PARAM_INT); // Groupid.
37
$user = optional_param('user', '', PARAM_INT);
38
$outputtarget = optional_param('target', 'html', PARAM_ALPHA); // Default 'html'. Could be 'pdf'.
39
 
40
$userid = $USER->id;
41
switch ($action) {
42
    case 'vallasort':
43
        $sort = 'ascending';
44
        break;
45
    case 'vallarsort':
46
        $sort = 'descending';
47
        break;
48
    default:
49
        $sort = 'default';
50
}
51
 
52
if ($instance === false) {
53
    if (!empty($SESSION->instance)) {
54
        $instance = $SESSION->instance;
55
    } else {
56
        throw new \moodle_exception('requiredparameter', 'mod_questionnaire');
57
    }
58
}
59
$SESSION->instance = $instance;
60
$usergraph = get_config('questionnaire', 'usergraph');
61
 
62
if (! $questionnaire = $DB->get_record("questionnaire", array("id" => $instance))) {
63
    throw new \moodle_exception('incorrectquestionnaire', 'mod_questionnaire');
64
}
65
if (! $course = $DB->get_record("course", array("id" => $questionnaire->course))) {
66
    throw new \moodle_exception('coursemisconf', 'mod_questionnaire');
67
}
68
if (! $cm = get_coursemodule_from_instance("questionnaire", $questionnaire->id, $course->id)) {
69
    throw new \moodle_exception('invalidcoursemodule', 'mod_questionnaire');
70
}
71
 
72
require_course_login($course, true, $cm);
73
 
74
$questionnaire = new questionnaire($course, $cm, 0, $questionnaire);
75
 
76
// Add renderer and page objects to the questionnaire object for display use.
77
$questionnaire->add_renderer($PAGE->get_renderer('mod_questionnaire'));
78
if ($outputtarget == 'pdf') {
79
    if ($action == 'vresp') {
80
        $questionnaire->add_page(new \mod_questionnaire\output\responsepagepdf());
81
    } else {
82
        $questionnaire->add_page(new \mod_questionnaire\output\reportpagepdf());
83
    }
84
} else { // Default to HTML.
85
    $questionnaire->add_page(new \mod_questionnaire\output\reportpage());
86
}
87
 
88
// If you can't view the questionnaire, or can't view a specified response, error out.
89
$context = context_module::instance($cm->id);
90
if (!$questionnaire->can_view_all_responses() && !$individualresponse) {
91
    // Should never happen, unless called directly by a snoop...
92
    throw new \moodle_exception('nopermissions', 'mod_questionnaire');
93
}
94
 
95
$questionnaire->canviewallgroups = has_capability('moodle/site:accessallgroups', $context);
96
$sid = $questionnaire->survey->id;
97
 
98
$url = new moodle_url($CFG->wwwroot.'/mod/questionnaire/report.php');
99
if ($instance) {
100
    $url->param('instance', $instance);
101
}
102
 
103
$url->param('action', $action);
104
 
105
if ($type) {
106
    $url->param('type', $type);
107
}
108
if ($byresponse || $individualresponse) {
109
    $url->param('byresponse', 1);
110
}
111
if ($user) {
112
    $url->param('user', $user);
113
}
114
if ($action == 'dresp') {
115
    $url->param('action', 'dresp');
116
    $url->param('byresponse', 1);
117
    $url->param('rid', $rid);
118
    $url->param('individualresponse', 1);
119
}
120
if ($currentgroupid !== null) {
121
    $url->param('group', $currentgroupid);
122
}
123
 
124
$PAGE->set_url($url);
125
$PAGE->set_context($context);
126
if ($outputtarget == 'print') {
127
    $PAGE->set_pagelayout('popup');
128
}
129
 
130
// Tab setup.
131
if (!isset($SESSION->questionnaire)) {
132
    $SESSION->questionnaire = new stdClass();
133
}
134
$SESSION->questionnaire->current_tab = 'allreport';
135
 
136
// Get all responses for further use in viewbyresp and deleteall etc.
137
// All participants.
138
$respsallparticipants = $questionnaire->get_responses();
139
$SESSION->questionnaire->numrespsallparticipants = count ($respsallparticipants);
140
$SESSION->questionnaire->numselectedresps = $SESSION->questionnaire->numrespsallparticipants;
141
 
142
// Available group modes (0 = no groups; 1 = separate groups; 2 = visible groups).
143
$groupmode = groups_get_activity_groupmode($cm, $course);
144
$questionnairegroups = '';
145
$groupscount = 0;
146
$SESSION->questionnaire->respscount = 0;
147
$SESSION->questionnaire_surveyid = $sid;
148
 
149
if ($groupmode > 0) {
150
    if ($groupmode == 1) {
151
        $questionnairegroups = groups_get_all_groups($course->id, $userid);
152
    }
153
    if ($groupmode == 2 || $questionnaire->canviewallgroups) {
154
        $questionnairegroups = groups_get_all_groups($course->id);
155
    }
156
 
157
    if (!empty($questionnairegroups)) {
158
        $groupscount = count($questionnairegroups);
159
        foreach ($questionnairegroups as $key) {
160
            $firstgroupid = $key->id;
161
            break;
162
        }
163
        if ($groupscount === 0 && $groupmode == 1) {
164
            $currentgroupid = 0;
165
        }
166
        if ($groupmode == 1 && !$questionnaire->canviewallgroups && $currentgroupid == 0) {
167
            $currentgroupid = $firstgroupid;
168
        }
169
    } else {
170
        // Groupmode = separate groups but user is not member of any group
171
        // and does not have moodle/site:accessallgroups capability -> refuse view responses.
172
        if (!$questionnaire->canviewallgroups) {
173
            $currentgroupid = 0;
174
        }
175
    }
176
 
177
    if ($currentgroupid > 0) {
178
        $groupname = get_string('group').' <strong>'.groups_get_group_name($currentgroupid).'</strong>';
179
    } else {
180
        $groupname = '<strong>'.get_string('allparticipants').'</strong>';
181
    }
182
}
183
if ($usergraph) {
184
    $charttype = $questionnaire->survey->chart_type;
185
    if ($charttype) {
186
        $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.common.core.js');
187
 
188
        switch ($charttype) {
189
            case 'bipolar':
190
                $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.bipolar.js');
191
                break;
192
            case 'hbar':
193
                $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.hbar.js');
194
                break;
195
            case 'radar':
196
                $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.radar.js');
197
                break;
198
            case 'rose':
199
                $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.rose.js');
200
                break;
201
            case 'vprogress':
202
                $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.vprogress.js');
203
                break;
204
        }
205
    }
206
}
207
 
208
switch ($action) {
209
 
210
    case 'dresp':  // Delete individual response? Ask for confirmation.
211
        require_capability('mod/questionnaire:deleteresponses', $context);
212
 
213
        if (empty($questionnaire->survey)) {
214
            $id = $questionnaire->survey;
215
            notify ("questionnaire->survey = /$id/");
216
            throw new \moodle_exception('surveynotexists', 'mod_questionnaire');
217
        } else if ($questionnaire->survey->courseid != $course->id) {
218
            throw new \moodle_exception('surveyowner', 'mod_questionnaire');
219
        } else if (!$rid || !is_numeric($rid)) {
220
            throw new \moodle_exception('invalidresponse', 'mod_questionnaire');
221
        } else if (!($resp = $DB->get_record('questionnaire_response', array('id' => $rid)))) {
222
            throw new \moodle_exception('invalidresponserecord', 'mod_questionnaire');
223
        }
224
 
225
        $ruser = false;
226
        if (!empty($resp->userid)) {
227
            if ($user = $DB->get_record('user', ['id' => $resp->userid])) {
228
                $ruser = fullname($user);
229
            } else {
230
                $ruser = '- '.get_string('unknown', 'questionnaire').' -';
231
            }
232
        } else {
233
            $ruser = $resp->userid;
234
        }
235
 
236
        // Print the page header.
237
        $PAGE->set_title(get_string('deletingresp', 'questionnaire'));
238
        $PAGE->set_heading(format_string($course->fullname));
239
        echo $questionnaire->renderer->header();
240
 
241
        // Print the tabs.
242
        $SESSION->questionnaire->current_tab = 'deleteresp';
243
        include('tabs.php');
244
 
245
        $timesubmitted = '<br />'.get_string('submitted', 'questionnaire').'&nbsp;'.userdate($resp->submitted);
246
        if ($questionnaire->respondenttype == 'anonymous') {
247
            $ruser = '- '.get_string('anonymous', 'questionnaire').' -';
248
            $timesubmitted = '';
249
        }
250
 
251
        // Print the confirmation.
252
        $msg = '<div class="warning centerpara">';
253
        $msg .= get_string('confirmdelresp', 'questionnaire', $ruser.$timesubmitted);
254
        $msg .= '</div>';
255
        $urlyes = new moodle_url('report.php', array('action' => 'dvresp',
256
            'rid' => $rid, 'individualresponse' => 1, 'instance' => $instance, 'group' => $currentgroupid));
257
        $urlno = new moodle_url('report.php', array('action' => 'vresp', 'instance' => $instance,
258
            'rid' => $rid, 'individualresponse' => 1, 'group' => $currentgroupid));
259
        $buttonyes = new single_button($urlyes, get_string('delete'), 'post');
260
        $buttonno = new single_button($urlno, get_string('cancel'), 'get');
261
        $questionnaire->page->add_to_page('notifications', $questionnaire->renderer->confirm($msg, $buttonyes, $buttonno));
262
        echo $questionnaire->renderer->render($questionnaire->page);
263
        // Finish the page.
264
        echo $questionnaire->renderer->footer($course);
265
        break;
266
 
267
    case 'delallresp': // Delete all responses? Ask for confirmation.
268
        require_capability('mod/questionnaire:deleteresponses', $context);
269
 
270
        if (!empty($respsallparticipants)) {
271
 
272
            // Print the page header.
273
            $PAGE->set_title(get_string('deletingresp', 'questionnaire'));
274
            $PAGE->set_heading(format_string($course->fullname));
275
            echo $questionnaire->renderer->header();
276
 
277
            // Print the tabs.
278
            $SESSION->questionnaire->current_tab = 'deleteall';
279
            include('tabs.php');
280
 
281
            // Print the confirmation.
282
            $msg = '<div class="warning centerpara">';
283
            if ($groupmode == 0) {   // No groups or visible groups.
284
                $msg .= get_string('confirmdelallresp', 'questionnaire');
285
            } else {                 // Separate groups.
286
                $msg .= get_string('confirmdelgroupresp', 'questionnaire', $groupname);
287
            }
288
            $msg .= '</div>';
289
 
290
            $urlyes = new moodle_url('report.php', array('action' => 'dvallresp', 'sid' => $sid,
291
                'instance' => $instance, 'group' => $currentgroupid));
292
            $urlno = new moodle_url('report.php', array('instance' => $instance, 'group' => $currentgroupid));
293
            $buttonyes = new single_button($urlyes, get_string('delete'), 'post');
294
            $buttonno = new single_button($urlno, get_string('cancel'), 'get');
295
 
296
            $questionnaire->page->add_to_page('notifications', $questionnaire->renderer->confirm($msg, $buttonyes, $buttonno));
297
            echo $questionnaire->renderer->render($questionnaire->page);
298
            // Finish the page.
299
            echo $questionnaire->renderer->footer($course);
300
        }
301
        break;
302
 
303
    case 'dvresp': // Delete single response. Do it!
304
        require_capability('mod/questionnaire:deleteresponses', $context);
305
 
306
        if (empty($questionnaire->survey)) {
307
            throw new \moodle_exception('surveynotexists', 'mod_questionnaire');
308
        } else if ($questionnaire->survey->courseid != $course->id) {
309
            throw new \moodle_exception('surveyowner', 'mod_questionnaire');
310
        } else if (!$rid || !is_numeric($rid)) {
311
            throw new \moodle_exception('invalidresponse', 'mod_questionnaire');
312
        } else if (!($response = $DB->get_record('questionnaire_response', array('id' => $rid)))) {
313
            throw new \moodle_exception('invalidresponserecord', 'mod_questionnaire');
314
        }
315
 
316
        if (questionnaire_delete_response($response, $questionnaire)) {
317
            if (!$DB->count_records('questionnaire_response', array('questionnaireid' => $questionnaire->id, 'complete' => 'y'))) {
318
                $redirection = $CFG->wwwroot.'/mod/questionnaire/view.php?id='.$cm->id;
319
            } else {
320
                $redirection = $CFG->wwwroot.'/mod/questionnaire/report.php?action=vresp&amp;instance='.
321
                    $instance.'&amp;byresponse=1';
322
            }
323
 
324
            // Log this questionnaire delete single response action.
325
            $params = array('objectid' => $questionnaire->survey->id,
326
                'context' => $questionnaire->context,
327
                'courseid' => $questionnaire->course->id,
328
                'relateduserid' => $response->userid);
329
            $event = \mod_questionnaire\event\response_deleted::create($params);
330
            $event->trigger();
331
 
332
            redirect($redirection);
333
        } else {
334
            if ($questionnaire->respondenttype == 'anonymous') {
335
                $ruser = '- '.get_string('anonymous', 'questionnaire').' -';
336
            } else if (!empty($response->userid)) {
337
                if ($user = $DB->get_record('user', ['id' => $response->userid])) {
338
                    $ruser = fullname($user);
339
                } else {
340
                    $ruser = '- '.get_string('unknown', 'questionnaire').' -';
341
                }
342
            } else {
343
                $ruser = $response->userid;
344
            }
345
            error (get_string('couldnotdelresp', 'questionnaire').$rid.get_string('by', 'questionnaire').$ruser.'?',
346
                $CFG->wwwroot.'/mod/questionnaire/report.php?action=vresp&amp;sid='.$sid.'&amp;&amp;instance='.
347
                $instance.'byresponse=1');
348
        }
349
        break;
350
 
351
    case 'dvallresp': // Delete all responses in questionnaire (or group). Do it!
352
        require_capability('mod/questionnaire:deleteresponses', $context);
353
 
354
        if (empty($questionnaire->survey)) {
355
            throw new \moodle_exception('surveynotexists', 'mod_questionnaire');
356
        } else if ($questionnaire->survey->courseid != $course->id) {
357
            throw new \moodle_exception('surveyowner', 'mod_questionnaire');
358
        }
359
 
360
        // Available group modes (0 = no groups; 1 = separate groups; 2 = visible groups).
361
        if ($groupmode > 0) {
362
            switch ($currentgroupid) {
363
                case 0:     // All participants.
364
                    $resps = $respsallparticipants;
365
                    break;
366
                default:     // Members of a specific group.
367
                    if (!($resps = $questionnaire->get_responses(false, $currentgroupid))) {
368
                        $resps = [];
369
                    }
370
            }
371
            if (empty($resps)) {
372
                $noresponses = true;
373
            } else {
374
                if ($rid === false) {
375
                    $resp = current($resps);
376
                    $rid = $resp->id;
377
                } else {
378
                    $resp = $DB->get_record('questionnaire_response', array('id' => $rid));
379
                }
380
                if (!empty($resp->userid)) {
381
                    if ($user = $DB->get_record('user', ['id' => $resp->userid])) {
382
                        $ruser = fullname($user);
383
                    } else {
384
                        $ruser = '- '.get_string('unknown', 'questionnaire').' -';
385
                    }
386
                } else {
387
                    $ruser = $resp->userid;
388
                }
389
            }
390
        } else {
391
            $resps = $respsallparticipants;
392
        }
393
 
394
        if (!empty($resps)) {
395
            foreach ($resps as $response) {
396
                questionnaire_delete_response($response, $questionnaire);
397
            }
398
            if (!$questionnaire->count_submissions()) {
399
                $redirection = $CFG->wwwroot.'/mod/questionnaire/view.php?id='.$cm->id;
400
            } else {
401
                $redirection = $CFG->wwwroot.'/mod/questionnaire/report.php?action=vall&amp;sid='.$sid.'&amp;instance='.$instance;
402
            }
403
 
404
            // Log this questionnaire delete all responses action.
405
            $context = context_module::instance($questionnaire->cm->id);
406
            $anonymous = $questionnaire->respondenttype == 'anonymous';
407
 
408
            $event = \mod_questionnaire\event\all_responses_deleted::create(array(
409
                'objectid' => $questionnaire->id,
410
                'anonymous' => $anonymous,
411
                'context' => $context
412
            ));
413
            $event->trigger();
414
 
415
            redirect($redirection);
416
        } else {
417
            error (get_string('couldnotdelresp', 'questionnaire'),
418
                $CFG->wwwroot.'/mod/questionnaire/report.php?action=vall&amp;sid='.$sid.'&amp;instance='.$instance);
419
        }
420
        break;
421
 
422
    case 'dwnpg': // Download page options.
423
        require_capability('mod/questionnaire:downloadresponses', $context);
424
 
425
        $PAGE->set_title(get_string('questionnairereport', 'questionnaire'));
426
        $PAGE->set_heading(format_string($course->fullname));
427
        echo $questionnaire->renderer->header();
428
 
429
        // Print the tabs.
430
        // Tab setup.
431
        if (empty($user)) {
432
            $SESSION->questionnaire->current_tab = 'downloadcsv';
433
        } else {
434
            $SESSION->questionnaire->current_tab = 'mydownloadcsv';
435
        }
436
 
437
        include('tabs.php');
438
 
439
        $groupname = '';
440
        if ($groupmode > 0) {
441
            switch ($currentgroupid) {
442
                case 0:     // All participants.
443
                    $groupname = get_string('allparticipants');
444
                    break;
445
                default:     // Members of a specific group.
446
                    $groupname = get_string('membersofselectedgroup', 'group').' '.get_string('group').' '.
447
                        $questionnairegroups[$currentgroupid]->name;
448
            }
449
        }
450
        $output = '';
451
        $output .= "<br /><br />\n";
452
        $output .= $questionnaire->renderer->help_icon('downloadtextformat', 'questionnaire');
453
        $output .= '&nbsp;' . (get_string('downloadtextformat', 'questionnaire')) . ':&nbsp;' .
454
            get_string('responses', 'questionnaire').'&nbsp;'.$groupname;
455
        $output .= $questionnaire->renderer->heading(get_string('textdownloadoptions', 'questionnaire'));
456
        $output .= $questionnaire->renderer->box_start();
457
        $downloadparams = [
458
            'instance' => $instance,
459
            'user' => $user,
460
            'sid' => $sid,
461
            'action' => 'dfs',
462
            'group' => $currentgroupid
463
        ];
464
        $extrafields = $questionnaire->renderer->render_from_template('mod_questionnaire/extrafields', []);
465
        $output .= $questionnaire->renderer->download_dataformat_selector(get_string('downloadtypes', 'questionnaire'),
466
            'report.php', 'downloadformat', $downloadparams, $extrafields);
467
        $output .= $questionnaire->renderer->box_end();
468
 
469
        $questionnaire->page->add_to_page('respondentinfo', $output);
470
        echo $questionnaire->renderer->render($questionnaire->page);
471
 
472
        echo $questionnaire->renderer->footer('none');
473
 
474
        // Log saved as text action.
475
        $params = array('objectid' => $questionnaire->id,
476
            'context' => $questionnaire->context,
477
            'courseid' => $course->id,
478
            'other' => array('action' => $action, 'instance' => $instance, 'currentgroupid' => $currentgroupid)
479
        );
480
        $event = \mod_questionnaire\event\all_responses_saved_as_text::create($params);
481
        $event->trigger();
482
 
483
        exit();
484
        break;
485
 
486
    case 'dfs':
487
        require_capability('mod/questionnaire:downloadresponses', $context);
488
        require_once($CFG->dirroot . '/lib/dataformatlib.php');
489
        // Use the questionnaire name as the file name. Clean it and change any non-filename characters to '_'.
490
        $name = clean_param($questionnaire->name, PARAM_FILE);
491
        $name = preg_replace("/[^A-Z0-9]+/i", "_", trim($name));
492
 
493
        $choicecodes = optional_param('choicecodes', '0', PARAM_INT);
494
        $choicetext = optional_param('choicetext', '0', PARAM_INT);
495
        $showincompletes = optional_param('complete', '0', PARAM_INT);
496
        $rankaverages = optional_param('rankaverages', '0', PARAM_INT);
497
        $dataformat = optional_param('downloadformat', '', PARAM_ALPHA);
498
        $emailroles = optional_param('emailroles', 0, PARAM_INT);
499
        $emailextra = optional_param('emailextra', '', PARAM_RAW);
500
 
501
        $output = $questionnaire->generate_csv($currentgroupid, '', $user, $choicecodes, $choicetext, $showincompletes,
502
            $rankaverages);
503
 
504
        $columns = $output[0];
505
        unset($output[0]);
506
 
507
        // Check if email report was selected.
508
        $emailreport = optional_param('emailreport', '', PARAM_ALPHA);
509
        if (empty($emailreport)) {
510
            // In 3.9 forward, download_as_dataformat is replaced by \core\dataformat::download_data.
511
            if (method_exists('\\core\\dataformat', 'download_data')) {
512
                \core\dataformat::download_data($name, $dataformat, $columns, $output);
513
            } else {
514
                download_as_dataformat($name, $dataformat, $columns, $output);
515
            }
516
        } else {
517
            // Emailreport button selected.
518
            if (get_config('questionnaire', 'allowemailreporting') && (!empty($emailroles) || !empty($emailextra))) {
519
                require_once('savefileformat.php');
520
                $users = !empty($emailroles) ? $questionnaire->get_notifiable_users($USER->id) : [];
521
                $otheremails = explode(',', $emailextra);
522
                if (!empty($users) || !empty($otheremails)) {
523
                    $thisurl = new moodle_url('report.php',
524
                        ['instance' => $instance, 'action' => 'dwnpg', 'group' => $currentgroupid]);
525
                    save_as_dataformat($name, $dataformat, $columns, $output, $users, $otheremails, $thisurl);
526
                }
527
            } else {
528
                redirect(new moodle_url('report.php', ['instance' => $instance, 'action' => 'dwnpg', 'group' => $currentgroupid]),
529
                    get_string('emailsnotspecified', 'questionnaire'));
530
            }
531
        }
532
        exit();
533
        break;
534
 
535
    case 'vall':         // View all responses.
536
    case 'vallasort':    // View all responses sorted in ascending order.
537
    case 'vallarsort':   // View all responses sorted in descending order.
538
        $PAGE->set_title(get_string('questionnairereport', 'questionnaire'));
539
        $PAGE->set_heading(format_string($course->fullname));
540
        if (!$questionnaire->capabilities->readallresponses && !$questionnaire->capabilities->readallresponseanytime) {
541
            echo $questionnaire->renderer->header();
542
            // Should never happen, unless called directly by a snoop.
543
            throw new \moodle_exception('nopermissions', 'mod_questionnaire');
544
            // Finish the page.
545
            echo $questionnaire->renderer->footer($course);
546
            break;
547
        }
548
 
549
        // Print the tabs.
550
        switch ($action) {
551
            case 'vallasort':
552
                $SESSION->questionnaire->current_tab = 'vallasort';
553
                break;
554
            case 'vallarsort':
555
                $SESSION->questionnaire->current_tab = 'vallarsort';
556
                break;
557
            default:
558
                $SESSION->questionnaire->current_tab = 'valldefault';
559
        }
560
        if ($outputtarget != 'print') {
561
            include('tabs.php');
562
        }
563
 
564
        $respinfo = '';
565
        $resps = array();
566
        // Enable choose_group if there are questionnaire groups and groupmode is not set to "no groups"
567
        // and if there are more goups than 1 (or if user can view all groups).
568
        if (is_array($questionnairegroups) && $groupmode > 0) {
569
            $groupselect = groups_print_activity_menu($cm, $url->out(), true);
570
            // Count number of responses in each group.
571
            foreach ($questionnairegroups as $group) {
572
                $respscount = $questionnaire->count_submissions(false, $group->id);
573
                $thisgroupname = groups_get_group_name($group->id);
574
                $escapedgroupname = preg_quote($thisgroupname, '/');
575
                if (!empty ($respscount)) {
576
                    // Add number of responses to name of group in the groups select list.
577
                    $groupselect = preg_replace('/\<option value="'.$group->id.'">'.$escapedgroupname.'<\/option>/',
578
                        '<option value="'.$group->id.'">'.$thisgroupname.' ('.$respscount.')</option>', $groupselect);
579
                } else {
580
                    // Remove groups with no responses from the groups select list.
581
                    $groupselect = preg_replace('/\<option value="'.$group->id.'">'.$escapedgroupname.
582
                        '<\/option>/', '', $groupselect);
583
                }
584
            }
585
            $respinfo .= isset($groupselect) ? ($groupselect . ' ') : '';
586
            $currentgroupid = groups_get_activity_group($cm);
587
        }
588
        if ($currentgroupid > 0) {
589
            $groupname = get_string('group').': <strong>'.groups_get_group_name($currentgroupid).'</strong>';
590
        } else {
591
            $groupname = '<strong>'.get_string('allparticipants').'</strong>';
592
        }
593
 
594
        // Available group modes (0 = no groups; 1 = separate groups; 2 = visible groups).
595
        if ($groupmode > 0) {
596
            switch ($currentgroupid) {
597
                case 0:     // All participants.
598
                    $resps = $respsallparticipants;
599
                    break;
600
                default:     // Members of a specific group.
601
                    if (!($resps = $questionnaire->get_responses(false, $currentgroupid))) {
602
                        $resps = '';
603
                    }
604
            }
605
            if (empty($resps)) {
606
                $noresponses = true;
607
            }
608
        } else {
609
            $resps = $respsallparticipants;
610
        }
611
        if (!empty($resps)) {
612
            // NOTE: response_analysis uses $resps to get the id's of the responses only.
613
            // Need to figure out what this function does.
614
            $feedbackmessages = $questionnaire->response_analysis(0, $resps, false, false, true, $currentgroupid);
615
 
616
            if ($feedbackmessages) {
617
                $msgout = '';
618
                foreach ($feedbackmessages as $msg) {
619
                    $msgout .= $msg;
620
                }
621
                $questionnaire->page->add_to_page('feedbackmessages', $msgout);
622
            }
623
        }
624
 
625
        $params = array('objectid' => $questionnaire->id,
626
            'context' => $context,
627
            'courseid' => $course->id,
628
            'other' => array('action' => $action, 'instance' => $instance, 'groupid' => $currentgroupid)
629
        );
630
 
631
        if ($outputtarget == 'pdf') {
632
            $pdf = questionnaire_report_start_pdf();
633
            if ($currentgroupid > 0) {
634
                $groupname = get_string('group') . ': <strong>' . groups_get_group_name($currentgroupid) . '</strong>';
635
            } else {
636
                $groupname = '<strong>' . get_string('allparticipants') . '</strong>';
637
            }
638
            $respinfo = get_string('viewallresponses', 'questionnaire') . '. ' . $groupname . '. ';
639
            $strsort = get_string('order_' . $sort, 'questionnaire');
640
            $respinfo .= $strsort;
641
            $questionnaire->page->add_to_page('respondentinfo', $respinfo);
642
            $questionnaire->survey_results('', false, true, $currentgroupid, $sort);
643
            $html = $questionnaire->renderer->render($questionnaire->page);
644
 
645
            // Supress any warnings. There is at least one error in the TCPF library at line 16749 where 'text-align' is
646
            // not an array.
647
            $errorreporting = error_reporting(0);
648
            $pdf->writeHTML($html);
649
            @$pdf->Output(clean_param($questionnaire->name, PARAM_FILE), 'D');
650
            error_reporting($errorreporting);
651
 
652
        } else { // Default to HTML.
653
            $event = \mod_questionnaire\event\all_responses_viewed::create($params);
654
            $event->trigger();
655
 
656
            if ($outputtarget != 'print') {
657
                $linkname = get_string('downloadpdf', 'mod_questionnaire');
658
                $link = new moodle_url('/mod/questionnaire/report.php',
659
                    ['action' => 'vall', 'instance' => $instance, 'group' => $currentgroupid, 'target' => 'pdf']);
660
                $downpdficon = new pix_icon('f/pdf', $linkname);
661
                $respinfo .= $questionnaire->renderer->action_link($link, null, null, null, $downpdficon);
662
 
663
                $linkname = get_string('print', 'mod_questionnaire');
664
                $link = new \moodle_url('/mod/questionnaire/report.php',
665
                    ['action' => 'vall', 'instance' => $instance, 'group' => $currentgroupid, 'target' => 'print']);
666
                $htmlicon = new pix_icon('t/print', $linkname);
667
                $options = ['menubar' => true, 'location' => false, 'scrollbars' => true, 'resizable' => true,
668
                    'height' => 600, 'width' => 800, 'title' => $linkname];
669
                $name = 'popup';
670
                $action = new popup_action('click', $link, $name, $options);
671
                $class = '';
672
                $respinfo .= $questionnaire->renderer->action_link($link, null, $action,
673
                        ['class' => $class, 'title' => $linkname], $htmlicon) . '&nbsp;';
674
 
675
                $respinfo .= get_string('viewallresponses', 'questionnaire') . '. ' . $groupname . '. ';
676
                $strsort = get_string('order_' . $sort, 'questionnaire');
677
                $respinfo .= $strsort;
678
                $respinfo .= $questionnaire->renderer->help_icon('orderresponses', 'questionnaire');
679
                $questionnaire->page->add_to_page('respondentinfo', $respinfo);
680
            }
681
 
682
            $ret = $questionnaire->survey_results('', false, false, $currentgroupid, $sort);
683
 
684
            echo $questionnaire->renderer->header();
685
            echo $questionnaire->renderer->render($questionnaire->page);
686
            echo $questionnaire->renderer->footer($course);
687
        }
688
        break;
689
 
690
    case 'vresp': // View by response.
691
    default:
692
        if (empty($questionnaire->survey)) {
693
            throw new \moodle_exception('surveynotexists', 'mod_questionnaire');
694
        } else if ($questionnaire->survey->courseid != $course->id) {
695
            throw new \moodle_exception('surveyowner', 'mod_questionnaire');
696
        }
697
        $ruser = false;
698
        $noresponses = false;
699
        if ($usergraph) {
700
            $charttype = $questionnaire->survey->chart_type;
701
            if ($charttype) {
702
                $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.common.core.js');
703
 
704
                switch ($charttype) {
705
                    case 'bipolar':
706
                        $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.bipolar.js');
707
                        break;
708
                    case 'hbar':
709
                        $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.hbar.js');
710
                        break;
711
                    case 'radar':
712
                        $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.radar.js');
713
                        break;
714
                    case 'rose':
715
                        $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.rose.js');
716
                        break;
717
                    case 'vprogress':
718
                        $PAGE->requires->js('/mod/questionnaire/javascript/RGraph/RGraph.vprogress.js');
719
                        break;
720
                }
721
            }
722
        }
723
 
724
        if ($byresponse || $rid) {
725
            // Available group modes (0 = no groups; 1 = separate groups; 2 = visible groups).
726
            if ($groupmode > 0) {
727
                switch ($currentgroupid) {
728
                    case 0:     // All participants.
729
                        $resps = $respsallparticipants;
730
                        break;
731
                    default:     // Members of a specific group.
732
                        $resps = $questionnaire->get_responses(false, $currentgroupid);
733
                }
734
                if (empty($resps)) {
735
                    $noresponses = true;
736
                } else {
737
                    if ($rid === false) {
738
                        $resp = current($resps);
739
                        $rid = $resp->id;
740
                    } else {
741
                        $resp = $DB->get_record('questionnaire_response', ['id' => $rid]);
742
                    }
743
                    if (!empty($resp->userid)) {
744
                        if ($user = $DB->get_record('user', ['id' => $resp->userid])) {
745
                            $ruser = fullname($user);
746
                        } else {
747
                            $ruser = '- '.get_string('unknown', 'questionnaire').' -';
748
                        }
749
                    } else {
750
                        $ruser = $resp->userid;
751
                    }
752
                }
753
            } else {
754
                $resps = $respsallparticipants;
755
            }
756
        }
757
        $rids = array_keys($resps);
758
        if (!$rid && !$noresponses) {
759
            $rid = $rids[0];
760
        }
761
 
762
        if ($noresponses) {
763
            $questionnaire->page->add_to_page('respondentinfo',
764
                get_string('group') . ' <strong>' . groups_get_group_name($currentgroupid) . '</strong>: ' .
765
                get_string('noresponses', 'questionnaire'));
766
 
767
        } else if ($outputtarget == 'pdf') {
768
            $pdf = questionnaire_report_start_pdf();
769
            if ($currentgroupid > 0) {
770
                $groupname = get_string('group') . ': <strong>' . groups_get_group_name($currentgroupid) . '</strong>';
771
            } else {
772
                $groupname = '<strong>' . get_string('allparticipants') . '</strong>';
773
            }
774
            if (!$byresponse) { // Show respondents individual responses.
775
                $questionnaire->view_response($rid, '', $resps, true, true, false, $currentgroupid, $outputtarget);
776
            }
777
            $html = $questionnaire->renderer->render($questionnaire->page);
778
            // Supress any warnings. There is at least one error in the TCPF library at line 16749 where 'text-align' is
779
            // not an array.
780
            $errorreporting = error_reporting(0);
781
            $pdf->writeHTML($html);
782
            @$pdf->Output(clean_param($questionnaire->name, PARAM_FILE), 'D');
783
            error_reporting($errorreporting);
784
 
785
        } else { // Default to HTML.
786
            // Print the page header.
787
            $PAGE->set_title(get_string('questionnairereport', 'questionnaire'));
788
            $PAGE->set_heading(format_string($course->fullname));
789
 
790
            // Print the tabs.
791
            if ($byresponse) {
792
                $SESSION->questionnaire->current_tab = 'vrespsummary';
793
            }
794
            if ($individualresponse) {
795
                $SESSION->questionnaire->current_tab = 'individualresp';
796
            }
797
            if ($outputtarget == 'html') {
798
                include('tabs.php');
799
            }
800
 
801
            // Print the main part of the page.
802
            // TODO provide option to select how many columns and/or responses per page.
803
 
804
            $groupname = get_string('group').': <strong>'.groups_get_group_name($currentgroupid).'</strong>';
805
            if ($currentgroupid == 0 ) {
806
                $groupname = get_string('allparticipants');
807
            }
808
            if ($byresponse) {
809
                $respinfo = '';
810
                $respinfo .= $questionnaire->renderer->box_start();
811
                $respinfo .= $questionnaire->renderer->help_icon('viewindividualresponse', 'questionnaire').'&nbsp;';
812
                $respinfo .= get_string('viewindividualresponse', 'questionnaire').' <strong> : '.$groupname.'</strong>';
813
                $respinfo .= $questionnaire->renderer->box_end();
814
                $questionnaire->page->add_to_page('respondentinfo', $respinfo);
815
            }
816
            if ($outputtarget == 'html') {
817
                $questionnaire->survey_results_navbar_alpha($rid, $currentgroupid, $cm, $byresponse);
818
            }
819
            if (!$byresponse) { // Show respondents individual responses.
820
                $questionnaire->view_response($rid, '', $resps, true, true, false, $currentgroupid, $outputtarget);
821
            }
822
            echo $questionnaire->renderer->header();
823
            echo $questionnaire->renderer->render($questionnaire->page);
824
            echo $questionnaire->renderer->footer($course);
825
        }
826
        break;
827
}
828
 
829
/**
830
 * Return a pdf object.
831
 * @return pdf
832
 */
833
function questionnaire_report_start_pdf() {
834
    global $CFG;
835
 
836
    require_once($CFG->libdir . '/pdflib.php');
837
    $pdf = new pdf();
838
    $pdf->SetCreator(PDF_CREATOR);
839
    $pdf->SetAuthor('Moodle Questionnaire');
840
    $pdf->SetTitle('All responses');
841
    $pdf->setPrintHeader(false);
842
    // Set default monospaced font.
843
    $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
844
 
845
    // Set margins.
846
    $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
847
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
848
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
849
 
850
    // Set auto page breaks.
851
    $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
852
 
853
    // Set image scale factor.
854
    $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
855
    // Set background color for headings.
856
    $pdf->SetFillColor(238, 238, 238);
857
    $pdf->AddPage('L');
858
    return $pdf;
859
}