public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false) { global $ilias; include_once "./Services/Xml/classes/class.ilXmlWriter.php"; $xml = new ilXmlWriter(); // set xml header $xml->xmlHeader(); $xml->xmlStartTag("questestinterop"); $attrs = array("ident" => "il_" . IL_INST_ID . "_qst_" . $this->object->getId(), "title" => $this->object->getTitle(), "maxattempts" => $this->object->getNrOfTries()); $xml->xmlStartTag("item", $attrs); // add question description $xml->xmlElement("qticomment", NULL, $this->object->getComment()); // add estimated working time $workingtime = $this->object->getEstimatedWorkingTime(); $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]); $xml->xmlElement("duration", NULL, $duration); // add ILIAS specific metadata $xml->xmlStartTag("itemmetadata"); $xml->xmlStartTag("qtimetadata"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "ILIAS_VERSION"); $xml->xmlElement("fieldentry", NULL, $ilias->getSetting("ilias_version")); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "QUESTIONTYPE"); $xml->xmlElement("fieldentry", NULL, KPRIM_CHOICE_QUESTION_IDENTIFIER); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "AUTHOR"); $xml->xmlElement("fieldentry", NULL, $this->object->getAuthor()); $xml->xmlEndTag("qtimetadatafield"); // additional content editing information $this->addAdditionalContentEditingModeInformation($xml); $this->addGeneralMetadata($xml); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "answer_type"); $xml->xmlElement("fieldentry", NULL, $this->object->getAnswerType()); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "thumb_size"); $xml->xmlElement("fieldentry", NULL, $this->object->getThumbSize()); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "option_label_setting"); $xml->xmlElement("fieldentry", NULL, $this->object->getOptionLabel()); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "custom_true_option_label"); $xml->xmlElement("fieldentry", NULL, $this->object->getCustomTrueOptionLabel()); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "custom_false_option_label"); $xml->xmlElement("fieldentry", NULL, $this->object->getCustomFalseOptionLabel()); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlStartTag("qtimetadatafield"); $xml->xmlElement("fieldlabel", NULL, "feedback_setting"); $xml->xmlElement("fieldentry", NULL, $this->object->getSpecificFeedbackSetting()); $xml->xmlEndTag("qtimetadatafield"); $xml->xmlEndTag("qtimetadata"); $xml->xmlEndTag("itemmetadata"); // PART I: qti presentation $attrs = array("label" => $this->object->getTitle()); $xml->xmlStartTag("presentation", $attrs); // add flow to presentation $xml->xmlStartTag("flow"); // add material with question text to presentation $this->object->addQTIMaterial($xml, $this->object->getQuestion()); // add answers to presentation $attrs = array("ident" => "MCMR", "rcardinality" => "Multiple"); $xml->xmlStartTag("response_lid", $attrs); $solution = $this->object->getSuggestedSolution(0); if (count($solution)) { if (preg_match("/il_(\\d*?)_(\\w+)_(\\d+)/", $solution["internal_link"], $matches)) { $xml->xmlStartTag("material"); $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3]; if (strcmp($matches[1], "") != 0) { $intlink = $solution["internal_link"]; } $attrs = array("label" => "suggested_solution"); $xml->xmlElement("mattext", $attrs, $intlink); $xml->xmlEndTag("material"); } } // shuffle output $attrs = array(); if ($this->object->isShuffleAnswersEnabled()) { $attrs = array("shuffle" => "Yes"); } else { $attrs = array("shuffle" => "No"); } $xml->xmlStartTag("render_choice", $attrs); // add answers $answers =& $this->object->getAnswers(); $akeys = array_keys($answers); foreach ($akeys as $index) { $answer = $this->object->getAnswer($index); $xml->xmlStartTag('response_label', array('ident' => $answer->getPosition())); if (strlen($answer->getImageFile())) { $this->object->addQTIMaterial($xml, $answer->getAnswertext(), FALSE, FALSE); $imagetype = "image/jpeg"; if (preg_match("/.*\\.(png|gif)\$/", $answer->getImageFile(), $matches)) { $imagetype = "image/" . $matches[1]; } if ($force_image_references) { $attrs = array("imagtype" => $imagetype, "label" => $answer->getImageFile(), "uri" => $answer->getImageWebPath()); $xml->xmlElement("matimage", $attrs); } else { $imagepath = $answer->getImageFsPath(); $fh = @fopen($imagepath, "rb"); if ($fh != false) { $imagefile = fread($fh, filesize($imagepath)); fclose($fh); $base64 = base64_encode($imagefile); $attrs = array("imagtype" => $imagetype, "label" => $answer->getImageFile(), "embedded" => "base64"); $xml->xmlElement("matimage", $attrs, $base64, FALSE, FALSE); } } $xml->xmlEndTag("material"); } else { $this->object->addQTIMaterial($xml, $answer->getAnswertext()); } $xml->xmlEndTag("response_label"); } $xml->xmlEndTag("render_choice"); $xml->xmlEndTag("response_lid"); $xml->xmlEndTag("flow"); $xml->xmlEndTag("presentation"); // PART II: qti resprocessing $xml->xmlStartTag('resprocessing'); $xml->xmlStartTag('outcomes'); $xml->xmlElement('decvar', array('varname' => 'SCORE', 'vartype' => 'Decimal', 'defaultval' => '0', 'minvalue' => $this->getMinPoints(), 'maxvalue' => $this->getMaxPoints())); $xml->xmlEndTag('outcomes'); foreach ($answers as $answer) { $xml->xmlStartTag('respcondition', array('continue' => 'Yes')); $xml->xmlStartTag('conditionvar'); $xml->xmlElement('varequal', array('respident' => $answer->getPosition()), $answer->getCorrectness()); $xml->xmlEndTag('conditionvar'); $xml->xmlElement('displayfeedback', array('feedbacktype' => 'Response', 'linkrefid' => "response_{$answer->getPosition()}")); $xml->xmlEndTag('respcondition'); } $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation($this->object->getId(), true); $xml->xmlStartTag('respcondition', array('continue' => 'Yes')); $xml->xmlStartTag('conditionvar'); $xml->xmlStartTag('and'); foreach ($answers as $answer) { $xml->xmlElement('varequal', array('respident' => $answer->getPosition()), $answer->getCorrectness()); } $xml->xmlEndTag('and'); $xml->xmlEndTag('conditionvar'); $xml->xmlElement('setvar', array('action' => 'Add'), $this->object->getPoints()); if (strlen($feedback_allcorrect)) { $xml->xmlElement('displayfeedback', array('feedbacktype' => 'Response', 'linkrefid' => 'response_allcorrect')); } $xml->xmlEndTag('respcondition'); $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation($this->object->getId(), false); $xml->xmlStartTag('respcondition', array('continue' => 'Yes')); $xml->xmlStartTag('conditionvar'); $xml->xmlStartTag('or'); foreach ($answers as $answer) { $xml->xmlStartTag('not'); $xml->xmlElement('varequal', array('respident' => $answer->getPosition()), $answer->getCorrectness()); $xml->xmlEndTag('not'); } $xml->xmlEndTag('or'); $xml->xmlEndTag('conditionvar'); $xml->xmlElement('setvar', array('action' => 'Add'), 0); if (strlen($feedback_onenotcorrect)) { $xml->xmlElement('displayfeedback', array('feedbacktype' => 'Response', 'linkrefid' => 'response_onenotcorrect')); } $xml->xmlEndTag('respcondition'); $xml->xmlEndTag('resprocessing'); foreach ($answers as $answer) { $xml->xmlStartTag('itemfeedback', array('ident' => "response_{$answer->getPosition()}", 'view' => 'All')); $xml->xmlStartTag('flow_mat'); $this->object->addQTIMaterial($xml, $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->object->getId(), $answer->getPosition())); $xml->xmlEndTag('flow_mat'); $xml->xmlEndTag('itemfeedback'); } if (strlen($feedback_allcorrect)) { $xml->xmlStartTag('itemfeedback', array('ident' => 'response_allcorrect', 'view' => 'All')); $xml->xmlStartTag('flow_mat'); $this->object->addQTIMaterial($xml, $feedback_allcorrect); $xml->xmlEndTag('flow_mat'); $xml->xmlEndTag('itemfeedback'); } if (strlen($feedback_onenotcorrect)) { $xml->xmlStartTag('itemfeedback', array('ident' => 'response_onenotcorrect', 'view' => 'All')); $xml->xmlStartTag('flow_mat'); $this->object->addQTIMaterial($xml, $feedback_onenotcorrect); $xml->xmlEndTag('flow_mat'); $xml->xmlEndTag('itemfeedback'); } $xml->xmlEndTag("item"); $xml->xmlEndTag("questestinterop"); $xml = $xml->xmlDumpMem(FALSE); if (!$a_include_header) { $pos = strpos($xml, "?>"); $xml = substr($xml, $pos + 2); } return $xml; }
/** * @param $active_id * @param null $pass * @param bool $graphicalOutput * @param bool $result_output * @param bool $show_question_only * @param bool $show_feedback * @param bool $show_correct_solution * @param bool $show_manual_scoring * @param bool $show_question_text */ public function 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) { // shuffle output $keys = $this->getParticipantsAnswerKeySequence(); // get the solution of the user for the active pass or from the last pass if allowed $user_solution = array(); if ($active_id > 0 && !$show_correct_solution) { $solutions =& $this->object->getSolutionValues($active_id, $pass); foreach ($solutions as $idx => $solution_value) { $user_solution[$solution_value['value1']] = $solution_value['value2']; } } else { // take the correct solution instead of the user solution foreach ($this->object->getAnswers() as $answer) { $user_solution[$answer->getPosition()] = $answer->getCorrectness(); } } // generate the question output $template = new ilTemplate("tpl.il_as_qpl_mc_kprim_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool"); foreach ($keys as $answer_id) { $answer = $this->object->getAnswer($answer_id); if ($active_id > 0 && !$show_correct_solution) { if ($graphicalOutput) { // output of ok/not ok icons for user entered solutions if ($user_solution[$answer->getPosition()] == $answer->getCorrectness()) { $template->setCurrentBlock("icon_ok"); $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg")); $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right")); $template->parseCurrentBlock(); } else { $template->setCurrentBlock("icon_ok"); $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg")); $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong")); $template->parseCurrentBlock(); } } } if (strlen($answer->getImageFile())) { $template->setCurrentBlock("answer_image"); if ($this->object->getThumbSize()) { $template->setVariable("ANSWER_IMAGE_URL", $answer->getThumbWebPath()); } else { $template->setVariable("ANSWER_IMAGE_URL", $answer->getImageWebPath()); } $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($answer->getImageFile())); $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($answer->getImageFile())); $template->parseCurrentBlock(); } if ($show_feedback) { $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template); } $template->setCurrentBlock("answer_row"); $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE)); if (isset($user_solution[$answer->getPosition()])) { if ($user_solution[$answer->getPosition()]) { $template->setVariable("SOLUTION_IMAGE_TRUE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_checked.png"))); $template->setVariable("SOLUTION_ALT_TRUE", $this->lng->txt("checked")); $template->setVariable("SOLUTION_IMAGE_FALSE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png"))); $template->setVariable("SOLUTION_ALT_FALSE", $this->lng->txt("unchecked")); } else { $template->setVariable("SOLUTION_IMAGE_TRUE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png"))); $template->setVariable("SOLUTION_ALT_TRUE", $this->lng->txt("unchecked")); $template->setVariable("SOLUTION_IMAGE_FALSE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_checked.png"))); $template->setVariable("SOLUTION_ALT_FALSE", $this->lng->txt("checked")); } } else { $template->setVariable("SOLUTION_IMAGE_TRUE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png"))); $template->setVariable("SOLUTION_ALT_TRUE", $this->lng->txt("unchecked")); $template->setVariable("SOLUTION_IMAGE_FALSE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png"))); $template->setVariable("SOLUTION_ALT_FALSE", $this->lng->txt("unchecked")); } $template->parseCurrentBlock(); } if ($show_question_text == true) { $questiontext = $this->object->getQuestion(); $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE)); $template->setVariable("INSTRUCTIONTEXT", $this->object->getInstructionTextTranslation($this->lng, $this->object->getOptionLabel())); } $template->setVariable("OPTION_LABEL_TRUE", $this->object->getTrueOptionLabelTranslation($this->lng, $this->object->getOptionLabel())); $template->setVariable("OPTION_LABEL_FALSE", $this->object->getFalseOptionLabelTranslation($this->lng, $this->object->getOptionLabel())); $questionoutput = $template->get(); $feedback = $show_feedback ? $this->getGenericFeedbackOutput($active_id, $pass) : ""; $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", TRUE, TRUE, "Modules/TestQuestionPool"); if (strlen($feedback)) { $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true)); } $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput); $solutionoutput = $solutiontemplate->get(); if (!$show_question_only) { // get page object output $solutionoutput = $this->getILIASPage($solutionoutput); } return $solutionoutput; }
public function insert(&$a_tpl) { $tpl = new ilTemplate("tpl.prop_kprimchoicewizardinput.html", true, true, "Modules/TestQuestionPool"); foreach ($this->values as $value) { /** * @var ilAssKprimChoiceAnswer $value */ if ($this->getSingleline()) { if (!$this->hideImages) { if (strlen($value->getImageFile())) { $imagename = $value->getImageWebPath(); if ($this->getSingleline() && $this->qstObject->getThumbSize()) { if (@file_exists($value->getThumbFsPath())) { $imagename = $value->getThumbWebPath(); } } $tpl->setCurrentBlock('image'); $tpl->setVariable('SRC_IMAGE', $imagename); $tpl->setVariable('IMAGE_NAME', $value->getImageFile()); $tpl->setVariable('ALT_IMAGE', ilUtil::prepareFormOutput($value->getAnswertext())); $tpl->setVariable("TXT_DELETE_EXISTING", $this->lng->txt("delete_existing_file")); $tpl->setVariable("IMAGE_ROW_NUMBER", $value->getPosition()); $tpl->setVariable("IMAGE_POST_VAR", $this->getPostVar()); $tpl->parseCurrentBlock(); } $tpl->setCurrentBlock('addimage'); $tpl->setVariable("IMAGE_ID", $this->getPostVar() . "[image][{$value->getPosition()}]"); $tpl->setVariable("IMAGE_SUBMIT", $this->lng->txt("upload")); $tpl->setVariable("IMAGE_ROW_NUMBER", $value->getPosition()); $tpl->setVariable("IMAGE_POST_VAR", $this->getPostVar()); $tpl->parseCurrentBlock(); } $tpl->setCurrentBlock("prop_text_propval"); $tpl->setVariable("PROPERTY_VALUE", ilUtil::prepareFormOutput($value->getAnswertext())); $tpl->parseCurrentBlock(); $tpl->setCurrentBlock('singleline'); $tpl->setVariable("SIZE", $this->getSize()); $tpl->setVariable("SINGLELINE_ID", $this->getPostVar() . "[answer][{$value->getPosition()}]"); $tpl->setVariable("SINGLELINE_ROW_NUMBER", $value->getPosition()); $tpl->setVariable("SINGLELINE_POST_VAR", $this->getPostVar()); $tpl->setVariable("MAXLENGTH", $this->getMaxLength()); if ($this->getDisabled()) { $tpl->setVariable("DISABLED_SINGLELINE", " disabled=\"disabled\""); } $tpl->parseCurrentBlock(); } else { if (!$this->getSingleline()) { $tpl->setCurrentBlock('multiline'); $tpl->setVariable("PROPERTY_VALUE", ilUtil::prepareFormOutput($value->getAnswertext())); $tpl->setVariable("MULTILINE_ID", $this->getPostVar() . "[answer][{$value->getPosition()}]"); $tpl->setVariable("MULTILINE_ROW_NUMBER", $value->getPosition()); $tpl->setVariable("MULTILINE_POST_VAR", $this->getPostVar()); if ($this->getDisabled()) { $tpl->setVariable("DISABLED_MULTILINE", " disabled=\"disabled\""); } $tpl->parseCurrentBlock(); } } if ($this->getAllowMove()) { $tpl->setCurrentBlock("move"); $tpl->setVariable("CMD_UP", "cmd[up" . $this->getFieldId() . "][{$value->getPosition()}]"); $tpl->setVariable("CMD_DOWN", "cmd[down" . $this->getFieldId() . "][{$value->getPosition()}]"); $tpl->setVariable("UP_ID", "up_{$this->getPostVar()}[{$value->getPosition()}]"); $tpl->setVariable("DOWN_ID", "down_{$this->getPostVar()}[{$value->getPosition()}]"); $tpl->setVariable("UP_BUTTON", ilGlyphGUI::get(ilGlyphGUI::UP)); $tpl->setVariable("DOWN_BUTTON", ilGlyphGUI::get(ilGlyphGUI::DOWN)); $tpl->parseCurrentBlock(); } $tpl->setCurrentBlock("row"); $tpl->setVariable("POST_VAR", $this->getPostVar()); $tpl->setVariable("ROW_NUMBER", $value->getPosition()); $tpl->setVariable("ID", $this->getPostVar() . "[answer][{$value->getPosition()}]"); $tpl->setVariable("CORRECTNESS_TRUE_ID", $this->getPostVar() . "[correctness][{$value->getPosition()}][true]"); $tpl->setVariable("CORRECTNESS_FALSE_ID", $this->getPostVar() . "[correctness][{$value->getPosition()}][false]"); $tpl->setVariable("CORRECTNESS_TRUE_VALUE", 1); $tpl->setVariable("CORRECTNESS_FALSE_VALUE", 0); if ($value->getCorrectness() !== null) { if ($value->getCorrectness()) { $tpl->setVariable('CORRECTNESS_TRUE_SELECTED', ' checked="checked"'); } else { $tpl->setVariable('CORRECTNESS_FALSE_SELECTED', ' checked="checked"'); } } if ($this->getDisabled()) { $tpl->setVariable("DISABLED_CORRECTNESS", " disabled=\"disabled\""); } $tpl->parseCurrentBlock(); } if ($this->getSingleline()) { if (!$this->hideImages) { if (is_array($this->getSuffixes())) { $suff_str = $delim = ""; foreach ($this->getSuffixes() as $suffix) { $suff_str .= $delim . "." . $suffix; $delim = ", "; } $tpl->setCurrentBlock('allowed_image_suffixes'); $tpl->setVariable("TXT_ALLOWED_SUFFIXES", $this->lng->txt("file_allowed_suffixes") . " " . $suff_str); $tpl->parseCurrentBlock(); } $tpl->setCurrentBlock("image_heading"); $tpl->setVariable("ANSWER_IMAGE", $this->lng->txt('answer_image')); $tpl->setVariable("TXT_MAX_SIZE", ilUtil::getFileSizeInfo()); $tpl->parseCurrentBlock(); } } foreach ($this->qstObject->getValidOptionLabels() as $optionLabel) { if ($this->qstObject->isCustomOptionLabel($optionLabel)) { continue; } $tpl->setCurrentBlock('option_label_translations'); $tpl->setVariable('OPTION_LABEL', $optionLabel); $tpl->setVariable('TRANSLATION_TRUE', $this->qstObject->getTrueOptionLabelTranslation($this->lng, $optionLabel)); $tpl->setVariable('TRANSLATION_FALSE', $this->qstObject->getFalseOptionLabelTranslation($this->lng, $optionLabel)); $tpl->parseCurrentBlock(); } $tpl->setVariable("ELEMENT_ID", $this->getPostVar()); $tpl->setVariable("DELETE_IMAGE_HEADER", $this->lng->txt('delete_image_header')); $tpl->setVariable("DELETE_IMAGE_QUESTION", $this->lng->txt('delete_image_question')); $tpl->setVariable("ANSWER_TEXT", $this->lng->txt('answer_text')); $tpl->setVariable("OPTIONS_TEXT", $this->lng->txt('options')); // winzards input column label values will be updated on document ready js //$tpl->setVariable("TRUE_TEXT", $this->qstObject->getTrueOptionLabelTranslation($this->lng, $this->qstObject->getOptionLabel())); //$tpl->setVariable("FALSE_TEXT", $this->qstObject->getFalseOptionLabelTranslation($this->lng, $this->qstObject->getOptionLabel())); $a_tpl->setCurrentBlock("prop_generic"); $a_tpl->setVariable("PROP_GENERIC", $tpl->get()); $a_tpl->parseCurrentBlock(); include_once "./Services/YUI/classes/class.ilYuiUtil.php"; $this->tpl->addJavascript("./Services/Form/js/ServiceFormWizardInput.js"); $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/kprimchoicewizard.js"); $this->tpl->addJavascript('Modules/TestQuestionPool/js/ilAssKprimChoice.js'); }