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
 
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Question development}}
==Importing or exporting questions==
==Importing or exporting questions==
{{Questiontype developer docs}}
 
Questions coming from other Moodle courses or from other e-learning systems (i.e. Blackboard, Webct etc.) can be imported in Moodle.
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.).
Similarly, 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.
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.
* examples:
* examples:
** '''question/format/aiken/format.php'''
** '''question/format/aiken/format.php'''
Line 13: Line 16:
* '''question/export.php'''
* '''question/export.php'''


The simplest and most comprehensive import/export type is probably the Moodle XML format. It is worth studying this file (question/format/xml/format.php) along with the parent class (question/format.php) to get an understanding of what is going on. Some other custom formats circumvent the normal rules and structure and should be studied with caution.
Import/Export formats are a pluggable resource and will automatically be "discovered" and made available to users simply by adding the plugin to question/format. Cross-support for optional questiontype plugins was added in 1.9 and support for language files (specifically a help file) has been implemented in Moodle 2.0.
 
=== Developing an import/export plugin ===
 
The simplest and most comprehensive import/export type is probably the Moodle XML format. There are also a few option plugins in contrib (plugins/question/format) that you can look at. It is worth studying these file (question/format/xml/format.php) along with the parent class (question/format.php) to get an understanding of what is going on. Some other custom formats circumvent the normal rules and structure and should be studied with caution.


Some things to note:
Some things to note:
* Study the question/format.php file to establish which methods must be overridden.  
* Study the question/format.php file to establish which methods must be overridden.  
* Each format.php file can support import, export or both indicated by the '''provide_import()''' and '''provide_export()''' methods
* Each format.php file can support import, export or both indicated by the '''provide_import()''' and '''provide_export()''' methods which must be overridden to return ''true'' as required. 
* Do not read or write directly to the database, this is handled for you by the parent class
* Do not read or write directly to the database, this is handled for you by the parent class
* when importing, question objects need to be in a format suitable for use by the questiontype->save_options() method (see question/type/questiontype.php class). The easiest way to get this information is to do a '''print_r($question);''' at the start of the '''save_options()''' method for the appropriate question type when a question is saved. The imported object must be the same format.
* when importing, question objects need to be in a format suitable for use by the questiontype->save_options() method (see question/type/questiontype.php class). The easiest way to get this information is to do a '''print_r($question);''' at the start of the '''save_options()''' method for the appropriate question type when a question is saved. The imported object must be the same format.
* when importing, obtain 'empty' question objects from the '''defaultquestion()''' method, which sets all required properties to their default values.
* when importing, always obtain 'empty' question objects from the '''defaultquestion()''' method, which sets all required properties to their default values.
* for exporting the $question object is supplied to the format class. Again, '''print_r($question)''' can be used to learn the format.
* for exporting the populated $question object is supplied to the format class. Again, '''print_r($question)''' can be used to learn the format.
 
* You should add a help file for the plugin using the structure lang/en_utf8/help/''myformat''/''myformat''.html where ''myformat'' is the name of your import/export plugin (Moodle 2.0).
 
 
==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);
::Process the next question until the last question in the file
:Return to the question or quiz editing.
===Cloning the '''default_questiontype->save_question()''' implications===
Comments by --[[User:Pierre Pichet|Pierre Pichet]] 08:25, 20 June 2006 (WST)
====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 centralize the verification and validation of the question common elements to '''questiontype->save_question().'''
However the code flow of the '''questiontype->save_question()''' when creating or modifying a question by the user is not necesseraly the code flow when importing from files in '''format->save_question()''' when errors occured in one or the other process.
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, '''questiontype->save_question()''' and '''format->save_question()'''  could process the saving of questions by a call to
# '''questiontype->validate_question_common_elements()'''
## '''questiontype''' or '''format''' processing of errors and notices.
# '''questiontype->save_question_common_elements()'''
## '''questiontype''' or '''format''' processing of errors and notices.
# '''qtype->save_question_options()'''
## '''questiontype''' or '''format''' processing of errors and notices.
and each class have the complete control for the treatment of errors or notices at the return of the three common functions.
 
====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.<br/>
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()'''.<br/>
This is the case for almost all actual questiontypes implemented in Moodle, one of the exceptions being calculated questiontype.<br/>
The solution found in older Moodle versions was to create a special save_question_options() in the extended filetype/format.php file to handle the saving of the data items elements.
ex. $QTYPES[CALCULATED]= new qformat_webct_modified_calculated_qtype();)
 
This imply that for each new file format you need to create a new code or copy the qformat_webct_modified_calculated_qtype one.<br/>
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 dataitemset definitions and the associated data items are set in $question


== See also ==
== See also ==
Line 127: Line 36:
[[Category:Quiz]]
[[Category:Quiz]]
[[Category:Lesson]]
[[Category:Lesson]]
[[Category:Plugins]]

Latest revision as of 06:06, 30 January 2012

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. Similarly, 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.

  • examples:
    • 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

Import/Export formats are a pluggable resource and will automatically be "discovered" and made available to users simply by adding the plugin to question/format. Cross-support for optional questiontype plugins was added in 1.9 and support for language files (specifically a help file) has been implemented in Moodle 2.0.

Developing an import/export plugin

The simplest and most comprehensive import/export type is probably the Moodle XML format. There are also a few option plugins in contrib (plugins/question/format) that you can look at. It is worth studying these file (question/format/xml/format.php) along with the parent class (question/format.php) to get an understanding of what is going on. Some other custom formats circumvent the normal rules and structure and should be studied with caution.

Some things to note:

  • Study the question/format.php file to establish which methods must be overridden.
  • Each format.php file can support import, export or both indicated by the provide_import() and provide_export() methods which must be overridden to return true as required.
  • Do not read or write directly to the database, this is handled for you by the parent class
  • when importing, question objects need to be in a format suitable for use by the questiontype->save_options() method (see question/type/questiontype.php class). The easiest way to get this information is to do a print_r($question); at the start of the save_options() method for the appropriate question type when a question is saved. The imported object must be the same format.
  • when importing, always obtain 'empty' question objects from the defaultquestion() method, which sets all required properties to their default values.
  • for exporting the populated $question object is supplied to the format class. Again, print_r($question) can be used to learn the format.
  • You should add a help file for the plugin using the structure lang/en_utf8/help/myformat/myformat.html where myformat is the name of your import/export plugin (Moodle 2.0).

See also

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