[ Index ]
 

Code source de Claroline 188

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/claroline/exercise/export/qti2/ -> qti2_classes.php (source)

   1  <?php // $Id: qti2_classes.php,v 1.15.2.2 2007/09/25 08:41:47 seb Exp $
   2  if ( count( get_included_files() ) == 1 ) die( '---' );
   3  /**
   4   * CLAROLINE
   5   *
   6   * @version 1.8 $Revision: 1.15.2.2 $
   7   *
   8   * @copyright (c) 2001-2006 Universite catholique de Louvain (UCL)
   9   *
  10   * @license http://www.gnu.org/copyleft/gpl.html (GPL) GENERAL PUBLIC LICENSE
  11   *
  12   * @author Claro Team <cvs@claroline.net>
  13   *
  14   */
  15  $path = dirname(__FILE__);
  16  include_once $path . '/../../lib/answer_multiplechoice.class.php';
  17  include_once $path . '/../../lib/answer_truefalse.class.php';
  18  include_once $path . '/../../lib/answer_fib.class.php';
  19  include_once $path . '/../../lib/answer_matching.class.php';
  20  
  21  include_once get_path('incRepositorySys') . '/lib/xml.lib.php';
  22  
  23  class Qti2Question extends Question
  24  {
  25      /**
  26       * Include the correct answer class and create answer
  27       */
  28      function setAnswer()
  29      {
  30          switch($this->type)
  31          {
  32              case 'MCUA' :
  33                  $this->answer = new Qti2AnswerMultipleChoice($this->id, false);
  34                  break;
  35              case 'MCMA' :
  36                  $this->answer = new Qti2AnswerMultipleChoice($this->id, true);
  37                  break;
  38              case 'TF' :
  39                  $this->answer = new Qti2AnswerTrueFalse($this->id, false);
  40                  break;
  41              case 'FIB' :
  42                  $this->answer = new Qti2AnswerFillInBlanks($this->id);
  43                  break;
  44              case 'MATCHING' :
  45                  $this->answer = new Qti2AnswerMatching($this->id);
  46                  break;
  47              default :
  48                  $this->answer = null;
  49                  break;
  50          }
  51  
  52          return true;
  53      }
  54      /**
  55       * allow to import the question
  56       *
  57       * @param questionArray is an array that must contain all the information needed to build the question
  58       */
  59  
  60      function import($questionInfo)
  61      {
  62          if( is_array($questionInfo) )
  63          {
  64              if( isset($questionInfo['title']) )       $this->setTitle($questionInfo['title']);
  65              if( isset($questionInfo['statement']) )   $this->setDescription($questionInfo['statement']."\n".'<!-- content: imsqti -->');
  66              $this->setType($questionInfo['type']);
  67  
  68              if( !empty($questionInfo['attached_file_url']) )
  69              {
  70                  $this->importAttachment($questionInfo['tempdir'].$questionInfo['attached_file_url']);
  71              }
  72          }
  73          else
  74          {
  75              return false;
  76          }
  77      }
  78  
  79      function importAttachment($importedFilePath)
  80      {
  81          // copy file in a tmp directory known by object,
  82          // attached file will be copied to its final destination when saving question
  83          $dir = $this->tmpQuestionDirSys;
  84          $filename = basename($importedFilePath);
  85  
  86          if( !is_dir( $dir ) )
  87          {
  88              // create it
  89              if( !claro_mkdir($dir, CLARO_FILE_PERMISSIONS) )
  90              {
  91                  claro_failure::set_failure('cannot_create_tmp_dir');
  92                  return false;
  93              }
  94          }
  95  
  96          if( claro_move_file($importedFilePath, $dir.$filename) )
  97          {
  98              $this->attachment = $filename;
  99              return true;
 100          }
 101          else
 102          {
 103              return false;
 104          }
 105      }
 106  }
 107  
 108  class Qti2AnswerMultipleChoice extends answerMultipleChoice
 109  {
 110      /**
 111       * Return the XML flow for the possible answers.
 112       *
 113       */
 114      function qti2ExportResponses($questionIdent, $questionStatment)
 115      {
 116          $out = "\n" . '    <![CDATA[' . $questionStatment . ']]>' . "\n";
 117          $out .= '    <choiceInteraction responseIdentifier="' . $questionIdent . '" >' . "\n";
 118  
 119          foreach ($this->answerList as $current_answer)
 120          {
 121              $out .= '      <simpleChoice identifier="answer_' . $current_answer['id'] . '" fixed="false"><![CDATA[' . $current_answer['answer'] . ']]>';
 122              if (isset($current_answer['comment']) && $current_answer['comment'] != '')
 123              {
 124                  $out .= '<feedbackInline identifier="answer_' . $current_answer['id'] . '"><![CDATA[' . $current_answer['comment'] . ']]></feedbackInline>';
 125              }
 126              $out .= '</simpleChoice>'. "\n";
 127          }
 128  
 129          $out .= '    </choiceInteraction>'. "\n";
 130  
 131          return $out;
 132      }
 133  
 134      /**
 135       * Return the XML flow of answer ResponsesDeclaration
 136       *
 137       */
 138      function qti2ExportResponsesDeclaration($questionIdent)
 139      {
 140  
 141          if ($this->multipleAnswer == 'MCMA')  $cardinality = 'multiple'; else $cardinality = 'single';
 142  
 143          $out = '  <responseDeclaration identifier="' . $questionIdent . '" cardinality="' . $cardinality . '" baseType="identifier">' . "\n";
 144  
 145          //Match the correct answers
 146  
 147          $out .= '    <correctResponse>'. "\n";
 148  
 149          foreach($this->answerList as $current_answer)
 150          {
 151              if ($current_answer['correct'])
 152              {
 153                  $out .= '      <value>answer_'. $current_answer['id'] .'</value>'. "\n";
 154              }
 155          }
 156          $out .= '    </correctResponse>'. "\n";
 157  
 158          //Add the grading
 159  
 160          $out .= '    <mapping>'. "\n";
 161  
 162          foreach($this->answerList as $current_answer)
 163          {
 164              if (isset($current_answer['grade']))
 165              {
 166                  $out .= '      <mapEntry mapKey="answer_'. $current_answer['id'] .'" mappedValue="'.$current_answer['grade'].'" />'. "\n";
 167              }
 168          }
 169          $out .= '    </mapping>'. "\n";
 170  
 171          $out .= '  </responseDeclaration>'. "\n";
 172  
 173          return $out;
 174      }
 175  
 176      /**
 177       * allow to import the answers, feedbacks, and grades of a question
 178       * @param questionArray is an array that must contain all the information needed to build the question
 179  
 180       */
 181  
 182      function import($questionArray)
 183      {
 184          $answerArray = $questionArray['answer'];
 185  
 186          $this->answerList = array(); //re-initialize answer object content
 187  
 188          foreach ($answerArray as $key => $answer)
 189          {
 190              if (!isset($answer['feedback'])) $answer['feedback'] = "";
 191  
 192              if (!isset($questionArray['weighting'][$key]))
 193              {
 194                  if (isset($questionArray['default_weighting']))
 195                  {
 196                      $grade = castToFloat($questionArray['default_weighting']);
 197                  }
 198                  else
 199                  {
 200                      $grade = 0;
 201                  }
 202              }
 203              else
 204              {
 205                  $grade = castToFloat($questionArray['weighting'][$key]);
 206              }
 207  
 208              if (in_array($key,$questionArray['correct_answers'])) $is_correct = 1; else $is_correct = 0;
 209  
 210              $addedAnswer = array(
 211                              'answer' => $answer['value'],
 212                              'correct' => $is_correct,
 213                              'grade' => $grade,
 214                              'comment' => $answer['feedback'],
 215                              );
 216  
 217              $this->answerList[] = $addedAnswer;
 218          }
 219      }
 220  }
 221  
 222  class Qti2AnswerTrueFalse extends AnswerTrueFalse
 223  {
 224      /**
 225       * Return the XML flow for the possible answers.
 226       *
 227       */
 228      function qti2ExportResponses($questionIdent, $questionStatment)
 229      {
 230          $out = "\n" . '    <![CDATA[' . $questionStatment . ']]>'. "\n";
 231          $out .= '    <choiceInteraction responseIdentifier="' . $questionIdent . '" >' . "\n";
 232  
 233          //set true answer
 234  
 235          $out .= '      <simpleChoice identifier="answer_true" fixed="false"><![CDATA[' . get_lang('True') . ']]>' . "\n";
 236          if (isset($this->trueFeedback) && $this->trueFeedback != '')
 237          {
 238              $out .= '<feedbackInline identifier="answer_true"><![CDATA[' . $this->trueFeedback . ']]></feedbackInline>'. "\n";
 239          }
 240          $out .= '</simpleChoice>'. "\n";
 241  
 242          //set false answer
 243  
 244          $out .= '      <simpleChoice identifier="answer_false" fixed="false"><![CDATA[' . get_lang('False') . ']]>' . "\n";
 245          if (isset($this->falseFeedback) && $this->falseFeedback != '')
 246          {
 247              $out .= '<feedbackInline identifier="answer_false"><![CDATA[' . $this->falseFeedback . ']]></feedbackInline>'. "\n";
 248          }
 249          $out .= '</simpleChoice>'. "\n";
 250  
 251  
 252          $out .= '    </choiceInteraction>'. "\n";
 253          return $out;
 254      }
 255  
 256  	function qti2ExportResponsesDeclaration($questionIdent)
 257      {
 258          $out = '  <responseDeclaration identifier="' . $questionIdent . '" cardinality="single" baseType="identifier">' . "\n";
 259  
 260          //Match the correct answers
 261  
 262          $out .= '    <correctResponse>'. "\n";
 263  
 264  
 265          if ($this->correctAnswer=='TRUE')
 266          {
 267              $out .= '      <value>answer_true</value>'. "\n";
 268          }
 269          else
 270          {
 271              $out .= '      <value>answer_false</value>'. "\n";
 272          }
 273  
 274          $out .= '    </correctResponse>'. "\n";
 275  
 276          //Add the grading
 277  
 278          $out .= '    <mapping>'. "\n";
 279  
 280          if (isset($this->trueGrade))
 281          {
 282              $out .= '      <mapEntry mapKey="answer_true" mappedValue="'.$this->trueGrade.'" />'. "\n";
 283          }
 284  
 285          if (isset($this->falseGrade))
 286          {
 287              $out .= '      <mapEntry mapKey="answer_false" mappedValue="'.$this->falseGrade.'" />'. "\n";
 288          }
 289  
 290          $out .= '    </mapping>'. "\n";
 291  
 292          $out .= '  </responseDeclaration>'. "\n";
 293  
 294          return $out;
 295  
 296      }
 297  }
 298  
 299  
 300  
 301  class Qti2AnswerFillInBlanks extends answerFillInBlanks
 302  {
 303      /**
 304       * Export the text with missing words.
 305       *
 306       *
 307       */
 308      function qti2ExportResponses($questionIdent, $questionStatment)
 309      {
 310          $out = '';
 311  
 312          $out .= '<prompt><![CDATA[' . $questionStatment . ']]></prompt>'. "\n";
 313  
 314          switch ($this->type)
 315          {
 316              case TEXTFIELD_FILL :
 317              {
 318                  $text = $this->answerText;
 319  
 320                  foreach ($this->answerList as $key=>$answer)
 321                  {
 322                      $text = str_replace('['.$answer.']','<textEntryInteraction responseIdentifier="fill_'.$key.'" expectedLength="'.strlen($answer).'"/>', $text);
 323                  }
 324                  $out .= $text;
 325              }
 326              break;
 327  
 328              case LISTBOX_FILL :
 329              {
 330                  $replacementList = array();
 331  
 332                  foreach ($this->answerList as $answerKey => $answer)
 333                  {
 334                      //build inlinechoice list
 335  
 336                      $inlineChoiceList = '';
 337  
 338                      //1-start interaction tag
 339  
 340                      $inlineChoiceList .= '<inlineChoiceInteraction responseIdentifier="fill_'.$answerKey.'" >'. "\n";
 341  
 342                      //2- add wrong answer array
 343  
 344                      foreach ($this->wrongAnswerList as $choiceKey => $wrongAnswer)
 345                      {
 346                          $inlineChoiceList .= '  <inlineChoice identifier="choice_w_'.$answerKey.'_'.$choiceKey.'"><![CDATA['.$wrongAnswer.']]></inlineChoice>'. "\n";
 347                      }
 348  
 349                      //3- add correct answers array
 350                      foreach ($this->answerList as $choiceKey => $correctAnswer)
 351                      {
 352                          $inlineChoiceList .= '  <inlineChoice identifier="choice_c_'.$answerKey.'_'.$choiceKey.'"><![CDATA['.$correctAnswer.']]></inlineChoice>'. "\n";
 353                      }
 354  
 355                      //4- finish interaction tag
 356  
 357                      $inlineChoiceList .= '</inlineChoiceInteraction>';
 358  
 359                      $replacementList['['.$answer.']'] =  $inlineChoiceList;
 360                  }
 361  
 362                  $out .= strtr($this->answerText, $replacementList);
 363              }
 364              break;
 365          }
 366  
 367          return $out;
 368  
 369      }
 370  
 371      /**
 372       *
 373       */
 374      function qti2ExportResponsesDeclaration($questionIdent)
 375      {
 376  
 377          $out = '';
 378  
 379          foreach ($this->answerList as $answerKey=>$answer)
 380          {
 381              $out .= '  <responseDeclaration identifier="fill_' . $answerKey . '" cardinality="single" baseType="identifier">' . "\n";
 382              $out .= '    <correctResponse>'. "\n";
 383  
 384              if ($this->type == TEXTFIELD_FILL)
 385              {
 386                  $out .= '      <value><![CDATA['.$answer.']]></value>'. "\n";
 387              }
 388              else
 389              {
 390                  //find correct answer key to apply in manifest and output it
 391  
 392                  foreach ($this->answerList as $choiceKey=>$correctAnswer)
 393                  {
 394                      if ($correctAnswer==$answer)
 395                      {
 396                          $out .= '      <value>choice_c_'.$answerKey.'_'.$choiceKey.'</value>'. "\n";
 397                      }
 398                  }
 399              }
 400  
 401              $out .= '    </correctResponse>'. "\n";
 402  
 403              if (isset($this->gradeList[$answerKey]))
 404              {
 405                  $out .= '    <mapping>'. "\n";
 406                  $out .= '      <mapEntry mapKey="'.$answer.'" mappedValue="'.$this->gradeList[$answerKey].'"/>'. "\n";
 407                  $out .= '    </mapping>'. "\n";
 408              }
 409  
 410              $out .= '  </responseDeclaration>'. "\n";
 411          }
 412  
 413         return $out;
 414      }
 415  
 416      /**
 417       * allow to import the answers, feedbacks, and grades of a question
 418       *
 419       * @param questionArray is an array that must contain all the information needed to build the question
 420  
 421       */
 422  
 423      function import($questionArray)
 424      {
 425          // $questionArray['answer'] should be empty for this question type
 426          $this->answerText = $questionArray['response_text'];
 427  
 428          if ($questionArray['subtype'] == "TEXTFIELD_FILL")
 429          {
 430              $this->type = TEXTFIELD_FILL;
 431          }
 432          if ($questionArray['subtype'] == "LISTBOX_FILL")
 433          {
 434              $this->wrongAnswerList = $questionArray['wrong_answers'];
 435              $this->type = LISTBOX_FILL;
 436          }
 437  
 438          //build correct_answsers array
 439          if( isset($questionArray['weighting']) && is_array($questionArray['weighting']) )
 440          {
 441              $this->gradeList = array();
 442              foreach( $questionArray['weighting'] as $key => $value )
 443              {
 444                  $this->gradeList[$key] = castToFloat($value);
 445              }
 446          }
 447      }
 448  }
 449  
 450  class Qti2AnswerMatching extends answerMatching
 451  {
 452      /**
 453       * Export the question part as a matrix-choice, with only one possible answer per line.
 454       */
 455      function qti2ExportResponses($questionIdent, $questionStatment)
 456      {
 457          $maxAssociation = max(count($this->leftList), count($this->rightList));
 458  
 459          $out = "";
 460  
 461          $out .= '<matchInteraction responseIdentifier="' . $questionIdent . '" maxAssociations="'. $maxAssociation .'">'. "\n";
 462          $out .= '<prompt><![CDATA[' . $questionStatment . ']]></prompt>'. "\n";
 463  
 464          //add left column
 465  
 466          $out .= '  <simpleMatchSet>'. "\n";
 467  
 468          foreach ($this->leftList as $leftKey=>$leftElement)
 469          {
 470              $out .= '    <simpleAssociableChoice identifier="left_'.$leftKey.'" ><![CDATA['. $leftElement['answer'] .']]></simpleAssociableChoice>'. "\n";
 471          }
 472  
 473          $out .= '  </simpleMatchSet>'. "\n";
 474  
 475          //add right column
 476  
 477          $out .= '  <simpleMatchSet>'. "\n";
 478  
 479          $i = 0;
 480  
 481          foreach($this->rightList as $rightKey=>$rightElement)
 482          {
 483              $out .= '    <simpleAssociableChoice identifier="right_'.$i.'" ><![CDATA['. $rightElement['answer'] .']]></simpleAssociableChoice>'. "\n";
 484              $i++;
 485          }
 486  
 487          $out .= '  </simpleMatchSet>'. "\n";
 488  
 489          $out .= '</matchInteraction>'. "\n";
 490  
 491          return $out;
 492      }
 493  
 494      /**
 495       *
 496       */
 497      function qti2ExportResponsesDeclaration($questionIdent)
 498      {
 499          $out =  '  <responseDeclaration identifier="' . $questionIdent . '" cardinality="multiple" baseType="identifier">' . "\n";
 500          $out .= '    <correctResponse>' . "\n";
 501  
 502          $gradeArray = array();
 503  
 504          foreach ($this->leftList as $leftKey=>$leftElement)
 505          {
 506              $i=0;
 507              foreach ($this->rightList as $rightKey=>$rightElement)
 508              {
 509                  if( ($leftElement['match'] == $rightElement['code']))
 510                  {
 511                      $out .= '      <value>left_' . $leftKey . ' right_'.$i.'</value>'. "\n";
 512  
 513                      $gradeArray['left_' . $leftKey . ' right_'.$i] = $leftElement['grade'];
 514                  }
 515                  $i++;
 516              }
 517          }
 518          $out .= '    </correctResponse>'. "\n";
 519          $out .= '    <mapping>' . "\n";
 520          foreach ($gradeArray as $gradeKey=>$grade)
 521          {
 522              $out .= '          <mapEntry mapKey="'.$gradeKey.'" mappedValue="'.$grade.'"/>' . "\n";
 523          }
 524          $out .= '    </mapping>' . "\n";
 525          $out .= '  </responseDeclaration>'. "\n";
 526  
 527          return $out;
 528      }
 529  
 530      /**
 531       * allow to import the answers, feedbacks, and grades of a question
 532       *
 533       * @param questionArray is an array that must contain all the information needed to build the question
 534  
 535       */
 536  
 537      function import($questionArray)
 538      {
 539          $answerArray = $questionArray['answer'];
 540  
 541          //This tick to remove examples in the answers!!!!
 542          $this->leftList = array();
 543          $this->rightList = array();
 544  
 545          //find right and left column
 546          $right_column = array_pop($answerArray);
 547          $left_column  = array_pop($answerArray);
 548  
 549          //1- build answers
 550  
 551          foreach ($right_column as $right_key => $right_element)
 552          {
 553              $code = $this->addRight($right_element);
 554  
 555              foreach ($left_column as $left_key => $left_element)
 556              {
 557                  $matched_pattern = $left_key." ".$right_key;
 558                  $matched_pattern_inverted = $right_key." ".$left_key;
 559  
 560                  if (in_array($matched_pattern, $questionArray['correct_answers']) || in_array($matched_pattern_inverted, $questionArray['correct_answers']))
 561                  {
 562                      if (isset($questionArray['weighting'][$matched_pattern]))
 563                      {
 564                          $grade = castToFloat($questionArray['weighting'][$matched_pattern]);
 565                      }
 566                      else
 567                      {
 568                          $grade = 0;
 569                      }
 570                      $this->addLeft($left_element, $code, $grade);
 571                  }
 572              }
 573          }
 574  
 575          $this->save();
 576      }
 577  }
 578  ?>


Généré le : Thu Nov 29 14:38:42 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics