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
namespace mod_questionnaire\output;
18
 
19
use mod_questionnaire\question\question;
20
 
21
/**
22
 * Contains class mod_questionnaire\output\renderer
23
 *
24
 * @package    mod_questionnaire
25
 * @copyright  2016 Mike Churchward (mike.churchward@poetgroup.org)
26
 * @author     Mike Churchward
27
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28
 */
29
class renderer extends \plugin_renderer_base {
30
    /**
31
     * Main view page.
32
     * @param \templateable $page
33
     * @return string | boolean
34
     */
35
    public function render_viewpage($page) {
36
        $data = $page->export_for_template($this);
37
        return $this->render_from_template('mod_questionnaire/viewpage', $data);
38
    }
39
 
40
    /**
41
     * Fill out the questionnaire (complete) page.
42
     * @param \templateable $page
43
     * @return string | boolean
44
     */
45
    public function render_completepage($page) {
46
        $data = $page->export_for_template($this);
47
        return $this->render_from_template('mod_questionnaire/completepage', $data);
48
    }
49
 
50
    /**
51
     * Fill out the report page.
52
     * @param \templateable $page
53
     * @return string | boolean
54
     */
55
    public function render_reportpage($page) {
56
        $data = $page->export_for_template($this);
57
        return $this->render_from_template('mod_questionnaire/reportpage', $data);
58
    }
59
 
60
    /**
61
     * Fill out the PDF report page.
62
     * @param \templateable $page
63
     * @return string | boolean
64
     */
65
    public function render_reportpagepdf($page) {
66
        $data = $page->export_for_template($this);
67
        return $this->render_from_template('mod_questionnaire/reportpagepdf', $data);
68
    }
69
 
70
    /**
71
     * Fill out the qsettings page.
72
     * @param \templateable $page
73
     * @return string | boolean
74
     */
75
    public function render_qsettingspage($page) {
76
        $data = $page->export_for_template($this);
77
        return $this->render_from_template('mod_questionnaire/qsettingspage', $data);
78
    }
79
 
80
    /**
81
     * Fill out the feedback page.
82
     * @param \templateable $page
83
     * @return string | boolean
84
     */
85
    public function render_feedbackpage($page) {
86
        $data = $page->export_for_template($this);
87
        return $this->render_from_template('mod_questionnaire/qsettingspage', $data);
88
    }
89
 
90
    /**
91
     * Fill out the questions page.
92
     * @param \templateable $page
93
     * @return string | boolean
94
     */
95
    public function render_questionspage($page) {
96
        $data = $page->export_for_template($this);
97
        return $this->render_from_template('mod_questionnaire/questionspage', $data);
98
    }
99
 
100
    /**
101
     * Fill out the preview page.
102
     * @param \templateable $page
103
     * @return string | boolean
104
     */
105
    public function render_previewpage($page) {
106
        $data = $page->export_for_template($this);
107
        return $this->render_from_template('mod_questionnaire/previewpage', $data);
108
    }
109
 
110
    /**
111
     * Fill out the non-respondents page.
112
     * @param \templateable $page
113
     * @return string | boolean
114
     */
115
    public function render_nonrespondentspage($page) {
116
        $data = $page->export_for_template($this);
117
        return $this->render_from_template('mod_questionnaire/nonrespondentspage', $data);
118
    }
119
 
120
    /**
121
     * Fill out the fbsections page.
122
     * @param \templateable $page
123
     * @return string | boolean
124
     */
125
    public function render_fbsectionspage($page) {
126
        $data = $page->export_for_template($this);
127
        return $this->render_from_template('mod_questionnaire/fbsectionspage', $data);
128
    }
129
 
130
    /**
131
     * Render the respondent information line.
132
     * @param string $text The respondent information.
133
     */
134
    public function respondent_info($text) {
135
        return \html_writer::tag('span', $text, ['class' => 'respondentinfo']);
136
    }
137
 
138
    /**
139
     * Render the completion form start HTML.
140
     * @param string $action The action URL.
141
     * @param array $hiddeninputs Name/value pairs of hidden inputs used by the form.
142
     * @return string The output for the page.
143
     */
144
    public function complete_formstart($action, $hiddeninputs=[]) {
145
        $output = '';
146
        $output .= \html_writer::start_tag('form', ['id' => 'phpesp_response', 'method' => 'post', 'action' => $action]) . "\n";
147
        foreach ($hiddeninputs as $name => $value) {
148
            $output .= \html_writer::empty_tag('input', ['type' => 'hidden', 'name' => $name, 'value' => $value]) . "\n";
149
        }
150
        return $output;
151
    }
152
 
153
    /**
154
     * Render the completion form end HTML.
155
     * @param array $inputs Type/attribute array of inputs and values used by the form.
156
     * @return string The output for the page.
157
     */
158
    public function complete_formend($inputs=[]) {
159
        $output = '';
160
        foreach ($inputs as $type => $attributes) {
161
            $output .= \html_writer::empty_tag('input', array_merge(['type' => $type], $attributes)) . "\n";
162
        }
163
        $output .= \html_writer::end_tag('form') . "\n";
164
        return $output;
165
    }
166
 
167
    /**
168
     * Render the completion form control buttons.
169
     * @param array|string $inputs Name/(Type/attribute) array of input types and values used by the form.
170
     * @return string The output for the page.
171
     */
172
    public function complete_controlbuttons($inputs=null) {
173
        $output = '';
174
        if (is_array($inputs)) {
175
            foreach ($inputs as $name => $attributes) {
176
                $output .= \html_writer::empty_tag('input', array_merge(['name' => $name], $attributes)) . ' ';
177
            }
178
        } else if (is_string($inputs)) {
179
            $output .= \html_writer::tag('p', $inputs);
180
        }
181
        return $output;
182
    }
183
 
184
    /**
185
     * Calculate the progress and return it.
186
     * @param int $section
187
     * @param array $questionsbysec
188
     * @return float
189
     */
190
    private function calculate_progress($section, $questionsbysec) {
191
        $done = 0;
192
        $todo = 0;
193
        for ($i = 1; $i <= count($questionsbysec); $i++) {
194
            if ($i < $section) {
195
                $done += count($questionsbysec[$i]);
196
            } else {
197
                $todo += count($questionsbysec[$i]);
198
            }
199
        }
200
 
201
        return round($done / ($done + $todo) * 100);
202
    }
203
 
204
    /**
205
     * Render the progress bar and return it.
206
     * @param int $section
207
     * @param array $questionsbysec
208
     * @return bool|string
209
     */
210
    public function render_progress_bar($section, $questionsbysec) {
211
        $templatecontext['percent'] = $this->calculate_progress($section, $questionsbysec);
212
        $helpicon = new \help_icon('progresshelp', 'mod_questionnaire');
213
        $templatecontext['progresshelp'] = $helpicon->export_for_template($this);
214
        return $this->render_from_template('mod_questionnaire/progressbar', $templatecontext);
215
    }
216
 
217
    /**
218
     * Render a question for a survey.
219
     * @param \mod_questionnaire\question\question $question The question object.
220
     * @param \mod_questionnaire\responsetype\response\response $response Any current response data.
221
     * @param int $qnum The question number.
222
     * @param boolean $blankquestionnaire Used for printing a blank one.
223
     * @param array $dependants Array of all questions/choices depending on $question.
224
     * @return string The output for the page.
225
     */
226
    public function question_output($question, $response, $qnum, $blankquestionnaire, $dependants=[]) {
227
 
228
        $pagetags = $question->question_output($response, $blankquestionnaire, $dependants, $qnum);
229
 
230
        // If the question has a template, then render it from the 'qformelement' context. If no template, then 'qformelement'
231
        // already contains HTML.
232
        if (($template = $question->question_template())) {
233
            $pagetags->qformelement = $this->render_from_template($template, $pagetags->qformelement);
234
        }
235
 
236
        // Calling "question_output" may generate per question notifications. If present, add them to the question output.
237
        if (($notifications = $question->get_notifications()) !== false) {
238
            foreach ($notifications as $notification) {
239
                $pagetags->notifications = $this->notification($notification, \core\output\notification::NOTIFY_ERROR);
240
            }
241
        }
242
 
243
        return $this->render_from_template('mod_questionnaire/question_container', $pagetags);
244
    }
245
 
246
    /**
247
     * Render a question response.
248
     * @param \mod_questionnaire\question\question $question The question object.
249
     * @param \mod_questionnaire\responsetype\response\response $response The response object.
250
     * @param int $qnum The question number.
251
     * @param bool $pdf
252
     * @return string The output for the page.
253
     * @throws \moodle_exception
254
     */
255
    public function response_output($question, $response, $qnum=null, $pdf=false) {
256
        $pagetags = $question->response_output($response, $qnum);
257
 
258
        // If the response has a template, then render it from the 'qformelement' context. If no template, then 'qformelement'
259
        // already contains HTML.
260
        if (($template = $question->response_template())) {
261
            if ($pdf) {
262
                $pagetags->qformelement->pdf = 1;
263
            }
264
            $pagetags->qformelement = $this->render_from_template($template, $pagetags->qformelement);
265
        }
266
 
267
        // Calling "question_output" may generate per question notifications. If present, add them to the question output.
268
        if (($notifications = $question->get_notifications()) !== false) {
269
            foreach ($notifications as $notification) {
270
                $pagetags->notifications = $this->notification($notification, \core\output\notification::NOTIFY_ERROR);
271
            }
272
        }
273
        if (!$pdf) {
274
            return $this->render_from_template('mod_questionnaire/question_container', $pagetags);
275
        } else {
276
            return $this->render_from_template('mod_questionnaire/questionpdf_container', $pagetags);
277
        }
278
    }
279
 
280
    /**
281
     * Render all responses for a question.
282
     * @param array|string $responses
283
     * @param array $questions
284
     * @return string The output for the page.
285
     */
286
    public function all_response_output($responses, $questions = null) {
287
        $output = '';
288
        if (is_string($responses)) {
289
            $output .= $responses;
290
        } else {
291
            $qnum = 1;
292
            foreach ($questions as $question) {
293
                if (empty($pagetags = $question->questionstart_survey_display($qnum))) {
294
                    continue;
295
                }
296
                foreach ($responses as $response) {
297
                    $resptags = $question->response_output($response);
298
                    // If the response has a template, then render it from the 'qformelement' context.
299
                    // If no template, then 'qformelement' already contains HTML.
300
                    if (($template = $question->response_template())) {
301
                        $resptags->qformelement = $this->render_from_template($template, $resptags->qformelement);
302
                    }
303
                    $resptags->respdate = userdate($response->submitted);
304
                    $pagetags->responses[] = $resptags;
305
                }
306
                $qnum++;
307
                $output .= $this->render_from_template('mod_questionnaire/response_container', $pagetags);
308
            }
309
        }
310
        return $output;
311
    }
312
 
313
    /**
314
     * Render a question results summary.
315
     * @param question $question The question object.
316
     * @param array $rids The response ids.
317
     * @param string $sort The sort order being used.
318
     * @param string $anonymous The value of the anonymous setting.
319
     * @param bool $pdf
320
     * @return string The output for the page.
321
     */
322
    public function results_output($question, $rids, $sort, $anonymous, $pdf = false) {
323
        $pagetags = $question->display_results($rids, $sort, $anonymous);
324
 
325
        // If the response has a template, then render it from $pagetags. If no template, then $pagetags already contains HTML.
326
        if (($template = $question->results_template($pdf))) {
327
            return $this->render_from_template($template, $pagetags);
328
        } else {
329
            return $pagetags;
330
        }
331
    }
332
 
333
    /**
334
     * Render the reporting navigation bar.
335
     * @param array $navbar All of the data needed for the template.
336
     * @return string The rendered HTML.
337
     */
338
    public function navigationbar($navbar) {
339
        return $this->render_from_template('mod_questionnaire/navbaralpha', $navbar);
340
    }
341
 
342
    /**
343
     * Render the reporting navigation bar for one user.
344
     * @param array $navbar All of the data needed for the template.
345
     * @return string The rendered HTML.
346
     */
347
    public function usernavigationbar($navbar) {
348
        return $this->render_from_template('mod_questionnaire/navbaruser', $navbar);
349
    }
350
 
351
    /**
352
     * Render the response list for a number of users.
353
     * @param array $navbar All of the data needed for the template.
354
     * @return string The rendered HTML.
355
     */
356
    public function responselist($navbar) {
357
        return $this->render_from_template('mod_questionnaire/responselist', $navbar);
358
    }
359
 
360
    /**
361
     * Render a print/preview page number line.
362
     * @param string $content The content to render.
363
     * @return string The rendered HTML.
364
     */
365
    public function print_preview_pagenumber($content) {
366
        return \html_writer::tag('div', $content, ['class' => 'surveyPage']);
367
    }
368
 
369
    /**
370
     * Render the print/preview completion form end HTML.
371
     * @param string $url The url to call.
372
     * @param string $submitstr The submit text.
373
     * @param string $resetstr The reset text.
374
     * @return string The output for the page.
375
     */
376
    public function print_preview_formend($url, $submitstr, $resetstr) {
377
        $output = '';
378
        $output .= \html_writer::start_tag('div');
379
        $output .= \html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'submit', 'value' => $submitstr,
380
            'class' => 'btn btn-primary']);
