/**#@-*/
/**#@+
- * The core question types - I don't think these constants are used any more. If so, they can be removed.
+ * The core question types.
*/
define("SHORTANSWER", "shortanswer");
define("TRUEFALSE", "truefalse");
/**#@-*/
/// QTYPES INITIATION //////////////////
-
+// These variables get initialised via calls to question_register_questiontype
+// as the question type classes are included.
+global $QTYPES, $QTYPE_MENU, $QTYPE_MANUAL, $QTYPE_EXCLUDE_FROM_RANDOM;
/**
* Array holding question type objects
*/
-global $QTYPES;
-$QTYPES = array(); // This array will be populated when the questiontype.php files are loaded below
-
+$QTYPES = array();
/**
* Array of question types names translated to the user's language
*
* be able to create directly. Some internal question types like random questions are excluded.
* The complete list of question types can be found in {@link $QTYPES}.
*/
-$QTYPE_MENU = array(); // This array will be populated when the questiontype.php files are loaded
+$QTYPE_MENU = array();
+/**
+ * String in the format "'type1','type2'" that can be used in SQL clauses like
+ * "WHERE q.type IN ($QTYPE_MANUAL)".
+ */
+$QTYPE_MANUAL = '';
+/**
+ * String in the format "'type1','type2'" that can be used in SQL clauses like
+ * "WHERE q.type NOT IN ($QTYPE_EXCLUDE_FROM_RANDOM)".
+ */
+$QTYPE_EXCLUDE_FROM_RANDOM = '';
+
+/**
+ * Add a new question type to the various global arrays above.
+ *
+ * @param object $qtype An instance of the new question type class.
+ */
+function question_register_questiontype($qtype) {
+ global $QTYPES, $QTYPE_MENU, $QTYPE_MANUAL, $QTYPE_EXCLUDE_FROM_RANDOM;
+
+ $name = $qtype->name();
+ $QTYPES[$name] = $qtype;
+ $menuname = $qtype->menu_name();
+ if ($menuname) {
+ $QTYPE_MENU[$name] = $menuname;
+ }
+ if ($qtype->is_manual_graded()) {
+ if ($QTYPE_MANUAL) {
+ $QTYPE_MANUAL .= ',';
+ }
+ $QTYPE_MANUAL .= "'$name'";
+ }
+ if (!$qtype->is_usable_by_random()) {
+ if ($QTYPE_EXCLUDE_FROM_RANDOM) {
+ $QTYPE_EXCLUDE_FROM_RANDOM .= ',';
+ }
+ $QTYPE_EXCLUDE_FROM_RANDOM .= "'$name'";
+ }
+}
require_once("$CFG->dirroot/question/type/questiontype.php");
-/*
-* Load the questiontype.php file for each question type
-* These files in turn instantiate the corresponding question type class
-* and add them to the $QTYPES array
-*/
+// Load the questiontype.php file for each question type
+// These files in turn call question_register_questiontype()
+// with a new instance of each qtype class.
$qtypenames= get_list_of_plugins('question/type');
foreach($qtypenames as $qtypename) {
// Instanciates all plug-in question types
<?php // $Id$
/////////////////
-/// CALCULATED ///
+// CALCULATED ///
/////////////////
/// QUESTION TYPE CLASS //////////////////
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['calculated']= new question_calculated_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['calculated'] = get_string("calculated", "quiz");
+question_register_questiontype(new question_calculated_qtype());
function qtype_calculated_calculate_answer($formula, $individualdata,
$tolerance, $tolerancetype, $answerlength, $answerformat='1', $unit='') {
function name() {
return 'description';
}
+
+ function is_usable_by_random() {
+ return false;
+ }
function get_question_options(&$question) {
// No options to be restored for this question type
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-// define("DESCRIPTION", "7"); // already defined in questionlib.php
-$QTYPES['description']= new description_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['description'] = get_string("description", "quiz");
-
+question_register_questiontype(new description_qtype());
?>
function name() {
return 'essay';
}
+
+ function is_manual_graded() {
+ return true;
+ }
+
+ function is_usable_by_random() {
+ return false;
+ }
function save_question_options($question) {
if ($answer = get_record("question_answers", "question", $question->id)) {
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['essay'] = new question_essay_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['essay'] = get_string("essay", "quiz");
-// Add essay to the list of manually graded questions
-$QTYPE_MANUAL = isset($QTYPE_MANUAL) ? $QTYPE_MANUAL.",'essay'" : "'essay'";
-
+question_register_questiontype(new question_essay_qtype());
?>
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['match']= new question_match_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['match'] = get_string("match", "quiz");
-
+question_register_questiontype(new question_match_qtype());
?>
function name() {
return 'missingtype';
}
+
+ function menu_name() {
+ return false;
+ }
+
+ function is_usable_by_random() {
+ return false;
+ }
function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options) {
global $CFG;
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['missingtype']= new question_missingtype_qtype();
+question_register_questiontype(new question_missingtype_qtype());
?>
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['multianswer']= new embedded_cloze_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['multianswer'] = get_string("multianswer", "quiz");
+question_register_questiontype(new embedded_cloze_qtype());
/////////////////////////////////////////////////////////////
//// ADDITIONAL FUNCTIONS
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['multichoice']= new question_multichoice_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['multichoice'] = get_string("multichoice", "quiz");
-
+question_register_questiontype(new question_multichoice_qtype());
?>
}
// INITIATION - Without this line the question type is not in use.
-$QTYPES['numerical']= new question_numerical_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['numerical'] = get_string("numerical", "quiz");
-
+question_register_questiontype(new question_numerical_qtype());
?>
class default_questiontype {
/**
- * Name of the question type
- *
- * The name returned should coincide with the name of the directory
- * in which this questiontype is located
- * @ return string
- */
+ * Name of the question type
+ *
+ * The name returned should coincide with the name of the directory
+ * in which this questiontype is located
+ *
+ * @ return string the name of this question type.
+ */
function name() {
return 'default';
}
+ /**
+ * The name this question should appear as in the create new question
+ * dropdown.
+ *
+ * @return mixed the desired string, or false to hide this question type in the menu.
+ */
+ function menu_name() {
+ $name = $this->name();
+ $menu_name = get_string($name, 'qtype_' . $name);
+ if ($menu_name[0] == '[') {
+ // Legacy behavior, if the string was not in the proper qtype_name
+ // language file, look it up in the quiz one.
+ $menu_name = get_string($this->name(), 'quiz');
+ }
+ return $menu_name;
+ }
+
+ /**
+ * @return boolean true if this question can only be graded manually.
+ */
+ function is_manual_graded() {
+ return false;
+ }
+
+ /**
+ * @return boolean true if this question type can be used by the random question type.
+ */
+ function is_usable_by_random() {
+ return true;
+ }
+
/**
* Saves or updates a question after editing by a teacher
*
/// QUESTION TYPE CLASS //////////////////
class random_qtype extends default_questiontype {
- var $excludedtypes = array("'random'", "'randomsamatch'", "'essay'", "'description'");
-
// Carries questions available as randoms sorted by category
// This array is used when needed only
var $catrandoms = array();
return 'random';
}
+ function menu_name() {
+ return false;
+ }
+
+ function is_usable_by_random() {
+ return false;
+ }
+
function get_question_options(&$question) {
// Don't do anything here, because the random question has no options.
// Everything is handled by the create- or restore_session_and_responses
}
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
+ global $QTYPE_EXCLUDE_FROM_RANDOM;
// Choose a random question from the category:
// We need to make sure that no question is used more than once in the
// quiz. Therfore the following need to be excluded:
// Need to fetch random questions from category $question->category"
// (Note: $this refers to the questiontype, not the question.)
global $CFG;
- $excludedtypes = implode(',', $this->excludedtypes);
if ($question->questiontext == "1") {
// recurse into subcategories
$categorylist = question_categorylist($question->category);
WHERE category IN ($categorylist)
AND parent = '0'
AND id NOT IN ($cmoptions->questionsinuse)
- AND qtype NOT IN ($excludedtypes)")) {
+ AND qtype NOT IN ($QTYPE_EXCLUDE_FROM_RANDOM)")) {
$this->catrandoms[$question->category][$question->questiontext] =
draw_rand_array($catrandoms, count($catrandoms)); // from bug 1889
} else {
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES[RANDOM]= new random_qtype();
+question_register_questiontype(new random_qtype());
?>
return 'randomsamatch';
}
+ function is_usable_by_random() {
+ return false;
+ }
+
function get_question_options(&$question) {
if (!$question->options = get_record('question_randomsamatch', 'question', $question->id)) {
notify('Error: Missing question options for random short answer question '.$question->id.'!');
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['randomsamatch']= new question_randomsamatch_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['randomsamatch'] = get_string("randomsamatch", "quiz");
-
+question_register_questiontype(new question_randomsamatch_qtype());
?>
*/
class question_rqp_qtype extends default_questiontype {
- /**
- * Name of the rqp question type
- *
- * @ return string 'rqp'
- */
function name() {
return 'rqp';
}
+ function menu_name() {
+ // Does not currently work, so don't include in the menu.
+ return false;
+ }
+
/**
* Save the type-specific options
*
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES[RQP]= new question_rqp_qtype();
+question_register_questiontype(new question_rqp_qtype());
?>
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['shortanswer']= new question_shortanswer_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['shortanswer'] = get_string("shortanswer", "quiz");
-
+question_register_questiontype(new question_shortanswer_qtype());
?>
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
-$QTYPES['truefalse']= new question_truefalse_qtype();
-// The following adds the questiontype to the menu of types shown to teachers
-$QTYPE_MENU['truefalse'] = get_string("truefalse", "quiz");
-
+question_register_questiontype(new question_truefalse_qtype());
?>