1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/TestQuestionPool/classes/class.ilSingleChoiceWizardInputGUI.php';
5require_once 'Modules/TestQuestionPool/classes/class.ilAssKprimChoiceAnswer.php';
6require_once 'Services/MediaObjects/classes/class.ilObjMediaObject.php';
7
8/**
9 * @author		Björn Heyser <bheyser@databay.de>
10 * @version		$Id$
11 *
12 * @package     Modules/TestQuestionPool
13 */
14class ilKprimChoiceWizardInputGUI extends ilSingleChoiceWizardInputGUI
15{
16    const CUSTOM_UPLOAD_ERR = 99;
17    /**
18     * @var ilLanguage
19     */
20    protected $lng;
21
22    /**
23     * @var ilTemplate
24     */
25    protected $tpl;
26
27    /**
28     * @var assKprimChoice
29     */
30    protected $qstObject;
31
32    private $files;
33
34    private $ignoreMissingUploadsEnabled;
35
36    public function __construct($a_title = "", $a_postvar = "")
37    {
38        parent::__construct($a_title, $a_postvar);
39
40        global $DIC;
41        $lng = $DIC['lng'];
42        $tpl = $DIC['tpl'];
43
44        $this->lng = $lng;
45        $this->tpl = $tpl;
46
47        $this->files = array();
48
49        $this->ignoreMissingUploadsEnabled = false;
50    }
51
52    public function setFiles($files)
53    {
54        $this->files = $files;
55    }
56
57    public function getFiles()
58    {
59        return $this->files;
60    }
61
62    public function setIgnoreMissingUploadsEnabled($ignoreMissingUploadsEnabled)
63    {
64        $this->ignoreMissingUploadsEnabled = $ignoreMissingUploadsEnabled;
65    }
66
67    public function isIgnoreMissingUploadsEnabled()
68    {
69        return $this->ignoreMissingUploadsEnabled;
70    }
71
72    public function setValue($a_value)
73    {
74        $this->values = array();
75
76        if (is_array($a_value) && is_array($a_value['answer'])) {
77            foreach ($a_value['answer'] as $index => $value) {
78                $answer = new ilAssKprimChoiceAnswer();
79
80                $answer->setPosition($index);
81                $answer->setAnswertext($value);
82                $answer->setImageFile($a_value['imagename'][$index]);
83
84                if (strlen($a_value['correctness'][$index])) {
85                    $answer->setCorrectness((bool) $a_value['correctness'][$index]);
86                }
87
88                $answer->setThumbPrefix($this->qstObject->getThumbPrefix());
89                $answer->setImageFsDir($this->qstObject->getImagePath());
90                $answer->setImageWebDir($this->qstObject->getImagePathWeb());
91
92                $this->values[] = $answer;
93            }
94        }
95
96        #vd($this->values);
97    }
98
99    public function checkInput()
100    {
101        global $DIC;
102        $lng = $DIC['lng'];
103
104        include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
105        if (is_array($_POST[$this->getPostVar()])) {
106            $_POST[$this->getPostVar()] = ilUtil::stripSlashesRecursive(
107                $_POST[$this->getPostVar()],
108                false,
109                ilObjAdvancedEditing::_getUsedHTMLTagsAsString("assessment")
110            );
111        }
112
113        $foundvalues = $_POST[$this->getPostVar()];
114
115        #vd($foundvalues);
116
117        if (is_array($foundvalues)) {
118            // check answers
119            if (is_array($foundvalues['answer'])) {
120                foreach ($foundvalues['answer'] as $aidx => $answervalue) {
121                    if (((strlen($answervalue)) == 0) && (strlen($foundvalues['imagename'][$aidx]) == 0)) {
122                        $this->setAlert($lng->txt("msg_input_is_required"));
123                        return false;
124                    }
125                }
126            }
127
128            // check correctness
129            if (!isset($foundvalues['correctness']) || count($foundvalues['correctness']) < count($foundvalues['answer'])) {
130                $this->setAlert($lng->txt("msg_input_is_required"));
131                return false;
132            }
133
134            if (!$this->checkUploads($foundvalues)) {
135                return false;
136            }
137        } else {
138            $this->setAlert($lng->txt("msg_input_is_required"));
139            return false;
140        }
141
142        return $this->checkSubItemsInput();
143    }
144
145    /**
146     * @param $a_tpl ilTemplate
147     */
148    public function insert($a_tpl)
149    {
150        $tpl = new ilTemplate("tpl.prop_kprimchoicewizardinput.html", true, true, "Modules/TestQuestionPool");
151
152        foreach ($this->values as $value) {
153            /**
154             * @var ilAssKprimChoiceAnswer $value
155             */
156
157            if ($this->getSingleline()) {
158                if (!$this->hideImages) {
159                    if (strlen($value->getImageFile())) {
160                        $imagename = $value->getImageWebPath();
161
162                        if (($this->getSingleline()) && ($this->qstObject->getThumbSize())) {
163                            if (@file_exists($value->getThumbFsPath())) {
164                                $imagename = $value->getThumbWebPath();
165                            }
166                        }
167
168                        $tpl->setCurrentBlock('image');
169                        $tpl->setVariable('SRC_IMAGE', $imagename);
170                        $tpl->setVariable('IMAGE_NAME', $value->getImageFile());
171                        $tpl->setVariable('ALT_IMAGE', ilUtil::prepareFormOutput($value->getAnswertext()));
172                        $tpl->setVariable("TXT_DELETE_EXISTING", $this->lng->txt("delete_existing_file"));
173                        $tpl->setVariable("IMAGE_ROW_NUMBER", $value->getPosition());
174                        $tpl->setVariable("IMAGE_POST_VAR", $this->getPostVar());
175                        $tpl->parseCurrentBlock();
176                    }
177                    $tpl->setCurrentBlock('addimage');
178                    $tpl->setVariable("IMAGE_BROWSE", $this->lng->txt('select_file'));
179                    $tpl->setVariable("IMAGE_ID", $this->getPostVar() . "[image][{$value->getPosition()}]");
180                    $tpl->setVariable("IMAGE_SUBMIT", $this->lng->txt("upload"));
181                    $tpl->setVariable("IMAGE_ROW_NUMBER", $value->getPosition());
182                    $tpl->setVariable("IMAGE_POST_VAR", $this->getPostVar());
183                    $tpl->parseCurrentBlock();
184                }
185
186                $tpl->setCurrentBlock("prop_text_propval");
187                $tpl->setVariable("PROPERTY_VALUE", ilUtil::prepareFormOutput($value->getAnswertext()));
188                $tpl->parseCurrentBlock();
189
190                $tpl->setCurrentBlock('singleline');
191                $tpl->setVariable("SIZE", $this->getSize());
192                $tpl->setVariable("SINGLELINE_ID", $this->getPostVar() . "[answer][{$value->getPosition()}]");
193                $tpl->setVariable("SINGLELINE_ROW_NUMBER", $value->getPosition());
194                $tpl->setVariable("SINGLELINE_POST_VAR", $this->getPostVar());
195                $tpl->setVariable("MAXLENGTH", $this->getMaxLength());
196                if ($this->getDisabled()) {
197                    $tpl->setVariable("DISABLED_SINGLELINE", " disabled=\"disabled\"");
198                }
199                $tpl->parseCurrentBlock();
200            } elseif (!$this->getSingleline()) {
201                $tpl->setCurrentBlock('multiline');
202                $tpl->setVariable("PROPERTY_VALUE", ilUtil::prepareFormOutput($value->getAnswertext()));
203                $tpl->setVariable("MULTILINE_ID", $this->getPostVar() . "[answer][{$value->getPosition()}]");
204                $tpl->setVariable("MULTILINE_ROW_NUMBER", $value->getPosition());
205                $tpl->setVariable("MULTILINE_POST_VAR", $this->getPostVar());
206                if ($this->getDisabled()) {
207                    $tpl->setVariable("DISABLED_MULTILINE", " disabled=\"disabled\"");
208                }
209                $tpl->parseCurrentBlock();
210            }
211            if ($this->getAllowMove()) {
212                $tpl->setCurrentBlock("move");
213                $tpl->setVariable("CMD_UP", "cmd[up" . $this->getFieldId() . "][{$value->getPosition()}]");
214                $tpl->setVariable("CMD_DOWN", "cmd[down" . $this->getFieldId() . "][{$value->getPosition()}]");
215                $tpl->setVariable("UP_ID", "up_{$this->getPostVar()}[{$value->getPosition()}]");
216                $tpl->setVariable("DOWN_ID", "down_{$this->getPostVar()}[{$value->getPosition()}]");
217                $tpl->setVariable("UP_BUTTON", ilGlyphGUI::get(ilGlyphGUI::UP));
218                $tpl->setVariable("DOWN_BUTTON", ilGlyphGUI::get(ilGlyphGUI::DOWN));
219                $tpl->parseCurrentBlock();
220            }
221
222            $tpl->setCurrentBlock("row");
223
224            $tpl->setVariable("POST_VAR", $this->getPostVar());
225            $tpl->setVariable("ROW_NUMBER", $value->getPosition());
226            $tpl->setVariable("ID", $this->getPostVar() . "[answer][{$value->getPosition()}]");
227
228            $tpl->setVariable(
229                "CORRECTNESS_TRUE_ID",
230                $this->getPostVar() . "[correctness][{$value->getPosition()}][true]"
231            );
232            $tpl->setVariable(
233                "CORRECTNESS_FALSE_ID",
234                $this->getPostVar() . "[correctness][{$value->getPosition()}][false]"
235            );
236            $tpl->setVariable("CORRECTNESS_TRUE_VALUE", 1);
237            $tpl->setVariable("CORRECTNESS_FALSE_VALUE", 0);
238
239            if ($value->getCorrectness() !== null) {
240                if ($value->getCorrectness()) {
241                    $tpl->setVariable('CORRECTNESS_TRUE_SELECTED', ' checked="checked"');
242                } else {
243                    $tpl->setVariable('CORRECTNESS_FALSE_SELECTED', ' checked="checked"');
244                }
245            }
246
247            if ($this->getDisabled()) {
248                $tpl->setVariable("DISABLED_CORRECTNESS", " disabled=\"disabled\"");
249            }
250
251            $tpl->parseCurrentBlock();
252        }
253
254        if ($this->getSingleline()) {
255            if (!$this->hideImages) {
256                if (is_array($this->getSuffixes())) {
257                    $suff_str = $delim = "";
258                    foreach ($this->getSuffixes() as $suffix) {
259                        $suff_str .= $delim . "." . $suffix;
260                        $delim = ", ";
261                    }
262                    $tpl->setCurrentBlock('allowed_image_suffixes');
263                    $tpl->setVariable("TXT_ALLOWED_SUFFIXES", $this->lng->txt("file_allowed_suffixes") . " " . $suff_str);
264                    $tpl->parseCurrentBlock();
265                }
266
267                $tpl->setCurrentBlock("image_heading");
268                $tpl->setVariable("ANSWER_IMAGE", $this->lng->txt('answer_image'));
269                $tpl->setVariable("TXT_MAX_SIZE", ilUtil::getFileSizeInfo());
270                $tpl->parseCurrentBlock();
271            }
272        }
273
274        foreach ($this->qstObject->getValidOptionLabels() as $optionLabel) {
275            if ($this->qstObject->isCustomOptionLabel($optionLabel)) {
276                continue;
277            }
278
279            $tpl->setCurrentBlock('option_label_translations');
280            $tpl->setVariable('OPTION_LABEL', $optionLabel);
281            $tpl->setVariable('TRANSLATION_TRUE', $this->qstObject->getTrueOptionLabelTranslation($this->lng, $optionLabel));
282            $tpl->setVariable('TRANSLATION_FALSE', $this->qstObject->getFalseOptionLabelTranslation($this->lng, $optionLabel));
283            $tpl->parseCurrentBlock();
284        }
285
286        $tpl->setVariable("ELEMENT_ID", $this->getPostVar());
287        $tpl->setVariable("DELETE_IMAGE_HEADER", $this->lng->txt('delete_image_header'));
288        $tpl->setVariable("DELETE_IMAGE_QUESTION", $this->lng->txt('delete_image_question'));
289        $tpl->setVariable("ANSWER_TEXT", $this->lng->txt('answer_text'));
290
291        $tpl->setVariable("OPTIONS_TEXT", $this->lng->txt('options'));
292
293        // winzards input column label values will be updated on document ready js
294        //$tpl->setVariable("TRUE_TEXT", $this->qstObject->getTrueOptionLabelTranslation($this->lng, $this->qstObject->getOptionLabel()));
295        //$tpl->setVariable("FALSE_TEXT", $this->qstObject->getFalseOptionLabelTranslation($this->lng, $this->qstObject->getOptionLabel()));
296
297        $a_tpl->setCurrentBlock("prop_generic");
298        $a_tpl->setVariable("PROP_GENERIC", $tpl->get());
299        $a_tpl->parseCurrentBlock();
300
301        include_once "./Services/YUI/classes/class.ilYuiUtil.php";
302        $this->tpl->addJavascript("./Services/Form/js/ServiceFormWizardInput.js");
303        $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/kprimchoicewizard.js");
304        $this->tpl->addJavascript('Modules/TestQuestionPool/js/ilAssKprimChoice.js');
305    }
306
307    public function checkUploads($foundvalues)
308    {
309        if (is_array($_FILES) && count($_FILES) && $this->getSingleline()) {
310            if (!$this->hideImages) {
311                if (is_array($_FILES[$this->getPostVar()]['error']['image'])) {
312                    foreach ($_FILES[$this->getPostVar()]['error']['image'] as $index => $error) {
313                        // error handling
314                        if ($error > 0) {
315                            switch ($error) {
316                                case UPLOAD_ERR_INI_SIZE:
317                                    $this->setAlert($this->lng->txt("form_msg_file_size_exceeds"));
318                                    return false;
319                                    break;
320
321                                case UPLOAD_ERR_FORM_SIZE:
322                                    $this->setAlert($this->lng->txt("form_msg_file_size_exceeds"));
323                                    return false;
324                                    break;
325
326                                case UPLOAD_ERR_PARTIAL:
327                                    $this->setAlert($this->lng->txt("form_msg_file_partially_uploaded"));
328                                    return false;
329                                    break;
330
331                                case UPLOAD_ERR_NO_FILE:
332                                    if ($this->getRequired() && !$this->isIgnoreMissingUploadsEnabled()) {
333                                        if ((!strlen($foundvalues['imagename'][$index])) && (!strlen($foundvalues['answer'][$index]))) {
334                                            $this->setAlert($this->lng->txt("form_msg_file_no_upload"));
335                                            return false;
336                                        }
337                                    }
338                                    break;
339
340                                case UPLOAD_ERR_NO_TMP_DIR:
341                                    $this->setAlert($this->lng->txt("form_msg_file_missing_tmp_dir"));
342                                    return false;
343                                    break;
344
345                                case UPLOAD_ERR_CANT_WRITE:
346                                    $this->setAlert($this->lng->txt("form_msg_file_cannot_write_to_disk"));
347                                    return false;
348                                    break;
349
350                                case UPLOAD_ERR_EXTENSION:
351                                    $this->setAlert($this->lng->txt("form_msg_file_upload_stopped_ext"));
352                                    return false;
353                                    break;
354                            }
355                        }
356                    }
357                } else {
358                    if ($this->getRequired()) {
359                        $this->setAlert($this->lng->txt("form_msg_file_no_upload"));
360                        return false;
361                    }
362                }
363
364                if (is_array($_FILES[$this->getPostVar()]['tmp_name']['image'])) {
365                    foreach ($_FILES[$this->getPostVar()]['tmp_name']['image'] as $index => $tmpname) {
366                        $filename = $_FILES[$this->getPostVar()]['name']['image'][$index];
367                        $filename_arr = pathinfo($filename);
368                        $suffix = $filename_arr["extension"];
369                        $mimetype = $_FILES[$this->getPostVar()]['type']['image'][$index];
370                        $size_bytes = $_FILES[$this->getPostVar()]['size']['image'][$index];
371                        // check suffixes
372                        if (strlen($tmpname) && is_array($this->getSuffixes())) {
373                            if (!in_array(strtolower($suffix), $this->getSuffixes())) {
374                                $this->setAlert($this->lng->txt("form_msg_file_wrong_file_type"));
375                                return false;
376                            }
377                        }
378                    }
379                }
380
381                if (is_array($_FILES[$this->getPostVar()]['tmp_name']['image'])) {
382                    foreach ($_FILES[$this->getPostVar()]['tmp_name']['image'] as $index => $tmpname) {
383                        if ($_FILES[$this->getPostVar()]['error']['image'][$index] > 0) {
384                            continue;
385                        }
386
387                        $mimetype = ilObjMediaObject::getMimeType($tmpname);
388
389                        if (!preg_match("/^image/", $mimetype)) {
390                            $_FILES[$this->getPostVar()]['error']['image'][$index] = self::CUSTOM_UPLOAD_ERR;
391                            $this->setAlert($this->lng->txt("form_msg_file_wrong_mime_type"));
392                            return false;
393                        }
394                    }
395                }
396
397
398                if (is_array($_FILES[$this->getPostVar()]['tmp_name']['image'])) {
399                    foreach ($_FILES[$this->getPostVar()]['tmp_name']['image'] as $index => $tmpname) {
400                        $filename = $_FILES[$this->getPostVar()]['name']['image'][$index];
401                        $filename_arr = pathinfo($filename);
402                        $suffix = $filename_arr["extension"];
403                        $mimetype = $_FILES[$this->getPostVar()]['type']['image'][$index];
404                        $size_bytes = $_FILES[$this->getPostVar()]['size']['image'][$index];
405                        // virus handling
406                        if (strlen($tmpname)) {
407                            $vir = ilUtil::virusHandling($tmpname, $filename);
408                            if ($vir[0] == false) {
409                                $_FILES[$this->getPostVar()]['error']['image'][$index] = self::CUSTOM_UPLOAD_ERR;
410                                $this->setAlert($this->lng->txt("form_msg_file_virus_found") . "<br />" . $vir[1]);
411                                return false;
412                            }
413                        }
414                    }
415                }
416            }
417        }
418
419        return true;
420    }
421
422    public function collectValidFiles()
423    {
424        foreach ($_FILES[$this->getPostVar()]['error']['image'] as $index => $err) {
425            if ($err > 0) {
426                continue;
427            }
428
429            $this->files[$index] = array(
430                'position' => $index,
431                'tmp_name' => $_FILES[$this->getPostVar()]['tmp_name']['image'][$index],
432                'name' => $_FILES[$this->getPostVar()]['name']['image'][$index],
433                'type' => $_FILES[$this->getPostVar()]['type']['image'][$index],
434                'size' => $_FILES[$this->getPostVar()]['size']['image'][$index]
435            );
436        }
437    }
438}
439