381
        $output .= ' ';
382
        $output .= \html_writer::tag('a', $resetstr, ['href' => $url, 'class' => 'btn btn-secondary mr-1']);
383
        $output .= \html_writer::end_tag('div') . "\n";
384
        $output .= \html_writer::end_tag('form') . "\n";
385
        return $output;
386
    }
387
 
388
    /**
389
     * Render the back to home link on the save page.
390
     * @param string $url The url to link to.
391
     * @param string $text The text to apply the link to.
392
     * @return string The rendered HTML.
393
     */
394
    public function homelink($url, $text) {
395
        $output = '';
396
        $output .= \html_writer::start_tag('div', ['class' => 'homelink']);
397
        $output .= \html_writer::tag('a', $text, ['href' => $url, 'class' => 'btn btn-primary']);
398
        $output .= \html_writer::end_tag('div');
399
        return $output;
400
    }
401
 
402
 
403
    /**
404
     * Generate and return any dependency warnings.
405
     * @param array $children
406
     * @param string $langstring
407
     * @param int $strnum
408
     * @return string
409
     */
410
    public function dependency_warnings($children, $langstring, $strnum) {
411
        $msg = '<div class="warning">' . get_string($langstring, 'questionnaire') . '</div><br />';
412
        foreach ($children as $child) {
413
            $loopindicator = array();
414
            foreach ($child as $subchild) {
415
                $childname = '';
416
                if ($subchild->name) {
417
                    $childname = ' ('.$subchild->name.')';
418
                }
419
 
420
                // Add conditions.
421
                switch ($subchild->dependlogic) {
422
                    case 0:
423
                        $logic = get_string('notset', 'questionnaire');
424
                        break;
425
                    case 1:
426
                        $logic = get_string('set', 'questionnaire');
427
                        break;
428
                    default:
429
                        $logic = '';
430
                }
431
 
432
                // Different colouring for and/or.
433
                switch ($subchild->dependandor) {
434
                    case 'or':
435
                        $color = 'qdepend-or';
436
                        break;
437
                    case 'and':
438
                        $color = "qdepend";
439
                        break;
440
                    default:
441
                        $color = "";
442
                }
443
 
444
                if (!in_array($subchild->qdependquestion, $loopindicator)) {
445
                    $msg .= '<div class = "qn-container">'.$strnum.' '.$subchild->position.$childname.
446
                        '<br/><span class="'.$color.'"><strong>'.
447
                        get_string('dependquestion', 'questionnaire').'</strong>'.
448
                        ' ('.$strnum.' '.$subchild->parentposition.') '.
449
                        '&nbsp;:&nbsp;'.$subchild->parent.' '.$logic.'</span>';
450
                } else {
451
                    $msg .= '<br/><span class="'.$color.'"><strong>'.
452
                        get_string('dependquestion', 'questionnaire').'</strong>'.
453
                        ' ('.$strnum.' '.$subchild->parentposition.') '.
454
                        '&nbsp;:&nbsp;'.$subchild->parent.' '.$logic.'</span>';
455
                }
456
                $loopindicator[] = $subchild->qdependquestion;
457
            }
458
            $msg .= '<div class="qn-question">'.
459
                $subchild->content.
460
                '</div></div>';
461
        }
462
        return $msg;
463
    }
