diff --git a/question/type/gapselect/questionbase.php b/question/type/gapselect/questionbase.php index 21fbf3b81a0..52857eeb45a 100755 --- a/question/type/gapselect/questionbase.php +++ b/question/type/gapselect/questionbase.php @@ -17,8 +17,8 @@ /** - * Definition class for embedded element in question text question. Parent of drag and drop and select from - * drop down list and ?others? * + * Definition class for embedded element in question text question. Parent of + * gap-select, drag and drop and possibly others. * * @package qtype * @subpackage gapselect @@ -34,7 +34,7 @@ * @copyright 2009 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class qtype_gapselect_question_base extends question_graded_automatically_with_countback { +abstract class qtype_gapselect_question_base extends question_graded_automatically_with_countback { /** @var boolean Whether the question stems should be shuffled. */ public $shufflechoices; @@ -89,12 +89,12 @@ class qtype_gapselect_question_base extends question_graded_automatically_with_c } public function get_question_summary() { - $question = html_to_text($this->format_questiontext(), 0, false); + $question = $this->html_to_text($this->questiontext); $groups = array(); foreach ($this->choices as $group => $choices) { $cs = array(); foreach ($choices as $choice) { - $cs[] = html_to_text($this->format_text($choice->text), 0, false); + $cs[] = $this->html_to_text($choice->text); } $groups[] = '[[' . $group . ']] -> {' . implode(' / ', $cs) . '}'; } @@ -112,8 +112,8 @@ class qtype_gapselect_question_base extends question_graded_automatically_with_c foreach ($this->places as $place => $group) { if (array_key_exists($this->field($place), $response) && $response[$this->field($place)]) { - $choices[] = '{' . html_to_text($this->format_text($this->get_selected_choice( - $group, $response[$this->field($place)])->text), 0, false) . '}'; + $choices[] = '{' . $this->html_to_text($this->get_selected_choice( + $group, $response[$this->field($place)])->text) . '}'; $allblank = false; } else { $choices[] = '{}'; @@ -278,7 +278,7 @@ class qtype_gapselect_question_base extends question_graded_automatically_with_c $choiceno = $this->choiceorder[$group][$response[$fieldname]]; $choice = $this->choices[$group][$choiceno]; $parts[$place] = new question_classified_response( - $choiceno, html_to_text($this->format_text($choice->text), 0, false), + $choiceno, $this->html_to_text($choice->text), $this->get_right_choice_for($place) == $response[$fieldname]); } return $parts; diff --git a/question/type/gapselect/questiontypebase.php b/question/type/gapselect/questiontypebase.php index e0cc3d97841..7b3b336c63f 100755 --- a/question/type/gapselect/questiontypebase.php +++ b/question/type/gapselect/questiontypebase.php @@ -37,7 +37,7 @@ require_once($CFG->dirroot . '/question/format/xml/format.php'); * @copyright 2009 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class qtype_gapselect_base extends question_type { +abstract class qtype_gapselect_base extends question_type { /** * Choices are stored in the question_answers table, and any options need to * be put into the feedback field somehow. This method is responsible for @@ -93,7 +93,7 @@ class qtype_gapselect_base extends question_type { } $update = true; - $options = get_record('question_'.$this->name(), 'questionid', $question->id); + $options = get_record('question_' . $this->name(), 'questionid', $question->id); if (!$options) { $update = false; $options = new stdClass; @@ -152,10 +152,7 @@ class qtype_gapselect_base extends question_type { $question->shufflechoices = $questiondata->options->shuffleanswers; - $question->correctfeedback = $questiondata->options->correctfeedback; - $question->partiallycorrectfeedback = $questiondata->options->partiallycorrectfeedback; - $question->incorrectfeedback = $questiondata->options->incorrectfeedback; - $question->shownumcorrect = $questiondata->options->shownumcorrect; + $this->initialise_combined_feedback($question, $questiondata, true); $question->choices = array(); $choiceindexmap= array(); @@ -235,7 +232,8 @@ class qtype_gapselect_base extends question_type { return $answers; } - /* This method gets the choices (answers) and sort them by groups + /** + * This method gets the choices (answers) and sort them by groups * in a 2 dimentional array. * * @param object $question @@ -244,10 +242,10 @@ class qtype_gapselect_base extends question_type { protected function get_array_of_groups($question, $state) { $answers = $this->get_array_of_choices($question); $arr = array(); - for($group=1;$groupget_group_of_players ($question, $state, $answers, $group); - if($players) { - $arr [$group]= $players; + for ($group=1; $group < count($answers); $group++) { + $players = $this->get_group_of_players($question, $state, $answers, $group); + if ($players) { + $arr[$group]= $players; } } return $arr; @@ -322,7 +320,7 @@ class qtype_gapselect_base extends question_type { foreach ($question->choices[$group] as $i => $choice) { $choices[$i] = new question_possible_response( - html_to_text($question->format_text($choice->text), 0, false), + $question->html_to_text($choice->text), $question->rightchoices[$place] == $i); } $choices[null] = question_possible_response::no_response(); diff --git a/question/type/gapselect/renderer.php b/question/type/gapselect/renderer.php index 62f14470ab5..c5b8a7e623c 100755 --- a/question/type/gapselect/renderer.php +++ b/question/type/gapselect/renderer.php @@ -45,8 +45,8 @@ class qtype_gapselect_renderer extends qtype_elements_embedded_in_question_text_ $attributes = array( 'id' => $this->box_id($qa, 'p' . $place, $group), - 'class' => 'group' . $group ); + $groupclass = 'group' . $group; if ($options->readonly) { $attributes['disabled'] = 'disabled'; @@ -68,7 +68,8 @@ class qtype_gapselect_renderer extends qtype_elements_embedded_in_question_text_ } } - return html_writer::select($selectoptions, $qa->get_qt_field_name($fieldname), $value, ' ', $attributes) . ' ' . $feedbackimage; + $selecthtml = html_writer::select($selectoptions, $qa->get_qt_field_name($fieldname), $value, ' ', $attributes) . ' ' . $feedbackimage; + return html_writer::tag('span', $selecthtml, array('class' => 'control '.$groupclass)); } } diff --git a/question/type/gapselect/rendererbase.php b/question/type/gapselect/rendererbase.php index 283b5b5ece5..9d9170d0117 100755 --- a/question/type/gapselect/rendererbase.php +++ b/question/type/gapselect/rendererbase.php @@ -3,7 +3,7 @@ * Generates the output for question types where the question includes embedded interactive elements in the * question text. * - * @copyright 2010 The Open University + * @copyright 2011 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class qtype_elements_embedded_in_question_text_renderer extends qtype_with_combined_feedback_renderer { @@ -20,9 +20,9 @@ abstract class qtype_elements_embedded_in_question_text_renderer extends qtype_w $questiontext .= $fragment; } - $result = ''; - $result .= html_writer::tag('div', $question->format_text($questiontext), + $result .= html_writer::tag('div', $question->format_text($questiontext, + $qa, 'question', 'questiontext', $question->id), array('class' => $this->qtext_classname(), 'id' => $qa->get_qt_field_name(''))); $result .= $this->post_qtext_elements($qa, $options); diff --git a/question/type/gapselect/simpletest/testquestiontype.php b/question/type/gapselect/simpletest/testquestiontype.php index 1cfcfcbb76e..dc8b364c313 100755 --- a/question/type/gapselect/simpletest/testquestiontype.php +++ b/question/type/gapselect/simpletest/testquestiontype.php @@ -20,7 +20,7 @@ * Unit tests for the select missing words question question definition class. * * @package qtype_gapselect - * @copyright 2010 The Open University + * @copyright 2011 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/question/type/gapselect/simpletest/testwalkthrough.php b/question/type/gapselect/simpletest/testwalkthrough.php index 26b0cc681ed..e3dc5d0864c 100755 --- a/question/type/gapselect/simpletest/testwalkthrough.php +++ b/question/type/gapselect/simpletest/testwalkthrough.php @@ -32,6 +32,111 @@ require_once($CFG->dirroot . '/question/type/gapselect/simpletest/helper.php'); class qtype_gapselect_walkthrough_test extends qbehaviour_walkthrough_test_base { + public function test_interactive_behaviour() { + // Create a gapselect question. + $q = qtype_gapselect_test_helper::make_a_gapselect_question(); + $q->hints = array( + new question_hint_with_parts('This is the first hint.', false, false), + new question_hint_with_parts('This is the second hint.', true, true), + ); + $ql->shufflechoices = false; + $this->start_attempt_at_question($q, 'interactive', 3); + // Check the initial state. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_select_expectation('p1', + array('' => ' ', '1' => 'quick', '2' => 'slow'), null, true), + $this->get_contains_select_expectation('p2', + array('' => ' ', '1' => 'fox', '2' => 'dog'), null, true), + $this->get_contains_select_expectation('p3', + array('' => ' ', '1' => 'lazy', '2' => 'assiduous'), null, true), + $this->get_contains_submit_button_expectation(true), + $this->get_does_not_contain_feedback_expectation(), + $this->get_tries_remaining_expectation(3), + $this->get_no_hint_visible_expectation()); + + // Save the wrong answer. + $this->process_submission(array('p1' => '2', 'p2' => '2', 'p3' => '2')); + + // Verify. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_select_expectation('p1', + array('' => ' ', '1' => 'quick', '2' => 'slow'), 2, true), + $this->get_contains_select_expectation('p2', + array('' => ' ', '1' => 'fox', '2' => 'dog'), 2, true), + $this->get_contains_select_expectation('p3', + array('' => ' ', '1' => 'lazy', '2' => 'assiduous'), 2, true), + $this->get_contains_submit_button_expectation(true), + $this->get_does_not_contain_correctness_expectation(), + $this->get_does_not_contain_feedback_expectation(), + $this->get_tries_remaining_expectation(3), + $this->get_no_hint_visible_expectation()); + + // Submit the wrong answer. + $this->process_submission(array('p1' => '2', 'p2' => '2', 'p3' => '2', '-submit' => 1)); + + // Verify. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_select_expectation('p1', + array('' => ' ', '1' => 'quick', '2' => 'slow'), 2, false), + $this->get_contains_select_expectation('p2', + array('' => ' ', '1' => 'fox', '2' => 'dog'), 2, false), + $this->get_contains_select_expectation('p3', + array('' => ' ', '1' => 'lazy', '2' => 'assiduous'), 2, false), + $this->get_contains_submit_button_expectation(false), + $this->get_contains_try_again_button_expectation(true), + $this->get_does_not_contain_correctness_expectation(), + new PatternExpectation('/' . preg_quote(get_string('notcomplete', 'qbehaviour_interactive')) . '/'), + $this->get_contains_hint_expectation('This is the first hint')); + + // Do try again. + $this->process_submission(array('-tryagain' => 1)); + + // Verify. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_select_expectation('p1', + array('' => ' ', '1' => 'quick', '2' => 'slow'), 2, true), + $this->get_contains_select_expectation('p2', + array('' => ' ', '1' => 'fox', '2' => 'dog'), 2, true), + $this->get_contains_select_expectation('p3', + array('' => ' ', '1' => 'lazy', '2' => 'assiduous'), 2, true), + $this->get_contains_submit_button_expectation(true), + $this->get_does_not_contain_correctness_expectation(), + $this->get_does_not_contain_feedback_expectation(), + $this->get_tries_remaining_expectation(2), + $this->get_no_hint_visible_expectation()); + + // Submit the right answer. + $this->process_submission(array('p1' => '1', 'p2' => '1', 'p3' => '1', '-submit' => 1)); + + // Verify. + $this->check_current_state(question_state::$gradedright); + $this->check_current_mark(2); + $this->check_current_output( + $this->get_contains_select_expectation('p1', + array('' => ' ', '1' => 'quick', '2' => 'slow'), 1, false), + $this->get_contains_select_expectation('p2', + array('' => ' ', '1' => 'fox', '2' => 'dog'), 1, false), + $this->get_contains_select_expectation('p3', + array('' => ' ', '1' => 'lazy', '2' => 'assiduous'), 1, false), + $this->get_contains_submit_button_expectation(false), + $this->get_contains_correct_expectation(), + $this->get_no_hint_visible_expectation()); + + // Check regrading does not mess anything up. + $this->quba->regrade_all_questions(); + + // Verify. + $this->check_current_state(question_state::$gradedright); + $this->check_current_mark(2); + } } diff --git a/question/type/gapselect/styles.css b/question/type/gapselect/styles.css index 09f1c147503..309b3b2508e 100755 --- a/question/type/gapselect/styles.css +++ b/question/type/gapselect/styles.css @@ -39,3 +39,6 @@ .que.gapselect .group8 { background-color: #F0E68C; } +.que.sddl .control { + padding: 0.2em; +}