19 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
51 $this->
object->loadFromDb(
$id);
60 $hasErrors = (!$always) ? $this->
editQuestion(
true) :
false;
74 $this->
object->flushMatchingPairs();
75 $this->
object->flushTerms();
76 $this->
object->flushDefinitions();
78 $uploads = $this->request->getProcessedUploads();
79 $allowed_mime_types = [
'image/jpeg',
'image/png',
'image/gif'];
81 if ($this->request->isset(
'terms')) {
82 $answers = $this->request->raw(
'terms')[
'answer'] ?? [];
83 $terms_image_names = $this->request->raw(
'terms')[
'imagename'] ?? [];
84 $terms_identifiers = $this->request->raw(
'terms')[
'identifier'] ?? [];
86 foreach ($answers as $index => $answer) {
87 $filename = $terms_image_names[$index] ??
'';
89 $upload_tmp_name = $this->request->getUploadFilename([
'terms',
'image'], $index);
91 if (isset($uploads[$upload_tmp_name]) && $uploads[$upload_tmp_name]->isOk() &&
92 in_array($uploads[$upload_tmp_name]->getMimeType(), $allowed_mime_types)) {
94 $name = $uploads[$upload_tmp_name]->getName();
95 if ($this->
object->setImageFile(
96 $uploads[$upload_tmp_name]->getPath(),
97 $this->
object->getEncryptedFilename($name)
99 $filename = $this->
object->getEncryptedFilename($name);
104 $this->
object->addTerm(
108 $terms_identifiers[$index] ?? 0
114 if ($this->request->isset(
'definitions')) {
115 $answers = $this->request->raw(
'definitions')[
'answer'] ?? [];
116 $definitions_image_names = $this->request->raw(
'definitions')[
'imagename'] ?? [];
117 $definitions_identifiers = $this->request->raw(
'definitions')[
'identifier'] ?? [];
119 foreach ($answers as $index => $answer) {
120 $filename = $definitions_image_names[$index] ??
'';
122 $upload_tmp_name = $this->request->getUploadFilename([
'definitions',
'image'], $index);
124 if (isset($uploads[$upload_tmp_name]) && $uploads[$upload_tmp_name]->isOk() &&
125 in_array($uploads[$upload_tmp_name]->getMimeType(), $allowed_mime_types)) {
127 $name = $uploads[$upload_tmp_name]->getName();
128 if ($this->
object->setImageFile(
129 $uploads[$upload_tmp_name]->getPath(),
130 $this->
object->getEncryptedFilename($name)
132 $filename = $this->
object->getEncryptedFilename($name);
136 $this->
object->addDefinition(
140 $definitions_identifiers[$index] ?? 0
146 if ($this->request->isset(
'pairs')) {
147 $points_of_pairs = $this->request->raw(
'pairs')[
'points'] ?? [];
148 $pair_terms = $this->request->raw(
'pairs')[
'term'] ?? [];
149 $pair_definitions = $this->request->raw(
'pairs')[
'definition'] ?? [];
151 foreach ($points_of_pairs as $index => $points) {
152 $term_id = $pair_terms[$index] ?? 0;
153 $definition_id = $pair_definitions[$index] ?? 0;
154 $this->
object->addMatchingPair(
155 $this->
object->getTermWithIdentifier($term_id),
156 $this->
object->getDefinitionWithIdentifier($definition_id),
157 (float) str_replace(
',',
'.', $points)
165 if (!$this->
object->getSelfAssessmentEditingMode()) {
166 $this->
object->setShuffle($_POST[
"shuffle"] ??
'0');
167 $this->
object->setShuffleMode($_POST[
"shuffle"] ??
'0');
169 $this->
object->setShuffle(1);
170 $this->
object->setShuffleMode(1);
172 $this->
object->setThumbGeometry($_POST[
"thumb_geometry"] ?? 0);
173 $this->
object->setMatchingMode($_POST[
'matching_mode']);
185 $position = key($_POST[
'cmd'][
'removeimageterms']);
186 $this->
object->removeTermImage($position);
199 $position = key($_POST[
'cmd'][
'removeimagedefinitions']);
200 $this->
object->removeDefinitionImage($position);
207 $position = key($_POST[
"cmd"][
"addterms"]);
208 $this->
object->insertTerm($position + 1);
215 $position = key($_POST[
"cmd"][
"removeterms"]);
216 $this->
object->deleteTerm($position);
223 $position = key($_POST[
"cmd"][
"adddefinitions"]);
224 $this->
object->insertDefinition($position + 1);
231 $position = key($_POST[
"cmd"][
"removedefinitions"]);
232 $this->
object->deleteDefinition($position);
239 $position = key($_POST[
"cmd"][
"addpairs"]);
240 $this->
object->insertMatchingPair($position + 1);
247 $position = key($_POST[
"cmd"][
"removepairs"]);
248 $this->
object->deleteMatchingPair($position);
258 $this->editForm = $form;
260 $form->setFormAction($this->
ctrl->getFormAction($this));
262 $form->setMultipart(
true);
263 $form->setTableWidth(
"100%");
264 $form->setId(
"matching");
274 $form->setValuesByPost();
275 $errors = !$form->checkInput();
276 $form->setValuesByPost();
279 $terms = $form->getItemByPostVar(
'terms');
280 $terms->setAlert($this->
lng->txt(
"msg_number_of_terms_too_low"));
281 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'form_input_not_valid'));
289 $this->tpl->setVariable(
"QUESTION_DATA", $form->getHTML());
296 return $this->
ctrl->getCmd() ==
'uploaddefinitions';
301 return $this->
ctrl->getCmd() ==
'uploadterms';
320 $numDefinitions = count($form->
getItemByPostVar(
'definitions')->getValues());
322 if ($numTerms >= $numDefinitions) {
332 if ($this->
object->getSelfAssessmentEditingMode()) {
337 return $value->withText(html_entity_decode($value->getText()));
340 $definitions->setRequired(
true);
341 $definitions->setQuestionObject($this->
object);
342 $definitions->setTextName($this->
lng->txt(
'definition_text'));
343 $definitions->setImageName($this->
lng->txt(
'definition_image'));
344 if (!count($this->
object->getDefinitions())) {
347 $definitionvalues = array_map($stripHtmlEntitesFromValues, $this->
object->getDefinitions());
348 $definitions->setValues($definitionvalues);
350 $definitions->checkInput();
355 if ($this->
object->getSelfAssessmentEditingMode()) {
358 $terms->setRequired(
true);
359 $terms->setQuestionObject($this->
object);
360 $terms->setTextName($this->
lng->txt(
'term_text'));
361 $terms->setImageName($this->
lng->txt(
'term_image'));
363 if (0 === count($this->
object->getTerms())) {
369 $termvalues = array_map($stripHtmlEntitesFromValues, $this->
object->getTerms());
370 $terms->setValues($termvalues);
372 $terms->checkInput();
378 $pairs->setTerms($this->
object->getTerms());
379 $pairs->setDefinitions($this->
object->getDefinitions());
380 if (count($this->
object->getMatchingPairs()) == 0) {
381 $this->
object->addMatchingPair($termvalues[0], $definitionvalues[0], 0);
384 $pairs->setPairs($this->
object->getMatchingPairs());
394 $hidden->setValue(
'');
397 if (!$this->
object->getSelfAssessmentEditingMode()) {
400 $shuffle_options = array(
401 0 => $this->
lng->txt(
"no"),
402 1 => $this->
lng->txt(
"matching_shuffle_terms_definitions"),
403 2 => $this->
lng->txt(
"matching_shuffle_terms"),
404 3 => $this->
lng->txt(
"matching_shuffle_definitions")
407 $shuffle->setValue($this->
object->getShuffleMode());
408 $shuffle->setRequired(
false);
412 $geometry->setValue($this->
object->getThumbGeometry());
413 $geometry->setRequired(
true);
414 $geometry->setMaxLength(6);
415 $geometry->setMinValue($this->
object->getMinimumThumbSize());
416 $geometry->setMaxValue($this->
object->getMaximumThumbSize());
417 $geometry->setSize(6);
418 $geometry->setInfo($this->
lng->txt(
'thumb_size_info'));
427 $this->
lng->txt(
'qpl_qst_inp_matching_mode_one_on_one'),
430 $mode->addOption($modeONEonONE);
433 $this->
lng->txt(
'qpl_qst_inp_matching_mode_all_on_all'),
436 $mode->addOption($modeALLonALL);
459 $graphicalOutput =
false,
460 $result_output =
false,
461 $show_question_only =
true,
462 $show_feedback =
false,
463 $show_correct_solution =
false,
464 $show_manual_scoring =
false,
465 $show_question_text =
true 468 $solutions = array();
469 if (($active_id > 0) && (!$show_correct_solution)) {
470 $solutions = $this->
object->getSolutionValues($active_id, $pass);
472 foreach ($this->
object->getMaximumScoringMatchingPairs() as $pair) {
473 $solutions[] = array(
474 "value1" => $pair->getTerm()->getIdentifier(),
475 "value2" => $pair->getDefinition()->getIdentifier(),
476 'points' => $pair->getPoints()
481 $user_solutions = $solutions;
482 $show_inline_feedback =
false;
491 $show_correct_solution,
492 $show_manual_scoring,
495 $show_inline_feedback,
500 mixed $user_solutions,
503 bool $graphical_output =
false,
504 bool $result_output =
false,
505 bool $show_question_only =
true,
506 bool $show_feedback =
false,
507 bool $show_correct_solution =
false,
508 bool $show_manual_scoring =
false,
509 bool $show_question_text =
true,
510 bool $show_autosave_title =
false,
511 bool $show_inline_feedback =
false,
513 $solutions = $user_solutions;
515 $template =
new ilTemplate(
"tpl.il_as_qpl_matching_output_solution.html",
true,
true,
"Modules/TestQuestionPool");
516 $solutiontemplate =
new ilTemplate(
"tpl.il_as_tst_solution_output.html",
true,
true,
"Modules/TestQuestionPool");
519 foreach ($solutions as $solution) {
520 $definition = $this->
object->getDefinitionWithIdentifier($solution[
'value2']);
521 $term = $this->
object->getTermWithIdentifier($solution[
'value1']);
522 $points = $solution[
'points'];
524 if (is_object($definition)) {
525 if (strlen($definition->getPicture())) {
526 if (strlen($definition->getText())) {
527 $template->setCurrentBlock(
'definition_image_text');
528 $template->setVariable(
532 $template->parseCurrentBlock();
536 $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $definition->getPicture()
539 $template->setCurrentBlock(
'definition_image');
540 $template->setVariable(
'ANSWER_IMAGE_URL', $answerImageSrc);
541 $template->setVariable(
544 $definition->getText()
547 $template->setVariable(
548 'ANSWER_IMAGE_TITLE',
550 $definition->getText()
553 $template->setVariable(
'URL_PREVIEW', $this->
object->getImagePathWeb() . $definition->getPicture());
554 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
556 $template->parseCurrentBlock();
558 $template->setCurrentBlock(
'definition_text');
560 $template->parseCurrentBlock();
563 if (is_object($term)) {
564 if (strlen($term->getPicture())) {
565 if (strlen($term->getText())) {
566 $template->setCurrentBlock(
'term_image_text');
568 $template->parseCurrentBlock();
572 $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $term->getPicture()
575 $template->setCurrentBlock(
'term_image');
576 $template->setVariable(
'ANSWER_IMAGE_URL', $answerImageSrc);
577 $template->setVariable(
583 $template->setVariable(
584 'ANSWER_IMAGE_TITLE',
589 $template->setVariable(
'URL_PREVIEW', $this->
object->getImagePathWeb() . $term->getPicture());
590 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
592 $template->parseCurrentBlock();
594 $template->setCurrentBlock(
'term_text');
596 $template->parseCurrentBlock();
600 if (($active_id > 0) && (!$show_correct_solution)) {
601 if ($graphical_output) {
604 foreach ($this->
object->getMatchingPairs() as $pair) {
614 $template->setCurrentBlock(
"icon_ok");
615 $template->setVariable(
"ICON_OK", $correctness_icon);
616 $template->parseCurrentBlock();
620 if ($result_output) {
621 $resulttext = ($points == 1) ?
"(%s " . $this->
lng->txt(
"point") .
")" :
"(%s " . $this->
lng->txt(
"points") .
")";
622 $template->setCurrentBlock(
"result_output");
623 $template->setVariable(
"RESULT_OUTPUT", sprintf($resulttext, $points));
624 $template->parseCurrentBlock();
627 $template->setCurrentBlock(
"row");
628 $template->setVariable(
"TEXT_MATCHES", $this->
lng->txt(
"matches"));
629 $template->parseCurrentBlock();
632 if ($show_question_text ==
true) {
633 $template->setVariable(
"QUESTIONTEXT", $this->
object->getQuestionForHTMLOutput());
636 $questionoutput = $template->get();
639 if ($show_feedback) {
642 $feedback .= strlen($fb) ? $fb :
'';
646 $feedback .= strlen($fb) ? $fb :
'';
648 if (strlen($feedback)) {
654 $solutiontemplate->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
658 $solutiontemplate->setVariable(
"SOLUTION_OUTPUT", $questionoutput);
660 $solutionoutput = $solutiontemplate->get();
661 if (!$show_question_only) {
665 return $solutionoutput;
668 public function getPreview($show_question_only =
false, $showInlineFeedback =
false): string
673 if ($DIC->http()->agent()->isMobile() || $DIC->http()->agent()->isIpad()) {
676 $this->tpl->addJavaScript(
'./node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js');
678 $this->tpl->addJavaScript(
'Modules/TestQuestionPool/js/ilMatchingQuestion.js');
679 $this->tpl->addOnLoadCode(
'ilMatchingQuestionInit();');
682 $template =
new ilTemplate(
"tpl.il_as_qpl_matching_output.html",
true,
true,
"Modules/TestQuestionPool");
684 foreach ($solutions as $defId => $terms) {
685 foreach ($terms as $termId) {
686 $template->setCurrentBlock(
"matching_data");
687 $template->setVariable(
"DEFINITION_ID", $defId);
688 $template->setVariable(
"TERM_ID", $termId);
689 $template->parseCurrentBlock();
694 $terms = $this->
object->getTerms();
695 $definitions = $this->
object->getDefinitions();
696 switch ($this->
object->getShuffleMode()) {
698 $terms = $this->
object->getShuffler()->transform($terms);
699 $definitions = $this->
object->getShuffler()->transform(
700 $this->
object->getShuffler()->transform($definitions)
704 $terms = $this->
object->getShuffler()->transform($terms);
707 $definitions = $this->
object->getShuffler()->transform($definitions);
713 foreach ($definitions as $definition) {
714 if (strlen($definition->getPicture())) {
715 $template->setCurrentBlock(
"definition_picture");
716 $template->setVariable(
"DEFINITION_ID", $definition->getIdentifier());
717 $template->setVariable(
"IMAGE_HREF", $this->
object->getImagePathWeb() . $definition->getPicture());
718 $thumbweb = $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $definition->getPicture();
719 $thumb = $this->
object->getImagePath() . $this->
object->getThumbPrefix() . $definition->getPicture();
720 if (!@file_exists($thumb)) {
721 $this->
object->rebuildThumbnails();
723 $template->setVariable(
"THUMBNAIL_HREF", $thumbweb);
724 $template->setVariable(
"THUMB_ALT", $this->
lng->txt(
"image"));
725 $template->setVariable(
"THUMB_TITLE", $this->
lng->txt(
"image"));
727 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
729 $template->parseCurrentBlock();
731 $template->setCurrentBlock(
"definition_text");
733 $template->parseCurrentBlock();
736 $template->setCurrentBlock(
"droparea");
737 $template->setVariable(
"ID_DROPAREA", $definition->getIdentifier());
738 $template->setVariable(
"QUESTION_ID", $this->
object->getId());
739 $template->parseCurrentBlock();
741 $template->setCurrentBlock(
"definition_data");
742 $template->setVariable(
"DEFINITION_ID", $definition->getIdentifier());
743 $template->parseCurrentBlock();
748 foreach ($terms as $term) {
749 if (strlen($term->getPicture())) {
750 $template->setCurrentBlock(
"term_picture");
751 $template->setVariable(
"TERM_ID", $term->getIdentifier());
752 $template->setVariable(
"IMAGE_HREF", $this->
object->getImagePathWeb() . $term->getPicture());
753 $thumbweb = $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $term->getPicture();
754 $thumb = $this->
object->getImagePath() . $this->
object->getThumbPrefix() . $term->getPicture();
755 if (!@file_exists($thumb)) {
756 $this->
object->rebuildThumbnails();
758 $template->setVariable(
"THUMBNAIL_HREF", $thumbweb);
759 $template->setVariable(
"THUMB_ALT", $this->
lng->txt(
"image"));
760 $template->setVariable(
"THUMB_TITLE", $this->
lng->txt(
"image"));
761 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
764 $template->parseCurrentBlock();
766 $template->setCurrentBlock(
"term_text");
768 $template->parseCurrentBlock();
770 $template->setCurrentBlock(
"draggable");
771 $template->setVariable(
"ID_DRAGGABLE", $term->getIdentifier());
772 $template->parseCurrentBlock();
774 $template->setCurrentBlock(
"term_data");
775 $template->setVariable(
"TERM_ID", $term->getIdentifier());
776 $template->parseCurrentBlock();
779 $template->setVariable(
'MATCHING_MODE', $this->
object->getMatchingMode());
781 $template->setVariable(
"RESET_BUTTON", $this->
lng->txt(
"reset_terms"));
783 $template->setVariable(
"QUESTIONTEXT", $this->
object->getQuestionForHTMLOutput());
785 $questionoutput = $template->get();
787 if (!$show_question_only) {
792 return $questionoutput;
800 protected function sortDefinitionsBySolution(array $solution, array $definitions): array
803 $handled_defintions = array();
804 foreach ($solution as $solution_values) {
805 $id = $solution_values[
'value2'];
806 if (!isset($handled_defintions[
$id])) {
807 $neworder[] = $this->
object->getDefinitionWithIdentifier($id);
808 $handled_defintions[
$id] =
$id;
812 foreach ($definitions as $definition) {
816 if (!isset($handled_defintions[$definition->getIdentifier()])) {
817 $neworder[] = $definition;
830 if ($DIC->http()->agent()->isMobile() || $DIC->http()->agent()->isIpad()) {
831 $files[] =
'./node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js';
834 $files[] =
'Modules/TestQuestionPool/js/ilMatchingQuestion.js';
840 public function getTestOutput($active_id, $pass, $is_postponed =
false, $user_post_solution =
false, $inlineFeedback =
false): string
844 if ($DIC->http()->agent()->isMobile() || $DIC->http()->agent()->isIpad()) {
847 $this->tpl->addJavaScript(
'./node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js');
849 $this->tpl->addJavaScript(
'Modules/TestQuestionPool/js/ilMatchingQuestion.js');
850 $this->tpl->addOnLoadCode(
'ilMatchingQuestionInit();');
853 $template =
new ilTemplate(
"tpl.il_as_qpl_matching_output.html",
true,
true,
"Modules/TestQuestionPool");
855 $solutions = array();
857 if (is_array($user_post_solution)) {
858 foreach ($user_post_solution[
'matching'][$this->
object->getId()] as $definition => $term) {
859 array_push($solutions, array(
"value1" => $term,
"value2" => $definition));
863 $solutions = $this->
object->getTestOutputSolutions($active_id, $pass);
868 foreach ($solutions as $idx => $solution_value) {
869 if (($solution_value[
'value2'] > -1) && ($solution_value[
'value1'] > -1)) {
870 $template->setCurrentBlock(
"matching_data");
871 $template->setVariable(
"TERM_ID", $solution_value[
'value1']);
872 $template->setVariable(
"DEFINITION_ID", $solution_value[
'value2']);
873 $template->parseCurrentBlock();
880 $terms = $this->
object->getTerms();
881 $definitions = $this->
object->getDefinitions();
882 switch ($this->
object->getShuffleMode()) {
884 $terms = $this->
object->getShuffler()->transform($terms);
885 if (count($solutions)) {
886 $definitions = $this->sortDefinitionsBySolution($solutions, $definitions);
888 $definitions = $this->
object->getShuffler()->transform(
889 $this->
object->getShuffler()->transform($definitions)
894 $terms = $this->
object->getShuffler()->transform($terms);
897 if (count($solutions)) {
898 $definitions = $this->sortDefinitionsBySolution($solutions, $definitions);
900 $definitions = $this->
object->getShuffler()->transform($definitions);
907 foreach ($definitions as $definition) {
908 if (strlen($definition->getPicture())) {
909 $template->setCurrentBlock(
"definition_picture");
910 $template->setVariable(
"DEFINITION_ID", $definition->getIdentifier());
911 $template->setVariable(
"IMAGE_HREF", $this->
object->getImagePathWeb() . $definition->getPicture());
912 $thumbweb = $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $definition->getPicture();
913 $thumb = $this->
object->getImagePath() . $this->
object->getThumbPrefix() . $definition->getPicture();
914 if (!@file_exists($thumb)) {
915 $this->
object->rebuildThumbnails();
917 $template->setVariable(
"THUMBNAIL_HREF", $thumbweb);
918 $template->setVariable(
"THUMB_ALT", $this->
lng->txt(
"image"));
919 $template->setVariable(
"THUMB_TITLE", $this->
lng->txt(
"image"));
921 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
923 $template->parseCurrentBlock();
925 $template->setCurrentBlock(
"definition_text");
927 $template->parseCurrentBlock();
930 $template->setCurrentBlock(
"droparea");
931 $template->setVariable(
"ID_DROPAREA", $definition->getIdentifier());
932 $template->setVariable(
"QUESTION_ID", $this->
object->getId());
933 $template->parseCurrentBlock();
935 $template->setCurrentBlock(
"definition_data");
936 $template->setVariable(
"DEFINITION_ID", $definition->getIdentifier());
937 $template->parseCurrentBlock();
942 foreach ($terms as $term) {
943 if (strlen($term->getPicture())) {
944 $template->setCurrentBlock(
"term_picture");
945 $template->setVariable(
"TERM_ID", $term->getIdentifier());
946 $template->setVariable(
"IMAGE_HREF", $this->
object->getImagePathWeb() . $term->getPicture());
947 $thumbweb = $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $term->getPicture();
948 $thumb = $this->
object->getImagePath() . $this->
object->getThumbPrefix() . $term->getPicture();
949 if (!@file_exists($thumb)) {
950 $this->
object->rebuildThumbnails();
952 $template->setVariable(
"THUMBNAIL_HREF", $thumbweb);
953 $template->setVariable(
"THUMB_ALT", $this->
lng->txt(
"image"));
954 $template->setVariable(
"THUMB_TITLE", $this->
lng->txt(
"image"));
955 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
958 $template->parseCurrentBlock();
960 $template->setCurrentBlock(
"term_text");
962 $template->parseCurrentBlock();
964 $template->setCurrentBlock(
"draggable");
965 $template->setVariable(
"ID_DRAGGABLE", $term->getIdentifier());
966 $template->parseCurrentBlock();
968 $template->setCurrentBlock(
'term_data');
969 $template->setVariable(
'TERM_ID', $term->getIdentifier());
970 $template->parseCurrentBlock();
973 $template->setVariable(
'MATCHING_MODE', $this->
object->getMatchingMode());
975 $template->setVariable(
"RESET_BUTTON", $this->
lng->txt(
"reset_terms"));
977 $template->setVariable(
"QUESTIONTEXT", $this->
object->getQuestionForHTMLOutput());
979 return $this->
outQuestionPage(
"", $is_postponed, $active_id, $template->get());
987 if ((!$_POST[
"title"]) or (!$_POST[
"author"]) or (!$_POST[
"question"])) {
995 $matches = array_values($this->
object->matchingpairs);
997 if (!$this->
object->feedbackOBJ->specificAnswerFeedbackExists()) {
1001 $feedback =
'<table class="test_specific_feedback"><tbody>';
1003 foreach ($matches as $idx => $ans) {
1004 if (!isset($userSolution[$ans->getDefinition()->getIdentifier()])) {
1008 if (!is_array($userSolution[$ans->getDefinition()->getIdentifier()])) {
1012 if (!in_array($ans->getTerm()->getIdentifier(), $userSolution[$ans->getDefinition()->getIdentifier()])) {
1016 $fb = $this->
object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
1021 $feedback .=
'<tr><td>"' . $ans->getDefinition()->getText() .
'" ' . $this->
lng->txt(
"matches") .
' "';
1022 $feedback .= $ans->getTerm()->getText() .
'"</td><td>';
1023 $feedback .= $fb .
'</td> </tr>';
1026 $feedback .=
'</tbody></table>';
1071 if (!($pair->getPoints() > 0)) {
1075 if (!is_object($term)) {
1079 if ($pair->getDefinition()->getIdentifier() != $definition->getIdentifier()) {
1083 if ($pair->getTerm()->getIdentifier() != $term->getIdentifier()) {
1092 $thumbweb = $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $picture;
1093 return '<img src="' . $thumbweb .
'" alt="' . $picture .
'" title="' . $picture .
'"/>';
1100 if (strlen($elem->getText())) {
1101 $html .= $elem->getText();
1104 if (strlen($elem->getPicture())) {
1113 $answersByActiveAndPass = array();
1115 foreach ($relevantAnswers as $row) {
1116 $key = $row[
'active_fi'] .
':' . $row[
'pass'];
1118 if (!isset($answersByActiveAndPass[
$key])) {
1119 $answersByActiveAndPass[
$key] = array();
1122 $answersByActiveAndPass[
$key][$row[
'value1']] = $row[
'value2'];
1127 foreach ($answersByActiveAndPass as
$key => $matchingPairs) {
1128 foreach ($matchingPairs as $termId => $defId) {
1129 $hash = md5($termId .
':' . $defId);
1131 if (!isset($answers[$hash])) {
1133 $this->
object->getTermWithIdentifier($termId)
1137 $this->
object->getDefinitionWithIdentifier($defId)
1140 $answers[$hash] = array(
1141 'answer' => $termHtml . $defHtml,
1142 'term' => $termHtml,
1143 'definition' => $defHtml,
1148 $answers[$hash][
'frequency']++;
1165 $table->setQuestionIndex($questionIndex);
1167 $table->initColumns();
1176 $pairs->setTerms($this->
object->getTerms());
1177 $pairs->setDefinitions($this->
object->getDefinitions());
1178 $pairs->setPairs($this->
object->getMatchingPairs());
1179 $pairs->setThumbsWebPathWithPrefix($this->
object->getImagePathWeb() . $this->
object->getThumbPrefix());
1188 $pairs = $this->
object->getMatchingPairs();
1191 if ($this->request->isset(
'pairs')) {
1192 $points_of_pairs = $this->request->raw(
'pairs')[
'points'];
1193 $pair_terms = explode(
',', $this->request->raw(
'pairs')[
'term_id']);
1194 $pair_definitions = explode(
',', $this->request->raw(
'pairs')[
'definition_id']);
1196 foreach ($points_of_pairs as $idx => $points) {
1197 $k = implode(
'.', [$pair_terms[$idx],$pair_definitions[$idx]]);
1198 $values[$k] = (float) str_replace(
',',
'.', $points);
1201 foreach ($pairs as $idx => $pair) {
1202 $id = implode(
'.', [
1203 $pair->getTerm()->getIdentifier(),
1204 $pair->getDefinition()->getIdentifier()
1206 $nu_pairs[
$id] = $pair->withPoints($values[
$id]);
1209 $this->
object = $this->
object->withMatchingPairs($nu_pairs);
isTestPresentationContext()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
hasCorrectSolution($activeId, $passIndex)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
generateCorrectnessIconsForCorrectness(int $correctness)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
const MATCHING_MODE_N_ON_N
getAnswerStatisticImageHtml($picture)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
const MATCHING_MODE_1_ON_1
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
getTestOutput($active_id, $pass, $is_postponed=false, $user_post_solution=false, $inlineFeedback=false)
isValidTermAndDefinitionAmount(ilPropertyFormGUI $form)
for mode 1:1 terms count must not be less than definitions count for mode n:n this limitation is canc...
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
const CSS_CLASS_FEEDBACK_CORRECT
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
populateTaxonomyFormSection(ilPropertyFormGUI $form)
getPresentationJavascripts()
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
Class for matching questions.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
checkInput()
check input fields
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
setErrorMessage(string $errormessage)
writeQuestionGenericPostData()
getAnswerStatisticMatchingElemHtml($elem)
__construct($id=-1)
assMatchingQuestionGUI constructor
writePostData(bool $always=false)
{}
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
setValue(string $a_value)
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
isCorrectMatching($pair, $definition, $term)
static initjQueryUI(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery-UI JS-File to the global template (see included_components.txt for included components)
getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
const CSS_CLASS_FEEDBACK_WRONG
getPreview($show_question_only=false, $showInlineFeedback=false)
Basic GUI class for assessment questions.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
saveTaxonomyAssignments()
getSpecificFeedbackOutput(array $userSolution)
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
renderSolutionOutput(mixed $user_solutions, int $active_id, ?int $pass, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_autosave_title=false, bool $show_inline_feedback=false,)
getAnswersFrequency($relevantAnswers, $questionIndex)
editQuestion($checkonly=false)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
static signFile(string $path_to_file)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getGenericFeedbackOutput(int $active_id, ?int $pass)