464
 
465
    /**
466
     * Get displayable list of parents for the question in questions_form.
467
     * @param int $qid The question id.
468
     * @param array $dependencies Array of dependency records for a question.
469
     * @return string
470
     */
471
    public function get_dependency_html($qid, $dependencies) {
472
        $html = '';
473
        foreach ($dependencies as $dependency) {
474
            switch ($dependency->dependlogic) {
475
                case 0:
476
                    $logic = get_string('notset', 'questionnaire');
477
                    break;
478
                case 1:
479
                    $logic = get_string('set', 'questionnaire');
480
                    break;
481
                default:
482
                    $logic = '';
483
            }
484
 
485
            // TODO - Move the HTML generation to the renderer.
486
            if ($dependency->dependandor == "and") {
487
                $html .= '<div id="qdepend_' . $qid . '_' . $dependency->dependquestionid . '_' .
488
                    $dependency->dependchoiceid . '" class="qdepend">' . '<strong>' .
489
                    get_string('dependquestion', 'questionnaire') . '</strong> : '. get_string('position', 'questionnaire') . ' ' .
490
                    $dependency->parentposition . ' (' . $dependency->parent . ') ' . $logic . '</div>';
491
            } else {
492
                $html .= '<div id="qdepend_or_' . $qid . '_' . $dependency->dependquestionid . '_' .
493
                    $dependency->dependchoiceid . '" class="qdepend-or">' . '<strong>' .
494
                    get_string('dependquestion', 'questionnaire') . '</strong> : '. get_string('position', 'questionnaire') . ' ' .
495
                    $dependency->parentposition . ' (' . $dependency->parent . ') ' . $logic . '</div>';
496
            }
497
        }
498
        return $html;
499
    }
