MDL-27505 Remove the ou-specific question types from the main branch.
authorTim Hunt <T.J.Hunt@open.ac.uk>
Mon, 16 May 2011 07:27:12 +0000 (08:27 +0100)
committerTim Hunt <T.J.Hunt@open.ac.uk>
Mon, 16 May 2011 07:30:44 +0000 (08:30 +0100)
The OU question types are now available from https://github.com/timhunt.

73 files changed:
question/behaviour/opaque/behaviour.php [deleted file]
question/behaviour/opaque/lang/en/qbehaviour_opaque.php [deleted file]
question/behaviour/opaque/renderer.php [deleted file]
question/behaviour/opaque/simpletest/testopaquebehaviour.php [deleted file]
question/type/ddwtos/backup/moodle2/backup_qtype_ddwtos_plugin.class.php [deleted file]
question/type/ddwtos/backup/moodle2/restore_qtype_ddwtos_plugin.class.php [deleted file]
question/type/ddwtos/db/install.xml [deleted file]
question/type/ddwtos/edit_ddwtos_form.php [deleted file]
question/type/ddwtos/lang/en/qtype_ddwtos.php [deleted file]
question/type/ddwtos/pix/icon.gif [deleted file]
question/type/ddwtos/question.php [deleted file]
question/type/ddwtos/questiontype.php [deleted file]
question/type/ddwtos/renderer.php [deleted file]
question/type/ddwtos/script.js [deleted file]
question/type/ddwtos/simpletest/helper.php [deleted file]
question/type/ddwtos/simpletest/testquestion.php [deleted file]
question/type/ddwtos/simpletest/testquestiontype.php [deleted file]
question/type/ddwtos/simpletest/testwalkthrough.php [deleted file]
question/type/ddwtos/styles.css [deleted file]
question/type/ddwtos/version.php [deleted file]
question/type/gapselect/backup/moodle2/backup_qtype_gapselect_plugin.class.php [deleted file]
question/type/gapselect/backup/moodle2/restore_qtype_gapselect_plugin.class.php [deleted file]
question/type/gapselect/db/install.xml [deleted file]
question/type/gapselect/edit_form_base.php [deleted file]
question/type/gapselect/edit_gapselect_form.php [deleted file]
question/type/gapselect/lang/en/qtype_gapselect.php [deleted file]
question/type/gapselect/pix/icon.gif [deleted file]
question/type/gapselect/question.php [deleted file]
question/type/gapselect/questionbase.php [deleted file]
question/type/gapselect/questiontype.php [deleted file]
question/type/gapselect/questiontypebase.php [deleted file]
question/type/gapselect/renderer.php [deleted file]
question/type/gapselect/rendererbase.php [deleted file]
question/type/gapselect/simpletest/helper.php [deleted file]
question/type/gapselect/simpletest/testquestion.php [deleted file]
question/type/gapselect/simpletest/testquestiontype.php [deleted file]
question/type/gapselect/simpletest/testwalkthrough.php [deleted file]
question/type/gapselect/styles.css [deleted file]
question/type/gapselect/version.php [deleted file]
question/type/opaque/backup/moodle2/backup_qtype_opaque_plugin.class.php [deleted file]
question/type/opaque/backup/moodle2/restore_qtype_opaque_plugin.class.php [deleted file]
question/type/opaque/db/install.xml [deleted file]
question/type/opaque/edit_engine_form.php [deleted file]
question/type/opaque/edit_opaque_form.php [deleted file]
question/type/opaque/editengine.php [deleted file]
question/type/opaque/engines.php [deleted file]
question/type/opaque/file.php [deleted file]
question/type/opaque/lang/en/qtype_opaque.php [deleted file]
question/type/opaque/locallib.php [deleted file]
question/type/opaque/pix/icon.gif [deleted file]
question/type/opaque/question.php [deleted file]
question/type/opaque/questiontype.php [deleted file]
question/type/opaque/renderer.php [deleted file]
question/type/opaque/settings.php [deleted file]
question/type/opaque/simpletest/testlocallib.php [deleted file]
question/type/opaque/simpletest/testquestiontype.php [deleted file]
question/type/opaque/styles.css [deleted file]
question/type/opaque/testengine.php [deleted file]
question/type/opaque/version.php [deleted file]
question/type/oumultiresponse/backup/moodle2/backup_qtype_oumultiresponse_plugin.class.php [deleted file]
question/type/oumultiresponse/backup/moodle2/restore_qtype_oumultiresponse_plugin.class.php [deleted file]
question/type/oumultiresponse/db/install.xml [deleted file]
question/type/oumultiresponse/edit_oumultiresponse_form.php [deleted file]
question/type/oumultiresponse/lang/en/qtype_oumultiresponse.php [deleted file]
question/type/oumultiresponse/pix/icon.gif [deleted file]
question/type/oumultiresponse/question.php [deleted file]
question/type/oumultiresponse/questiontype.php [deleted file]
question/type/oumultiresponse/simpletest/helper.php [deleted file]
question/type/oumultiresponse/simpletest/testquestion.php [deleted file]
question/type/oumultiresponse/simpletest/testquestiontype.php [deleted file]
question/type/oumultiresponse/simpletest/testwalkthrough.php [deleted file]
question/type/oumultiresponse/styles.css [deleted file]
question/type/oumultiresponse/version.php [deleted file]

