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
 * This page handles the main question editing screen.
19
 *
20
 * @package    mod_questionnaire
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 * @copyright  2016 Mike Churchward (mike.churchward@poetopensource.org)
23
 */
24
 
25
require_once("../../config.php");
26
require_once($CFG->dirroot.'/mod/questionnaire/questionnaire.class.php');
27
require_once($CFG->dirroot.'/mod/questionnaire/classes/question/question.php'); // Needed for question type constants.
28
 
29
$id = required_param('id', PARAM_INT);                 // Course module ID.
30
$action = optional_param('action', 'main', PARAM_ALPHA);   // Screen.
31
$qid = optional_param('qid', 0, PARAM_INT);             // Question id.
32
$moveq = optional_param('moveq', 0, PARAM_INT);           // Question id to move.
33
$delq = optional_param('delq', 0, PARAM_INT);             // Question id to delete.
34
$qtype = optional_param('type_id', 0, PARAM_INT);         // Question type.
35
$currentgroupid = optional_param('group', 0, PARAM_INT); // Group id.
36
 
37
if (! $cm = get_coursemodule_from_id('questionnaire', $id)) {
38
    throw new \moodle_exception('invalidcoursemodule', 'mod_questionnaire');
39
}
40
 
41
if (! $course = $DB->get_record("course", array("id" => $cm->course))) {
42
    throw new \moodle_exception('coursemisconf', 'mod_questionnaire');
43
}
44
 
45
if (! $questionnaire = $DB->get_record("questionnaire", array("id" => $cm->instance))) {
46
    throw new \moodle_exception('invalidcoursemodule', 'mod_questionnaire');
47
}
48
 
49
require_course_login($course, true, $cm);
50
$context = context_module::instance($cm->id);
51
 
52
$url = new moodle_url($CFG->wwwroot.'/mod/questionnaire/questions.php');
53
$url->param('id', $id);
54
if ($qid) {
55
    $url->param('qid', $qid);
56
}
57
 
58
$PAGE->set_url($url);
59
$PAGE->set_context($context);
60
 
61
$questionnaire = new questionnaire($course, $cm, 0, $questionnaire);
62
 
63
// Add renderer and page objects to the questionnaire object for display use.
64
$questionnaire->add_renderer($PAGE->get_renderer('mod_questionnaire'));
65
$questionnaire->add_page(new \mod_questionnaire\output\questionspage());
66
 
67
if (!$questionnaire->capabilities->editquestions) {
68
    throw new \moodle_exception('nopermissions', 'mod_questionnaire');
69
}
70
 
71
$questionnairehasdependencies = $questionnaire->has_dependencies();
72
$dependants = null;
73
if (!isset($SESSION->questionnaire)) {
74
    $SESSION->questionnaire = new stdClass();
75
}
76
$SESSION->questionnaire->current_tab = 'questions';
77
$reload = false;
78
$sid = $questionnaire->survey->id;
79
// Process form data.
80
 
81
// Delete question button has been pressed in questions_form AND deletion has been confirmed on the confirmation page.
82
if ($delq) {
83
    $qid = $delq;
84
    $sid = $questionnaire->survey->id;
85
    $questionnaireid = $questionnaire->id;
86
 
87
    // Need to reload questions before setting deleted question to 'y'.
88
    $questions = $DB->get_records('questionnaire_question', ['surveyid' => $sid, 'deleted' => 'n'], 'id') ?? [];
89
    $DB->set_field('questionnaire_question', 'deleted', 'y', ['id' => $qid, 'surveyid' => $sid]);
90
 
91
    // Delete all dependency records for this question.
92
    questionnaire_delete_dependencies($qid);
93
 
94
    // Just in case the page is refreshed (F5) after a question has been deleted.
95
    if (isset($questions[$qid])) {
96
        $select = 'surveyid = '.$sid.' AND deleted = \'n\' AND position > '.
97
                        $questions[$qid]->position;
98
    } else {
99
        redirect($CFG->wwwroot.'/mod/questionnaire/questions.php?id='.$questionnaire->cm->id);
100
    }
101
 
102
    if ($records = $DB->get_records_select('questionnaire_question', $select, null, 'position ASC')) {
103
        foreach ($records as $record) {
104
            $DB->set_field('questionnaire_question', 'position', $record->position - 1, array('id' => $record->id));
105
        }
106
    }
107
    // Delete section breaks without asking for confirmation.
108
    // No need to delete responses to those "question types" which are not real questions.
109
    if (!$questionnaire->questions[$qid]->supports_responses()) {
110
        $reload = true;
111
    } else {
112
        // Delete responses to that deleted question.
113
        questionnaire_delete_responses($qid);
114
 
115
        // If no questions left in this questionnaire, remove all responses.
116
        if ($DB->count_records('questionnaire_question', ['surveyid' => $sid, 'deleted' => 'n']) == 0) {
117
            $DB->delete_records('questionnaire_response', ['questionnaireid' => $qid]);
118
        }
119
    }
120
 
121
    // Log question deleted event.
122
    $context = context_module::instance($questionnaire->cm->id);
123
    $questiontype = \mod_questionnaire\question\question::qtypename($questionnaire->questions[$qid]->type_id);
124
    $params = array(
125
                    'context' => $context,
126
                    'courseid' => $questionnaire->course->id,
127
                    'other' => array('questiontype' => $questiontype)
128
    );
129
    $event = \mod_questionnaire\event\question_deleted::create($params);
130
    $event->trigger();
131
 
132
    if ($questionnairehasdependencies) {
133
        $SESSION->questionnaire->validateresults = questionnaire_check_page_breaks($questionnaire);
134
    }
135
    $reload = true;
136
}
137
 
