]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-8003 - part - Use formslib for question editing forms
authortjhunt <tjhunt>
Fri, 22 Dec 2006 15:39:40 +0000 (15:39 +0000)
committertjhunt <tjhunt>
Fri, 22 Dec 2006 15:39:40 +0000 (15:39 +0000)
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.

lang/en_utf8/qtype_truefalse.php [new file with mode: 0644]
lang/en_utf8/question.php [new file with mode: 0644]
question/edit.php
question/question.php
question/question2.php [new file with mode: 0644]
question/type/edit_question_form.php [new file with mode: 0644]
question/type/questiontype.php
question/type/truefalse/edit_truefalse_question_form.php [new file with mode: 0644]
question/type/truefalse/editquestion.html [deleted file]
question/type/truefalse/editquestion.php [deleted file]
question/type/truefalse/questiontype.php

diff --git a/lang/en_utf8/qtype_truefalse.php b/lang/en_utf8/qtype_truefalse.php
new file mode 100644 (file)
index 0000000..a06ff7a
--- /dev/null
@@ -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';
+
+?>
diff --git a/lang/en_utf8/question.php b/lang/en_utf8/question.php
new file mode 100644 (file)
index 0000000..30c08c4
--- /dev/null
@@ -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.';
+
+?>
index e70ec9436517e87fa6e7fbe97128b9377a4aaf96..d811a5a855456a22058cdc591a235df374adae6b 100644 (file)
@@ -31,6 +31,7 @@
     require_login($course->id, false);
   
     $SESSION->returnurl = $FULLME;
+    $SESSION->fromurl = $FULLME;
 
     // Print basic page layout.
 
index 158f5d00549955908f63ce95572b41a098157f5d..57f283864f112b763d61df978c32a46dd46259a7 100644 (file)
         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);
diff --git a/question/question2.php b/question/question2.php
new file mode 100644 (file)
index 0000000..2e95e91
--- /dev/null
@@ -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 T.J.Hunt@open.ac.uk
+ * @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);
+}
+?>
diff --git a/question/type/edit_question_form.php b/question/type/edit_question_form.php
new file mode 100644 (file)
index 0000000..6078f1e
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+/**
+ * A base class for question editing forms.
+ *
+ * @copyright &copy; 2006 The Open University
+ * @author T.J.Hunt@open.ac.uk
+ * @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 '';
+    }
+}
+
+?>
\ No newline at end of file
index 13740d839c955fc56d085723b7757b62027cb9e1..22b96a91536f21e103fc65e2d630235cf0e45d75 100644 (file)
@@ -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
     *
diff --git a/question/type/truefalse/edit_truefalse_question_form.php b/question/type/truefalse/edit_truefalse_question_form.php
new file mode 100644 (file)
index 0000000..b1488da
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Defines the editing form for the thruefalse question type.
+ *
+ * @copyright &copy; 2006 The Open University
+ * @author T.J.Hunt@open.ac.uk
+ * @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';
+    }
+}
+?>
\ No newline at end of file
diff --git a/question/type/truefalse/editquestion.html b/question/type/truefalse/editquestion.html
deleted file mode 100644 (file)
index 1ae0c37..0000000
+++ /dev/null
@@ -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);
-?>
diff --git a/question/type/truefalse/editquestion.php b/question/type/truefalse/editquestion.php
deleted file mode 100644 (file)
index 7de8d98..0000000
+++ /dev/null
@@ -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");
-
-?>
index d32a654e663036c80631ced3a9d1c7c746c4c885..50ad3888140cc335883d30c05dd00949dc34ae3a 100644 (file)
@@ -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\")!";