From f7c1dfaf79f32429ca702749b9f400159f7a6f8b Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Mon, 21 Feb 2011 17:29:18 +0000 Subject: [PATCH] MDL-20636 Finish off converting question import. --- lang/en/question.php | 4 + lib/questionlib.php | 16 ++-- question/editlib.php | 2 +- question/export_form.php | 77 +++++++++++++------ question/format.php | 5 +- question/import.php | 129 +++++++++++++++++--------------- question/import_form.php | 148 +++++++++++++++++++++++++------------ question/todo/diffstat.txt | 64 +++++++++++++++- 8 files changed, 301 insertions(+), 144 deletions(-) diff --git a/lang/en/question.php b/lang/en/question.php index e902df54d9932..a0d6c8c2fb615 100644 --- a/lang/en/question.php +++ b/lang/en/question.php @@ -125,6 +125,7 @@ $string['exportquestions_link'] = 'question/export'; $string['filecantmovefrom'] = 'The questions files cannot be moved because you do not have permission to remove files from the place you are trying to move questions from.'; $string['filecantmoveto'] = 'The question files cannot be moved or copied becuase you do not have permission to add files to the place you are trying to move the questions to.'; +$string['fileformat'] = 'File format'; $string['filesareacourse'] = 'the course files area'; $string['filesareasite'] = 'the site files area'; $string['filestomove'] = 'Move / copy files to {$a}?'; @@ -145,6 +146,7 @@ $string['importquestions'] = 'Import questions from file'; $string['importquestions_help'] = 'This function enables questions in a variety of formats to be imported via text file. Note that the file must use UTF-8 encoding.'; $string['importquestions_link'] = 'question/import'; +$string['importwrongfiletype'] = 'The type of the file you selected ({$a->actualtype}) does not match the type expected by this import format ({$a->expectedtype}).'; $string['invalidarg'] = 'No valid arguments supplied or incorrect server configuration'; $string['invalidcategoryidforparent'] = 'Invalid category id for parent!'; $string['invalidcategoryidtomove'] = 'Invalid category id to move!'; @@ -156,6 +158,8 @@ $string['makechildof'] = 'Make child of \'{$a}\''; $string['maketoplevelitem'] = 'Move to top level'; $string['matchgrades'] = 'Match grades'; +$string['matchgradeserror'] = 'Error if grade not listed'; +$string['matchgradesnearest'] = 'Nearest grade if not listed'; $string['matchgrades_help'] = 'Imported grades must match one of the fixed list of valid grades - 100, 90, 80, 75, 70, 66.666, 60, 50, 40, 33.333, 30, 25, 20, 16.666, 14.2857, 12.5, 11.111, 10, 5, 0 (also negative values). If not, there are two options: * Error if grade not listed - If a question contains any grades not found in the list an error is displayed and that question will not be imported diff --git a/lib/questionlib.php b/lib/questionlib.php index 25e5514875ec9..2124f8ea420c0 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -1255,12 +1255,12 @@ function question_categorylist($categoryid) { * @return array sorted list of import/export formats available */ function get_import_export_formats($type) { - global $CFG; + $fileformats = get_plugin_list('qformat'); - $fileformatname=array(); - require_once( "{$CFG->dirroot}/question/format.php" ); + $fileformatname = array(); + require_once($CFG->dirroot . '/question/format.php'); foreach ($fileformats as $fileformat => $fdir) { $formatfile = $fdir . '/format.php'; if (is_readable($formatfile)) { @@ -1269,20 +1269,20 @@ function get_import_export_formats($type) { continue; } - $classname = "qformat_$fileformat"; + $classname = 'qformat_' . $fileformat; $formatclass = new $classname(); if ($type == 'import') { - $provided = $format_class->provide_import(); + $provided = $formatclass->provide_import(); } else { - $provided = $format_class->provide_export(); + $provided = $formatclass->provide_export(); } if ($provided) { - $fileformatnames[$fileformat] = get_string($fileformat, 'qformat_'.$fileformat); + $fileformatnames[$fileformat] = get_string($fileformat, 'qformat_' . $fileformat); } } - natcasesort($fileformatnames); + textlib_get_instance()->asort($fileformatnames); return $fileformatnames; } diff --git a/question/editlib.php b/question/editlib.php index fdfb4bf959b74..72c1dcf428ea2 100644 --- a/question/editlib.php +++ b/question/editlib.php @@ -26,7 +26,7 @@ */ -require_once($CFG->libdir.'/questionlib.php'); +require_once($CFG->libdir . '/questionlib.php'); define('DEFAULT_QUESTIONS_PER_PAGE', 20); diff --git a/question/export_form.php b/question/export_form.php index f76a991b6fbb6..dbc1e07416ec3 100644 --- a/question/export_form.php +++ b/question/export_form.php @@ -1,57 +1,86 @@ . + +/** + * Defines the export questions form. + * + * @package moodlecore + * @subpackage questionbank + * @copyright 2007 Jamie Pratt me@jamiep.org + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + if (!defined('MOODLE_INTERNAL')) { - die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page + die('Direct access to this script is forbidden.'); } -require_once($CFG->libdir.'/formslib.php'); +require_once($CFG->libdir . '/formslib.php'); + +/** + * Form to export questions from the question bank. + * + * @copyright 2007 Jamie Pratt me@jamiep.org + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class question_export_form extends moodleform { function definition() { - $mform =& $this->_form; + $mform = $this->_form; - $defaultcategory = $this->_customdata['defaultcategory']; - $contexts = $this->_customdata['contexts']; -//-------------------------------------------------------------------------------- - $mform->addElement('header','fileformat',get_string('fileformat','quiz')); + $defaultcategory = $this->_customdata['defaultcategory']; + $contexts = $this->_customdata['contexts']; + + // Choice of format, with help. + $mform->addElement('header', 'fileformat', get_string('fileformat', 'question')); $fileformatnames = get_import_export_formats('export'); $radioarray = array(); $i = 0 ; foreach ($fileformatnames as $shortname => $fileformatname) { $currentgrp1 = array(); - $currentgrp1[] = &$mform->createElement('radio','format','',$fileformatname,$shortname); - $mform->addGroup($currentgrp1,"formathelp[$i]",'',array('
'),false); - $mform->addHelpButton("formathelp[$i]", $shortname, 'qformat_'.$shortname); + $currentgrp1[] = $mform->createElement('radio', 'format', '', $fileformatname, $shortname); + $mform->addGroup($currentgrp1, "formathelp[$i]", '', array('
'), false); + $mform->addHelpButton("formathelp[$i]", $shortname, 'qformat_' . $shortname); $i++ ; } - $mform->addRule("formathelp[0]",null,'required',null,'client'); -//-------------------------------------------------------------------------------- - $mform->addElement('header','general', get_string('general', 'form')); + $mform->addRule("formathelp[0]", null, 'required', null, 'client'); + + // Export options. + $mform->addElement('header', 'general', get_string('general', 'form')); $mform->addElement('questioncategory', 'category', get_string('exportcategory', 'question'), compact('contexts')); $mform->setDefault('category', $defaultcategory); $mform->addHelpButton('category', 'exportcategory', 'question'); $categorygroup = array(); - $categorygroup[] =& $mform->createElement('checkbox', 'cattofile', '', get_string('tofilecategory', 'question')); - $categorygroup[] =& $mform->createElement('checkbox', 'contexttofile', '', get_string('tofilecontext', 'question')); + $categorygroup[] = $mform->createElement('checkbox', 'cattofile', '', get_string('tofilecategory', 'question')); + $categorygroup[] = $mform->createElement('checkbox', 'contexttofile', '', get_string('tofilecontext', 'question')); $mform->addGroup($categorygroup, 'categorygroup', '', '', false); $mform->disabledIf('categorygroup', 'cattofile', 'notchecked'); $mform->setDefault('cattofile', 1); $mform->setDefault('contexttofile', 1); -// $fileformatnames = get_import_export_formats('export'); -// $mform->addElement('select', 'format', get_string('fileformat','quiz'), $fileformatnames); -// $mform->setDefault('format', 'gift'); - - // set a template for the format select elements - $renderer =& $mform->defaultRenderer(); + // Set a template for the format select elements + $renderer = $mform->defaultRenderer(); $template = "{help} {element}\n"; $renderer->setGroupElementTemplate($template, 'format'); -//-------------------------------------------------------------------------------- - $this->add_action_buttons(false, get_string('exportquestions', 'quiz')); -//-------------------------------------------------------------------------------- + // Submit buttons. + $this->add_action_buttons(false, get_string('exportquestions', 'question')); } } diff --git a/question/format.php b/question/format.php index 7ec15b11af12d..eaad19c59ca2b 100644 --- a/question/format.php +++ b/question/format.php @@ -256,7 +256,7 @@ function importprocess($category) { set_time_limit(0); // STAGE 1: Parse the file - echo $OUTPUT->notification(get_string('parsingquestions','quiz')); + echo $OUTPUT->notification(get_string('parsingquestions','quiz'), 'notifysuccess'); if (! $lines = $this->readdata($this->filename)) { echo $OUTPUT->notification(get_string('cannotread','quiz')); @@ -269,7 +269,8 @@ function importprocess($category) { } // STAGE 2: Write data to database - echo $OUTPUT->notification(get_string('importingquestions','quiz',$this->count_questions($questions))); + echo $OUTPUT->notification(get_string('importingquestions', 'quiz', + $this->count_questions($questions)), 'notifysuccess'); // check for errors before we continue if ($this->stoponerror and ($this->importerrors>0)) { diff --git a/question/import.php b/question/import.php index 48be0d4525280..68e5dcc34dd92 100644 --- a/question/import.php +++ b/question/import.php @@ -1,17 +1,34 @@ . + /** - * Import quiz questions into the given category + * Defines the import questions form. * - * @author Martin Dougiamas, Howard Miller, and many others. - * {@link http://moodle.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU Public License - * @package questionbank - * @subpackage importexport + * @package moodlecore + * @subpackage questionbank + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once("../config.php"); -require_once("editlib.php"); // Includes lib/questionlib.php -require_once("import_form.php"); + +require_once(dirname(__FILE__) . '/../config.php'); +require_once($CFG->dirroot . '/question/editlib.php'); +require_once($CFG->dirroot . '/question/import_form.php'); +require_once($CFG->dirroot . '/question/format.php'); list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) = question_edit_setup('import', '/question/import.php', false, false); @@ -72,59 +89,53 @@ $importfile = "{$CFG->dataroot}/temp/questionimport/{$realfilename}"; make_upload_directory('temp/questionimport'); if (!$result = $import_form->save_file('newfile', $importfile, true)) { - print_error('uploadproblem', 'moodle'); - }else { - $fileisgood = true; + throw new moodle_exception('uploadproblem'); + } + + $formatfile = 'format/' . $form->format . '/format.php'; + if (!is_readable($formatfile)) { + throw new moodle_exception('formatnotfound', 'quiz', '', $form->format); } - // process if we are happy file is ok - if ($fileisgood) { - - if (! is_readable("format/$form->format/format.php")) { - print_error('formatnotfound','quiz', $form->format); - } - - require_once("format.php"); // Parent class - require_once("format/$form->format/format.php"); - - $classname = "qformat_$form->format"; - $qformat = new $classname(); - - // load data into class - $qformat->setCategory($category); - $qformat->setContexts($contexts->having_one_edit_tab_cap('import')); - $qformat->setCourse($COURSE); - $qformat->setFilename($importfile); - $qformat->setRealfilename($realfilename); - $qformat->setMatchgrades($form->matchgrades); - $qformat->setCatfromfile(!empty($form->catfromfile)); - $qformat->setContextfromfile(!empty($form->contextfromfile)); - $qformat->setStoponerror($form->stoponerror); - - // Do anything before that we need to - if (! $qformat->importpreprocess()) { - //TODO: need more detailed error info - print_error('cannotimport', '', $thispageurl->out()); - } - - // Process the uploaded file - if (! $qformat->importprocess($category)) { - //TODO: need more detailed error info - print_error('cannotimport', '', $thispageurl->out()); - } - - // In case anything needs to be done after - if (! $qformat->importpostprocess()) { - //TODO: need more detailed error info - print_error('cannotimport', '', $thispageurl->out()); - } - - echo '
'; - $params = $thispageurl->params() + array('category'=>"{$qformat->category->id},{$qformat->category->contextid}"); - echo $OUTPUT->continue_button(new moodle_url('edit.php', $params)); - echo $OUTPUT->footer(); - exit; + require_once($formatfile); + + $classname = 'qformat_' . $form->format; + $qformat = new $classname(); + + // load data into class + $qformat->setCategory($category); + $qformat->setContexts($contexts->having_one_edit_tab_cap('import')); + $qformat->setCourse($COURSE); + $qformat->setFilename($importfile); + $qformat->setRealfilename($realfilename); + $qformat->setMatchgrades($form->matchgrades); + $qformat->setCatfromfile(!empty($form->catfromfile)); + $qformat->setContextfromfile(!empty($form->contextfromfile)); + $qformat->setStoponerror($form->stoponerror); + + // Do anything before that we need to + if (!$qformat->importpreprocess()) { + //TODO: need more detailed error info + print_error('cannotimport', '', $thispageurl->out()); } + + // Process the uploaded file + if (!$qformat->importprocess($category)) { + //TODO: need more detailed error info + print_error('cannotimport', '', $thispageurl->out()); + } + + // In case anything needs to be done after + if (!$qformat->importpostprocess()) { + //TODO: need more detailed error info + print_error('cannotimport', '', $thispageurl->out()); + } + + $params = $thispageurl->params() + array( + 'category' => $qformat->category->id . ',' . $qformat->category->contextid); + echo $OUTPUT->continue_button(new moodle_url('edit.php', $params)); + echo $OUTPUT->footer(); + exit; } echo $OUTPUT->heading_with_help($txt->importquestions, 'importquestions', 'question'); diff --git a/question/import_form.php b/question/import_form.php index 30408a655c5c5..7ed0097d482a8 100644 --- a/question/import_form.php +++ b/question/import_form.php @@ -1,33 +1,68 @@ . + +/** + * Defines the import questions form. + * + * @package moodlecore + * @subpackage questionbank + * @copyright 2007 Jamie Pratt me@jamiep.org + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page } -require_once($CFG->libdir.'/formslib.php'); +require_once($CFG->libdir . '/formslib.php'); + +/** + * Form to import questions into the question bank. + * + * @copyright 2007 Jamie Pratt me@jamiep.org + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class question_import_form extends moodleform { function definition() { global $COURSE; - $mform =& $this->_form; + $mform = $this->_form; - $defaultcategory = $this->_customdata['defaultcategory']; - $contexts = $this->_customdata['contexts']; + $defaultcategory = $this->_customdata['defaultcategory']; + $contexts = $this->_customdata['contexts']; + + // Choice of import format, with help icons. + $mform->addElement('header', 'fileformat', get_string('fileformat', 'question')); -//-------------------------------------------------------------------------------- - $mform->addElement('header','fileformat', get_string('fileformat','quiz')); $fileformatnames = get_import_export_formats('import'); + $radioarray = array(); $i = 0 ; foreach ($fileformatnames as $shortname => $fileformatname) { $currentgrp1 = array(); - $currentgrp1[] = &$mform->createElement('radio','format','',$fileformatname,$shortname); - $mform->addGroup($currentgrp1,"formathelp[$i]",'',array('
'),false); - $mform->addHelpButton("formathelp[$i]", $shortname, 'qformat_'.$shortname); + $currentgrp1[] = $mform->createElement('radio', 'format', '', $fileformatname, $shortname); + $mform->addGroup($currentgrp1, "formathelp[$i]", '', array('
'), false); + $mform->addHelpButton("formathelp[$i]", $shortname, 'qformat_' . $shortname); $i++ ; } - $mform->addRule("formathelp[0]", null, 'required', null, 'client' ); -//-------------------------------------------------------------------------------- + $mform->addRule("formathelp[0]", null, 'required', null, 'client'); + + // Import options. $mform->addElement('header','general', get_string('general', 'form')); $mform->addElement('questioncategory', 'category', get_string('importcategory', 'question'), compact('contexts')); @@ -35,17 +70,16 @@ function definition() { $mform->addHelpButton('category', 'importcategory', 'question'); $categorygroup = array(); - $categorygroup[] =& $mform->createElement('checkbox', 'catfromfile', '', get_string('getcategoryfromfile', 'question')); - $categorygroup[] =& $mform->createElement('checkbox', 'contextfromfile', '', get_string('getcontextfromfile', 'question')); + $categorygroup[] = $mform->createElement('checkbox', 'catfromfile', '', get_string('getcategoryfromfile', 'question')); + $categorygroup[] = $mform->createElement('checkbox', 'contextfromfile', '', get_string('getcontextfromfile', 'question')); $mform->addGroup($categorygroup, 'categorygroup', '', '', false); $mform->disabledIf('categorygroup', 'catfromfile', 'notchecked'); $mform->setDefault('catfromfile', 1); $mform->setDefault('contextfromfile', 1); - $matchgrades = array(); - $matchgrades['error'] = get_string('matchgradeserror','quiz'); - $matchgrades['nearest'] = get_string('matchgradesnearest','quiz'); + $matchgrades['error'] = get_string('matchgradeserror', 'question'); + $matchgrades['nearest'] = get_string('matchgradesnearest', 'question'); $mform->addElement('select', 'matchgrades', get_string('matchgrades', 'question'), $matchgrades); $mform->addHelpButton('matchgrades', 'matchgrades', 'question'); $mform->setDefault('matchgrades', 'error'); @@ -54,47 +88,63 @@ function definition() { $mform->setDefault('stoponerror', 1); $mform->addHelpButton('stoponerror', 'stoponerror', 'question'); -//-------------------------------------------------------------------------------- - $mform->addElement('header', 'importfileupload', get_string('importfromthisfile','quiz')); - - $mform->addElement('filepicker', 'newfile', get_string('import', 'quiz')); -//-------------------------------------------------------------------------------- - $mform->addElement('submit', 'submitbutton', get_string('import', 'quiz')); - -//-------------------------------------------------------------------------------- - //if (has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $COURSE->id))){ - //$mform->addElement('header', 'importfilearea', get_string('importfilearea','quiz')); - //TODO: MDL-16094 - //$mform->addElement('choosecoursefile', 'choosefile', get_string('choosefile','quiz')); -//-------------------------------------------------------------------------------- - //$mform->addElement('submit', 'submitbutton', get_string('importfromthisfile','quiz')); - //} -//-------------------------------------------------------------------------------- - $mform->addElement('static', 'dummy', ''); - $mform->closeHeaderBefore('dummy'); - - // set a template for the format select elements - $renderer =& $mform->defaultRenderer(); + // The file to import + $mform->addElement('header', 'importfileupload', get_string('importquestions', 'question')); + + $mform->addElement('filepicker', 'newfile', get_string('import')); + $mform->addRule('newfile', null, 'required', null, 'client'); + + // Submit button. + $mform->addElement('submit', 'submitbutton', get_string('import')); + + // Set a template for the format select elements + $renderer = $mform->defaultRenderer(); $template = "{help} {element}\n"; $renderer->setGroupElementTemplate($template, 'format'); } - public function validation($data, $files){ - $errors = parent::validation($data, $files); - return $errors; // TODO. - // If a file is uploaded return - if ($data['choosefile'] || $files['newfile']) { + /** + * Checks that a file has been uploaded, and that it is of a plausible type. + * @param array $data the submitted data. + * @param array $errors the errors so far. + * @return array the updated errors. + */ + protected function validate_uploaded_file($data, $errors) { + if (empty($data['newfile'])) { + $errors['newfile'] = get_string('required'); return $errors; } - // If file is not uploaded from file upload - if (!$files['newfile']) { - $errors['newfile'] = get_string('importfromupload', 'question'); + + $files = $this->get_draft_files('newfile'); + if (count($files) < 1) { + $errors['newfile'] = get_string('required'); + return $errors; } - // If filke is not imported from course files - if (!$data['choosefile'] && !$files['newfile']) { - $errors['choosefile'] = get_string('importfromcoursefiles', 'question'); + + $formatfile = 'format/' . $data['format'] . '/format.php'; + if (!is_readable($formatfile)) { + throw new moodle_exception('formatnotfound', 'quiz', '', $data['format']); + } + + require_once($formatfile); + + $classname = 'qformat_' . $data['format']; + $qformat = new $classname(); + + $file = reset($files); + if ($file->get_mimetype() != $qformat->mime_type()) { + $a = new stdClass(); + $a->actualtype = $file->get_mimetype(); + $a->expectedtype = $qformat->mime_type(); + $errors['newfile'] = get_string('importwrongfiletype', 'question', $a); } + return $errors; } -} + public function validation($data, $files) { + $errors = parent::validation($data, $files); + $errors = $this->validate_uploaded_file($data, $errors); + return $errors; + } +} diff --git a/question/todo/diffstat.txt b/question/todo/diffstat.txt index 89f5bcb6671a8..11eb9a321b50f 100644 --- a/question/todo/diffstat.txt +++ b/question/todo/diffstat.txt @@ -175,7 +175,7 @@ DONE question/comment.html | 25 - DONE question/editlib.php | 36 +- GONE question/exportfile.php | 52 +- DONE question/file.php | 171 +- | but this file is probably obsolete. - question/import_form.php | 19 + | the change is to add validation that a file has been uploaded. +DONE question/import_form.php | 19 + | the change is to add validation that a file has been uploaded. DONE question/move_form.php | 32 +- DONE question/preview.js | 47 + DONE question/preview.php | 408 ++-- @@ -468,3 +468,65 @@ DONE mod/quiz/report/statistics/simpletest/mdl_question_states.csv DONE mod/quiz/settingslib.php DONE mod/quiz/styles.css DONE mod/quiz/version.php +question/behaviour/adaptive/lang/en/qbehaviour_adaptive.php +question/behaviour/adaptivenopenalty/lang/en/qbehaviour_adaptivenopenalty.php +question/behaviour/deferredcbm/lang/en/qbehaviour_deferredcbm.php +question/behaviour/deferredfeedback/lang/en/qbehaviour_deferredfeedback.php +question/behaviour/immediatecbm/lang/en/qbehaviour_immediatecbm.php +question/behaviour/immediatefeedback/lang/en/qbehaviour_immediatefeedback.php +question/behaviour/informationitem/lang/en/qbehaviour_informationitem.php +question/behaviour/interactive/lang/en/qbehaviour_interactive.php +question/behaviour/interactivecountback/lang/en/qbehaviour_interactivecountback.php +question/behaviour/manualgraded/lang/en/qbehaviour_manualgraded.php +question/behaviour/missing/lang/en/qbehaviour_missing.php +question/behaviour/opaque/lang/en/qbehaviour_opaque.php +question/category_form.php +question/export_form.php +question/flags.js +question/format/aiken/format.php +question/format/gift/examples.txt +question/format/qti_two/templates/choice.tpl +question/format/qti_two/templates/choiceMultiple.tpl +question/format/qti_two/templates/composite.tpl +question/format/qti_two/templates/extendedText.tpl +question/format/qti_two/templates/extendedText_simpleEssay.tpl +question/format/qti_two/templates/graphicGapMatch.tpl +question/format/qti_two/templates/imsmanifest.tpl +question/format/qti_two/templates/match.tpl +question/format/qti_two/templates/mmchoiceMultiple.tpl +question/format/qti_two/templates/notimplemented.tpl +question/format/qti_two/templates/numerical.tpl +question/format/qti_two/templates/textEntry.tpl +question/format/README.txt +question/format/webct/TODO.txt +question/import_form.php +question/qbank.js +question/qengine.js +question/todo/quizinstall.diff.txt +question/type/calculated/datasetitems_form.php +question/type/calculated/db/upgrade.php +question/type/calculated/questiontype.php +question/type/calculated/version.php +question/type/calculatedmulti/pix/icon.gif +question/type/calculatedmulti/questiontype.php +question/type/calculatedsimple/pix/icon.gif +question/type/calculatedsimple/questiontype.php +question/type/ddwtos/version.php +question/type/description/question.html +question/type/essay/display.html +question/type/essay/version.php +question/type/gapselect/edit_form_base.php +question/type/gapselect/rendererbase.php +question/type/match/db/upgrade.php +question/type/match/version.php +question/type/multianswer/db/upgrade.php +question/type/multianswer/version.php +question/type/multichoice/db/upgrade.php +question/type/multichoice/version.php +question/type/numerical/db/upgrade.php +question/type/numerical/display.html +question/type/numerical/version.php +question/type/opaque/lang/en/qtype_opaque.php +question/type/opaque/settings.php +question/type/randomsamatch/version.php +question/type/truefalse/version.php