Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Question formats: Difference between revisions

From MoodleDocs
Line 84: Line 84:


===Cloning the '''default_questiontype->save_question()''' implications===
===Cloning the '''default_questiontype->save_question()''' implications===
===saving the question common elements===   
====saving the question common elements====   
the format.php clone in a certain way the '''default_questiontype->save_question()'''  
the '''format.php''' clone in a certain way the '''default_questiontype->save_question()'''  
:by saving the question common elements
by saving the question common elements.
However the '''format.php''' do not verify or validate these common elements the same way that '''question/type/questiontype->save_question()'''do.
'''format.php''' let to each '''filetype/format.php''' the responsability to verify or validate these common question elements.
A more stable code will be to centralized the verification and validation of the question common elements to '''questiontype->save_question().'''
A better solution will be to separate the three steps of questiontype->save_question().
* verification and validation of the question common elements
* question saving in the database
* call to '''qtype/questiontype->save_question_options()'''
by creating two new functions
* '''questiontype->validate_question_common_elements()'''
* '''questiontype->save_question_common_elements()'''
With these two additional functions, '''format.php''' could process the saving of questions by a call to
* '''questiontype->validate_question_common_elements()'''
* '''questiontype->save_question_common_elements()'''
* '''qtype->save_question_options()'''
and have the complete control for the treatment of errors or notices at the return of these functions.
The '''questiontype->save_question().''' code flow is not the same as the that format one.
====saving the question options elements====  
====saving the question options elements====  
  '''format.php''' calls the specific '''qtype->save_question_options()''' function.  
  '''format.php''' calls the specific '''qtype->save_question_options()''' function.  

Revision as of 04:32, 15 June 2006

Importing or exporting questions

Questions coming from other Moodle courses or from other e-learning systems (i.e. Blackboard, Webct etc.) can be imported in Moodle. Similarlay Moodle offers a process to export questions to other systems in different format ( XML, QTI etc.). The import and export code is mostly written in format.php files located in a directory specific to the type of format files from which the import or export is done.

  • typically
    • question/format/aiken/format.php
    • question/format/blackboard/format.php
    • question/format/qti2/format.php
    • question/format/xml/format.php

there is a default class qformat_default defined in question/format.php and the process is controlled by

  • question/import.php
  • question/export.php

The main difficulty in coding these specific format.php files is that the developpers should be aware of

  • the coding format of the import or export files (XML, QTI etc.)
  • the parameters needed for the various question types already installed of Moodle and the new types that could easily be introduced in the near future due to the reworking of the question Moodle code By Gustav Delius and his group.

Where to find the information to code for import/export format.php files.

As we are developping new questiontypes or new import functions from external files, we need to safeguard the default_questiontype->save_question() from importing bad question data. We must well document these question parameters and get stronger validation before saving a new question.

The most exhaustive developper documentations rely on the knowledge of the database tables, the tags definition and a good comprehension of the few comments inserted in the code.

Efforts have been made to document the database (i.e. Gustav Delius has work a lot on the question part) but as usual solving the bugs and developping new features took most of the energy.

For the description of the different question parameters you should look at the developper docs Quiz database structure and the quiz_questions table that have been renamed question when the question code has been replaced as independent from the quiz in moodle 1.6.

These docs illustrate well the difficulty to maintain an up-to-date, I had to correct it (at least I try...) for the modifications done by Gustav himself in the database .

The format.php code flow for import

When importing questions

  • the import.php let select the file and import format
    • pass the control to format.php and format/$format/format.php
$format being the selected file format ( Blackboard, XML etc.)
       require("format.php");  // Parent class
       require("format/$format/format.php");
       $classname = "qformat_$format";
       $qformat = new $classname();
       if (! $qformat->importpreprocess($category,$course)) {  // Do anything before that we need to
           error( $txt->importerror ,
                     "$CFG->wwwroot/question/import.php?courseid={$course->id}&category=$category->id");
       }
       if (! $qformat->importprocess($importfile, $params->matchgrades) ) {  // Process the uploaded file
           error( $txt->importerror ,
                 "$CFG->wwwroot/question/import.php?courseid={$course->id}&category=$category->id");
       }
       if (! $qformat->importpostprocess()) {                  // In case anything needs to be done after
  • format.php call format/$format/format.php (i.e. the the specific format.php)
to read the imput file and return the questions (if any) that are in the imported files
        if (! $questions = $this->readquestions($lines)) {   // Extract all the questions
           notify( get_string('noquestionsinfile','quiz') );
           return false;
       }
       notify( get_string('importingquestions','quiz',count($questions)) );
  • get list of valid answer grades
        $grades = get_grade_options();
       $gradeoptionsfull = $grades->gradeoptionsfull;
  • Process some data and store each question
  • check for answer grades validity (must match fixed list of grades)
  • store question general parameters DIRECTLY in the dadabase
           $question->category = $this->category->id;
           $question->stamp = make_unique_id_code();  // Set the unique code (not to be changed)
           if (!$question->id = insert_record("question", $question)) {
               error( get_string('cannotinsert','quiz') );
           }
           $this->questionids[] = $question->id;
  • save the options using the qtype->save_question_options() function
$QTYPES being the different questiontypes (shortanwer,truefalse etc.)
           global $QTYPES;
           $result = $QTYPES[$question->qtype]
                   ->save_question_options($question);
  • diplay errors or notices
           if (!empty($result->error)) {
               notify($result->error);
               return false;
           }
           if (!empty($result->notice)) {
               notify($result->notice);
               return true;
           }
  • if noerrors and no notices
Give the question a unique version stamp determined by question_hash()
           set_field('question', 'version', question_hash($question), 'id', $question->id);

Cloning the default_questiontype->save_question() implications

saving the question common elements

the format.php clone in a certain way the default_questiontype->save_question() by saving the question common elements. However the format.php do not verify or validate these common elements the same way that question/type/questiontype->save_question()do. format.php let to each filetype/format.php the responsability to verify or validate these common question elements.

A more stable code will be to centralized the verification and validation of the question common elements to questiontype->save_question().
A better solution will be to separate the three steps of questiontype->save_question().
* verification and validation of the question common elements 
* question saving in the database
* call to qtype/questiontype->save_question_options()
by creating two new functions
* questiontype->validate_question_common_elements()
* questiontype->save_question_common_elements()

With these two additional functions, format.php could process the saving of questions by a call to

* questiontype->validate_question_common_elements()
* questiontype->save_question_common_elements()
* qtype->save_question_options()

and have the complete control for the treatment of errors or notices at the return of these functions. The questiontype->save_question(). code flow is not the same as the that format one.

saving the question options elements

format.php calls the specific qtype->save_question_options() function. 

This is the regular way to save these options that were retrieved from the imported file. This should be the correct way to implement a stable code and it will work correctly if ALL the necessary data supplementary to have a valid question of the questiontype that is currently saved, is handled by a one call to the regular specific qtype/questiontype->save_question_options(). This is the case for almost all actual questiontypes implemented in Moodle, one of the exceptions being calculated questiontype. The solution found in older Moodle version was to create a special save_question_options() in the extended filetype/format.php file (ex. $QTYPES[CALCULATED] = new qformat_webct_modified_calculated_qtype();) to handle the saving of the data items elements. This imply that for each new file format you need to create a new code or copy the qformat_webct_modified_calculated_qtype one. A better solution would be to modify the calculated/questiontype.php->save_question_options() function so that it could save all the data ( options and data items).

This could be done by checking if the dataitemsdefs and the associated data items are set in $question

See also

Lesson question types - both Lesson and Quiz can import the basic Moodle question types.