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;
18
 
19
defined('MOODLE_INTERNAL') || die();
20
 
21
require_once($CFG->libdir . '/formslib.php');
22
 
23
/**
24
 * The form definition class for questions.
25
 *
26
 * @package mod_questionnaire
27
 * @copyright  2016 Mike Churchward (mike.churchward@poetgroup.org)
28
 * @author Mike Churchward & Joseph Rézeau
29
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 */
31
class questions_form extends \moodleform {
32
 
33
    /**
34
     * The constructor.
35
     * @param mixed $action
36
     * @param bool $moveq
37
     */
38
    public function __construct($action, $moveq=false) {
39
        $this->moveq = $moveq;
40
        return parent::__construct($action);
41
    }
42
 
43
    /**
44
     * Form definition.
45
     */
46
    public function definition() {
47
        global $CFG, $questionnaire, $SESSION;
48
        global $DB;
49
 
50
        $sid = $questionnaire->survey->id;
51
        $mform    =& $this->_form;
52
 
53
        $mform->addElement('header', 'questionhdr', get_string('addquestions', 'questionnaire'));
54
        $mform->addHelpButton('questionhdr', 'questiontypes', 'questionnaire');
55
 
56
        $strremove = get_string('remove', 'questionnaire');
57
        $strmove = get_string('move');
58
        $strmovehere = get_string('movehere');
59
        $strposition = get_string('position', 'questionnaire');
60
 
61
        if (!isset($questionnaire->questions)) {
62
            $questionnaire->questions = array();
63
        }
64
        if ($this->moveq) {
65
            $moveqposition = $questionnaire->questions[$this->moveq]->position;
66
        }
67
 
68
        $pos = 0;
69
        $select = '';
70
        if (!($qtypes = $DB->get_records_select_menu('questionnaire_question_type', $select, null, '', 'typeid,type'))) {
71
            $qtypes = array();
72
        }
73
        // Get the names of each question type in the appropriate language.
74
        foreach ($qtypes as $key => $qtype) {
75
            // Do not allow "Page Break" to be selected as first element of a Questionnaire.
76
            if (empty($questionnaire->questions) && ($qtype == 'Page Break')) {
77
                unset($qtypes[$key]);
78
            } else {
79
                $qtypes[$key] = questionnaire_get_type($key);
80
            }
81
        }
82
        natsort($qtypes);
83
        $addqgroup = array();
84
        $addqgroup[] =& $mform->createElement('select', 'type_id', '', $qtypes);
85
 
86
        // The 'sticky' type_id value for further new questions.
87
        if (isset($SESSION->questionnaire->type_id)) {
88
                $mform->setDefault('type_id', $SESSION->questionnaire->type_id);
89
        }
90
 
91
        $addqgroup[] =& $mform->createElement('submit', 'addqbutton', get_string('addselqtype', 'questionnaire'));
92
 
93
        $questionnairehasdependencies = $questionnaire->has_dependencies();
94
 
95
        $mform->addGroup($addqgroup, 'addqgroup', '', ' ', false);
96
 
97
        if (isset($SESSION->questionnaire->validateresults) &&  $SESSION->questionnaire->validateresults != '') {
98
            $mform->addElement('static', 'validateresult', '', '<div class="qdepend warning">'.
99
                $SESSION->questionnaire->validateresults.'</div>');
100
            $SESSION->questionnaire->validateresults = '';
101
        }
102
 
103
        $qnum = 0;
104
 
105
        // JR skip logic :: to prevent moving child higher than parent OR parent lower than child
106
        // we must get now the parent and child positions.
107
 
108
        if ($questionnairehasdependencies) {
109
            $parentpositions = questionnaire_get_parent_positions($questionnaire->questions);
110
            $childpositions = questionnaire_get_child_positions($questionnaire->questions);
111
        }
112
 
113
        $mform->addElement('header', 'manageq', get_string('managequestions', 'questionnaire'));
114
        $mform->addHelpButton('manageq', 'managequestions', 'questionnaire');
115
 
116
        $mform->addElement('html', '<div class="qcontainer">');
117
 
118
        foreach ($questionnaire->questions as $question) {
119
 
120
            $manageqgroup = array();
121
 
122
            $qid = $question->id;
123
            $tid = $question->type_id;
124
            $qtype = $question->type;
125
            $required = $question->required;
126
 
127
            // Get displayable list of parents for the questions in questions_form.
128
            if ($questionnairehasdependencies) {
129
                // TODO - Perhaps this should be a function called by the questionnaire after it loads all questions?
130
                $questionnaire->load_parents($question);
131
                $dependencies = $questionnaire->renderer->get_dependency_html($question->id, $question->dependencies);
132
            } else {
133
                $dependencies = '';
134
            }
135
 
136
            $pos = $question->position;
137
 
138
            // No page break in first position!
139
            if ($tid == QUESPAGEBREAK && $pos == 1) {
140
                $DB->set_field('questionnaire_question', 'deleted', 'y', ['id' => $qid, 'surveyid' => $sid]);
141
                if ($records = $DB->get_records_select('questionnaire_question', $select, null, 'position ASC')) {
142
                    foreach ($records as $record) {
143
                        $DB->set_field('questionnaire_question', 'position', $record->position - 1, array('id' => $record->id));
144
                    }
145
                }
146
                redirect($CFG->wwwroot.'/mod/questionnaire/questions.php?id='.$questionnaire->cm->id);
147
            }
148
 
149
            if ($tid != QUESPAGEBREAK && $tid != QUESSECTIONTEXT) {
150
                $qnum++;
151
            }
152
 
153
            // Needed for non-English languages JR.
154
            $qtype = '['.questionnaire_get_type($tid).']';
155
            $content = '';
156
            // If question text is "empty", i.e. 2 non-breaking spaces were inserted, do not display any question text.
157
            if ($question->content == '<p>  </p>') {
158
                $question->content = '';
159
            }
160
            if ($tid != QUESPAGEBREAK) {
161
                // Needed to print potential media in question text.
162
                $content = format_text(file_rewrite_pluginfile_urls($question->content, 'pluginfile.php',
163
                    $question->context->id, 'mod_questionnaire', 'question', $question->id), FORMAT_HTML, ['noclean' => true]);
164
            }
165
            $moveqgroup = array();
166
 
167
            $spacer = $questionnaire->renderer->image_url('spacer');
168
 
169
            if (!$this->moveq) {
170
                if ($dependencies) {
171
                    // Begin div qn-container with indent if questionnaire has child.
172
                    $mform->addElement('html', '<div class="qn-container qn-indent">');
173
                } else {
174
                    $mform->addElement('html', '<div class="qn-container">'); // Begin div qn-container.
175
                }
176
 
177
                $mextra = array('value' => $question->id,
178
                                'alt' => $strmove,
179
                                'title' => $strmove);
180
                $eextra = array('value' => $question->id,
181
                                'alt' => get_string('edit', 'questionnaire'),
182
                                'title' => get_string('edit', 'questionnaire'));
183
                $rextra = array('value' => $question->id,
184
                                'alt' => $strremove,
185
                                'title' => $strremove);
186
 
187
                if ($tid == QUESPAGEBREAK) {
188
                    $esrc = $spacer;
189
                    $eextra = array('disabled' => 'disabled');
190
                } else {
191
                    $esrc = $questionnaire->renderer->image_url('t/edit');
192
                }
193
                $rsrc = $questionnaire->renderer->image_url('t/delete');
194
 
195
                // Question numbers.
196
                $manageqgroup[] =& $mform->createElement('static', 'qnums', '',
197
                                '<div class="qnums">'.$strposition.' '.$pos.'</div>');
198
 
199
                // Need to index by 'id' since IE doesn't return assigned 'values' for image inputs.
200
                $manageqgroup[] =& $mform->createElement('static', 'opentag_'.$question->id, '', '');
201
                $msrc = $questionnaire->renderer->image_url('t/move');
202
 
203
                if ($questionnairehasdependencies) {
204
                    // Do not allow moving parent question at position #1 to be moved down if it has a child at position < 4.
205
                    if ($pos == 1) {
206
                        if (isset($childpositions[$qid])) {
207
                            $maxdown = $childpositions[$qid];
208
                            if ($maxdown < 4) {
209
                                $strdisabled = get_string('movedisabled', 'questionnaire');
210
                                $msrc = $questionnaire->renderer->image_url('t/block');
211
                                $mextra = array('value' => $question->id,
212
                                                'alt' => $strdisabled,
213
                                                'title' => $strdisabled);
214
                                $mextra += array('disabled' => 'disabled');
215
                            }
216
                        }
217
                    }
218
 
219
                    // Do not allow moving or deleting a page break if immediately followed by a child question
220
                    // or immediately preceded by a question with a dependency and followed by a non-dependent question.
221
                    if ($tid == QUESPAGEBREAK) {
222
                        if ($nextquestion = $DB->get_record('questionnaire_question',
223
                            ['surveyid' => $sid, 'position' => $pos + 1, 'deleted' => 'n'], 'id, name, content') ) {
224
 
225
                            $nextquestiondependencies = $DB->get_records('questionnaire_dependency',
226
                                ['questionid' => $nextquestion->id , 'surveyid' => $sid], 'id ASC');
227
 
228
                            if ($previousquestion = $DB->get_record('questionnaire_question',
229
                                ['surveyid' => $sid, 'position' => $pos - 1, 'deleted' => 'n'], 'id, name, content')) {
230
 
231
                                $previousquestiondependencies = $DB->get_records('questionnaire_dependency',
232
                                    ['questionid' => $previousquestion->id , 'surveyid' => $sid], 'id ASC');
233
 
234
                                if (!empty($nextquestiondependencies) ||
235
                                    (!empty($previousquestiondependencies) && empty($nextquestiondependencies))) {
236
                                    $strdisabled = get_string('movedisabled', 'questionnaire');
237
                                    $msrc = $questionnaire->renderer->image_url('t/block');
238
                                    $mextra = array('value' => $question->id,
239
                                                    'alt' => $strdisabled,
240
                                                    'title' => $strdisabled);
241
                                    $mextra += array('disabled' => 'disabled');
242
 
243
                                    $rsrc = $msrc;
244
                                    $strdisabled = get_string('deletedisabled', 'questionnaire');
245
                                    $rextra = array('value' => $question->id,
246
                                                    'alt' => $strdisabled,
247
                                                    'title' => $strdisabled);
248
                                    $rextra += array('disabled' => 'disabled');
249
                                }
250
                            }
251
                        }
252
                    }
253
                }
254
                $manageqgroup[] =& $mform->createElement('image', 'movebutton['.$question->id.']',
255
                                $msrc, $mextra);
256
                $manageqgroup[] =& $mform->createElement('image', 'editbutton['.$question->id.']', $esrc, $eextra);
257
                $manageqgroup[] =& $mform->createElement('image', 'removebutton['.$question->id.']', $rsrc, $rextra);
258
 
259
                if ($tid != QUESPAGEBREAK && $tid != QUESSECTIONTEXT  && $tid != QUESSLIDER) {
260
                    if ($required == 'y') {
261
                        $reqsrc = $questionnaire->renderer->image_url('t/stop');
262
                        $strrequired = get_string('required', 'questionnaire');
263
                    } else {
264
                        $reqsrc = $questionnaire->renderer->image_url('t/go');
265
                        $strrequired = get_string('notrequired', 'questionnaire');
266
                    }
267
                    $strrequired .= ' '.get_string('clicktoswitch', 'questionnaire');
268
                    $reqextra = array('value' => $question->id,
269
                                    'alt' => $strrequired,
270
                                    'title' => $strrequired);
271
                    $manageqgroup[] =& $mform->createElement('image', 'requiredbutton['.$question->id.']', $reqsrc, $reqextra);
272
                }
273
                $manageqgroup[] =& $mform->createElement('static', 'closetag_'.$question->id, '', '');
274
 
275
            } else {
276
                $manageqgroup[] =& $mform->createElement('static', 'qnum', '',
277
                                '<div class="qnums">'.$strposition.' '.$pos.'</div>');
278
                $moveqgroup[] =& $mform->createElement('static', 'qnum', '', '');
279
 
280
                $display = true;
281
                if ($questionnairehasdependencies) {
282
                    // Prevent moving child to higher position than its parent.
283
                    if (isset($parentpositions[$this->moveq])) {
284
                        $maxup = $parentpositions[$this->moveq];
285
                        if ($pos <= $maxup) {
286
                            $display = false;
287
                        }
288
                    }
289
                    // Prevent moving parent to lower position than its (first) child.
290
                    if (isset($childpositions[$this->moveq])) {
291
                        $maxdown = $childpositions[$this->moveq];
292
                        if ($pos >= $maxdown) {
293
                            $display = false;
294
                        }
295
                    }
296
                }
297
 
298
                $typeid = $DB->get_field('questionnaire_question', 'type_id', array('id' => $this->moveq));
299
 
300
                if ($display) {
301
                    // Do not move a page break to first position.
302
                    if ($typeid == QUESPAGEBREAK && $pos == 1) {
303
                        $manageqgroup[] =& $mform->createElement('static', 'qnums', '', '');
304
                    } else {
305
                        if ($this->moveq == $question->id) {
306
                            $moveqgroup[] =& $mform->createElement('cancel', 'cancelbutton', get_string('cancel'));
307
                        } else {
308
                            $mextra = array('value' => $question->id,
309
                                            'alt' => $strmove,
310
                                            'title' => $strmovehere.' (position '.$pos.')');
311
                            $msrc = $questionnaire->renderer->image_url('movehere');
312
                            $moveqgroup[] =& $mform->createElement('static', 'opentag_'.$question->id, '', '');
313
                            $moveqgroup[] =& $mform->createElement('image', 'moveherebutton['.$pos.']', $msrc, $mextra);
314
                            $moveqgroup[] =& $mform->createElement('static', 'closetag_'.$question->id, '', '');
315
                        }
316
                    }
317
                } else {
318
                    $manageqgroup[] =& $mform->createElement('static', 'qnums', '', '');
319
                    $moveqgroup[] =& $mform->createElement('static', 'qnums', '', '');
320
                }
321
            }
322
            if ($question->name) {
323
                $qname = '('.$question->name.')';
324
            } else {
325
                $qname = '';
326
            }
327
            $manageqgroup[] =& $mform->createElement('static', 'qinfo_'.$question->id, '', $qtype.' '.$qname);
328
 
329
            if (!empty($dependencies)) {
330
                $mform->addElement('static', 'qdepend_' . $question->id, '', $dependencies);
331
            }
332
 
333
            if ($tid != QUESPAGEBREAK) {
334
                if ($tid != QUESSECTIONTEXT) {
335
                    $qnumber = '<div class="qn-info"><h2 class="qn-number">'.$qnum.'</h2></div>';
336
                } else {
337
                    $qnumber = '';
338
                }
339
            }
340
 
341
            if ($this->moveq && $pos < $moveqposition) {
342
                $mform->addGroup($moveqgroup, 'moveqgroup', '', '', false);
343
            }
344
            if ($this->moveq) {
345
                if ($this->moveq == $question->id && $display) {
346
                    $mform->addElement('html', '<div class="moving" title="'.$strmove.'">'); // Begin div qn-container.
347
                } else {
348
                    $mform->addElement('html', '<div class="qn-container">'); // Begin div qn-container.
349
                }
350
            }
351
            $mform->addGroup($manageqgroup, 'manageqgroup', '', '&nbsp;', false);
352
            if ($tid != QUESPAGEBREAK) {
353
                $mform->addElement('static', 'qcontent_'.$question->id, '',
354
                    $qnumber.'<div class="qn-question">'.$content.'</div>');
355
            }
356
            $mform->addElement('html', '</div>'); // End div qn-container.
357
 
358
            if ($this->moveq && $pos >= $moveqposition) {
359
                $mform->addGroup($moveqgroup, 'moveqgroup', '', '', false);
360
            }
361
        }
362
 
363
        if ($this->moveq) {
364
            $mform->addElement('hidden', 'moveq', $this->moveq);
365
        }
366
 
367
        // Hidden fields.
368
        $mform->addElement('hidden', 'id', 0);
369
        $mform->setType('id', PARAM_INT);
370
        $mform->addElement('hidden', 'sid', 0);
371
        $mform->setType('sid', PARAM_INT);
372
        $mform->addElement('hidden', 'action', 'main');
373
        $mform->setType('action', PARAM_RAW);
374
        $mform->setType('moveq', PARAM_RAW);
375
 
376
        $mform->addElement('html', '</div>');
377
    }
378
 
379
    /**
380
     * Form validation.
381
     * @param array $data
382
     * @param array $files
383
     * @return array
384
     */
385
    public function validation($data, $files) {
386
        $errors = parent::validation($data, $files);
387
        return $errors;
388
    }
389
}