500
 
501
    /**
502
     * Helper method dealing with the fact we can not just fetch the output of flexible_table
503
     *
504
     * @param flexible_table $table
505
     * @param boolean $buffering True if already buffering.
506
     * @return string HTML
507
     */
508
    public function flexible_table(\flexible_table $table, $buffering = false) {
509
 
510
        $o = '';
511
        if (!$buffering) {
512
            ob_start();
513
        }
514
        $table->finish_output();
515
        $o = ob_get_contents();
516
        ob_end_clean();
517
 
518
        return $o;
519
    }
520
 
521
    /**
522
     * Returns a dataformat selection and download form
523
     *
524
     * @param string $label A text label
525
     * @param moodle_url|string $base The download page url
526
     * @param string $name The query param which will hold the type of the download
527
     * @param array $params Extra params sent to the download page
528
     * @param string $extrafields HTML for extra form fields
529
     * @return string HTML fragment
530
     */
531
    public function download_dataformat_selector($label, $base, $name = 'dataformat', $params = array(), $extrafields = '') {
532
 
533
        $formats = \core_plugin_manager::instance()->get_plugins_of_type('dataformat');
534
        $options = array();
535
        foreach ($formats as $format) {
536
            if ($format->is_enabled()) {
537
                $options[] = array(
538
                    'value' => $format->name,
539
                    'label' => get_string('dataformat', $format->component),
540
                );
541
            }
542
        }
543
        $hiddenparams = array();
544
        foreach ($params as $key => $value) {
545
            $hiddenparams[] = array(
546
                'name' => $key,
547
                'value' => $value,
548
            );
549
        }
550
        $data = array(
551
            'label' => $label,
552
            'base' => $base,
553
            'name' => $name,
554
            'params' => $hiddenparams,
555
            'options' => $options,
556
            'extrafields' => $extrafields,
557
            'sesskey' => sesskey(),
558
            'submit' => get_string('download'),
559
            'emailroleshelp' => $this->help_icon('emailroles', 'questionnaire'),
560
            'emailextrahelp' => $this->help_icon('emailextra', 'questionnaire'),
561
            'allowemailreporting' => get_config('questionnaire', 'allowemailreporting'),
562
        );
563
 
564
        return $this->render_from_template('mod_questionnaire/dataformat_selector', $data);
565
    }
566
}