MDL-8003 - part - Use formslib for question editing forms
This commit does two things: 1. Gives question types he opion to use formslib for their editing forms, instead of the old mechanism. 2. Converts the truefalse question type to formslib.
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
<?php // $Id$
|
||||
// qtype_truefalse.php - created with Moodle 1.8dev
|
||||
|
||||
$string['correctanswer'] = 'Correct answer';
|
||||
$string['editingtruefalse'] = 'Editing a True/False question';
|
||||
$string['false'] = 'False';
|
||||
$string['feedbackfalse'] = 'Feedback (False)';
|
||||
$string['feedbacktrue'] = 'Feedback (True)';
|
||||
$string['true'] = 'True';
|
||||
$string['truefalse'] = 'True/False';
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php // $Id$
|
||||
// question.php - created with Moodle 1.8 dev
|
||||
|
||||
$string['categorydoesnotexist'] = 'This category does not exist';
|
||||
$string['editingquestion'] = 'Editing a question';
|
||||
$string['missingimportantcode'] = 'This question type is missing important code: $a.';
|
||||
$string['notenoughdatatoeditaquestion'] = 'Neither a question id, nor a category id and question type, was specified.';
|
||||
$string['questiondoesnotexist'] = 'This question does not exist';
|
||||
$string['unknownquestiontype'] = 'Unknown question type: $a.';
|
||||
|
||||
?>
|
||||
@@ -31,6 +31,7 @@
|
||||
require_login($course->id, false);
|
||||
|
||||
$SESSION->returnurl = $FULLME;
|
||||
$SESSION->fromurl = $FULLME;
|
||||
|
||||
// Print basic page layout.
|
||||
|
||||
|
||||
@@ -88,6 +88,10 @@
|
||||
error("Could not find question type: '$qtype'");
|
||||
}
|
||||
|
||||
if (!file_exists("type/$qtype/editquestion.php")) {
|
||||
redirect(str_ireplace('question.php', 'question2.php', me()));
|
||||
}
|
||||
|
||||
require_login($course->id, false);
|
||||
$coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
|
||||
require_capability('moodle/question:manage', $coursecontext);
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php // $Id$
|
||||
/**
|
||||
* Page for editing questions using the new form library.
|
||||
*
|
||||
* TODO: currently this still treats the quiz as special
|
||||
*
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package question
|
||||
*//** */
|
||||
|
||||
// Includes.
|
||||
require_once(dirname(__FILE__) . '/../config.php');
|
||||
require_once(dirname(__FILE__) . '/editlib.php');
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
|
||||
$returnurl = optional_param('returnurl', 0, PARAM_URL);
|
||||
if (!$returnurl && isset($SESSION->fromurl)) {
|
||||
$returnurl = $SESSION->fromurl;
|
||||
}
|
||||
|
||||
// Read URL parameters telling us which question to edit.
|
||||
$id = optional_param('id', 0, PARAM_INT); // question id
|
||||
$qtype = optional_param('qtype', '', PARAM_FILE);
|
||||
$categoryid = optional_param('category', 0, PARAM_INT);
|
||||
|
||||
// Validate the URL parameters.
|
||||
if ($id = optional_param('id', 0, PARAM_INT)) {
|
||||
if (!$question = get_record("question", "id", $id)) {
|
||||
print_error('questiondoesnotexist', 'question', $returnurl);
|
||||
}
|
||||
get_question_options($question);
|
||||
$submiturl = "question2.php?id=$id&returnurl=" . urlencode($returnurl);
|
||||
} else if ($categoryid && $qtype) { // only for creating new questions
|
||||
$question = new stdClass;
|
||||
$question->category = $categoryid;
|
||||
$question->qtype = $qtype;
|
||||
$submiturl = "question2.php?category=$categoryid&qtype=$qtype&returnurl=" . urlencode($returnurl);
|
||||
} else {
|
||||
print_error('notenoughdatatoeditaquestion', 'question', $returnurl);
|
||||
}
|
||||
|
||||
// Validate the question category.
|
||||
if (!$category = get_record('question_categories', 'id', $question->category)) {
|
||||
print_error('categorydoesnotexist', 'question', $returnurl);
|
||||
}
|
||||
if (!$returnurl) {
|
||||
$returnurl = "{$CFG->wwwroot}/question/edit.php?courseid={$category->course}";
|
||||
$SESSION->fromurl = $returnurl;
|
||||
}
|
||||
|
||||
// Validate the question type.
|
||||
if (!isset($QTYPES[$question->qtype])) {
|
||||
print_error('unknownquestiontype', 'question', $returnurl, $question->qtype);
|
||||
}
|
||||
$CFG->pagepath = 'question/type/' . $question->qtype;
|
||||
|
||||
// Check the user is logged in and has enough premissions.
|
||||
require_login($category->course, false);
|
||||
$coursecontext = get_context_instance(CONTEXT_COURSE, $category->course);
|
||||
require_capability('moodle/question:manage', $coursecontext);
|
||||
|
||||
// Create the question editing form.
|
||||
$mform = $QTYPES[$question->qtype]->create_editing_form($submiturl);
|
||||
if ($mform === null) {
|
||||
print_error('missingimportantcode', 'question', $returnurl, 'question editing form definition');
|
||||
}
|
||||
|
||||
if ($mform->is_cancelled()){
|
||||
redirect($returnurl);
|
||||
} else if ($data = $mform->data_submitted()){
|
||||
if (!empty($data->makecopy)) {
|
||||
$question->id = 0; // causes a new question to be created.
|
||||
$question->hidden = 0; // Copies should not be hidden
|
||||
}
|
||||
$question = $QTYPES[$qtype]->save_question($question, $data, $COURSE);
|
||||
|
||||
$strsaved = get_string('changessaved');
|
||||
if (optional_param('inpopup', 0, PARAM_BOOL)) {
|
||||
notify($strsaved, '');
|
||||
close_window(3);
|
||||
} else {
|
||||
redirect($SESSION->returnurl, $strsaved);
|
||||
}
|
||||
} else {
|
||||
// Display the question editing form
|
||||
$streditingquestion = get_string('editingquestion', 'question');
|
||||
if (isset($SESSION->modform->instance)) {
|
||||
// TODO: remove restriction to quiz
|
||||
$strediting = '<a href="' . $returnurl . '">' . get_string('editingquiz', 'quiz') . '</a> -> '.
|
||||
$streditingquestion;
|
||||
} else {
|
||||
$strediting = '<a href="edit.php?courseid='.$course->id.'">'.
|
||||
get_string("editquestions", "quiz").'</a> -> '.$streditingquestion;
|
||||
}
|
||||
print_header_simple($streditingquestion, '', $strediting);
|
||||
$mform->set_defaults($question);
|
||||
$mform->display();
|
||||
print_footer($COURSE);
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* A base class for question editing forms.
|
||||
*
|
||||
* @copyright © 2006 The Open University
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package quiz
|
||||
*//** */
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
class edit_question_form extends moodleform {
|
||||
/**
|
||||
* Build the form definition.
|
||||
*
|
||||
* This adds all the form files that the default question type supports.
|
||||
* If your question type does not support all these fields, then you can
|
||||
* override this method and remove the ones you don't want with $mform->removeElement().
|
||||
*/
|
||||
function definition() {
|
||||
global $COURSE;
|
||||
|
||||
$qtype = $this->qtype();
|
||||
$langfile = "qtype_$qtype";
|
||||
|
||||
$mform =& $this->_form;
|
||||
$renderer =& $mform->defaultRenderer();
|
||||
|
||||
// Standard fields at the start of the form.
|
||||
$mform->addElement('header', 'formheader', get_string("editing$qtype", $langfile));
|
||||
$mform->setHelpButton('formheader', array($qtype, get_string($qtype, $qtype), $qtype));
|
||||
|
||||
$mform->addElement('questioncategory', 'category', get_string('category', 'quiz'),
|
||||
array('courseid' => $COURSE->id, 'published' => true, 'only_editable' => true));
|
||||
|
||||
$mform->addElement('text', 'name', get_string('questionname', 'quiz'),
|
||||
array('size' => 50));
|
||||
$mform->setType('name', PARAM_MULTILANG);
|
||||
$mform->addRule('name', null, 'required', null, 'client');
|
||||
|
||||
$mform->addElement('htmleditor', 'questiontext', get_string('questiontext', 'quiz'),
|
||||
array('rows' => 15, 'course' => $COURSE->id));
|
||||
$mform->setType('questiontext', PARAM_RAW);
|
||||
$mform->setHelpButton('questiontext', array('questiontext', get_string('questiontext', 'quiz'), 'quiz'));
|
||||
$mform->addElement('format', 'questiontextformat', get_string('format'));
|
||||
|
||||
if (empty($images)) {
|
||||
$mform->addElement('static', 'image', get_string('imagedisplay', 'quiz'), get_string('noimagesyet'));
|
||||
} else {
|
||||
$images[''] = get_string('none');
|
||||
$mform->addElement('select', 'image', get_string('imagedisplay', 'quiz'), $images);
|
||||
$mform->setType('image', PARAM_FILE);
|
||||
}
|
||||
|
||||
$mform->addElement('text', 'defaultgrade', get_string('defaultgrade', 'quiz'),
|
||||
array('size' => 3));
|
||||
$mform->setType('defaultgrade', PARAM_INT);
|
||||
$mform->addRule('defaultgrade', null, 'required', null, 'client');
|
||||
|
||||
$mform->addElement('text', 'penalty', get_string('penaltyfactor', 'quiz'),
|
||||
array('size' => 3));
|
||||
$mform->setType('penalty', PARAM_NUMBER);
|
||||
$mform->addRule('penalty', null, 'required', null, 'client');
|
||||
$mform->setHelpButton('penalty', array('penalty', get_string('penalty', 'quiz'), 'quiz'));
|
||||
|
||||
$mform->addElement('htmleditor', 'generalfeedback', get_string('generalfeedback', 'quiz'),
|
||||
array('rows' => 10, 'course' => $COURSE->id));
|
||||
$mform->setType('generalfeedback', PARAM_RAW);
|
||||
$mform->setHelpButton('generalfeedback', array('generalfeedback', get_string('generalfeedback', 'quiz'), 'quiz'));
|
||||
|
||||
// Any questiontype specific fields.
|
||||
$this->definition_inner($mform);
|
||||
|
||||
// Standard fields at the end of the form.
|
||||
$mform->addElement('hidden', 'id');
|
||||
$mform->setType('id', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'qtype');
|
||||
$mform->setType('qtype', PARAM_ALPHA);
|
||||
|
||||
$mform->addElement('hidden', 'inpopup');
|
||||
$mform->setType('inpopup', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'versioning');
|
||||
$mform->setType('versioning', PARAM_BOOL);
|
||||
|
||||
$buttonarray = array();
|
||||
$buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('savechanges'));
|
||||
if (!empty($id)) {
|
||||
$buttonarray[] = &$mform->createElement('submit', 'makecopy', get_string('makecopy', 'quiz'));
|
||||
}
|
||||
$buttonarray[] = &$mform->createElement('reset', 'resetbutton', get_string('revert'));
|
||||
$buttonarray[] = &$mform->createElement('cancel');
|
||||
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
|
||||
$renderer->addStopFieldsetElements('buttonar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any question-type specific form fields.
|
||||
*
|
||||
* @param object $mform the form being built.
|
||||
*/
|
||||
function definition_inner(&$mform) {
|
||||
// By default, do nothing.
|
||||
}
|
||||
|
||||
function set_defaults($question) {
|
||||
global $QTYPES;
|
||||
$QTYPES[$question->qtype]->set_default_options($question);
|
||||
parent::set_defaults($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this in the subclass to question type name.
|
||||
* @return the question type name, should be the same as the name() method in the question type class.
|
||||
*/
|
||||
function qtype() {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -71,6 +71,40 @@ class default_questiontype {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the question editing form definition. This looks for a
|
||||
* class called edit_{$this->name()}_question_form in the file
|
||||
* {$CFG->docroot}/question/type/{$this->name()}/edit_{$this->name()}_question_form.php
|
||||
* and if it exists returns an instance of it.
|
||||
*
|
||||
* @param string $submiturl passed on to the constructor call.
|
||||
* @return object an instance of the form definition, or null if one could not be found.
|
||||
*/
|
||||
function create_editing_form($submiturl) {
|
||||
global $CFG;
|
||||
require_once("{$CFG->dirroot}/question/type/edit_question_form.php");
|
||||
$definition_file = "{$CFG->dirroot}/question/type/{$this->name()}/edit_{$this->name()}_question_form.php";
|
||||
if (!(is_readable($definition_file) && is_file($definition_file))) {
|
||||
return null;
|
||||
}
|
||||
require_once($definition_file);
|
||||
$classname = "edit_{$this->name()}_question_form";
|
||||
if (!class_exists($classname)) {
|
||||
return null;
|
||||
}
|
||||
return new $classname($submiturl);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param $question
|
||||
*/
|
||||
function set_default_options(&$question) {
|
||||
$question->penalty = 0.1;
|
||||
$question->defaultgrade = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves or updates a question after editing by a teacher
|
||||
*
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Defines the editing form for the thruefalse question type.
|
||||
*
|
||||
* @copyright © 2006 The Open University
|
||||
* @author [email protected]
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package questions
|
||||
*//** */
|
||||
|
||||
/**
|
||||
* truefalse editing form definition.
|
||||
*/
|
||||
class edit_truefalse_question_form extends edit_question_form {
|
||||
/**
|
||||
* Add question-type specific form fields.
|
||||
*
|
||||
* @param object $mform the form being built.
|
||||
*/
|
||||
function definition_inner(&$mform) {
|
||||
$mform->addElement('select', 'correctanswer', get_string('correctanswer', 'qtype_truefalse'),
|
||||
array(0 => get_string('false', 'qtype_truefalse'), 1 => get_string('true', 'qtype_truefalse')));
|
||||
|
||||
$mform->addElement('htmleditor', 'feedbacktrue', get_string('feedbacktrue', 'qtype_truefalse'));
|
||||
$mform->setType('feedbacktrue', PARAM_RAW);
|
||||
|
||||
$mform->addElement('htmleditor', 'feedbackfalse', get_string('feedbackfalse', 'qtype_truefalse'));
|
||||
$mform->setType('feedbackfalse', PARAM_RAW);
|
||||
}
|
||||
|
||||
function set_defaults($question) {
|
||||
if (!empty($question->options->trueanswer)) {
|
||||
$trueanswer = $question->options->answers[$question->options->trueanswer];
|
||||
$question->correctanswer = ($trueanswer->fraction != 0);
|
||||
$question->feedbacktrue = $trueanswer->feedback;
|
||||
$question->feedbackfalse = $question->options->answers[$question->options->falseanswer]->feedback;
|
||||
}
|
||||
parent::set_defaults($question);
|
||||
}
|
||||
|
||||
function qtype() {
|
||||
return 'truefalse';
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
$QTYPES[$question->qtype]->print_question_form_start($question, array(), $course, $usehtmleditor);
|
||||
?>
|
||||
<tr valign="top">
|
||||
<td align="right"><b><?php print_string("correctanswer", "quiz") ?>:</b></td>
|
||||
<td align="left">
|
||||
<?php $menu[0] = get_string("false", "quiz");
|
||||
$menu[1] = get_string("true", "quiz");
|
||||
choose_from_menu($menu, "answer", "$question->answer", ""); ?>
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td align="right"><b><?php print_string("feedback", "quiz") ?> (<?php print_string("true", "quiz") ?>):</b></td>
|
||||
<td align="left">
|
||||
<textarea name="feedbacktrue" rows="2" cols="50" wrap="virtual"><?php p($true->feedback) ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td align="right"><b><?php print_string("feedback", "quiz") ?> (<?php print_string("false", "quiz") ?>):</b></td>
|
||||
<td align="left">
|
||||
<textarea name="feedbackfalse" rows="2" cols="50"><?php p($false->feedback) ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$QTYPES[$question->qtype]->print_replacement_options($question, $course, $contextquiz);
|
||||
$QTYPES[$question->qtype]->print_question_form_end($question);
|
||||
?>
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php // $Id$
|
||||
|
||||
if (!empty($question->id)) {
|
||||
$options = get_record("question_truefalse", "question", "$question->id");
|
||||
}
|
||||
if (!empty($options->trueanswer)) {
|
||||
$true = get_record("question_answers", "id", $options->trueanswer);
|
||||
} else {
|
||||
$true->fraction = 1;
|
||||
$true->feedback = "";
|
||||
}
|
||||
if (!empty($options->falseanswer)) {
|
||||
$false = get_record("question_answers", "id", "$options->falseanswer");
|
||||
} else {
|
||||
$false->fraction = 0;
|
||||
$false->feedback = "";
|
||||
}
|
||||
|
||||
if ($true->fraction > $false->fraction) {
|
||||
$question->answer = 1;
|
||||
} else {
|
||||
$question->answer = 0;
|
||||
}
|
||||
|
||||
print_heading_with_help(get_string("editingtruefalse", "quiz"), "truefalse", "quiz");
|
||||
require("$CFG->dirroot/question/type/truefalse/editquestion.html");
|
||||
|
||||
?>
|
||||
@@ -22,7 +22,7 @@ class question_truefalse_qtype extends default_questiontype {
|
||||
// Save answer 'True'
|
||||
if ($true = array_shift($oldanswers)) { // Existing answer, so reuse it
|
||||
$true->answer = get_string("true", "quiz");
|
||||
$true->fraction = $question->answer;
|
||||
$true->fraction = $question->correctanswer;
|
||||
$true->feedback = $question->feedbacktrue;
|
||||
if (!update_record("question_answers", $true)) {
|
||||
$result->error = "Could not update quiz answer \"true\")!";
|
||||
@@ -32,7 +32,7 @@ class question_truefalse_qtype extends default_questiontype {
|
||||
unset($true);
|
||||
$true->answer = get_string("true", "quiz");
|
||||
$true->question = $question->id;
|
||||
$true->fraction = $question->answer;
|
||||
$true->fraction = $question->correctanswer;
|
||||
$true->feedback = $question->feedbacktrue;
|
||||
if (!$true->id = insert_record("question_answers", $true)) {
|
||||
$result->error = "Could not insert quiz answer \"true\")!";
|
||||
@@ -43,7 +43,7 @@ class question_truefalse_qtype extends default_questiontype {
|
||||
// Save answer 'False'
|
||||
if ($false = array_shift($oldanswers)) { // Existing answer, so reuse it
|
||||
$false->answer = get_string("false", "quiz");
|
||||
$false->fraction = 1 - (int)$question->answer;
|
||||
$false->fraction = 1 - (int)$question->correctanswer;
|
||||
$false->feedback = $question->feedbackfalse;
|
||||
if (!update_record("question_answers", $false)) {
|
||||
$result->error = "Could not insert quiz answer \"false\")!";
|
||||
@@ -53,7 +53,7 @@ class question_truefalse_qtype extends default_questiontype {
|
||||
unset($false);
|
||||
$false->answer = get_string("false", "quiz");
|
||||
$false->question = $question->id;
|
||||
$false->fraction = 1 - (int)$question->answer;
|
||||
$false->fraction = 1 - (int)$question->correctanswer;
|
||||
$false->feedback = $question->feedbackfalse;
|
||||
if (!$false->id = insert_record("question_answers", $false)) {
|
||||
$result->error = "Could not insert quiz answer \"false\")!";
|
||||
|
||||
Reference in New Issue
Block a user