138
if ($action == 'main') {
139
    $questionsform = new \mod_questionnaire\questions_form('questions.php', $moveq);
140
    $sdata = clone($questionnaire->survey);
141
    $sdata->sid = $questionnaire->survey->id;
142
    $sdata->id = $cm->id;
143
    if (!empty($questionnaire->questions)) {
144
        $pos = 1;
145
        foreach ($questionnaire->questions as $qidx => $question) {
146
            $sdata->{'pos_'.$qidx} = $pos;
147
            $pos++;
148
        }
149
    }
150
    $questionsform->set_data($sdata);
151
    if ($questionsform->is_cancelled()) {
152
        // Switch to main screen.
153
        $action = 'main';
154
        redirect($CFG->wwwroot.'/mod/questionnaire/questions.php?id='.$questionnaire->cm->id);
155
        $reload = true;
156
    }
157
    if ($qformdata = $questionsform->get_data()) {
158
        // Quickforms doesn't return values for 'image' input types using 'exportValue', so we need to grab
159
        // it from the raw submitted data.
160
        $exformdata = data_submitted();
161
 
162
        if (isset($exformdata->movebutton)) {
163
            $qformdata->movebutton = $exformdata->movebutton;
164
        } else if (isset($exformdata->moveherebutton)) {
165
            $qformdata->moveherebutton = $exformdata->moveherebutton;
166
        } else if (isset($exformdata->editbutton)) {
167
            $qformdata->editbutton = $exformdata->editbutton;
168
        } else if (isset($exformdata->removebutton)) {
169
            $qformdata->removebutton = $exformdata->removebutton;
170
        } else if (isset($exformdata->requiredbutton)) {
171
            $qformdata->requiredbutton = $exformdata->requiredbutton;
172
        }
173
 
174
        // Insert a section break.
175
        if (isset($qformdata->removebutton)) {
176
            // Need to use the key, since IE returns the image position as the value rather than the specified
177
            // value in the <input> tag.
178
            $qid = key($qformdata->removebutton);
179
            $qtype = $questionnaire->questions[$qid]->type_id;
180
 
181
            // Delete section breaks without asking for confirmation.
182
            if ($qtype == QUESPAGEBREAK) {
183
                redirect($CFG->wwwroot.'/mod/questionnaire/questions.php?id='.$questionnaire->cm->id.'&amp;delq='.$qid);
184
            }
185
 
186
            $action = "confirmdelquestion";
187
            if ($questionnairehasdependencies) {
188
                // Important: due to possibly multiple parents per question
189
                // just remove the dependency and inform the user about it.
190
                $dependants = $questionnaire->get_all_dependants($qid);
191
                if (!(empty($dependants->directs) && empty($dependants->indirects))) {
192
                    $action = "confirmdelquestionparent";
193
                }
194
            }
195
        } else if (isset($qformdata->editbutton)) {
196
            // Switch to edit question screen.
197
            $action = 'question';
198
            // Need to use the key, since IE returns the image position as the value rather than the specified
199
            // value in the <input> tag.
200
            $qid = key($qformdata->editbutton);
201
            $reload = true;
202
 
203
        } else if (isset($qformdata->requiredbutton)) {
204
            // Need to use the key, since IE returns the image position as the value rather than the specified
205
            // value in the <input> tag.
206
 
207
            $qid = key($qformdata->requiredbutton);
208
            if ($questionnaire->questions[$qid]->required()) {
209
                $questionnaire->questions[$qid]->set_required(false);
210
 
211
            } else {
212
                $questionnaire->questions[$qid]->set_required(true);
213
            }
214
 
215
            $reload = true;
216
 
217
        } else if (isset($qformdata->addqbutton)) {
218
            if ($qformdata->type_id == QUESPAGEBREAK) { // Adding section break is handled right away....
219
                $questionrec = new stdClass();
220
                $questionrec->surveyid = $qformdata->sid;
221
                $questionrec->type_id = QUESPAGEBREAK;
222
                $questionrec->content = 'break';
223
                $question = \mod_questionnaire\question\question::question_builder(QUESPAGEBREAK);
224
                $question->add($questionrec);
225
                $reload = true;
226
            } else {
227
                // Switch to edit question screen.
228
                $action = 'question';
229
                $qtype = $qformdata->type_id;
230
                $qid = 0;
231
                $reload = true;
232
            }
233
 
234
        } else if (isset($qformdata->movebutton)) {
235
            // Nothing I do will seem to reload the form with new data, except for moving away from the page, so...
236
            redirect($CFG->wwwroot.'/mod/questionnaire/questions.php?id='.$questionnaire->cm->id.
237
                     '&moveq='.key($qformdata->movebutton));
238
            $reload = true;
239
 
240
 
241
 
242
        } else if (isset($qformdata->moveherebutton)) {
243
            // Need to use the key, since IE returns the image position as the value rather than the specified
244
            // value in the <input> tag.
245
 
246
            // No need to move question if new position = old position!
247
            $qpos = key($qformdata->moveherebutton);
248
            if ($qformdata->moveq != $qpos) {
249
                $questionnaire->move_question($qformdata->moveq, $qpos);
250
            }
251
            if ($questionnairehasdependencies) {
252
                $SESSION->questionnaire->validateresults = questionnaire_check_page_breaks($questionnaire);
253
            }
254
            // Nothing I do will seem to reload the form with new data, except for moving away from the page, so...
255
            redirect($CFG->wwwroot.'/mod/questionnaire/questions.php?id='.$questionnaire->cm->id);
256
            $reload = true;
257
 
258
        } else if (isset($qformdata->validate)) {
259
            // Validates page breaks for depend questions.
260
            $SESSION->questionnaire->validateresults = questionnaire_check_page_breaks($questionnaire);
261
            $reload = true;
262
        }
263
    }
264
 
265
 
266
} else if ($action == 'question') {
267
    $question = questionnaire_prep_for_questionform($questionnaire, $qid, $qtype);
268
    $questionsform = new \mod_questionnaire\edit_question_form('questions.php');
269
    $questionsform->set_data($question);
270
    if ($questionsform->is_cancelled()) {
271
        // Switch to main screen.
272
        $action = 'main';
273
        $reload = true;
274
 
275
    } else if ($qformdata = $questionsform->get_data()) {
276
        // Saving question data.
277
        if (isset($qformdata->makecopy)) {
278
            $qformdata->qid = 0;
279
        }
280
 
281
        $question->form_update($qformdata, $questionnaire);
282
 
283
        // Make these field values 'sticky' for further new questions.
284
        if (!isset($qformdata->required)) {
285
            $qformdata->required = 'n';
286
        }
287
 
288
        questionnaire_check_page_breaks($questionnaire);
289
        $SESSION->questionnaire->required = $qformdata->required;
290
        $SESSION->questionnaire->type_id = $qformdata->type_id;
291
        // Switch to main screen.
292
        $action = 'main';
293
        $reload = true;
294
    }
295
 
296
    // Log question created event.
297
    if (isset($qformdata)) {
298
        $context = context_module::instance($questionnaire->cm->id);
299
        $questiontype = \mod_questionnaire\question\question::qtypename($qformdata->type_id);
300
        $params = array(
301
                        'context' => $context,
302
                        'courseid' => $questionnaire->course->id,
303
                        'other' => array('questiontype' => $questiontype)
304
        );
305
        $event = \mod_questionnaire\event\question_created::create($params);
306
        $event->trigger();
307
    }
308
 
309
    $questionsform->set_data($question);
310
}
311
 