diff --git a/question/behaviour/opaque/behaviour.php b/question/behaviour/opaque/behaviour.php
deleted file mode 100644 (file)
index 0b155f0..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * This behaviour that is used when the actual qim was not
- * available.
- *
- * @package    qbehaviour
- * @subpackage opaque
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * This behaviour is specifically for use with the Opaque question type.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qbehaviour_opaque extends question_behaviour {
-    /** @var string */
-    protected $preferredbehaviour;
-    /** @var string */
-    protected $questionsummary;
-
-    public function __construct(question_attempt $qa, $preferredbehaviour) {
-        parent::__construct($qa, $preferredbehaviour);
-        $this->preferredbehaviour = $preferredbehaviour;
-    }
-
-    public function required_question_definition_type() {
-        return 'qtype_opaque_question';
-    }
-
-    public function get_state_string($showcorrectness) {
-        $state = $this->qa->get_state();
-        $omstate = $this->qa->get_last_behaviour_var('_statestring');
-        if ($state->is_finished()) {
-            return $state->default_string($showcorrectness);
-        } else if ($omstate) {
-            return $omstate;
-        } else {
-            return get_string('notcomplete', 'qbehaviour_opaque');
-        }
-    }
-
-    public function init_first_step(question_attempt_step $step) {
-        global $USER;
-
-        // Set up the random seed to be the current time in milliseconds.
-        list($micros, $sec) = explode(' ', microtime());
-        $step->set_behaviour_var('_randomseed', $sec . floor($micros * 1000));
-        $step->set_behaviour_var('_userid', $USER->id);
-        $step->set_behaviour_var('_language', current_language());
-        $step->set_behaviour_var('_preferredbehaviour', $this->preferredbehaviour);
-        $opaquestate = qtype_opaque_update_state($this->qa, $step);
-        $step->set_behaviour_var('_statestring', $opaquestate->progressinfo);
-
-        // Remember the question summary.
-        $this->questionsummary = html_to_text($opaquestate->xhtml, 0, false);
-    }
-
-    public function get_question_summary() {
-        return $this->questionsummary;
-    }
-
-    protected function is_same_response(question_attempt_step $pendingstep) {
-        $newdata = $pendingstep->get_submitted_data();
-
-        foreach ($newdata as $key => $ignored) {
-            // If an omact_ button has been clicked, never treat this as a duplicate submission.
-            if (strpos($key, 'omact_') === 0) {
-                return false;
-            }
-        }
-
-        $olddata = $this->qa->get_last_step()->get_submitted_data();
-        return question_utils::arrays_have_same_keys_and_values($newdata, $olddata);
-    }
-
-    public function summarise_action(question_attempt_step $step) {
-        if ($step->has_behaviour_var('finish')) {
-            return $this->summarise_finish($step);
-        } else if ($step->has_behaviour_var('comment')) {
-            return $this->summarise_manual_comment($step);
-        } else {
-            $data = qtype_opaque_get_submitted_data($step);
-            $formatteddata = array();
-            foreach ($data as $name => $value) {
-                $formatteddata[] = $name . ' => ' . s($value);
-            }
-            if ($formatteddata) {
-                return get_string('submitted', 'question', implode(', ', $formatteddata));
-            } else {
-                return $this->summarise_start($step);
-            }
-        }
-    }
-
-    public function process_action(question_attempt_pending_step $pendingstep) {
-        if ($pendingstep->has_behaviour_var('finish')) {
-            return $this->process_finish($pendingstep);
-        }
-        if ($pendingstep->has_behaviour_var('comment')) {
-            return $this->process_comment($pendingstep);
-        } else if ($this->is_same_response($pendingstep) ||
-                $this->qa->get_state()->is_finished()) {
-            return question_attempt::DISCARD;
-        } else {
-            return $this->process_remote_action($pendingstep);
-        }
-    }
-
-    public function process_finish(question_attempt_pending_step $pendingstep) {
-        if ($this->qa->get_state()->is_finished()) {
-            return question_attempt::DISCARD;
-        }
-
-        // Try to get the question to stop.
-        $result = $this->process_remote_action($pendingstep);
-
-        if ($result == question_attempt::KEEP && !$this->qa->get_state()->is_finished()) {
-            // They tried to finish but the question is not finished, so all we
-            // can do is to set the state to gave up. This lets the renderer
-            // handle the review page appropriately.
-            $pendingstep->set_state(question_state::$gaveup);
-        }
-        return $result;
-    }
-
-    public function process_remote_action(question_attempt_pending_step $pendingstep) {
-        try {
-            $opaquestate = qtype_opaque_update_state($this->qa, $pendingstep);
-        } catch (SoapFault $sf) {
-            print_object($sf);
-            return question_attempt::DISCARD; // TODO better Opaque error handling.
-        }
-
-        if ($opaquestate->resultssequencenumber != $this->qa->get_num_steps()) {
-            $pendingstep->set_state(question_state::$todo);
-            $pendingstep->set_behaviour_var('_statestring', $opaquestate->progressinfo);
-
-        } else {
-            // Look for a score on the default axis.
-            $pendingstep->set_fraction(0);
-            foreach ($opaquestate->results->scores as $score) {
-                if ($score->axis == '') {
-                    $pendingstep->set_fraction($score->marks / $this->question->defaultmark);
-                }
-            }
-
-            if ($opaquestate->results->attempts > 0) {
-                $pendingstep->set_state(question_state::$gradedright);
-            } else {
-                $pendingstep->set_state(
-                        question_state::graded_state_for_fraction($pendingstep->get_fraction()));
-            }
-
-            if (!empty($opaquestate->results->questionLine)) {
-                $this->qa->set_question_summary(
-                        $this->cleanup_results($opaquestate->results->questionLine));
-            }
-            if (!empty($opaquestate->results->answerLine)) {
-                $pendingstep->set_new_response_summary(
-                        $this->cleanup_results($opaquestate->results->answerLine));
-            }
-            if (!empty($opaquestate->results->actionSummary)) {
-                $pendingstep->set_behaviour_var('_actionsummary',
-                        $this->cleanup_results($opaquestate->results->actionSummary));
-            }
-        }
-
-        return question_attempt::KEEP;
-    }
-
-    protected function cleanup_results($line) {
-        return preg_replace('/\\s+/', ' ', $line);
-    }
-}
diff --git a/question/behaviour/opaque/lang/en/qbehaviour_opaque.php b/question/behaviour/opaque/lang/en/qbehaviour_opaque.php
deleted file mode 100644 (file)
index 7ea3bb3..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Strings for component 'qbehaviour_opaque', language 'en'.
- *
- * @package    qbehaviour
- * @subpackage opaque
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-$string['notcomplete'] = 'Not complete';
-$string['pluginname'] = 'Question managed by a remote engine';
diff --git a/question/behaviour/opaque/renderer.php b/question/behaviour/opaque/renderer.php
deleted file mode 100644 (file)
index 8feaf81..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Defines the renderer for the Opaque behaviour.
- *
- * @package    qbehaviour
- * @subpackage opaque
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Renderer for outputting parts of a question when the actual behaviour
- * used is not available.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qbehaviour_opaque_renderer extends qbehaviour_renderer {
-    public function controls(question_attempt $qa, question_display_options $options) {
-        if ($qa->get_state()->is_gave_up()) {
-            return html_writer::tag('div', get_string('notcompletedmessage', 'qtype_opaque'),
-                    array('class' => 'question_aborted'));
-        }
-
-        try {
-            $opaquestate = qtype_opaque_update_state($qa);
-        } catch (SoapFault $sf) {
-            return html_writer::tag('div', get_string('errorconnecting', 'qtype_opaque') .
-                    html_writer::tag('pre', get_string('soapfault', 'qtype_opaque', $sf),
-                            array('class' => 'notifytiny')),
-                    array('class' => 'opaqueerror'));
-        }
-
-        return html_writer::tag('div', $opaquestate->xhtml,
-                array('class' => qtype_opaque_browser_type()));
-    }
-
-    public function head_code(question_attempt $qa) {
-        $output = '';
-        try {
-            $opaquestate = qtype_opaque_update_state($qa);
-        } catch (SoapFault $sf) {
-            // Errors are reported properly elsewhere.
-            return '';
-        }
-
-        $question = $qa->get_question();
-        $resourcecache = new qtype_opaque_resource_cache($question->engineid,
-                $question->remoteid, $question->remoteversion);
-
-        if (!empty($opaquestate->cssfilename) &&
-                $resourcecache->file_in_cache($opaquestate->cssfilename)) {
-            $this->page->requires->css($resourcecache->file_url($opaquestate->cssfilename));
-        }
-
-        return $output;
-    }
-}
\ No newline at end of file
diff --git a/question/behaviour/opaque/simpletest/testopaquebehaviour.php b/question/behaviour/opaque/simpletest/testopaquebehaviour.php
deleted file mode 100644 (file)
index 12d975d..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * This file contains tests for the Opaque behaviour.
- *
- * @package    qbehaviour
- * @subpackage opaque
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once(dirname(__FILE__) . '/../../../engine/lib.php');
-require_once(dirname(__FILE__) . '/../../../engine/simpletest/helpers.php');
-require_once(dirname(__FILE__) . '/../behaviour.php');
-
-
-/**
- * Unit tests for the Opaque behaviour.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qbehaviour_opaque_test extends qbehaviour_walkthrough_test_base {
-    /**
-     * Makes an Opaque question that refers to one of the sample questions
-     * supplied by OpenMark.
-     * @return unknown_type
-     */
-    protected function make_standard_om_question() {
-        global $DB;
-        $engineid = $DB->get_field('question_opaque_engines', 'MIN(id)', array());
-        if (empty($engineid)) {
-            throw new coding_exception('Cannot test Opaque. No question engines configured.');
-        }
-
-        question_bank::load_question_definition_classes('opaque');
-        $q = new qtype_opaque_question();
-        test_question_maker::initialise_a_question($q);
-
-        $q->name = 'samples.mu120.module5.question01';
-        $q->qtype = question_bank::get_qtype('opaque');
-        $q->defaultmark = 3;
-
-        $q->engineid = $engineid;
-        $q->remoteid = 'samples.mu120.module5.question01';
-        $q->remoteversion = '1.0';
-
-        return $q;
-    }
-
-    public function test_wrong_three_times() {
-        $q = $this->make_standard_om_question();
-        $this->start_attempt_at_question($q, 'interactive');
-        $qa = $this->quba->get_question_attempt($this->slot);
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/Below is a plan of a proposed garden/'),
-                new PatternExpectation('/You have 3 attempts/'),
-                $this->get_contains_button_expectation(
-                        $qa->get_qt_field_name('omact_gen_14'), 'Check'));
-        $this->assertPattern('/^\s*Below is a plan of a proposed garden./',
-                $qa->get_question_summary());
-        $this->assertNull($qa->get_right_answer_summary());
-
-        // Submit a wrong answer.
-        $this->process_submission(array('omval_response1' => 1, 'omval_response2' => 666,
-                'omact_gen_14' => 'Check'));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/Below is a plan of a proposed garden/'),
-                new PatternExpectation('/incorrect/'),
-                new PatternExpectation('/' .
-                        preg_quote(get_string('notcomplete', 'qbehaviour_opaque')) . '/'),
-                $this->get_contains_button_expectation(
-                        $qa->get_qt_field_name('omact_ok'), 'Try again'));
-
-        // Try again.
-        $this->process_submission(array('omact_ok' => 'Try again'));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/You have 2 attempts/'));
-
-        // Submit a wrong answer again.
-        $this->process_submission(array('omval_response1' => 1, 'omval_response2' => 666,
-                'omact_gen_14' => 'Check'));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/Below is a plan of a proposed garden/'),
-                new PatternExpectation('/still incorrect/'),
-                new PatternExpectation('/' .
-                        preg_quote(get_string('notcomplete', 'qbehaviour_opaque')) . '/'));
-
-        // Try again.
-        $this->process_submission(array('omact_ok' => 'Try again'));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/This is your last attempt/'));
-
-        // Submit a wrong answer third time.
-        $this->process_submission(array('omval_response1' => 1, 'omval_response2' => 666,
-                'omact_gen_14' => 'Check'));
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedwrong);
-        $this->check_current_mark(0);
-        $this->check_current_output(
-                new PatternExpectation(
-                        '/Please see MU120 Preparatory Resource Book B section 5.1/'),
-                new PatternExpectation('/still incorrect/'));
-        $this->assertTrue(preg_match(
-                '/What is \(X\*W\) (\d+\.\d+)\*(\d+), \(X\*L\)(\d+\.\d+)\*(\d+)\?/',
-                $qa->get_question_summary(), $matches));
-        $this->assertNull($qa->get_right_answer_summary());
-        $this->assertPattern('/' . $matches[1]*$matches[2] . '.*, ' . $matches[3]*$matches[4] . '/',
-                $qa->get_response_summary());
-    }
-
-    public function test_right_first_time() {
-        $q = $this->make_standard_om_question();
-        $this->start_attempt_at_question($q, 'interactive');
-        $qa = $this->quba->get_question_attempt($this->slot);
-
-        // Work out right answer (yuck!)
-        $html = $this->quba->render_question($this->slot, $this->displayoptions);
-        preg_match('/(0\.5|2\.0|3\.0) metres/', $html, $matches);
-        $scale = $matches[1];
-        preg_match('/Patio|Summer House|Flowerbed|Vegetable Plot|Pond/', $html, $matches);
-        $feature = $matches[0];
-        $sizes = array(
-            'Patio' => array(4, 7),
-            'Summer House' => array(3, 5),
-            'Flowerbed' => array(2, 7),
-            'Vegetable Plot' => array(3, 10),
-            'Pond' => array(2, 3),
-        );
-        $size = $sizes[$feature];
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/Below is a plan of a proposed garden/'),
-                new PatternExpectation('/You have 3 attempts/'),
-                $this->get_contains_button_expectation(
-                        $qa->get_qt_field_name('omact_gen_14'), 'Check'));
-
-        // Submit the right answer.
-        $this->process_submission(array('omval_response1' => $size[0] * $scale,
-                'omval_response2' => $size[1] * $scale, 'omact_gen_14' => 'Check'));
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedright);
-        $this->check_current_mark(3);
-        $this->check_current_output(
-                new PatternExpectation('/Below is a plan of a proposed garden/'),
-                new PatternExpectation('/correct/'));
-    }
-
-    public function test_different_max() {
-        $q = $this->make_standard_om_question();
-        $this->start_attempt_at_question($q, 'interactive', 6.0);
-        $qa = $this->quba->get_question_attempt($this->slot);
-
-        // Work out right answer (yuck!)
-        $html = $this->quba->render_question($this->slot, $this->displayoptions);
-        preg_match('/(0\.5|2\.0|3\.0) metres/', $html, $matches);
-        $scale = $matches[1];
-        preg_match('/Patio|Summer House|Flowerbed|Vegetable Plot|Pond/', $html, $matches);
-        $feature = $matches[0];
-        $sizes = array(
-            'Patio' => array(4, 7),
-            'Summer House' => array(3, 5),
-            'Flowerbed' => array(2, 7),
-            'Vegetable Plot' => array(3, 10),
-            'Pond' => array(2, 3),
-        );
-        $size = $sizes[$feature];
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/Below is a plan of a proposed garden/'),
-                new PatternExpectation('/You have 3 attempts/'),
-                $this->get_contains_button_expectation(
-                        $qa->get_qt_field_name('omact_gen_14'), 'Check'));
-
-        // Submit the right answer.
-        $this->process_submission(array('omval_response1' => $size[0] * $scale,
-                'omval_response2' => $size[1] * $scale, 'omact_gen_14' => 'Check'));
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedright);
-        $this->check_current_mark(6);
-        $this->check_current_output(
-                new PatternExpectation('/Below is a plan of a proposed garden/'),
-                new PatternExpectation('/correct/'));
-    }
-
-    public function test_gave_up() {
-        $q = $this->make_standard_om_question();
-        $this->start_attempt_at_question($q, 'interactive');
-
-        $this->quba->finish_all_questions();
-
-        $this->check_current_state(question_state::$gaveup);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                new PatternExpectation('/' .
-                        preg_quote(get_string('notcompletedmessage', 'qtype_opaque')) . '/'));
-    }
-}
diff --git a/question/type/ddwtos/backup/moodle2/backup_qtype_ddwtos_plugin.class.php b/question/type/ddwtos/backup/moodle2/backup_qtype_ddwtos_plugin.class.php
deleted file mode 100644 (file)
index 89cb186..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * @package    moodlecore
- * @subpackage backup-moodle2
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Provides the information to backup ddwtos questions
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class backup_qtype_ddwtos_plugin extends backup_qtype_plugin {
-
-    /**
-     * Returns the qtype information to attach to question element
-     */
-    protected function define_question_plugin_structure() {
-
-        // Define the virtual plugin element with the condition to fulfill
-        $plugin = $this->get_plugin_element(null, '../../qtype', 'ddwtos');
-
-        // Create one standard named plugin element (the visible container)
-        $pluginwrapper = new backup_nested_element($this->get_recommended_name());
-
-        // connect the visible container ASAP
-        $plugin->add_child($pluginwrapper);
-
-        // This qtype uses standard question_answers, add them here
-        // to the tree before any other information that will use them
-        $this->add_question_question_answers($pluginwrapper);
-
-        // Now create the qtype own structures
-        $ddwtos = new backup_nested_element('ddwtos', array('id'), array(
-            'shuffleanswers', 'correctfeedback', 'correctfeedbackformat',
-            'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
-            'incorrectfeedback', 'incorrectfeedbackformat', 'shownumcorrect'));
-
-        // Now the own qtype tree
-        $pluginwrapper->add_child($ddwtos);
-
-        // set source to populate the data
-        $ddwtos->set_source_table('question_ddwtos', array('questionid' => backup::VAR_PARENTID));
-
-        // don't need to annotate ids nor files
-
-        return $plugin;
-    }
-
-    /**
-     * Returns one array with filearea => mappingname elements for the qtype
-     *
-     * Used by {@link get_components_and_fileareas} to know about all the qtype
-     * files to be processed both in backup and restore.
-     */
-    public static function get_qtype_fileareas() {
-        return array(
-            'correctfeedback' => 'question_created',
-            'partiallycorrectfeedback' => 'question_created',
-            'incorrectfeedback' => 'question_created');
-    }
-}
diff --git a/question/type/ddwtos/backup/moodle2/restore_qtype_ddwtos_plugin.class.php b/question/type/ddwtos/backup/moodle2/restore_qtype_ddwtos_plugin.class.php
deleted file mode 100644 (file)
index 48fd969..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * @package    moodlecore
- * @subpackage backup-moodle2
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * restore plugin class that provides the necessary information
- * needed to restore one ddwtos qtype plugin
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class restore_qtype_ddwtos_plugin extends restore_qtype_plugin {
-
-    /**
-     * Returns the paths to be handled by the plugin at question level
-     */
-    protected function define_question_plugin_structure() {
-
-        $paths = array();
-
-        // This qtype uses question_answers, add them
-        $this->add_question_question_answers($paths);
-
-        // Add own qtype stuff
-        $elename = 'ddwtos';
-        $elepath = $this->get_pathfor('/ddwtos'); // we used get_recommended_name() so this works
-        $paths[] = new restore_path_element($elename, $elepath);
-
-        return $paths; // And we return the interesting paths
-    }
-
-    /**
-     * Process the qtype/ddwtos element
-     */
-    public function process_ddwtos($data) {
-        global $DB;
-
-        $data = (object)$data;
-        $oldid = $data->id;
-
-        // Detect if the question is created or mapped
-        $oldquestionid   = $this->get_old_parentid('question');
-        $newquestionid   = $this->get_new_parentid('question');
-        $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
-
-        // If the question has been created by restore, we need to create its question_ddwtos too
-        if ($questioncreated) {
-            // Adjust some columns
-            $data->questionid = $newquestionid;
-            // Insert record
-            $newitemid = $DB->insert_record('question_ddwtos', $data);
-            // Create mapping (needed for decoding links)
-            $this->set_mapping('question_ddwtos', $oldid, $newitemid);
-        }
-    }
-
-    /**
-     * Return the contents of this qtype to be processed by the links decoder
-     */
-    public static function define_decode_contents() {
-
-        $contents = array();
-
-        $fields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
-        $contents[] = new restore_decode_content('question_ddwtos', $fields, 'question_ddwtos');
-
-        return $contents;
-    }
-}
diff --git a/question/type/ddwtos/db/install.xml b/question/type/ddwtos/db/install.xml
deleted file mode 100644 (file)
index 50dbefe..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="question/type/ddwtos/db" VERSION="20080909" COMMENT="XMLDB file for Moodle question/type/ddwtos"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
->
-  <TABLES>
-    <TABLE NAME="question_ddwtos" COMMENT="Defines drag and drop (words into sentences) questions">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="questionid"/>
-        <FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="shuffleanswers"/>
-        <FIELD NAME="shuffleanswers" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="questionid" NEXT="correctfeedback"/>
-        <FIELD NAME="correctfeedback" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any correct response." PREVIOUS="shuffleanswers" NEXT="correctfeedbackformat"/>
-        <FIELD NAME="correctfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="correctfeedback" NEXT="partiallycorrectfeedback"/>
-        <FIELD NAME="partiallycorrectfeedback" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any partially correct response." PREVIOUS="correctfeedbackformat" NEXT="partiallycorrectfeedbackformat"/>
-        <FIELD NAME="partiallycorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="partiallycorrectfeedback" NEXT="incorrectfeedback"/>
-        <FIELD NAME="incorrectfeedback" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any incorrect response." PREVIOUS="partiallycorrectfeedbackformat" NEXT="incorrectfeedbackformat"/>
-        <FIELD NAME="incorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="incorrectfeedback" NEXT="shownumcorrect"/>
-        <FIELD NAME="shownumcorrect" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="incorrectfeedbackformat"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="questionid"/>
-        <KEY NAME="questionid" TYPE="foreign" FIELDS="questionid" REFTABLE="questions" REFFIELDS="id" PREVIOUS="primary"/>
-      </KEYS>
-    </TABLE>
-  </TABLES>
-</XMLDB>
\ No newline at end of file
diff --git a/question/type/ddwtos/edit_ddwtos_form.php b/question/type/ddwtos/edit_ddwtos_form.php
deleted file mode 100644 (file)
index 5f30792..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Defines the editing form for the drag-and-drop words into sentences question type.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/type/gapselect/edit_form_base.php');
-
-
-/**
- * Drag-and-drop words into sentences editing form definition.
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_edit_form extends qtype_gapselect_edit_form_base {
-    public function qtype() {
-        return 'ddwtos';
-    }
-
-    protected function data_preprocessing_choice($question, $answer, $key) {
-        $question = parent::data_preprocessing_choice($question, $answer, $key);
-        $options = unserialize($answer->feedback);
-        $question->choices[$key]['choicegroup'] = $options->draggroup;
-        $question->choices[$key]['infinite'] = $options->infinite;
-        return $question;
-    }
-
-    protected function choice_group($mform) {
-        $grouparray = parent::choice_group($mform);
-        $grouparray[] = $mform->createElement('checkbox', 'infinite', ' ',
-                get_string('infinite', 'qtype_ddwtos'), null,
-                array('size' => 1, 'class' => 'tweakcss'));
-        return $grouparray;
-    }
-}
diff --git a/question/type/ddwtos/lang/en/qtype_ddwtos.php b/question/type/ddwtos/lang/en/qtype_ddwtos.php
deleted file mode 100644 (file)
index 4475925..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-$string['addingddwtos'] = 'Adding drag and drop: words in text';
-$string['addmorechoiceblanks'] = 'Blanks for {no} More Choices';
-$string['answer'] = 'Answer';
-$string['correctansweris'] = 'The correct answer is: {$a}';
-$string['ddwtos'] = 'Drag and drop: words in text';
-$string['ddwtos_help'] = 'Type in some question text like "The [[1]] jumped over the [[2]]", then enter the possible words to go in gaps 1 and 2 underneath.';
-$string['ddwtossummary'] = 'Missing words in some text are filled in using drag-and-drop.';
-$string['editingddwtos'] = 'Editing drag and drop: words in text';
-$string['infinite'] = 'Infinite';
-$string['pleaseputananswerineachbox'] = 'Please put an answer in each box.';
diff --git a/question/type/ddwtos/pix/icon.gif b/question/type/ddwtos/pix/icon.gif
deleted file mode 100644 (file)
index f900852..0000000
Binary files a/question/type/ddwtos/pix/icon.gif and /dev/null differ
diff --git a/question/type/ddwtos/question.php b/question/type/ddwtos/question.php
deleted file mode 100644 (file)
index 25e3fe4..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Drag-and-drop words into sentences question definition class.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/type/gapselect/questionbase.php');
-
-
-/**
- * Represents a drag-and-drop words into sentences question.
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_question extends qtype_gapselect_question_base {
-    // Is actually exactly the same.
-}
-
-
-/**
- * Represents one of the choices (draggable boxes).
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_choice {
-    public $text;
-    public $draggroup;
-    public $isinfinite;
-
-    public function __construct($text, $draggroup = 1, $isinfinite = false) {
-        $this->text = $text;
-        $this->draggroup = $draggroup;
-        $this->isinfinite = $isinfinite;
-    }
-    public function choice_group() {
-        return $this->draggroup;
-    }
-}
diff --git a/question/type/ddwtos/questiontype.php b/question/type/ddwtos/questiontype.php
deleted file mode 100644 (file)
index 8b46966..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Question type class for the drag-and-drop words into sentences question type.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir . '/questionlib.php');
-require_once($CFG->dirroot . '/question/engine/lib.php');
-require_once($CFG->dirroot . '/question/format/xml/format.php');
-require_once($CFG->dirroot . '/question/type/gapselect/questiontypebase.php');
-
-
-/**
- * The drag-and-drop words into sentences question type class.
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos extends qtype_gapselect_base {
-    protected function choice_group_key() {
-        return 'draggroup';
-    }
-
-    public function requires_qtypes() {
-        return array('gapselect');
-    }
-
-    protected function choice_options_to_feedback($choice) {
-        $output = new stdClass();
-        $output->draggroup = $choice['choicegroup'];
-        $output->infinite = !empty($choice['infinite']);
-        return serialize($output);
-    }
-
-    protected function feedback_to_choice_options($feedback) {
-        $feedbackobj = unserialize($feedback);
-        return array('draggroup' => $feedbackobj->draggroup, 'infinite' => $feedbackobj->infinite);
-    }
-
-    protected function make_choice($choicedata) {
-        $options = unserialize($choicedata->feedback);
-        return new qtype_ddwtos_choice(
-                $choicedata->answer, $options->draggroup, $options->infinite);
-    }
-
-    public function import_from_xml($data, $question, $format, $extra=null) {
-        if (!isset($data['@']['type']) || $data['@']['type'] != 'ddwtos') {
-            return false;
-        }
-
-        $question = $format->import_headers($data);
-        $question->qtype = 'ddwtos';
-
-        $question->shuffleanswers = $format->trans_single(
-                $format->getpath($data, array('#', 'shuffleanswers', 0, '#'), 1));
-
-        if (!empty($data['#']['dragbox'])) {
-            // Modern XML format.
-            $dragboxes = $data['#']['dragbox'];
-            $question->answer = array();
-            $question->draggroup = array();
-            $question->infinite = array();
-
-            foreach ($data['#']['dragbox'] as $dragboxxml) {
-                $question->choices[] = array(
-                    'answer' => $format->getpath($dragboxxml, array('#', 'text', 0, '#'), '', true),
-                    'choicegroup' => $format->getpath($dragboxxml, array('#', 'group', 0, '#'), 1),
-                    'infinite' => array_key_exists('infinite', $dragboxxml['#']),
-                );
-            }
-
-        } else {
-            // Legacy format containing PHP serialisation.
-            foreach ($data['#']['answer'] as $answerxml) {
-                $ans = $format->import_answer($answerxml);
-                $options = unserialize(stripslashes($ans->feedback['text']));
-                $question->choices[] = array(
-                    'answer' => $ans->answer,
-                    'choicegroup' => $options->draggroup,
-                    'infinite' => $options->infinite,
-                );
-            }
-        }
-
-        $format->import_combined_feedback($question, $data, true);
-        $format->import_hints($question, $data, true);
-
-        return $question;
-    }
-
-    public function export_to_xml($question, $format, $extra = null) {
-        $output = '';
-
-        $output .= '    <shuffleanswers>' . $question->options->shuffleanswers .
-                "</shuffleanswers>\n";
-
-        $output .= $format->write_combined_feedback($question->options);
-
-        foreach ($question->options->answers as $answer) {
-            $options = unserialize($answer->feedback);
-
-            $output .= "    <dragbox>\n";
-            $output .= $format->writetext($answer->answer, 3);
-            $output .= "      <group>{$options->draggroup}</group>\n";
-            if ($options->infinite) {
-                $output .= "      <infinite/>\n";
-            }
-            $output .= "    </dragbox>\n";
-        }
-
-        return $output;
-    }
-}
diff --git a/question/type/ddwtos/renderer.php b/question/type/ddwtos/renderer.php
deleted file mode 100644 (file)
index e047163..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Drag-and-drop words into sentences question renderer class.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/type/gapselect/rendererbase.php');
-
-
-/**
- * Generates the output for drag-and-drop words into sentences questions.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_renderer extends qtype_elements_embedded_in_question_text_renderer {
-
-    protected function qtext_classname() {
-        return 'qtext ddwtos_questionid_for_javascript';
-    }
-
-    protected function post_qtext_elements(question_attempt $qa,
-            question_display_options $options) {
-        $result = '';
-        $question = $qa->get_question();
-        $dragboxs = '';
-        foreach ($question->choices as $group => $choices) {
-            $dragboxs .= $this->drag_boxes($qa, $group,
-                    $question->get_ordered_choices($group), $options);
-        }
-        $result .= html_writer::tag('div', $dragboxs,
-                array('class' => 'answercontainer'));
-        // We abuse the clear_wrong method to output the hidden form fields we
-        // want irrespective of whether we are actually clearing the wrong
-        // bits of the response.
-        if (!$options->clearwrong) {
-            $result .= $this->clear_wrong($qa, false);
-        }
-        return $result;
-    }
-
-    /**
-     * Modify the contents of a drag/drop box to fix some IE-related problem.
-     * Unfortunately I don't have more details than that.
-     * @param string $string the box contents.
-     * @return string the box contents modified.
-     */
-    protected function dodgy_ie_fix($string) {
-        return '<sub>&#160;</sub>' . $string . '<sup>&#160;</sup>';
-    }
-
-    protected function embedded_element(question_attempt $qa, $place,
-            question_display_options $options) {
-        $question = $qa->get_question();
-        $group = $question->places[$place];
-        $boxcontents = $this->dodgy_ie_fix('&#160;');
-
-        $value = $qa->get_last_qt_var($question->field($place));
-
-        $attributes = array(
-            'id' => $this->box_id($qa, 'p' . $place, $group),
-            'class' => 'slot group' . $group
-        );
-
-        if ($options->readonly) {
-            $attributes['class'] .= ' readonly';
-        } else {
-            $attributes['tabindex'] = '0';
-        }
-
-        $feedbackimage = '';
-        if ($options->correctness) {
-            $response = $qa->get_last_qt_data();
-            $fieldname = $question->field($place);
-            if (array_key_exists($fieldname, $response)) {
-                $fraction = (int) ($response[$fieldname] ==
-                        $question->get_right_choice_for($place));
-                $attributes['class'] .= ' ' . $this->feedback_class($fraction);
-                $feedbackimage = $this->feedback_image($fraction);
-            }
-        }
-
-        return html_writer::tag('span', $boxcontents, $attributes) . ' ' . $feedbackimage;
-    }
-
-    protected function drag_boxes($qa, $group, $choices, question_display_options $options) {
-        $readonly = '';
-        if ($options->readonly) {
-            $readonly = ' readonly';
-        }
-
-        $boxes = '';
-        foreach ($choices as $key => $choice) {
-            //Bug 8632 -  long text entry causes bug in drag and drop field in IE
-            $content = str_replace('-', '&#x2011;', $choice->text);
-            $content = $this->dodgy_ie_fix(str_replace(' ', '&#160;', $content));
-
-            $infinite = '';
-            if ($choice->isinfinite) {
-                $infinite = ' infinite';
-            }
-
-            $boxes .= html_writer::tag('span', $content, array(
-                    'id' => $this->box_id($qa, $key, $choice->draggroup),
-                    'class' => 'player group' . $choice->draggroup . $infinite . $readonly)) . ' ';
-        }
-
-        return html_writer::nonempty_tag('div', $boxes, array('class' => 'answertext'));
-    }
-
-
-    public function head_code(question_attempt $qa) {
-        $this->page->requires->yui2_lib('dom');
-        $this->page->requires->yui2_lib('event');
-        $this->page->requires->yui2_lib('dragdrop');
-        return parent::head_code($qa);
-    }
-
-    /**
-     * Actually, this question type abuses this method to always ouptut the
-     * hidden fields it needs.
-     */
-    public function clear_wrong(question_attempt $qa, $reallyclear = true) {
-        $question = $qa->get_question();
-        $response = $qa->get_last_qt_data();
-
-        if (!empty($response) && $reallyclear) {
-            $cleanresponse = $question->clear_wrong_from_response($response);
-        } else {
-            $cleanresponse = $response;
-        }
-
-        $output = '';
-        foreach ($question->places as $place => $group) {
-            $fieldname = $question->field($place);
-            if (array_key_exists($fieldname, $response)) {
-                $value = $response[$fieldname];
-            } else {
-                $value = '0';
-            }
-            if (array_key_exists($fieldname, $cleanresponse)) {
-                $cleanvalue = $cleanresponse[$fieldname];
-            } else {
-                $cleanvalue = '0';
-            }
-            if ($cleanvalue != $value) {
-                $output .= html_writer::empty_tag('input', array(
-                        'type' => 'hidden',
-                        'id' => $this->box_id($qa, 'p' . $place, $group) . '_hidden',
-                        'value' => s($value))) .
-                        html_writer::empty_tag('input', array(
-                        'type' => 'hidden',
-                        'name' => $qa->get_qt_field_name($fieldname),
-                        'value' => s($cleanvalue)));
-            } else {
-                $output .= html_writer::empty_tag('input', array(
-                        'type' => 'hidden',
-                        'id' => $this->box_id($qa, 'p' . $place, $group) . '_hidden',
-                        'name' => $qa->get_qt_field_name($fieldname),
-                        'value' => s($value)));
-            }
-        }
-        return $output;
-    }
-
-}
diff --git a/question/type/ddwtos/script.js b/question/type/ddwtos/script.js
deleted file mode 100644 (file)
index 8e5f2d3..0000000
+++ /dev/null
@@ -1,578 +0,0 @@
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * JavaScript objects, functions as well as usage of some YUI library for
- * enabling drag and drop interaction for dran-anddrop words into sentences
- * (ddwtos)
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-//global variables
-var ddwtos_currentzindex = 10;
-
-
-/*
- * The way it seems to be, if there are more than one of this type of question
- * on a page, then this file is shared between them. Therefore it has to cope
- * with ALL the questions of this type on the page.
- */
-(function() {
-
-    // start of App object by all questions of this type on a page.
-    YAHOO.example.DDApp = {
-        init : function() {
-            var questionspans = YAHOO.util.Dom.getElementsByClassName("ddwtos_questionid_for_javascript");
-
-            // we need this loop in case of more than one of this qtype on one page
-            for (var i = 0; i < questionspans.length; i++) {
-                // The Questions object should now contain a QuestionDataObject
-                // object for each question of this type on the page.
-                Questions[questionspans[i].id] = new QuestionDataObject(questionspans[i].id);
-            }
-
-            // populate the arrays "slots" and "players" for each question
-            var tempSlots = YAHOO.util.Dom.getElementsByClassName("slot", "span");
-            var tempPlayers = YAHOO.util.Dom.getElementsByClassName("player", "span");
-
-            //ie7 zoom message
-            ie7_zoom_message();
-
-            for (var i = 0; i < tempSlots.length; i++) {
-                var name_prefix = tempSlots[i].id.split("_")[0] + "_";
-                var q = Questions[name_prefix];
-                var g = getGroupForThis(tempSlots[i].id);
-
-                var ddtarget = new YAHOO.util.DDTarget(tempSlots[i].id, g);
-                q.tempSlots.push(tempSlots[i]);
-                q.slots.push(ddtarget);
-            }
-
-            for (var i = 0; i < tempPlayers.length; i++) {
-                var name_prefix = tempPlayers[i].id.split("_")[0] + "_";
-                var q = Questions[name_prefix];
-                var g = getGroupForThis(tempPlayers[i].id);
-                var ddplayer = new YAHOO.example.DDPlayer(tempPlayers[i].id, g);
-                q.tempPlayers.push(tempPlayers[i]);
-                q.players.push(ddplayer);
-            }
-
-            for (var i = 0; i < questionspans.length; i++) {
-                var q = Questions[questionspans[i].id];
-                var groupwidth = getWidthForAllGroups(q.tempPlayers);
-                for (var j = 0; j < q.tempSlots.length; j++) {
-                    var g = getGroupForThis(q.tempSlots[j].id);
-                    setWidth(q.tempSlots[j], groupwidth[g]);
-                }
-                for (var j = 0; j < q.tempPlayers.length; j++) {
-                    var g = getGroupForThis(q.tempPlayers[j].id);
-                    setWidth(q.tempPlayers[j], groupwidth[g]);
-                }
-
-                // set responses for all slots
-                setResponsesForAllSlots(q.tempSlots, q.tempPlayers);
-            }
-        }
-    };
-    // end of App object ////////////////////////////////////////////////////////
-
-    // beginning of Player object (the draggable item) //////////////////////////
-    YAHOO.example.DDPlayer = function(id, sGroup, config) {
-        YAHOO.example.DDPlayer.superclass.constructor.apply(this, arguments);
-        this.initPlayer(id, sGroup, config);
-    };
-
-    YAHOO.extend(YAHOO.example.DDPlayer, YAHOO.util.DD, {
-        TYPE :"DDPlayer",
-
-        initPlayer : function(id, sGroup, config) {
-            this.isTarget = false;
-            this.currentPos = YAHOO.util.Dom.getXY(this.getEl());
-        },
-
-        //Abstract method called after a drag/drop object is clicked and the drag or mousedown time thresholds have beeen met.
-        startDrag : function(x, y) {
-            YAHOO.util.Dom.setStyle(this.getEl(), "zIndex", ddwtos_currentzindex++);
-            YAHOO.util.Dom.removeClass(this.getEl(), 'placed');
-
-            if (is_infinite(this.getEl()) && !this.slot){
-                var currentplayer = this.getEl().id.replace(/_clone[0-9]+$/, '');
-                var ddplayer = YAHOO.util.DragDropMgr.getDDById(currentplayer);
-                clone_player(ddplayer);
-            }
-
-            if (this.slot) { // dragging starts from a slot
-                var hiddenElement = document.getElementById(this.slot.getEl().id + '_hidden');
-                hiddenElement.value = '';
-                this.slot.player = null;
-                this.slot = null;
-            }
-        },
-
-        //Abstract method called when this item is dropped on another DragDrop obj
-        onDragDrop : function(e, id) {
-            // get the drag and drop object that was targeted
-            var target = YAHOO.util.DragDropMgr.getDDById(id);
-            var dragged = this.getEl();
-
-            //get the question-prefix of slot and player and check whether they belong to the same question
-            var slotprefix = target.id.split("_")[0] + "_";
-            var playerprefix = dragged.id.split("_")[0] + "_";
-            if (slotprefix != playerprefix){
-                var p = YAHOO.util.DragDropMgr.getDDById(dragged.id);
-                p.startDrag(0,0);
-                p.onInvalidDrop(null);
-                return;
-            }
-
-            show_element(this.getEl());
-
-            if (target.player) { // there's a player already there
-                var oldplayer = target.player;
-                oldplayer.startDrag(0,0);
-                oldplayer.onInvalidDrop(null);
-            }
-
-            YAHOO.util.DragDropMgr.moveToEl(dragged, target.getEl());
-            this.slot = target;
-            target.player = this;
-            YAHOO.util.Dom.setXY(target.player.getEl(), YAHOO.util.Dom.getXY(target.getEl()));
-            YAHOO.util.Dom.addClass(this.getEl(), 'placed');
-            if (YAHOO.util.Dom.hasClass(target.getEl(), 'readonly')) {
-                if (YAHOO.util.Dom.hasClass(target.getEl(), 'correct')) {
-                    YAHOO.util.Dom.addClass(this.getEl(), 'correct');
-                } else if (YAHOO.util.Dom.hasClass(target.getEl(), 'incorrect')) {
-                    YAHOO.util.Dom.addClass(this.getEl(), 'incorrect');
-                }
-            }
-
-            // set value
-            var hiddenElement = document.getElementById(id + '_hidden');
-            hiddenElement.value = this.getEl().id.split("_")[1];
-        },
-
-        //Abstract method called when this item is dropped on an area with no drop target
-        onInvalidDrop : function(e) {
-            YAHOO.util.Dom.setXY(this.getEl(), YAHOO.util.Dom.getXY(this.originalplayer.getEl()));
-            YAHOO.util.Dom.removeClass(this.getEl(), 'placed');
-        }
-    });
-    // end of Player object (the draggable item) ////////////////////////////////
-
-    YAHOO.util.Event.onDOMReady(YAHOO.example.DDApp.init, YAHOO.example.DDApp, true);
-
-    // Objects///////////////////////////////////////////////////////////////////
-    var Questions = new Object();
-
-    function QuestionDataObject(theid) {
-        this.id = theid;
-        this.tempSlots = [];
-        this.tempPlayers = [];
-        this.slots = [];
-        this.players = [];
-    }
-
-    // template for the slot object
-    function SlotObject(id, group, currentvalue, values, callback) {
-        this.id = id;
-        this.group = group;
-        this.currentvalue = currentvalue;
-        this.values = values;
-        this.callback = callback;
-    }
-    // End of Objects ///////////////////////////////////////////////////////////
-
-    // functions ////////////////////////////////////////////////////////////////
-
-    function clone_player(p) {
-        var el = p.getEl();
-        var newNode = document.createElement('div');
-        newNode.className = el.className;
-        newNode.innerHTML = el.innerHTML;
-
-        if (!p.clones) {
-            p.clones = [];
-        }
-        newNode.id = el.id + '_clone' + p.clones.length; // _clone0 for first
-
-        newNode.style.position = 'absolute';
-
-        var region = YAHOO.util.Dom.getRegion(el);
-        var height = region.bottom - region.top;
-        var width = region.right - region.left;
-
-        // -2 is becuase get_region includes the border, but style.width/height does not.
-        newNode.style.height = (height - 2) + "px";
-        newNode.style.width = (width - 2) + "px";
-
-        el.parentNode.parentNode.appendChild(newNode);
-        YAHOO.util.Dom.setXY(newNode, YAHOO.util.Dom.getXY(el));
-
-        var g = getGroupForThis(el.id);
-        var p2 = new YAHOO.example.DDPlayer(newNode.id, g);
-        p2.originalplayer = p;
-
-        hide_element(el);
-        show_element(newNode);
-
-        if (is_readonly(newNode)) {
-            p2.lock();
-        }
-
-        p.clones[p.clones.length] = p2;
-        return p2;
-    }
-
-    function clone_players(players){
-        for (var i = 0; i < players.length; i++) {
-            var p = YAHOO.util.DragDropMgr.getDDById(players[i].id);
-            clone_player(p);
-        }
-    }
-
-    function is_readonly(el){
-        return YAHOO.util.Dom.hasClass(el, 'readonly');
-    }
-
-    function is_infinite(el){
-        return YAHOO.util.Dom.hasClass(el, 'infinite');
-    }
-
-    function show_element(el){
-        YAHOO.util.Dom.setStyle(el, 'visibility', 'visible');
-    }
-
-    function hide_element(el){
-        YAHOO.util.Dom.setStyle(el, 'visibility', 'hidden');
-    }
-
-    function list_of_slots_and_players(slots, players) {
-        this.slots = slots;
-        this.players = players;
-    }
-
-    function set_xy_after_resize(e, slotsandplayerobj){
-        setTimeout(function() {
-            set_xy_after_resize_actual(e,slotsandplayerobj);
-        }, 0);
-    }
-
-    function set_xy_after_resize_actual(e, slotsandplayerobj) {
-        var slots = slotsandplayerobj.slots;
-        var players = slotsandplayerobj.players;
-        for (var i = 0; i < players.length; i++) {
-            var original = YAHOO.util.DragDropMgr.getDDById(players[i].id);
-            for (var index in original.clones) {
-                var c = original.clones[index];
-                if (c.slot) {
-                    //player is in slot
-                    YAHOO.util.Dom.setXY(c.getEl(), YAHOO.util.Dom.getXY(c.slot.getEl()));
-                } else {
-                    //player is not in slot
-                    YAHOO.util.Dom.setXY(c.getEl(), YAHOO.util.Dom.getXY(c.originalplayer.getEl()));
-                }
-            }
-        }
-    }
-
-    function setResponsesForAllSlots(slots, players) {
-        clone_players(players);
-
-        for (var i = 0; i < slots.length; i++) {
-            var slot = slots[i];
-
-            var hiddenElement = document.getElementById(slot.id + '_hidden');
-            if (!hiddenElement) {
-                continue;
-            }
-
-            // get group
-            var group = getGroupForThis(slot.id);
-
-            // get array of values
-            var values = getValuesForThisSlot(slot.id, players);
-
-            var currentvalue = parseInt(hiddenElement.value);
-            // if slot is occupied
-            if (currentvalue) {
-                // Find player
-                var idbits = hiddenElement.id.split('_');
-                idbits[1] = currentvalue;
-                idbits.pop();
-                var newid = idbits.join('_');
-                var original = YAHOO.util.DragDropMgr.getDDById(newid);
-                var index = original.clones.length - 1;
-                original.clones[index].startDrag(0, 0);
-                original.clones[index].onDragDrop(null, slot.id);
-            }
-            YAHOO.util.Event.addListener(slot.id, "focus", setFocus);
-            YAHOO.util.Event.addListener(slot.id, "blur", setBlur);
-
-            YAHOO.util.Event.addListener(slot.id, "mousedown", mouseDown);
-
-            var myobj = new SlotObject(slot.id, group, currentvalue, values, funCallKeys);
-
-            // event keydown
-            YAHOO.util.Event.addListener(slot.id, "keydown", funCallKeys, myobj);
-        }
-
-        //resize
-        var listofslotsandplayers = new list_of_slots_and_players(slots, players);
-        YAHOO.util.Event.addListener(window, "resize", set_xy_after_resize, listofslotsandplayers);
-        YAHOO.util.Event.addListener(window, "load", set_xy_after_resize, listofslotsandplayers);
-    }
-
-    function getValuesForThisSlot(slotid, players) {
-        var gslot = getGroupForThis(slotid);
-        var values = [];
-        var j = 0;
-        for (var i = 0; i < players.length; i++) {
-            var pElement = players[i];
-            var gplayer = getGroupForThis(pElement.id);
-
-            // from the same group
-            if (gslot == gplayer) {
-                values[j++] = pElement.id;
-            }
-        }
-        return values;
-    }
-
-    function getWidthForAllGroups(allplayers) {
-        var widtharray = [];
-        for (var i = 0; i < allplayers.length; i++) {
-            var g = getGroupForThis(allplayers[i].id);
-            var width = getWidthForThisElement(allplayers[i]);
-            if (!widtharray[g] || width > widtharray[g]) {
-                widtharray[g] = width;
-            }
-        }
-        return widtharray;
-    }
-
-    function getWidthForThisGroup(allplayers, group) {
-        var tempwidth = 0;
-        for (var i = 0; i < allplayers.length; i++) {
-            var g = getGroupForThis(allplayers[i].id);
-            if (group != g) {
-                continue;
-            }
-            var width = getWidthForThisElement(allplayers[i]);
-            if (width > tempwidth) {
-                tempwidth = width;
-            }
-        }
-        return tempwidth;
-    }
-
-    function getWidthForThisElement(el) {
-        var region = YAHOO.util.Dom.getRegion(el);
-        return region.right - region.left;
-    }
-
-    function setWidth(el, gwidth) {
-        var width = getWidthForThisElement(el);
-        var remainder = (gwidth - width) + 10;
-
-        // IE8 does not rewrap lines when the padding changes, so this
-        // change uses different layout for that browser version only.
-        if (navigator.appVersion.indexOf('MSIE 8') != -1) {
-            var region = YAHOO.util.Dom.getRegion(el);
-            var height = region.bottom - region.top;
-            el.style.display = 'inline-block';
-            el.style.width = gwidth + 'px';
-            el.style.height = height + 'px';
-            return;
-        }
-
-        YAHOO.util.Dom.setStyle(el, 'padding-right', Math.floor((remainder + 1) / 2) + 'px');
-        YAHOO.util.Dom.setStyle(el, 'padding-left', Math.floor(remainder / 2) + 'px');
-    }
-
-    function funCallKeys(e, slotobj) {
-        //disable the key access when readonly
-        if (is_readonly(document.getElementById(slotobj.values[0]))) {
-            return;
-        }
-
-        var evt = e || window.event;
-        var key = evt.keyCode;
-
-        switch (key) {
-        case 39: // arrow right (forwards)
-        case 40: // arrow down (forwards)
-        case 32: // space (forwards)
-            changeObject(slotobj, 1);
-            return false; //this has to return false because of IE
-
-        case 37: // arrow left (backwards)
-        case 38: // arrow up (backwards)
-            changeObject(slotobj, -1);
-            return false; //this has to return false because of IE
-
-        case 66: // B (backwards)
-        case 98: // b (backwards)
-        case 80: // P (previous)
-        case 112: // p (previous)
-            changeObject(slotobj, -1);
-            break;
-
-        case 13: // cariage return (forwards)
-        case 70: // F (forwards)
-        case 102: // f (forwards)
-        case 78: // N (next)
-        case 110: // n (next)
-            changeObject(slotobj, 1);
-            break;
-
-        case 27: // escape (empty the drop box)
-            changeObject(slotobj, 0);
-        default:
-            return true;
-        }
-        return true;
-    }
-
-    function changeObject(slotobj, direction) {
-        // Prevent infinite loop if there are no values for this slot
-        if (slotobj.values.length == 0) {
-            return;
-        }
-
-        if (direction == 0) {
-            call_YUI_startDrag_onInvalidDrop(slotobj);
-            return;
-        }
-
-        var hiddenElement = document.getElementById(slotobj.id + '_hidden');
-
-        // Get current position in values list
-        var selectedIndex = -1;
-        for(var i = 0; i < slotobj.values.length; i++) {
-            if (slotobj.values[i].split("_")[1] == hiddenElement.value) {
-                selectedIndex = i;
-                break;
-            }
-        }
-
-        var currentIndex = selectedIndex;
-        while (true) {
-            // Get new position in values list
-            selectedIndex += direction;
-            if (selectedIndex > slotobj.values.length) {
-                selectedIndex-= slotobj.values.length + 1;
-            }
-            if (selectedIndex < 0) {
-                selectedIndex += slotobj.values.length + 1;
-            }
-
-            //empty the slot at the beginning or the end of the players list
-            if (selectedIndex == slotobj.values.length) {
-                call_YUI_startDrag_onInvalidDrop(slotobj);
-                return;
-            }
-
-            // If we loop round back to the current one then there are
-            // no more options, so stop
-            if (selectedIndex == currentIndex) {
-                break;
-            }
-
-            // Check the item at the new position is not used
-            var original = YAHOO.util.DragDropMgr.getDDById(slotobj.values[selectedIndex]);
-            var index = original.clones.length - 1;
-            if (!original.clones[index].slot) {
-                // This one is not in a slot so we can use it
-                original.clones[index].startDrag(0, 0);
-                original.clones[index].onDragDrop(null, slotobj.id);
-                break;
-            }
-        }
-    }
-
-    function call_YUI_startDrag_onInvalidDrop(slotobj){
-        var target = YAHOO.util.DragDropMgr.getDDById(slotobj.id);
-        if (!target.player) {
-            return;
-        }
-        var player = target.player;
-
-        // Find player and call YUI methods
-        player.startDrag(0, 0);
-        player.onInvalidDrop(null);
-    }
-
-    function getGroupForThis(str) {
-        var g = str.split("_")[2];
-        return g;
-    }
-
-    function mouseDown() {
-    }
-
-    function setFocus() {
-        YAHOO.util.Dom.addClass(this, 'focussed');
-    }
-
-    function setBlur() {
-        YAHOO.util.Dom.removeClass(this, 'focussed');
-    }
-
-    function ie7_zoom_message (){
-        var browser = navigator.appVersion;
-        if (browser.indexOf('MSIE 7') > -1){
-            var b = document.body.getBoundingClientRect();
-            var magnifactor = (b.right - b.left)/document.body.clientWidth;
-            if (magnifactor < 0.9  || magnifactor > 1.1){
-
-                var answers = YAHOO.util.Dom.getElementsByClassName("answercontainer", "div");
-                for(var i=0; i<answers.length; i++) {
-                    var block = document.createElement('div');
-
-                    var text = 'This question type is not compatible with the zoom feature in Internet Explorer 7. '+
-                                'Please press Ctrl+0 and then click on the question number in the navigation panel '+
-                                'on the left to reload this question. Alternatively ';
-                    block.appendChild(document.createTextNode(text));
-
-                    //add ie8 link
-                    var ie8link = document.createElement('a');
-                    ie8link.href = 'http://www.microsoft.com/uk/windows/internet-explorer';
-                    ie8link.appendChild(document.createTextNode('upgrade your browser to Internet Explorer 8'));
-                    block.appendChild(ie8link);
-
-                    var ie8textsuffix = ' before carrying on.';
-                    block.appendChild(document.createTextNode(ie8textsuffix));
-
-                    YAHOO.util.Dom.setStyle(block, 'margin', '5px 5px 5px 0');
-                    YAHOO.util.Dom.setStyle(block, 'padding', '5px');
-                    YAHOO.util.Dom.setStyle(block, 'border', '1px  solid #BB0000');
-                    YAHOO.util.Dom.setStyle(block, 'background-color', '#FFFAFA');
-                    answers[i].parentNode.insertBefore(block, answers[i]);
-                    innerHideAnswers(answers[i]);
-                }
-            }
-        }
-    }
-
-    function innerHideAnswers(answers) {
-        setTimeout(function() {
-            answers.parentNode.removeChild(answers);
-        }, 0);
-    }
-})();
diff --git a/question/type/ddwtos/simpletest/helper.php b/question/type/ddwtos/simpletest/helper.php
deleted file mode 100644 (file)
index 50e244f..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Test helpers for the drag-and-drop words into sentences question type.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Test helper class for the drag-and-drop words into sentences question type.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_test_helper extends question_test_helper {
-    public function get_test_questions() {
-        return array('fox', 'maths');
-    }
-
-    /**
-     * @return qtype_ddwtos_question
-     */
-    public function make_ddwtos_question_fox() {
-        question_bank::load_question_definition_classes('ddwtos');
-        $dd = new qtype_ddwtos_question();
-
-        test_question_maker::initialise_a_question($dd);
-
-        $dd->name = 'Drag-and-drop words into sentences question';
-        $dd->questiontext = 'The [[1]] brown [[2]] jumped over the [[3]] dog.';
-        $dd->generalfeedback = 'This sentence uses each letter of the alphabet.';
-        $dd->qtype = question_bank::get_qtype('ddwtos');
-
-        $dd->shufflechoices = true;
-
-        test_question_maker::set_standard_combined_feedback_fields($dd);
-
-        $dd->choices = array(
-            1 => array(
-                1 => new qtype_ddwtos_choice('quick', 1),
-                2 => new qtype_ddwtos_choice('slow', 1)),
-            2 => array(
-                1 => new qtype_ddwtos_choice('fox', 2),
-                2 => new qtype_ddwtos_choice('dog', 2)),
-            3 => array(
-                1 => new qtype_ddwtos_choice('lazy', 3),
-                2 => new qtype_ddwtos_choice('assiduous', 3)),
-        );
-
-        $dd->places = array(1 => 1, 2 => 2, 3 => 3);
-        $dd->rightchoices = array(1 => 1, 2 => 1, 3 => 1);
-        $dd->textfragments = array('The ', ' brown ', ' jumped over the ', ' dog.');
-
-        return $dd;
-    }
-
-    /**
-     * @return qtype_ddwtos_question
-     */
-    public function make_ddwtos_question_maths() {
-        question_bank::load_question_definition_classes('ddwtos');
-        $dd = new qtype_ddwtos_question();
-
-        test_question_maker::initialise_a_question($dd);
-
-        $dd->name = 'Drag-and-drop words into sentences question';
-        $dd->questiontext = 'Fill in the operators to make this equation work: ' .
-                '7 [[1]] 11 [[2]] 13 [[1]] 17 [[2]] 19 = 3';
-        $dd->generalfeedback = 'This sentence uses each letter of the alphabet.';
-        $dd->qtype = question_bank::get_qtype('ddwtos');
-
-        $dd->shufflechoices = true;
-
-        test_question_maker::set_standard_combined_feedback_fields($dd);
-
-        $dd->choices = array(
-            1 => array(
-                1 => new qtype_ddwtos_choice('+', 1, true),
-                2 => new qtype_ddwtos_choice('-', 1, true),
-                3 => new qtype_ddwtos_choice('*', 1, true),
-                4 => new qtype_ddwtos_choice('/', 1, true),
-            ));
-
-        $dd->places = array(1 => 1, 2 => 1, 3 => 1, 4 => 1);
-        $dd->rightchoices = array(1 => 1, 2 => 2, 3 => 1, 4 => 2);
-        $dd->textfragments = array('7 ', ' 11 ', ' 13 ', ' 17 ', ' 19 = 3');
-
-        return $dd;
-    }
-}
diff --git a/question/type/ddwtos/simpletest/testquestion.php b/question/type/ddwtos/simpletest/testquestion.php
deleted file mode 100644 (file)
index c7f27d7..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Unit tests for the drag-and-drop words into sentences question definition class.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
-require_once($CFG->dirroot . '/question/type/ddwtos/simpletest/helper.php');
-
-
-/**
- * Unit tests for the matching question definition class.
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_question_test extends UnitTestCase {
-
-    public function test_get_question_summary() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $this->assertEqual('The [[1]] brown [[2]] jumped over the [[3]] dog.; ' .
-                '[[1]] -> {quick / slow}; [[2]] -> {fox / dog}; [[3]] -> {lazy / assiduous}',
-                $dd->get_question_summary());
-    }
-
-    public function test_get_question_summary_maths() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $this->assertEqual('Fill in the operators to make this equation work: ' .
-                '7 [[1]] 11 [[2]] 13 [[1]] 17 [[2]] 19 = 3; [[1]] -> {+ / - / * / /}',
-                $dd->get_question_summary());
-    }
-
-    public function test_summarise_response() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual('{quick} {fox} {lazy}',
-                $dd->summarise_response(array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_summarise_response_maths() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual('{+} {-} {+} {-}',
-                $dd->summarise_response(array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2')));
-    }
-
-    public function test_get_random_guess_score() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $this->assertEqual(0.5, $dd->get_random_guess_score());
-    }
-
-    public function test_get_random_guess_score_maths() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $this->assertEqual(0.25, $dd->get_random_guess_score());
-    }
-
-    public function test_get_right_choice_for() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(1, $dd->get_right_choice_for(1));
-        $this->assertEqual(1, $dd->get_right_choice_for(2));
-    }
-
-    public function test_get_right_choice_for_maths() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(1, $dd->get_right_choice_for(1));
-        $this->assertEqual(2, $dd->get_right_choice_for(2));
-    }
-
-    public function test_clear_wrong_from_response() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $initialresponse = array('p1' => '1', 'p2' => '1', 'p3' => '1', 'p4' => '1');
-        $this->assertEqual(array('p1' => '1', 'p2' => '0', 'p3' => '1', 'p4' => '0'),
-                $dd->clear_wrong_from_response($initialresponse));
-    }
-
-    public function test_get_num_parts_right() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(2, 3),
-                $dd->get_num_parts_right(array('p1' => '1', 'p2' => '1', 'p3' => '2')));
-        $this->assertEqual(array(3, 3),
-                $dd->get_num_parts_right(array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_get_num_parts_right_maths() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(2, 4),
-                $dd->get_num_parts_right(array(
-                        'p1' => '1', 'p2' => '1', 'p3' => '1', 'p4' => '1')));
-    }
-
-    public function test_get_expected_data() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array('p1' => PARAM_INT, 'p2' => PARAM_INT, 'p3' => PARAM_INT),
-                $dd->get_expected_data());
-    }
-
-    public function test_get_correct_response() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array('p1' => '1', 'p2' => '1', 'p3' => '1'),
-                $dd->get_correct_response());
-    }
-
-    public function test_get_correct_response_maths() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2'),
-                $dd->get_correct_response());
-    }
-
-    public function test_is_same_response() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertTrue($dd->is_same_response(
-                array(),
-                array('p1' => '0', 'p2' => '0', 'p3' => '0')));
-
-        $this->assertFalse($dd->is_same_response(
-                array(),
-                array('p1' => '1', 'p2' => '0', 'p3' => '0')));
-
-        $this->assertFalse($dd->is_same_response(
-                array('p1' => '0', 'p2' => '0', 'p3' => '0'),
-                array('p1' => '1', 'p2' => '0', 'p3' => '0')));
-
-        $this->assertTrue($dd->is_same_response(
-                array('p1' => '1', 'p2' => '2', 'p3' => '3'),
-                array('p1' => '1', 'p2' => '2', 'p3' => '3')));
-
-        $this->assertFalse($dd->is_same_response(
-                array('p1' => '1', 'p2' => '2', 'p3' => '3'),
-                array('p1' => '1', 'p2' => '2', 'p3' => '2')));
-    }
-    public function test_is_complete_response() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertFalse($dd->is_complete_response(array()));
-        $this->assertFalse($dd->is_complete_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '0')));
-        $this->assertFalse($dd->is_complete_response(array('p1' => '1')));
-        $this->assertTrue($dd->is_complete_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_is_gradable_response() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertFalse($dd->is_gradable_response(array()));
-        $this->assertFalse($dd->is_gradable_response(
-                array('p1' => '0', 'p2' => '0', 'p3' => '0')));
-        $this->assertTrue($dd->is_gradable_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '0')));
-        $this->assertTrue($dd->is_gradable_response(array('p1' => '1')));
-        $this->assertTrue($dd->is_gradable_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_grading() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(1, question_state::$gradedright),
-                $dd->grade_response(array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-        $this->assertEqual(array(1/3, question_state::$gradedpartial),
-                $dd->grade_response(array('p1' => '1')));
-        $this->assertEqual(array(0, question_state::$gradedwrong),
-                $dd->grade_response(array('p1' => '2', 'p2' => '2', 'p3' => '2')));
-    }
-
-    public function test_grading_maths() {
-        $dd = test_question_maker::make_question('ddwtos', 'maths');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(1, question_state::$gradedright),
-                $dd->grade_response(array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2')));
-        $this->assertEqual(array(0.5, question_state::$gradedpartial),
-                $dd->grade_response(array('p1' => '1', 'p2' => '1', 'p3' => '1', 'p4' => '1')));
-        $this->assertEqual(array(0, question_state::$gradedwrong),
-                $dd->grade_response(array('p1' => '0', 'p2' => '1', 'p3' => '2', 'p4' => '1')));
-    }
-
-    public function test_classify_response() {
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $dd->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(
-                    1 => new question_classified_response(1, 'quick', 1),
-                    2 => new question_classified_response(2, 'dog', 0),
-                    3 => new question_classified_response(1, 'lazy', 1),
-                ), $dd->classify_response(array('p1' => '1', 'p2' => '2', 'p3' => '1')));
-        $this->assertEqual(array(
-                    1 => question_classified_response::no_response(),
-                    2 => new question_classified_response(1, 'fox', 1),
-                    3 => new question_classified_response(2, 'assiduous', 0),
-                ), $dd->classify_response(array('p1' => '0', 'p2' => '1', 'p3' => '2')));
-    }
-}
diff --git a/question/type/ddwtos/simpletest/testquestiontype.php b/question/type/ddwtos/simpletest/testquestiontype.php
deleted file mode 100644 (file)
index 34c41f8..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Unit tests for the drag-and-drop words into sentences question definition class.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
-require_once($CFG->dirroot . '/question/type/ddwtos/simpletest/helper.php');
-
-
-/**
- * Unit tests for the drag-and-drop words into sentences question definition class.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_test extends UnitTestCase {
-    /** @var qtype_ddwtos instance of the question type class to test. */
-    protected $qtype;
-
-    public function setUp() {
-        $this->qtype = question_bank::get_qtype('ddwtos');;
-    }
-
-    public function tearDown() {
-        $this->qtype = null;
-    }
-
-    public function assert_same_xml($expectedxml, $xml) {
-        $this->assertEqual(str_replace("\r\n", "\n", $expectedxml),
-                str_replace("\r\n", "\n", $xml));
-    }
-
-    /**
-     * @return object the data to construct a question like
-     * {@link qtype_ddwtos_test_helper::make_ddwtos_question_fox()}.
-     */
-    protected function get_test_question_data() {
-        global $USER;
-
-        $dd = new stdClass();
-        $dd->id = 0;
-        $dd->category = 0;
-        $dd->contextid = 0;
-        $dd->parent = 0;
-        $dd->questiontextformat = FORMAT_HTML;
-        $dd->generalfeedbackformat = FORMAT_HTML;
-        $dd->defaultmark = 1;
-        $dd->penalty = 0.3333333;
-        $dd->length = 1;
-        $dd->stamp = make_unique_id_code();
-        $dd->version = make_unique_id_code();
-        $dd->hidden = 0;
-        $dd->timecreated = time();
-        $dd->timemodified = time();
-        $dd->createdby = $USER->id;
-        $dd->modifiedby = $USER->id;
-
-        $dd->name = 'Drag-and-drop words into sentences question';
-        $dd->questiontext = 'The [[1]] brown [[2]] jumped over the [[3]] dog.';
-        $dd->generalfeedback = 'This sentence uses each letter of the alphabet.';
-        $dd->qtype = 'ddwtos';
-
-        $dd->options->shuffleanswers = true;
-
-        test_question_maker::set_standard_combined_feedback_fields($dd->options);
-
-        $dd->options->answers = array(
-            (object) array('answer' => 'quick', 'feedback' =>
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}'),
-            (object) array('answer' => 'fox', 'feedback' =>
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}'),
-            (object) array('answer' => 'lazy', 'feedback' =>
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}'),
-            (object) array('answer' => 'assiduous', 'feedback' =>
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}'),
-            (object) array('answer' => 'dog', 'feedback' =>
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}'),
-            (object) array('answer' => 'slow', 'feedback' =>
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}'),
-        );
-
-        return $dd;
-    }
-
-    public function test_name() {
-        $this->assertEqual($this->qtype->name(), 'ddwtos');
-    }
-
-    public function test_can_analyse_responses() {
-        $this->assertTrue($this->qtype->can_analyse_responses());
-    }
-
-    public function test_initialise_question_instance() {
-        $qdata = $this->get_test_question_data();
-
-        $expected = test_question_maker::make_question('ddwtos');
-        $expected->stamp = $qdata->stamp;
-        $expected->version = $qdata->version;
-
-        $q = $this->qtype->make_question($qdata);
-
-        $this->assertEqual($expected, $q);
-    }
-
-    public function test_get_random_guess_score() {
-        $q = $this->get_test_question_data();
-        $this->assertWithinMargin(0.5, $this->qtype->get_random_guess_score($q), 0.0000001);
-    }
-
-    public function test_get_possible_responses() {
-        $q = $this->get_test_question_data();
-
-        $this->assertEqual(array(
-            1 => array(
-                1 => new question_possible_response('quick', 1),
-                2 => new question_possible_response('slow', 0),
-                null => question_possible_response::no_response()),
-            2 => array(
-                1 => new question_possible_response('fox', 1),
-                2 => new question_possible_response('dog', 0),
-                null => question_possible_response::no_response()),
-            3 => array(
-                1 => new question_possible_response('lazy', 1),
-                2 => new question_possible_response('assiduous', 0),
-                null => question_possible_response::no_response()),
-        ), $this->qtype->get_possible_responses($q));
-    }
-
-    public function test_xml_import() {
-        $xml = '  <question type="ddwtos">
-    <name>
-      <text>A drag-and-drop question</text>
-    </name>
-    <questiontext format="moodle_auto_format">
-      <text>Put these in order: [[1]], [[2]], [[3]].</text>
-    </questiontext>
-    <generalfeedback>
-      <text>The answer is Alpha, Beta, Gamma.</text>
-    </generalfeedback>
-    <defaultgrade>3</defaultgrade>
-    <penalty>0.3333333</penalty>
-    <hidden>0</hidden>
-    <shuffleanswers>1</shuffleanswers>
-    <correctfeedback>
-      <text><![CDATA[<p>Your answer is correct.</p>]]></text>
-    </correctfeedback>
-    <partiallycorrectfeedback>
-      <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
-    </partiallycorrectfeedback>
-    <incorrectfeedback>
-      <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
-    </incorrectfeedback>
-    <shownumcorrect/>
-    <dragbox>
-      <text>Alpha</text>
-      <group>1</group>
-    </dragbox>
-    <dragbox>
-      <text>Beta</text>
-      <group>1</group>
-    </dragbox>
-    <dragbox>
-      <text>Gamma</text>
-      <group>1</group>
-      <infinite/>
-    </dragbox>
-    <hint>
-      <text>Try again.</text>
-      <shownumcorrect />
-    </hint>
-    <hint>
-      <text>These are the first three letters of the Greek alphabet.</text>
-      <shownumcorrect />
-      <clearwrong />
-    </hint>
-  </question>';
-        $xmldata = xmlize($xml);
-
-        $importer = new qformat_xml();
-        $q = $importer->try_importing_using_qtypes(
-                $xmldata['question'], null, null, 'ddwtos');
-
-        $expectedq = new stdClass();
-        $expectedq->qtype = 'ddwtos';
-        $expectedq->name = 'A drag-and-drop question';
-        $expectedq->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
-        $expectedq->questiontextformat = FORMAT_MOODLE;
-        $expectedq->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
-        $expectedq->defaultmark = 3;
-        $expectedq->length = 1;
-        $expectedq->penalty = 0.3333333;
-
-        $expectedq->shuffleanswers = 1;
-        $expectedq->correctfeedback = array('text' => '<p>Your answer is correct.</p>',
-                'format' => FORMAT_MOODLE, 'files' => array());
-        $expectedq->partiallycorrectfeedback = array(
-                'text' => '<p>Your answer is partially correct.</p>',
-                'format' => FORMAT_MOODLE, 'files' => array());
-        $expectedq->shownumcorrect = true;
-        $expectedq->incorrectfeedback = array('text' => '<p>Your answer is incorrect.</p>',
-                'format' => FORMAT_MOODLE, 'files' => array());
-
-        $expectedq->choices = array(
-            array('answer' => 'Alpha', 'choicegroup' => 1, 'infinite' => false),
-            array('answer' => 'Beta', 'choicegroup' => 1, 'infinite' => false),
-            array('answer' => 'Gamma', 'choicegroup' => 1, 'infinite' => true),
-        );
-
-        $expectedq->hint = array(
-                array('text' => 'Try again.', 'format' => FORMAT_MOODLE, 'files' => array()),
-                array('text' => 'These are the first three letters of the Greek alphabet.',
-                        'format' => FORMAT_MOODLE, 'files' => array()));
-        $expectedq->hintshownumcorrect = array(true, true);
-        $expectedq->hintclearwrong = array(false, true);
-
-        $this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
-    }
-
-    public function test_xml_import_legacy() {
-        $xml = '  <question type="ddwtos">
-    <name>
-      <text>QDandD1 Base definition</text>
-    </name>
-    <questiontext format="html">
-      <text>&lt;p&gt;Drag and drop the words from the list below to fill the blank spaces ' .
-            'and correctly complete the sentence.&lt;/p&gt; &lt;p&gt;At 25°C all aqueous basic ' .
-            'solutions have [[1]]&#160;ion concentrations less than [[8]]&lt;br /&gt;mol ' .
-            'litre&lt;sup&gt;-1&lt;/sup&gt; and pH values [[9]] than [[6]].&lt;/p&gt; ' .
-            '&lt;!--DONOTCLEAN--&gt;</text>
-    </questiontext>
-    <image></image>
-    <generalfeedback>
-      <text>&lt;p&gt;At 25 &amp;#xB0;C all aqueous basic solutions have hydrogen ion ' .
-            'concentrations less than 10&lt;sup&gt;&amp;#x2212;7&lt;/sup&gt; mol ' .
-            'litre&lt;sup&gt;&amp;#x2212;1&lt;/sup&gt; and pH values greater than 7.&lt;/p&gt; ' .
-            '&lt;p&gt;See Section 9 of S103 &lt;em class="italic"&gt;Discovering ' .
-            'Science&lt;/em&gt; Block 8.&lt;/p&gt;</text>
-    </generalfeedback>
-    <defaultgrade>1</defaultgrade>
-    <penalty>0.33</penalty>
-    <hidden>0</hidden>
-    <shuffleanswers>0</shuffleanswers>
-    <shuffleanswers>false</shuffleanswers>
-    <answer>
-      <correctanswer>1</correctanswer>
-      <text>hydrogen</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>0</correctanswer>
-      <text>positive</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>0</correctanswer>
-      <text>hydroxide</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>0</correctanswer>
-      <text>negative</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>0</correctanswer>
-      <text>10&lt;sup&gt;7&lt;/sup&gt;</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>1</correctanswer>
-      <text>7</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>0</correctanswer>
-      <text>1</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>1</correctanswer>
-      <text>10&lt;sup&gt;-7&lt;/sup&gt;</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>1</correctanswer>
-      <text>greater</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <answer>
-      <correctanswer>0</correctanswer>
-      <text>less</text>
-      <feedback>
-        <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}</text>
-      </feedback>
-    </answer>
-    <correctfeedback>
-      <text>Your answer is correct.</text>
-    </correctfeedback>
-    <correctresponsesfeedback>1</correctresponsesfeedback>
-    <partiallycorrectfeedback>
-      <text>Your answer is partially correct.</text>
-    </partiallycorrectfeedback>
-    <incorrectfeedback>
-      <text>Your answer is incorrect.</text>
-    </incorrectfeedback>
-    <unlimited>0</unlimited>
-    <penalty>0.33</penalty>
-    <hint>
-      <statenumberofcorrectresponses>1</statenumberofcorrectresponses>
-      <clearincorrectresponses>0</clearincorrectresponses>
-      <hintcontent>
-        <text>You may wish to read&#160;Section 9 of&#160;&lt;em ' .
-            'class="italic"&gt;Discovering Science&lt;/em&gt; Block 8.</text>
-      </hintcontent>
-    </hint>
-    <hint>
-      <statenumberofcorrectresponses>1</statenumberofcorrectresponses>
-      <clearincorrectresponses>1</clearincorrectresponses>
-      <hintcontent>
-        <text>Any incorrect choices&#160;will be removed before your final try.</text>
-      </hintcontent>
-    </hint>
-  </question>';
-        $xmldata = xmlize($xml);
-
-        $importer = new qformat_xml();
-        $q = $importer->try_importing_using_qtypes(
-                $xmldata['question'], null, null, 'ddwtos');
-
-        $expectedq = new stdClass();
-        $expectedq->qtype = 'ddwtos';
-        $expectedq->name = 'QDandD1 Base definition';
-        $expectedq->questiontext = '<p>Drag and drop the words from the list below ' .
-                'to fill the blank spaces and correctly complete the sentence.</p>' .
-                '<p>At 25°C all aqueous basic solutions have [[1]] ion concentrations ' .
-                'less than [[8]]<br />mol litre<sup>-1</sup> and pH values [[9]] than [[6]].</p>' .
-                '<!--DONOTCLEAN-->';
-        $expectedq->questiontextformat = FORMAT_HTML;
-        $expectedq->generalfeedback = '<p>At 25 &#xB0;C all aqueous basic solutions ' .
-                'have hydrogen ion concentrations less than 10<sup>&#x2212;7</sup> ' .
-                'mol litre<sup>&#x2212;1</sup> and pH values greater than 7.</p><p>See ' .
-                'Section 9 of S103 <em class="italic">Discovering Science</em> Block 8.</p>';
-        $expectedq->defaultmark = 1;
-        $expectedq->length = 1;
-        $expectedq->penalty = 0.3333333;
-
-        $expectedq->shuffleanswers = 0;
-        $expectedq->correctfeedback = array('text' => 'Your answer is correct.',
-                'format' => FORMAT_MOODLE, 'files' => array());
-        $expectedq->partiallycorrectfeedback = array(
-                'text' => 'Your answer is partially correct.',
-                'format' => FORMAT_MOODLE, 'files' => array());
-        $expectedq->shownumcorrect = true;
-        $expectedq->incorrectfeedback = array('text' => 'Your answer is incorrect.',
-                'format' => FORMAT_MOODLE, 'files' => array());
-
-        $expectedq->choices = array(
-            array('answer' => array('text' => 'hydrogen',        'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 1, 'infinite' => false),
-            array('answer' => array('text' => 'positive',        'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 1, 'infinite' => false),
-            array('answer' => array('text' => 'hydroxide',       'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 1, 'infinite' => false),
-            array('answer' => array('text' => 'negative',        'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 1, 'infinite' => false),
-            array('answer' => array('text' => '10<sup>7</sup>',  'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 2, 'infinite' => false),
-            array('answer' => array('text' => '7',               'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 2, 'infinite' => false),
-            array('answer' => array('text' => '1',               'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 2, 'infinite' => false),
-            array('answer' => array('text' => '10<sup>-7</sup>', 'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 2, 'infinite' => false),
-            array('answer' => array('text' => 'greater',         'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 3, 'infinite' => false),
-            array('answer' => array('text' => 'less',            'format' => FORMAT_MOODLE,
-                    'files' => array()), 'choicegroup' => 3, 'infinite' => false),
-        );
-
-        $expectedq->hint = array(array('text' => 'You may wish to read Section 9 of ' .
-                '<em class="italic">Discovering Science</em> Block 8.',
-                    'format' => FORMAT_HTML, 'files' => array()),
-                array('text' => 'Any incorrect choices will be removed before your final try.',
-                    'format' => FORMAT_HTML, 'files' => array()),
-        );
-        $expectedq->hintshownumcorrect = array(true, true);
-        $expectedq->hintclearwrong = array(false, true);
-
-        $this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
-        $this->assertEqual($expectedq->hint, $q->hint);
-    }
-
-    public function test_xml_export() {
-        $qdata = new stdClass();
-        $qdata->id = 123;
-        $qdata->contextid = 0;
-        $qdata->qtype = 'ddwtos';
-        $qdata->name = 'A drag-and-drop question';
-        $qdata->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
-        $qdata->questiontextformat = FORMAT_MOODLE;
-        $qdata->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
-        $qdata->generalfeedbackformat = FORMAT_MOODLE;
-        $qdata->defaultmark = 3;
-        $qdata->length = 1;
-        $qdata->penalty = 0.3333333;
-        $qdata->hidden = 0;
-
-        $qdata->options->shuffleanswers = 1;
-        $qdata->options->correctfeedback = '<p>Your answer is correct.</p>';
-        $qdata->options->correctfeedbackformat = FORMAT_MOODLE;
-        $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
-        $qdata->options->partiallycorrectfeedbackformat = FORMAT_MOODLE;
-        $qdata->options->shownumcorrect = 1;
-        $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>';
-        $qdata->options->incorrectfeedbackformat = FORMAT_MOODLE;
-
-        $qdata->options->answers = array(
-            13 => new question_answer(13, 'Alpha', 0,
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}',
-                    FORMAT_MOODLE),
-            14 => new question_answer(14, 'Beta', 0,
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}',
-                    FORMAT_MOODLE),
-            15 => new question_answer(15, 'Gamma', 0,
-                    'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:1;}',
-                    FORMAT_MOODLE),
-        );
-
-        $qdata->hints = array(
-            1 => new question_hint_with_parts(1, 'Try again.', FORMAT_MOODLE, true, false),
-            2 => new question_hint_with_parts(2,
-                    'These are the first three letters of the Greek alphabet.',
-                    FORMAT_MOODLE, true, true),
-        );
-
-        $exporter = new qformat_xml();
-        $xml = $exporter->writequestion($qdata);
-
-        $expectedxml = '<!-- question: 123  -->
-  <question type="ddwtos">
-    <name>
-      <text>A drag-and-drop question</text>
-    </name>
-    <questiontext format="moodle_auto_format">
-      <text>Put these in order: [[1]], [[2]], [[3]].</text>
-    </questiontext>
-    <generalfeedback format="moodle_auto_format">
-      <text>The answer is Alpha, Beta, Gamma.</text>
-    </generalfeedback>
-    <defaultgrade>3</defaultgrade>
-    <penalty>0.3333333</penalty>
-    <hidden>0</hidden>
-    <shuffleanswers>1</shuffleanswers>
-    <correctfeedback format="moodle_auto_format">
-      <text><![CDATA[<p>Your answer is correct.</p>]]></text>
-    </correctfeedback>
-    <partiallycorrectfeedback format="moodle_auto_format">
-      <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
-    </partiallycorrectfeedback>
-    <incorrectfeedback format="moodle_auto_format">
-      <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
-    </incorrectfeedback>
-    <shownumcorrect/>
-    <dragbox>
-      <text>Alpha</text>
-      <group>1</group>
-    </dragbox>
-    <dragbox>
-      <text>Beta</text>
-      <group>1</group>
-    </dragbox>
-    <dragbox>
-      <text>Gamma</text>
-      <group>1</group>
-      <infinite/>
-    </dragbox>
-    <hint format="moodle_auto_format">
-      <text>Try again.</text>
-      <shownumcorrect/>
-    </hint>
-    <hint format="moodle_auto_format">
-      <text>These are the first three letters of the Greek alphabet.</text>
-      <shownumcorrect/>
-      <clearwrong/>
-    </hint>
-  </question>
-';
-
-        $this->assert_same_xml($expectedxml, $xml);
-    }
-}
diff --git a/question/type/ddwtos/simpletest/testwalkthrough.php b/question/type/ddwtos/simpletest/testwalkthrough.php
deleted file mode 100644 (file)
index a296640..0000000
+++ /dev/null
@@ -1,766 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Unit tests for the drag-and-drop words into sentences question type.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
-require_once($CFG->dirroot . '/question/type/ddwtos/simpletest/helper.php');
-
-
-/**
- * Unit tests for the drag-and-drop words into sentences question type.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_ddwtos_walkthrough_test extends qbehaviour_walkthrough_test_base {
-
-    protected function get_contains_drop_box_expectation($place, $group, $readonly,
-            $stateclass = '0') {
-        $qa = $this->quba->get_question_attempt($this->slot);
-
-        $expectedattrs = array(
-            'id' => $qa->get_qt_field_name($place . '_' . $group),
-        );
-        $class = 'slot group' . $group;
-        if ($readonly) {
-            $class .= ' readonly';
-        } else {
-            $expectedattrs['tabindex'] = 0;
-        }
-        if ($stateclass) {
-            $class .= ' ' . $stateclass;
-        }
-        $expectedattrs['class'] = $class;
-
-        return new ContainsTagWithAttributes('span', $expectedattrs);
-    }
-
-    public function test_interactive_behaviour() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->hints = array(
-            new question_hint_with_parts(13, 'This is the first hint.', FORMAT_HTML, false, false),
-            new question_hint_with_parts(14, 'This is the second hint.', FORMAT_HTML, true, true),
-        );
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, '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_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $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_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '2'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '2'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '2'),
-                $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_drop_box_expectation('p1', 1, true),
-                $this->get_contains_drop_box_expectation('p2', 2, true),
-                $this->get_contains_drop_box_expectation('p3', 3, true),
-                $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_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '2'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '2'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '2'),
-                $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_drop_box_expectation('p1', 1, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p2', 2, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p3', 3, true, 'correct'),
-                $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);
-    }
-
-    public function test_deferred_feedback() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, 'deferredfeedback', 3);
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_does_not_contain_feedback_expectation());
-
-        // Save a partial answer.
-        $this->process_submission(array('p1' => '1', 'p2' => '2'));
-
-        // Verify.
-        $this->check_current_state(question_state::$invalid);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '2'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation());
-
-        // Save the right answer.
-        $this->process_submission(array('p1' => '1', 'p2' => '1', 'p3' => '1'));
-
-        // Verify.
-        $this->check_current_state(question_state::$complete);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '1'),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation());
-
-        // Finish the attempt.
-        $this->quba->finish_all_questions();
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedright);
-        $this->check_current_mark(3);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p2', 2, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p3', 3, true, 'correct'),
-                $this->get_contains_correct_expectation());
-
-        // Change the right answer a bit.
-        $dd->rightchoices[2] = 2;
-
-        // Check regrading does not mess anything up.
-        $this->quba->regrade_all_questions();
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedpartial);
-        $this->check_current_mark(2);
-    }
-
-    public function test_deferred_feedback_unanswered() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, 'deferredfeedback', 3);
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation());
-        $this->check_step_count(1);
-
-        // Save a blank response.
-        $this->process_submission(array('p1' => '0', 'p2' => '0', 'p3' => '0'));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation());
-        $this->check_step_count(1);
-
-        // Finish the attempt.
-        $this->quba->finish_all_questions();
-
-        // Verify.
-        $this->check_current_state(question_state::$gaveup);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true),
-                $this->get_contains_drop_box_expectation('p2', 2, true),
-                $this->get_contains_drop_box_expectation('p3', 3, true));
-    }
-
-    public function test_deferred_feedback_partial_answer() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, 'deferredfeedback', 3);
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation());
-
-        // Save a partial response.
-        $this->process_submission(array('p1' => '1', 'p2' => '0', 'p3' => '0'));
-
-        // Verify.
-        $this->check_current_state(question_state::$invalid);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation());
-
-        // Finish the attempt.
-        $this->quba->finish_all_questions();
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedpartial);
-        $this->check_current_mark(1);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p2', 2, true, 'incorrect'),
-                $this->get_contains_drop_box_expectation('p3', 3, true, 'incorrect'),
-                $this->get_contains_partcorrect_expectation());
-    }
-
-    public function test_interactive_grading() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->hints = array(
-            new question_hint_with_parts(1, 'This is the first hint.',
-                    FORMAT_MOODLE, true, true),
-            new question_hint_with_parts(2, 'This is the second hint.',
-                    FORMAT_MOODLE, true, true),
-        );
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, 'interactive', 9);
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->assertEqual('interactivecountback',
-                $this->quba->get_question_attempt($this->slot)->get_behaviour_name());
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_contains_submit_button_expectation(true),
-                $this->get_does_not_contain_feedback_expectation(),
-                $this->get_tries_remaining_expectation(3),
-                $this->get_does_not_contain_num_parts_correct(),
-                $this->get_no_hint_visible_expectation());
-
-        // Submit an response with the first two parts right.
-        $this->process_submission(array('p1' => '1', 'p2' => '1', 'p3' => '2', '-submit' => 1));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true),
-                $this->get_contains_drop_box_expectation('p2', 2, true),
-                $this->get_contains_drop_box_expectation('p3', 3, true),
-                $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'),
-                $this->get_contains_num_parts_correct(2),
-                $this->get_contains_standard_partiallycorrect_combined_feedback_expectation(),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'));
-
-        // Check that extract responses will return the reset data.
-        $prefix = $this->quba->get_field_prefix($this->slot);
-        $this->assertEqual(array('p1' => '1', 'p2' => '1'),
-                $this->quba->extract_responses($this->slot,
-                array($prefix . 'p1' => '1', $prefix . 'p2' => '1', '-tryagain' => 1)));
-
-        // Do try again.
-        $this->process_submission(array('p1' => '1', 'p2' => '1', '-tryagain' => 1));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_contains_submit_button_expectation(true),
-                $this->get_does_not_contain_try_again_button_expectation(),
-                $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 an response with the first and last parts right.
-        $this->process_submission(array('p1' => '1', 'p2' => '2', 'p3' => '1', '-submit' => 1));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true),
-                $this->get_contains_drop_box_expectation('p2', 2, true),
-                $this->get_contains_drop_box_expectation('p3', 3, true),
-                $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 second hint'),
-                $this->get_contains_num_parts_correct(2),
-                $this->get_contains_standard_partiallycorrect_combined_feedback_expectation(),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '1'));
-
-        // Do try again.
-        $this->process_submission(array('p1' => '1', 'p3' => '1', '-tryagain' => 1));
-
-        // Verify.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '1'),
-                $this->get_contains_submit_button_expectation(true),
-                $this->get_does_not_contain_try_again_button_expectation(),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation(),
-                $this->get_tries_remaining_expectation(1),
-                $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(6);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p2', 2, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p3', 3, true, 'correct'),
-                $this->get_contains_submit_button_expectation(false),
-                $this->get_does_not_contain_try_again_button_expectation(),
-                $this->get_contains_correct_expectation(),
-                $this->get_no_hint_visible_expectation(),
-                $this->get_does_not_contain_num_parts_correct(),
-                $this->get_contains_standard_correct_combined_feedback_expectation(),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '1'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '1'));
-    }
-
-    public function test_interactive_correct_no_submit() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->hints = array(
-            new question_hint_with_parts(23, 'This is the first hint.',
-                    FORMAT_MOODLE, false, false),
-            new question_hint_with_parts(24, 'This is the second hint.',
-                    FORMAT_MOODLE, true, true),
-        );
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, '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_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $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 right answer.
-        $this->process_submission(array('p1' => '1', 'p2' => '1', 'p3' => '1'));
-
-        // Finish the attempt without clicking check.
-        $this->quba->finish_all_questions();
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedright);
-        $this->check_current_mark(3);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p2', 2, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p3', 3, true, 'correct'),
-                $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(3);
-    }
-
-    public function test_interactive_partial_no_submit() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->hints = array(
-            new question_hint_with_parts(23, 'This is the first hint.',
-                    FORMAT_MOODLE, false, false),
-            new question_hint_with_parts(24, 'This is the second hint.',
-                    FORMAT_MOODLE, true, true),
-        );
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, '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_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $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 a partially right answer.
-        $this->process_submission(array('p1' => '1', 'p2' => '2', 'p3' => '2'));
-
-        // Finish the attempt without clicking check.
-        $this->quba->finish_all_questions();
-
-        // Verify.
-        $this->check_current_state(question_state::$gradedpartial);
-        $this->check_current_mark(1);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p2', 2, true, 'incorrect'),
-                $this->get_contains_drop_box_expectation('p3', 3, true, 'incorrect'),
-                $this->get_contains_submit_button_expectation(false),
-                $this->get_contains_partcorrect_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::$gradedpartial);
-        $this->check_current_mark(1);
-    }
-
-    public function test_interactive_no_right_clears() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $dd->hints = array(
-            new question_hint_with_parts(23, 'This is the first hint.', FORMAT_MOODLE, false, true),
-            new question_hint_with_parts(24, 'This is the second hint.', FORMAT_MOODLE, true, true),
-        );
-        $dd->shufflechoices = false;
-        $this->start_attempt_at_question($dd, '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_marked_out_of_summary(),
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $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 a completely 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_marked_out_of_summary(),
-                $this->get_contains_drop_box_expectation('p1', 1, true),
-                $this->get_contains_drop_box_expectation('p2', 2, true),
-                $this->get_contains_drop_box_expectation('p3', 3, true),
-                $this->get_contains_submit_button_expectation(false),
-                $this->get_contains_hint_expectation('This is the first hint'));
-
-        // Do try again.
-        $this->process_submission(array('p1' => '0', 'p2' => '0', 'p3' => '0', '-tryagain' => 1));
-
-        // Check that all the wrong answers have been cleared.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_marked_out_of_summary(),
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_contains_submit_button_expectation(true),
-                $this->get_does_not_contain_feedback_expectation(),
-                $this->get_tries_remaining_expectation(2),
-                $this->get_no_hint_visible_expectation());
-    }
-
-    public function test_display_of_right_answer_when_shuffled() {
-
-        // Create a drag-and-drop question.
-        $dd = test_question_maker::make_question('ddwtos');
-        $this->start_attempt_at_question($dd, 'deferredfeedback', 3);
-
-        // Check the initial state.
-        $this->check_current_state(question_state::$todo);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2', '0'),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3', '0'),
-                $this->get_does_not_contain_feedback_expectation());
-
-        // Save a partial answer.
-        $this->process_submission($dd->get_correct_response());
-
-        // Verify.
-        $this->check_current_state(question_state::$complete);
-        $this->check_current_mark(null);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, false),
-                $this->get_contains_drop_box_expectation('p2', 2, false),
-                $this->get_contains_drop_box_expectation('p3', 3, false),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p1',
-                                $dd->get_right_choice_for(1)),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p2',
-                                $dd->get_right_choice_for(2)),
-                $this->get_contains_hidden_expectation(
-                        $this->quba->get_field_prefix($this->slot) . 'p3',
-                                $dd->get_right_choice_for(3)),
-                $this->get_does_not_contain_correctness_expectation(),
-                $this->get_does_not_contain_feedback_expectation());
-
-        // Finish the attempt.
-        $this->quba->finish_all_questions();
-
-        // Verify.
-        $this->displayoptions->rightanswer = question_display_options::VISIBLE;
-        $this->assertEqual('{quick} {fox} {lazy}', $dd->get_right_answer_summary());
-        $this->check_current_state(question_state::$gradedright);
-        $this->check_current_mark(3);
-        $this->check_current_output(
-                $this->get_contains_drop_box_expectation('p1', 1, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p2', 2, true, 'correct'),
-                $this->get_contains_drop_box_expectation('p3', 3, true, 'correct'),
-                $this->get_contains_correct_expectation(),
-                new PatternExpectation('/' .
-                        preg_quote('The [quick] brown [fox] jumped over the [lazy] dog.') . '/'));
-    }
-}
diff --git a/question/type/ddwtos/styles.css b/question/type/ddwtos/styles.css
deleted file mode 100644 (file)
index 8a84a09..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-.que.ddwtos .qtext {
-    line-height: 2em;
-    margin-bottom: 0.5em;
-    display: block;
-}
-
-.que.ddwtos .qtext * {
-    line-height: 2em;
-}
-
-.que.ddwtos .answercontainer {
-    line-height: 2em;
-    margin-bottom: 1em;
-    display: block;
-}
-
-.que.ddwtos .answertext {
-    padding-bottom: 0.5em;
-}
-
-.que.ddwtos .slot {
-    display: inline-block;
-    text-align: center;
-    border: 1px solid #000000;
-}
-.que.ddwtos .player {
-    display: inline-block;
-    text-align: center;
-    cursor: move;
-    border: 1px solid #000000;
-}
-.que.ddwtos .player.placed { /* Lets the focus rectangle be visible in IE. */
-    background: transparent;
-}
-
-.que.ddwtos .readonly {
-    cursor: default;
-}
-
-.que.ddwtos span.incorrect {
-    background-color: #faa;
-}
-.que.ddwtos span.correct {
-    background-color: #afa;
-}
-
-.que.ddwtos .group1 {
-    background-color: #FFFFFF;
-}
-.que.ddwtos .group2 {
-    background-color: #DCDCDC;
-}
-.que.ddwtos .group3 {
-    background-color: #B0C4DE;
-}
-.que.ddwtos .group4 {
-    background-color: #D8BFD8;
-}
-.que.ddwtos .group5 {
-    background-color: #87CEFA;
-}
-.que.ddwtos .group6 {
-    background-color: #DAA520;
-}
-.que.ddwtos .group7 {
-    background-color: #FFD700;
-}
-.que.ddwtos .group8 {
-    background-color: #F0E68C;
-}
diff --git a/question/type/ddwtos/version.php b/question/type/ddwtos/version.php
deleted file mode 100644 (file)
index 036d05a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Version information for the drag-and-drop words into sentences question type.
- *
- * @package    qtype
- * @subpackage ddwtos
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-$plugin->version  = 2011051200;
-$plugin->requires = 2011051212;
diff --git a/question/type/gapselect/backup/moodle2/backup_qtype_gapselect_plugin.class.php b/question/type/gapselect/backup/moodle2/backup_qtype_gapselect_plugin.class.php
deleted file mode 100644 (file)
index 8af1eec..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * @package    moodlecore
- * @subpackage backup-moodle2
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Provides the information to backup gapselect questions
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class backup_qtype_gapselect_plugin extends backup_qtype_plugin {
-
-    /**
-     * Returns the qtype information to attach to question element
-     */
-    protected function define_question_plugin_structure() {
-
-        // Define the virtual plugin element with the condition to fulfill
-        $plugin = $this->get_plugin_element(null, '../../qtype', 'gapselect');
-
-        // Create one standard named plugin element (the visible container)
-        $pluginwrapper = new backup_nested_element($this->get_recommended_name());
-
-        // connect the visible container ASAP
-        $plugin->add_child($pluginwrapper);
-
-        // This qtype uses standard question_answers, add them here
-        // to the tree before any other information that will use them
-        $this->add_question_question_answers($pluginwrapper);
-
-        // Now create the qtype own structures
-        $gapselect = new backup_nested_element('gapselect', array('id'), array(
-            'shuffleanswers', 'correctfeedback', 'correctfeedbackformat',
-            'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
-            'incorrectfeedback', 'incorrectfeedbackformat', 'shownumcorrect'));
-
-        // Now the own qtype tree
-        $pluginwrapper->add_child($gapselect);
-
-        // set source to populate the data
-        $gapselect->set_source_table('question_gapselect',
-                array('questionid' => backup::VAR_PARENTID));
-
-        // don't need to annotate ids nor files
-
-        return $plugin;
-    }
-
-    /**
-     * Returns one array with filearea => mappingname elements for the qtype
-     *
-     * Used by {@link get_components_and_fileareas} to know about all the qtype
-     * files to be processed both in backup and restore.
-     */
-    public static function get_qtype_fileareas() {
-        return array(
-            'correctfeedback' => 'question_created',
-            'partiallycorrectfeedback' => 'question_created',
-            'incorrectfeedback' => 'question_created');
-    }
-}
diff --git a/question/type/gapselect/backup/moodle2/restore_qtype_gapselect_plugin.class.php b/question/type/gapselect/backup/moodle2/restore_qtype_gapselect_plugin.class.php
deleted file mode 100644 (file)
index 55f7c96..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * @package    moodlecore
- * @subpackage backup-moodle2
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * restore plugin class that provides the necessary information
- * needed to restore one gapselect qtype plugin
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class restore_qtype_gapselect_plugin extends restore_qtype_plugin {
-
-    /**
-     * Returns the paths to be handled by the plugin at question level
-     */
-    protected function define_question_plugin_structure() {
-
-        $paths = array();
-
-        // This qtype uses question_answers, add them
-        $this->add_question_question_answers($paths);
-
-        // Add own qtype stuff
-        $elename = 'gapselect';
-        // we used get_recommended_name() so this works
-        $elepath = $this->get_pathfor('/gapselect');
-        $paths[] = new restore_path_element($elename, $elepath);
-
-        return $paths; // And we return the interesting paths
-    }
-
-    /**
-     * Process the qtype/gapselect element
-     */
-    public function process_gapselect($data) {
-        global $DB;
-
-        $data = (object)$data;
-        $oldid = $data->id;
-
-        // Detect if the question is created or mapped
-        $oldquestionid   = $this->get_old_parentid('question');
-        $newquestionid   = $this->get_new_parentid('question');
-        $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
-
-        // If the question has been created by restore, we need to create its question_gapselect too
-        if ($questioncreated) {
-            // Adjust some columns
-            $data->questionid = $newquestionid;
-            // Insert record
-            $newitemid = $DB->insert_record('question_gapselect', $data);
-            // Create mapping (needed for decoding links)
-            $this->set_mapping('question_gapselect', $oldid, $newitemid);
-        }
-    }
-
-    /**
-     * Return the contents of this qtype to be processed by the links decoder
-     */
-    public static function define_decode_contents() {
-
-        $contents = array();
-
-        $fields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
-        $contents[] = new restore_decode_content('question_gapselect',
-                $fields, 'question_gapselect');
-
-        return $contents;
-    }
-}
diff --git a/question/type/gapselect/db/install.xml b/question/type/gapselect/db/install.xml
deleted file mode 100644 (file)
index cfab23d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="question/type/gapselect/db" VERSION="20080909" COMMENT="XMLDB file for Moodle question/type/gapselect"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
->
-  <TABLES>
-    <TABLE NAME="question_gapselect" COMMENT="Defines select missing words questions">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="questionid"/>
-        <FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="shuffleanswers"/>
-        <FIELD NAME="shuffleanswers" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="questionid" NEXT="correctfeedback"/>
-        <FIELD NAME="correctfeedback" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any correct response." PREVIOUS="shuffleanswers" NEXT="correctfeedbackformat"/>
-        <FIELD NAME="correctfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="correctfeedback" NEXT="partiallycorrectfeedback"/>
-        <FIELD NAME="partiallycorrectfeedback" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any partially correct response." PREVIOUS="correctfeedbackformat" NEXT="partiallycorrectfeedbackformat"/>
-        <FIELD NAME="partiallycorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="partiallycorrectfeedback" NEXT="incorrectfeedback"/>
-        <FIELD NAME="incorrectfeedback" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any incorrect response." PREVIOUS="partiallycorrectfeedbackformat" NEXT="incorrectfeedbackformat"/>
-        <FIELD NAME="incorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="incorrectfeedback" NEXT="shownumcorrect"/>
-        <FIELD NAME="shownumcorrect" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="incorrectfeedbackformat"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="questionid"/>
-        <KEY NAME="questionid" TYPE="foreign" FIELDS="questionid" REFTABLE="questions" REFFIELDS="id" PREVIOUS="primary"/>
-      </KEYS>
-    </TABLE>
-  </TABLES>
-</XMLDB>
\ No newline at end of file
diff --git a/question/type/gapselect/edit_form_base.php b/question/type/gapselect/edit_form_base.php
deleted file mode 100644 (file)
index 829a62d..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Base class for editing question types like this one.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Elements embedded in question text editing form definition.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_edit_form_base extends question_edit_form {
-    const MAX_GROUPS = 8;
-
-    /** @var array of HTML tags allowed in choices / drag boxes. */
-    protected $allowedhtmltags = array(
-        'sub',
-        'sup',
-        'b',
-        'i',
-        'em',
-        'strong'
-    );
-
-    /** @var string regex to match HTML open tags. */
-    private $htmltstarttagsandattributes = '/<\s*\w.*?>/';
-
-    /** @var string regex to match HTML close tags or br. */
-    private $htmltclosetags = '~<\s*/\s*\w\s*.*?>|<\s*br\s*>~';
-
-    /** @var string regex to select text like [[cat]] (including the square brackets). */
-    private $squarebracketsregex = '/\[\[[^]]*?\]\]/';
-
-    private function get_html_tags($text) {
-        $textarray = array();
-        foreach ($this->allowedhtmltags as $htmltag) {
-            $tagpair = "/<\s*\/?\s*$htmltag\s*.*?>/";
-            preg_match_all($tagpair, $text, $textarray);
-            if ($textarray[0]) {
-                return $textarray[0];
-            }
-        }
-
-        preg_match_all($this->htmltstarttagsandattributes, $text, $textarray);
-        if ($textarray[0]) {
-            $tag = htmlspecialchars($textarray[0][0]);
-            $allowedtaglist = $this->get_list_of_printable_allowed_tags($this->allowedhtmltags);
-            return $tag . ' is not allowed (only ' . $allowedtaglist .
-                    ' and corresponsing closing tags are allowed)';
-        }
-
-        preg_match_all($this->htmltclosetags, $text, $textarray);
-        if ($textarray[0]) {
-            $tag = htmlspecialchars($textarray[0][0]);
-            $allowedtaglist=$this->get_list_of_printable_allowed_tags($this->allowedhtmltags);
-            return $tag . ' is not allowed (only ' . $allowedtaglist .
-                    ' and corresponsing closing tags are allowed)';
-        }
-
-        return false;
-    }
-
-    private function get_list_of_printable_allowed_tags($allowedhtmltags) {
-        $allowedtaglist = null;
-        foreach ($allowedhtmltags as $htmltag) {
-            $allowedtaglist .= htmlspecialchars('<'.$htmltag.'>') . ', ';
-        }
-        return $allowedtaglist;
-    }
-
-    /**
-     * definition_inner adds all specific fields to the form.
-     * @param object $mform (the form being built).
-     */
-    protected function definition_inner($mform) {
-        global $CFG;
-
-        //add the answer (choice) fields to the form
-        $this->definition_answer_choice($mform);
-
-        $this->add_combined_feedback_fields(true);
-        $this->add_interactive_settings(true, true);
-    }
-
-    protected function definition_answer_choice(&$mform) {
-        $mform->addElement('header', 'choicehdr', get_string('choices', 'qtype_gapselect'));
-
-        $mform->addElement('checkbox', 'shuffleanswers', get_string('shuffle', 'qtype_gapselect'));
-        $mform->setDefault('shuffleanswers', 0);
-
-        $textboxgroup = array();
-        $textboxgroup[] = $mform->createElement('group', 'choices',
-                get_string('choicex', 'qtype_gapselect'), $this->choice_group($mform));
-
-        if (isset($this->question->options)) {
-            $countanswers = count($this->question->options->answers);
-        } else {
-            $countanswers = 0;
-        }
-
-        if ($this->question->formoptions->repeatelements) {
-            $defaultstartnumbers = QUESTION_NUMANS_START * 2;
-            $repeatsatstart = max($defaultstartnumbers, QUESTION_NUMANS_START,
-                    $countanswers + QUESTION_NUMANS_ADD);
-        } else {
-            $repeatsatstart = $countanswers;
-        }
-
-        $repeatedoptions = $this->repeated_options();
-        $mform->setType('answer', PARAM_RAW);
-        $this->repeat_elements($textboxgroup, $repeatsatstart, $repeatedoptions,
-                'noanswers', 'addanswers', QUESTION_NUMANS_ADD,
-                get_string('addmorechoiceblanks', 'qtype_gapselect'));
-    }
-
-    protected function choice_group($mform) {
-        $options = array();
-        for ($i = 1; $i <= self::MAX_GROUPS; $i += 1) {
-            $options[$i] = $i;
-        }
-        $grouparray = array();
-        $grouparray[] = $mform->createElement('text', 'answer',
-                get_string('answer', 'qtype_gapselect'), array('size'=>30, 'class'=>'tweakcss'));
-        $grouparray[] = $mform->createElement('static', '', '', ' ' .
-                get_string('group', 'qtype_gapselect').' ');
-        $grouparray[] = $mform->createElement('select', 'choicegroup',
-                get_string('group', 'qtype_gapselect'), $options);
-        return $grouparray;
-    }
-
-    protected function repeated_options() {
-        $repeatedoptions = array();
-        $repeatedoptions['choicegroup']['default'] = '1';
-        return $repeatedoptions;
-    }
-
-    public function data_preprocessing($question) {
-        $question = parent::data_preprocessing($question);
-        $question = $this->data_preprocessing_combined_feedback($question, true);
-        $question = $this->data_preprocessing_hints($question, true, true);
-
-        $question = $this->data_preprocessing_answers($question, true);
-        if (!empty($question->options->answers)) {
-            $key = 0;
-            foreach ($question->options->answers as $answer) {
-                $question = $this->data_preprocessing_choice($question, $answer, $key);
-                $key++;
-            }
-        }
-
-        if (!empty($question->options)) {
-            $question->shuffleanswers = $question->options->shuffleanswers;
-        }
-
-        return $question;
-    }
-
-    protected function data_preprocessing_choice($question, $answer, $key) {
-        // See comment in data_preprocessing_answers.
-        unset($this->_form->_defaultValues['choices[$key][choicegroup]']);
-        $question->choices[$key]['answer'] = $answer->answer;
-        $question->choices[$key]['choicegroup'] = $answer->feedback;
-        return $question;
-    }
-
-    public function validation($data, $files) {
-        $errors = parent::validation($data, $files);
-        $questiontext = $data['questiontext'];
-        $choices = $data['choices'];
-
-        //check the whether the slots are valid
-        $errorsinquestiontext = $this->validate_slots($questiontext['text'], $choices);
-        if ($errorsinquestiontext) {
-            $errors['questiontext'] = $errorsinquestiontext;
-        }
-        foreach ($choices as $key => $choice) {
-            $answer = $choice['answer'];
-
-            //check whether the html-tags are allowed tags
-            $validtags = $this->get_html_tags($answer);
-            if (is_array($validtags)) {
-                continue;
-            }
-            if ($validtags) {
-                $errors['choices['.$key.']'] = $validtags;
-            }
-        }
-        return $errors;
-    }
-
-    private function validate_slots($questiontext, $choices) {
-        $error = 'Please check the Question text: ';
-        if (!$questiontext) {
-            return $error . 'The question text is empty!';
-        }
-
-        $matches = array();
-        preg_match_all($this->squarebracketsregex, $questiontext, $matches);
-        $slots = $matches[0];
-
-        if (!$slots) {
-            return $error . 'The question text is not in the correct format!';
-        }
-
-        $output = array();
-        foreach ($slots as $slot) {
-            // The 2 is for'[[' and 4 is for '[[]]'.
-            $output[] = substr($slot, 2, (strlen($slot)-4));
-        }
-
-        $slots = $output;
-        $found = false;
-        foreach ($slots as $slot) {
-            $found = false;
-            foreach ($choices as $key => $choice) {
-                if ($slot == $key + 1) {
-                    if (!$choice['answer']) {
-                        return " Please check Choices: The choice <b>$slot</b> empty.";
-                    }
-                    $found = true;
-                    break;
-                }
-            }
-            if (!$found) {
-                return $error . '<b>' . $slot . '</b> was not found in Choices! ' .
-                        '(only the choice numbers that exist in choices are allowed ' .
-                        'to be used a place holders!';
-            }
-        }
-        return false;
-    }
-
-    public function qtype() {
-        return '';
-    }
-}
\ No newline at end of file
diff --git a/question/type/gapselect/edit_gapselect_form.php b/question/type/gapselect/edit_gapselect_form.php
deleted file mode 100644 (file)
index c0b0060..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Defines the editing form for the select missing words question type.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/type/gapselect/edit_form_base.php');
-
-
-/**
- * Select from drop down list question editing form definition.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_edit_form extends qtype_gapselect_edit_form_base {
-    // HTML tags allowed in answers (choices).
-    protected $allowedhtmltags = array();
-
-    public function qtype() {
-        return 'gapselect';
-    }
-}
diff --git a/question/type/gapselect/lang/en/qtype_gapselect.php b/question/type/gapselect/lang/en/qtype_gapselect.php
deleted file mode 100644 (file)
index fd25df2..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Language strings for the sdrag-and-drop words into sentences question type.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-$string['addinggapselect'] = 'Adding a select missing words question';
-$string['addmorechoiceblanks'] = 'Blanks for {no} more choices';
-$string['answer'] = 'Answer';
-$string['choices'] = 'Choices';
-$string['choicex'] = 'Choice {no}';
-$string['correctansweris'] = 'The correct answer is: {$a}';
-$string['editinggapselect'] = 'Editing a select missing words question';
-$string['gapselect'] = 'Select missing words';
-$string['gapselect_help'] = 'Type in some question text like "The [[1]] jumped over the [[2]]", then enter the possible words to go in gaps 1 and 2 underneath.';
-$string['gapselectsummary'] = 'Missing words in some text are filled in using dropdown menus.';
-$string['group'] = 'Group';
-$string['pleaseputananswerineachbox'] = 'Please put an answer in each box.';
-$string['shuffle'] = 'Shuffle';
diff --git a/question/type/gapselect/pix/icon.gif b/question/type/gapselect/pix/icon.gif
deleted file mode 100644 (file)
index f900852..0000000
Binary files a/question/type/gapselect/pix/icon.gif and /dev/null differ
diff --git a/question/type/gapselect/question.php b/question/type/gapselect/question.php
deleted file mode 100644 (file)
index e3ec5e3..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Select from drop down list question definition class.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/type/gapselect/questionbase.php');
-
-
-/**
- * Represents select missing words question.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_question extends qtype_gapselect_question_base {
-    // Is actually exactly the same.
-}
-
-
-/**
- * Represents one of the choices (select box option).
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_choice {
-    public $text;
-    public $selectgroup;
-
-    public function __construct($text, $selectgroup = 1) {
-        $this->text = $text;
-        $this->selectgroup = $selectgroup;
-    }
-
-    public function choice_group() {
-        return $this->selectgroup;
-    }
-}
diff --git a/question/type/gapselect/questionbase.php b/question/type/gapselect/questionbase.php
deleted file mode 100644 (file)
index bcda4bd..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Definition class for embedded element in question text question. Parent of
- * gap-select, drag and drop and possibly others.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Represents embedded element in question text question. Parent of drag and drop and select from
- * drop down list and ?others?
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-abstract class qtype_gapselect_question_base extends question_graded_automatically_with_countback {
-    /** @var boolean Whether the question stems should be shuffled. */
-    public $shufflechoices;
-
-    public $correctfeedback;
-    public $partiallycorrectfeedback;
-    public $incorrectfeedback;
-
-    /** @var array of arrays. The keys are the choice group numbers. The values
-     * are arrays of qtype_gapselect_choice objects. */
-    public $choices;
-
-    /**
-     * @var array place number => group number of the places in the question
-     * text where choices can be put. Places are numbered from 1.
-     */
-    public $places;
-
-    /**
-     * @var array of strings, one longer than $places, which is achieved by
-     * indexing from 0. The bits of question text that go between the placeholders.
-     */
-    public $textfragments;
-
-    /** @var array index of the right choice for each stem. */
-    public $rightchoices;
-
-    /** @var array shuffled choice indexes. */
-    protected $choiceorder;
-
-    public function start_attempt(question_attempt_step $step) {
-        foreach ($this->choices as $group => $choices) {
-            $choiceorder = array_keys($choices);
-            if ($this->shufflechoices) {
-                shuffle($choiceorder);
-            }
-            $step->set_qt_var('_choiceorder' . $group, implode(',', $choiceorder));
-            $this->set_choiceorder($group, $choiceorder);
-        }
-    }
-
-    public function apply_attempt_state(question_attempt_step $step) {
-        foreach ($this->choices as $group => $choices) {
-            $this->set_choiceorder($group, explode(',',
-                    $step->get_qt_var('_choiceorder' . $group)));
-        }
-    }
-
-    /**
-     * Helper method used by both {@link start_attempt()} and
-     * {@link apply_attempt_state()}.
-     * @param int $group the group number.
-     * @param array $choiceorder the choices, in order.
-     */
-    protected function set_choiceorder($group, $choiceorder) {
-        foreach ($choiceorder as $key => $value) {
-            $this->choiceorder[$group][$key + 1] = $value;
-        }
-    }
-
-    public function get_question_summary() {
-        $question = $this->html_to_text($this->questiontext, $this->questiontextformat);
-        $groups = array();
-        foreach ($this->choices as $group => $choices) {
-            $cs = array();
-            foreach ($choices as $choice) {
-                $cs[] = html_to_text($choice->text, 0, false);
-            }
-            $groups[] = '[[' . $group . ']] -> {' . implode(' / ', $cs) . '}';
-        }
-        return $question . '; ' . implode('; ', $groups);
-    }
-
-    protected function get_selected_choice($group, $shuffledchoicenumber) {
-        $choiceno = $this->choiceorder[$group][$shuffledchoicenumber];
-        return $this->choices[$group][$choiceno];
-    }
-
-    public function summarise_response(array $response) {
-        $matches = array();
-        $allblank = true;
-        foreach ($this->places as $place => $group) {
-            if (array_key_exists($this->field($place), $response) &&
-                    $response[$this->field($place)]) {
-                $choices[] = '{' . html_to_text($this->get_selected_choice(
-                        $group, $response[$this->field($place)])->text, 0, false) . '}';
-                $allblank = false;
-            } else {
-                $choices[] = '{}';
-            }
-        }
-        if ($allblank) {
-            return null;
-        }
-        return implode(' ', $choices);
-    }
-
-    public function get_random_guess_score() {
-        $accum = 0;
-
-        foreach ($this->places as $placegroup) {
-            $accum += 1 / count($this->choices[$placegroup]);
-        }
-
-        return $accum / count($this->places);
-    }
-
-    public function clear_wrong_from_response(array $response) {
-        foreach ($this->places as $place => $notused) {
-            if (array_key_exists($this->field($place), $response) &&
-                    $response[$this->field($place)] != $this->get_right_choice_for($place)) {
-                $response[$this->field($place)] = '0';
-            }
-        }
-        return $response;
-    }
-
-    public function get_num_parts_right(array $response) {
-        $numright = 0;
-        foreach ($this->places as $place => $notused) {
-            if (!array_key_exists($this->field($place), $response)) {
-                continue;
-            }
-            if ($response[$this->field($place)] == $this->get_right_choice_for($place)) {
-                $numright += 1;
-            }
-        }
-        return array($numright, count($this->places));
-    }
-
-    /**
-     * @param int $key stem number
-     * @return string the question-type variable name.
-     */
-    public function field($place) {
-        return 'p' . $place;
-    }
-
-    public function get_expected_data() {
-        $vars = array();
-        foreach ($this->places as $place => $notused) {
-            $vars[$this->field($place)] = PARAM_INTEGER;
-        }
-        return $vars;
-    }
-
-    public function get_correct_response() {
-        $response = array();
-        foreach ($this->places as $place => $notused) {
-            $response[$this->field($place)] = $this->get_right_choice_for($place);
-        }
-        return $response;
-    }
-
-    public function get_right_choice_for($place) {
-        $group = $this->places[$place];
-        foreach ($this->choiceorder[$group] as $choicekey => $choiceid) {
-            if ($this->rightchoices[$place] == $choiceid) {
-                return $choicekey;
-            }
-        }
-    }
-
-    public function get_ordered_choices($group) {
-        $choices = array();
-        foreach ($this->choiceorder[$group] as $choicekey => $choiceid) {
-            $choices[$choicekey] = $this->choices[$group][$choiceid];
-        }
-        return $choices;
-    }
-
-    public function is_complete_response(array $response) {
-        $complete = true;
-        foreach ($this->places as $place => $notused) {
-            $complete = $complete && !empty($response[$this->field($place)]);
-        }
-        return $complete;
-    }
-
-    public function is_gradable_response(array $response) {
-        foreach ($this->places as $place => $notused) {
-            if (!empty($response[$this->field($place)])) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public function is_same_response(array $prevresponse, array $newresponse) {
-        foreach ($this->places as $place => $notused) {
-            $fieldname = $this->field($place);
-            if (!question_utils::arrays_same_at_key_integer(
-                    $prevresponse, $newresponse, $fieldname)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public function get_validation_error(array $response) {
-        if ($this->is_complete_response($response)) {
-            return '';
-        }
-        return get_string('pleaseputananswerineachbox', 'qtype_gapselect');
-    }
-
-    public function grade_response(array $response) {
-        list($right, $total) = $this->get_num_parts_right($response);
-        $fraction = $right / $total;
-        return array($fraction, question_state::graded_state_for_fraction($fraction));
-    }
-
-    public function compute_final_grade($responses, $totaltries) {
-        $totalscore = 0;
-        foreach ($this->places as $place => $notused) {
-            $fieldname = $this->field($place);
-
-            $lastwrongindex = -1;
-            $finallyright = false;
-            foreach ($responses as $i => $response) {
-                if (!array_key_exists($fieldname, $response) ||
-                        $response[$fieldname] != $this->get_right_choice_for($place)) {
-                    $lastwrongindex = $i;
-                    $finallyright = false;
-                } else {
-                    $finallyright = true;
-                }
-            }
-
-            if ($finallyright) {
-                $totalscore += max(0, 1 - ($lastwrongindex + 1) * $this->penalty);
-            }
-        }
-
-        return $totalscore / count($this->places);
-    }
-
-    public function classify_response(array $response) {
-        $parts = array();
-        foreach ($this->places as $place => $group) {
-            if (!array_key_exists($this->field($place), $response) ||
-                    !$response[$this->field($place)]) {
-                $parts[$place] = question_classified_response::no_response();
-                continue;
-            }
-
-            $fieldname = $this->field($place);
-            $choiceno = $this->choiceorder[$group][$response[$fieldname]];
-            $choice = $this->choices[$group][$choiceno];
-            $parts[$place] = new question_classified_response(
-                    $choiceno, html_to_text($choice->text, 0, false),
-                    $this->get_right_choice_for($place) == $response[$fieldname]);
-        }
-        return $parts;
-    }
-
-    public function check_file_access($qa, $options, $component, $filearea, $args, $forcedownload) {
-        if ($component == 'question' && in_array($filearea,
-                array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback'))) {
-            return $this->check_combined_feedback_file_access($qa, $options, $filearea);
-
-        } else if ($component == 'question' && $filearea == 'hint') {
-            return $this->check_hint_file_access($qa, $options, $args);
-
-        } else {
-            return parent::check_file_access($qa, $options, $component, $filearea,
-                    $args, $forcedownload);
-        }
-    }
-}
diff --git a/question/type/gapselect/questiontype.php b/question/type/gapselect/questiontype.php
deleted file mode 100644 (file)
index 308b613..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Question type class for the select missing words question type.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir . '/questionlib.php');
-require_once($CFG->dirroot . '/question/engine/lib.php');
-require_once($CFG->dirroot . '/question/format/xml/format.php');
-require_once($CFG->dirroot . '/question/type/gapselect/questiontypebase.php');
-
-
-/**
- * The select missing words question type class.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect extends qtype_gapselect_base {
-    protected function choice_options_to_feedback($choice) {
-        return $choice['choicegroup'];
-    }
-
-    protected function make_choice($choicedata) {
-        return new qtype_gapselect_choice($choicedata->answer, $choicedata->feedback);
-    }
-
-    protected function feedback_to_choice_options($feedback) {
-        return array('selectgroup' => $feedback);
-    }
-
-
-    protected function choice_group_key() {
-        return 'selectgroup';
-    }
-
-    public function import_from_xml($data, $question, $format, $extra=null) {
-        if (!isset($data['@']['type']) || $data['@']['type'] != 'gapselect') {
-            return false;
-        }
-
-        $question = $format->import_headers($data);
-        $question->qtype = 'gapselect';
-
-        $question->shuffleanswers = $format->trans_single(
-                $format->getpath($data, array('#', 'shuffleanswers', 0, '#'), 1));
-
-        if (!empty($data['#']['selectoption'])) {
-            // Modern XML format.
-            $selectoptions = $data['#']['selectoption'];
-            $question->answer = array();
-            $question->selectgroup = array();
-
-            foreach ($data['#']['selectoption'] as $selectoptionxml) {
-                $question->choices[] = array(
-                    'answer'      => $format->getpath($selectoptionxml,
-                                                      array('#', 'text', 0, '#'), '', true),
-                    'choicegroup' => $format->getpath($selectoptionxml,
-                                                      array('#', 'group', 0, '#'), 1),
-                );
-            }
-
-        } else {
-            // Legacy format containing PHP serialisation.
-            foreach ($data['#']['answer'] as $answerxml) {
-                $ans = $format->import_answer($answerxml);
-                $question->choices[] = array(
-                    'answer' => $ans->answer,
-                    'choicegroup' => $ans->feedback,
-                );
-            }
-        }
-
-        $format->import_combined_feedback($question, $data, true);
-        $format->import_hints($question, $data, true);
-
-        return $question;
-    }
-
-    public function export_to_xml($question, $format, $extra = null) {
-        $output = '';
-
-        $output .= '    <shuffleanswers>' . $question->options->shuffleanswers .
-                "</shuffleanswers>\n";
-
-        $output .= $format->write_combined_feedback($question->options);
-
-        foreach ($question->options->answers as $answer) {
-            $output .= "    <selectoption>\n";
-            $output .= $format->writetext($answer->answer, 3);
-            $output .= "      <group>{$answer->feedback}</group>\n";
-            $output .= "    </selectoption>\n";
-        }
-
-        return $output;
-    }
-}
diff --git a/question/type/gapselect/questiontypebase.php b/question/type/gapselect/questiontypebase.php
deleted file mode 100644 (file)
index c321b7e..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Question type class for the embedded element in question text question types.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir . '/questionlib.php');
-require_once($CFG->dirroot . '/question/engine/lib.php');
-require_once($CFG->dirroot . '/question/format/xml/format.php');
-
-
-/**
- * The embedded element in question text question type class.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-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
-     * converting all the options to a single string for this purpose. It is used
-     * by {@link save_question_options()}.
-     * @param array $choice the form data relating to this choice.
-     * @return string ready to store in the database.
-     */
-    protected abstract function choice_options_to_feedback($choice);
-
-    public function save_question_options($question) {
-        global $DB;
-        $context = $question->context;
-        $result = new stdClass();
-
-        $oldanswers = $DB->get_records('question_answers',
-                array('question' => $question->id), 'id ASC');
-
-        // Insert all the new answers
-        foreach ($question->choices as $key => $choice) {
-
-            if (trim($choice['answer']) == '') {
-                continue;
-            }
-
-            $feedback = $this->choice_options_to_feedback($choice);
-
-            if ($answer = array_shift($oldanswers)) {
-                $answer->answer = $choice['answer'];
-                $answer->feedback = $feedback;
-                $DB->update_record('question_answers', $answer);
-
-            } else {
-                $answer = new stdClass();
-                $answer->question = $question->id;
-                $answer->answer = $choice['answer'];
-                $answer->answerformat = FORMAT_HTML;
-                $answer->fraction = 0;
-                $answer->feedback = $feedback;
-                $answer->feedbackformat = 0;
-                $DB->insert_record('question_answers', $answer);
-            }
-        }
-
-        // Delete old answer records
-        foreach ($oldanswers as $oa) {
-            delete_records('question_answers', 'id', $oa->id);
-        }
-
-        $options = $DB->get_record('question_' . $this->name(),
-                array('questionid' => $question->id));
-        if (!$options) {
-            $options = new stdClass();
-            $options->questionid = $question->id;
-            $options->correctfeedback = '';
-            $options->partiallycorrectfeedback = '';
-            $options->incorrectfeedback = '';
-            $options->id = $DB->insert_record('question_' . $this->name(), $options);
-        }
-
-        $options->shuffleanswers = !empty($question->shuffleanswers);
-        $options = $this->save_combined_feedback_helper($options, $question, $context, true);
-        $DB->update_record('question_' . $this->name(), $options);
-
-        $this->save_hints($question, true);
-    }
-
-    public function get_question_options($question) {
-        global $DB;
-        $question->options = $DB->get_record('question_'.$this->name(),
-                array('questionid' => $question->id), '*', MUST_EXIST);
-        parent::get_question_options($question);
-    }
-
-    public function delete_question($questionid, $contextid) {
-        global $DB;
-        $DB->delete_records('question_'.$this->name(), array('questionid' => $questionid));
-        return parent::delete_question($questionid, $contextid);
-    }
-
-    /**
-     * Used by {@link initialise_question_instance()} to set up the choice-specific data.
-     * @param object $choicedata as loaded from the question_answers table.
-     * @return object an appropriate object for representing the choice.
-     */
-    protected abstract function make_choice($choicedata);
-
-    protected function initialise_question_instance(question_definition $question, $questiondata) {
-        parent::initialise_question_instance($question, $questiondata);
-
-        $question->shufflechoices = $questiondata->options->shuffleanswers;
-
-        $this->initialise_combined_feedback($question, $questiondata, true);
-
-        $question->choices = array();
-        $choiceindexmap= array();
-
-        // Store the choices in arrays by group.
-        $i = 1;
-        foreach ($questiondata->options->answers as $choicedata) {
-            $choice = $this->make_choice($choicedata);
-
-            if (array_key_exists($choice->choice_group(), $question->choices)) {
-                $question->choices[$choice->choice_group()][] = $choice;
-            } else {
-                $question->choices[$choice->choice_group()][1] = $choice;
-            }
-
-            end($question->choices[$choice->choice_group()]);
-            $choiceindexmap[$i] = array($choice->choice_group(),
-                    key($question->choices[$choice->choice_group()]));
-            $i += 1;
-        }
-
-        $question->places = array();
-        $question->textfragments = array();
-        $question->rightchoices = array();
-        // Break up the question text, and store the fragments, places and right answers.
-
-        $bits = preg_split('/\[\[(\d+)]]/', $question->questiontext,
-                null, PREG_SPLIT_DELIM_CAPTURE);
-        $question->textfragments[0] = array_shift($bits);
-        $i = 1;
-
-        while (!empty($bits)) {
-            $choice = array_shift($bits);
-
-            list($group, $choiceindex) = $choiceindexmap[$choice];
-            $question->places[$i] = $group;
-            $question->rightchoices[$i] = $choiceindex;
-
-            $question->textfragments[$i] = array_shift($bits);
-            $i += 1;
-        }
-    }
-
-    protected function make_hint($hint) {
-        return question_hint_with_parts::load_from_record($hint);
-    }
-
-    public function get_random_guess_score($questiondata) {
-        $question = $this->make_question($questiondata);
-        return $question->get_random_guess_score();
-    }
-
-    /**
-     * This function should reverse {@link choice_options_to_feedback()}.
-     * @param string $feedback the data loaded from the database.
-     * @return array the choice options.
-     */
-    protected abstract function feedback_to_choice_options($feedback);
-
-    /**
-     * This method gets the choices (answers)
-     * in a 2 dimentional array.
-     *
-     * @param object $question
-     * @return array of groups
-     */
-    protected function get_array_of_choices($question) {
-        $subquestions = $question->options->answers;
-        $count = 0;
-        foreach ($subquestions as $key => $subquestion) {
-            $answers[$count]['id'] = $subquestion->id;
-            $answers[$count]['answer'] = $subquestion->answer;
-            $answers[$count]['fraction'] = $subquestion->fraction;
-            $answers[$count] += $this->feedback_to_choice_options($subquestion->feedback);
-            $answers[$count]['choice'] = $count+1;
-            ++$count;
-        }
-        return $answers;
-    }
-
-    /**
-     * This method gets the choices (answers) and sort them by groups
-     * in a 2 dimentional array.
-     *
-     * @param object $question
-     * @return array of groups
-     */
-    protected function get_array_of_groups($question, $state) {
-        $answers = $this->get_array_of_choices($question);
-        $arr = array();
-        for ($group=1; $group < count($answers); $group++) {
-            $players = $this->get_group_of_players($question, $state, $answers, $group);
-            if ($players) {
-                $arr[$group]= $players;
-            }
-        }
-        return $arr;
-    }
-
-    /**
-     * This method gets the correct answers in a 2 dimentional array.
-     *
-     * @param object $question
-     * @return array of groups
-     */
-    protected function get_correct_answers($question) {
-        $arrayofchoices = $this->get_array_of_choices($question);
-        $arrayofplaceholdeers = $this->get_array_of_placeholders($question);
-
-        $correctplayers = array();
-        foreach ($arrayofplaceholdeers as $ph) {
-            foreach ($arrayofchoices as $key => $choice) {
-                if ($key + 1 == $ph) {
-                    $correctplayers[]= $choice;
-                }
-            }
-        }
-        return $correctplayers;
-    }
-
-    protected function get_array_of_placeholders($question) {
-        $qtext = $question->questiontext;
-        $error = '<b> ERROR</b>: Please check the form for this question. ';
-        if (!$qtext) {
-            echo $error . 'The question text is empty!';
-            return false;
-        }
-
-        //get the slots
-        $slots = $this->getEmbeddedTextArray($question);
-
-        if (!$slots) {
-            echo $error . 'The question text is not in the correct format!';
-            return false;
-        }
-
-        $output = array();
-        foreach ($slots as $slot) {
-            $output[] = substr($slot, 2, strlen($slot) - 4); //2 is for '[[' and 4 is for '[[]]'.
-        }
-        return $output;
-    }
-
-    protected function get_group_of_players($question, $state, $subquestions, $group) {
-        $goupofanswers = array();
-        foreach ($subquestions as $key => $subquestion) {
-            if ($subquestion[$this->choice_group_key()] == $group) {
-                $goupofanswers[] = $subquestion;
-            }
-        }
-
-        // Shuffle answers within this group
-        if ($question->options->shuffleanswers == 1) {
-            shuffle($goupofanswers);
-        }
-        return $goupofanswers;
-    }
-
-    public function get_possible_responses($questiondata) {
-        $question = $this->make_question($questiondata);
-
-        $parts = array();
-        foreach ($question->places as $place => $group) {
-            $choices = array();
-
-            foreach ($question->choices[$group] as $i => $choice) {
-                $choices[$i] = new question_possible_response(
-                        html_to_text($choice->text, 0, false),
-                        $question->rightchoices[$place] == $i);
-            }
-            $choices[null] = question_possible_response::no_response();
-
-            $parts[$place] = $choices;
-        }
-
-        return $parts;
-    }
-
-    public function move_files($questionid, $oldcontextid, $newcontextid) {
-        parent::move_files($questionid, $oldcontextid, $newcontextid);
-
-        $fs = get_file_storage();
-        $fs->move_area_files_to_new_context($oldcontextid,
-                $newcontextid, 'question', 'correctfeedback', $questionid);
-        $fs->move_area_files_to_new_context($oldcontextid,
-                $newcontextid, 'question', 'partiallycorrectfeedback', $questionid);
-        $fs->move_area_files_to_new_context($oldcontextid,
-                $newcontextid, 'question', 'incorrectfeedback', $questionid);
-    }
-
-    protected function delete_files($questionid, $contextid) {
-        parent::delete_files($questionid, $contextid);
-
-        $fs = get_file_storage();
-        $fs->delete_area_files($contextid, 'question', 'correctfeedback', $questionid);
-        $fs->delete_area_files($contextid, 'question', 'partiallycorrectfeedback', $questionid);
-        $fs->delete_area_files($contextid, 'question', 'incorrectfeedback', $questionid);
-    }
-}
diff --git a/question/type/gapselect/renderer.php b/question/type/gapselect/renderer.php
deleted file mode 100644 (file)
index 2e4d9d9..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Select from drop down list question renderer class.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/type/gapselect/rendererbase.php');
-
-
-/**
- * Generates the output for select missing words questions.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_renderer extends qtype_elements_embedded_in_question_text_renderer {
-    protected function embedded_element(question_attempt $qa, $place,
-            question_display_options $options) {
-        $question = $qa->get_question();
-        $group = $question->places[$place];
-
-        $fieldname = $question->field($place);
-
-        $value = $qa->get_last_qt_var($question->field($place));
-
-        $attributes = array(
-            'id' => $this->box_id($qa, 'p' . $place, $group),
-        );
-        $groupclass = 'group' . $group;
-
-        if ($options->readonly) {
-            $attributes['disabled'] = 'disabled';
-        }
-
-        $orderedchoices = $question->get_ordered_choices($group);
-        $selectoptions = array();
-        foreach ($orderedchoices as $orderedchoicevalue => $orderedchoice) {
-            $selectoptions[$orderedchoicevalue] = $orderedchoice->text;
-        }
-
-        $feedbackimage = '';
-        if ($options->correctness) {
-            $response = $qa->get_last_qt_data();
-            if (array_key_exists($fieldname, $response)) {
-                $fraction = (int) ($response[$fieldname] ==
-                        $question->get_right_choice_for($place));
-                $attributes['class'] = $this->feedback_class($fraction);
-                $feedbackimage = $this->feedback_image($fraction);
-            }
-        }
-
-        $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
deleted file mode 100644 (file)
index fae921e..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Base class for rendering question types like this one.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Generates the output for question types where the question includes embedded
- * interactive elements in the question text.
- *
- * @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 {
-    public function formulation_and_controls(question_attempt $qa,
-            question_display_options $options) {
-
-        $question = $qa->get_question();
-
-        $questiontext = '';
-        foreach ($question->textfragments as $i => $fragment) {
-            if ($i > 0) {
-                $questiontext .= $this->embedded_element($qa, $i, $options);
-            }
-            $questiontext .= $fragment;
-        }
-
-        $result = '';
-        $result .= html_writer::tag('div', $question->format_text($questiontext,
-                $question->questiontextformat, $qa, 'question', 'questiontext', $question->id),
-                array('class' => $this->qtext_classname(), 'id' => $qa->get_qt_field_name('')));
-
-        $result .= $this->post_qtext_elements($qa, $options);
-
-        if ($qa->get_state() == question_state::$invalid) {
-            $result .= html_writer::nonempty_tag('div',
-                    $question->get_validation_error($qa->get_last_qt_data()),
-                    array('class' => 'validationerror'));
-        }
-
-        return $result;
-    }
-
-    protected function qtext_classname() {
-        return 'qtext';
-    }
-
-    protected abstract function embedded_element(question_attempt $qa, $place,
-            question_display_options $options);
-
-    protected function post_qtext_elements(question_attempt $qa,
-            question_display_options $options) {
-        return '';
-    }
-
-    protected function box_id(question_attempt $qa, $place, $group) {
-        return $qa->get_qt_field_name($place) . '_' . $group;
-    }
-
-    public function specific_feedback(question_attempt $qa) {
-        return $this->combined_feedback($qa);
-    }
-
-    public function correct_response(question_attempt $qa) {
-        $question = $qa->get_question();
-
-        $correctanswer = '';
-        foreach ($question->textfragments as $i => $fragment) {
-            if ($i > 0) {
-                $group = $question->places[$i];
-                $choice = $question->choices[$group][$question->rightchoices[$i]];
-                $correctanswer .= '[' . str_replace('-', '&#x2011;',
-                        $choice->text) . ']';
-            }
-            $correctanswer .= $fragment;
-        }
-
-        if (!empty($correctanswer)) {
-            return get_string('correctansweris', 'qtype_gapselect', $correctanswer);
-        }
-    }
-}
diff --git a/question/type/gapselect/simpletest/helper.php b/question/type/gapselect/simpletest/helper.php
deleted file mode 100644 (file)
index d865a72..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Contains the helper class for the select missing words question type tests.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Test helper class for the select missing words question type.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_test_helper {
-    /**
-     * @return qtype_gapselect_question
-     */
-    public static function make_a_gapselect_question() {
-        question_bank::load_question_definition_classes('gapselect');
-        $gapselect = new qtype_gapselect_question();
-
-        test_question_maker::initialise_a_question($gapselect);
-
-        $gapselect->name = 'Selection from drop down list question';
-        $gapselect->questiontext = 'The [[1]] brown [[2]] jumped over the [[3]] dog.';
-        $gapselect->generalfeedback = 'This sentence uses each letter of the alphabet.';
-        $gapselect->qtype = question_bank::get_qtype('gapselect');
-
-        $gapselect->shufflechoices = true;
-
-        test_question_maker::set_standard_combined_feedback_fields($gapselect);
-
-        $gapselect->choices = array(
-            1 => array(
-                1 => new qtype_gapselect_choice('quick', 1),
-                2 => new qtype_gapselect_choice('slow', 1)),
-            2 => array(
-                1 => new qtype_gapselect_choice('fox', 2),
-                2 => new qtype_gapselect_choice('dog', 2)),
-            3 => array(
-                1 => new qtype_gapselect_choice('lazy', 3),
-                2 => new qtype_gapselect_choice('assiduous', 3)),
-        );
-
-        $gapselect->places = array(1 => 1, 2 => 2, 3 => 3);
-        $gapselect->rightchoices = array(1 => 1, 2 => 1, 3 => 1);
-        $gapselect->textfragments = array('The ', ' brown ', ' jumped over the ', ' dog.');
-
-        return $gapselect;
-    }
-
-    /**
-     * @return qtype_gapselect_question
-     */
-    public static function make_a_maths_gapselect_question() {
-        question_bank::load_question_definition_classes('gapselect');
-        $gapselect = new qtype_gapselect_question();
-
-        test_question_maker::initialise_a_question($gapselect);
-
-        $gapselect->name = 'Selection from drop down list question';
-        $gapselect->questiontext = 'Fill in the operators to make this equation work: ' .
-                '7 [[1]] 11 [[2]] 13 [[1]] 17 [[2]] 19 = 3';
-        $gapselect->generalfeedback = 'This sentence uses each letter of the alphabet.';
-        $gapselect->qtype = question_bank::get_qtype('gapselect');
-
-        $gapselect->shufflechoices = true;
-
-        test_question_maker::set_standard_combined_feedback_fields($gapselect);
-
-        $gapselect->choices = array(
-            1 => array(
-                1 => new qtype_gapselect_choice('+', 1, true),
-                2 => new qtype_gapselect_choice('-', 1, true),
-                3 => new qtype_gapselect_choice('*', 1, true),
-                4 => new qtype_gapselect_choice('/', 1, true),
-            ));
-
-        $gapselect->places = array(1 => 1, 2 => 1, 3 => 1, 4 => 1);
-        $gapselect->rightchoices = array(1 => 1, 2 => 2, 3 => 1, 4 => 2);
-        $gapselect->textfragments = array('7 ', ' 11 ', ' 13 ', ' 17 ', ' 19 = 3');
-
-        return $gapselect;
-    }
-}
diff --git a/question/type/gapselect/simpletest/testquestion.php b/question/type/gapselect/simpletest/testquestion.php
deleted file mode 100644 (file)
index c232cde..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Unit tests for the select missing words question definition class.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
-require_once($CFG->dirroot . '/question/type/gapselect/simpletest/helper.php');
-
-
-/**
- * Unit tests for the select missing words question definition class.
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_question_test extends UnitTestCase {
-
-    public function test_get_question_summary() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $this->assertEqual('The [[1]] brown [[2]] jumped over the [[3]] dog.; ' .
-                '[[1]] -> {quick / slow}; [[2]] -> {fox / dog}; [[3]] -> {lazy / assiduous}',
-                $gapselect->get_question_summary());
-    }
-
-    public function test_get_question_summary_maths() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $this->assertEqual('Fill in the operators to make this equation work: ' .
-                '7 [[1]] 11 [[2]] 13 [[1]] 17 [[2]] 19 = 3; [[1]] -> {+ / - / * / /}',
-                $gapselect->get_question_summary());
-    }
-
-    public function test_summarise_response() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual('{quick} {fox} {lazy}',
-                $gapselect->summarise_response(array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_summarise_response_maths() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual('{+} {-} {+} {-}', $gapselect->summarise_response(
-                array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2')));
-    }
-
-    public function test_get_random_guess_score() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $this->assertEqual(0.5, $gapselect->get_random_guess_score());
-    }
-
-    public function test_get_random_guess_score_maths() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $this->assertEqual(0.25, $gapselect->get_random_guess_score());
-    }
-
-    public function test_get_right_choice_for() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(1, $gapselect->get_right_choice_for(1));
-        $this->assertEqual(1, $gapselect->get_right_choice_for(2));
-    }
-
-    public function test_get_right_choice_for_maths() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(1, $gapselect->get_right_choice_for(1));
-        $this->assertEqual(2, $gapselect->get_right_choice_for(2));
-    }
-
-    public function test_clear_wrong_from_response() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $initialresponse = array('p1' => '1', 'p2' => '1', 'p3' => '1', 'p4' => '1');
-        $this->assertEqual(array('p1' => '1', 'p2' => '0', 'p3' => '1', 'p4' => '0'),
-                $gapselect->clear_wrong_from_response($initialresponse));
-    }
-
-    public function test_get_num_parts_right() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(2, 3),
-                $gapselect->get_num_parts_right(array('p1' => '1', 'p2' => '1', 'p3' => '2')));
-        $this->assertEqual(array(3, 3),
-                $gapselect->get_num_parts_right(array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_get_num_parts_right_maths() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(2, 4), $gapselect->get_num_parts_right(
-                array('p1' => '1', 'p2' => '1', 'p3' => '1', 'p4' => '1')));
-    }
-
-    public function test_get_expected_data() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array('p1' => PARAM_INT, 'p2' => PARAM_INT, 'p3' => PARAM_INT),
-                $gapselect->get_expected_data());
-    }
-
-    public function test_get_correct_response() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array('p1' => '1', 'p2' => '1', 'p3' => '1'),
-                $gapselect->get_correct_response());
-    }
-
-    public function test_get_correct_response_maths() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2'),
-                $gapselect->get_correct_response());
-    }
-
-    public function test_is_same_response() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertTrue($gapselect->is_same_response(
-                array(),
-                array('p1' => '0', 'p2' => '0', 'p3' => '0')));
-
-        $this->assertFalse($gapselect->is_same_response(
-                array(),
-                array('p1' => '1', 'p2' => '0', 'p3' => '0')));
-
-        $this->assertFalse($gapselect->is_same_response(
-                array('p1' => '0', 'p2' => '0', 'p3' => '0'),
-                array('p1' => '1', 'p2' => '0', 'p3' => '0')));
-
-        $this->assertTrue($gapselect->is_same_response(
-                array('p1' => '1', 'p2' => '2', 'p3' => '3'),
-                array('p1' => '1', 'p2' => '2', 'p3' => '3')));
-
-        $this->assertFalse($gapselect->is_same_response(
-                array('p1' => '1', 'p2' => '2', 'p3' => '3'),
-                array('p1' => '1', 'p2' => '2', 'p3' => '2')));
-    }
-    public function test_is_complete_response() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertFalse($gapselect->is_complete_response(array()));
-        $this->assertFalse($gapselect->is_complete_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '0')));
-        $this->assertFalse($gapselect->is_complete_response(array('p1' => '1')));
-        $this->assertTrue($gapselect->is_complete_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_is_gradable_response() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertFalse($gapselect->is_gradable_response(array()));
-        $this->assertFalse($gapselect->is_gradable_response(
-                array('p1' => '0', 'p2' => '0', 'p3' => '0')));
-        $this->assertTrue($gapselect->is_gradable_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '0')));
-        $this->assertTrue($gapselect->is_gradable_response(array('p1' => '1')));
-        $this->assertTrue($gapselect->is_gradable_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-    }
-
-    public function test_grading() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(1, question_state::$gradedright),
-                $gapselect->grade_response(array('p1' => '1', 'p2' => '1', 'p3' => '1')));
-        $this->assertEqual(array(1/3, question_state::$gradedpartial),
-                $gapselect->grade_response(array('p1' => '1')));
-        $this->assertEqual(array(0, question_state::$gradedwrong),
-                $gapselect->grade_response(array('p1' => '2', 'p2' => '2', 'p3' => '2')));
-    }
-
-    public function test_grading_maths() {
-        $gapselect = qtype_gapselect_test_helper::make_a_maths_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(1, question_state::$gradedright), $gapselect->grade_response(
-                array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2')));
-        $this->assertEqual(array(0.5, question_state::$gradedpartial), $gapselect->grade_response(
-                array('p1' => '1', 'p2' => '1', 'p3' => '1', 'p4' => '1')));
-        $this->assertEqual(array(0, question_state::$gradedwrong), $gapselect->grade_response(
-                array('p1' => '0', 'p2' => '1', 'p3' => '2', 'p4' => '1')));
-    }
-
-    public function test_classify_response() {
-        $gapselect = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $gapselect->shufflechoices = false;
-        $gapselect->start_attempt(new question_attempt_step());
-
-        $this->assertEqual(array(
-                    1 => new question_classified_response(1, 'quick', 1),
-                    2 => new question_classified_response(2, 'dog', 0),
-                    3 => new question_classified_response(1, 'lazy', 1),
-                ), $gapselect->classify_response(array('p1' => '1', 'p2' => '2', 'p3' => '1')));
-        $this->assertEqual(array(
-                    1 => question_classified_response::no_response(),
-                    2 => new question_classified_response(1, 'fox', 1),
-                    3 => new question_classified_response(2, 'assiduous', 0),
-                ), $gapselect->classify_response(array('p1' => '0', 'p2' => '1', 'p3' => '2')));
-    }
-}
diff --git a/question/type/gapselect/simpletest/testquestiontype.php b/question/type/gapselect/simpletest/testquestiontype.php
deleted file mode 100644 (file)
index e8e1656..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Unit tests for the select missing words question question definition class.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
-require_once($CFG->dirroot . '/question/type/gapselect/simpletest/helper.php');
-
-
-/**
- * Unit tests for the select missing words question definition class.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_gapselect_test extends UnitTestCase {
-    /** @var qtype_gapselect instance of the question type class to test. */
-    protected $qtype;
-
-    public function setUp() {
-        $this->qtype = question_bank::get_qtype('gapselect');;
-    }
-
-    public function tearDown() {
-        $this->qtype = null;
-    }
-
-    public function assert_same_xml($expectedxml, $xml) {
-        $this->assertEqual(str_replace("\r\n", "\n", $expectedxml),
-                str_replace("\r\n", "\n", $xml));
-    }
-
-    /**
-     * @return object the data to construct a question like
-     * {@link qtype_gapselect_test_helper::make_a_gapselect_question()}.
-     */
-    protected function get_test_question_data() {
-        global $USER;
-
-        $gapselect = new stdClass();
-        $gapselect->id = 0;
-        $gapselect->category = 0;
-        $gapselect->contextid = 0;
-        $gapselect->parent = 0;
-        $gapselect->questiontextformat = FORMAT_HTML;
-        $gapselect->generalfeedbackformat = FORMAT_HTML;
-        $gapselect->defaultmark = 1;
-        $gapselect->penalty = 0.3333333;
-        $gapselect->length = 1;
-        $gapselect->stamp = make_unique_id_code();
-        $gapselect->version = make_unique_id_code();
-        $gapselect->hidden = 0;
-        $gapselect->timecreated = time();
-        $gapselect->timemodified = time();
-        $gapselect->createdby = $USER->id;
-        $gapselect->modifiedby = $USER->id;
-
-        $gapselect->name = 'Selection from drop down list question';
-        $gapselect->questiontext = 'The [[1]] brown [[2]] jumped over the [[3]] dog.';
-        $gapselect->generalfeedback = 'This sentence uses each letter of the alphabet.';
-        $gapselect->qtype = 'gapselect';
-
-        $gapselect->options->shuffleanswers = true;
-
-        test_question_maker::set_standard_combined_feedback_fields($gapselect->options);
-
-        $gapselect->options->answers = array(
-            (object) array('answer' => 'quick', 'feedback' => '1'),
-            (object) array('answer' => 'fox', 'feedback' => '2'),
-            (object) array('answer' => 'lazy', 'feedback' => '3'),
-            (object) array('answer' => 'assiduous', 'feedback' => '3'),
-            (object) array('answer' => 'dog', 'feedback' => '2'),
-            (object) array('answer' => 'slow', 'feedback' => '1'),
-        );
-
-        return $gapselect;
-    }
-
-    public function test_name() {
-        $this->assertEqual($this->qtype->name(), 'gapselect');
-    }
-
-    public function test_can_analyse_responses() {
-        $this->assertTrue($this->qtype->can_analyse_responses());
-    }
-
-    public function test_initialise_question_instance() {
-        $qdata = $this->get_test_question_data();
-
-        $expected = qtype_gapselect_test_helper::make_a_gapselect_question();
-        $expected->stamp = $qdata->stamp;
-        $expected->version = $qdata->version;
-
-        $q = $this->qtype->make_question($qdata);
-
-        $this->assertEqual($expected, $q);
-    }
-
-    public function test_get_random_guess_score() {
-        $q = $this->get_test_question_data();
-        $this->assertWithinMargin(0.5, $this->qtype->get_random_guess_score($q), 0.0000001);
-    }
-
-    public function test_get_possible_responses() {
-        $q = $this->get_test_question_data();
-
-        $this->assertEqual(array(
-            1 => array(
-                1 => new question_possible_response('quick', 1),
-                2 => new question_possible_response('slow', 0),
-                null => question_possible_response::no_response()),
-            2 => array(
-                1 => new question_possible_response('fox', 1),
-                2 => new question_possible_response('dog', 0),
-                null => question_possible_response::no_response()),
-            3 => array(
-                1 => new question_possible_response('lazy', 1),
-                2 => new question_possible_response('assiduous', 0),
-                null => question_possible_response::no_response()),
-        ), $this->qtype->get_possible_responses($q));
-    }
-
-    public function test_xml_import() {
-        $xml = '  <question type="gapselect">
-    <name>
-      <text>A select missing words question</text>
-    </name>
-    <questiontext format="moodle_auto_format">
-      <text>Put these in order: [[1]], [[2]], [[3]].</text>
-    </questiontext>
-    <generalfeedback>
-      <text>The answer is Alpha, Beta, Gamma.</text>
-    </generalfeedback>
-    <defaultgrade>3</defaultgrade>
-    <penalty>0.3333333</penalty>
-    <hidden>0</hidden>
-    <shuffleanswers>1</shuffleanswers>
-    <correctfeedback>
-      <text><![CDATA[<p>Your answer is correct.</p>]]></text>
-    </correctfeedback>
-    <partiallycorrectfeedback>
-      <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
-    </partiallycorrectfeedback>
-    <incorrectfeedback>
-      <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
-    </incorrectfeedback>
-    <shownumcorrect/>
-    <selectoption>
-      <text>Alpha</text>
-      <group>1</group>
-    </selectoption>
-    <selectoption>
-      <text>Beta</text>
-      <group>1</group>
-    </selectoption>
-    <selectoption>
-      <text>Gamma</text>
-      <group>1</group>
-    </selectoption>
-    <hint>
-      <text>Try again.</text>
-      <shownumcorrect />
-    </hint>
-    <hint>
-      <text>These are the first three letters of the Greek alphabet.</text>
-      <shownumcorrect />
-      <clearwrong />
-    </hint>
-  </question>';
-        $xmldata = xmlize($xml);
-
-        $importer = new qformat_xml();
-        $q = $importer->try_importing_using_qtypes(
-                $xmldata['question'], null, null, 'gapselect');
-
-        $expectedq = new stdClass();
-        $expectedq->qtype = 'gapselect';
-        $expectedq->name = 'A select missing words question';
-        $expectedq->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
-        $expectedq->questiontextformat = FORMAT_MOODLE;
-        $expectedq->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
-        $expectedq->defaultmark = 3;
-        $expectedq->length = 1;
-        $expectedq->penalty = 0.3333333;
-
-        $expectedq->shuffleanswers = 1;
-        $expectedq->correctfeedback = array('text' => '<p>Your answer is correct.</p>',
-                'format' => FORMAT_MOODLE, 'files' => array());
-        $expectedq->partiallycorrectfeedback = array(
-                'text' => '<p>Your answer is partially correct.</p>',
-                'format' => FORMAT_MOODLE, 'files' => array());
-        $expectedq->shownumcorrect = true;
-        $expectedq->incorrectfeedback = array('text' => '<p>Your answer is incorrect.</p>',
-                'format' => FORMAT_MOODLE, 'files' => array());
-
-        $expectedq->choices = array(
-            array('answer' => 'Alpha', 'choicegroup' => 1),
-            array('answer' => 'Beta', 'choicegroup' => 1),
-            array('answer' => 'Gamma', 'choicegroup' => 1),
-        );
-
-        $expectedq->hint = array(
-                array('text' => 'Try again.', 'format' => FORMAT_MOODLE, 'files' => array()),
-                array('text' => 'These are the first three letters of the Greek alphabet.',
-                        'format' => FORMAT_MOODLE, 'files' => array()));
-        $expectedq->hintshownumcorrect = array(true, true);
-        $expectedq->hintclearwrong = array(false, true);
-
-        $this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
-        $this->assertEqual($expectedq->hint, $q->hint);
-    }
-
-    public function test_xml_export() {
-        $qdata = new stdClass();
-        $qdata->id = 123;
-        $qdata->contextid = 0;
-        $qdata->qtype = 'gapselect';
-        $qdata->name = 'A select missing words question';
-        $qdata->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
-        $qdata->questiontextformat = FORMAT_MOODLE;
-        $qdata->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
-        $qdata->generalfeedbackformat = FORMAT_MOODLE;
-        $qdata->defaultmark = 3;
-        $qdata->length = 1;
-        $qdata->penalty = 0.3333333;
-        $qdata->hidden = 0;
-
-        $qdata->options->shuffleanswers = 1;
-        $qdata->options->correctfeedback = '<p>Your answer is correct.</p>';
-        $qdata->options->correctfeedbackformat = FORMAT_MOODLE;
-        $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
-                $qdata->options->partiallycorrectfeedbackformat = FORMAT_MOODLE;
-        $qdata->options->shownumcorrect = true;
-        $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>';
-        $qdata->options->incorrectfeedbackformat = FORMAT_MOODLE;
-
-        $qdata->options->answers = array(
-            13 => new question_answer(13, 'Alpha', 0, '1', FORMAT_MOODLE),
-            14 => new question_answer(14, 'Beta', 0, '1', FORMAT_MOODLE),
-            15 => new question_answer(15, 'Gamma', 0, '1', FORMAT_MOODLE),
-        );
-
-        $qdata->hints = array(
-            1 => new question_hint_with_parts(1, 'Try again.', FORMAT_MOODLE, true, false),
-            2 => new question_hint_with_parts(2,
-                    'These are the first three letters of the Greek alphabet.',
-                    FORMAT_MOODLE, true, true),
-        );
-
-        $exporter = new qformat_xml();
-        $xml = $exporter->writequestion($qdata);
-
-        $expectedxml = '<!-- question: 123  -->
-  <question type="gapselect">
-    <name>
-      <text>A select missing words question</text>
-    </name>
-    <questiontext format="moodle_auto_format">
-      <text>Put these in order: [[1]], [[2]], [[3]].</text>
-    </questiontext>
-    <generalfeedback format="moodle_auto_format">
-      <text>The answer is Alpha, Beta, Gamma.</text>
-    </generalfeedback>
-    <defaultgrade>3</defaultgrade>
-    <penalty>0.3333333</penalty>
-    <hidden>0</hidden>
-    <shuffleanswers>1</shuffleanswers>
-    <correctfeedback format="moodle_auto_format">
-      <text><![CDATA[<p>Your answer is correct.</p>]]></text>
-    </correctfeedback>
-    <partiallycorrectfeedback format="moodle_auto_format">
-      <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
-    </partiallycorrectfeedback>
-    <incorrectfeedback format="moodle_auto_format">
-      <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
-    </incorrectfeedback>
-    <shownumcorrect/>
-    <selectoption>
-      <text>Alpha</text>
-      <group>1</group>
-    </selectoption>
-    <selectoption>
-      <text>Beta</text>
-      <group>1</group>
-    </selectoption>
-    <selectoption>
-      <text>Gamma</text>
-      <group>1</group>
-    </selectoption>
-    <hint format="moodle_auto_format">
-      <text>Try again.</text>
-      <shownumcorrect/>
-    </hint>
-    <hint format="moodle_auto_format">
-      <text>These are the first three letters of the Greek alphabet.</text>
-      <shownumcorrect/>
-      <clearwrong/>
-    </hint>
-  </question>
-';
-
-        $this->assert_same_xml($expectedxml, $xml);
-    }
-}
diff --git a/question/type/gapselect/simpletest/testwalkthrough.php b/question/type/gapselect/simpletest/testwalkthrough.php
deleted file mode 100644 (file)
index 42fd19b..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * This file contains tests that walks a question through the interactive
- * behaviour.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
-require_once($CFG->dirroot . '/question/type/gapselect/simpletest/helper.php');
-
-
-/**
- * Unit tests for the gap-select question type.
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-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(1, 'This is the first hint.', FORMAT_HTML, false, false),
-            new question_hint_with_parts(2, 'This is the second hint.', FORMAT_HTML, true, true),
-        );
-        $q->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
deleted file mode 100644 (file)
index f6931c9..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-.que.gapselect .qtext {
-    line-height:2em;
-    margin-top: 1px;
-    margin-bottom: 0.5em;
-    display: block;
-}
-
-.que.gapselect .answercontainer {
-    line-height: 2em;
-    margin-bottom:1em;
-    display: block;
-}
-
-.que.gapselect .answertext {
-    padding-bottom: 0.5em;
-}
-
-.que.gapselect .group1 {
-    background-color: #E4F1FA;
-}
-.que.gapselect .group2 {
-    background-color: #DCDCDC;
-}
-.que.gapselect .group3 {
-    background-color: #B0C4DE;
-}
-.que.gapselect .group4 {
-    background-color: #D8BFD8;
-}
-.que.gapselect .group5 {
-    background-color: #87CEFA;
-}
-.que.gapselect .group6 {
-    background-color: #DAA520;
-}
-.que.gapselect .group7 {
-    background-color: #FFD700;
-}
-.que.gapselect .group8 {
-    background-color: #F0E68C;
-}
-.que.sddl .control {
-    padding: 0.2em;
-}
diff --git a/question/type/gapselect/version.php b/question/type/gapselect/version.php
deleted file mode 100644 (file)
index 35d30ee..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Version information for the select missing words question type.
- *
- * @package    qtype
- * @subpackage gapselect
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-$plugin->version  = 2011020100;
-$plugin->requires = 2011051212;
diff --git a/question/type/opaque/backup/moodle2/backup_qtype_opaque_plugin.class.php b/question/type/opaque/backup/moodle2/backup_qtype_opaque_plugin.class.php
deleted file mode 100644 (file)
index 29c9498..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * @package    moodlecore
- * @subpackage backup-moodle2
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Provides the information to backup ddwtos questions
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class backup_qtype_opaque_plugin extends backup_qtype_plugin {
-
-    /**
-     * Returns the qtype information to attach to question element
-     */
-    protected function define_question_plugin_structure() {
-
-        // Define the virtual plugin element with the condition to fulfill
-        $plugin = $this->get_plugin_element(null, '../../qtype', 'opaque');
-
-        // Create one standard named plugin element (the visible container)
-        $pluginwrapper = new backup_nested_element($this->get_recommended_name());
-
-        // connect the visible container ASAP
-        $plugin->add_child($pluginwrapper);
-
-        // Now create the qtype own structures
-        $opaque = new backup_nested_element('opaque', array('id'), array(
-            'remoteid', 'remoteversion'));
-        $engine = new backup_nested_element('engine', array('id'), array('name', 'passkey'));
-        $server = new backup_nested_element('server', array('type'), array('url'));
-
-        // Now the own qtype tree
-        $pluginwrapper->add_child($opaque);
-        $opaque->add_child($engine);
-        $engine->add_child($server);
-
-        // set source to populate the data
-        $opaque->set_source_table('question_opaque',
-                array('questionid' => backup::VAR_PARENTID));
-        $engine->set_source_sql('
-                SELECT e.*
-                FROM {question_opaque_engines} e
-                JOIN {question_opaque} qo ON qo.engineid = e.id
-                WHERE qo.id = ?',
-                array(backup::VAR_PARENTID));
-        $server->set_source_table('question_opaque_servers',
-                array('engineid' => backup::VAR_PARENTID));
-
-        return $plugin;
-    }
-
-    /**
-     * Returns one array with filearea => mappingname elements for the qtype
-     *
-     * Used by {@link get_components_and_fileareas} to know about all the qtype
-     * files to be processed both in backup and restore.
-     */
-    public static function get_qtype_fileareas() {
-        return array(
-            'correctfeedback' => 'question_created',
-            'partiallycorrectfeedback' => 'question_created',
-            'incorrectfeedback' => 'question_created');
-    }
-}
diff --git a/question/type/opaque/backup/moodle2/restore_qtype_opaque_plugin.class.php b/question/type/opaque/backup/moodle2/restore_qtype_opaque_plugin.class.php
deleted file mode 100644 (file)
index 4af0b41..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * @package    moodlecore
- * @subpackage backup-moodle2
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->dirroot . '/question/type/opaque/locallib.php');
-
-
-/**
- * restore plugin class that provides the necessary information
- * needed to restore one ddwtos qtype plugin
- *
- * @copyright  2011 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class restore_qtype_opaque_plugin extends restore_qtype_plugin {
-    protected $enginemanager = null;
-
-    /* Overridden. See parent class for docs. */
-    protected function define_question_plugin_structure() {
-        return array(
-            new restore_path_element('opaque', $this->get_pathfor('/opaque'), true),
-            new restore_path_element('engine', $this->get_pathfor('/opaque/engine')),
-            new restore_path_element('server', $this->get_pathfor('/opaque/engine/server')),
-        );
-    }
-
-    /**
-     * Process the qtype/opaque element
-     */
-    public function process_opaque($data) {
-        global $DB;
-
-        $engine = (object) $data['engine'][0];
-        $engine->questionengines = array();
-        $engine->questionbanks = array();
-
-        foreach ($data['engine'][0]['server'] as $server) {
-            if ($server['type'] == 'qe') {
-                $engine->questionengines[] = $server['url'];
-            } else if ($server['type'] == 'qb') {
-                $engine->questionbanks[] = $server['url'];
-            }
-        }
-        if (empty($engine->questionengines)) {
-            throw new coding_exception(
-                    'Missing question engine URLs in an Opaque question backup.');
-        }
-
-        // Detect if the question is created or mapped
-        $oldquestionid   = $this->get_old_parentid('question');
-        $newquestionid   = $this->get_new_parentid('question');
-        $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
-
-        // If the question has been created by restore, we need to create its question_ddwtos too
-        if (!$questioncreated) {
-            // New question, insert.
-            $question = (object) $data;
-            $question->engineid = $this->engine_manager()->find_or_create_engineid($engine);
-            $question->questionid = $newquestionid;
-
-            $DB->insert_record('question_opaque', $question);
-        }
-    }
-
-    /**
-     * Process the qtype/opaque/server element
-     */
-    public function process_engine($data) {
-        // Do nothing. All the data is processed in process_opaque.
-    }
-
-    /**
-     * Process the qtype/opaque/server element
-     */
-    public function process_server($data) {
-        // Do nothing. All the data is processed in process_opaque.
-    }
-
-    /**
-     * @return qtype_opaque_engine_manager an engine manager.
-     */
-    protected function engine_manager() {
-        if (is_null($this->enginemanager)) {
-            $this->enginemanager = new qtype_opaque_engine_manager();
-        }
-        return $this->enginemanager;
-    }
-}
diff --git a/question/type/opaque/db/install.xml b/question/type/opaque/db/install.xml
deleted file mode 100644 (file)
index eb16fce..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="question/type/opaque/db" VERSION="20110114" COMMENT="XMLDB file for Moodle question/type/opaque"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
->
-  <TABLES>
-    <TABLE NAME="question_opaque_engines" COMMENT="Remote engines that the Opaque question type can connect to. Each engine will comprise one or more servers stored in the question_opaque_servers table" NEXT="question_opaque_servers">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" COMMENT="id of the table, please edit me" NEXT="name"/>
-        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The name used to identify this engine in the interface." PREVIOUS="id" NEXT="passkey"/>
-        <FIELD NAME="passkey" TYPE="char" LENGTH="8" NOTNULL="false" SEQUENCE="false" COMMENT="The passkey for the QE if required." PREVIOUS="name"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me"/>
-      </KEYS>
-    </TABLE>
-    <TABLE NAME="question_opaque_servers" COMMENT="This table stores the individual servers that make up an Opaque remote engine." PREVIOUS="question_opaque_engines" NEXT="question_opaque">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" COMMENT="id of the table, please edit me" NEXT="engineid"/>
-        <FIELD NAME="engineid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" COMMENT="The Opaque engine this server is part of." PREVIOUS="id" NEXT="type"/>
-        <FIELD NAME="type" TYPE="char" LENGTH="16" NOTNULL="true" SEQUENCE="false" COMMENT="The type of this server - question engine or question bank." PREVIOUS="engineid" NEXT="url"/>
-        <FIELD NAME="url" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The base URL of this server." PREVIOUS="type"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="quesopaqserv_eng_fk"/>
-        <KEY NAME="quesopaqserv_eng_fk" TYPE="foreign" FIELDS="engineid" REFTABLE="question_opaque_engines" REFFIELDS="id" PREVIOUS="primary"/>
-      </KEYS>
-    </TABLE>
-    <TABLE NAME="question_opaque" COMMENT="Extra infomation required to define an Opaque question. This table extends the question table." PREVIOUS="question_opaque_servers">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" COMMENT="id of the table, please edit me" NEXT="questionid"/>
-        <FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" COMMENT="The id of the question this row relates to." PREVIOUS="id" NEXT="engineid"/>
-        <FIELD NAME="engineid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" COMMENT="The remote engine that provides this question. Refers to question_opaaque_engines.id." PREVIOUS="questionid" NEXT="remoteid"/>
-        <FIELD NAME="remoteid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The id of this question - meaningful to the remote engine." PREVIOUS="engineid" NEXT="remoteversion"/>
-        <FIELD NAME="remoteversion" TYPE="char" LENGTH="16" NOTNULL="true" SEQUENCE="false" COMMENT="The version of this question - meaningful to the remote engine." PREVIOUS="remoteid"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="quesopaq_eng_fk"/>
-        <KEY NAME="quesopaq_eng_fk" TYPE="foreign" FIELDS="engineid" REFTABLE="question_opaque_engines" REFFIELDS="id" PREVIOUS="primary" NEXT="quesopaq_que_fk"/>
-        <KEY NAME="quesopaq_que_fk" TYPE="foreign" FIELDS="questionid" REFTABLE="question" REFFIELDS="id" PREVIOUS="quesopaq_eng_fk"/>
-      </KEYS>
-    </TABLE>
-  </TABLES>
-</XMLDB>
diff --git a/question/type/opaque/edit_engine_form.php b/question/type/opaque/edit_engine_form.php
deleted file mode 100644 (file)
index 3736671..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Page for editing the configuration of a particular Opaque engine.
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir . '/formslib.php');
-require_once($CFG->libdir . '/validateurlsyntax.php');
-
-
-/**
- * Form definition class.
- *
- * @copyright  2006 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_opaque_engine_edit_form extends moodleform {
-    protected function definition() {
-        $mform = $this->_form;
-
-        $mform->addElement('text', 'enginename', get_string('enginename', 'qtype_opaque'));
-        $mform->addRule('enginename', get_string('missingenginename', 'qtype_opaque'),
-                'required', null, 'client');
-        $mform->setType('enginename', PARAM_MULTILANG);
-
-        $mform->addElement('textarea', 'questionengineurls',
-                get_string('questionengineurls', 'qtype_opaque'), 'rows="5" cols="80"');
-        $mform->addRule('questionengineurls', get_string('missingengineurls', 'qtype_opaque'),
-                'required', null, 'client');
-        $mform->setType('questionengineurls', PARAM_RAW);
-
-        $mform->addElement('textarea', 'questionbankurls',
-                get_string('questionbankurls', 'qtype_opaque'), array('rows' => 5, 'cols' => 80));
-        $mform->setType('questionbankurls', PARAM_RAW);
-
-        $mform->addElement('text', 'passkey', get_string('passkey', 'qtype_opaque'));
-        $mform->setType('passkey', PARAM_MULTILANG);
-        $mform->addHelpButton('passkey', 'passkey', 'qtype_opaque');
-
-        $mform->addElement('hidden', 'engineid');
-        $mform->setType('engineid', PARAM_INT);
-
-        $this->add_action_buttons();
-    }
-
-    /**
-     * Validate the contents of a textarea field, which should be a
-     * newline-separated list of URLs.
-     *
-     * @param $data the form data.
-     * @param $field the field to validate.
-     * @param $errors any error messages are added to this array.
-     */
-    protected function validateurllist(&$data, $field, &$errors) {
-        $urls = preg_split('/[\r\n]+/', $data[$field]);
-        foreach ($urls as $url) {
-            $url = trim($url);
-            if ($url && !validateUrlSyntax($url, 's?H?S?u-P-a?I?p?f?q?r?')) {
-                $errors[$field] = get_string('urlsinvalid', 'qtype_opaque');
-            }
-        }
-    }
-
-    /**
-     * Extract the contents of a textarea field, which should be a
-     * newline-separated list of URLs.
-     *
-     * @param $data the form data.
-     * @param $field the field to extract.
-     * @param @return array those lines from the form field that are valid URLs.
-     */
-    public function extracturllist($data, $field) {
-        $rawurls = preg_split('/[\r\n]+/', $data->$field);
-        $urls = array();
-        foreach ($rawurls as $url) {
-            $url = clean_param(trim($url), PARAM_URL);
-            if ($url) {
-                $urls[] = $url;
-            }
-        }
-        return $urls;
-    }
-
-    public function validation($data, $files) {
-        $errors = parent::validation($data, $files);
-        $this->validateurllist($data, 'questionengineurls', $errors);
-        $this->validateurllist($data, 'questionbankurls', $errors);
-        return $errors;
-    }
-}
diff --git a/question/type/opaque/edit_opaque_form.php b/question/type/opaque/edit_opaque_form.php
deleted file mode 100644 (file)
index 6f76713..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Defines the editing form for the Opaque question type.
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2006 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once(dirname(__FILE__) . '/locallib.php');
-
-
-/**
- * Form definition base class. This defines the common fields that
- * all question types need. Question types should define their own
- * class that inherits from this one, and implements the definition_inner()
- * method.
- *
- * @copyright  2006 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_opaque_edit_form extends question_edit_form {
-    protected function definition() {
-        parent::definition();
-        $mform = $this->_form;
-        $mform->removeElement('questiontext');
-        $mform->removeElement('generalfeedback');
-        $mform->removeElement('defaultmark');
-        $mform->addElement('hidden', 'defaultmark');
-        $mform->setType('defaultmark', PARAM_INT);
-        $mform->setDefault('defaultmark', 1);
-    }
-
-    protected function definition_inner($mform) {
-        $mform->addElement('select', 'engineid', get_string('questionengine', 'qtype_opaque'),
-                qtype_opaque_installed_engine_choices());
-        $mform->setType('engineid', PARAM_INT);
-        $mform->addRule('engineid', null, 'required', null, 'client');
-        $mform->addHelpButton('engineid', 'questionengine', 'qtype_opaque');
-
-        $mform->addElement('text', 'remoteid',
-                get_string('questionid', 'qtype_opaque'), array('size' => 50));
-        $mform->setType('remoteid', PARAM_RAW);
-        $mform->addRule('remoteid', null, 'required', null, 'client');
-        $mform->addHelpButton('remoteid', 'questionid', 'qtype_opaque');
-
-        $mform->addElement('text', 'remoteversion',
-                get_string('questionversion', 'qtype_opaque'), array('size' => 3));
-        $mform->setType('remoteversion', PARAM_RAW);
-        $mform->addRule('remoteversion', null, 'required', null, 'client');
-    }
-
-    public function validation($data, $files) {
-        $errors = parent::validation($data, $files);
-
-        // Check we can connect to this questoin engine.
-        $engine = qtype_opaque_load_engine_def($data['engineid']);
-        if (is_string($engine)) {
-            $errors['engineid'] = $engine;
-        }
-
-        $remoteidok = true;
-        $partregexp = '[_a-z][_a-zA-Z0-9]*';
-        if (!preg_match("/^$partregexp(\\.$partregexp)*\$/", $data['remoteid'])) {
-            $errors['remoteid'] = get_string('invalidquestionidsyntax', 'qtype_opaque');
-            $remoteidok = false;
-        }
-        if (!preg_match('/^\d+\.\d+$/', $data['remoteversion'])) {
-            $errors['remoteversion'] = get_string('invalidquestionversionsyntax', 'qtype_opaque');
-            $remoteidok = false;
-        }
-
-        // Try connecting to the remote question engine both as extra validation of the id, and
-        // also to get the default grade.
-        if ($remoteidok) {
-            $metadata = qtype_opaque_get_question_metadata($engine,
-                    $data['remoteid'], $data['remoteversion']);
-            if (is_string($metadata)) {
-                $errors['remoteid'] = $metadata;
-            } else if (!isset($metadata['questionmetadata']['#']['scoring']
-                    [0]['#']['marks'][0]['#'])) {
-                $errors['remoteid'] = get_string('maxgradenotreturned');
-            } else {
-                $this->_defaultmark = $metadata['questionmetadata']['#']['scoring']
-                        [0]['#']['marks'][0]['#'];
-            }
-        }
-
-        return $errors;
-    }
-
-    public function get_data($slashed = true) {
-        // We override get_data to to add the defaultmark, which was determined
-        // during validation, to the data that is returned.
-        $data = parent::get_data($slashed);
-        if (is_object($data) && isset($this->_defaultmark)) {
-            $data->defaultmark = $this->_defaultmark;
-        }
-        return $data;
-    }
-
-    public function qtype() {
-        return 'opaque';
-    }
-}
diff --git a/question/type/opaque/editengine.php b/question/type/opaque/editengine.php
deleted file mode 100644 (file)
index d42cc2b..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Page for editing the configuration of a particular Opaque engine.
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2006 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-require_once(dirname(__FILE__) . '/../../../config.php');
-require_once($CFG->libdir . '/adminlib.php');
-require_once(dirname(__FILE__) . '/locallib.php');
-require_once(dirname(__FILE__) . '/edit_engine_form.php');
-
-$engineid = optional_param('engineid', 0, PARAM_INT);
-
-// Check the user is logged in.
-require_login();
-$context = get_context_instance(CONTEXT_SYSTEM);
-require_capability('moodle/question:config', $context);
-
-admin_externalpage_setup('qtypesettingopaque', '', null,
-        new moodle_url('/question/type/opaque/editengine.php', array('engineid' => $engineid)));
-$PAGE->set_title(get_string('editquestionengine', 'qtype_opaque'));
-$PAGE->navbar->add(get_string('editquestionengineshort', 'qtype_opaque'));
-
-// Create form.
-$mform = new qtype_opaque_engine_edit_form('editengine.php');
-
-if ($mform->is_cancelled()) {
-    redirect(new moodle_url('/question/type/opaque/engines.php'));
-
-} else if ($data = $mform->get_data()) {
-    $engine = new stdClass();
-    if (!empty($data->engineid)) {
-        $engine->id = $data->engineid;
-    }
-    $engine->name = $data->enginename;
-    $engine->passkey = trim($data->passkey);
-    $engine->questionengines = $mform->extracturllist($data, 'questionengineurls');
-    $engine->questionbanks = $mform->extracturllist($data, 'questionbankurls');
-    qtype_opaque_save_engine_def($engine);
-    redirect(new moodle_url('/question/type/opaque/engines.php'));
-}
-
-// Prepare defaults.
-$defaults = new stdClass();
-$defaults->engineid = $engineid;
-if ($engineid) {
-    $engine = qtype_opaque_load_engine_def($engineid);
-    $defaults->enginename = $engine->name;
-    $defaults->questionengineurls = implode("\n", $engine->questionengines);
-    $defaults->questionbankurls = implode("\n", $engine->questionbanks);
-    $defaults->passkey = $engine->passkey;
-}
-$mform->set_data($defaults);
-
-// Display the form.
-echo $OUTPUT->header();
-echo $OUTPUT->heading_with_help(get_string('editquestionengine', 'qtype_opaque'),
-        'editquestionengine', 'qtype_opaque');
-$mform->display();
-echo $OUTPUT->footer();
diff --git a/question/type/opaque/engines.php b/question/type/opaque/engines.php
deleted file mode 100644 (file)
index a1fd219..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * This page lets admins manage the list of known remote Opaque engines.
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2006 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-require_once(dirname(__FILE__) . '/../../../config.php');
-require_once($CFG->libdir . '/adminlib.php');
-require_once(dirname(__FILE__) . '/locallib.php');
-
-// Check the user is logged in.
-require_login();
-$context = get_context_instance(CONTEXT_SYSTEM);
-require_capability('moodle/question:config', $context);
-
-admin_externalpage_setup('qtypesettingopaque');
-
-// See if any action was requested.
-$delete = optional_param('delete', 0, PARAM_INT);
-if ($delete) {
-    $engine = $DB->get_record('question_opaque_engines', array('id' => $delete), '*', MUST_EXIST);
-    if (optional_param('confirm', false, PARAM_BOOL) && confirm_sesskey()) {
-        qtype_opaque_delete_engine_def($delete);
-        redirect($PAGE->url);
-    } else {
-        echo $OUTPUT->header();
-        echo $OUTPUT->confirm(get_string('deleteconfigareyousure', 'qtype_opaque',
-                format_string($engine->name)),
-                new moodle_url('/question/type/opaque/engines.php',
-                        array('delete' => $delete, 'confirm' => 'yes', 'sesskey' => sesskey())),
-                $PAGE->url);
-        echo $OUTPUT->footer();
-        exit;
-    }
-}
-
-// Get the list of configured engines.
-$engines = $DB->get_records('question_opaque_engines', array(), 'id ASC');
-
-// Header.
-echo $OUTPUT->header();
-echo $OUTPUT->heading_with_help(get_string('configuredquestionengines', 'qtype_opaque'),
-        'configuredquestionengines', 'qtype_opaque');
-
-// List of configured engines.
-if ($engines) {
-    $strtest = get_string('testconnection', 'qtype_opaque');
-    $stredit = get_string('edit');
-    $strdelete = get_string('delete');
-
-    foreach ($engines as $engine) {
-        echo html_writer::tag('p', format_string($engine->name) .
-                $OUTPUT->action_icon(new moodle_url('/question/type/opaque/testengine.php',
-                        array('engineid' => $engine->id)),
-                        new pix_icon('t/preview', $strtest)) .
-                $OUTPUT->action_icon(new moodle_url('/question/type/opaque/editengine.php',
-                        array('engineid' => $engine->id)),
-                        new pix_icon('t/edit', $stredit)) .
-                $OUTPUT->action_icon(new moodle_url('/question/type/opaque/engines.php',
-                        array('delete' => $engine->id)),
-                        new pix_icon('t/delete', $strdelete)));
-    }
-} else {
-    echo html_writer::tag('p', get_string('noengines', 'qtype_opaque'));
-}
-
-// Add new engine link.
-echo html_writer::tag('p', html_writer::link(new moodle_url('/question/type/opaque/editengine.php'),
-        get_string('addengine', 'qtype_opaque')));
-
-// Footer.
-echo $OUTPUT->footer();
diff --git a/question/type/opaque/file.php b/question/type/opaque/file.php
deleted file mode 100644 (file)
index a562cc0..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Serves files from the Opaque resource cache.
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2007 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-require_once(dirname(__FILE__) . '/../../../config.php');
-require_once(dirname(__FILE__) . '/locallib.php');
-
-$engineid = required_param('engineid', PARAM_INT);
-$remoteid = required_param('remoteid', PARAM_PATH);
-$remoteversion = required_param('remoteversion', PARAM_PATH);
-$filename = required_param('filename', PARAM_FILE);
-
-// The Open University found it necessary to comment out the whole of the following if statement
-// to make things work reliably. However, I think that was only problems with synchronising
-// the session between our load-balanced servers, and I think it is better to leave
-// this code in. (OU bug 7991.)
-global $SESSION;
-if ($SESSION->cached_opaque_state->engineid != $engineid ||
-        $SESSION->cached_opaque_state->remoteid != $remoteid ||
-        $SESSION->cached_opaque_state->remoteversion != $remoteversion) {
-            print_error('cannotaccessfile');
-}
-
-$resourcecache = new qtype_opaque_resource_cache($engineid, $remoteid, $remoteversion);
-$resourcecache->serve_file($filename);
diff --git a/question/type/opaque/lang/en/qtype_opaque.php b/question/type/opaque/lang/en/qtype_opaque.php
deleted file mode 100644 (file)
index fa70557..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Strings for component 'qtype_opaque', language 'en', branch 'MOODLE_20_STABLE'
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2006 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-$string['accessoutofsequence'] = 'You have accessed this page out of sequence. Please do not use the Back button when attempting questions.';
-$string['addengine'] = 'Add another engine';
-$string['addingopaque'] = 'Adding an Opaque question';
-$string['cannotaccessfile'] = 'You are not allowed to access this file.';
-$string['configuredquestionengines'] = 'Configured question engines';
-$string['configuredquestionengines_help'] = 'Opaque is a way of connecting other compatible question engines into Moodle. For Moodle to use another question engine, it needs to be set up here. This screen lists all the question engines that have been configured. Lets you edit their configurations, delete configurations, and create new ones.';
-$string['couldnotconnect'] = 'Could not connect to the opaque server {$a}.';
-$string['couldnotgetengineinfo'] = 'Could not get the remote server information for engine id {$a}.';
-$string['couldnotloadenginename'] = 'Could not load the engine name from the database for engine id {$a}.';
-$string['couldnotloadengineservers'] = 'Could not load the servers list from the database for engine id {$a}.';
-$string['couldnotsaveengineinfo'] = 'Could not save the details of the question engine to the database.';
-$string['deleteconfigareyousure'] = 'Are you sure you want to delete the configuration of engine {$a}?';
-$string['deletefailed'] = 'Error when trying to delete the engine configuration.';
-$string['editingopaque'] = 'Editing an opaque question';
-$string['editquestionengine'] = 'Editing Opaque question engine configuration';
-$string['editquestionengine_help'] = 'Each remote system you configure must have a name, which will be used to identify it within Moodle. You must specify at least one question engine URL. You can also specify question bank URLs, if your remote question engine uses a separate question bank. When specifying URLs, you may specify several, one per line. Do this when you have several load-balanced servers. Calls to the question engines will be distributed approximately evenly over the different remote servers.';
-$string['editquestionengineshort'] = 'Editing engine';
-$string['enginedeleted'] = 'Engine configuration deleted.';
-$string['enginename'] = 'Engine name';
-$string['errorconnecting'] = 'Error connecting to the remote question engine.';
-$string['getmetadatacallfailed'] = 'Failed to retrieve the metadata for this question.  Are you sure the remote id and version are correct?';
-$string['invalidquestionidsyntax'] = 'This does not match the syntax for a question id';
-$string['invalidquestionversionsyntax'] = 'The question version should be of the form major.minor, where major and minor are integers.';
-$string['lTRYAGAIN'] = 'Try again';
-$string['lGIVEUP'] = 'Pass';
-$string['lNEXTQUESTION'] = 'Next';
-$string['lENTERANSWER'] = 'Check';
-$string['lCLEAR'] = 'Clear';
-$string['managequestionengines'] = 'Manage the list of installed question engines.';
-$string['maxgradenotreturned'] = 'The question engine was not able to return the maximum grades for this question. Are you sure the remote id and version are correct?';
-$string['missingenginedetailsinimport'] = 'Missing engine details when importing an Opaque question.';
-$string['missingenginename'] = 'Missing engine name';
-$string['missingengineurls'] = 'Missing question engine URLs';
-$string['missingremoteidinimport'] = 'Missing remote id in import file.';
-$string['missingremoteversioninimport'] = 'Missing remote version in import file.';
-$string['noengines'] = 'Currenly, there are no configured remote engines.';
-$string['notcompleted'] = '[Not completed]';
-$string['notcompletedmessage'] = 'You did not complete this question during the attempt. No review is possible.';
-$string['onequestionperpage'] = 'For technical reasons, this question cannot be shown here at this time. (Only one one question of this type can be displayed on each screen.) Please review one question at a time by clicking on the question number in the navigation panel.';
-$string['opaque'] = 'Opaque';
-$string['opaque_help'] = 'Opaque is a way of connecting other compatible question engines into Moodle. This screen lets you create an Opaque question by identifying which remote question engine to connect to, and giving the identity of the question on that remote engine, as explained in the Opaque documentation. Question engines need to be configured on the question engine configuration admin screen.';
-$string['opaquesummary'] = 'Use a question provided by another question engine system.';
-$string['passkey'] = 'Pass key';
-$string['passkey_help'] = 'A pass key is a security measure that some question engines implement. You will only be able to connect to that question engine if you know the pass key. Consult the documentation for the particular type of question engine you are trying to connect to.';
-$string['pluginname'] = 'Opaque';
-$string['processcallfailed'] = 'Failed to process a response. {$a}';
-$string['questionbankurls'] = 'Question bank URLs';
-$string['questionengineurls'] = 'Question engine URLs';
-$string['questionengine'] = 'Question engine';
-$string['questionengine_help'] = 'Select the remote question engine that hosts the question you wish to use.';
-$string['questionid'] = 'Question id';
-$string['questionid_help'] = 'Opaque questions are identified by both a question id and a question version number. The person who created the question you are trying to refer to will be able to tell you these.';
-$string['questionversion'] = 'Question version';
-$string['soapfault'] = 'Technical details:
-Fault code: {$a->faultcode}.
-Fault actor: {$a->faultactor}.
-Fault string: {$a->faultstring}.
-Fault detail: {$a->faultdetail}.';
-$string['startcallfailed'] = 'Failed to start a question session. {$a}';
-$string['stopcallfailed'] = 'Failed to close question session. {$a}';
-$string['testconnection'] = 'Test connection';
-$string['testconnectionfailed'] = 'Connection test failed.';
-$string['testconnectionpassed'] = 'Connection test passed.';
-$string['testconnectionto'] = 'Test connection to question engine {$a}';
-$string['testconnectionunknownreturn'] = 'Connection test returned an unrecognised response.';
-$string['testingengine'] = 'Testing question engine';
-$string['unknownengine'] = 'Unknown engine. {$a}';
-$string['unrecognisedservertype'] = 'Unrecognised server type read from the database.';
-$string['urlsinvalid'] = 'You must enter a list of URLs, one per line.';
diff --git a/question/type/opaque/locallib.php b/question/type/opaque/locallib.php
deleted file mode 100644 (file)
index 0316d00..0000000
+++ /dev/null
@@ -1,851 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Library routines used by the Opaque question type.
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2006 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir . '/soaplib.php');
-require_once($CFG->libdir . '/xmlize.php');
-
-
-/** User passed on question. Should match the definition in Om.question.Results. */
-define('OPAQUE_ATTEMPTS_PASS', 0);
-/**
- * User got question wrong after all attempts. Should match the definition in
- * om.question.Results.
- */
-define('OPAQUE_ATTEMPTS_WRONG', -1);
-/**
- * User got question partially correct after all attempts. Should match the
- * definition in om.question.Results.
- */
-define('OPAQUE_ATTEMPTS_PARTIALLYCORRECT', -2);
-/** If developer hasn't set the value. Should match the definition in om.question.Results. */
-define('OPAQUE_ATTEMPTS_UNSET', -99);
-/** Prefix used for CSS files. */
-define('OPAQUE_CSS_FILENAME_PREFIX', '__styles_');
-
-/**
- * @return an array id -> enginename, that can be used to build a dropdown
- * menu of installed question types.
- */
-function qtype_opaque_installed_engine_choices() {
-    global $DB;
-    return $DB->get_records_menu('question_opaque_engines', array(), 'name ASC', 'id, name');
-}
-
-function qtype_opaque_format_soap_fault($fault) {
-    foreach (array('faultcode', 'faultactor', 'faultstring', 'faultdetail') as $field) {
-        if (empty($fault->$field)) {
-            $fault->$field = '';
-        }
-    }
-    return get_string('soapfault', 'qtype_opaque', $fault);
-}
-
-
-/**
- * Manages loading and saving question engine definitions to and from the database.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_opaque_engine_manager {
-    /**
-     * Load the definition of an engine from the database.
-     * @param int $engineid the id of the engine to load.
-     * @return mixed On success, and object with fields id, name, questionengines
-     *      and questionbanks. The last two fields are arrays of URLs. On an error,
-     *      returns a string to look up in the qtype_opaque language file as an
-     *      error message.
-     */
-    public function load_engine_def($engineid) {
-        global $DB;
-        $engine = $DB->get_record('question_opaque_engines',
-                array('id' => $engineid), '*', MUST_EXIST);
-
-        $engine->questionengines = array();
-        $engine->questionbanks = array();
-        $servers = $DB->get_records('question_opaque_servers',
-                array('engineid' => $engineid), 'id ASC');
-        if (!$servers) {
-            throw new moodle_exception('couldnotloadengineservers', 'qtype_opaque', '', $engineid);
-        }
-        foreach ($servers as $server) {
-            if ($server->type == 'qe') {
-                $engine->questionengines[] = $server->url;
-            } else if ($server->type == 'qb') {
-                $engine->questionbanks[] = $server->url;
-            } else {
-                throw new moodle_exception('unrecognisedservertype', 'qtype_opaque', '', $engineid);
-            }
-        }
-        return $engine;
-    }
-
-    /**
-     * Save or update an engine definition in the database, and returm the engine id. The definition
-     * will be created if $engine->id is not set, and updated if it is.
-     *
-     * @param object $engine the definition to save.
-     * @return int the id of the saved definition.
-     */
-    public function save_engine_def($engine) {
-        global $DB;
-        $transaction = $DB->start_delegated_transaction();
-
-        if (!empty($engine->id)) {
-            $DB->update_record('question_opaque_engines', $engine);
-        } else {
-            $engine->id = $DB->insert_record('question_opaque_engines', $engine);
-        }
-        $DB->delete_records('question_opaque_servers', array('engineid' => $engine->id));
-        $this->store_opaque_servers($engine->questionengines, 'qe', $engine->id);
-        $this->store_opaque_servers($engine->questionbanks, 'qb', $engine->id);
-
-        $transaction->allow_commit();
-        return $engine->id;
-    }
-
-    /**
-     * Save a list of servers of a given type in the question_opaque_servers table.
-     *
-     * @param array $urls an array of URLs.
-     * @param string $type 'qe' or 'qb'.
-     * @param int $engineid
-     */
-    protected function store_opaque_servers($urls, $type, $engineid) {
-        global $DB;
-        foreach ($urls as $url) {
-            $server = new stdClass();
-            $server->engineid = $engineid;
-            $server->type = $type;
-            $server->url = $url;
-            $DB->insert_record('question_opaque_servers', $server, false);
-        }
-    }
-
-    /**
-     * Delete the definition of an engine from the database.
-     * @param int $engineid the id of the engine to delete.
-     * @return bool whether the delete succeeded.
-     */
-    public function delete_engine_def($engineid) {
-        global $DB;
-        $transaction = $DB->start_delegated_transaction();
-        $DB->delete_records('question_opaque_servers', array('engineid' => $engineid));
-        $DB->delete_records('question_opaque_engines', array('id' => $engineid));
-        $transaction->allow_commit();
-    }
-
-    protected function get_possibly_matching_engines($engine) {
-        global $DB;
-
-        // First we try to get a reasonably accurate guess with SQL - we load
-        // the id of all engines with the same passkey and which use the first
-        // questionengine and questionbank (if any).
-        $tables = array('FROM {question_opaque_engines} e');
-        $conditions = array('e.passkey = :passkey');
-        $params = array('passkey' => $engine->passkey);
-        if (!empty($engine->questionengines)) {
-            $qeurl = reset($engine->questionengines);
-            $tables[] = "JOIN {question_opaque_servers} qe ON
-                    qe.engineid = e.id AND qe.type = 'qe'";
-            $conditions[] = 'qe.url = :qeurl';
-            $params['qeurl'] = $qeurl;
-        }
-        if (!empty($engine->questionbanks)) {
-            $qburl = reset($engine->questionbanks);
-            $tables[] = "JOIN {question_opaque_servers} qb ON
-                    qb.engineid = e.id AND qb.type = 'qb'";
-            $conditions[] = 'qb.url = :qburl';
-            $params['qburl'] = $qburl;
-        }
-        return $DB->get_records_sql_menu('
-                SELECT e.id,1 ' . implode(' ', $tables) . ' WHERE ' .
-                implode(' AND ', $conditions), $params);
-    }
-
-    /**
-     * If an engine definition like this one (same passkey and server lists) already exists
-     * in the database, then return its id, otherwise save this one to the database and
-     * return the new engine id.
-     *
-     * @param object $engine the engine to ensure is in the databse.
-     * @return int its id.
-     */
-    public function find_or_create_engineid($engine) {
-        $possibleengineids = $this->get_possibly_matching_engines($engine);
-
-        // Then we loop through the possibilities loading the full definition and comparing it.
-        if ($possibleengineids) {
-            foreach ($possibleengineids as $engineid => $ignored) {
-                $testengine = $this->load_engine_def($engineid);
-                $testengine->passkey = $testengine->passkey;
-                if ($this->is_same_engine($engine, $testengine)) {
-                    return $engineid;
-                }
-            }
-        }
-
-        return $this->save_engine_def($engine);
-    }
-
-    /**
-     * Are these two engine definitions essentially the same (same passkey and server lists)?
-     *
-     * @param object $engine1 one engine definition.
-     * @param object $engine2 another engine definition.
-     * @return bool whether they are the same.
-     */
-    public function is_same_engine($engine1, $engine2) {
-        // Same passkey.
-        $ans = $engine1->passkey == $engine2->passkey &&
-        // Same question engines.
-                !array_diff($engine1->questionengines, $engine2->questionengines) &&
-                !array_diff($engine2->questionengines, $engine1->questionengines) &&
-        // Same question banks.
-                !array_diff($engine1->questionbanks, $engine2->questionbanks) &&
-                !array_diff($engine2->questionbanks, $engine1->questionbanks);
-        return $ans;
-    }
-}
-
-/**
- * Load the definition of an engine from the database.
- * @param int $engineid the id of the engine to load.
- * @return mixed On success, and object with fields id, name, questionengines and questionbanks.
- * The last two fields are arrays of URLs. On an error, returns a string to look up in the
- * qtype_opaque language file as an error message.
- */
-function qtype_opaque_load_engine_def($engineid) {
-    $manager = new qtype_opaque_engine_manager();
-    return $manager->load_engine_def($engineid);
-}
-
-/**
- * Save or update an engine definition in the database, and returm the engine id. The definition
- * will be created if $engine->id is not set, and updated if it is.
- *
- * @param object $engine the definition to save.
- * @return int the id of the saved definition.
- */
-function qtype_opaque_save_engine_def($engine) {
-    $manager = new qtype_opaque_engine_manager();
-    return $manager->save_engine_def($engine);
-}
-
-/**
- * Delete the definition of an engine from the database.
- * @param int $engineid the id of the engine to delete.
- * @return bool whether the delete succeeded.
- */
-function qtype_opaque_delete_engine_def($engineid) {
-    $manager = new qtype_opaque_engine_manager();
-    return $manager->delete_engine_def($engineid);
-}
-
-/**
- * If an engine definition like this one (same passkey and server lists) already exists
- * in the database, then return its id, otherwise save this one to the database and
- * return the new engine id.
- *
- * @param object $engine the engine to ensure is in the databse.
- * @return int its id.
- */
-function qtype_opaque_find_or_create_engineid($engine) {
-    $manager = new qtype_opaque_engine_manager();
-    return $manager->find_or_create_engineid($engine);
-}
-
-/**
- * @param mixed $engine either an $engine object, or the URL of a particular
- *      question engine server.
- * @return a soap connection, either to the specific URL give, or to to one of
- *      the question engine servers of this $engine object picked at random.
- *      returns a string to look up in the qtype_opaque language file as an error
- *      message if a problem arises.
- */
-function qtype_opaque_connect($engine) {
-    if (is_string($engine)) {
-        $url = $engine;
-    } else if (!empty($engine->urlused)) {
-        $url = $engine->urlused;
-    } else {
-        $url = $engine->questionengines[array_rand($engine->questionengines)];
-    }
-    $connection = new SoapClient($url . '?wsdl',
-            array('soap_version'=>SOAP_1_1, 'exceptions'=>true));
-    if (!is_string($engine)) {
-        $engine->urlused = $url;
-    }
-    return $connection;
-}
-
-/**
- * @param mixed $engine either an $engine object, or the URL of a particular
- *      question engine server.
- * @return some XML, as parsed by xmlize, on success, or a string to look up in
- *      the qtype_opaque language file as an error message.
- */
-function qtype_opaque_get_engine_info($engine) {
-    $connection = qtype_opaque_connect($engine);
-    $getengineinforesult = $connection->getEngineInfo();
-    return xmlize($getengineinforesult);
-}
-
-/**
- * @param mixed $engine either an $engine object, or the URL of a particular
- *      question engine server.
- * @return The question metadata, as an xmlised array, so, for example,
- *      $metadata[questionmetadata][@][#][scoring][0][#][marks][0][#] is the
- *      maximum possible score for this question.
- */
-function qtype_opaque_get_question_metadata($engine, $remoteid, $remoteversion) {
-    $connection = qtype_opaque_connect($engine);
-    $questionbaseurl = $engine->questionbanks[array_rand($engine->questionbanks)];
-    $getmetadataresult = $connection->getQuestionMetadata(
-            $remoteid, $remoteversion, $questionbaseurl);
-    return xmlize($getmetadataresult);
-}
-
-/**
- * @param object $engine the engine to connect to.
- * @param string $remoteid
- * @param string $remoteversion
- * @param int $randomseed
- * @return mixed the result of the soap call on success, or a string error message on failure.
- */
-function qtype_opaque_start_question_session($engine, $remoteid, $remoteversion,
-        $data, $cached_resources) {
-    $connection = qtype_opaque_connect($engine);
-
-    $questionbaseurl = '';
-    if (!empty($engine->questionbanks)) {
-        $questionbaseurl = $engine->questionbanks[array_rand($engine->questionbanks)];
-    }
-
-    $initialparams = array(
-        'randomseed' => $data['-_randomseed'],
-        'userid' => $data['-_userid'],
-        'language' => $data['-_language'],
-        'passKey' => qtype_opaque_generate_passkey($engine->passkey, $data['-_userid']),
-        'preferredbehaviour' => $data['-_preferredbehaviour'],
-    );
-
-    return $connection->start($remoteid, $remoteversion, $questionbaseurl,
-            array_keys($initialparams), array_values($initialparams), $cached_resources);
-}
-
-function qtype_opaque_process($engine, $questionsessionid, $response) {
-    $connection = qtype_opaque_connect($engine);
-    return $connection->process($questionsessionid, array_keys($response),
-            array_values($response));
-}
-
-/**
- * @param string $questionsessionid the question session to stop.
- * @return true on success, or a string error message on failure.
- */
-function qtype_opaque_stop_question_session($engine, $questionsessionid) {
-    $connection = qtype_opaque_connect($engine);
-    $connection->stop($questionsessionid);
-    return true;
-}
-
-/**
- * Get a step from $qa, as if $pendingstep had already been added at the end
- * of the list, if it is not null.
- * @param int $seq
- * @param question_attempt $qa
- * @param question_attempt_step|null $pendingstep
- * @return question_attempt_step
- */
-function qtype_opaque_get_step($seq, question_attempt $qa, $pendingstep) {
-    if ($seq < $qa->get_num_steps()) {
-        return $qa->get_step($seq);
-    }
-    if ($seq == $qa->get_num_steps() && !is_null($pendingstep)) {
-        return $pendingstep;
-    }
-    throw new coding_exception('Sequence number ' . $seq . ' out of range.');
-}
-
-/**
- * Wrapper round $step->get_submitted_data() to work around an incompatibility
- * between OpenMark and the Moodle question engine.
- * @param question_attempt_step $step a step.
- * @return array approximately $step->get_submitted_data().
- */
-function qtype_opaque_get_submitted_data(question_attempt_step $step) {
-    // By default, OpenMark radio buttons get the name '_rg', whcih breaks
-    // one of the assumptions of the qutesion engine, so we have to manually
-    // include it when doing get_submitted_data.
-    $response = $step->get_submitted_data();
-    if ($step->has_qt_var('_rg')) {
-        $response['_rg'] = $step->get_qt_var('_rg');
-    }
-    return $response;
-}
-
-/**
- * Update the $SESSION->cached_opaque_state to show the current status of $question for state
- * $state.
- * @param object $question the question
- * @param object $state
- * @return mixed $SESSION->cached_opaque_state on success, a string error message on failure.
- */
-function qtype_opaque_update_state(question_attempt $qa,
-        question_attempt_step $pendingstep = null) {
-    global $SESSION;
-
-    $question = $qa->get_question();
-    $targetseq = $qa->get_num_steps() - 1;
-    if (!is_null($pendingstep)) {
-        $targetseq += 1;
-    }
-
-    if (empty($SESSION->cached_opaque_state) ||
-            empty($SESSION->cached_opaque_state->qaid) ||
-            empty($SESSION->cached_opaque_state->sequencenumber)) {
-        $cachestatus = 'empty';
-    } else if ($SESSION->cached_opaque_state->qaid != $qa->get_database_id() ||
-            $SESSION->cached_opaque_state->sequencenumber > $targetseq) {
-        if (!empty($SESSION->cached_opaque_state->questionsessionid)) {
-            $error = qtype_opaque_stop_question_session($SESSION->cached_opaque_state->engine,
-                    $SESSION->cached_opaque_state->questionsessionid);
-            if (is_string($error)) {
-                unset($SESSION->cached_opaque_state);
-                return $error;
-            }
-        }
-        unset($SESSION->cached_opaque_state);
-        $cachestatus = 'empty';
-    } else if ($SESSION->cached_opaque_state->sequencenumber < $targetseq) {
-        $cachestatus = 'catchup';
-    } else {
-        $cachestatus = 'good';
-    }
-
-    $resourcecache = new qtype_opaque_resource_cache($question->engineid,
-            $question->remoteid, $question->remoteversion);
-
-    if ($cachestatus == 'empty') {
-        $SESSION->cached_opaque_state = new stdClass();
-        $opaquestate = $SESSION->cached_opaque_state;
-        $opaquestate->qaid = $qa->get_database_id();
-        $opaquestate->remoteid = $question->remoteid;
-        $opaquestate->remoteversion = $question->remoteversion;
-        $opaquestate->engineid = $question->engineid;
-        $opaquestate->nameprefix = $qa->get_field_prefix();
-        $opaquestate->questionended = false;
-        $opaquestate->sequencenumber = -1;
-        $opaquestate->resultssequencenumber = -1;
-
-        $engine = qtype_opaque_load_engine_def($question->engineid);
-        if (is_string($engine)) {
-            unset($SESSION->cached_opaque_state);
-            return $engine;
-        }
-        $opaquestate->engine = $engine;
-
-        $step = qtype_opaque_get_step(0, $qa, $pendingstep);
-        $startreturn = qtype_opaque_start_question_session($engine, $question->remoteid,
-                $question->remoteversion, $step->get_all_data(),
-                $resourcecache->list_cached_resources());
-        if (is_string($startreturn)) {
-            unset($SESSION->cached_opaque_state);
-            return $startreturn;
-        }
-
-        qtype_opaque_extract_stuff_from_response($opaquestate, $startreturn, $resourcecache);
-        $opaquestate->sequencenumber++;
-        $cachestatus = 'catchup';
-    } else {
-        $opaquestate = $SESSION->cached_opaque_state;
-    }
-
-    if ($cachestatus == 'catchup') {
-        if ($opaquestate->sequencenumber >= $targetseq) {
-            $error = qtype_opaque_stop_question_session($opaquestate->engine,
-                    $opaquestate->questionsessionid);
-        }
-        while ($opaquestate->sequencenumber < $targetseq) {
-            $step = qtype_opaque_get_step($opaquestate->sequencenumber + 1, $qa, $pendingstep);
-
-            $processreturn = qtype_opaque_process($opaquestate->engine,
-                    $opaquestate->questionsessionid, qtype_opaque_get_submitted_data($step));
-            if (is_string($processreturn)) {
-                unset($SESSION->cached_opaque_state);
-                return $processreturn;
-            }
-
-            if (!empty($processreturn->results)) {
-                $opaquestate->resultssequencenumber = $opaquestate->sequencenumber + 1;
-                $opaquestate->results = $processreturn->results;
-            }
-            if ($processreturn->questionEnd) {
-                $opaquestate->questionended = true;
-                $opaquestate->sequencenumber = $targetseq;
-                $opaquestate->xhtml = qtype_opaque_strip_omact_buttons($opaquestate->xhtml);
-                unset($opaquestate->questionsessionid);
-                break;
-            }
-            qtype_opaque_extract_stuff_from_response($opaquestate, $processreturn, $resourcecache);
-
-            $opaquestate->sequencenumber++;
-        }
-        $cachestatus = 'good';
-    }
-
-    return $opaquestate;
-}
-
-/**
- * File name used to store the CSS of the question, question session id is appended.
- */
-function qtype_opaque_stylesheet_filename($questionsessionid) {
-    return OPAQUE_CSS_FILENAME_PREFIX . $questionsessionid . '.css';
-}
-
-/**
- * Pulls out the fields common to StartResponse and ProcessResponse.
- * @param object $opaquestate should be $SESSION->cached_opaque_state, or equivalent.
- * @param object $response a StartResponse or ProcessResponse.
- * @param object $resourcecache the resource cache for this question.
- * @return true on success, or a string error message on failure.
- */
-function qtype_opaque_extract_stuff_from_response($opaquestate, $response, $resourcecache) {
-    global $CFG;
-    static $replaces;
-
-    if (empty($replaces)) {
-        $replaces = array(
-            '%%RESOURCES%%' => '', // Filled in below.
-            '%%IDPREFIX%%' => '', // Filled in below.
-            '%%%%' => '%%'
-        );
-
-        $strings = array('lTRYAGAIN', 'lGIVEUP', 'lNEXTQUESTION', 'lENTERANSWER', 'lCLEAR');
-        foreach ($strings as $string) {
-            $replaces["%%$string%%"] = get_string($string, 'qtype_opaque');
-        }
-    }
-
-    // Process the XHTML, replacing the strings that need to be replaced.
-    $xhtml = $response->XHTML;
-
-    $replaces['%%RESOURCES%%'] = $resourcecache->file_url('');
-    $replaces['%%IDPREFIX%%'] = $opaquestate->nameprefix;
-    $xhtml = str_replace(array_keys($replaces), $replaces, $xhtml);
-
-    // TODO this is a nasty hack. Flash uses & as a separator in the FlashVars string,
-    // so we have to replce the &amp;s with %26s in this one place only. So for now
-    // do it with a regexp. Longer term, it might be better to changes the file.php urls
-    // so they don't contain &s.
-    $xhtml = preg_replace_callback(
-            '/name="FlashVars" value="TheSound=[^"]+"/',
-            create_function('$matches', 'return str_replace("&amp;", "%26", $matches[0]);'),
-            $xhtml);
-
-    // Another hack to take out the next button that most OM questions include,
-    // but which does not work in Moodle. Actually, we remove any non-disabled
-    // buttons, and the following script tag.
-    // TODO think of a better way to do this.
-    if ($opaquestate->resultssequencenumber >= 0) {
-        $xhtml = qtype_opaque_strip_omact_buttons($xhtml);
-    }
-
-    $opaquestate->xhtml = $xhtml;
-
-    // Process the CSS (only when we have a StartResponse).
-    if (!empty($response->CSS)) {
-        $opaquestate->cssfilename = qtype_opaque_stylesheet_filename($response->questionSession);
-        $resourcecache->cache_file($opaquestate->cssfilename,
-                'text/css;charset=UTF-8', $response->CSS);
-    }
-
-    // Process the resources.
-    // TODO remove this. Evil hack. IE cannot cope with : and other odd characters
-    // in the name argument to window.open. Until we can deploy a fix to the
-    // OpenMark servers, apply the fix to the JS code here.
-    foreach ($response->resources as $key => $resource) {
-        if ($resource->filename == 'script.js') {
-            $response->resources[$key]->content = preg_replace(
-                    '/(?<=' . preg_quote('window.open("", idprefix') . '|' .
-                            preg_quote('window.open("",idprefix') . ')\+(?=\"\w+\"\+id,)/',
-                    '.replace(/\W/g,"_")+', $resource->content);
-        }
-    }
-    $resourcecache->cache_resources($response->resources);
-
-    // Process the other bits.
-    $opaquestate->progressinfo = $response->progressInfo;
-    if (!empty($response->questionSession)) {
-        $opaquestate->questionsessionid = $response->questionSession;
-    }
-
-    if (!empty($response->head)) {
-        $opaquestate->headXHTML = $response->head;
-    }
-
-    return true;
-}
-
-/**
- * Strip any buttons, followed by script tags, where the button has an id
- * containing _omact_, and is not disabled.
- */
-function qtype_opaque_strip_omact_buttons($xhtml) {
-    return preg_replace(
-            '|<input(?:(?!disabled=)[^>])*? id="[^"]*_omact_[^"]*"(?:(?!disabled=)[^>])*?>' .
-            '<script type="text/javascript">[^<]*</script>|', '', $xhtml);
-}
-
-/**
- * @param string $secret the secret string for this question engine.
- * @param int $userid the id of the user attempting this question.
- * @return string the passkey that needs to be sent to the quetion engine to
- *      show that we are allowed to start a question session for this user.
- */
-function qtype_opaque_generate_passkey($secret, $userid) {
-    return md5($secret . $userid);
-}
-
-/**
- * OpenMark relies on certain browser-specific class names to be present in the
- * HTML outside the question, in order to apply certian browser-specific layout
- * work-arounds. This function re-implements Om's browser sniffing rules. See
- * http://java.net/projects/openmark/sources/svn/content/trunk/src/util/misc/UserAgent.java
- * @return string class to add to the HTML.
- */
-function qtype_opaque_browser_type() {
-    $useragent = $_SERVER['HTTP_USER_AGENT'];
-
-    // Filter troublemakers
-    if (strpos($useragent, 'KHTML') !== false) {
-        return "khtml";
-    }
-    if (strpos($useragent, 'Opera') !== false) {
-        return "opera";
-    }
-
-    // Check version of our two supported browsers
-    $matches = array();
-    if (preg_match('/"^.*rv:(\d+)\\.(\d+)\D.*$"/', $useragent, $matches)) {
-        return 'gecko-' . $matches[1] . '-' . $matches[2];
-    }
-    if (preg_match('/^.*MSIE (\d+)\\.(\d+)\D.*Windows.*$/', $useragent, $matches)) {
-        return 'winie-' . $matches[1]; // Major verison only
-    }
-
-    return '';
-}
-
-
-/**
- * This class caches the resources belonging a particular question.
- *
- * There are synchronisation issues if two students are doing the same question
- * at the same time.
- *
- * @copyright  2010 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_opaque_resource_cache {
-    protected $folder; // Path to the folder where resources for this question are cached.
-    protected $metadatafolder; // Path to the folder where mime types are stored.
-    protected $baseurl; // initial part of the URL to link to a file in the cache.
-
-    /**
-     * Create a new qtype_opaque_resource_cache for a particular remote question.
-     * @param int $engineid the id of the question engine.
-     * @param string $remoteid remote question id, as per Opaque spec.
-     * @param string $remoteversion remote question version, as per Opaque spec.
-     */
-    public function __construct($engineid, $remoteid, $remoteversion) {
-        global $CFG;
-        $folderstart = $CFG->dataroot . '/opaqueresources/' . $engineid . '/' .
-                $remoteid . '/' . $remoteversion;
-        $this->folder = $folderstart . '/files';
-        if (!is_dir($this->folder)) {
-            $this->mkdir_recursive($this->folder);
-        }
-        $this->metadatafolder = $folderstart . '/meta';
-        if (!is_dir($this->metadatafolder)) {
-            $this->mkdir_recursive($this->metadatafolder);
-        }
-        $this->baseurl = new moodle_url('/question/type/opaque/file.php',
-                array('engineid' => $engineid, 'remoteid' => $remoteid,
-                      'remoteversion' => $remoteversion));
-    }
-
-    /**
-     * @param string $filename the file name.
-     * @return the full path of a file with the given name.
-     */
-    public function file_path($filename) {
-        return $this->folder . '/' . $filename;
-    }
-
-    /**
-     * @param string $filename the file name.
-     * @return the full path of a file with the given name.
-     */
-    public function file_meta_path($filename) {
-        return $this->metadatafolder . '/' . $filename;
-    }
-
-    /**
-     * @param string $filename the file name.
-     * @return the URL to access this file.
-     */
-    public function file_url($filename) {
-        return new moodle_url($this->baseurl, array('filename' => $filename));
-    }
-
-    /**
-     * @param string $filename the file name.
-     * @return the URL to access this file.
-     */
-    public function file_mime_type($filename) {
-        $metapath = $this->file_meta_path($filename);
-        if (file_exists($metapath)) {
-            return file_get_contents($metapath);
-        }
-        return mimeinfo('type', $filename);
-    }
-
-    /**
-     * @param string $filename the name of the file to look for.
-     * @return true if this named file is in the cache, otherwise false.
-     */
-    public function file_in_cache($filename) {
-        return file_exists($this->file_path($filename));
-    }
-
-    /**
-     * Serve a file from the cache.
-     * @param string $filename the file name.
-     */
-    public function serve_file($filename) {
-        if (!$this->file_in_cache($filename)) {
-            header('HTTP/1.0 404 Not Found');
-            header('Content-Type: text/plain;charset=UTF-8');
-            echo 'File not found';
-            exit;
-        }
-        $mimetype = $this->file_mime_type($filename);
-
-        // Handle If-Modified-Since
-        $file = $this->file_path($filename);
-        $filedate = filemtime($file);
-        $ifmodifiedsince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
-                $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
-        if ($ifmodifiedsince && strtotime($ifmodifiedsince) >= $filedate) {
-            header('HTTP/1.0 304 Not Modified');
-            exit;
-        }
-        header('Last-Modified: '.gmdate('D, d M Y H:i:s', $filedate).' GMT');
-
-        // Type
-        header('Content-Type: ' . $mimetype);
-        header('Content-Length: ' . filesize($file));
-
-        // Output file
-        session_write_close(); // unlock session during fileserving
-        readfile($file);
-    }
-
-    /**
-     * Store a file in the cache.
-     *
-     * @param string $filename the name of the file to cache.
-     * @param string $mimetype the type of the file to cache.
-     * @param string $content the contents to write to the file.
-     */
-    public function cache_file($filename, $mimetype, $content) {
-        file_put_contents($this->file_path($filename), $content);
-        file_put_contents($this->file_meta_path($filename), $mimetype);
-    }
-
-    /**
-     * Add the resources from a particular response to the cache.
-     * @param array $resources as returned from start or process Opaque methods.
-     */
-    public function cache_resources($resources) {
-        if (!empty($resources)) {
-            foreach ($resources as $resource) {
-                $mimetype = $resource->mimeType;
-                if (strpos($resource->mimeType, 'text/') === 0 && !empty($resource->encoding)) {
-                    $mimetype .= ';charset=' . $resource->encoding;
-                }
-                $this->cache_file($resource->filename, $mimetype, $resource->content);
-            }
-        }
-    }
-
-    /**
-     * List the resources cached for this question.
-     * @return array list of resource names.
-     */
-    public function list_cached_resources() {
-        $filepaths = glob($this->folder . '/*');
-        if (!is_array($filepaths)) {
-            // If an error occurrs, say that we have no files cached.
-            $filepaths = array();
-        }
-        $pathlen = strlen($this->folder . '/');
-        $files = array();
-        foreach ($filepaths as &$filepath) {
-            $file = substr($filepath, $pathlen);
-            if (strpos($file, OPAQUE_CSS_FILENAME_PREFIX) !== 0) {
-                $files[] = $file;
-            }
-        }
-        return $files;
-    }
-
-    /**
-     * This function exists because mkdir(folder,mode,TRUE) doesn't work on our server.
-     * Safe to call even if folder already exists (checks)
-     * @param string $folder Folder to create
-     * @param int $mode Mode for creation (default 0755)
-     * @return bool True if folder (now) exists, false if there was a failure
-     */
-    protected function mkdir_recursive($folder, $mode='') {
-        if (is_dir($folder)) {
-            return true;
-        }
-        if ($mode == '') {
-            global $CFG;
-            $mode = $CFG->directorypermissions;
-        }
-        if (!$this->mkdir_recursive(dirname($folder), $mode)) {
-            return false;
-        }
-        return mkdir($folder, $mode);
-    }
-}
diff --git a/question/type/opaque/pix/icon.gif b/question/type/opaque/pix/icon.gif
deleted file mode 100644 (file)
index 278ec3e..0000000
Binary files a/question/type/opaque/pix/icon.gif and /dev/null differ
diff --git a/question/type/opaque/question.php b/question/type/opaque/question.php
deleted file mode 100644 (file)
index 53f9c10..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Opaque question definition class.
- *
- * @package    qtype
- * @subpackage opaque
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die();
-
-
-/**
- * Represents an Opaque question.
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_opaque_question extends question_definition {
-    /** @var integer the ID of the question engine that serves this question. */
-    public $engineid;
-    /** @var string the id by which the question engine knows this question. */
-    public $remoteid;
-    /** @var string the version number of this question to use. */
-    public