Converts the multichoice info and writes it into the question.xml

@param array $multichoices the grouped structure
@param int $oldquestiontextformat - {@see moodle1_question_bank_handler::process_question()}
@param int $questionid question id
965243
protected function write_multichoice(array $multichoices, $oldquestiontextformat, $questionid) {
        global $CFG;

        // The grouped array is supposed to have just one element - let us use foreach anyway
        // just to be sure we do not loose anything.
        foreach ($multichoices as $multichoice) {
            // Append an artificial 'id' attribute (is not included in moodle.xml).
            $multichoice['id'] = $this->converter->get_nextid();

            // Replay the upgrade step 2009021801.
            $multichoice['correctfeedbackformat']               = 0;
            $multichoice['partiallycorrectfeedbackformat']      = 0;
            $multichoice['incorrectfeedbackformat']             = 0;

            if ($CFG->texteditors !== 'textarea' and $oldquestiontextformat == FORMAT_MOODLE) {
                $multichoice['correctfeedback']                 = text_to_html($multichoice['correctfeedback'], false, false, true);
                $multichoice['correctfeedbackformat']           = FORMAT_HTML;
                $multichoice['partiallycorrectfeedback']        = text_to_html($multichoice['partiallycorrectfeedback'], false, false, true);
                $multichoice['partiallycorrectfeedbackformat']  = FORMAT_HTML;
                $multichoice['incorrectfeedback']               = text_to_html($multichoice['incorrectfeedback'], false, false, true);
                $multichoice['incorrectfeedbackformat']         = FORMAT_HTML;
            } else {
                $multichoice['correctfeedbackformat']           = $oldquestiontextformat;
                $multichoice['partiallycorrectfeedbackformat']  = $oldquestiontextformat;
                $multichoice['incorrectfeedbackformat']         = $oldquestiontextformat;
            }

            $multichoice['correctfeedback'] = $this->migrate_files(
                    $multichoice['correctfeedback'], 'question', 'correctfeedback', $questionid);
            $multichoice['partiallycorrectfeedback'] = $this->migrate_files(
                    $multichoice['partiallycorrectfeedback'], 'question', 'partiallycorrectfeedback', $questionid);
            $multichoice['incorrectfeedback'] = $this->migrate_files(
                    $multichoice['incorrectfeedback'], 'question', 'incorrectfeedback', $questionid);

            $this->write_xml('multichoice', $multichoice, array('/multichoice/id'));
        }
    }
873125
protected function formatQuestionText(Question $question) {
    $question_text = $question->getQuestion();
    $default_value = $question->getDefault();

    $question_text = "\n <info>$question_text</info>";
    if (is_bool($default_value)) {
      $default_value = $default_value ? 'Yes' : 'No';
    }
    if ($default_value) {
      $question_text .= " [<comment>$default_value</comment>]";
    }
    $question_text .= ":";
    if ($question instanceof ChoiceQuestion) {
      $question->setPrompt('  ➤➤➤ ');
    }
    else {
      $question_text .= "\n ➤ ";
    }

    $this->setQuestionText($question, $question_text);
  }
1280203
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = null)
    {
        $helper = $this->getHelperSet()->get('question');

        $question = new ChoiceQuestion("<question>$question</question> ", $choices, $default);

        $question->setMaxAttempts($attempts)->setMultiselect($multiple);

        return $helper->ask($this->input, $this->output, $question);
    }
800448
public function askWithCompletion($question, array $choices, $default = null)
    {
        $helper = $this->getHelperSet()->get('question');

        $question = new Question("<question>$question</question> ", $default);

        $question->setAutocompleterValues($choices);

        return $helper->ask($this->input, $this->output, $question);
    }
977568
public function process_category($xml, &$questions) {
        $title = $this->getpath($xml, array('questestinterop', '#', 'assessment', 0, '@', 'title'), '', true);

        $dummyquestion = new stdClass();
        $dummyquestion->qtype = 'category';
        $dummyquestion->category = $this->cleaninput($this->clean_question_name($title));

        $questions[] = $dummyquestion;
    }