312
// Reload the form data if called for...
313
if ($reload) {
314
    unset($questionsform);
315
    $questionnaire = new questionnaire($course, $cm, $questionnaire->id, null);
316
    // Add renderer and page objects to the questionnaire object for display use.
317
    $questionnaire->add_renderer($PAGE->get_renderer('mod_questionnaire'));
318
    $questionnaire->add_page(new \mod_questionnaire\output\questionspage());
319
    if ($action == 'main') {
320
        $questionsform = new \mod_questionnaire\questions_form('questions.php', $moveq);
321
        $sdata = clone($questionnaire->survey);
322
        $sdata->sid = $questionnaire->survey->id;
323
        $sdata->id = $cm->id;
324
        if (!empty($questionnaire->questions)) {
325
            $pos = 1;
326
            foreach ($questionnaire->questions as $qidx => $question) {
327
                $sdata->{'pos_'.$qidx} = $pos;
328
                $pos++;
329
            }
330
        }
331
        $questionsform->set_data($sdata);
332
    } else if ($action == 'question') {
333
        $question = questionnaire_prep_for_questionform($questionnaire, $qid, $qtype);
334
        $questionsform = new \mod_questionnaire\edit_question_form('questions.php');
335
        $questionsform->set_data($question);
336
    }
337
}
338
 
