From 82cb7fe78c3a65a903e49cd60b4229b27d92bb48 Mon Sep 17 00:00:00 2001 From: thepurpleblob Date: Thu, 9 Aug 2007 08:43:23 +0000 Subject: [PATCH] MDL-6367: Backporting quiz import/export for plugins --- question/format.php | 74 +++++++++++++++++++++++++++----- question/format/xml/format.php | 77 +++++++++------------------------- 2 files changed, 84 insertions(+), 67 deletions(-) diff --git a/question/format.php b/question/format.php index 4a774339251..0cfd17bfd46 100644 --- a/question/format.php +++ b/question/format.php @@ -1,13 +1,13 @@ importerrors++; } + /** + * Import for questiontype plugins + * Do not override. + * @param data mixed The segment of data containing the question + * @param question object processed (so far) by standard import code if appropriate + * @param extra mixed any additional format specific data that may be passed by the format + * @return object question object suitable for save_options() or false if cannot handle + */ + function try_importing_using_qtypes( $data, $question=null, $extra=null ) { + global $QTYPES; + + // work out what format we are using + $formatname = substr( get_class( $this ), strlen('qformat_')); + $methodname = "import_from_$formatname"; + + // loop through installed questiontypes checking for + // function to handle this question + foreach ($QTYPES as $qtype) { + if (method_exists( $qtype, $methodname)) { + if ($question = $qtype->$methodname( $data, $question, $this, $extra )) { + return $question; + } + } + } + return false; + } + /** * Perform any required pre-processing * @return boolean success @@ -193,7 +220,7 @@ class qformat_default { } } if (!$answersvalid) { - notify( get_string('matcherror','quiz') ); + notify(get_string('matcherror', 'quiz')); continue; } else { @@ -312,6 +339,7 @@ class qformat_default { $question->correctfeedback = ''; $question->partiallycorrectfeedback = ''; $question->incorrectfeedback = ''; + $question->answernumbering = 'abc'; $question->penalty = 0.1; // this option in case the questiontypes class wants @@ -393,6 +421,32 @@ class qformat_default { * EXPORT FUNCTIONS *******************/ + /** + * Provide export functionality for plugin questiontypes + * Do not override + * @param name questiontype name + * @param question object data to export + * @param extra mixed any addition format specific data needed + * @return string the data to append to export or false if error (or unhandled) + */ + function try_exporting_using_qtypes( $name, $question, $extra=null ) { + global $QTYPES; + + // work out the name of format in use + $formatname = substr( get_class( $this ), strlen( 'qformat_' )); + $methodname = "export_to_$formatname"; + + if (array_key_exists( $name, $QTYPES )) { + $qtype = $QTYPES[ $name ]; + if (method_exists( $qtype, $methodname )) { + if ($data = $qtype->$methodname( $question, $this, $extra )) { + return $data; + } + } + } + return false; + } + /** * Return the files extension appropriate for this type * override if you don't want .txt diff --git a/question/format/xml/format.php b/question/format/xml/format.php index 49cfeb7243c..27d340888b3 100755 --- a/question/format/xml/format.php +++ b/question/format/xml/format.php @@ -172,6 +172,7 @@ class qformat_xml extends qformat_default { $single = $this->getpath( $question, array('#','single',0,'#'), 'true' ); $qo->single = $this->trans_single( $single ); $shuffleanswers = $this->getpath( $question, array('#','shuffleanswers',0,'#'), 'false' ); + $qo->answernumbering = $this->getpath( $question, array('#','answernumbering',0,'#'), 'abc' ); $qo->shuffleanswers = $this->trans_single($shuffleanswers); $qo->correctfeedback = $this->getpath( $question, array('#','correctfeedback',0,'#','text',0,'#'), '', true ); $qo->partiallycorrectfeedback = $this->getpath( $question, array('#','partiallycorrectfeedback',0,'#','text',0,'#'), '', true ); @@ -287,35 +288,6 @@ class qformat_xml extends qformat_default { return $qo; } - /** - * import regexp type question - * @param array question question array from xml tree - * @return object question object - */ - function import_regexp( $question ) { - // get common parts - $qo = $this->import_headers( $question ); - - // header parts particular to shortanswer - $qo->qtype = regexp; - - // get usecase - $qo->usecase = $question['#']['usecase'][0]['#']; - - // run through the answers - $answers = $question['#']['answer']; - $a_count = 0; - foreach ($answers as $answer) { - $ans = $this->import_answer( $answer ); - $qo->answer[$a_count] = $ans->answer; - $qo->fraction[$a_count] = $ans->fraction; - $qo->feedback[$a_count] = $ans->feedback; - ++$a_count; - } - - return $qo; - } - /** * import description type question * @param array question question array from xml tree @@ -563,9 +535,6 @@ class qformat_xml extends qformat_default { elseif ($question_type=='shortanswer') { $qo = $this->import_shortanswer( $question ); } - //elseif ($question_type=='regexp') { - // $qo = $this->import_regexp( $question ); - //} elseif ($question_type=='numerical') { $qo = $this->import_numerical( $question ); } @@ -588,9 +557,14 @@ class qformat_xml extends qformat_default { $qo = $this->import_category( $question ); } else { - $notsupported = get_string( 'xmltypeunsupported','quiz',$question_type ); - $this->error( $notsupported ); - $qo = null; + // try for plugin support + // no default question, as the plugin can call + // import_headers() itself if it wants to + if (!$qo=$this->try_importing_using_qtypes( $question )) { + $notsupported = get_string( 'xmltypeunsupported','quiz',$question_type ); + $this->error( $notsupported ); + $qo = null; + } } // stick the result in the $questions array @@ -628,9 +602,6 @@ class qformat_xml extends qformat_default { case SHORTANSWER: $name = 'shortanswer'; break; - //case regexp: - // $name = 'regexp'; - // break; case NUMERICAL: $name = 'numerical'; break; @@ -650,7 +621,7 @@ class qformat_xml extends qformat_default { $name = 'calculated'; break; default: - $name = 'unknown'; + $name = false; } return $name; } @@ -791,10 +762,10 @@ class qformat_xml extends qformat_default { // add comment $expout .= "\n\n\n"; - // check question type - make sure valid - $question_type = $this->get_qtype( $question->qtype ); - if ($question_type=='unknown') { - $expout .= "\n\n"; + // check question type + if (!$question_type = $this->get_qtype( $question->qtype )) { + // must be a plugin then, so just accept the name supplied + $question_type = $question->qtype; } // add opening tag @@ -872,6 +843,7 @@ class qformat_xml extends qformat_default { $expout .= " ".$this->writetext($question->options->correctfeedback, 3)."\n"; $expout .= " ".$this->writetext($question->options->partiallycorrectfeedback, 3)."\n"; $expout .= " ".$this->writetext($question->options->incorrectfeedback, 3)."\n"; + $expout .= " {$question->options->answernumbering}\n"; foreach($question->options->answers as $answer) { $percent = $answer->fraction * 100; $expout .= " \n"; @@ -894,18 +866,6 @@ class qformat_xml extends qformat_default { $expout .= " \n"; } break; - //case regexp: - //$expout .= " {$question->options->usecase}\n "; - // foreach($question->options->answers as $answer) { - // $percent = 100 * $answer->fraction; - // $expout .= " \n"; - // $expout .= $this->writetext( $answer->answer,3,false ); - // $expout .= " \n"; - // $expout .= $this->writetext( $answer->feedback,4,false ); - // $expout .= " \n"; - // $expout .= " \n"; - // } - // break; case NUMERICAL: foreach ($question->options->answers as $answer) { $tolerance = $answer->tolerance; @@ -1025,8 +985,11 @@ class qformat_xml extends qformat_default { } break; default: - // should not get here - error( 'Unsupported question type detected in strange circumstances!' ); + // try support by optional plugin + if (!$data = $this->try_exporting_using_qtypes( $question->qtype, $question )) { + error( "Unsupported question type $question->qtype" ); + } + $expout .= $data; } // close the question tag