1 | <?php |
||
2 | |||
3 | /* For licensing terms, see /license.txt */ |
||
4 | |||
5 | use ChamiloSession as Session; |
||
6 | |||
7 | /** |
||
8 | * UniqueAnswerImage. |
||
9 | * |
||
10 | * @author Angel Fernando Quiroz Campos <[email protected]> |
||
11 | */ |
||
12 | class UniqueAnswerImage extends UniqueAnswer |
||
13 | { |
||
14 | public $typePicture = 'uaimg.png'; |
||
15 | public $explanationLangVar = 'UniqueAnswerImage'; |
||
16 | |||
17 | /** |
||
18 | * UniqueAnswerImage constructor. |
||
19 | */ |
||
20 | public function __construct() |
||
21 | { |
||
22 | parent::__construct(); |
||
23 | $this->type = UNIQUE_ANSWER_IMAGE; |
||
24 | $this->isContent = $this->getIsContent(); |
||
25 | } |
||
26 | |||
27 | /** |
||
28 | * {@inheritdoc} |
||
29 | * |
||
30 | * @throws Exception |
||
31 | */ |
||
32 | public function createAnswersForm($form) |
||
33 | { |
||
34 | $objExercise = Session::read('objExercise'); |
||
35 | $editorConfig = [ |
||
36 | 'ToolbarSet' => 'TestProposedAnswer', |
||
37 | 'Width' => '100%', |
||
38 | 'Height' => '125', |
||
39 | ]; |
||
40 | |||
41 | //this line defines how many questions by default appear when creating a choice question |
||
42 | // The previous default value was 2. See task #1759. |
||
43 | $numberAnswers = isset($_POST['nb_answers']) ? (int) $_POST['nb_answers'] : 4; |
||
44 | $numberAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); |
||
45 | |||
46 | $feedbackTitle = ''; |
||
47 | switch ($objExercise->getFeedbackType()) { |
||
48 | case EXERCISE_FEEDBACK_TYPE_DIRECT: |
||
49 | // Scenario |
||
50 | $commentTitle = '<th width="20%">'.get_lang('Comment').'</th>'; |
||
51 | $feedbackTitle = '<th width="20%">'.get_lang('Scenario').'</th>'; |
||
52 | break; |
||
53 | case EXERCISE_FEEDBACK_TYPE_POPUP: |
||
54 | $commentTitle = '<th width="20%">'.get_lang('Comment').'</th>'; |
||
55 | break; |
||
56 | default: |
||
57 | $commentTitle = '<th width="40%">'.get_lang('Comment').'</th>'; |
||
58 | break; |
||
59 | } |
||
60 | |||
61 | $html = '<div class="alert alert-success" role="alert">'. |
||
62 | get_lang('UniqueAnswerImagePreferredSize200x150').'</div>'; |
||
63 | |||
64 | $zoomOptions = api_get_configuration_value('quiz_image_zoom'); |
||
65 | if (isset($zoomOptions['options'])) { |
||
66 | $finderFolder = api_get_path(WEB_PATH).'vendor/studio-42/elfinder/'; |
||
67 | $html .= '<!-- elFinder CSS (REQUIRED) -->'; |
||
68 | $html .= '<link rel="stylesheet" type="text/css" media="screen" |
||
69 | href="'.$finderFolder.'css/elfinder.full.css">'; |
||
70 | $html .= '<link rel="stylesheet" type="text/css" media="screen" href="'.$finderFolder.'css/theme.css">'; |
||
71 | $html .= '<!-- elFinder JS (REQUIRED) -->'; |
||
72 | $html .= '<script type="text/javascript" src="'.$finderFolder.'js/elfinder.full.js"></script>'; |
||
73 | $html .= '<!-- elFinder translation (OPTIONAL) -->'; |
||
74 | $language = 'en'; |
||
75 | $platformLanguage = api_get_interface_language(); |
||
76 | $iso = api_get_language_isocode($platformLanguage); |
||
77 | $filePart = "vendor/studio-42/elfinder/js/i18n/elfinder.$iso.js"; |
||
78 | $file = api_get_path(SYS_PATH).$filePart; |
||
79 | $includeFile = ''; |
||
80 | if (file_exists($file)) { |
||
81 | $includeFile = '<script type="text/javascript" src="'.api_get_path(WEB_PATH).$filePart.'"></script>'; |
||
82 | $language = $iso; |
||
83 | } |
||
84 | $html .= $includeFile; |
||
85 | |||
86 | $html .= '<script type="text/javascript" charset="utf-8"> |
||
87 | $(function() { |
||
88 | $(".add_img_link").on("click", function(e){ |
||
89 | e.preventDefault(); |
||
90 | e.stopPropagation(); |
||
91 | |||
92 | var name = $(this).prop("name"); |
||
93 | var id = parseInt(name.match(/[0-9]+/)); |
||
94 | |||
95 | $([document.documentElement, document.body]).animate({ |
||
96 | scrollTop: $("#elfinder").offset().top |
||
97 | }, 1000); |
||
98 | |||
99 | var elf = $("#elfinder").elfinder({ |
||
100 | url : "'.api_get_path(WEB_LIBRARY_PATH).'elfinder/connectorAction.php?'.api_get_cidreq().'", |
||
101 | getFileCallback: function(file) { |
||
102 | var filePath = file; //file contains the relative url. |
||
103 | var imageZoom = filePath.url; |
||
104 | var iname = "answer["+id+"]"; |
||
105 | |||
106 | CKEDITOR.instances[iname].insertHtml(\' |
||
107 | <img |
||
108 | id="zoom_picture" |
||
109 | class="zoom_picture" |
||
110 | src="\'+imageZoom+\'" |
||
111 | data-zoom-image="\'+imageZoom+\'" |
||
112 | width="200px" |
||
113 | height="150px" |
||
114 | />\'); |
||
115 | |||
116 | $("#elfinder").elfinder("destroy"); //close the window after image is selected |
||
117 | }, |
||
118 | startPathHash: "l2_Lw", // Sets the course driver as default |
||
119 | resizable: false, |
||
120 | lang: "'.$language.'" |
||
121 | }).elfinder("instance"+id); |
||
122 | }); |
||
123 | }); |
||
124 | </script>'; |
||
125 | $html .= '<div id="elfinder"></div>'; |
||
126 | } |
||
127 | |||
128 | $html .= '<table class="table table-striped table-hover"> |
||
129 | <thead> |
||
130 | <tr style="text-align: center;"> |
||
131 | <th width="10">'.get_lang('Number').'</th> |
||
132 | <th>'.get_lang('True').'</th> |
||
133 | <th>'.get_lang('Answer').'</th> |
||
134 | '.$commentTitle.' |
||
135 | '.$feedbackTitle.' |
||
136 | <th width="15">'.get_lang('Weighting').'</th> |
||
137 | </tr> |
||
138 | </thead> |
||
139 | <tbody>'; |
||
140 | |||
141 | $form->addHeader(get_lang('Answers')); |
||
142 | $form->addHtml($html); |
||
143 | |||
144 | $defaults = []; |
||
145 | $correct = 0; |
||
146 | |||
147 | if (!empty($this->iid)) { |
||
148 | $answer = new Answer($this->iid); |
||
149 | $answer->read(); |
||
150 | |||
151 | if ($answer->nbrAnswers > 0 && !$form->isSubmitted()) { |
||
152 | $numberAnswers = $answer->nbrAnswers; |
||
153 | } |
||
154 | } |
||
155 | |||
156 | $form->addElement('hidden', 'nb_answers'); |
||
157 | |||
158 | //Feedback SELECT |
||
159 | $questionList = $objExercise->selectQuestionList(); |
||
160 | $selectQuestion = []; |
||
161 | $selectQuestion[0] = get_lang('SelectTargetQuestion'); |
||
162 | |||
163 | if (is_array($questionList)) { |
||
164 | foreach ($questionList as $key => $questionid) { |
||
165 | //To avoid warning messages |
||
166 | if (!is_numeric($questionid)) { |
||
167 | continue; |
||
168 | } |
||
169 | |||
170 | $question = Question::read($questionid); |
||
171 | $questionTitle = strip_tags($question->selectTitle()); |
||
172 | $selectQuestion[$questionid] = "Q$key: $questionTitle"; |
||
173 | } |
||
174 | } |
||
175 | |||
176 | $selectQuestion[-1] = get_lang('ExitTest'); |
||
177 | |||
178 | $list = new LearnpathList(api_get_user_id()); |
||
179 | $flatList = $list->get_flat_list(); |
||
180 | $selectLpId = []; |
||
181 | $selectLpId[0] = get_lang('SelectTargetLP'); |
||
182 | |||
183 | foreach ($flatList as $id => $details) { |
||
184 | $selectLpId[$id] = cut($details['lp_name'], 20); |
||
185 | } |
||
186 | |||
187 | $tempScenario = []; |
||
188 | if ($numberAnswers < 1) { |
||
189 | $numberAnswers = 1; |
||
190 | echo Display::return_message(get_lang('YouHaveToCreateAtLeastOneAnswer')); |
||
191 | } |
||
192 | |||
193 | for ($i = 1; $i <= $numberAnswers; $i++) { |
||
194 | $form->addHtml('<tr>'); |
||
195 | if (isset($answer) && is_object($answer)) { |
||
196 | if ($answer->correct[$i]) { |
||
197 | $correct = $i; |
||
198 | } |
||
199 | |||
200 | $defaults['answer['.$i.']'] = $answer->answer[$i]; |
||
201 | $defaults['comment['.$i.']'] = $answer->comment[$i]; |
||
202 | $defaults['weighting['.$i.']'] = float_format( |
||
203 | $answer->weighting[$i], |
||
204 | 1 |
||
205 | ); |
||
206 | |||
207 | $itemList = explode('@@', $answer->destination[$i]); |
||
208 | |||
209 | $try = $itemList[0]; |
||
210 | $lp = $itemList[1]; |
||
211 | $listDestination = $itemList[2]; |
||
212 | $url = $itemList[3]; |
||
213 | |||
214 | $tryResult = 0; |
||
215 | if (0 != $try) { |
||
216 | $tryResult = 1; |
||
217 | } |
||
218 | |||
219 | $urlResult = ''; |
||
220 | if (0 != $url) { |
||
221 | $urlResult = $url; |
||
222 | } |
||
223 | |||
224 | $tempScenario['url'.$i] = $urlResult; |
||
225 | $tempScenario['try'.$i] = $tryResult; |
||
226 | $tempScenario['lp'.$i] = $lp; |
||
227 | $tempScenario['destination'.$i] = $listDestination; |
||
228 | } else { |
||
229 | $defaults['answer[1]'] = get_lang('DefaultUniqueAnswer1'); |
||
230 | $defaults['weighting[1]'] = 10; |
||
231 | $defaults['answer[2]'] = get_lang('DefaultUniqueAnswer2'); |
||
232 | $defaults['weighting[2]'] = 0; |
||
233 | |||
234 | $tempScenario['destination'.$i] = ['0']; |
||
235 | $tempScenario['lp'.$i] = ['0']; |
||
236 | } |
||
237 | |||
238 | $defaults['scenario'] = $tempScenario; |
||
239 | $renderer = $form->defaultRenderer(); |
||
240 | $renderer->setElementTemplate( |
||
241 | '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', |
||
242 | 'correct' |
||
243 | ); |
||
244 | $renderer->setElementTemplate( |
||
245 | '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', |
||
246 | 'counter['.$i.']' |
||
247 | ); |
||
248 | $renderer->setElementTemplate( |
||
249 | '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}'. |
||
250 | (isset($zoomOptions['options']) ? |
||
251 | '<br><div class="form-group "> |
||
252 | <label for="question_admin_form_btn_add_img['.$i.']" class="col-sm-2 control-label"></label> |
||
253 | <div class="col-sm-8"> |
||
254 | <button class="add_img_link btn btn-info btn-sm" |
||
255 | name="btn_add_img['.$i.']" |
||
256 | type="submit" |
||
257 | id="question_admin_form_btn_add_img['.$i.']"> |
||
258 | <em class="fa fa-plus"></em> '.get_lang('AddImageWithZoom').' |
||
259 | </button> |
||
260 | </div> |
||
261 | <div class="col-sm-2"></div> |
||
262 | </div>' : '').'</td>', |
||
263 | 'answer['.$i.']' |
||
264 | ); |
||
265 | $renderer->setElementTemplate( |
||
266 | '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', |
||
267 | 'comment['.$i.']' |
||
268 | ); |
||
269 | $renderer->setElementTemplate( |
||
270 | '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', |
||
271 | 'weighting['.$i.']' |
||
272 | ); |
||
273 | |||
274 | $answerNumber = $form->addElement('text', 'counter['.$i.']', null, ' value = "'.$i.'"'); |
||
275 | $answerNumber->freeze(); |
||
276 | |||
277 | $form->addElement('radio', 'correct', null, null, $i, 'class="checkbox"'); |
||
278 | $form->addHtmlEditor('answer['.$i.']', null, null, false, $editorConfig); |
||
279 | |||
280 | $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required'); |
||
281 | |||
282 | switch ($objExercise->getFeedbackType()) { |
||
283 | case EXERCISE_FEEDBACK_TYPE_DIRECT: |
||
284 | $this->setDirectOptions($i, $form, $renderer, $selectLpId, $selectQuestion); |
||
285 | break; |
||
286 | case EXERCISE_FEEDBACK_TYPE_POPUP: |
||
287 | default: |
||
288 | $form->addHtmlEditor('comment['.$i.']', null, null, false, $editorConfig); |
||
289 | break; |
||
290 | } |
||
291 | |||
292 | $form->addText('weighting['.$i.']', null, null, ['class' => 'col-md-1', 'value' => '0']); |
||
293 | $form->addHtml('</tr>'); |
||
294 | } |
||
295 | |||
296 | $form->addHtml('</tbody>'); |
||
297 | $form->addHtml('</table>'); |
||
298 | |||
299 | global $text; |
||
300 | $buttonGroup = []; |
||
301 | if ($objExercise->edit_exercise_in_lp == true || |
||
302 | (empty($this->exerciseList) && empty($objExercise->iid)) |
||
303 | ) { |
||
304 | //setting the save button here and not in the question class.php |
||
305 | $buttonGroup[] = $form->addButtonDelete(get_lang('LessAnswer'), 'lessAnswers', true); |
||
306 | $buttonGroup[] = $form->addButtonCreate(get_lang('PlusAnswer'), 'moreAnswers', true); |
||
307 | $buttonGroup[] = $form->addButtonSave($text, 'submitQuestion', true); |
||
308 | $form->addGroup($buttonGroup); |
||
309 | } |
||
310 | |||
311 | // We check the first radio button to be sure a radio button will be check |
||
312 | if (0 == $correct) { |
||
313 | $correct = 1; |
||
314 | } |
||
315 | |||
316 | $defaults['correct'] = $correct; |
||
317 | |||
318 | if (!empty($this->iid)) { |
||
319 | $form->setDefaults($defaults); |
||
320 | } else { |
||
321 | if (1 == $this->isContent) { |
||
322 | // Default sample content. |
||
323 | $form->setDefaults($defaults); |
||
324 | } else { |
||
325 | $form->setDefaults(['correct' => 1]); |
||
326 | } |
||
327 | } |
||
328 | |||
329 | $form->setConstants(['nb_answers' => $numberAnswers]); |
||
330 | } |
||
331 | |||
332 | /** |
||
333 | * {@inheritdoc} |
||
334 | */ |
||
335 | public function processAnswersCreation($form, $exercise) |
||
336 | { |
||
337 | $questionWeighting = $nbrGoodAnswers = 0; |
||
338 | $correct = $form->getSubmitValue('correct'); |
||
339 | $objAnswer = new Answer($this->iid); |
||
340 | $numberAnswers = $form->getSubmitValue('nb_answers'); |
||
341 | |||
342 | for ($i = 1; $i <= $numberAnswers; $i++) { |
||
343 | $answer = trim(str_replace(['<p>', '</p>'], '', $form->getSubmitValue('answer['.$i.']'))); |
||
344 | $comment = trim(str_replace(['<p>', '</p>'], '', $form->getSubmitValue('comment['.$i.']'))); |
||
345 | $weighting = trim($form->getSubmitValue('weighting['.$i.']')); |
||
346 | |||
347 | $scenario = $form->getSubmitValue('scenario'); |
||
348 | |||
349 | //$listDestination = $form -> getSubmitValue('destination'.$i); |
||
350 | //$destinationStr = $form -> getSubmitValue('destination'.$i); |
||
351 | if (!empty($scenario)) { |
||
352 | $try = $scenario['try'.$i]; |
||
353 | $lp = $scenario['lp'.$i]; |
||
354 | $destination = $scenario['destination'.$i]; |
||
355 | $url = trim($scenario['url'.$i]); |
||
356 | } |
||
357 | |||
358 | /* |
||
359 | How we are going to parse the destination value |
||
360 | |||
361 | here we parse the destination value which is a string |
||
362 | 1@@3@@2;4;4;@@http://www.chamilo.org |
||
363 | |||
364 | where: try_again@@lp_id@@selected_questions@@url |
||
365 | |||
366 | try_again = is 1 || 0 |
||
367 | lp_id = id of a learning path (0 if dont select) |
||
368 | selected_questions= ids of questions |
||
369 | url= an url |
||
370 | |||
371 | $destinationStr=''; |
||
372 | foreach ($listDestination as $destination_id) |
||
373 | { |
||
374 | $destinationStr.=$destination_id.';'; |
||
375 | } */ |
||
376 | $goodAnswer = $correct == $i ? true : false; |
||
377 | if ($goodAnswer) { |
||
378 | $nbrGoodAnswers++; |
||
379 | $weighting = abs($weighting); |
||
380 | |||
381 | if ($weighting > 0) { |
||
382 | $questionWeighting += $weighting; |
||
383 | } |
||
384 | } |
||
385 | |||
386 | if (empty($try)) { |
||
387 | $try = 0; |
||
388 | } |
||
389 | |||
390 | if (empty($lp)) { |
||
391 | $lp = 0; |
||
392 | } |
||
393 | |||
394 | if (empty($destination)) { |
||
395 | $destination = 0; |
||
396 | } |
||
397 | |||
398 | if ($url == '') { |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Loading history...
|
|||
399 | $url = 0; |
||
400 | } |
||
401 | |||
402 | //1@@1;2;@@2;4;4;@@http://www.chamilo.org |
||
403 | $dest = $try.'@@'.$lp.'@@'.$destination.'@@'.$url; |
||
404 | |||
405 | $objAnswer->createAnswer( |
||
406 | $answer, |
||
407 | $goodAnswer, |
||
408 | $comment, |
||
409 | $weighting, |
||
410 | $i, |
||
411 | null, |
||
412 | null, |
||
413 | $dest |
||
414 | ); |
||
415 | } |
||
416 | |||
417 | // saves the answers into the data base |
||
418 | $objAnswer->save(); |
||
419 | |||
420 | // sets the total weighting of the question |
||
421 | $this->updateWeighting($questionWeighting); |
||
422 | $this->save($exercise); |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * {@inheritdoc} |
||
427 | */ |
||
428 | public function return_header(Exercise $exercise, $counter = null, $score = []) |
||
429 | { |
||
430 | if ($exercise->showExpectedChoice()) { |
||
431 | $header = '<table class="'.$this->question_table_class.'"> |
||
432 | <tr> |
||
433 | <th>'.get_lang('Choice').'</th>'; |
||
434 | if ($exercise->showExpectedChoiceColumn()) { |
||
435 | $header .= '<th>'.get_lang('ExpectedChoice').'</th>'; |
||
436 | } |
||
437 | $header .= '<th>'.get_lang('Answer').'</th>'; |
||
438 | $header .= '<th>'.get_lang('Status').'</th>'; |
||
439 | if (false === $exercise->hideComment) { |
||
440 | $header .= '<th>'.get_lang('Comment').'</th>'; |
||
441 | } |
||
442 | $header .= '</tr>'; |
||
443 | } else { |
||
444 | $header = parent::return_header($exercise, $counter, $score); |
||
445 | } |
||
446 | |||
447 | return $header; |
||
448 | } |
||
449 | } |
||
450 |