1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php";
5include_once 'Modules/Test/classes/class.ilTestExpressPage.php';
6
7/**
8 * @ilCtrl_Calls ilTestExpressPageObjectGUI: assMultipleChoiceGUI, assClozeTestGUI, assMatchingQuestionGUI
9 * @ilCtrl_Calls ilTestExpressPageObjectGUI: assOrderingQuestionGUI, assImagemapQuestionGUI, assJavaAppletGUI
10 * @ilCtrl_Calls ilTestExpressPageObjectGUI: assNumericGUI
11 * @ilCtrl_Calls ilTestExpressPageObjectGUI: assTextSubsetGUI
12 * @ilCtrl_Calls ilTestExpressPageObjectGUI: assSingleChoiceGUI
13 * @ilCtrl_Calls ilTestExpressPageObjectGUI: assTextQuestionGUI, assFormulaQuestionGUI
14 * @ilCtrl_Calls ilTestExpressPageObjectGUI: ilPageEditorGUI, ilEditClipboardGUI, ilMediaPoolTargetSelector
15 * @ilCtrl_Calls ilTestExpressPageObjectGUI: ilRatingGUI, ilPublicUserProfileGUI, ilAssQuestionPageGUI, ilNoteGUI
16 * @ilCtrl_Calls ilTestExpressPageObjectGUI: ilObjQuestionPoolGUI
17 * @ilCtrl_IsCalledBy ilTestExpressPageObjectGUI: assMultipleChoiceGUI, assClozeTestGUI, assMatchingQuestionGUI
18 * @ilCtrl_IsCalledBy ilTestExpressPageObjectGUI: assOrderingQuestionGUI, assImagemapQuestionGUI, assJavaAppletGUI
19 * @ilCtrl_IsCalledBy ilTestExpressPageObjectGUI: assNumericGUI
20 * @ilCtrl_IsCalledBy ilTestExpressPageObjectGUI: assTextSubsetGUI
21 * @ilCtrl_IsCalledBy ilTestExpressPageObjectGUI: assSingleChoiceGUI
22 * @ilCtrl_IsCalledBy ilTestExpressPageObjectGUI: assTextQuestionGUI, assFormulaQuestionGUI
23 */
24class ilTestExpressPageObjectGUI extends ilAssQuestionPageGUI
25{
26    public function nextQuestion()
27    {
28        $obj = new ilObjTest($_REQUEST['ref_id']);
29        $questions = array_keys($obj->getQuestionTitlesAndIndexes());
30
31        $pos = array_search($_REQUEST['q_id'], $questions);
32
33        if ($pos !== false) {
34            $next = $questions[$pos + 1];
35        } else {
36            $next = $questions[0];
37        }
38
39        $this->ctrl->setParameter($this, 'q_id', $next);
40        $link = $this->ctrl->getLinkTarget($this, 'edit', '', '', false);
41
42        ilUtil::redirect($link);
43    }
44
45    public function prevQuestion()
46    {
47        $obj = new ilObjTest($_REQUEST['ref_id']);
48        $questions = array_keys($obj->getQuestionTitlesAndIndexes());
49
50        $pos = array_search($_REQUEST['q_id'], $questions);
51
52        if ($pos !== false) {
53            $next = $questions[$pos - 1];
54        } else {
55            $next = $questions[0];
56        }
57
58        $this->ctrl->setParameter($this, 'q_id', $next);
59        $link = $this->ctrl->getLinkTarget($this, 'edit', '', '', false);
60
61        ilUtil::redirect($link);
62    }
63
64    public function __construct($a_id = 0, $a_old_nr = 0)
65    {
66        parent::__construct($a_id, $a_old_nr);
67    }
68
69    public function executeCommand()
70    {
71
72        global $DIC; /* @var ILIAS\DI\Container $DIC */
73        $ilCtrl = $DIC['ilCtrl'];
74        $ilTabs = $DIC['ilTabs'];
75        $ilUser = $DIC['ilUser'];
76        $lng = $DIC['lng'];
77
78        $next_class = $this->ctrl->getNextClass($this);
79        $cmd = $this->ctrl->getCmd();
80
81        switch ($next_class) {
82            case 'ilobjquestionpoolgui':
83
84                $nodeParts = explode(':', $_GET['cmdNode']);
85
86                $params = array(
87                    'ref_id' => $_GET['ref_id'],
88                    'calling_test' => $_GET['ref_id'],
89                    'q_id' => $_GET['q_id'],
90                    'cmd' => $_GET['cmd'],
91                    'cmdClass' => $_GET['cmdClass'],
92                    'baseClass' => 'ilObjQuestionPoolGUI',
93                    'test_express_mode' => '1'
94                );
95
96                ilUtil::redirect(
97                    'ilias.php' . ilUtil::appendUrlParameterString(
98                        '?' . http_build_query($params, null, '&'),
99                        'cmdNode=' . ($nodeParts[count($nodeParts) - 2] . ':' . $nodeParts[count($nodeParts) - 1])
100                    )
101                );
102
103                break;
104
105            case "ilpageeditorgui":
106
107                if (!$this->getEnableEditing()) {
108                    ilUtil::sendFailure($lng->txt("permission_denied"), true);
109                    $ilCtrl->redirect($this, "preview");
110                }
111
112                $page_editor = new ilPageEditorGUI($this->getPageObject(), $this);
113                $page_editor->setLocator($this->locator);
114                $page_editor->setHeader($this->getHeader());
115                $page_editor->setPageBackTitle($this->page_back_title);
116                $page_editor->setIntLinkReturn($this->int_link_return);
117
118                $this->ctrl->saveParameterByClass('ilpageeditorgui', 'q_mode');
119
120                $ret = $this->ctrl->forwardCommand($page_editor);
121                if ($ret != "") {
122                    $this->tpl->setContent($ret);
123                }
124                break;
125
126            case '':
127            case 'iltestexpresspageobjectgui':
128
129                include_once 'Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
130
131                if ($cmd == 'view') {
132                    $cmd = 'showPage';
133                    $ilCtrl->setCmd($cmd);
134                }
135
136                $q_gui = assQuestionGUI::_getQuestionGUI('', (int) $_REQUEST["q_id"]);
137
138                if ($q_gui->object) {
139                    $obj = ilObjectFactory::getInstanceByRefId((int) $_REQUEST['ref_id']);
140                    $q_gui->object->setObjId($obj->getId());
141                }
142
143                $cmds = array(
144                    'handleToolbarCommand',
145                    'addQuestion',
146                    'questions',
147                    'insertQuestions',
148                    'browseForQuestions',
149                    'filterAvailableQuestions',
150                    'resetfilterAvailableQuestions'
151                );
152
153                if (in_array($cmd, $cmds)) {
154                    return $this->$cmd();
155                } elseif ($q_gui->object) {
156                    $total = $this->test_object->evalTotalPersons();
157
158                    $this->setOutputMode($total == 0 ? ilPageObjectGUI::EDIT : ilPageObjectGUI::PREVIEW);
159
160                    if ($total != 0) {
161                        $link = $DIC->ui()->factory()->link()->standard(
162                            $DIC->language()->txt("test_has_datasets_warning_page_view_link"),
163                            $DIC->ctrl()->getLinkTargetByClass(array('ilTestResultsGUI', 'ilParticipantsTestResultsGUI'))
164                        );
165
166                        $message = $DIC->language()->txt("test_has_datasets_warning_page_view");
167
168                        $msgBox = $DIC->ui()->factory()->messageBox()->info($message)->withLinks(array($link));
169
170                        $DIC->ui()->mainTemplate()->setCurrentBlock('mess');
171                        $DIC->ui()->mainTemplate()->setVariable(
172                            'MESSAGE',
173                            $DIC->ui()->renderer()->render($msgBox)
174                        );
175                        $DIC->ui()->mainTemplate()->parseCurrentBlock();
176                    }
177
178                    if ((in_array($cmd, array('view', 'showPage')) || $cmd == 'edit') && $this->test_object->evalTotalPersons()) {
179                        return $this->showPage();
180                    }
181
182                    return parent::executeCommand();
183                }
184
185                break;
186
187            default:
188                $type = ilObjQuestionPool::getQuestionTypeByTypeId(ilUtil::stripSlashes((string) $_REQUEST['qtype']));
189
190                if (!$_GET['q_id']) {
191                    $q_gui = $this->addPageOfQuestions(preg_replace('/(.*?)gui/i', '$1', $_GET['sel_question_types']));
192                    $q_gui->setQuestionTabs();
193
194                    $this->ctrl->forwardCommand($q_gui);
195                    break;
196                }
197
198                $this->ctrl->setReturn($this, "questions");
199
200                require_once 'Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
201                $q_gui = assQuestionGUI::_getQuestionGUI($type, (int) $_GET['q_id']);
202                if ($q_gui->object) {
203                    $obj = ilObjectFactory::getInstanceByRefId((int) $_GET['ref_id']);
204                    $q_gui->object->setObjId($obj->getId());
205                }
206
207                $this->ctrl->saveParameterByClass('ilpageeditorgui', 'q_id');
208                $this->ctrl->saveParameterByClass('ilpageeditorgui', 'q_mode');
209
210                $q_gui->setQuestionTabs();
211                $this->ctrl->forwardCommand($q_gui);
212                break;
213        }
214    }
215
216    public function addPageOfQuestions($type = '')
217    {
218        global $DIC;
219        $ilCtrl = $DIC['ilCtrl'];
220
221        if (!$type) {
222            $qtype = $_REQUEST['qtype'];
223            $pool = new ilObjQuestionPool();
224            $type = ilObjQuestionPool::getQuestionTypeByTypeId($qtype);
225        }
226
227        $this->ctrl->setReturn($this, "questions");
228
229        include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
230        $q_gui = &assQuestionGUI::_getQuestionGUI($type);
231
232        $obj = ilObjectFactory::getInstanceByRefId($_GET['ref_id']);
233
234        $q_gui->object->setObjId($obj->getId());
235
236        return $q_gui;
237    }
238
239    public function handleToolbarCommand()
240    {
241        global $DIC;
242        $ilCtrl = $DIC['ilCtrl'];
243
244        include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
245
246        if ($_REQUEST['qtype']) {
247            include_once 'Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php';
248            $questionType = ilObjQuestionPool::getQuestionTypeByTypeId($_REQUEST['qtype']);
249        } elseif ($_REQUEST['sel_question_types']) {
250            $questionType = $_REQUEST['sel_question_types'];
251        }
252
253        include_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
254        if (ilObjAssessmentFolder::isAdditionalQuestionContentEditingModePageObjectEnabled()) {
255            $addContEditMode = $_REQUEST['add_quest_cont_edit_mode'];
256        } else {
257            $addContEditMode = assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT;
258        }
259
260        $q_gui = &assQuestionGUI::_getQuestionGUI($questionType);
261
262        $q_gui->object->setObjId(ilObject::_lookupObjectId($_GET['ref_id']));
263        $q_gui->object->setAdditionalContentEditingMode($addContEditMode);
264
265        $q_gui->object->createNewQuestion();
266
267        $previousQuestionId = $_REQUEST['position'];
268
269        switch ($_REQUEST['usage']) {
270            case 3: // existing pool
271
272                $ilCtrl->setParameterByClass('ilobjtestgui', 'sel_qpl', $_REQUEST['sel_qpl']);
273                $ilCtrl->setParameterByClass('ilobjtestgui', 'sel_question_types', $questionType);
274                $ilCtrl->setParameterByClass('ilobjtestgui', 'q_id', $q_gui->object->getId());
275                $ilCtrl->setParameterByClass('ilobjtestgui', 'prev_qid', $previousQuestionId);
276
277                if ($_REQUEST['test_express_mode']) {
278                    $ilCtrl->setParameterByClass('ilobjtestgui', 'test_express_mode', 1);
279                }
280
281                if (isset($_REQUEST['add_quest_cont_edit_mode'])) {
282                    $ilCtrl->setParameterByClass(
283                        'ilobjtestgui',
284                        'add_quest_cont_edit_mode',
285                        $_REQUEST['add_quest_cont_edit_mode']
286                    );
287                }
288
289                $ilCtrl->setParameterByClass('ilobjtestgui', 'usage', 3);
290                $ilCtrl->setParameterByClass('ilobjtestgui', 'calling_test', $this->test_object->getId());
291
292                $link = $ilCtrl->getLinkTargetByClass('ilobjtestgui', 'executeCreateQuestion', false, false, false);
293
294                ilUtil::redirect($link);
295
296                break;
297
298            case 2: // new pool
299
300                $ilCtrl->setParameterByClass('ilobjtestgui', 'txt_qpl', $_REQUEST['txt_qpl']);
301                $ilCtrl->setParameterByClass('ilobjtestgui', 'sel_question_types', $questionType);
302                $ilCtrl->setParameterByClass('ilobjtestgui', 'q_id', $q_gui->object->getId());
303                $ilCtrl->setParameterByClass('ilobjtestgui', 'prev_qid', $previousQuestionId);
304
305                if ($_REQUEST['test_express_mode']) {
306                    $ilCtrl->setParameterByClass('ilobjtestgui', 'test_express_mode', 1);
307                }
308
309                if (isset($_REQUEST['add_quest_cont_edit_mode'])) {
310                    $ilCtrl->setParameterByClass(
311                        'ilobjtestgui',
312                        'add_quest_cont_edit_mode',
313                        $_REQUEST['add_quest_cont_edit_mode']
314                    );
315                }
316
317                $ilCtrl->setParameterByClass('ilobjtestgui', 'usage', 2);
318                $ilCtrl->setParameterByClass('ilobjtestgui', 'calling_test', $this->test_object->getId());
319
320                $link = $ilCtrl->getLinkTargetByClass('ilobjtestgui', 'executeCreateQuestion', false, false, false);
321                ilUtil::redirect($link);
322
323                break;
324
325            case 1: // no pool
326            default:
327
328                $this->redirectToQuestionEditPage($questionType, $q_gui->object->getId(), $previousQuestionId);
329
330                break;
331        }
332    }
333
334    public function addQuestion()
335    {
336        global $DIC;
337        $lng = $DIC['lng'];
338        $ilCtrl = $DIC['ilCtrl'];
339        $tpl = $DIC['tpl'];
340        global $DIC; /* @var \ILIAS\DI\Container $DIC */
341        $ilHelp = $DIC['ilHelp']; /* @var ilHelpGUI $ilHelp */
342
343        $subScreenId = array('createQuestion');
344
345        include_once "Services/Form/classes/class.ilPropertyFormGUI.php";
346
347        $ilCtrl->setParameter($this, 'qtype', $_REQUEST['qtype']);
348
349        $form = new ilPropertyFormGUI();
350
351        $ilCtrl->setParameter($this, 'test_express_mode', 1);
352
353        $form->setFormAction($ilCtrl->getFormAction($this, "handleToolbarCommand"));
354        $form->setTitle($lng->txt("ass_create_question"));
355        include_once 'Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php';
356
357        $pool = new ilObjQuestionPool();
358        $questionTypes = $pool->getQuestionTypes(false, true, false);
359        $options = array();
360
361        // question type
362        foreach ($questionTypes as $label => $data) {
363            $options[$data['question_type_id']] = $label;
364        }
365
366        include_once("./Services/Form/classes/class.ilSelectInputGUI.php");
367        $si = new ilSelectInputGUI($lng->txt("question_type"), "qtype");
368        $si->setOptions($options);
369        $form->addItem($si, true);
370
371        // position
372        $questions = $this->test_object->getQuestionTitlesAndIndexes();
373        if ($questions) {
374            $si = new ilSelectInputGUI($lng->txt("position"), "position");
375            $options = array('0' => $lng->txt('first'));
376            foreach ($questions as $key => $title) {
377                $options[$key] = $lng->txt('behind') . ' ' . $title . ' [' . $this->lng->txt('question_id_short') . ': ' . $key . ']';
378            }
379            $si->setOptions($options);
380            $si->setValue($_REQUEST['q_id']);
381            $form->addItem($si, true);
382        }
383
384        // content editing mode
385        if (ilObjAssessmentFolder::isAdditionalQuestionContentEditingModePageObjectEnabled()) {
386            $subScreenId[] = 'editMode';
387
388            $ri = new ilRadioGroupInputGUI($lng->txt("tst_add_quest_cont_edit_mode"), "add_quest_cont_edit_mode");
389
390            $ri->addOption(new ilRadioOption(
391                $lng->txt('tst_add_quest_cont_edit_mode_page_object'),
392                assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
393            ));
394
395            $ri->addOption(new ilRadioOption(
396                $lng->txt('tst_add_quest_cont_edit_mode_default'),
397                assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT
398            ));
399
400            $ri->setValue(assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT);
401
402            $form->addItem($ri, true);
403        } else {
404            $hi = new ilHiddenInputGUI("question_content_editing_type");
405            $hi->setValue(assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT);
406            $form->addItem($hi, true);
407        }
408
409        if ($this->test_object->getPoolUsage()) {
410            $subScreenId[] = 'poolSelect';
411
412            // use pool
413            $usage = new ilRadioGroupInputGUI($this->lng->txt("assessment_pool_selection"), "usage");
414            $usage->setRequired(true);
415            $no_pool = new ilRadioOption($this->lng->txt("assessment_no_pool"), 1);
416            $usage->addOption($no_pool);
417            $existing_pool = new ilRadioOption($this->lng->txt("assessment_existing_pool"), 3);
418            $usage->addOption($existing_pool);
419            $new_pool = new ilRadioOption($this->lng->txt("assessment_new_pool"), 2);
420            $usage->addOption($new_pool);
421            $form->addItem($usage);
422
423            $usage->setValue(1);
424
425            $questionpools = ilObjQuestionPool::_getAvailableQuestionpools(false, false, true, false, false, "write");
426            $pools_data = array();
427            foreach ($questionpools as $key => $p) {
428                $pools_data[$key] = $p['title'];
429            }
430            $pools = new ilSelectInputGUI($this->lng->txt("select_questionpool"), "sel_qpl");
431            $pools->setOptions($pools_data);
432            $existing_pool->addSubItem($pools);
433
434            $name = new ilTextInputGUI($this->lng->txt("name"), "txt_qpl");
435            $name->setSize(50);
436            $name->setMaxLength(50);
437            $new_pool->addSubItem($name);
438        }
439
440        $form->addCommandButton("handleToolbarCommand", $lng->txt("create"));
441        $form->addCommandButton("questions", $lng->txt("cancel"));
442
443        $ilHelp->setSubScreenId(implode('_', $subScreenId));
444
445        return $form->getHTML();
446    }
447
448    public function questions()
449    {
450        global $DIC;
451        $ilCtrl = $DIC['ilCtrl'];
452
453        $ilCtrl->saveParameterByClass('ilobjtestgui', 'q_id');
454
455        $ilCtrl->redirectByClass('ilobjtestgui', 'showPage');
456    }
457
458    private function redirectToQuestionEditPage($questionType, $qid, $prev_qid)
459    {
460        $cmdClass = $questionType . 'GUI';
461
462        $this->ctrl->setParameterByClass($cmdClass, 'ref_id', $_GET['ref_id']);
463        $this->ctrl->setParameterByClass($cmdClass, 'sel_question_types', $questionType);
464        $this->ctrl->setParameterByClass($cmdClass, 'test_ref_id', $_GET['ref_id']);
465        $this->ctrl->setParameterByClass($cmdClass, 'calling_test', $_GET['ref_id']);
466        $this->ctrl->setParameterByClass($cmdClass, 'q_id', $qid);
467        $this->ctrl->setParameterByClass($cmdClass, 'prev_qid', $prev_qid);
468
469        if ($_REQUEST['test_express_mode']) {
470            $this->ctrl->setParameterByClass($cmdClass, 'test_express_mode', 1);
471        }
472
473        $this->ctrl->redirectByClass(
474            array('ilRepositoryGUI', 'ilObjTestGUI', $questionType . "GUI"),
475            'editQuestion'
476        );
477    }
478
479    private function redirectToQuestionPoolSelectionPage($questionType, $qid, $prev_qid)
480    {
481        $this->ctrl->setParameterByClass('ilObjTestGUI', 'ref_id', $_REQUEST['ref_id']);
482        $this->ctrl->setParameterByClass('ilObjTestGUI', 'q_id', $qid);
483        $this->ctrl->setParameterByClass('ilObjTestGUI', 'sel_question_types', $questionType);
484        $this->ctrl->setParameterByClass('ilObjTestGUI', 'prev_qid', $prev_qid);
485        $redir = $this->ctrl->getLinkTargetByClass('ilObjTestGUI', 'createQuestion', '', false, false);
486
487        ilUtil::redirect($redir);
488    }
489
490    public function insertQuestions()
491    {
492        $selected_array = (is_array($_POST['q_id'])) ? $_POST['q_id'] : array();
493        if (!count($selected_array)) {
494            ilUtil::sendInfo($this->lng->txt("tst_insert_missing_question"), true);
495            $this->ctrl->redirect($this, "browseForQuestions");
496        } else {
497            include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
498            $manscoring = false;
499
500            global $DIC;
501            $tree = $DIC['tree'];
502            $ilDB = $DIC['ilDB'];
503            $ilPluginAdmin = $DIC['ilPluginAdmin'];
504
505            require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
506            $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $this->test_object);
507            $testQuestionSetConfig = $testQuestionSetConfigFactory->getQuestionSetConfig();
508
509            foreach ($selected_array as $key => $value) {
510                $last_question_id = $this->test_object->insertQuestion($testQuestionSetConfig, $value);
511
512                if (!$manscoring) {
513                    $manscoring = $manscoring | assQuestion::_needsManualScoring($value);
514                }
515            }
516            $this->test_object->saveCompleteStatus($testQuestionSetConfig);
517            if ($manscoring) {
518                ilUtil::sendInfo($this->lng->txt("manscoring_hint"), true);
519            } else {
520                ilUtil::sendSuccess($this->lng->txt("tst_questions_inserted"), true);
521            }
522
523            $this->ctrl->setParameter($this, 'q_id', $last_question_id);
524            $this->ctrl->redirect($this, "showPage");
525            return;
526        }
527    }
528}
529