Dokeos PHP Cross Reference Learning Management Systems

Source: /main/exercice/question.class.php - 1742 lines - 66056 bytes - Summary - Text - Print

Description: File containing the Question class.

   1  <?php
   2  // $Id: question.class.php 22257 2009-07-20 17:50:09Z juliomontoya $
   3  
   4  /* For licensing terms, see /dokeos_license.txt */
   5  
   6  /**
   7   *     File containing the Question class.
   8   *     @package dokeos.exercise
   9   *     @author Olivier Brouckaert
  10   *     @version $Id: question.class.php 22257 2009-07-20 17:50:09Z juliomontoya $
  11   */
  12  if (!class_exists('Question')):
  13  
  14  // answer types
  15   define('UNIQUE_ANSWER', 1);
  16   define('MULTIPLE_ANSWER', 2);
  17   define('FILL_IN_BLANKS', 3);
  18   define('MATCHING', 4);
  19   define('FREE_ANSWER', 5);
  20   define('HOT_SPOT', 6);
  21   define('HOT_SPOT_ORDER', 7);
  22   define('REASONING', 8);
  23   define('HOT_SPOT_DELINEATION', 9);
  24  
  25  //define('DOKEOS_QUIZGALLERY', true);
  26  
  27   /**
  28     CLASS QUESTION
  29    *
  30    *     This class allows to instantiate an object of type Question
  31    *
  32    *     @author Olivier Brouckaert, original author
  33    *     @author Patrick Cool, LaTeX support
  34    *     @package dokeos.exercise
  35    */
  36   abstract class Question {
  37  
  38    var $id;
  39    var $question;
  40    var $description;
  41    var $weighting;
  42    var $position;
  43    var $type;
  44    var $level;
  45    var $category;
  46    var $picture;
  47    var $exerciseList;  // array with the list of exercises which this question is in
  48    var $mediaPosition;
  49  
  50    static $typePicture = 'new_question.png';
  51    static $explanationLangVar = '';
  52    static $questionTypes = array(
  53        UNIQUE_ANSWER => array('unique_answer.class.php', 'UniqueAnswer'),
  54        MULTIPLE_ANSWER => array('multiple_answer.class.php', 'MultipleAnswer'),
  55        FILL_IN_BLANKS => array('fill_blanks.class.php', 'FillBlanks'),
  56        MATCHING => array('matching.class.php', 'Matching'),
  57        FREE_ANSWER => array('freeanswer.class.php', 'FreeAnswer'),
  58        REASONING => array('reasoning.class.php', 'Reasoning'),
  59        HOT_SPOT => array('hotspot.class.php', 'HotSpot'),
  60        HOT_SPOT_DELINEATION => array('hotspot_delineation.class.php', 'HotspotDelineation')
  61    );
  62  
  63    /**
  64     * constructor of the class
  65     *
  66     * @author - Olivier Brouckaert
  67     */
  68    function Question() {
  69     $this->id = 0;
  70     $this->question = '';
  71     $this->description = '';
  72     $this->weighting = 20;
  73     $this->position = 1;
  74     $this->picture = '';
  75     $this->level = 1;
  76     $this->category = 0;
  77     $this->mediaPosition = 'right';
  78     $this->exerciseList = array();
  79    }
  80  
  81    /**
  82     * reads question informations from the data base
  83     *
  84     * @author - Olivier Brouckaert
  85     * @param - integer $id - question ID
  86     * @return - boolean - true if question exists, otherwise false
  87     */
  88    static function read($id) {
  89     global $_course;
  90  
  91     $db_name = !empty($_course['dbName']) ? $_course['dbName'] : $_SESSION['dbName'];
  92     $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST, $db_name);
  93     $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $db_name);
  94     $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $db_name);
  95  
  96     $sql_count = "SELECT count(*) as count FROM $TBL_QUESTIONS WHERE id='" . Database::escape_string($id) . "'";
  97     $rs_count = Database::query($sql_count, __FILE__, __LINE__);
  98     $count = Database::result($rs_count, 0);
  99  
 100     // if the question has been found
 101     if ($count > 0) {
 102      $sql = "SELECT question,description,ponderation,position,type,picture,level,category,media_position FROM $TBL_QUESTIONS WHERE id='" . Database::escape_string($id) . "' order by position";
 103      $result = Database::query($sql, __FILE__, __LINE__);
 104  
 105      $object = Database::fetch_object($result);
 106      $type = $object->type;
 107   /* if($type == 9) {//Hotspot delineation is still in development
 108          $type = 6;
 109      }*/
 110      $objQuestion = Question::getInstance($type);
 111      $objQuestion->id = $id;
 112      $objQuestion->question = $object->question;
 113      $objQuestion->description = $object->description;
 114      $objQuestion->weighting = $object->ponderation;
 115      $objQuestion->position = $object->position;
 116      $objQuestion->type = $object->type;
 117      $objQuestion->picture = $object->picture;
 118      $objQuestion->level = (int) $object->level;
 119      $objQuestion->category = $object->category;
 120      $objQuestion->mediaPosition = $object->media_position;
 121  
 122      $sql = "SELECT exercice_id FROM $TBL_EXERCICE_QUESTION WHERE question_id='" . intval($id) . "'";
 123      $quiz_result = api_sql_query($sql, __FILE__, __LINE__);
 124  
 125      // fills the array with the exercises which this question is in
 126      while ($quiz_object = Database::fetch_object($quiz_result)) {
 127       $objQuestion->exerciseList[] = $quiz_object->exercice_id;
 128      }
 129      return $objQuestion;
 130     }
 131     // question not found
 132     return false;
 133    }
 134  
 135    /**
 136     * Set media position field 
 137     */
 138    function selectMediaPosition() {      
 139     return $this->mediaPosition;
 140    }
 141  
 142    /**
 143     * returns the question ID
 144     *
 145     * @author - Olivier Brouckaert
 146     * @return - integer - question ID
 147     */
 148    function selectId() {
 149     return $this->id;
 150    }
 151  
 152    /**
 153     * returns the question title
 154     *
 155     * @author - Olivier Brouckaert
 156     * @return - string - question title
 157     */
 158    function selectTitle() {
 159     $this->question = api_parse_tex($this->question);
 160     return $this->question;
 161    }
 162  
 163    /**
 164     * returns the question description
 165     *
 166     * @author - Olivier Brouckaert
 167     * @return - string - question description
 168     */
 169    function selectDescription() {
 170     $this->description = api_parse_tex($this->description);
 171     return $this->description;
 172    }
 173  
 174    /**
 175     * returns the question weighting
 176     *
 177     * @author - Olivier Brouckaert
 178     * @return - integer - question weighting
 179     */
 180    function selectWeighting() {
 181     return $this->weighting;
 182    }
 183  
 184    /**
 185     * returns the question position
 186     *
 187     * @author - Olivier Brouckaert
 188     * @return - integer - question position
 189     */
 190    function selectPosition() {
 191     return $this->position;
 192    }
 193  
 194    /**
 195     * returns the answer type
 196     *
 197     * @author - Olivier Brouckaert
 198     * @return - integer - answer type
 199     */
 200    function selectType() {
 201     return $this->type;
 202    }
 203  
 204    /**
 205     * returns the level of the question
 206     *
 207     * @author - Nicolas Raynaud
 208     * @return - integer - level of the question, 0 by default.
 209     */
 210    function selectLevel() {
 211     return $this->level;
 212    }
 213  
 214     /**
 215     * returns the category of the question
 216     *
 217     * @author - Nicolas Raynaud
 218     * @return - category of the question, 0 by default.
 219     */
 220    function selectCategory() {
 221     return $this->category;
 222    }
 223  
 224  
 225    /**
 226     * returns the picture name
 227     *
 228     * @author - Olivier Brouckaert
 229     * @return - string - picture name
 230     */
 231    function selectPicture() {
 232     return $this->picture;
 233    }
 234  
 235    /**
 236     * returns the array with the exercise ID list
 237     *
 238     * @author - Olivier Brouckaert
 239     * @return - array - list of exercise ID which the question is in
 240     */
 241    function selectExerciseList() {
 242     return $this->exerciseList;
 243    }
 244  
 245    /**
 246     * returns the number of exercises which this question is in
 247     *
 248     * @author - Olivier Brouckaert
 249     * @return - integer - number of exercises
 250     */
 251    function selectNbrExercises() {
 252     return sizeof($this->exerciseList);
 253    }
 254  
 255    /**
 256     * changes the question title
 257     *
 258     * @author - Olivier Brouckaert
 259     * @param - string $title - question title
 260     */
 261    function updateTitle($title) {
 262     $this->question = $title;
 263    }
 264  
 265    /**
 266     * changes the question description
 267     *
 268     * @author - Olivier Brouckaert
 269     * @param - string $description - question description
 270     */
 271    function updateDescription($description) {
 272     $this->description = $description;
 273    }
 274  
 275    /**
 276     * changes the question weighting
 277     *
 278     * @author - Olivier Brouckaert
 279     * @param - integer $weighting - question weighting
 280     */
 281    function updateWeighting($weighting) {
 282     $this->weighting = $weighting;
 283    }
 284  
 285    /**
 286     * changes the question position
 287     *
 288     * @author - Olivier Brouckaert
 289     * @param - integer $position - question position
 290     */
 291    function updatePosition($position) {
 292     $this->position = $position;
 293    }
 294  
 295    /**
 296     * changes the question level
 297     *
 298     * @author - Nicolas Raynaud
 299     * @param - integer $level - question level
 300     */
 301    function updateLevel($level) {
 302     $this->level = $level;
 303    }
 304  
 305    /**
 306     * changes the question category
 307     *
 308     * @author - Nicolas Raynaud
 309     * @param - integer $level - question level
 310     */
 311    function updateCategory($category) {
 312     $this->category = $category;
 313    }
 314  
 315    /**
 316     * changes the answer type. If the user changes the type from "unique answer" to "multiple answers"
 317     * (or conversely) answers are not deleted, otherwise yes
 318     *
 319     * @author - Olivier Brouckaert
 320     * @param - integer $type - answer type
 321     */
 322    function updateType($type) {
 323     global $TBL_REPONSES;
 324  
 325     // if we really change the type
 326     if ($type != $this->type) {
 327      // if we don't change from "unique answer" to "multiple answers" (or conversely)
 328      if (!in_array($this->type, array(UNIQUE_ANSWER, MULTIPLE_ANSWER)) || !in_array($type, array(UNIQUE_ANSWER, MULTIPLE_ANSWER))) {
 329       // removes old answers
 330       $sql = "DELETE FROM $TBL_REPONSES WHERE question_id='" . Database::escape_string($this->id) . "'";
 331       api_sql_query($sql, __FILE__, __LINE__);
 332      }
 333  
 334      $this->type = $type;
 335     }
 336    }
 337  
 338    function updateMediaPosition($mediaPosition) {
 339     $this->mediaPosition = $mediaPosition;
 340    }
 341  
 342    /**
 343     * adds a picture to the question
 344     *
 345     * @author - Olivier Brouckaert
 346     * @param - string $Picture - temporary path of the picture to upload
 347     * @param - string $PictureName - Name of the picture
 348     * @return - boolean - true if uploaded, otherwise false
 349     */
 350    function uploadPicture($Picture, $PictureName) {
 351     global $picturePath, $_course, $_user;
 352  
 353     // if the question has got an ID
 354     if ($this->id) {
 355  
 356      $extension = pathinfo($PictureName, PATHINFO_EXTENSION);
 357      $this->picture = 'quiz-' . $this->id . '.jpg';
 358      if ($extension == 'gif' || $extension == 'png') {
 359       $o_img = new image($Picture);
 360       $o_img->send_image('JPG', $picturePath . '/' . $this->picture);
 361       $document_id = add_document($_course, '/images/' . $this->picture, 'file', filesize($picturePath . '/' . $this->picture), $this->picture);
 362      } else {
 363       move_uploaded_file($Picture, $picturePath . '/' . $this->picture) ? true : false;
 364      }
 365      $document_id = add_document($_course, '/images/' . $this->picture, 'file', filesize($picturePath . '/' . $this->picture), $this->picture);
 366      if ($document_id) {
 367       return api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $_user['user_id']);
 368      }
 369     }
 370  
 371     return false;
 372    }
 373  
 374    /**
 375     * Resizes a picture || Warning!: can only be called after uploadPicture, or if picture is already available in object.
 376     *
 377     * @author - Toon Keppens
 378     * @param - string $Dimension - Resizing happens proportional according to given dimension: height|width|any
 379     * @param - integer $Max - Maximum size
 380     * @return - boolean - true if success, false if failed
 381     */
 382    function resizePicture($Dimension, $Max) {
 383     global $picturePath;
 384  
 385     // if the question has an ID
 386     if ($this->id) {
 387      // Get dimensions from current image.
 388      $current_img = imagecreatefromjpeg($picturePath . '/' . $this->picture);
 389  
 390      $current_image_size = getimagesize($picturePath . '/' . $this->picture);
 391      $current_height = imagesy($current_img);
 392      $current_width = imagesx($current_img);
 393  
 394      if ($current_image_size[0] < $Max && $current_image_size[1] < $Max)
 395       return true;
 396      elseif ($current_height == "")
 397       return false;
 398  
 399      // Resize according to height.
 400      if ($Dimension == "height") {
 401       $resize_scale = $current_height / $Max;
 402       $new_height = $Max;
 403       $new_width = ceil($current_width / $resize_scale);
 404      }
 405  
 406      // Resize according to width
 407      if ($Dimension == "width") {
 408       $resize_scale = $current_width / $Max;
 409       $new_width = $Max;
 410       $new_height = ceil($current_height / $resize_scale);
 411      }
 412  
 413      // Resize according to height or width, both should not be larger than $Max after resizing.
 414      if ($Dimension == "any") {
 415       if ($current_height > $current_width || $current_height == $current_width) {
 416        $resize_scale = $current_height / $Max;
 417        $new_height = $Max;
 418        $new_width = ceil($current_width / $resize_scale);
 419       }
 420       if ($current_height < $current_width) {
 421        $resize_scale = $current_width / $Max;
 422        $new_width = $Max;
 423        $new_height = ceil($current_height / $resize_scale);
 424       }
 425      }
 426  
 427      // Create new image
 428      $new_img = imagecreatetruecolor($new_width, $new_height);
 429      $bgColor = imagecolorallocate($new_img, 255, 255, 255);
 430      imagefill($new_img, 0, 0, $bgColor);
 431  
 432      // Resize image
 433      imagecopyresized($new_img, $current_img, 0, 0, 0, 0, $new_width, $new_height, $current_width, $current_height);
 434  
 435      // Write image to file
 436      $result = imagejpeg($new_img, $picturePath . '/' . $this->picture, 100);
 437  
 438      // Delete temperory images, clear memory
 439      imagedestroy($current_img);
 440      imagedestroy($new_img);
 441  
 442      if ($result) {
 443       return true;
 444      } else {
 445       return false;
 446      }
 447     }
 448    }
 449  
 450    /**
 451     * deletes the picture
 452     *
 453     * @author - Olivier Brouckaert
 454     * @return - boolean - true if removed, otherwise false
 455     */
 456    function removePicture() {
 457     global $picturePath;
 458  
 459     // if the question has got an ID and if the picture exists
 460     if ($this->id) {
 461      $picture = $this->picture;
 462      $this->picture = '';
 463  
 464      return @unlink($picturePath . '/' . $picture) ? true : false;
 465     }
 466  
 467     return false;
 468    }
 469  
 470    /**
 471     * exports a picture to another question
 472     *
 473     * @author - Olivier Brouckaert
 474     * @param - integer $questionId - ID of the target question
 475     * @return - boolean - true if copied, otherwise false
 476     */
 477    function exportPicture($questionId) {
 478     global $TBL_QUESTIONS, $picturePath;
 479  
 480     // if the question has got an ID and if the picture exists
 481     if ($this->id && !empty($this->picture)) {
 482      $picture = explode('.', $this->picture);
 483      $Extension = $picture[sizeof($picture) - 1];
 484      $picture = 'quiz-' . $questionId . '.' . $Extension;
 485  
 486      $sql = "UPDATE $TBL_QUESTIONS SET picture='" . Database::escape_string($picture) . "' WHERE id='" . Database::escape_string($questionId) . "'";
 487      api_sql_query($sql, __FILE__, __LINE__);
 488  
 489      return @copy($picturePath . '/' . $this->picture, $picturePath . '/' . $picture) ? true : false;
 490     }
 491  
 492     return false;
 493    }
 494  
 495    /**
 496     * saves the picture coming from POST into a temporary file
 497     * Temporary pictures are used when we don't want to save a picture right after a form submission.
 498     * For example, if we first show a confirmation box.
 499     *
 500     * @author - Olivier Brouckaert
 501     * @param - string $Picture - temporary path of the picture to move
 502     * @param - string $PictureName - Name of the picture
 503     */
 504    function setTmpPicture($Picture, $PictureName) {
 505     global $picturePath;
 506  
 507     $PictureName = explode('.', $PictureName);
 508     $Extension = $PictureName[sizeof($PictureName) - 1];
 509  
 510     // saves the picture into a temporary file
 511     @move_uploaded_file($Picture, $picturePath . '/tmp.' . $Extension);
 512    }
 513  
 514    /**
 515     * moves the temporary question "tmp" to "quiz-$questionId"
 516     * Temporary pictures are used when we don't want to save a picture right after a form submission.
 517     * For example, if we first show a confirmation box.
 518     *
 519     * @author - Olivier Brouckaert
 520     * @return - boolean - true if moved, otherwise false
 521     */
 522    function getTmpPicture() {
 523     global $picturePath;
 524  
 525     // if the question has got an ID and if the picture exists
 526     if ($this->id) {
 527      if (file_exists($picturePath . '/tmp.jpg')) {
 528       $Extension = 'jpg';
 529      } elseif (file_exists($picturePath . '/tmp.gif')) {
 530       $Extension = 'gif';
 531      } elseif (file_exists($picturePath . '/tmp.png')) {
 532       $Extension = 'png';
 533      }
 534  
 535      $this->picture = 'quiz-' . $this->id . '.' . $Extension;
 536  
 537      return @rename($picturePath . '/tmp.' . $Extension, $picturePath . '/' . $this->picture) ? true : false;
 538     }
 539  
 540     return false;
 541    }
 542  
 543    /**
 544     * updates the question in the data base
 545     * if an exercise ID is provided, we add that exercise ID into the exercise list
 546     *
 547     * @author - Olivier Brouckaert
 548     * @param - integer $exerciseId - exercise ID if saving in an exercise
 549     */
 550    function save($exerciseId=0) {
 551     global $_course, $_user;
 552  
 553     $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
 554     $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
 555     $id = $this->id;
 556     $question = $this->question;
 557     $description = $this->description;
 558     $weighting = $this->weighting;
 559     $position = $this->position;
 560     $type = $this->type;
 561     $picture = $this->picture;
 562     $level = $this->level;
 563     $mediaPosition = $this->mediaPosition;
 564  
 565     if (($_SESSION['fromTpl'] == '1') && ($_SESSION['editQn'] == '')) {
 566       $id = '';
 567       $exerciseId = $_REQUEST['exerciseId'];
 568     }
 569  
 570     // question already exists
 571     if (!empty($id)) {
 572      $sql = "UPDATE $TBL_QUESTIONS SET
 573                      question         ='" . Database::escape_string($question) . "',
 574                      description        ='" . Database::escape_string(Security::remove_XSS(api_html_entity_decode($description), COURSEMANAGERLOWSECURITY)) . "',
 575                      ponderation        ='" . Database::escape_string($weighting) . "',
 576                      position        ='" . Database::escape_string($position) . "',
 577                      type            ='" . Database::escape_string($type) . "',
 578                      picture            ='" . Database::escape_string($picture) . "',
 579                      level            ='" . Database::escape_string($level) . "',
 580                      media_position  ='" . Database::escape_string($mediaPosition) . "' 
 581                      WHERE id='" . Database::escape_string($id) . "'";
 582      api_sql_query($sql, __FILE__, __LINE__);
 583      if (!empty($exerciseId)) {
 584       api_item_property_update($_course, TOOL_QUIZ, $id, 'QuizQuestionUpdated', $_user['user_id']);
 585      }
 586      if (api_get_setting('search_enabled') == 'true') {
 587       if ($exerciseId != 0) {
 588        //$this->search_engine_edit($exerciseId);
 589       } else {
 590        /**
 591         * actually there is *not* an user interface for
 592         * creating questions without a relation with an exercise
 593         */
 594       }
 595      }
 596     } else {// creates a new question
 597      $sql = "SELECT max(position) FROM $TBL_QUESTIONS as question, $TBL_EXERCICE_QUESTION as test_question WHERE question.id=test_question.question_id AND test_question.exercice_id='" . Database::escape_string($exerciseId) . "'";
 598  
 599      $result = api_sql_query($sql);
 600      $current_position = Database::result($result, 0, 0);
 601      $this->updatePosition($current_position + 1);
 602      $position = $this->position;
 603  
 604      $sql = "INSERT INTO $TBL_QUESTIONS(question,description,ponderation,position,type,picture,level,media_position) VALUES(
 605                      '" . Database::escape_string(Security::remove_XSS($question,COURSEMANAGERLOWSECURITY)) . "',
 606                      '" . Database::escape_string(Security::remove_XSS(api_html_entity_decode($description), COURSEMANAGERLOWSECURITY)) . "',
 607                      '" . Database::escape_string($weighting) . "',
 608                      '" . Database::escape_string($position) . "',
 609                      '" . Database::escape_string($type) . "',
 610                      '" . Database::escape_string($picture) . "',
 611                      '" . Database::escape_string($level) . "',
 612                      '" . Database::escape_string($mediaPosition) . "'
 613                      )";
 614  
 615      api_sql_query($sql, __FILE__, __LINE__);
 616  
 617      $this->id = Database::get_last_insert_id();
 618  
 619      api_item_property_update($_course, TOOL_QUIZ, $this->id, 'QuizQuestionAdded', $_user['user_id']);
 620  
 621      // If hotspot, create first answer
 622      if ($type == HOT_SPOT || $type == HOT_SPOT_ORDER) {
 623       $TBL_ANSWERS = Database::get_course_table(TABLE_QUIZ_ANSWER);
 624  
 625       $sql = "INSERT INTO $TBL_ANSWERS (`id` , `question_id` , `answer` , `correct` , `comment` , `ponderation` , `position` , `hotspot_coordinates` , `hotspot_type` ) VALUES ('1', '" . Database::escape_string($this->id) . "', '', NULL , '', '10' , '1', '0;0|0|0', 'square')";
 626       api_sql_query($sql, __FILE__, __LINE__);
 627      }
 628  
 629      if (api_get_setting('search_enabled') == 'true') {
 630       if ($exerciseId != 0) {
 631        //$this->search_engine_edit($exerciseId, TRUE);
 632       } else {
 633        /**
 634         * actually there is *not* an user interface for
 635         * creating questions without a relation with an exercise
 636         */
 637       }
 638      }
 639     }
 640  
 641     // if the question is created in an exercise
 642     if ($exerciseId) {
 643      /*
 644        $sql = 'UPDATE '.Database::get_course_table(TABLE_LP_ITEM).'
 645        SET max_score = '.intval($weighting).'
 646        WHERE item_type = "'.TOOL_QUIZ.'"
 647        AND path='.intval($exerciseId);
 648        api_sql_query($sql,__FILE__,__LINE__);
 649       */
 650      // adds the exercise into the exercise list of this question
 651      $this->addToList($exerciseId, TRUE);
 652     }
 653    }
 654  
 655    function create_question_from_an_attached_file ($quiz_id, $question_name, $ponderation = 0, $type = 1, $level = 1) {
 656      $tbl_quiz_question = Database::get_course_table(TABLE_QUIZ_QUESTION);
 657      $tbl_quiz_rel_question = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
 658  
 659      // Get the max position
 660      $sql = "SELECT max(position) as max_position FROM $tbl_quiz_question q INNER JOIN $tbl_quiz_rel_question r
 661      ON q.id = r.question_id AND exercice_id = '".Database::escape_string($quiz_id)."'";
 662      $rs_max = Database::query($sql, __FILE__, __LINE__);
 663      $row_max = Database::fetch_object($rs_max);
 664      $max_position = $row_max->max_position +1;
 665  
 666      $question_description = '<table height="100%" width="98%" cellspacing="2" cellpadding="0" style="font-family: Comic Sans MS; font-size: 16px;"><tbody><tr><td height="323px" align="center"><img height="310px" src="../img/instructor-idea.jpg" alt="" /></td></tr></tbody></table>';
 667  
 668      // Insert the new question
 669      $sql = "INSERT INTO $tbl_quiz_question (question,description,ponderation,position,type,level)
 670      VALUES('".Database::escape_string($question_name)."', '".Database::escape_string($question_description)."', '".$ponderation."', '".$max_position."',
 671       '".$type."', '".$level."')";
 672      $rs = Database::query($sql, __FILE__, __LINE__);
 673      // Get the question ID
 674      $question_id = Database::get_last_insert_id();
 675  
 676      // Get the max question_order
 677      $sql = "SELECT max(question_order) as max_order FROM $tbl_quiz_rel_question WHERE exercice_id ='".$quiz_id."'
 678       AND exercice_id ='".$quiz_id."'";
 679      $rs_max_order = Database::query($sql, __FILE__, __LINE__);
 680      $row_max_order = Database::fetch_object($rs_max);
 681      $max_order = $row_max_order->max_order + 1;
 682  
 683      // Attach questions to quiz
 684      $sql = "INSERT INTO $tbl_quiz_rel_question(question_id,exercice_id,question_order)
 685      VALUES('".$question_id."', '".$quiz_id."', '".$max_order."')";
 686      $rs = Database::query($sql, __FILE__, __LINE__);
 687      return $question_id;
 688    }
 689    function search_engine_edit($exerciseId, $addQs=FALSE, $rmQs=FALSE) {
 690     // update search engine and its values table if enabled
 691     if (api_get_setting('search_enabled') == 'true' && extension_loaded('xapian')) {
 692      $course_id = api_get_course_id();
 693      // get search_did
 694      $tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
 695      if ($addQs || $rmQs) {
 696       //there's only one row per question on normal db and one document per question on search engine db
 697       $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_second_level=%s LIMIT 1';
 698       $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_QUIZ, $this->id);
 699      } else {
 700       $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s AND ref_id_second_level=%s LIMIT 1';
 701       $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_QUIZ, $exerciseId, $this->id);
 702      }
 703      $res = api_sql_query($sql, __FILE__, __LINE__);
 704  
 705      if (Database::num_rows($res) > 0 || $addQs) {
 706       require_once(api_get_path(LIBRARY_PATH) . 'search/DokeosIndexer.class.php');
 707       require_once(api_get_path(LIBRARY_PATH) . 'search/IndexableChunk.class.php');
 708  
 709       $di = new DokeosIndexer();
 710       if ($addQs) {
 711        $question_exercises = array((int) $exerciseId);
 712       } else {
 713        $question_exercises = array();
 714       }
 715       isset($_POST['language']) ? $lang = Database::escape_string($_POST['language']) : $lang = 'english';
 716       $di->connectDb(NULL, NULL, $lang);
 717  
 718       // retrieve others exercise ids
 719       $se_ref = Database::fetch_array($res);
 720       $se_doc = $di->get_document((int) $se_ref['search_did']);
 721       if ($se_doc !== FALSE) {
 722        if (($se_doc_data = $di->get_document_data($se_doc)) !== FALSE) {
 723         $se_doc_data = unserialize($se_doc_data);
 724         if (isset($se_doc_data[SE_DATA]['type']) && $se_doc_data[SE_DATA]['type'] == SE_DOCTYPE_EXERCISE_QUESTION) {
 725          if (isset($se_doc_data[SE_DATA]['exercise_ids']) && is_array($se_doc_data[SE_DATA]['exercise_ids'])) {
 726           foreach ($se_doc_data[SE_DATA]['exercise_ids'] as $old_value) {
 727            if (!in_array($old_value, $question_exercises)) {
 728             $question_exercises[] = $old_value;
 729            }
 730           }
 731          }
 732         }
 733        }
 734       }
 735       if ($rmQs) {
 736        while (($key = array_search($exerciseId, $question_exercises)) !== FALSE) {
 737         unset($question_exercises[$key]);
 738        }
 739       }
 740  
 741       // build the chunk to index
 742       $ic_slide = new IndexableChunk();
 743       $ic_slide->addValue("title", $this->question);
 744       $ic_slide->addCourseId($course_id);
 745       $ic_slide->addToolId(TOOL_QUIZ);
 746       $xapian_data = array(
 747           SE_COURSE_ID => $course_id,
 748           SE_TOOL_ID => TOOL_QUIZ,
 749           SE_DATA => array('type' => SE_DOCTYPE_EXERCISE_QUESTION, 'exercise_ids' => $question_exercises, 'question_id' => (int) $this->id),
 750           SE_USER => (int) api_get_user_id(),
 751       );
 752       $ic_slide->xapian_data = serialize($xapian_data);
 753       $question_description = !empty($this->description) ? $this->description : $this->question;
 754       $ic_slide->addValue("content", $question_description);
 755  
 756       //TODO: index answers, see also form validation on question_admin.inc.php
 757  
 758       $di->remove_document((int) $se_ref['search_did']);
 759       $di->addChunk($ic_slide);
 760  
 761       //index and return search engine document id
 762       if (!empty($question_exercises)) { // if empty there is nothing to index
 763        $did = $di->index();
 764        unset($di);
 765       }
 766       if ($did || $rmQs) {
 767        // save it to db
 768        if ($addQs || $rmQs) {
 769         $sql = 'DELETE FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_second_level=\'%s\'';
 770         $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_QUIZ, $this->id);
 771        } else {
 772         $sql = 'DELETE FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=\'%s\' AND ref_id_second_level=\'%s\'';
 773         $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_QUIZ, $exerciseId, $this->id);
 774        }
 775        api_sql_query($sql, __FILE__, __LINE__);
 776        if ($rmQs) {
 777         if (!empty($question_exercises)) {
 778          $sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, ref_id_second_level, search_did)
 779                                VALUES (NULL , \'%s\', \'%s\', %s, %s, %s)';
 780          $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_QUIZ, array_shift($question_exercises), $this->id, $did);
 781          api_sql_query($sql, __FILE__, __LINE__);
 782         }
 783        } else {
 784         $sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, ref_id_second_level, search_did)
 785                              VALUES (NULL , \'%s\', \'%s\', %s, %s, %s)';
 786         $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_QUIZ, $exerciseId, $this->id, $did);
 787         api_sql_query($sql, __FILE__, __LINE__);
 788        }
 789       }
 790      }
 791     }
 792    }
 793  
 794    /**
 795     * adds an exercise into the exercise list
 796     *
 797     * @author - Olivier Brouckaert
 798     * @param - integer $exerciseId - exercise ID
 799     * @param - boolean $fromSave - comming from $this->save() or not
 800     */
 801    function addToList($exerciseId, $fromSave=FALSE) {
 802     global $TBL_EXERCICE_QUESTION;
 803     $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
 804     $id = $this->id;
 805     // checks if the exercise ID is not in the list
 806     if (!in_array($exerciseId, $this->exerciseList)) {
 807      $this->exerciseList[] = $exerciseId;
 808      // Get the max value of question_order field
 809      $sql = "SELECT max(question_order) AS last_order FROM $TBL_EXERCICE_QUESTION WHERE exercice_id='".Database::escape_string($exerciseId)."' ";
 810      $res = Database::query($sql, __FILE__, __LINE__);
 811      $row = Database::fetch_object($res);
 812      // Next question order
 813      $next_order = $row->last_order + 1;
 814      // Save new question to quiz
 815      $sql = "INSERT INTO $TBL_EXERCICE_QUESTION (question_id, exercice_id, question_order) VALUES('" . Database::escape_string($id) . "','" . Database::escape_string($exerciseId) . "','" . Database::escape_string($next_order) . "')";
 816      Database::query($sql, __FILE__, __LINE__);
 817  
 818      // we do not want to reindex if we had just saved adnd indexed the question
 819      if (!$fromSave) {
 820       $this->search_engine_edit($exerciseId, TRUE);
 821      }
 822     }
 823  
 824     if($_REQUEST['fromTpl'] == 1)
 825      {
 826      $sql = "SELECT max(question_order) AS last_order FROM $TBL_EXERCICE_QUESTION WHERE exercice_id='".Database::escape_string($exerciseId)."' ";
 827      $res = Database::query($sql, __FILE__, __LINE__);
 828      $row = Database::fetch_object($res);
 829      // Next question order
 830      $next_order = $row->last_order + 1;
 831      // Save new question to quiz
 832      $sql = "INSERT INTO $TBL_EXERCICE_QUESTION (question_id, exercice_id, question_order) VALUES('" . Database::escape_string($id) . "','" . Database::escape_string($exerciseId) . "','" . Database::escape_string($next_order) . "')";
 833      Database::query($sql, __FILE__, __LINE__);
 834      }
 835    }
 836  
 837    /**
 838     * removes an exercise from the exercise list
 839     *
 840     * @author - Olivier Brouckaert
 841     * @param - integer $exerciseId - exercise ID
 842     * @return - boolean - true if removed, otherwise false
 843     */
 844    function removeFromList($exerciseId) {
 845     global $TBL_EXERCICE_QUESTION;
 846  
 847     $id = $this->id;
 848  
 849     // searches the position of the exercise ID in the list
 850     $pos = array_search($exerciseId, $this->exerciseList);
 851  
 852     // exercise not found
 853     if ($pos === false) {
 854      return false;
 855     } else {
 856      // deletes the position in the array containing the wanted exercise ID
 857      unset($this->exerciseList[$pos]);
 858      //update order of other elements
 859      $sql = "SELECT question_order FROM $TBL_EXERCICE_QUESTION WHERE question_id='" . Database::escape_string($id) . "' AND exercice_id='" . Database::escape_string($exerciseId) . "'";
 860      $res = api_sql_query($sql, __FILE__, __LINE__);
 861      if (Database::num_rows($res) > 0) {
 862       $row = Database::fetch_array($res);
 863       if (!empty($row['question_order'])) {
 864        $sql = "UPDATE $TBL_EXERCICE_QUESTION SET question_order = question_order-1 WHERE exercice_id='" . Database::escape_string($exerciseId) . "' AND question_order > " . $row['question_order'];
 865        $res = api_sql_query($sql, __FILE__, __LINE__);
 866       }
 867      }
 868  
 869      $sql = "DELETE FROM $TBL_EXERCICE_QUESTION WHERE question_id='" . Database::escape_string($id) . "' AND exercice_id='" . Database::escape_string($exerciseId) . "'";
 870      api_sql_query($sql, __FILE__, __LINE__);
 871  
 872      return true;
 873     }
 874    }
 875  
 876    /**
 877     * deletes a question from the database
 878     * the parameter tells if the question is removed from all exercises (value = 0),
 879     * or just from one exercise (value = exercise ID)
 880     *
 881     * @author - Olivier Brouckaert
 882     * @param - integer $deleteFromEx - exercise ID if the question is only removed from one exercise
 883     */
 884    function delete($deleteFromEx=0) {
 885     global $_course, $_user;
 886  
 887     $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
 888     $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
 889     $TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
 890  
 891     $id = $this->id;
 892  
 893     // if the question must be removed from all exercises
 894     if (!$deleteFromEx) {
 895      //update the question_order of each question to avoid inconsistencies
 896      $sql = "SELECT exercice_id, question_order FROM $TBL_EXERCICE_QUESTION WHERE question_id='" . Database::escape_string($id) . "'";
 897      $res = api_sql_query($sql, __FILE__, __LINE__);
 898      if (Database::num_rows($res) > 0) {
 899       while ($row = Database::fetch_array($res)) {
 900        if (!empty($row['question_order'])) {
 901         $sql = "UPDATE $TBL_EXERCICE_QUESTION SET question_order = question_order-1 WHERE exercice_id='" . Database::escape_string($row['exercice_id']) . "' AND question_order > " . $row['question_order'];
 902         $res = api_sql_query($sql, __FILE__, __LINE__);
 903        }
 904       }
 905      }
 906      $sql = "DELETE FROM $TBL_EXERCICE_QUESTION WHERE question_id='" . Database::escape_string($id) . "'";
 907      api_sql_query($sql, __FILE__, __LINE__);
 908  
 909      $sql = "DELETE FROM $TBL_QUESTIONS WHERE id='" . Database::escape_string($id) . "'";
 910      api_sql_query($sql, __FILE__, __LINE__);
 911  
 912      $sql = "DELETE FROM $TBL_REPONSES WHERE question_id='" . Database::escape_string($id) . "'";
 913      api_sql_query($sql, __FILE__, __LINE__);
 914  
 915      api_item_property_update($_course, TOOL_QUIZ, $id, 'QuizQuestionDeleted', $_user['user_id']);
 916      $this->removePicture();
 917  
 918      // resets the object
 919      $this->Question();
 920     }
 921     // just removes the exercise from the list
 922     else {
 923      $this->removeFromList($deleteFromEx);
 924      if (api_get_setting('search_enabled') == 'true' && extension_loaded('xapian')) {
 925       // disassociate question with this exercise
 926       $this->search_engine_edit($deleteFromEx, FALSE, TRUE);
 927      }
 928      api_item_property_update($_course, TOOL_QUIZ, $id, 'QuizQuestionDeleted', $_user['user_id']);
 929     }
 930    }
 931  
 932    /**
 933     * duplicates the question
 934     *
 935     * @author - Olivier Brouckaert
 936     * @return - integer - ID of the new question
 937     */
 938    function duplicate() {
 939     global $TBL_QUESTIONS, $picturePath;
 940  
 941     $question = $this->question;
 942     $description = $this->description;
 943     $weighting = $this->weighting;
 944     $position = $this->position;
 945     $type = $this->type;
 946  
 947     $sql = "INSERT INTO $TBL_QUESTIONS(question,description,ponderation,position,type) VALUES('" . Database::escape_string($question) . "','" . Database::escape_string($description) . "','" . Database::escape_string($weighting) . "','" . Database::escape_string($position) . "','" . Database::escape_string($type) . "')";
 948     api_sql_query($sql, __FILE__, __LINE__);
 949  
 950     $id = Database::get_last_insert_id();
 951     // duplicates the picture
 952     $this->exportPicture($id);
 953  
 954     return $id;
 955    }
 956  
 957    /**
 958     * Returns an instance of the class corresponding to the type
 959     * @param integer $type the type of the question
 960     * @return an instance of a Question subclass (or of Questionc class by default)
 961     */
 962    static function getInstance($type) {
 963     if (!is_null($type)) {
 964      list($file_name, $class_name) = self::$questionTypes[$type];
 965      include_once($file_name);
 966      if (class_exists($class_name)) {
 967       return new $class_name();
 968      } else {
 969       echo 'Can\'t instanciate class ' . $class_name . ' of type ' . $type;
 970       return null;
 971      }
 972     }
 973    }
 974  
 975    /**
 976     * Creates the form to create / edit a question
 977     * A subclass can redifine this function to add fields...
 978     * @param FormValidator $form the formvalidator instance (by reference)
 979     */
 980    function createForm(&$form, $fck_config=0) {
 981     global $charset;
 982     echo '<style>
 983                      div.row div.label{ width: 10%; }
 984                      div.row div.formw{ width: 89%; }
 985                  </style>';
 986  
 987     echo '<script>
 988  			function show_media()
 989              {
 990              if(document.getElementById(\'media\').style.display == \'none\') {
 991                  document.getElementById(\'media\').style.display = \'block\';
 992                  document.getElementById(\'media_icon\').innerHTML=\'&nbsp;<img style="vertical-align: middle;" src="../img/looknfeel.png" alt="" />&nbsp;' . get_lang('EnrichQuestion') . '\';
 993              } else {
 994                  document.getElementById(\'media\').style.display = \'none\';
 995                  document.getElementById(\'media_icon\').innerHTML=\'&nbsp;<img style="vertical-align: middle;" src="../img/looknfeelna.png" alt="" />&nbsp;' . get_lang('EnrichQuestion') . '\';
 996              }
 997          }
 998  
 999  		function bigform()
1000              {
1001              if(document.getElementById(\'newform\').style.display == \'none\') {
1002                  document.getElementById(\'newform\').style.display = \'block\';
1003                  document.getElementById(\'big_icon\').innerHTML=\'<img src="../img/BigFormFilled.png" alt="" onclick="smallform()" />\';
1004                  document.getElementById(\'small_icon\').innerHTML=\'<img src="../img/SmallFormClosed.png" alt="" onclick="bigform()" />\';
1005                  formlineshigh();
1006              } else {
1007                  document.getElementById(\'newform\').style.display = \'none\';
1008                  document.getElementById(\'big_icon\').innerHTML=\'<img src="../img/BigFormClosed.png" alt="" onclick="smallform()" />\';
1009                  document.getElementById(\'small_icon\').innerHTML=\'<img src="../img/SmallFormFilled.png" alt="" onclick="bigform()" />\';
1010                  formlineslow();
1011              }
1012  
1013          }
1014  		function smallform()
1015              {
1016              if(document.getElementById(\'newform\').style.display == \'none\') {
1017                  document.getElementById(\'newform\').style.display = \'block\';
1018                  document.getElementById(\'small_icon\').innerHTML=\'<img src="../img/SmallFormClosed.png" alt="" onclick="bigform()" />\';
1019                  document.getElementById(\'big_icon\').innerHTML=\'<img src="../img/BigFormFilled.png" alt="" onclick="smallform()" />\';
1020                  formlineshigh();
1021              } else {
1022                  document.getElementById(\'newform\').style.display = \'none\';
1023                  document.getElementById(\'small_icon\').innerHTML=\'<img src="../img/SmallFormFilled.png" alt="" onclick="bigform()" />\';
1024                  document.getElementById(\'big_icon\').innerHTML=\'<img src="../img/BigFormClosed.png" alt="" onclick="smallform()" />\';
1025                  formlineslow();
1026              }
1027  
1028          }
1029  		function highlineform()
1030        {
1031           document.getElementById("questionName___Frame").style.height = "150px";
1032           var questiontype = document.question_admin_form.questiontype.value;
1033  
1034           if(questiontype != 6)
1035           {
1036               if(questiontype == 4 || questiontype == 5)
1037               {
1038               document.getElementById("questionDescription___Frame").style.height = "400px";
1039               }
1040               else
1041               {
1042               document.getElementById("questionDescription___Frame").style.height = "520px";
1043               }
1044           }
1045  
1046           if(questiontype != "4")
1047              {
1048                  document.question_admin_form.formsize.value = "High";
1049                  if(questiontype == "6")
1050                  {
1051                      var nb_matches = document.question_admin_form.nb_matches.value;
1052                      var nb_options = document.question_admin_form.nb_options.value;
1053  
1054                      for(var i=1;i<=nb_matches;i++)
1055                      {
1056                          document.getElementById("nos["+i+"]").style.height = "160px";
1057                          document.getElementById("answer["+i+"]___Frame").style.height = "150px";
1058                      }
1059  
1060                      for(var i=1;i<=nb_options;i++)
1061                      {
1062                          document.getElementById("alpha["+i+"]").style.height = "160px";
1063                          document.getElementById("option["+i+"]___Frame").style.height = "150px";
1064                      }
1065                  }
1066                  else
1067                  {
1068                      var nb_answers = document.question_admin_form.nb_answers.value;
1069  
1070                      for(var i=1;i<=nb_answers;i++)
1071                      {
1072                          document.getElementById("answer["+i+"]___Frame").style.height = "150px";
1073                      }
1074                  }
1075              }
1076              if(questiontype != 5)
1077              {
1078                  document.getElementById("comment[1]___Frame").style.height = "150px";
1079                  document.getElementById("comment[2]___Frame").style.height = "150px";
1080              }
1081              if(questiontype == 4)
1082              {
1083                  document.getElementById("answer___Frame").style.height = "400px";
1084              }
1085        }
1086  
1087  	  function lowlineform()
1088        {
1089           document.getElementById("questionName___Frame").style.height = "40px";
1090           var questiontype = document.question_admin_form.questiontype.value;
1091           if(questiontype != 6)
1092           {
1093           document.getElementById("questionDescription___Frame").style.height = "300px";
1094           }
1095  
1096           if(questiontype != "4")
1097              {
1098                  document.question_admin_form.formsize.value = "Low";
1099                  if(questiontype == "6")
1100                  {
1101                      var nb_matches = document.question_admin_form.nb_matches.value;
1102                      var nb_options = document.question_admin_form.nb_options.value;
1103                      for(var i=1;i<=nb_matches;i++)
1104                      {
1105                          document.getElementById("nos["+i+"]").style.height = "50px";
1106                          document.getElementById("answer["+i+"]___Frame").style.height = "40px";
1107                      }
1108  
1109                      for(var i=1;i<=nb_options;i++)
1110                      {
1111                          document.getElementById("alpha["+i+"]").style.height = "52px";
1112                          document.getElementById("option["+i+"]___Frame").style.height = "40px";
1113                      }
1114                  }
1115                  else
1116                  {
1117                      var nb_answers = document.question_admin_form.nb_answers.value;
1118  
1119                      for(var i=1;i<=nb_answers;i++)
1120                      {
1121                          document.getElementById("answer["+i+"]___Frame").style.height = "40px";
1122                      }
1123                  }
1124              }
1125              if(questiontype != 5)
1126              {
1127                  document.getElementById("comment[1]___Frame").style.height = "40px";
1128                  document.getElementById("comment[2]___Frame").style.height = "40px";
1129              }
1130              if(questiontype == 4)
1131              {
1132                  document.getElementById("answer___Frame").style.height = "250px";
1133              }
1134        }
1135  
1136  		function FCKeditor_OnComplete( editorInstance ) {
1137          // Get the fck instance
1138          _currentEditor = editorInstance;
1139          // automated event loaded by each fckeditor area when loaded
1140          editorInstance.Events.AttachEvent( "OnSelectionChange", takeFocus ) ;
1141          var oFCKeditor=FCKeditorAPI.GetInstance("questionName") ;
1142          oFCKeditor.Focus();
1143          var questiontype = document.question_admin_form.questiontype.value;
1144  
1145          if(questiontype == 4)
1146          {
1147             if (window.attachEvent) {
1148                editorInstance.EditorDocument.attachEvent("onkeyup", updateBlanks) ;
1149             } else {
1150                editorInstance.EditorDocument.addEventListener("keyup",updateBlanks,true);
1151             }
1152          }
1153      }
1154  
1155      var _currentEditor;
1156  
1157  	function takeFocus(editor){
1158      _currentEditor = editor
1159      }
1160  
1161  	function makeitbold(){
1162      _currentEditor.Commands.GetCommand("Bold").Execute();
1163  
1164      }
1165  
1166  	function word(){
1167      _currentEditor.Commands.GetCommand("PasteWord").Execute();
1168  
1169      }
1170  	function link(){
1171      _currentEditor.Commands.GetCommand("Link").Execute();
1172  
1173      }
1174  	function youtube(){
1175      _currentEditor.Commands.GetCommand("YouTube").Execute();
1176  
1177      }
1178  	function image(){
1179      _currentEditor.Commands.GetCommand("Image").Execute();
1180  
1181      }
1182  	function mindmap(){
1183      _currentEditor.Commands.GetCommand("MindmapManager").Execute();
1184  
1185      }
1186  	function mascot(){
1187      _currentEditor.Commands.GetCommand("MascotManager").Execute();
1188  
1189      }
1190  	function flash(){
1191      _currentEditor.Commands.GetCommand("Flash").Execute();
1192  
1193      }
1194  	function embedmovies(){
1195      _currentEditor.Commands.GetCommand("EmbedMovies").Execute();
1196  
1197      }
1198  	function audio(){
1199      _currentEditor.Commands.GetCommand("MP3").Execute();
1200  
1201      }
1202  	function table(){
1203      _currentEditor.Commands.GetCommand("Table").Execute();
1204  
1205      }
1206  	function unordered(){
1207      _currentEditor.Commands.GetCommand("InsertUnorderedList").Execute();
1208  
1209      }
1210  	function source(){
1211      _currentEditor.Commands.GetCommand("Source").Execute();
1212  
1213      }
1214  	function alignleft(){
1215      _currentEditor.Commands.GetCommand("JustifyLeft").Execute();
1216  
1217      }
1218  	function aligncenter(){
1219      _currentEditor.Commands.GetCommand("JustifyCenter").Execute();
1220  
1221      }
1222  	function alignright(){
1223      _currentEditor.Commands.GetCommand("JustifyRight").Execute();
1224  
1225      }
1226          /*
1227      function flvplayer(){
1228      _currentEditor.Commands.GetCommand("flvPlayer").Execute();
1229      }*/
1230          
1231          function videoplayer(){
1232      _currentEditor.Commands.GetCommand("videoPlayer").Execute();
1233      }
1234  
1235  
1236  	function imagemap(){
1237      _currentEditor.Commands.GetCommand("imgmapPopup").Execute();
1238  
1239      }
1240  	function fontcolor(event){
1241      event = $.event.fix(event);
1242      _currentEditor.Commands.GetCommand("TextColor").Execute(-120,20,event.target);
1243  
1244      }
1245  
1246  	function glossary(){
1247      _currentEditor.Commands.GetCommand("Glossary").Execute();
1248  
1249      }
1250  
1251  	function fontsize() {
1252      var font_option = document.question_admin_form.font.value;
1253      //var selection = (_currentEditor.EditorWindow.getSelection ? _currentEditor.EditorWindow.getSelection() : _currentEditor.EditorDocument.selection);
1254      var selection = "";
1255      if(_currentEditor.EditorDocument.selection != null) {
1256        selection = _currentEditor.EditorDocument.selection.createRange().text;
1257      }
1258      else {
1259        selection = _currentEditor.EditorWindow.getSelection();
1260      }
1261      var new_selection = "<span style=\"font-size:"+font_option+";\">"+selection+"</span>";
1262      _currentEditor.InsertHtml(new_selection);
1263      }
1264                  </script>';
1265  
1266  
1267     $renderer = $form->defaultRenderer();
1268  
1269     // Main container
1270     $form->addElement('html', '<div class="form-main-container">');
1271     $glossary_plugin = '';
1272     if (api_get_setting('show_glossary_in_documents') == 'ismanual') {
1273       $glossary_plugin = '<td width="5px;" class="toolbar_style"><img onclick="glossary();" src="'.api_get_path(WEB_LIBRARY_PATH).'fckeditor/editor/plugins/glossary/glossary.gif" alt="'.get_lang('Glossary').'" title="'.get_lang('Glossary').'"></td>';
1274     }
1275     if (isset($_GET['answerType']) && $_GET['answerType'] != 6 || isset($_GET['type']) && $_GET['type'] != 6 || isset($_GET['fromTpl'])) {
1276     $form->addElement('html','<table cellspacing="3" width="100%" height="50px" class="toolbar_style"><tr><td width="80%"><table width="100%"><tr style="height:5px;"><td colspan="3"></td></tr>
1277     <tr>
1278     <td width="5px"><img src="../img/toolbar_start.gif"></td>
1279     <td width="5px" class="toolbar_style">
1280     <img src="../img/pasteword_icon.png" onclick="word();" alt="'.get_lang('PasteWord').'" title="'.get_lang('PasteWord').'"></td>
1281     <td width="5px"><img src="../img/toolbar_start.gif"></td>
1282     <td width="5px;" class="toolbar_style"><img src="../img/link_icon.png" onclick="link();" alt="'.get_lang('Link').'" title="'.get_lang('Link').'"></td>
1283     <td width="5px"><img src="../img/toolbar_start.gif"></td><td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Images'),array('class'=>'fckactionplaceholdericon fckactionimages_icon','onclick'=>'image();')) .'</td>
1284     <td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Imagemap'),array('class'=>'fckactionplaceholdericon fckactionimagemap','onclick'=>'imagemap();')).'</td>
1285     <td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Mindmap'),array('class'=>'fckactionplaceholdericon fckactionmindmap_18','onclick'=>'mindmap();')).'</td>
1286     <td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Mascot'),array('class'=>'fckactionplaceholdericon fckactionmascot_icon','onclick'=>'mascot();')).'</td>
1287     <td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Videoplayer'),array('class'=>'fckactionplaceholdericon fckactionvideoPlayer','onclick'=>'videoplayer();')).'</td>
1288     <td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Audio'),array('class'=>'fckactionplaceholdericon fckactionaudio','onclick'=>'audio();')).'</td>
1289     '.$glossary_plugin.'
1290     <td width="5px"><img src="../img/toolbar_start.gif"></td>
1291     <td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Table'),array('class'=>'fckactionplaceholdericon fckactiontable','onclick'=>'table();')).'</td>
1292     <td width="5px;" class="toolbar_style"><img src="../img/unordered_list.png" onclick="unordered();" alt="'.get_lang('Orderedlist').'" title="'.get_lang('Orderedlist').'"></td>
1293     <td width="5px;" class="toolbar_style"><img src="../img/view_source.png" onclick="source();" alt="'.get_lang('Source').'" title="'.get_lang('Source').'"></td>
1294     <td width="5px"><img src="../img/toolbar_start.gif"></td>
1295     <td width="5px;" class="toolbar_style"><img src="../img/text_bold.png" onclick="makeitbold();" alt="'.get_lang('Bold').'" title="'.get_lang('Bold').'"></td>
1296     <td width="5px"><img src="../img/toolbar_start.gif"></td><td width="5px;" class="toolbar_style"><img src="../img/text_left.png" onclick="alignleft();" alt="'.get_lang('Alignleft').'" title="'.get_lang('Alignleft').'"></td>
1297     <td width="5px;" class="toolbar_style"><img src="../img/text_center.png" onclick="aligncenter();" alt="'.get_lang('Aligncenter').'" title="'.get_lang('Aligncenter').'"></td>
1298     <td width="5px;" class="toolbar_style">'.Display::return_icon('pixel.gif',get_lang('Textcolor'), array('class' => 'fckactionplaceholdericon fckactionfontcolor', 'onclick' => 'fontcolor(event);')).'</td>
1299     <td width="5px"><img src="../img/toolbar_start.gif"></td>
1300     </tr>
1301     <tr height="5px">
1302     <td></td></tr>
1303     </table></td>
1304     <td>
1305     <table width="100%">
1306     <tr><td><span style="color:#333333;">Font:</span><select name="font" onchange="fontsize()"><option></option><option value="smaller" style="font-size: smaller;">smaller</option><option value="larger" style="font-size: larger;">larger</option><option value="xx-small" style="font-size: xx-small;">xx-small</option><option value="x-small" style="font-size: x-small;">x-small</option><option value="small" style="font-size: small;">small</option><option value="medium" style="font-size: medium;">medium</option><option value="large" style="font-size: large;">large</option><option value="x-large" style="font-size: x-large;">x-large</option><option value="xx-large" style="font-size: x-large;">xx-large</option></select></td></tr></table></td></tr></table></td></tr></table><br>');
1307     }
1308  
1309    if(empty($this->level))
1310    {
1311          $questionLevel = '';
1312    }
1313    else
1314    {
1315          if($this->level == "1")
1316          {
1317              $questionLevel = "Prerequestie";
1318          }
1319          if($this->level == "2")
1320          {
1321              $questionLevel = "Beginner";
1322          }
1323          if($this->level == "3")
1324          {
1325              $questionLevel = "Intermediate";
1326          }
1327          if($this->level == "4")
1328          {
1329              $questionLevel = "Advanced";
1330          }
1331    }
1332  
1333    if(isset($_POST['formsize']))
1334    {
1335       $formsize = $_POST['formsize'];
1336    }
1337    else
1338    {
1339        $formsize = '';
1340    }
1341  
1342    if(empty($formsize) || $formsize == 'Low')
1343    {
1344        $formsize_px = "40px";
1345    }
1346    else
1347    {
1348        $formsize_px = "150px";
1349    }
1350  
1351    if (isset($_GET['answerType']) && $_GET['answerType'] == 4 || isset($_GET['type']) && $_GET['type'] == 4) {
1352       $formsize_px = "90px";
1353    }
1354  
1355     // Left container
1356     $form->addElement('html', '<div class="form-left" style="float:left">');
1357  
1358     // question name
1359     //$form->addElement('text','questionName','<span class="form_required"></span> '.get_lang('Question'),'size="40"');
1360     $form->addElement('html', '<div class="form-left-left">'.get_lang('Question'));
1361  //   $form->addElement('textarea', 'questionName', '<span class="form_required"></span> ' . get_lang('Question'), 'id="questionName" cols="50" rows="1"');
1362     $form->add_html_editor('questionName','', false, false, array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '450px', 'Height' => ''.$formsize_px.''));
1363     $form->addElement('html', '</div>');
1364     // Question Score
1365     $score_options = array();
1366     $score_options = range(0, 20);
1367  
1368     $show_score = true;
1369     if (isset($_GET['answerType']) && $_GET['answerType'] == 3 || isset($_GET['type']) && $_GET['type'] == 3) {
1370       $show_score = false;
1371     }
1372     if ($show_score === false) {
1373       $form->addElement('html', '<div class="form-left-right" style="display:none;">');
1374     } else {
1375       $form->addElement('html', '<div class="form-left-right">');
1376     }
1377  
1378     if (isset($_GET['answerType']) && $_GET['answerType'] != 6 || isset($_GET['type']) && $_GET['type'] != 6  || isset($_GET['fromTpl'])) {
1379     $form->addElement('select', 'scoreQuestions', get_lang('Score'), $score_options);
1380     }
1381     $form->addElement('html', '</div>');
1382  
1383     $form->addElement('html', '<div>&nbsp;</div>');
1384  /* $select_level = array(1, 2, 3, 4, 5);
1385     foreach ($select_level as $val) {
1386      if ($val == '1') {
1387       $level = 'Prerequisite';
1388      }
1389      if ($val == '2') {
1390       $level = 'Beginner';
1391      }
1392      if ($val == '3') {
1393       $level = 'Intermediate';
1394      }
1395      if ($val == '4') {
1396       $level = 'Advanced';
1397      }
1398      if ($val == '5') {
1399       $level = 'Expert';
1400      }
1401      $radios_results_enabled[] = FormValidator :: createElement('radio', null, null, $level, $val);
1402     }
1403     $form->addGroup($radios_results_enabled, 'questionLevel', get_lang('Difficulty'));*/
1404  
1405     $form->addElement('hidden','questionLevel');
1406  
1407     $renderer->setElementTemplate('<div><div class="label">{label}</div><div class="formw" >{element}</div></div>', 'scoreQuestions');
1408  // $renderer->setElementTemplate('<div><div class="label">{label}</div><div class="formw" >{element}</div></div>', 'questionName');
1409  // $renderer->setElementTemplate('<div><div class="label">{label}</div><div class="formw">{element}</div></div>', 'questionLevel');
1410     $form->addRule('questionName', get_lang('GiveQuestion'), 'required');
1411  
1412  /* $form->addElement('html', '<div><table width="100%"><tr><td align="right"><span id="small_icon"> <img src="../img/SmallFormFilled.png" alt="" onclick="smallform()" /></span><span id="big_icon"> <img src="../img/BigFormClosed.png" alt="" onclick="bigform()" /></span></td></tr></table></div>');
1413     $form -> addElement ('html','<div align="right" id="newform" style="display:none;"></div>');
1414  
1415     $form->addElement('html','<br/><div id="level">Level (Each square represent level.Click on it ) - <input type="text" size="20" name="qnlevel" value="'.$questionLevel.'" disabled /></div><div class="level_style_advanced" onclick="level(\'advanced\');" title="Advanced"></div><div class="level_style_intermediate" onclick="level(\'intermediate\');" title="Intermediate"></div><div class="level_style_beginner" onclick="level(\'beginner\');" title="Beginner"></div><div class="level_style_prerequestie" onclick="level(\'prerequestie\');" title="Prerequestie"></div>');*/
1416  
1417     // question type
1418     $answerType = intval($_REQUEST['answerType']);
1419     $form->addElement('hidden', 'answerType', $_REQUEST['answerType']);
1420  
1421     // html editor
1422     $editor_config = array('ToolbarSet' => 'TestQuestionDescription', 'Width' => '90%', 'Height' => '500');
1423     if (is_array($fck_config)) {
1424      $editor_config = array_merge($editor_config, $fck_config);
1425     }
1426     if (!api_is_allowed_to_edit())
1427      $editor_config['UserStatus'] = 'student';
1428  
1429     /* if(($this->type == '1') || ($this->type == '2')  || ($this->type == '4')){
1430       $form -> addElement('html','<div class="row">
1431       <div class="label"></div>
1432       <div class="formw" style="height:50px">
1433       <a href="javascript://" onclick=" return show_media()"> <span id="media_icon"> <img style="vertical-align: middle;" src="../img/looknfeelna.png" alt="" />&nbsp;'.get_lang('EnrichQuestion').'</span></a>
1434       </div>
1435       </div>');
1436  
1437       $form -> addElement ('html','<div id="media" style="display:none;">');
1438       $form->addElement('html_editor', 'questionDescription',null,'style="vertical-align:middle"',array('ToolbarSet' => 'TestQuestionDescription', 'Width' => '90%', 'Height' => '250'));
1439       $form -> addElement ('html','</div><br/><br/>');
1440       } */
1441  
1442     //$renderer->setElementTemplate('<div class="row"><div class="label">{label}</div><div class="formw">{element}</div></div>','questionDescription');
1443     // hidden values
1444     $form->addElement('hidden', 'myid', $_REQUEST['myid']);
1445     $form->addElement('html', '</div>');
1446     $quizmedia_lang_var = api_convert_encoding(get_lang('QuizMedia'), $charset, api_get_system_encoding());   
1447  
1448     // Setting for "Matching" question type
1449     if ((isset($_REQUEST['answerType']) && $_REQUEST['answerType'] == 4) || (isset($_GET['type']) && $_GET['type'] == 4)) {
1450       $media_img = "deco_matching.png";
1451      $default_image = '<div style="text-align: center;"><img  src="../img/'.$media_img.'"/></div>';
1452       // Right container - Movie image
1453       $form->addElement('html', '<div class="quiz_little_squarebox">');
1454       $form->add_html_editor('questionDescription',$quizmedia_lang_var, false, false, array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '350px', 'Height' => '90px'));
1455      
1456     } elseif ((isset($_REQUEST['answerType']) && $_REQUEST['answerType'] == 6) || (isset($_REQUEST['type']) && $_REQUEST['type'] == 6)) {
1457     // Right container - Movie image
1458      $form->addElement('html', '<div class="quiz_little_squarebox" style="width:420px">');
1459     } else {
1460     // Right container - Movie image
1461          if($this->mediaPosition == 'nomedia'){
1462              $display_css = 'display:none';
1463              $form->addElement('html', '<div id="rightcontainer"  class="quiz_questions_small_squarebox">');
1464          }
1465          else {
1466              $display_css = 'display:';
1467              $form->addElement('html', '<div id="rightcontainer"  class="quiz_questions_squarebox">');
1468          }
1469  
1470          $form->addElement('html','<div id="mediatext" style="'.$display_css.';text-align:left">'.$quizmedia_lang_var.'</div><div id="media" style="'.$display_css.';">');
1471          $form->add_html_editor('questionDescription','', false, false, array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '300px'));
1472  
1473          if($_REQUEST['answerType'] == '1')
1474          {
1475              $media_img = "instructor-faq.png";
1476          }
1477          elseif($_REQUEST['answerType'] == '2')
1478          {
1479              $media_img = "instructor-books.jpg";
1480          }
1481          elseif($_REQUEST['answerType'] == '8')
1482          {
1483              $media_img = "instructor-think.png";
1484          }
1485          elseif($_REQUEST['answerType'] == '3')
1486          {
1487              $media_img = "KnockOnWood.png";
1488          }
1489          elseif($_REQUEST['answerType'] == '5')
1490          {
1491              $media_img = "instructor-idea.jpg";
1492          }
1493             $default_image = '<div align="center"><br/><img height="240"  src="../img/'.$media_img.'"/></div>';
1494     }
1495  
1496     $form->addElement('html','</div>');
1497    
1498     echo '<script>
1499     $(document).ready(function(){';
1500     if($this->mediaPosition == 'nomedia'){
1501          echo '$("#leftcontainer").removeClass().addClass("quiz_answer_squarebox");';
1502     }
1503     else{
1504          echo '$("#leftcontainer").removeClass().addClass("quiz_answer_small_squarebox");';
1505     }
1506          echo '$("#mediaposition").change(onSelectChange);
1507      });
1508  	function onSelectChange(){    
1509      var selected = $("#mediaposition option:selected");   
1510      var mediaposition = selected.val();    
1511      if(mediaposition == "nomedia"){        
1512          $("#media").hide();
1513          $("#mediatext").hide();
1514          $("#rightcontainer").removeClass().addClass("quiz_questions_small_squarebox");
1515          $("#leftcontainer").removeClass().addClass("quiz_answer_squarebox");
1516      }
1517      else {
1518          $("#media").show();
1519          $("#mediatext").show();
1520          $("#rightcontainer").removeClass().addClass("quiz_questions_squarebox");
1521          $("#leftcontainer").removeClass().addClass("quiz_answer_small_squarebox");
1522      }
1523    }
1524     </script>';
1525  
1526     if ((isset($_REQUEST['answerType']) && $_REQUEST['answerType'] <> 4) || (isset($_GET['type']) && $_GET['type'] <> 4) || isset($_GET['fromTpl'])) {
1527         // Select position media
1528         $form->addElement('html','<div style="clear:both;"></div><br/>');
1529         $form->addElement('html','<div class="form-left">');
1530         $form->addElement('html', '<div style="float:left">'.get_lang('PositionBlockMedia'));
1531         $form->addElement('select', 'mediaPosition', '', array('top'=>get_lang('TopSide'), 'right'=>get_lang('RightSide'), 'nomedia'=>get_lang('NoMedia')),'id="mediaposition" onChange="javascript:call(this.value)"');
1532         $form->addElement('html','</div></div>');
1533         
1534         $form->addElement('html', '<div>&nbsp;</div>');
1535  
1536         // Close right container
1537         $form->addElement('html','</div>');
1538     }  
1539     
1540     // Close main container
1541     $form->addElement('html', '</div>');
1542     if ($this->description != "") {
1543       $default_image = $this->description;
1544     }
1545  
1546     // default values
1547     $defaults = array();
1548     $defaults['questionName'] = $this->question;
1549     $defaults['questionLevel'] = $this->level;
1550     $defaults['scoreQuestions'] = $this->weighting;
1551     $defaults['mediaPosition']   = $this->mediaPosition;
1552     $defaults['questionDescription'] = $default_image;
1553     $form->setDefaults($defaults);
1554    }
1555  
1556    /**
1557     * function which process the creation of questions
1558     * @param FormValidator $form the formvalidator instance
1559     * @param Exercise $objExercise the Exercise instance
1560     */
1561    function processCreation($form, $objExercise) {
1562  
1563     $this->updateTitle($form->getSubmitValue('questionName'));
1564     $this->updateDescription($form->getSubmitValue('questionDescription'));
1565     $this->updateLevel($form->getSubmitValue('questionLevel'));
1566     $this->updateMediaPosition($form->getSubmitValue('mediaPosition')); 
1567     $this->save($objExercise->id);
1568  
1569     // modify the exercise
1570     $objExercise->addToList($this->id);
1571     $objExercise->update_question_positions();
1572    }
1573  
1574    /**
1575     * abstract function which creates the form to create / edit the answers of the question
1576     * @param the formvalidator instance
1577     */
1578    abstract function createAnswersForm($form);
1579  
1580    /**
1581     * abstract function which process the creation of answers
1582     * @param the formvalidator instance
1583     */
1584    abstract function processAnswersCreation($form);
1585  
1586    /**
1587     * Displays the menu of question types
1588     */
1589    /*     static function display_type_menu ($feedbacktype = 0)
1590      {
1591      global $exerciseId;
1592      // 1. by default we show all the question types
1593      $question_type_custom_list = self::$questionTypes;
1594  
1595      if (!isset($feedbacktype)) $feedbacktype=0;
1596      if ($feedbacktype==1) {
1597      //2. but if it is a feedback DIRECT we only show the UNIQUE_ANSWER type that is currently available
1598      $question_type_custom_list = array ( UNIQUE_ANSWER => self::$questionTypes[UNIQUE_ANSWER]);
1599      }
1600      echo '<ul class="question_menu" style="padding:0px; margin:-2px;">';
1601      foreach ($question_type_custom_list as $i=>$a_type) {
1602      // include the class of the type
1603      include_once($a_type[0]);
1604      // get the picture of the type and the langvar which describes it
1605      eval('$img = '.$a_type[1].'::$typePicture;');
1606      eval('$explanation = get_lang('.$a_type[1].'::$explanationLangVar);');
1607      echo '<li>';
1608      echo '<div class="icon_image_content">';
1609      echo '<a href="admin.php?newQuestion=yes&answerType='.$i.'">'.Display::return_icon($img, $explanation).'</a>';
1610      echo '<br>';
1611      echo '<a href="admin.php?newQuestion=yes&answerType='.$i.'">'.$explanation.'</a>';
1612      echo '</div>';
1613      echo '</li>';
1614      }
1615      echo '<li>';
1616      echo '<div class="icon_image_content">';
1617      if ($feedbacktype==1) {
1618      echo $url = '<a href="question_pool.php?type=1&fromExercise='.$exerciseId.'">';
1619      } else {
1620      echo $url = '<a href="question_pool.php?fromExercise='.$exerciseId.'">';
1621      }
1622      echo Display::return_icon('database.png', get_lang('GetExistingQuestion'), '');
1623      echo '</a><br>';
1624      echo $url;
1625      echo get_lang('GetExistingQuestion');
1626      echo '</a>';
1627      echo '</div></li>';
1628      echo '</ul>';
1629      } */
1630  
1631    static function display_type_menu($feedbacktype = 0) {
1632     global $exerciseId,$charset;
1633     // 1. by default we show all the question types
1634     $question_type_custom_list = self::$questionTypes;
1635  
1636     if (!isset($feedbacktype))
1637      $feedbacktype = 0;
1638     if ($feedbacktype == 1) {
1639      //2. but if it is a feedback DIRECT we only show the UNIQUE_ANSWER type that is currently available
1640      $question_type_custom_list = array(UNIQUE_ANSWER => self::$questionTypes[UNIQUE_ANSWER]);
1641      $url = 'admin.php?newQuestion=yes&' . api_get_cidreq() . '&fromExercise=' . $exerciseId . '&answerType=';
1642     } else {
1643      $url = 'admin.php?newQuestion=yes&' . api_get_cidreq() . '&fromExercise=' . $exerciseId . '&answerType=';
1644     }
1645     echo '<div class="actions">';
1646     echo '<div class="overflow_h" style="margin-left:10px;">';
1647  
1648     $question_list_items = array();
1649     $question_list_id = array();
1650     foreach ($question_type_custom_list as $i => $my_question) {
1651      switch ($my_question[1]) {
1652       case 'UniqueAnswer':
1653        $question_list_id['UniqueAnswer'] = $i;
1654        $question_list_items[0] = $my_question;
1655        break;
1656       case 'MultipleAnswer':
1657        $question_list_id['MultipleAnswer'] = $i;
1658        $question_list_items[1] = $my_question;
1659        break;
1660       case 'FillBlanks':
1661        $question_list_id['FillBlanks'] = $i;
1662        $question_list_items[3] = $my_question;
1663        break;
1664       case 'Matching':
1665        $question_list_id['Matching'] = $i;
1666        $question_list_items[5] = $my_question;
1667        break;
1668       case 'FreeAnswer':
1669        $question_list_id['FreeAnswer'] = $i;
1670        $question_list_items[4] = $my_question;
1671        break;
1672       case 'Reasoning':
1673        $question_list_id['Reasoning'] = $i;
1674        $question_list_items[2] = $my_question;
1675        break;
1676       case 'HotSpot':
1677        $question_list_id['HotSpot'] = $i;
1678        $question_list_items[6] = $my_question;
1679        break;
1680       case 'HotspotDelineation':
1681     //   if(api_get_setting('hotspost_delineation') == "true"){
1682          $question_list_id['HotspotDelineation'] = $i;
1683          $question_list_items[7] = $my_question;
1684      //  }
1685        break;
1686        
1687      }
1688     }
1689  
1690     for ($j = 0; $j < count($question_list_items); $j++) {
1691      if (!is_null($question_list_items[$j][0])) {
1692       include_once $question_list_items[$j][0];
1693  
1694       //eval('$explanation = get_lang(' . $question_list_items[$j][1] . '::$explanationLangVar);');
1695       $explanation_lang_var = api_convert_encoding(get_lang($question_list_items[$j][1]), $charset, api_get_system_encoding());
1696  
1697       $k = $question_list_id[$question_list_items[$j][1]];
1698       if (!isset($_SESSION['fromlp'])) {
1699          echo '<div class="questionType">';
1700          echo '<a href="'.$url . $k.'">';
1701       }
1702       else
1703       {
1704          echo '<a href="'.$url . $k.'">';
1705       }
1706  
1707       switch ($question_list_items[$j][1]) {
1708            case 'UniqueAnswer':            echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_multiple_choice'));        break;
1709            case 'MultipleAnswer':        echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_multiple_answer'));        break;
1710            case 'FillBlanks':            echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_fill_blanks'));            break;
1711            case 'Matching':                echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_matching'));                break;
1712            case 'FreeAnswer':            echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_open_question'));        break;
1713            case 'Reasoning':                echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_reasoning'));            break;
1714            case 'HotSpot':                echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_hotspots'));            break;
1715            case 'HotspotDelineation':    echo Display::return_icon('pixel.gif', $explanation_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_contour'));    break;
1716       }
1717  
1718       echo '<br /><font size="2">' . $explanation_lang_var . '</font></a>';
1719       echo '</div>';
1720      }
1721     }
1722      $template_lang_var = api_convert_encoding(get_lang('Templates'), $charset, api_get_system_encoding());
1723      // Add the templates feature
1724      echo '<div class="questionType">';
1725          echo '<a href="template_gallery.php?fromExercise=' . Security::remove_XSS($_REQUEST['exerciseId']) . '&' . api_get_cidreq() . '">';
1726              echo Display::return_icon('pixel.gif', $template_lang_var, array('class' => 'quiztypeplaceholdericon quiztype_templates'));
1727              echo '<br /><font size="2">' . $template_lang_var . '</font></a>';
1728          echo '</a>';
1729      echo'</div>';
1730  
1731     echo '</div>';
1732     echo '</div>';
1733    }
1734  
1735    static function get_types_information() {
1736     return self::$questionTypes;
1737    }
1738  
1739   }
1740  
1741   endif;
1742  ?>

title

Description

title

Description

title

Description

title

title

Body