339
// Print the page header.
340
if ($action == 'question') {
341
    if (isset($question->qid)) {
342
        $streditquestion = get_string('editquestion', 'questionnaire', questionnaire_get_type($question->type_id));
343
    } else {
344
        $streditquestion = get_string('addnewquestion', 'questionnaire', questionnaire_get_type($question->type_id));
345
    }
346
} else {
347
    $streditquestion = get_string('managequestions', 'questionnaire');
348
}
349
 
350
$PAGE->set_title($streditquestion);
351
$PAGE->set_heading(format_string($course->fullname));
352
$PAGE->navbar->add($streditquestion);
353
echo $questionnaire->renderer->header();
354
require('tabs.php');
355
 
356
if ($action == "confirmdelquestion" || $action == "confirmdelquestionparent") {
357
 
358
    $qid = key($qformdata->removebutton);
359
    $question = $questionnaire->questions[$qid];
360
    $qtype = $question->type_id;
361
 
362
    // Count responses already saved for that question.
363
    $countresps = 0;
364
    if ($qtype != QUESSECTIONTEXT) {
365
        $responsetable = $DB->get_field('questionnaire_question_type', 'response_table', array('typeid' => $qtype));
366
        if (!empty($responsetable)) {
367
            $countresps = $DB->count_records('questionnaire_'.$responsetable, array('question_id' => $qid));
368
        }
369
    }
370
 
371
    // Needed to print potential media in question text.
372
 
373
    // If question text is "empty", i.e. 2 non-breaking spaces were inserted, do not display any question text.
374
 
375
    if ($question->content == '<p>  </p>') {
376
        $question->content = '';
377
    }
378
 
379
    $qname = '';
380
    if ($question->name) {
381
        $qname = ' ('.$question->name.')';
382
    }
383
 
384
    $num = get_string('position', 'questionnaire');
385
    $pos = $question->position.$qname;
386
 
387
    $msg = '<div class="warning centerpara"><p>'.get_string('confirmdelquestion', 'questionnaire', $pos).'</p>';
388
    if ($countresps !== 0) {
389
        $msg .= '<p>'.get_string('confirmdelquestionresps', 'questionnaire', $countresps).'</p>';
390
    }
391
    $msg .= '</div>';
392
    $msg .= '<div class = "qn-container">'.$num.' '.$pos.'<div class="qn-question">'.$question->content.'</div></div>';
393
    $args = "id={$questionnaire->cm->id}";
394
    $urlno = new moodle_url("/mod/questionnaire/questions.php?{$args}");
395
    $args .= "&delq={$qid}";
396
    $urlyes = new moodle_url("/mod/questionnaire/questions.php?{$args}");
397
    $buttonyes = new single_button($urlyes, get_string('yes'));
398
    $buttonno = new single_button($urlno, get_string('no'));
399
    if ($action == "confirmdelquestionparent") {
400
        $strnum = get_string('position', 'questionnaire');
401
        $qid = key($qformdata->removebutton);
402
        if ($dependants) {
403
            // Show the dependencies and inform about the dependencies to be removed.
404
            // Split dependencies in direct and indirect ones to separate for the confirm-dialogue.
405
            // Only direct ones will be deleted. List direct dependencies.
406
            $msg .= $questionnaire->renderer->dependency_warnings($dependants->directs, 'directwarnings', $strnum);
407
            // List indirect dependencies.
408
            $msg .= $questionnaire->renderer->dependency_warnings($dependants->indirects, 'indirectwarnings', $strnum);
409
        }
410
    }
411
    $questionnaire->page->add_to_page('formarea', $questionnaire->renderer->confirm($msg, $buttonyes, $buttonno));
412
 
413
} else {
414
    $questionnaire->page->add_to_page('formarea', $questionsform->render());
415
}
416
echo $questionnaire->renderer->render($questionnaire->page);
417
echo $questionnaire->renderer->footer();