/**
  * Perform the necessary preprocessing for the fields added by
  * {@link add_per_answer_fields()}.
  * @param object $question the data being passed to the form.
  * @return object $question the modified data.
  */
 protected function data_preprocessing_answers($question, $withanswerfiles = false)
 {
     if (empty($question->options->answers)) {
         return $question;
     }
     $key = 0;
     foreach ($question->options->answers as $answer) {
         // answer content & format
         $question->answer[$key] = json_encode(qtype_omerocommon::serialize_to_json_from($answer->answer));
         $question->answerformat[$key] = $answer->answerformat;
         // answer fraction
         $question->fraction[$key] = 0 + $answer->fraction;
         unset($this->_form->_defaultValues["fraction[{$key}]"]);
         // answer feedback
         $question->feedback[$key] = json_encode(qtype_omerocommon::serialize_to_json_from($answer->feedback));
         $question->feedbackformat[$key] = $answer->feedbackformat;
         $question->feedbackimages[$key] = empty($answer->images) ? json_encode(array()) : $answer->images;
         $question->answer_locale_map[$key] = json_encode(qtype_omerocommon::serialize_to_json_from($answer->answer));
         $question->feedback_locale_map[$key] = json_encode(qtype_omerocommon::serialize_to_json_from($answer->feedback));
         $key++;
     }
     // Now process extra answer fields.
     $extraanswerfields = question_bank::get_qtype($question->qtype)->extra_answer_fields();
     if (is_array($extraanswerfields)) {
         // Omit table name.
         array_shift($extraanswerfields);
         $question = $this->data_preprocessing_extra_answer_fields($question, $extraanswerfields);
     }
     return $question;
 }
 public function save_question_options($question)
 {
     global $DB;
     $context = $question->context;
     $result = new stdClass();
     $oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC');
     // Following hack to check at least two answers exist.
     $answercount = 0;
     foreach ($question->answer_locale_map as $key => $answer) {
         if ($answer != '') {
             $answercount++;
         }
     }
     if ($answercount < 1) {
         // Check there are at lest 2 answers for multiple choice.
         $result->notice = get_string('notenoughanswers', 'qtype_multichoice', '1');
         return $result;
     }
     // Insert all the new answers.
     $totalfraction = 0;
     $maxfraction = -1;
     foreach ($question->answer_locale_map as $key => $answertext) {
         if (trim($answertext) == '') {
             continue;
         }
         // Update an existing answer if possible.
         $answer = array_shift($oldanswers);
         if (!$answer) {
             $answer = new stdClass();
             $answer->question = $question->id;
             $answer->answer = '';
             $answer->answerformat = '';
             $answer->feedback = '';
             $answer->fraction = 0;
             $answer->id = $DB->insert_record('question_answers', $answer);
         }
         $answer->answer = qtype_omerocommon::serialize_to_multilang_form($question->answer_locale_map[$key]);
         $answer->feedback = qtype_omerocommon::serialize_to_multilang_form($question->feedback_locale_map[$key]);
         if (isset($question->fraction[$key])) {
             $answer->fraction = $question->fraction[$key];
         }
         $DB->update_record('question_answers', $answer);
         if ($question->fraction[$key] > 0) {
             $totalfraction += $question->fraction[$key];
         }
         if ($question->fraction[$key] > $maxfraction) {
             $maxfraction = $question->fraction[$key];
         }
         // NOTICE: our implementation supports at most one 'answer-option' per answer
         $answer_option = $DB->get_record('question_answers_omemopt', array('answerid' => $answer->id));
         if (!$answer_option) {
             $answer_option = new stdClass();
             $answer_option->answerid = $answer->id;
             $answer_option->images = $question->feedbackimages[$key];
             $answer_option->id = $DB->insert_record("question_answers_omemopt", $answer_option);
         } else {
             $answer_option->images = $question->feedbackimages[$key];
             $DB->update_record("question_answers_omemopt", $answer_option);
         }
     }
     // Delete any left over old answer records.
     $fs = get_file_storage();
     foreach ($oldanswers as $oldanswer) {
         $fs->delete_area_files($context->id, 'question', 'answerfeedback', $oldanswer->id);
         $DB->delete_records('question_answers', array('id' => $oldanswer->id));
     }
     $options = $DB->get_record($this->get_table_name(), array('questionid' => $question->id));
     if (!$options) {
         $options = new stdClass();
         $options->questionid = $question->id;
         $options->omeroimageurl = '';
         $options->correctfeedback = '';
         $options->partiallycorrectfeedback = '';
         $options->incorrectfeedback = '';
         $options->visiblerois = '';
         $options->focusablerois = '';
         $options->omeroimagelocked = 0;
         $options->omeroimageproperties = "";
         $options->id = $DB->insert_record($this->get_table_name(), $options);
     }
     $options->single = $question->single;
     if (isset($question->layout)) {
         $options->layout = $question->layout;
     }
     $options->omeroimageurl = $question->omeroimageurl;
     $options->omeroimagelocked = $question->omeroimagelocked;
     $options->omeroimageproperties = $question->omeroimageproperties;
     $options->answernumbering = $question->answernumbering;
     $options->shuffleanswers = $question->shuffleanswers;
     $options->visiblerois = $question->visiblerois;
     $options->focusablerois = $question->focusablerois;
     $options = $this->save_combined_feedback_helper($options, $question, $context, true);
     $options->correctfeedback = qtype_omerocommon::serialize_to_multilang_form($question->correctfeedback_locale_map);
     $options->partiallycorrectfeedback = qtype_omerocommon::serialize_to_multilang_form($question->partiallycorrectfeedback_locale_map);
     $options->incorrectfeedback = qtype_omerocommon::serialize_to_multilang_form($question->incorrectfeedback_locale_map);
     $DB->update_record($this->get_table_name(), $options);
     $this->save_hints($question, true);
     // Perform sanity checks on fractional grades.
     if ($options->single) {
         if ($maxfraction != 1) {
             $result->notice = get_string('fractionsnomax', 'qtype_multichoice', $maxfraction * 100);
             return $result;
         }
     } else {
         $totalfraction = round($totalfraction, 2);
         if ($totalfraction != 1) {
             $result->notice = get_string('fractionsaddwrong', 'qtype_multichoice', $totalfraction * 100);
             return $result;
         }
     }
 }
 /**
  * Serialize a JSON array of a multilang text to HTML
  *
  * @param $json_format
  * @return string
  */
 public static function serialize_to_multilang_form($json_format)
 {
     $result = "";
     $languages = array();
     $json_data = json_decode($json_format);
     foreach ($json_data as $lang => $text) {
         if (!empty(strip_tags($text)) && !in_array($lang, $languages)) {
             $result .= '<div class="multilang" lang="' . $lang . '">' . $text . '</div>';
             array_push($languages, $lang);
         }
     }
     return qtype_omerocommon::normalize_html_text($result);
 }