1145955
protected function get_default_numerical_options($oldquestiontextformat, $units) {
        global $CFG;

        // replay the upgrade step 2009100100 - new table
        $options = array(
            'id'                 => $this->converter->get_nextid(),
            'instructions'       => null,
            'instructionsformat' => 0,
            'showunits'          => 0,
            'unitsleft'          => 0,
            'unitgradingtype'    => 0,
            'unitpenalty'        => 0.1
        );

        // replay the upgrade step 2009100101
        if ($CFG->texteditors !== 'textarea' and $oldquestiontextformat == FORMAT_MOODLE) {
            $options['instructionsformat'] = FORMAT_HTML;
        } else {
            $options['instructionsformat'] = $oldquestiontextformat;
        }

        // Set a good default, depending on whether there are any units defined.
        if (empty($units)) {
            $options['showunits'] = 3;
        }

        return $options;
    }
1332628
public function process_question(array $data, array $raw) {
        global $CFG;

        // firstly make sure that the category data and the <questions> wrapper are written
        // note that because of MDL-27693 we can't use {@link self::process_question_category()}
        // and {@link self::on_questions_start()} to do so

        if (empty($this->currentcategorywritten)) {
            $this->xmlwriter->begin_tag('question_category', array('id' => $this->currentcategory['id']));
            foreach ($this->currentcategory as $name => $value) {
                if ($name === 'id') {
                    continue;
                }
                $this->xmlwriter->full_tag($name, $value);
            }
            $this->currentcategorywritten = true;
        }

        if (empty($this->questionswrapperwritten)) {
            $this->xmlwriter->begin_tag('questions');
            $this->questionswrapperwritten = true;
        }

        $qtype = $data['qtype'];

        // replay the upgrade step 2008050700 {@see question_fix_random_question_parents()}
        if ($qtype == 'random' and $data['parent'] <> $data['id']) {
            $data['parent'] = $data['id'];
        }

        // replay the upgrade step 2010080900 and part of 2010080901
        $data['generalfeedbackformat'] = $data['questiontextformat'];
        $data['oldquestiontextformat'] = $data['questiontextformat'];

        if ($CFG->texteditors !== 'textarea') {
            $data['questiontext'] = text_to_html($data['questiontext'], false, false, true);
            $data['questiontextformat'] = FORMAT_HTML;
            $data['generalfeedback'] = text_to_html($data['generalfeedback'], false, false, true);
            $data['generalfeedbackformat'] = FORMAT_HTML;
        }

        // Migrate files in questiontext.
        $this->fileman->contextid = $this->currentcategory['contextid'];
        $this->fileman->component = 'question';
        $this->fileman->filearea  = 'questiontext';
        $this->fileman->itemid    = $data['id'];
        $data['questiontext'] = moodle1_converter::migrate_referenced_files($data['questiontext'], $this->fileman);

        // Migrate files in generalfeedback.
        $this->fileman->filearea  = 'generalfeedback';
        $data['generalfeedback'] = moodle1_converter::migrate_referenced_files($data['generalfeedback'], $this->fileman);

        // replay the upgrade step 2010080901 - updating question image
        if (!empty($data['image'])) {
            if (core_text::substr(core_text::strtolower($data['image']), 0, 7) == 'http://') {
                // it is a link, appending to existing question text
                $data['questiontext'] .= ' <img src="' . $data['image'] . '" />';

            } else {
                // it is a file in course_files
                $filename = basename($data['image']);
                $filepath = dirname($data['image']);
                if (empty($filepath) or $filepath == '.' or $filepath == '/') {
                    $filepath = '/';
                } else {
                    // append /
                    $filepath = '/'.trim($filepath, './@#$ ').'/';
                }

                if (file_exists($this->converter->get_tempdir_path().'/course_files'.$filepath.$filename)) {
                    $this->fileman->contextid = $this->currentcategory['contextid'];
                    $this->fileman->component = 'question';
                    $this->fileman->filearea  = 'questiontext';
                    $this->fileman->itemid    = $data['id'];
                    $this->fileman->migrate_file('course_files'.$filepath.$filename, '/', $filename);
                    // note this is slightly different from the upgrade code as we put the file into the
                    // root folder here. this makes our life easier as we do not need to create all the
                    // directories within the specified filearea/itemid
                    $data['questiontext'] .= ' <img src="@@PLUGINFILE@@/' . $filename . '" />';

                } else {
                    $this->log('question file not found', backup::LOG_WARNING, array($data['id'], $filepath.$filename));
                }
            }
        }
        unset($data['image']);

        // replay the upgrade step 2011060301 - Rename field defaultgrade on table question to defaultmark
        $data['defaultmark'] = $data['defaultgrade'];

        // write the common question data
        $this->xmlwriter->begin_tag('question', array('id' => $data['id']));
        foreach (array(
            'parent', 'name', 'questiontext', 'questiontextformat',
            'generalfeedback', 'generalfeedbackformat', 'defaultmark',
            'penalty', 'qtype', 'length', 'stamp', 'version', 'hidden',
            'timecreated', 'timemodified', 'createdby', 'modifiedby'
        ) as $fieldname) {
            if (!array_key_exists($fieldname, $data)) {
                throw new moodle1_convert_exception('missing_common_question_field', $fieldname);
            }
            $this->xmlwriter->full_tag($fieldname, $data[$fieldname]);
        }
        // unless we know that the given qtype does not append any own structures,
        // give the handler a chance to do so now
        if (!in_array($qtype, array('description', 'random'))) {
            $handler = $this->get_qtype_handler($qtype);
            if ($handler === false) {
                $this->log('question type converter not found', backup::LOG_ERROR, $qtype);

            } else {
                $this->xmlwriter->begin_tag('plugin_qtype_'.$qtype.'_question');
                $handler->use_xml_writer($this->xmlwriter);
                $handler->process_question($data, $raw);
                $this->xmlwriter->end_tag('plugin_qtype_'.$qtype.'_question');
            }
        }

        $this->xmlwriter->end_tag('question');
    }
