MDL-79863 qtype_ordering: Coding style improvements part 2
Co-authored by: Tim Hunt <[email protected]>
This commit is contained in:
+5
-2
@@ -9,15 +9,18 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- php: '8.0'
|
||||
- php: '8.2'
|
||||
moodle-branch: 'master'
|
||||
database: 'mariadb'
|
||||
- php: '8.2'
|
||||
moodle-branch: 'MOODLE_403_STABLE'
|
||||
database: 'pgsql'
|
||||
- php: '8.1'
|
||||
moodle-branch: 'MOODLE_402_STABLE'
|
||||
database: 'mariadb'
|
||||
- php: '8.0'
|
||||
moodle-branch: 'MOODLE_401_STABLE'
|
||||
database: 'mariadb'
|
||||
database: 'pgsql'
|
||||
- php: '7.4'
|
||||
moodle-branch: 'MOODLE_400_STABLE'
|
||||
database: 'mariadb'
|
||||
|
||||
@@ -34,13 +34,13 @@ class moodle1_qtype_ordering_handler extends moodle1_qtype_handler {
|
||||
* Returns the list of paths within one <QUESTION> that this qtype needs to have included
|
||||
* in the grouped question structure
|
||||
*
|
||||
* @return array of strings
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_question_subpaths() {
|
||||
return array(
|
||||
public function get_question_subpaths(): array {
|
||||
return [
|
||||
'ANSWERS/ANSWER',
|
||||
'ORDERING',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +49,7 @@ class moodle1_qtype_ordering_handler extends moodle1_qtype_handler {
|
||||
* @param array $data grouped question data
|
||||
* @param array $raw grouped raw QUESTION data
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
public function process_question(array $data, array $raw): void {
|
||||
|
||||
// Convert and write the answers first.
|
||||
if (isset($data['answers'])) {
|
||||
@@ -59,7 +59,7 @@ class moodle1_qtype_ordering_handler extends moodle1_qtype_handler {
|
||||
// Convert and write the ordering extra fields.
|
||||
foreach ($data['ordering'] as $ordering) {
|
||||
$ordering['id'] = $this->converter->get_nextid();
|
||||
$this->write_xml('ordering', $ordering, array('/ordering/id'));
|
||||
$this->write_xml('ordering', $ordering, ['/ordering/id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,10 @@ class backup_qtype_ordering_plugin extends backup_qtype_plugin {
|
||||
|
||||
/**
|
||||
* Returns the qtype information to attach to question element
|
||||
*
|
||||
* @return backup_plugin_element
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
protected function define_question_plugin_structure(): backup_plugin_element {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'ordering');
|
||||
@@ -49,18 +51,18 @@ class backup_qtype_ordering_plugin extends backup_qtype_plugin {
|
||||
$this->add_question_question_answers($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures.
|
||||
$fields = array('layouttype', 'selecttype', 'selectcount',
|
||||
'gradingtype', 'showgrading', 'numberingstyle',
|
||||
'correctfeedback', 'correctfeedbackformat',
|
||||
'incorrectfeedback', 'incorrectfeedbackformat',
|
||||
'partiallycorrectfeedback', 'partiallycorrectfeedbackformat', 'shownumcorrect');
|
||||
$ordering = new backup_nested_element('ordering', array('id'), $fields);
|
||||
$fields = ['layouttype', 'selecttype', 'selectcount',
|
||||
'gradingtype', 'showgrading', 'numberingstyle',
|
||||
'correctfeedback', 'correctfeedbackformat',
|
||||
'incorrectfeedback', 'incorrectfeedbackformat',
|
||||
'partiallycorrectfeedback', 'partiallycorrectfeedbackformat', 'shownumcorrect'];
|
||||
$ordering = new backup_nested_element('ordering', ['id'], $fields);
|
||||
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($ordering);
|
||||
|
||||
// Set source to populate the data.
|
||||
$params = array('questionid' => backup::VAR_PARENTID);
|
||||
$params = ['questionid' => backup::VAR_PARENTID];
|
||||
$ordering->set_source_table('qtype_ordering_options', $params);
|
||||
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
@@ -32,10 +32,11 @@ class restore_qtype_ordering_plugin extends restore_qtype_plugin {
|
||||
|
||||
/**
|
||||
* Returns the paths to be handled by the plugin at question level
|
||||
*
|
||||
* @return restore_path_element[]
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
$paths = array();
|
||||
protected function define_question_plugin_structure(): array {
|
||||
$paths = [];
|
||||
|
||||
// This qtype uses question_answers, add them.
|
||||
$this->add_question_question_answers($paths);
|
||||
@@ -53,7 +54,7 @@ class restore_qtype_ordering_plugin extends restore_qtype_plugin {
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function process_ordering($data) {
|
||||
public function process_ordering(array $data): void {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
@@ -61,8 +62,8 @@ class restore_qtype_ordering_plugin extends restore_qtype_plugin {
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// "question" is the XML tag name, not the DB field name.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
|
||||
// If the question has been created by restore,
|
||||
// we need to create a "qtype_ordering_options" record
|
||||
@@ -83,8 +84,9 @@ class restore_qtype_ordering_plugin extends restore_qtype_plugin {
|
||||
* If not empty, answer is one question_answers->id.
|
||||
*
|
||||
* @param object $state
|
||||
* @return string|false
|
||||
*/
|
||||
public function recode_legacy_state_answer($state) {
|
||||
public function recode_legacy_state_answer($state): string|false {
|
||||
$answer = $state->answer;
|
||||
$result = '';
|
||||
if ($answer) {
|
||||
|
||||
@@ -30,7 +30,7 @@ class provider implements \core_privacy\local\metadata\null_provider {
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reason(): string {
|
||||
return 'privacy:metadata';
|
||||
|
||||
@@ -29,8 +29,8 @@ use question_hint_with_parts;
|
||||
/**
|
||||
* Question hint for ordering.
|
||||
*
|
||||
* An extension of {@link question_hint} for questions like match and multiple
|
||||
* choice with multile answers, where there are options for whether to show the
|
||||
* An extension of {@see question_hint} for questions like match and multiple
|
||||
* choice with multiple answers, where there are options for whether to show the
|
||||
* number of parts right at each stage, and to reset the wrong parts.
|
||||
*
|
||||
* @package qtype_ordering
|
||||
@@ -39,18 +39,20 @@ use question_hint_with_parts;
|
||||
*/
|
||||
class question_hint_ordering extends question_hint_with_parts {
|
||||
/** Highlight response in the hint options. */
|
||||
public $highlightresponse;
|
||||
public bool $highlightresponse;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int The hint id from the database.
|
||||
* @param int $id The hint id from the database.
|
||||
* @param string $hint The hint text.
|
||||
* @param int The corresponding text FORMAT_... type.
|
||||
* @param int $hintformat The corresponding text FORMAT_... type.
|
||||
* @param bool $shownumcorrect Whether the number of right parts should be shown.
|
||||
* @param bool $clearwrong Whether the wrong parts should be reset.
|
||||
* @param bool $highlightresponse Whether to highlight response.
|
||||
*/
|
||||
public function __construct($id, $hint, $hintformat, $shownumcorrect, $clearwrong, $highlightresponse) {
|
||||
public function __construct(int $id, string $hint, int $hintformat, bool $shownumcorrect,
|
||||
bool $clearwrong, bool $highlightresponse) {
|
||||
parent::__construct($id, $hint, $hintformat, $shownumcorrect, $clearwrong);
|
||||
$this->highlightresponse = $highlightresponse;
|
||||
}
|
||||
@@ -61,7 +63,7 @@ class question_hint_ordering extends question_hint_with_parts {
|
||||
* @param object $row With property options as well as hint, shownumcorrect and clearwrong set.
|
||||
* @return question_hint_ordering
|
||||
*/
|
||||
public static function load_from_record($row) {
|
||||
public static function load_from_record($row): question_hint_ordering {
|
||||
global $DB;
|
||||
|
||||
// Initialize with the old questions.
|
||||
@@ -74,14 +76,4 @@ class question_hint_ordering extends question_hint_with_parts {
|
||||
return new question_hint_ordering($row->id, $row->hint, $row->hintformat,
|
||||
$row->shownumcorrect, $row->clearwrong, $row->options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust this display options according to the hint settings.
|
||||
*
|
||||
* @param question_display_options $options
|
||||
*/
|
||||
public function adjust_display_options(question_display_options $options) {
|
||||
parent::adjust_display_options($options);
|
||||
$options->highlightresponse = $this->highlightresponse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,24 +53,28 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
|
||||
/**
|
||||
* qtype is plugin name without leading "qtype_"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function qtype() {
|
||||
public function qtype(): string {
|
||||
return 'ordering';
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin name is class name without trailing "_edit_form"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function plugin_name() {
|
||||
public function plugin_name(): string {
|
||||
return 'qtype_ordering';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add question-type specific form fields.
|
||||
*
|
||||
* @param object $mform the form being built.
|
||||
* @param MoodleQuickForm $mform the form being built.
|
||||
*/
|
||||
public function definition_inner($mform) {
|
||||
public function definition_inner($mform): void {
|
||||
|
||||
// Cache this plugins name.
|
||||
$plugin = 'qtype_ordering';
|
||||
@@ -94,7 +98,7 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
// Field for selectcount.
|
||||
$name = 'selectcount';
|
||||
$label = get_string($name, $plugin);
|
||||
$options = array(0 => get_string('all'));
|
||||
$options = [0 => get_string('all')];
|
||||
for ($i = 3; $i <= 20; $i++) {
|
||||
$options[$i] = $i;
|
||||
}
|
||||
@@ -114,8 +118,7 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
// Field for showgrading.
|
||||
$name = 'showgrading';
|
||||
$label = get_string($name, $plugin);
|
||||
$options = array(0 => get_string('hide'),
|
||||
1 => get_string('show'));
|
||||
$options = [0 => get_string('hide'), 1 => get_string('show')];
|
||||
$mform->addElement('select', $name, $label, $options);
|
||||
$mform->addHelpButton($name, $name, $plugin);
|
||||
$mform->setDefault($name, $this->get_default_value($name, 1));
|
||||
@@ -127,19 +130,19 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
$mform->addHelpButton($name, $name, $plugin);
|
||||
$mform->setDefault($name, $this->get_default_value($name, qtype_ordering_question::NUMBERING_STYLE_DEFAULT));
|
||||
|
||||
$elements = array();
|
||||
$options = array();
|
||||
$elements = [];
|
||||
$options = [];
|
||||
|
||||
$name = 'answerheader';
|
||||
$label = get_string($name, $plugin);
|
||||
$elements[] = $mform->createElement('header', $name, $label);
|
||||
$options[$name] = array('expanded' => true);
|
||||
$options[$name] = ['expanded' => true];
|
||||
|
||||
$name = 'answer';
|
||||
$elements[] = $mform->createElement('editor', $name, $label, $this->get_editor_attributes(), $this->get_editor_options());
|
||||
$elements[] = $mform->createElement('submit', $name . 'removeeditor', get_string('removeeditor', $plugin),
|
||||
array('onclick' => 'skipClientValidation = true;'));
|
||||
$options[$name] = array('type' => PARAM_RAW);
|
||||
['onclick' => 'skipClientValidation = true;']);
|
||||
$options[$name] = ['type' => PARAM_RAW];
|
||||
|
||||
$this->add_repeat_elements($mform, $name, $elements, $options);
|
||||
|
||||
@@ -156,10 +159,10 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
/**
|
||||
* Returns answer repeats count
|
||||
*
|
||||
* @param object $question
|
||||
* @param stdClass $question
|
||||
* @return int
|
||||
*/
|
||||
protected function get_answer_repeats($question) {
|
||||
protected function get_answer_repeats(stdClass $question): int {
|
||||
if (isset($question->id)) {
|
||||
$repeats = count($question->options->answers);
|
||||
} else {
|
||||
@@ -176,11 +179,11 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_editor_attributes() {
|
||||
return array(
|
||||
'rows' => self::TEXTFIELD_ROWS,
|
||||
'cols' => self::TEXTFIELD_COLS
|
||||
);
|
||||
protected function get_editor_attributes(): array {
|
||||
return [
|
||||
'rows' => self::TEXTFIELD_ROWS,
|
||||
'cols' => self::TEXTFIELD_COLS,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,45 +191,44 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_editor_options() {
|
||||
return array(
|
||||
'context' => $this->context,
|
||||
protected function get_editor_options(): array {
|
||||
return [
|
||||
'context' => $this->context,
|
||||
'maxfiles' => EDITOR_UNLIMITED_FILES,
|
||||
'noclean' => true
|
||||
);
|
||||
'noclean' => true,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets editor format to specified
|
||||
*
|
||||
* @param object $editor
|
||||
* @param int $format
|
||||
* @param MoodleQuickForm_editor $editor
|
||||
* @param int|string $format
|
||||
* @return int
|
||||
*/
|
||||
protected function reset_editor_format($editor, $format=FORMAT_MOODLE) {
|
||||
protected function reset_editor_format(MoodleQuickForm_editor $editor, int|string $format = FORMAT_MOODLE): int {
|
||||
$value = $editor->getValue();
|
||||
$value['format'] = $format;
|
||||
$value = $editor->setValue($value);
|
||||
$editor->setValue($value);
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust HTML editor and removal buttons.
|
||||
*
|
||||
* @param object $mform
|
||||
* @param MoodleQuickForm $mform
|
||||
* @param string $name
|
||||
* @param int $repeats
|
||||
*/
|
||||
protected function adjust_html_editors($mform, $name) {
|
||||
protected function adjust_html_editors(MoodleQuickForm $mform, string $name): void {
|
||||
|
||||
// Cache the number of formats supported
|
||||
// by the preferred editor for each format.
|
||||
$count = array();
|
||||
$count = [];
|
||||
|
||||
if (isset($this->question->options->answers)) {
|
||||
$ids = array_keys($this->question->options->answers);
|
||||
} else {
|
||||
$ids = array();
|
||||
$ids = [];
|
||||
}
|
||||
|
||||
$defaultanswerformat = get_config('qtype_ordering', 'defaultanswerformat');
|
||||
@@ -245,12 +247,7 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
|
||||
for ($i = 0; $i < $repeats; $i++) {
|
||||
$editor = $mform->getElement($name."[$i]");
|
||||
|
||||
if (isset($ids[$i])) {
|
||||
$id = $ids[$i];
|
||||
} else {
|
||||
$id = 0;
|
||||
}
|
||||
$id = $ids[$i] ?? 0;
|
||||
|
||||
// The old/new name of the button to remove the HTML editor
|
||||
// old : the name of the button when added by repeat_elements
|
||||
@@ -260,7 +257,7 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
|
||||
// Remove HTML editor, if necessary.
|
||||
if (optional_param($newname, 0, PARAM_RAW)) {
|
||||
$format = $this->reset_editor_format($editor, FORMAT_MOODLE);
|
||||
$format = $this->reset_editor_format($editor);
|
||||
$_POST['answer'][$i]['format'] = $format; // Overwrite incoming data.
|
||||
} else if ($id) {
|
||||
$format = $this->question->options->answers[$id]->answerformat;
|
||||
@@ -270,11 +267,12 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
|
||||
// Check we have a submit button - it should always be there !!
|
||||
if ($mform->elementExists($oldname)) {
|
||||
if (! isset($count[$format])) {
|
||||
if (!isset($count[$format])) {
|
||||
$editor = editors_get_preferred_editor($format);
|
||||
$count[$format] = $editor->get_supported_formats();
|
||||
$count[$format] = count($count[$format]);
|
||||
}
|
||||
|
||||
if ($count[$format] > 1) {
|
||||
$mform->removeElement($oldname);
|
||||
} else {
|
||||
@@ -293,7 +291,7 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
* @param string $withshownumpartscorrect Whether this quesiton type uses the 'Show num parts correct' option on hints.
|
||||
* @return array Form field elements for one hint.
|
||||
*/
|
||||
protected function get_hint_fields($withclearwrong = false, $withshownumpartscorrect = false) {
|
||||
protected function get_hint_fields($withclearwrong = false, $withshownumpartscorrect = false): array {
|
||||
$mform = $this->_form;
|
||||
|
||||
$repeated = [];
|
||||
@@ -320,12 +318,12 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an preprocessing needed on the data passed to {@link set_data()}
|
||||
* Perform any preprocessing needed on the data passed to {@see set_data()}
|
||||
* before it is used to initialise the form.
|
||||
* @param object $question the data being passed to the form.
|
||||
* @return object $question the modified data.
|
||||
* @return stdClass $question the modified data.
|
||||
*/
|
||||
public function data_preprocessing($question) {
|
||||
public function data_preprocessing($question): stdClass {
|
||||
|
||||
$question = parent::data_preprocessing($question);
|
||||
$question = $this->data_preprocessing_answers($question, true);
|
||||
@@ -336,11 +334,11 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
$question = $this->data_preprocessing_hints($question, false, true);
|
||||
|
||||
// Preprocess answers and fractions.
|
||||
$question->answer = array();
|
||||
$question->fraction = array();
|
||||
$question->answer = [];
|
||||
$question->fraction = [];
|
||||
|
||||
if (empty($question->options->answers)) {
|
||||
$answerids = array();
|
||||
$answerids = [];
|
||||
} else {
|
||||
$answerids = array_keys($question->options->answers);
|
||||
}
|
||||
@@ -352,8 +350,7 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
if ($answerid = array_shift($answerids)) {
|
||||
$answer = $question->options->answers[$answerid];
|
||||
} else {
|
||||
$answer = (object)array('answer' => '',
|
||||
'answerformat' => $defaultanswerformat);
|
||||
$answer = (object) ['answer' => '', 'answerformat' => $defaultanswerformat];
|
||||
$answerid = 0;
|
||||
}
|
||||
|
||||
@@ -363,29 +360,25 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
$itemid = file_get_submitted_draft_itemid("answer[$i]");
|
||||
$format = $answer->answerformat;
|
||||
$text = file_prepare_draft_area($itemid, $this->context->id, 'question', 'answer',
|
||||
$answerid, $this->editoroptions, $answer->answer);
|
||||
$question->answer[$i] = array('text' => $text,
|
||||
'format' => $format,
|
||||
'itemid' => $itemid);
|
||||
$answerid, $this->editoroptions, $answer->answer);
|
||||
$question->answer[$i] = ['text' => $text,
|
||||
'format' => $format,
|
||||
'itemid' => $itemid];
|
||||
}
|
||||
$question->fraction[$i] = ($i + 1);
|
||||
}
|
||||
|
||||
// Defining default values.
|
||||
$names = array(
|
||||
'layouttype' => qtype_ordering_question::LAYOUT_VERTICAL,
|
||||
'selecttype' => qtype_ordering_question::SELECT_ALL,
|
||||
$names = [
|
||||
'layouttype' => qtype_ordering_question::LAYOUT_VERTICAL,
|
||||
'selecttype' => qtype_ordering_question::SELECT_ALL,
|
||||
'selectcount' => 0, // 0 means ALL.
|
||||
'gradingtype' => qtype_ordering_question::GRADING_ABSOLUTE_POSITION,
|
||||
'showgrading' => 1, // 1 means SHOW.
|
||||
'numberingstyle' => qtype_ordering_question::NUMBERING_STYLE_DEFAULT
|
||||
);
|
||||
'numberingstyle' => qtype_ordering_question::NUMBERING_STYLE_DEFAULT,
|
||||
];
|
||||
foreach ($names as $name => $default) {
|
||||
if (isset($question->options->$name)) {
|
||||
$question->$name = $question->options->$name;
|
||||
} else {
|
||||
$question->$name = $this->get_default_value($name, $default);
|
||||
}
|
||||
$question->$name = $question->options->$name ?? $this->get_default_value($name, $default);
|
||||
}
|
||||
|
||||
return $question;
|
||||
@@ -397,9 +390,9 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
* @param object $question The data being passed to the form.
|
||||
* @param bool $withclearwrong Clear wrong hints.
|
||||
* @param bool $withshownumpartscorrect Show number correct.
|
||||
* @return object The modified data.
|
||||
* @return stdClass The modified data.
|
||||
*/
|
||||
protected function data_preprocessing_hints($question, $withclearwrong = false, $withshownumpartscorrect = false) {
|
||||
protected function data_preprocessing_hints($question, $withclearwrong = false, $withshownumpartscorrect = false): stdClass {
|
||||
if (empty($question->hints)) {
|
||||
return $question;
|
||||
}
|
||||
@@ -421,8 +414,8 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
* @return array of "element_name"=>"error_description" if there are errors,
|
||||
* or an empty array if everything is OK (true allowed for backwards compatibility too).
|
||||
*/
|
||||
public function validation($data, $files) {
|
||||
$errors = array();
|
||||
public function validation($data, $files): array {
|
||||
$errors = [];
|
||||
$plugin = 'qtype_ordering';
|
||||
|
||||
// Identify duplicates and report as an error.
|
||||
@@ -438,7 +431,7 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
$item = get_string('answerheader', $plugin);
|
||||
$item = str_replace('{no}', $i + 1, $item);
|
||||
$item = html_writer::link("#id_answerheader_$i", $item);
|
||||
$a = (object)array('text' => $answer, 'item' => $item);
|
||||
$a = (object) ['text' => $answer, 'item' => $item];
|
||||
$errors["answer[$answercount]"] = get_string('duplicatesnotallowed', $plugin, $a);
|
||||
} else {
|
||||
$answers[] = $answer;
|
||||
@@ -447,15 +440,20 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
}
|
||||
}
|
||||
|
||||
switch ($answercount) {
|
||||
case 0: $errors['answer[0]'] = get_string('notenoughanswers', $plugin, 2);
|
||||
case 1: $errors['answer[1]'] = get_string('notenoughanswers', $plugin, 2);
|
||||
// If there are no answers provided, show error message under first 2 answer boxes
|
||||
// If only 1 answer provided, show error message under second answer box
|
||||
if ($answercount < 2) {
|
||||
$errors['answer[1]'] = get_string('notenoughanswers', $plugin, 2);
|
||||
|
||||
if ($answercount == 0) {
|
||||
$errors['answer[0]'] = get_string('notenoughanswers', $plugin, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// If adding a new ordering question, update defaults.
|
||||
if (empty($errors) && empty($data['id'])) {
|
||||
$fields = array('layouttype', 'selecttype', 'selectcount',
|
||||
'gradingtype', 'showgrading', 'numberingstyle');
|
||||
$fields = ['layouttype', 'selecttype', 'selectcount',
|
||||
'gradingtype', 'showgrading', 'numberingstyle'];
|
||||
foreach ($fields as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
question_bank::get_qtype($this->qtype())->set_default_value($field, $data[$field]);
|
||||
@@ -473,22 +471,24 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
* @param string $name Item name
|
||||
* @return string full preference name
|
||||
*/
|
||||
protected function get_my_preference_name($name) {
|
||||
protected function get_my_preference_name(string $name): string {
|
||||
return $this->plugin_name()."_$name";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of countable item types
|
||||
*
|
||||
* @return array(type => description)
|
||||
* @param string $type
|
||||
* @param int $max
|
||||
* @return array (type => description)
|
||||
*/
|
||||
protected function get_addcount_options($type, $max=10) {
|
||||
protected function get_addcount_options(string $type, int $max = 10): array {
|
||||
|
||||
// Cache plugin name.
|
||||
$plugin = $this->plugin_name();
|
||||
|
||||
// Generate options.
|
||||
$options = array();
|
||||
$options = [];
|
||||
for ($i = 1; $i <= $max; $i++) {
|
||||
if ($i == 1) {
|
||||
$options[$i] = get_string('addsingle'.$type, $plugin);
|
||||
@@ -502,10 +502,13 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
/**
|
||||
* Add repeated elements with a button allowing a selectable number of new elements
|
||||
*
|
||||
* @param object $mform the Moodle form object
|
||||
* @return voide, but will update $mform
|
||||
* @param MoodleQuickForm $mform the Moodle form object
|
||||
* @param string $type
|
||||
* @param array $elements
|
||||
* @param array $options
|
||||
* @return void, but will update $mform
|
||||
*/
|
||||
protected function add_repeat_elements($mform, $type, $elements, $options) {
|
||||
protected function add_repeat_elements(MoodleQuickForm $mform, string $type, array $elements, array $options): void {
|
||||
|
||||
// Cache plugin name.
|
||||
$plugin = $this->plugin_name();
|
||||
@@ -531,10 +534,10 @@ class qtype_ordering_edit_form extends question_edit_form {
|
||||
|
||||
// ... and replace it with "Add" button + select group.
|
||||
$options = $this->get_addcount_options($type);
|
||||
$mform->addGroup(array(
|
||||
$mform->addGroup([
|
||||
$mform->createElement('submit', $addtypes, get_string('add')),
|
||||
$mform->createElement('select', $addtypescount, '', $options)
|
||||
), $addtypesgroup, '', ' ', false);
|
||||
], $addtypesgroup, '', ' ', false);
|
||||
|
||||
// Set default value and type of select element.
|
||||
$mform->setDefault($addtypescount, $count);
|
||||
|
||||
@@ -67,6 +67,24 @@ class qtype_ordering_question extends question_graded_automatically {
|
||||
/** @var int Items are graded relative to their position in the correct answer */
|
||||
const GRADING_RELATIVE_TO_CORRECT = 7;
|
||||
|
||||
/** @var int {@see LAYOUT_VERTICAL} or {@see LAYOUT_HORIZONTAL}. */
|
||||
public $layouttype;
|
||||
|
||||
/** @var int {@see SELECT_ALL}, {@see SELECT_RANDOM} or {@see SELECT_CONTIGUOUS}. */
|
||||
public $selecttype;
|
||||
|
||||
/** @var int if {@see $selecttype} is not SELECT_ALL, then the number to select. */
|
||||
public $selectcount;
|
||||
|
||||
/** @var int Which grading strategy to use. One of the GRADING_... constants. */
|
||||
public $gradingtype;
|
||||
|
||||
/** @var bool Should details of the grading calculation be shown to students. */
|
||||
public $showgrading;
|
||||
|
||||
/** @var string How to number the items. A key from the array returned by {@see get_numbering_styles()}. */
|
||||
public $numberingstyle;
|
||||
|
||||
// Fields from "qtype_ordering_options" table.
|
||||
/** @var string */
|
||||
public $correctfeedback;
|
||||
|
||||
@@ -36,28 +36,30 @@ class qtype_ordering extends question_type {
|
||||
const DEFAULT_NUM_HINTS = 2;
|
||||
|
||||
/** @var array Combined feedback fields */
|
||||
public $feedbackfields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
|
||||
public array $feedbackfields = ['correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback'];
|
||||
|
||||
/**
|
||||
* @return bool whether the question_answers.answer field needs to have
|
||||
* restore_decode_content_links_worker called on it.
|
||||
*/
|
||||
public function has_html_answers() {
|
||||
public function has_html_answers(): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If your question type has a table that extends the question table, and
|
||||
* you want the base class to automatically save, backup and restore the extra fields,
|
||||
* override this method to return an array wherer the first element is the table name,
|
||||
* override this method to return an array where the first element is the table name,
|
||||
* and the subsequent entries are the column names (apart from id and questionid).
|
||||
*
|
||||
* @return mixed array as above, or null to tell the base class to do nothing.
|
||||
* @return array extra fields
|
||||
*/
|
||||
public function extra_question_fields() {
|
||||
return array('qtype_ordering_options',
|
||||
'layouttype', 'selecttype', 'selectcount',
|
||||
'gradingtype', 'showgrading', 'numberingstyle');
|
||||
public function extra_question_fields(): array {
|
||||
return [
|
||||
'qtype_ordering_options',
|
||||
'layouttype', 'selecttype', 'selectcount',
|
||||
'gradingtype', 'showgrading', 'numberingstyle',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,15 +67,14 @@ class qtype_ordering extends question_type {
|
||||
* @param question_definition $question the question_definition we are creating.
|
||||
* @param object $questiondata the question data loaded from the database.
|
||||
*/
|
||||
protected function initialise_question_instance(question_definition $question, $questiondata) {
|
||||
protected function initialise_question_instance(question_definition $question, $questiondata): void {
|
||||
global $CFG;
|
||||
|
||||
parent::initialise_question_instance($question, $questiondata);
|
||||
|
||||
$question->answers = $questiondata->options->answers;
|
||||
foreach ($question->answers as $answerid => $answer) {
|
||||
$question->answers[$answerid]->md5key =
|
||||
'ordering_item_' . md5(($CFG->passwordsaltmain ?? '') . $answer->answer);
|
||||
$question->answers[$answerid]->md5key = 'ordering_item_' . md5(($CFG->passwordsaltmain ?? '') . $answer->answer);
|
||||
}
|
||||
|
||||
$question->options = clone($questiondata->options);
|
||||
@@ -85,19 +86,20 @@ class qtype_ordering extends question_type {
|
||||
/**
|
||||
* Saves question-type specific options
|
||||
*
|
||||
* This is called by {@link save_question()} to save the question-type specific data
|
||||
* @return object $result->error or $result->notice
|
||||
* @param object $question This holds the information from the editing form,
|
||||
* This is called by {@see save_question()} to save the question-type specific data
|
||||
*
|
||||
* @param object $question This holds the information from the editing form,
|
||||
* it is not a standard question object.
|
||||
* @return bool|stdClass $result->error or $result->notice
|
||||
*/
|
||||
public function save_question_options($question) {
|
||||
public function save_question_options($question): bool|stdClass {
|
||||
global $DB;
|
||||
|
||||
$result = new stdClass();
|
||||
$context = $question->context;
|
||||
|
||||
// Remove empty answers.
|
||||
$question->answer = array_filter($question->answer, array($this, 'is_not_blank'));
|
||||
$question->answer = array_filter($question->answer, [$this, 'is_not_blank']);
|
||||
$question->answer = array_values($question->answer); // Make keys sequential.
|
||||
|
||||
// Count how many answers we have.
|
||||
@@ -119,10 +121,10 @@ class qtype_ordering extends question_type {
|
||||
|
||||
$question->feedback = range(1, $countanswers);
|
||||
|
||||
if ($answerids = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC', 'id,question')) {
|
||||
if ($answerids = $DB->get_records('question_answers', ['question' => $question->id], 'id ASC', 'id,question')) {
|
||||
$answerids = array_keys($answerids);
|
||||
} else {
|
||||
$answerids = array();
|
||||
$answerids = [];
|
||||
}
|
||||
|
||||
// Insert all the new answers.
|
||||
@@ -163,24 +165,24 @@ class qtype_ordering extends question_type {
|
||||
$answertext = preg_replace($imgsearch, $imgreplace, $answertext);
|
||||
|
||||
// Prepare the $answer object.
|
||||
$answer = (object)array(
|
||||
'question' => $question->id,
|
||||
'fraction' => ($i + 1), // Start at 1.
|
||||
'answer' => $answertext,
|
||||
'answerformat' => $answerformat,
|
||||
'feedback' => '',
|
||||
$answer = (object) [
|
||||
'question' => $question->id,
|
||||
'fraction' => ($i + 1), // Start at 1.
|
||||
'answer' => $answertext,
|
||||
'answerformat' => $answerformat,
|
||||
'feedback' => '',
|
||||
'feedbackformat' => FORMAT_MOODLE,
|
||||
);
|
||||
];
|
||||
|
||||
// Add/insert $answer into the database.
|
||||
if ($answer->id = array_shift($answerids)) {
|
||||
if (! $DB->update_record('question_answers', $answer)) {
|
||||
if (!$DB->update_record('question_answers', $answer)) {
|
||||
$result->error = get_string('cannotupdaterecord', 'error', 'question_answers (id='.$answer->id.')');
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
unset($answer->id);
|
||||
if (! $answer->id = $DB->insert_record('question_answers', $answer)) {
|
||||
if (!$answer->id = $DB->insert_record('question_answers', $answer)) {
|
||||
$result->error = get_string('cannotinsertrecord', 'error', 'question_answers');
|
||||
return $result;
|
||||
}
|
||||
@@ -191,32 +193,32 @@ class qtype_ordering extends question_type {
|
||||
// because the answer id is used as the file's "itemid".
|
||||
if ($answeritemid) {
|
||||
$answertext = file_save_draft_area_files($answeritemid, $context->id, 'question', 'answer', $answer->id,
|
||||
$this->fileoptions, $answertext);
|
||||
$DB->set_field('question_answers', 'answer', $answertext, array('id' => $answer->id));
|
||||
$this->fileoptions, $answertext);
|
||||
$DB->set_field('question_answers', 'answer', $answertext, ['id' => $answer->id]);
|
||||
}
|
||||
}
|
||||
// Create $options for this ordering question.
|
||||
$options = (object)array(
|
||||
$options = (object) [
|
||||
'questionid' => $question->id,
|
||||
'layouttype' => $question->layouttype,
|
||||
'selecttype' => $question->selecttype,
|
||||
'selectcount' => $question->selectcount,
|
||||
'gradingtype' => $question->gradingtype,
|
||||
'showgrading' => $question->showgrading,
|
||||
'numberingstyle' => $question->numberingstyle
|
||||
);
|
||||
'numberingstyle' => $question->numberingstyle,
|
||||
];
|
||||
$options = $this->save_combined_feedback_helper($options, $question, $context, true);
|
||||
$this->save_hints($question, true);
|
||||
|
||||
// Add/update $options for this ordering question.
|
||||
if ($options->id = $DB->get_field('qtype_ordering_options', 'id', array('questionid' => $question->id))) {
|
||||
if (! $DB->update_record('qtype_ordering_options', $options)) {
|
||||
if ($options->id = $DB->get_field('qtype_ordering_options', 'id', ['questionid' => $question->id])) {
|
||||
if (!$DB->update_record('qtype_ordering_options', $options)) {
|
||||
$result->error = get_string('cannotupdaterecord', 'error', 'qtype_ordering_options (id='.$options->id.')');
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
unset($options->id);
|
||||
if (! $options->id = $DB->insert_record('qtype_ordering_options', $options)) {
|
||||
if (!$options->id = $DB->insert_record('qtype_ordering_options', $options)) {
|
||||
$result->error = get_string('cannotinsertrecord', 'error', 'qtype_ordering_options');
|
||||
return $result;
|
||||
}
|
||||
@@ -227,7 +229,7 @@ class qtype_ordering extends question_type {
|
||||
$fs = get_file_storage();
|
||||
foreach ($answerids as $answerid) {
|
||||
$fs->delete_area_files($context->id, 'question', 'answer', $answerid);
|
||||
$DB->delete_records('question_answers', array('id' => $answerid));
|
||||
$DB->delete_records('question_answers', ['id' => $answerid]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +243,7 @@ class qtype_ordering extends question_type {
|
||||
* @param bool $withparts Whether to take into account clearwrong and shownumcorrect options.
|
||||
* @return int Count of hints on the form.
|
||||
*/
|
||||
protected function count_hints_on_form($formdata, $withparts) {
|
||||
protected function count_hints_on_form($formdata, $withparts): int {
|
||||
$numhints = parent::count_hints_on_form($formdata, $withparts);
|
||||
|
||||
if (!empty($formdata->hintoptions)) {
|
||||
@@ -260,7 +262,7 @@ class qtype_ordering extends question_type {
|
||||
* @param bool $withparts whether to take into account clearwrong and shownumcorrect options.
|
||||
* @return bool is this particular hint data empty.
|
||||
*/
|
||||
protected function is_hint_empty_in_form_data($formdata, $number, $withparts) {
|
||||
protected function is_hint_empty_in_form_data($formdata, $number, $withparts): bool {
|
||||
return parent::is_hint_empty_in_form_data($formdata, $number, $withparts) &&
|
||||
empty($formdata->hintoptions[$number]);
|
||||
}
|
||||
@@ -271,9 +273,9 @@ class qtype_ordering extends question_type {
|
||||
* @param object $formdata the data from the form.
|
||||
* @param int $number number of hint to get options from.
|
||||
* @param bool $withparts whether question have parts.
|
||||
* @return string value to save into the options field of question_hints table.
|
||||
* @return bool value to save into the options field of question_hints table.
|
||||
*/
|
||||
protected function save_hint_options($formdata, $number, $withparts) {
|
||||
protected function save_hint_options($formdata, $number, $withparts): bool {
|
||||
return !empty($formdata->hintoptions[$number]);
|
||||
}
|
||||
|
||||
@@ -283,7 +285,7 @@ class qtype_ordering extends question_type {
|
||||
* @param object $hint The DB row from the question hints table.
|
||||
* @return question_hint_ordering Hints of question from record.
|
||||
*/
|
||||
protected function make_hint($hint) {
|
||||
protected function make_hint($hint): question_hint_ordering {
|
||||
return question_hint_ordering::load_from_record($hint);
|
||||
}
|
||||
|
||||
@@ -314,18 +316,18 @@ class qtype_ordering extends question_type {
|
||||
* @return array keys are subquestionid, values are arrays of possible
|
||||
* responses to that subquestion.
|
||||
*/
|
||||
public function get_possible_responses($questiondata) {
|
||||
$responseclasses = array();
|
||||
public function get_possible_responses($questiondata): array {
|
||||
$responseclasses = [];
|
||||
$itemcount = count($questiondata->options->answers);
|
||||
|
||||
$position = 0;
|
||||
foreach ($questiondata->options->answers as $answerid => $answer) {
|
||||
foreach ($questiondata->options->answers as $answer) {
|
||||
$position += 1;
|
||||
$classes = array();
|
||||
$classes = [];
|
||||
for ($i = 1; $i <= $itemcount; $i++) {
|
||||
$classes[$i] = new question_possible_response(
|
||||
get_string('positionx', 'qtype_ordering', $i),
|
||||
($i === $position) / $itemcount);
|
||||
get_string('positionx', 'qtype_ordering', $i),
|
||||
($i === $position) / $itemcount);
|
||||
}
|
||||
|
||||
$subqid = question_utils::to_plain_text($answer->answer, $answer->answerformat);
|
||||
@@ -342,7 +344,7 @@ class qtype_ordering extends question_type {
|
||||
* @param mixed $value
|
||||
* @return bool If true, this item should be saved.
|
||||
*/
|
||||
public function is_not_blank($value) {
|
||||
public function is_not_blank(mixed $value): bool {
|
||||
if (is_array($value)) {
|
||||
$value = $value['text'];
|
||||
}
|
||||
@@ -356,17 +358,17 @@ class qtype_ordering extends question_type {
|
||||
* This function loads any question type specific options for the
|
||||
* question from the database into the question object. This information
|
||||
* is placed in the $question->options field. A question type is
|
||||
* free, however, to decide on a internal structure of the options field.
|
||||
* free, however, to decide on an internal structure of the options field.
|
||||
* @return bool Indicates success or failure.
|
||||
* @param object $question The question object for the question. This object
|
||||
* should be updated to include the question type
|
||||
* specific information (it is passed by reference).
|
||||
*/
|
||||
public function get_question_options($question) {
|
||||
public function get_question_options($question): bool {
|
||||
global $DB, $OUTPUT;
|
||||
|
||||
// Load the options.
|
||||
if (!$question->options = $DB->get_record('qtype_ordering_options', array('questionid' => $question->id))) {
|
||||
if (!$question->options = $DB->get_record('qtype_ordering_options', ['questionid' => $question->id])) {
|
||||
echo $OUTPUT->notification('Error: Missing question options!');
|
||||
return false;
|
||||
}
|
||||
@@ -374,7 +376,7 @@ class qtype_ordering extends question_type {
|
||||
// Load the answers - "fraction" is used to signify the order of the answers,
|
||||
// with id as a tie-break which should not be required.
|
||||
if (!$question->options->answers = $DB->get_records('question_answers',
|
||||
array('question' => $question->id), 'fraction, id')) {
|
||||
['question' => $question->id], 'fraction, id')) {
|
||||
echo $OUTPUT->notification('Error: Missing question answers for ordering question ' . $question->id . '!');
|
||||
return false;
|
||||
}
|
||||
@@ -389,9 +391,9 @@ class qtype_ordering extends question_type {
|
||||
* @param int $questionid The id of question being deleted.
|
||||
* @param int $contextid the context this quesiotn belongs to.
|
||||
*/
|
||||
public function delete_question($questionid, $contextid) {
|
||||
public function delete_question($questionid, $contextid): void {
|
||||
global $DB;
|
||||
$DB->delete_records('qtype_ordering_options', array('questionid' => $questionid));
|
||||
$DB->delete_records('qtype_ordering_options', ['questionid' => $questionid]);
|
||||
parent::delete_question($questionid, $contextid);
|
||||
}
|
||||
|
||||
@@ -399,43 +401,42 @@ class qtype_ordering extends question_type {
|
||||
* Import question from GIFT format
|
||||
*
|
||||
* @param array $lines
|
||||
* @param object $question
|
||||
* @param stdClass $question
|
||||
* @param qformat_gift $format
|
||||
* @param string $extra (optional, default=null)
|
||||
* @return object Question instance
|
||||
* @param string|null $extra (optional, default=null)
|
||||
* @return stdClass|bool Question instance
|
||||
*/
|
||||
public function import_from_gift($lines, $question, $format, $extra=null) {
|
||||
public function import_from_gift(array $lines, stdClass $question, qformat_gift $format, string $extra = null): bool|stdClass {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/question/type/ordering/question.php');
|
||||
|
||||
// Extract question info from GIFT file $lines.
|
||||
$questionname = '[^{]*';
|
||||
$selectcount = '\d+';
|
||||
$selecttype = '(?:ALL|EXACT|'.
|
||||
'RANDOM|REL|'.
|
||||
'CONTIGUOUS|CONTIG)?';
|
||||
'RANDOM|REL|'.
|
||||
'CONTIGUOUS|CONTIG)?';
|
||||
$layouttype = '(?:HORIZONTAL|HORI|H|1|'.
|
||||
'VERTICAL|VERT|V|0)?';
|
||||
'VERTICAL|VERT|V|0)?';
|
||||
$gradingtype = '(?:ALL_OR_NOTHING|'.
|
||||
'ABSOLUTE_POSITION|'.
|
||||
'ABSOLUTE|ABS|'.
|
||||
'RELATIVE_NEXT_EXCLUDE_LAST|'.
|
||||
'RELATIVE_NEXT_INCLUDE_LAST|'.
|
||||
'RELATIVE_ONE_PREVIOUS_AND_NEXT|'.
|
||||
'RELATIVE_ALL_PREVIOUS_AND_NEXT|'.
|
||||
'RELATIVE_TO_CORRECT|'.
|
||||
'RELATIVE|REL'.
|
||||
'LONGEST_ORDERED_SUBSET|'.
|
||||
'LONGEST_CONTIGUOUS_SUBSET)?';
|
||||
'ABSOLUTE_POSITION|'.
|
||||
'ABSOLUTE|ABS|'.
|
||||
'RELATIVE_NEXT_EXCLUDE_LAST|'.
|
||||
'RELATIVE_NEXT_INCLUDE_LAST|'.
|
||||
'RELATIVE_ONE_PREVIOUS_AND_NEXT|'.
|
||||
'RELATIVE_ALL_PREVIOUS_AND_NEXT|'.
|
||||
'RELATIVE_TO_CORRECT|'.
|
||||
'RELATIVE|REL'.
|
||||
'LONGEST_ORDERED_SUBSET|'.
|
||||
'LONGEST_CONTIGUOUS_SUBSET)?';
|
||||
$showgrading = '(?:SHOW|TRUE|YES|1|HIDE|FALSE|NO|0)?';
|
||||
$numberingstyle = '(?:none|123|abc|ABCD|iii|IIII)?';
|
||||
$search = '/^\s*>\s*('.$selectcount.')\s*'.
|
||||
'('.$selecttype.')\s*'.
|
||||
'('.$layouttype.')\s*'.
|
||||
'('.$gradingtype.')\s*'.
|
||||
'('.$showgrading.')\s*'.
|
||||
'('.$numberingstyle.')\s*'.
|
||||
'(.*?)\s*$/s';
|
||||
'('.$selecttype.')\s*'.
|
||||
'('.$layouttype.')\s*'.
|
||||
'('.$gradingtype.')\s*'.
|
||||
'('.$showgrading.')\s*'.
|
||||
'('.$numberingstyle.')\s*'.
|
||||
'(.*?)\s*$/s';
|
||||
// Item $1 the number of items to be shown.
|
||||
// Item $2 the extraction/grading type.
|
||||
// Item $3 the layout type.
|
||||
@@ -443,10 +444,10 @@ class qtype_ordering extends question_type {
|
||||
// Item $5 show the grading details (SHOW/HIDE).
|
||||
// Item $6 the numbering style (none/123/abc/...).
|
||||
// Item $7 the lines of items to be ordered.
|
||||
if (! $extra) {
|
||||
if (!$extra) {
|
||||
return false; // Format not recognized.
|
||||
}
|
||||
if (! preg_match($search, $extra, $matches)) {
|
||||
if (!preg_match($search, $extra, $matches)) {
|
||||
return false; // Format not recognized.
|
||||
}
|
||||
|
||||
@@ -469,7 +470,7 @@ class qtype_ordering extends question_type {
|
||||
|
||||
// Extract name.
|
||||
$name = false;
|
||||
if (substr($text, 0, 2) == '::') {
|
||||
if (str_starts_with($text, '::')) {
|
||||
$text = substr($text, 2);
|
||||
$pos = strpos($text, '::');
|
||||
if (is_numeric($pos)) {
|
||||
@@ -481,7 +482,7 @@ class qtype_ordering extends question_type {
|
||||
|
||||
// Extract question text format.
|
||||
$format = FORMAT_MOODLE;
|
||||
if (substr($text, 0, 1) == '[') {
|
||||
if (str_starts_with($text, '[')) {
|
||||
$text = substr($text, 1);
|
||||
$pos = strpos($text, ']');
|
||||
if (is_numeric($pos)) {
|
||||
@@ -521,18 +522,18 @@ class qtype_ordering extends question_type {
|
||||
$selectcount = min(6, count($answers));
|
||||
}
|
||||
$this->set_options_for_import($question, $layouttype, $selecttype, $selectcount,
|
||||
$gradingtype, $showgrading, $numberingstyle);
|
||||
$gradingtype, $showgrading, $numberingstyle);
|
||||
|
||||
// Remove blank items.
|
||||
$answers = array_map('trim', $answers);
|
||||
$answers = array_filter($answers); // Remove blanks.
|
||||
|
||||
// Set up answer arrays.
|
||||
$question->answer = array();
|
||||
$question->answerformat = array();
|
||||
$question->fraction = array();
|
||||
$question->feedback = array();
|
||||
$question->feedbackformat = array();
|
||||
$question->answer = [];
|
||||
$question->answerformat = [];
|
||||
$question->fraction = [];
|
||||
$question->feedback = [];
|
||||
$question->feedbackformat = [];
|
||||
|
||||
// Note that "fraction" field is used to denote sort order
|
||||
// "fraction" fields will be set to correct values later
|
||||
@@ -555,12 +556,12 @@ class qtype_ordering extends question_type {
|
||||
/**
|
||||
* Check that the required feedback fields exist
|
||||
*
|
||||
* @param object $question
|
||||
* @param stdClass $question
|
||||
*/
|
||||
protected function check_ordering_combined_feedback(&$question) {
|
||||
protected function check_ordering_combined_feedback(stdClass $question): void {
|
||||
foreach ($this->feedbackfields as $field) {
|
||||
if (empty($question->$field)) {
|
||||
$question->$field = array('text' => '', 'format' => FORMAT_MOODLE, 'itemid' => 0, 'files' => null);
|
||||
$question->$field = ['text' => '', 'format' => FORMAT_MOODLE, 'itemid' => 0, 'files' => null];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,78 +570,42 @@ class qtype_ordering extends question_type {
|
||||
* Given question object, returns array with array layouttype, selecttype, selectcount, gradingtype, showgrading
|
||||
* where layouttype, selecttype, gradingtype and showgrading are string representations.
|
||||
*
|
||||
* @param object $question
|
||||
* @param stdClass $question
|
||||
* @return array(layouttype, selecttype, selectcount, gradingtype, $showgrading, $numberingstyle)
|
||||
*/
|
||||
public function extract_options_for_export($question) {
|
||||
public function extract_options_for_export(stdClass $question): array {
|
||||
|
||||
switch ($question->options->layouttype) {
|
||||
case qtype_ordering_question::LAYOUT_VERTICAL:
|
||||
$layouttype = 'VERTICAL';
|
||||
break;
|
||||
case qtype_ordering_question::LAYOUT_HORIZONTAL:
|
||||
$layouttype = 'HORIZONTAL';
|
||||
break;
|
||||
default:
|
||||
$layouttype = ''; // Shouldn't happen !!
|
||||
}
|
||||
$layouttype = match ($question->options->layouttype) {
|
||||
qtype_ordering_question::LAYOUT_VERTICAL => 'VERTICAL',
|
||||
qtype_ordering_question::LAYOUT_HORIZONTAL => 'HORIZONTAL',
|
||||
default => '', // Shouldn't happen !!
|
||||
};
|
||||
|
||||
switch ($question->options->selecttype) {
|
||||
case qtype_ordering_question::SELECT_ALL:
|
||||
$selecttype = 'ALL';
|
||||
break;
|
||||
case qtype_ordering_question::SELECT_RANDOM:
|
||||
$selecttype = 'RANDOM';
|
||||
break;
|
||||
case qtype_ordering_question::SELECT_CONTIGUOUS:
|
||||
$selecttype = 'CONTIGUOUS';
|
||||
break;
|
||||
default:
|
||||
$selecttype = ''; // Shouldn't happen !!
|
||||
}
|
||||
$selecttype = match ($question->options->selecttype) {
|
||||
qtype_ordering_question::SELECT_ALL => 'ALL',
|
||||
qtype_ordering_question::SELECT_RANDOM => 'RANDOM',
|
||||
qtype_ordering_question::SELECT_CONTIGUOUS => 'CONTIGUOUS',
|
||||
default => '', // Shouldn't happen !!
|
||||
};
|
||||
|
||||
switch ($question->options->gradingtype) {
|
||||
case qtype_ordering_question::GRADING_ALL_OR_NOTHING:
|
||||
$gradingtype = 'ALL_OR_NOTHING';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_ABSOLUTE_POSITION:
|
||||
$gradingtype = 'ABSOLUTE_POSITION';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST:
|
||||
$gradingtype = 'RELATIVE_NEXT_EXCLUDE_LAST';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_RELATIVE_NEXT_INCLUDE_LAST:
|
||||
$gradingtype = 'RELATIVE_NEXT_INCLUDE_LAST';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT:
|
||||
$gradingtype = 'RELATIVE_ONE_PREVIOUS_AND_NEXT';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT:
|
||||
$gradingtype = 'RELATIVE_ALL_PREVIOUS_AND_NEXT';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_LONGEST_ORDERED_SUBSET:
|
||||
$gradingtype = 'LONGEST_ORDERED_SUBSET';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_LONGEST_CONTIGUOUS_SUBSET:
|
||||
$gradingtype = 'LONGEST_CONTIGUOUS_SUBSET';
|
||||
break;
|
||||
case qtype_ordering_question::GRADING_RELATIVE_TO_CORRECT:
|
||||
$gradingtype = 'RELATIVE_TO_CORRECT';
|
||||
break;
|
||||
default:
|
||||
$gradingtype = ''; // Shouldn't happen !!
|
||||
}
|
||||
$gradingtype = match ($question->options->gradingtype) {
|
||||
qtype_ordering_question::GRADING_ALL_OR_NOTHING => 'ALL_OR_NOTHING',
|
||||
qtype_ordering_question::GRADING_ABSOLUTE_POSITION => 'ABSOLUTE_POSITION',
|
||||
qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST => 'RELATIVE_NEXT_EXCLUDE_LAST',
|
||||
qtype_ordering_question::GRADING_RELATIVE_NEXT_INCLUDE_LAST => 'RELATIVE_NEXT_INCLUDE_LAST',
|
||||
qtype_ordering_question::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT => 'RELATIVE_ONE_PREVIOUS_AND_NEXT',
|
||||
qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT => 'RELATIVE_ALL_PREVIOUS_AND_NEXT',
|
||||
qtype_ordering_question::GRADING_LONGEST_ORDERED_SUBSET => 'LONGEST_ORDERED_SUBSET',
|
||||
qtype_ordering_question::GRADING_LONGEST_CONTIGUOUS_SUBSET => 'LONGEST_CONTIGUOUS_SUBSET',
|
||||
qtype_ordering_question::GRADING_RELATIVE_TO_CORRECT => 'RELATIVE_TO_CORRECT',
|
||||
default => '', // Shouldn't happen !!
|
||||
};
|
||||
|
||||
switch ($question->options->showgrading) {
|
||||
case 0:
|
||||
$showgrading = 'HIDE';
|
||||
break;
|
||||
case 1:
|
||||
$showgrading = 'SHOW';
|
||||
break;
|
||||
default:
|
||||
$showgrading = ''; // Shouldn't happen !!
|
||||
}
|
||||
$showgrading = match ($question->options->showgrading) {
|
||||
0 => 'HIDE',
|
||||
1 => 'SHOW',
|
||||
default => '', // Shouldn't happen !!
|
||||
};
|
||||
|
||||
if (empty($question->options->numberingstyle)) {
|
||||
$numberingstyle = qtype_ordering_question::NUMBERING_STYLE_DEFAULT;
|
||||
@@ -651,18 +616,18 @@ class qtype_ordering extends question_type {
|
||||
// Note: this used to be (selectcount + 2).
|
||||
$selectcount = $question->options->selectcount;
|
||||
|
||||
return array($layouttype, $selecttype, $selectcount, $gradingtype, $showgrading, $numberingstyle);
|
||||
return [$layouttype, $selecttype, $selectcount, $gradingtype, $showgrading, $numberingstyle];
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports question to GIFT format
|
||||
*
|
||||
* @param object $question
|
||||
* @param stdClass $question
|
||||
* @param qformat_gift $format
|
||||
* @param string $extra (optional, default=null)
|
||||
* @param string|null $extra (optional, default=null)
|
||||
* @return string GIFT representation of question
|
||||
*/
|
||||
public function export_to_gift($question, $format, $extra=null) {
|
||||
public function export_to_gift(stdClass $question, qformat_gift $format, string $extra = null): string {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/question/type/ordering/question.php');
|
||||
|
||||
@@ -672,25 +637,18 @@ class qtype_ordering extends question_type {
|
||||
$output .= '::'.$question->name.'::';
|
||||
}
|
||||
|
||||
switch ($question->questiontextformat) {
|
||||
case FORMAT_HTML:
|
||||
$output .= '[html]';
|
||||
break;
|
||||
case FORMAT_PLAIN:
|
||||
$output .= '[plain]';
|
||||
break;
|
||||
case FORMAT_MARKDOWN:
|
||||
$output .= '[markdown]';
|
||||
break;
|
||||
case FORMAT_MOODLE:
|
||||
$output .= '[moodle]';
|
||||
break;
|
||||
}
|
||||
$output .= match ($question->questiontextformat) {
|
||||
FORMAT_HTML => '[html]',
|
||||
FORMAT_PLAIN => '[plain]',
|
||||
FORMAT_MARKDOWN => '[markdown]',
|
||||
FORMAT_MOODLE => '[moodle]',
|
||||
default => '',
|
||||
};
|
||||
|
||||
$output .= $question->questiontext.'{';
|
||||
|
||||
list($layouttype, $selecttype, $selectcount, $gradingtype, $showgrading, $numberingstyle) =
|
||||
$this->extract_options_for_export($question);
|
||||
$this->extract_options_for_export($question);
|
||||
$output .= ">$selectcount $selecttype $layouttype $gradingtype $showgrading $numberingstyle".PHP_EOL;
|
||||
|
||||
foreach ($question->options->answers as $answer) {
|
||||
@@ -709,12 +667,12 @@ class qtype_ordering extends question_type {
|
||||
* @param string $extra (optional, default=null)
|
||||
* @return string XML representation of question
|
||||
*/
|
||||
public function export_to_xml($question, qformat_xml $format, $extra=null) {
|
||||
public function export_to_xml($question, qformat_xml $format, $extra = null): string {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/question/type/ordering/question.php');
|
||||
|
||||
list($layouttype, $selecttype, $selectcount, $gradingtype, $showgrading, $numberingstyle) =
|
||||
$this->extract_options_for_export($question);
|
||||
$this->extract_options_for_export($question);
|
||||
|
||||
$output = '';
|
||||
$output .= " <layouttype>$layouttype</layouttype>\n";
|
||||
@@ -734,7 +692,7 @@ class qtype_ordering extends question_type {
|
||||
foreach ($question->options->answers as $answer) {
|
||||
$output .= ' <answer fraction="'.$answer->fraction.'" '.$format->format($answer->answerformat).">\n";
|
||||
$output .= $format->writetext($answer->answer, 3);
|
||||
if ($feedback = trim($answer->feedback)) { // Usually there is no feedback.
|
||||
if (trim($answer->feedback)) { // Usually there is no feedback.
|
||||
$output .= ' <feedback '.$format->format($answer->feedbackformat).">\n";
|
||||
$output .= $format->writetext($answer->feedback, 4);
|
||||
$output .= $format->write_files($answer->feedbackfiles);
|
||||
@@ -755,14 +713,14 @@ class qtype_ordering extends question_type {
|
||||
* @param array $data
|
||||
* @param qtype_ordering $question (or null)
|
||||
* @param qformat_xml $format
|
||||
* @param string $extra (optional, default=null)
|
||||
* @return object New question object
|
||||
* @param null $extra (optional, default=null)
|
||||
* @return object|bool New question object
|
||||
*/
|
||||
public function import_from_xml($data, $question, qformat_xml $format, $extra=null) {
|
||||
public function import_from_xml($data, $question, qformat_xml $format, $extra = null): object|bool {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/question/type/ordering/question.php');
|
||||
|
||||
$questiontype = $format->getpath($data, array('@', 'type'), '');
|
||||
$questiontype = $format->getpath($data, ['@', 'type'], '');
|
||||
|
||||
if ($questiontype != 'ordering') {
|
||||
return false;
|
||||
@@ -783,23 +741,23 @@ class qtype_ordering extends question_type {
|
||||
$selecttype = 'logical';
|
||||
$selectcount = 'studentsee';
|
||||
}
|
||||
$layouttype = $format->getpath($data, array('#', 'layouttype', 0, '#'), 'VERTICAL');
|
||||
$selecttype = $format->getpath($data, array('#', $selecttype, 0, '#'), 'RANDOM');
|
||||
$selectcount = $format->getpath($data, array('#', $selectcount, 0, '#'), 6);
|
||||
$gradingtype = $format->getpath($data, array('#', 'gradingtype', 0, '#'), 'RELATIVE');
|
||||
$showgrading = $format->getpath($data, array('#', 'showgrading', 0, '#'), '1');
|
||||
$numberingstyle = $format->getpath($data, array('#', 'numberingstyle', 0, '#'), '1');
|
||||
$layouttype = $format->getpath($data, ['#', 'layouttype', 0, '#'], 'VERTICAL');
|
||||
$selecttype = $format->getpath($data, ['#', $selecttype, 0, '#'], 'RANDOM');
|
||||
$selectcount = $format->getpath($data, ['#', $selectcount, 0, '#'], 6);
|
||||
$gradingtype = $format->getpath($data, ['#', 'gradingtype', 0, '#'], 'RELATIVE');
|
||||
$showgrading = $format->getpath($data, ['#', 'showgrading', 0, '#'], '1');
|
||||
$numberingstyle = $format->getpath($data, ['#', 'numberingstyle', 0, '#'], '1');
|
||||
$this->set_options_for_import($newquestion, $layouttype, $selecttype, $selectcount,
|
||||
$gradingtype, $showgrading, $numberingstyle);
|
||||
$gradingtype, $showgrading, $numberingstyle);
|
||||
|
||||
$newquestion->answer = array();
|
||||
$newquestion->answerformat = array();
|
||||
$newquestion->fraction = array();
|
||||
$newquestion->feedback = array();
|
||||
$newquestion->feedbackformat = array();
|
||||
$newquestion->answer = [];
|
||||
$newquestion->answerformat = [];
|
||||
$newquestion->fraction = [];
|
||||
$newquestion->feedback = [];
|
||||
$newquestion->feedbackformat = [];
|
||||
|
||||
$i = 0;
|
||||
while ($answer = $format->getpath($data, array('#', 'answer', $i), '')) {
|
||||
while ($answer = $format->getpath($data, ['#', 'answer', $i], '')) {
|
||||
$ans = $format->import_answer($answer, true, $format->get_format($newquestion->questiontextformat));
|
||||
$newquestion->answer[$i] = $ans->answer;
|
||||
$newquestion->fraction[$i] = 1; // Will be reset later in save_question_options().
|
||||
@@ -807,7 +765,7 @@ class qtype_ordering extends question_type {
|
||||
$i++;
|
||||
}
|
||||
|
||||
$format->import_combined_feedback($newquestion, $data, false);
|
||||
$format->import_combined_feedback($newquestion, $data);
|
||||
$newquestion->shownumcorrect = $format->getpath($data, ['#', 'shownumcorrect', 0, '#'], null);
|
||||
// Check that the required feedback fields exist.
|
||||
$this->check_ordering_combined_feedback($newquestion);
|
||||
@@ -842,7 +800,7 @@ class qtype_ordering extends question_type {
|
||||
* @param integer $maxnamelength (optional, default=42)
|
||||
* @return string Fixed name
|
||||
*/
|
||||
public function fix_questionname($name, $defaultname='', $maxnamelength = 42) {
|
||||
public function fix_questionname(string $name, string $defaultname = '', int $maxnamelength = 42): string {
|
||||
if (trim($name) == '') {
|
||||
if ($defaultname) {
|
||||
$name = $defaultname;
|
||||
@@ -863,58 +821,29 @@ class qtype_ordering extends question_type {
|
||||
/**
|
||||
* Set layouttype, selecttype, selectcount, gradingtype, showgrading based on their textual representation
|
||||
*
|
||||
* @param object $question (passed by reference)
|
||||
* @param string $layout the layout type
|
||||
* @param string $select the select type
|
||||
* @param string $count the number of items to display
|
||||
* @param string $grading the grading type
|
||||
* @param string $show the grading details or not
|
||||
* @param stdClass $question the question object
|
||||
* @param string $layouttype the layout type
|
||||
* @param string $selecttype the select type
|
||||
* @param string $selectcount the number of items to display
|
||||
* @param string $gradingtype the grading type
|
||||
* @param string $showgrading the grading details or not
|
||||
* @param string $numberingstyle the numbering style
|
||||
*/
|
||||
public function set_options_for_import(&$question, $layouttype, $selecttype, $selectcount,
|
||||
$gradingtype, $showgrading, $numberingstyle) {
|
||||
public function set_options_for_import(stdClass $question, string $layouttype, string $selecttype, string $selectcount,
|
||||
string $gradingtype, string $showgrading, string $numberingstyle): void {
|
||||
|
||||
// Set "layouttype" option.
|
||||
switch (strtoupper($layouttype)) {
|
||||
|
||||
case 'HORIZONTAL':
|
||||
case 'HORI':
|
||||
case 'H':
|
||||
case '1':
|
||||
$question->layouttype = qtype_ordering_question::LAYOUT_HORIZONTAL;
|
||||
break;
|
||||
|
||||
case 'VERTICAL':
|
||||
case 'VERT':
|
||||
case 'V':
|
||||
case '0':
|
||||
$question->layouttype = qtype_ordering_question::LAYOUT_VERTICAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
$question->layouttype = qtype_ordering_question::LAYOUT_VERTICAL;
|
||||
}
|
||||
$question->layouttype = match (strtoupper($layouttype)) {
|
||||
'HORIZONTAL', 'HORI', 'H', '1' => qtype_ordering_question::LAYOUT_HORIZONTAL,
|
||||
default => qtype_ordering_question::LAYOUT_VERTICAL,
|
||||
};
|
||||
|
||||
// Set "selecttype" option.
|
||||
switch (strtoupper($selecttype)) {
|
||||
|
||||
case 'ALL':
|
||||
case 'EXACT':
|
||||
$question->selecttype = qtype_ordering_question::SELECT_ALL;
|
||||
break;
|
||||
|
||||
case 'RANDOM':
|
||||
case 'REL':
|
||||
$question->selecttype = qtype_ordering_question::SELECT_RANDOM;
|
||||
break;
|
||||
|
||||
case 'CONTIGUOUS':
|
||||
case 'CONTIG':
|
||||
$question->selecttype = qtype_ordering_question::SELECT_CONTIGUOUS;
|
||||
break;
|
||||
|
||||
default:
|
||||
$question->selecttype = qtype_ordering_question::SELECT_RANDOM;
|
||||
}
|
||||
$question->selecttype = match (strtoupper($selecttype)) {
|
||||
'ALL', 'EXACT' => qtype_ordering_question::SELECT_ALL,
|
||||
'CONTIGUOUS', 'CONTIG' => qtype_ordering_question::SELECT_CONTIGUOUS,
|
||||
default => qtype_ordering_question::SELECT_RANDOM,
|
||||
};
|
||||
|
||||
// Set "selectcount" option - this used to be ($count - 2).
|
||||
if (is_numeric($selectcount)) {
|
||||
@@ -924,96 +853,39 @@ class qtype_ordering extends question_type {
|
||||
}
|
||||
|
||||
// Set "gradingtype" option.
|
||||
switch (strtoupper($gradingtype)) {
|
||||
|
||||
case 'ALL_OR_NOTHING':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_ALL_OR_NOTHING;
|
||||
break;
|
||||
|
||||
case 'ABS':
|
||||
case 'ABSOLUTE':
|
||||
case 'ABSOLUTE_POSITION':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_ABSOLUTE_POSITION;
|
||||
break;
|
||||
|
||||
case 'REL':
|
||||
case 'RELATIVE':
|
||||
case 'RELATIVE_NEXT_EXCLUDE_LAST':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST;
|
||||
break;
|
||||
|
||||
case 'RELATIVE_NEXT_INCLUDE_LAST':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_RELATIVE_NEXT_INCLUDE_LAST;
|
||||
break;
|
||||
|
||||
case 'RELATIVE_ONE_PREVIOUS_AND_NEXT':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT;
|
||||
break;
|
||||
|
||||
case 'RELATIVE_ALL_PREVIOUS_AND_NEXT':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT;
|
||||
break;
|
||||
|
||||
case 'LONGEST_ORDERED_SUBSET':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_LONGEST_ORDERED_SUBSET;
|
||||
break;
|
||||
|
||||
case 'LONGEST_CONTIGUOUS_SUBSET':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_LONGEST_CONTIGUOUS_SUBSET;
|
||||
break;
|
||||
|
||||
case 'RELATIVE_TO_CORRECT':
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_RELATIVE_TO_CORRECT;
|
||||
break;
|
||||
|
||||
default:
|
||||
$question->gradingtype = qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST;
|
||||
}
|
||||
$question->gradingtype = match (strtoupper($gradingtype)) {
|
||||
'ALL_OR_NOTHING' => qtype_ordering_question::GRADING_ALL_OR_NOTHING,
|
||||
'ABS', 'ABSOLUTE', 'ABSOLUTE_POSITION' => qtype_ordering_question::GRADING_ABSOLUTE_POSITION,
|
||||
'RELATIVE_NEXT_INCLUDE_LAST' => qtype_ordering_question::GRADING_RELATIVE_NEXT_INCLUDE_LAST,
|
||||
'RELATIVE_ONE_PREVIOUS_AND_NEXT' => qtype_ordering_question::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT,
|
||||
'RELATIVE_ALL_PREVIOUS_AND_NEXT' => qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT,
|
||||
'LONGEST_ORDERED_SUBSET' => qtype_ordering_question::GRADING_LONGEST_ORDERED_SUBSET,
|
||||
'LONGEST_CONTIGUOUS_SUBSET' => qtype_ordering_question::GRADING_LONGEST_CONTIGUOUS_SUBSET,
|
||||
'RELATIVE_TO_CORRECT' => qtype_ordering_question::GRADING_RELATIVE_TO_CORRECT,
|
||||
default => qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST,
|
||||
};
|
||||
|
||||
// Set "showgrading" option.
|
||||
switch (strtoupper($showgrading)) {
|
||||
|
||||
case 'SHOW':
|
||||
case 'TRUE':
|
||||
case 'YES':
|
||||
$question->showgrading = 1;
|
||||
break;
|
||||
|
||||
case 'HIDE':
|
||||
case 'FALSE':
|
||||
case 'NO':
|
||||
$question->showgrading = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
$question->showgrading = 1;
|
||||
break;
|
||||
}
|
||||
$question->showgrading = match (strtoupper($showgrading)) {
|
||||
'HIDE', 'FALSE', 'NO' => 0,
|
||||
default => 1,
|
||||
};
|
||||
|
||||
// Set "numberingstyle" option.
|
||||
switch ($numberingstyle) {
|
||||
|
||||
case 'none':
|
||||
case '123':
|
||||
case 'abc':
|
||||
case 'ABCD':
|
||||
case 'iii':
|
||||
case 'IIII':
|
||||
$question->numberingstyle = $numberingstyle;
|
||||
break;
|
||||
|
||||
default:
|
||||
$question->numberingstyle = qtype_ordering_question::NUMBERING_STYLE_DEFAULT;
|
||||
}
|
||||
$question->numberingstyle = match ($numberingstyle) {
|
||||
'none', '123', 'abc', 'ABCD', 'iii', 'IIII' => $numberingstyle,
|
||||
default => qtype_ordering_question::NUMBERING_STYLE_DEFAULT,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the answer numbering style.
|
||||
* This method is used by "tests/questiontype_test.php".
|
||||
* @param $questiondata
|
||||
*
|
||||
* @param stdClass $questiondata
|
||||
* @return string
|
||||
*/
|
||||
public function get_numberingstyle($questiondata) {
|
||||
public function get_numberingstyle(stdClass $questiondata): string {
|
||||
return $questiondata->options->numberingstyle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,12 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
}
|
||||
|
||||
// In the multi-tries, the highlight response base on the hint highlight option.
|
||||
if (isset($options->highlightresponse) && $options->highlightresponse) {
|
||||
$hint = null;
|
||||
if (method_exists($qa->get_behaviour(), 'get_applicable_hint')) {
|
||||
/** @var \qtype_ordering\question_hint_ordering $hint */
|
||||
$hint = $qa->get_behaviour()->get_applicable_hint();
|
||||
}
|
||||
if ($hint && $hint->highlightresponse) {
|
||||
$sortablelist .= ' notactive';
|
||||
}
|
||||
|
||||
@@ -153,7 +158,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($options->highlightresponse) && $options->highlightresponse) {
|
||||
if ($hint && $hint->highlightresponse) {
|
||||
$score = $this->get_ordering_item_score($question, $position, $answerid);
|
||||
// To do: we need image calculation here in MDL-79873.
|
||||
list($score, $maxscore, $fraction, $percent, $class, $img) = $score;
|
||||
|
||||
Reference in New Issue
Block a user