463268
public function askWithCompletion($question, array $choices, $default = null)
    {
        $question = new Question($question, $default);

        $question->setAutocompleterValues($choices);

        return $this->output->askQuestion($question);
    }
681821
public function process_question(array $data, array $raw) {

        // Convert and write the answers first.
        if (isset($data['answers'])) {
            $this->write_answers($data['answers'], $this->pluginname);
        }

        // Convert and write the multichoice.
        if (!isset($data['multichoice'])) {
            // This should never happen, but it can do if the 1.9 site contained
            // corrupt data.
            $data['multichoice'] = array(array(
                'single'                         => 1,
                'shuffleanswers'                 => 1,
                'correctfeedback'                => '',
                'correctfeedbackformat'          => FORMAT_HTML,
                'partiallycorrectfeedback'       => '',
                'partiallycorrectfeedbackformat' => FORMAT_HTML,
                'incorrectfeedback'              => '',
                'incorrectfeedbackformat'        => FORMAT_HTML,
                'answernumbering'                => 'abc',
            ));
        }
        $this->write_multichoice($data['multichoice'], $data['oldquestiontextformat'], $data['id']);
    }
891986
protected function after_execute_question() {
        global $DB;

        $essayswithoutoptions = $DB->get_records_sql("
                    SELECT q.*
                      FROM {question} q
                      JOIN {backup_ids_temp} bi ON bi.newitemid = q.id
                 LEFT JOIN {qtype_essay_options} qeo ON qeo.questionid = q.id
                     WHERE q.qtype = ?
                       AND qeo.id IS NULL
                       AND bi.backupid = ?
                       AND bi.itemname = ?
                ", array('essay', $this->get_restoreid(), 'question_created'));

        foreach ($essayswithoutoptions as $q) {
            $defaultoptions = new stdClass();
            $defaultoptions->questionid = $q->id;
            $defaultoptions->responseformat = 'editor';
            $defaultoptions->responserequired = 1;
            $defaultoptions->responsefieldlines = 15;
            $defaultoptions->attachments = 0;
            $defaultoptions->attachmentsrequired = 0;
            $defaultoptions->graderinfo = '';
            $defaultoptions->graderinfoformat = FORMAT_HTML;
            $defaultoptions->responsetemplate = '';
            $defaultoptions->responsetemplateformat = FORMAT_HTML;
            $DB->insert_record('qtype_essay_options', $defaultoptions);
        }
    }
957857
public function process_redo_question($slot, $timestamp) {
        global $DB;

        if (!$this->can_question_be_redone_now($slot)) {
            throw new coding_exception('Attempt to restart the question in slot ' . $slot .
                    ' when it is not in a state to be restarted.');
        }

        $qubaids = new \mod_quiz\question\qubaids_for_users_attempts(
                $this->get_quizid(), $this->get_userid());

        $transaction = $DB->start_delegated_transaction();

        // Choose the replacement question.
        $questiondata = $DB->get_record('question',
                array('id' => $this->slots[$slot]->questionid));
        if ($questiondata->qtype != 'random') {
            $newqusetionid = $questiondata->id;
        } else {
            $tagids = quiz_retrieve_slot_tag_ids($this->slots[$slot]->id);

            $randomloader = new \core_question\bank\random_question_loader($qubaids, array());
            $newqusetionid = $randomloader->get_next_question_id($questiondata->category,
                    (bool) $questiondata->questiontext, $tagids);
            if ($newqusetionid === null) {
                throw new moodle_exception('notenoughrandomquestions', 'quiz',
                        $this->quizobj->view_url(), $questiondata);
            }
        }

        // Add the question to the usage. It is important we do this before we choose a variant.
        $newquestion = question_bank::load_question($newqusetionid);
        $newslot = $this->quba->add_question_in_place_of_other($slot, $newquestion);

        // Choose the variant.
        if ($newquestion->get_num_variants() == 1) {
            $variant = 1;
        } else {
            $variantstrategy = new core_question\engine\variants\least_used_strategy(
                    $this->quba, $qubaids);
            $variant = $variantstrategy->choose_variant($newquestion->get_num_variants(),
                    $newquestion->get_variants_selection_seed());
        }

        // Start the question.
        $this->quba->start_question($slot, $variant);
        $this->quba->set_max_mark($newslot, 0);
        $this->quba->set_question_attempt_metadata($newslot, 'originalslot', $slot);
        question_engine::save_questions_usage_by_activity($this->quba);

        $transaction->allow_commit();
    }
77868
public function serialize(BooleanQuestion $question, array $options = [])
    {
        // Serializes choices
        $choices = $this->serializeChoices($question, $options);

        if (in_array(Transfer::SHUFFLE_ANSWERS, $options)) {
            shuffle($choices);
        }

        $serialized = ['choices' => $choices];

        if (in_array(Transfer::INCLUDE_SOLUTIONS, $options)) {
            $serialized['solutions'] = $this->serializeSolutions($question);
        }

        return $serialized;
    }
643137
protected function writePrompt(OutputInterface $output, Question $question, $formats = [])
	{
		$formats = array_replace($this->formats, $formats);

		$output->write(sprintf($formats['question_format'], $question->getQuestion()));

		$default = $question->getDefault();
		if (! is_null($default)) {
			if ($question instanceof ConfirmationQuestion) {
				$default = $default ? "yes" : "no";
			}

			$output->write(sprintf($formats['default_format'], $default));
		}

		if ($question instanceof ChoiceQuestion) {
			$messages = [];
			foreach ($question->getChoices() as $key => $value) {
				$messages[] = sprintf($formats['choice_format'], $key, substr($value, 0));
			}

			$output->writeln("");
			$output->writeln("");
			$output->writeln(implode(PHP_EOL, $messages));
			$output->writeln("");
			$output->write("> ");
		} else {
			$output->write(": ");
		}
	}
139007
private function serializeSolutions(BooleanQuestion $question)
    {
        return array_map(function (BooleanChoice $choice) {
            $solutionData = [
                'id' => $choice->getUuid(),
                'score' => $choice->getScore(),
            ];

            if ($choice->getFeedback()) {
                $solutionData['feedback'] = $choice->getFeedback();
            }

            return $solutionData;
        }, $question->getChoices()->toArray());
    }
1219473
protected function askOptions(string $description, array $options, int $default, $multiSelect = false)
    {
        $helper   = $this->getHelper('question');
        $question = new ChoiceQuestion(
            $description,
            $options,
            $default
        );
        if ($multiSelect) {
            $question->setMultiselect(true);
        }
        $question->setErrorMessage('Answer is invalid');
        $answer = $helper->ask($this->input, $this->output, $question);

        return $answer;
    }
610
private function choice($question, array $choices, $default, InputInterface $input, OutputInterface $output)
    {
        $helper = new QuestionHelper();

        $result = $helper->ask($input, $output, new ChoiceQuestion(
            $question,
            $choices,
            $choices[$default]
        ));

        $output->writeln('');

        return $result;
    }
992354
public function load_choices() {
        global $CFG;

        if (is_array($this->choices)) {
            return true;
        }

        require_once($CFG->dirroot . '/question/type/multichoice/questiontype.php');
        $this->choices = qtype_multichoice::get_numbering_styles();

        return true;
    }