ソースを参照

Adding new unique image answer type see BT#5938

Julio Montoya 12 年 前
コミット
5c7b44b478

+ 10 - 4
main/exercice/answer.class.php

@@ -74,11 +74,17 @@ class Answer
 
         // fills arrays
         $objExercise = new Exercise($this->course_id);
-        $objExercise->read($_REQUEST['exerciseId']);
-        if ($objExercise->random_answers == '1') {
-            $this->readOrderedBy('rand()', ''); // randomize answers
+        $exerciseId = isset($_REQUEST['exerciseId']) ? $_REQUEST['exerciseId'] : null;
+
+        if ($exerciseId) {
+            $objExercise->read($exerciseId);
+            if ($objExercise->random_answers == '1') {
+                $this->readOrderedBy('rand()', ''); // randomize answers
+            } else {
+                $this->read(); // natural order
+            }
         } else {
-            $this->read(); // natural order
+            $this->read();
         }
     }
 

+ 18 - 7
main/exercice/exercise.class.php

@@ -199,10 +199,11 @@ class Exercise
     }
 
     /**
-     * returns the exercise ID
+     * Returns the exercise ID
      *
      * @author - Olivier Brouckaert
-     * @return - integer - exercise ID
+     *
+     * @return int - exercise ID
      */
     function selectId()
     {
@@ -213,7 +214,8 @@ class Exercise
      * returns the exercise title
      *
      * @author - Olivier Brouckaert
-     * @return - string - exercise title
+     *
+     * @return string - exercise title
      */
     function selectTitle()
     {
@@ -223,7 +225,7 @@ class Exercise
     /**
      * returns the number of attempts setted
      *
-     * @return - numeric - exercise attempts
+     * @return numeric - exercise attempts
      */
     function selectAttempts()
     {
@@ -232,7 +234,8 @@ class Exercise
 
     /** returns the number of FeedbackType  *
      *  0=>Feedback , 1=>DirectFeedback, 2=>NoFeedback
-     * @return - numeric - exercise attempts
+     *
+     * @return int exercise attempts
      */
     function selectFeedbackType()
     {
@@ -251,6 +254,7 @@ class Exercise
      * returns the exercise description
      *
      * @author - Olivier Brouckaert
+     *
      * @return - string - exercise description
      */
     function selectDescription()
@@ -262,6 +266,7 @@ class Exercise
      * returns the exercise sound file
      *
      * @author - Olivier Brouckaert
+     *
      * @return - string - exercise description
      */
     function selectSound()
@@ -2522,6 +2527,7 @@ class Exercise
             switch ($answerType) {
                 // for unique answer
                 case UNIQUE_ANSWER :
+                case UNIQUE_ANSWER_IMAGE :
                 case UNIQUE_ANSWER_NO_OPTION :
                     if ($from_database) {
                         $queryans = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT." WHERE exe_id = '".$exeId."' and question_id= '".$questionId."'";
@@ -2956,7 +2962,9 @@ class Exercise
                                 $totalScore += $answerWeighting;
                                 $user_answer = '<span>'.$answer_matching[$choice[$numAnswer]].'</span>';
                             } else {
-                                $user_answer = '<span style="color: #FF0000; text-decoration: line-through;">'.$answer_matching[$choice[$numAnswer]].'</span>';
+                                if ($choice[$numAnswer]) {
+                                    $user_answer = '<span style="color: #FF0000; text-decoration: line-through;">'.$answer_matching[$choice[$numAnswer]].'</span>';
+                                }
                             }
                             $matching[$numAnswer] = $choice[$numAnswer];
                         }
@@ -3050,12 +3058,14 @@ class Exercise
                     if ($debug) {
                         error_log('Showing questions $from '.$from);
                     }
+
                     //display answers (if not matching type, or if the answer is correct)
                     if ($answerType != MATCHING || $answerCorrect) {
                         if (in_array(
                             $answerType,
                             array(
                                 UNIQUE_ANSWER,
+                                UNIQUE_ANSWER_IMAGE,
                                 UNIQUE_ANSWER_NO_OPTION,
                                 MULTIPLE_ANSWER,
                                 MULTIPLE_ANSWER_COMBINATION,
@@ -3309,6 +3319,7 @@ class Exercise
 
                     switch ($answerType) {
                         case UNIQUE_ANSWER :
+                        case UNIQUE_ANSWER_IMAGE :
                         case UNIQUE_ANSWER_NO_OPTION:
                         case MULTIPLE_ANSWER :
                         case GLOBAL_MULTIPLE_ANSWER :
@@ -3901,7 +3912,7 @@ class Exercise
             } elseif ($answerType == ORAL_EXPRESSION) {
                 $answer = $choice;
                 exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $this->id, $nano);
-            } elseif ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) {
+            } elseif ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_IMAGE || $answerType == UNIQUE_ANSWER_NO_OPTION) {
                 $answer = $choice;
                 exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
                 //            } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {

+ 17 - 7
main/exercice/exercise.lib.php

@@ -206,7 +206,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
 
             $attributes = array();
             // Unique answer
-            if ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) {
+            if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION))) {
                 $input_id = 'choice-'.$questionId.'-'.$answerId;
                 if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
                     $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
@@ -225,11 +225,21 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
 
                 $s .= Display::input('hidden', 'choice2['.$questionId.']', '0');
 
-                $answer_input = '<label class="radio">';
+                $answer_input = null;
+                if ($answerType == UNIQUE_ANSWER_IMAGE) {
+                    $attributes['style'] = 'display:none';
+                    $answer_input .= '<div id="answer'.$questionId.$numAnswer.'" style="float:left" class="highlight_image">';
+                }
+
+                $answer_input .= '<label class="radio">';
                 $answer_input .= Display::input('radio', 'choice['.$questionId.']', $numAnswer, $attributes);
                 $answer_input .= $answer;
                 $answer_input .= '</label>';
 
+                if ($answerType == UNIQUE_ANSWER_IMAGE) {
+                    $answer_input .= "</div>";
+                }
+
                 if ($show_comment) {
                     $s .= '<tr><td>';
                     $s .= $answer_input;
@@ -241,6 +251,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
                 } else {
                     $s .= $answer_input;
                 }
+
             } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                 $input_id = 'choice-'.$questionId.'-'.$answerId;
                 $answer = Security::remove_XSS($answer, STUDENT);
@@ -1253,7 +1264,7 @@ function get_exam_results_data($from, $number_of_items, $column, $direction, $ex
             }
         }
     } else {
-        //echo $hpsql; var_dump($hpsql);
+
         $hpresults = getManyResultsXCol($hpsql, 6);
 
         // Print HotPotatoes test results.
@@ -1264,7 +1275,6 @@ function get_exam_results_data($from, $number_of_items, $column, $direction, $ex
                 if ($hp_title == '') {
                     $hp_title = basename($hpresults[$i][3]);
                 }
-                //var_dump($hpresults[$i]);
 
                 $hp_date = api_get_local_time($hpresults[$i][6], null, date_default_timezone_get());
                 $hp_result = round(($hpresults[$i][4] / ($hpresults[$i][5] != 0 ? $hpresults[$i][5] : 1)) * 100, 2).'% ('.$hpresults[$i][4].' / '.$hpresults[$i][5].')';
@@ -1531,7 +1541,7 @@ function get_exercise_result_ranking($my_score, $my_exe_id, $exercise_id, $cours
         }
         //}
         $return_value = array('position' => $position, 'count' => count($my_ranking));
-        //var_dump($my_score, $my_ranking);
+
         if ($return_string) {
             if (!empty($position) && !empty($my_ranking)) {
                 $return_value = $position.'/'.count($my_ranking);
@@ -2176,9 +2186,8 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
             // creates a temporary Question object
             $objQuestionTmp = Question :: read($questionId);
 
-            //this variable commes from exercise_submit_modal.php
-
             ob_start();
+            $hotspot_delineation_result = null;
 
             // We're inside *one* question. Go through each possible answer for this question
             $result = $objExercise->manage_answer($exercise_stat_info['exe_id'], $questionId, null, 'exercise_result', array(), $save_user_result, true, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result);
@@ -2218,6 +2227,7 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
 
             //No category for this question!
             if ($category_was_added_for_this_test == false) {
+                $category_list['none'] = array();
                 $category_list['none']['score'] += $my_total_score;
                 $category_list['none']['total'] += $my_total_weight;
             }

+ 1 - 1
main/exercice/exercise_reminder.php

@@ -229,7 +229,7 @@ echo Display::div($table, array('class'=>'span10'));
 $exercise_actions = Display::url(get_lang('EndTest'), 'javascript://', array('onclick'=>'final_submit();', 'class'=>'btn btn-warning'));
 $exercise_actions .=  '&nbsp;'.Display::url(get_lang('ReviewQuestions'), 'javascript://', array('onclick'=>'review_questions();','class'=>'btn btn-success'));
 
-echo Display::div('', array('class'=>'clear'));
+echo Display::div(' ', array('class'=>'clear'));
 echo Display::div($exercise_actions, array('class'=>'form-actions'));
 
 if ($origin != 'learnpath') {

+ 21 - 2
main/exercice/exercise_submit.php

@@ -41,6 +41,8 @@ require_once '../inc/global.inc.php';
 $current_course_tool  = TOOL_QUIZ;
 require_once 'exercise.lib.php';
 
+$nameTools = get_lang('Quiz');
+
 $this_section = SECTION_COURSES;
 
 if ($debug) { error_log('--- Enter to the exercise_submit.php ---- '); error_log('0. POST variables : '.print_r($_POST,1)); }
@@ -205,6 +207,23 @@ jsPlumb.ready(function() {
 	}
 });
 
+$(function(){
+    $(".highlight_image").on("click", function() {
+        $(this).parent().find(".highlight_image").each(function(index){
+            $(this).find("img").css({
+                "border" :"none"
+            });
+            $(this).find("label").find("input").attr("checked", false);
+        });
+
+        $(this).find("label").find("img").css({
+            "border": "5px solid #f00"
+        });
+        $(this).find("label").find("input").attr("checked", "checked");
+
+    });
+});
+
 </script>';
 
 // General parameters passed via POST/GET
@@ -1145,7 +1164,7 @@ function render_question_list($objExercise, $questionList, $current_question, $e
         }
 
         //Medias question render
-        if (isset($media_questions) && !empty($media_questions)) {
+        if (isset($media_questions) && !empty($media_questions) && isset($media_questions[$questionId])) {
             $media_question_list = $media_questions[$questionId];
             $objQuestionTmp = Question::read($questionId);
 
@@ -1252,7 +1271,7 @@ function render_question($objExercise, $questionId, $attempt_list, $remind_list,
             $remind_question_div = Display::tag('label', Display::input('checkbox', 'remind_list['.$questionId.']', '', $attributes).get_lang('ReviewQuestionLater'), array('class' => 'checkbox', 'for' =>'remind_list['.$questionId.']'));
             $exercise_actions   .= Display::div($remind_question_div, array('class'=>'exercise_save_now_button'));
         }
-
+        echo Display::div(' ', array('class'=>'clear'));
         echo Display::div($exercise_actions, array('class'=>'form-actions'));
     echo '</div>';
 }

+ 6 - 1
main/exercice/question.class.php

@@ -28,6 +28,7 @@ define('MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE', 12);
 define('ORAL_EXPRESSION', 13);
 define('GLOBAL_MULTIPLE_ANSWER', 14);
 define('MEDIA_QUESTION', 15);
+define('UNIQUE_ANSWER_IMAGE', 16);
 
 //Some alias used in the QTI exports
 define('MCUA', 1);
@@ -80,7 +81,8 @@ abstract class Question
             'MultipleAnswerCombinationTrueFalse'
         ),
         GLOBAL_MULTIPLE_ANSWER => array('global_multiple_answer.class.php', 'GlobalMultipleAnswer'),
-        MEDIA_QUESTION => array('media_question.class.php', 'MediaQuestion')
+        MEDIA_QUESTION => array('media_question.class.php', 'MediaQuestion'),
+        UNIQUE_ANSWER_IMAGE => array('unique_answer_image.class.php', 'UniqueAnswerImage')
     );
 
     /**
@@ -1627,6 +1629,8 @@ abstract class Question
      * @param type $feedback_type
      * @param type $counter
      * @param type $score
+     *
+     * @return string
      */
     function return_header($feedback_type = null, $counter = null, $score = null)
     {
@@ -1655,6 +1659,7 @@ abstract class Question
         // display question category, if any
         //$header = Testcategory::returnCategoryAndTitle($this->id);
         $show_media = null;
+        $header = null;
         if ($show_media) {
             $header .= $this->show_media_content();
         }

+ 2 - 5
main/exercice/result.php

@@ -22,9 +22,8 @@ require_once '../inc/global.inc.php';
 require_once 'exercise.lib.php';
 
 if (empty($origin)) {
-    $origin = $_REQUEST['origin'];
+    $origin = isset($_REQUEST['origin']) ? $_REQUEST['origin'] : null;
 }
-
 $id 	       = isset($_REQUEST['id']) 	  ? intval($_GET['id']) : null; //exe id
 $show_headers  = isset($_REQUEST['show_headers']) ? intval($_REQUEST['show_headers']) : null; //exe id
 
@@ -76,6 +75,4 @@ if ($show_headers) {
 
 display_question_list_by_attempt($objExercise, $id, false);
 
-if ($show_headers) {
-	Display::display_footer();
-}
+Display::display_footer();

+ 379 - 0
main/exercice/unique_answer_image.class.php

@@ -0,0 +1,379 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ *    File containing the UNIQUE_ANSWER class.
+ * @package chamilo.exercise
+ * @author Eric Marguin
+ */
+/**
+ * Code
+ */
+
+/**
+ *
+ *    This class allows to instantiate an object of type UNIQUE_ANSWER_IMAGE
+ *    extending the class question
+ *
+
+ * @author Julio Montoya
+ * @package chamilo.exercise
+ **/
+
+class UniqueAnswerImage extends UniqueAnswer
+{
+
+    static $typePicture = 'mcua.gif';
+    static $explanationLangVar = 'UniqueSelect';
+
+    /**
+     * Constructor
+     */
+    function UniqueAnswerImage()
+    {
+        //this is highly important
+        parent::question();
+        $this->type      = UNIQUE_ANSWER_IMAGE;
+        $this->isContent = $this->getIsContent();
+    }
+
+    /**
+     * function which redifines Question::createAnswersForm
+     * @param the formvalidator instance
+     * @param the answers number to display
+     */
+    function createAnswersForm($form)
+    {
+        // Getting the exercise list
+        $obj_ex = $_SESSION['objExercise'];
+
+        $editor_config = array('ToolbarSet' => 'UniqueAnswerImage', 'Width' => '100%', 'Height' => '125');
+
+        //this line define how many question by default appear when creating a choice question
+        $nb_answers = isset($_POST['nb_answers']) ? (int)$_POST['nb_answers'] : 4; // The previous default value was 2. See task #1759.
+        $nb_answers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0));
+
+        $feedback_title = '';
+        $comment_title  = '';
+
+        if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_END) {
+            $comment_title = '<th>'.get_lang('Comment').'</th>';
+        } elseif ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
+            //Scenario
+            $editor_config['Width']  = '250';
+            $editor_config['Height'] = '110';
+            $comment_title           = '<th width="500px" >'.get_lang('Comment').'</th>';
+            $feedback_title          = '<th width="350px" >'.get_lang('Scenario').'</th>';
+        }
+
+        $html = '<table class="data_table">
+                <tr style="text-align: center;">
+                    <th width="10px">
+                        '.get_lang('Number').'
+                    </th>
+                    <th width="10px" >
+                        '.get_lang('True').'
+                    </th>
+                    <th width="50%">
+                        '.get_lang('Answer').'
+                    </th>
+                        '.$comment_title.'
+                        '.$feedback_title.'
+                    <th width="50px">
+                        '.get_lang('Weighting').'
+                    </th>
+                </tr>';
+
+        $form->addElement('label', get_lang('Answers').'<br /> <img src="../img/fill_field.png">', $html);
+
+        $defaults = array();
+        $correct  = 0;
+        if (!empty($this->id)) {
+            $answer = new Answer($this->id);
+            $answer->read();
+            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
+                $nb_answers = $answer->nbrAnswers;
+            }
+        }
+        $form->addElement('hidden', 'nb_answers');
+
+        //Feedback SELECT
+        $question_list      = $obj_ex->selectQuestionList();
+        $select_question    = array();
+        $select_question[0] = get_lang('SelectTargetQuestion');
+
+        require_once '../newscorm/learnpathList.class.php';
+        if (is_array($question_list)) {
+            foreach ($question_list as $key => $questionid) {
+                //To avoid warning messages
+                if (!is_numeric($questionid)) {
+                    continue;
+                }
+                $question = Question::read($questionid);
+
+                if ($question) {
+                    $select_question[$questionid] = 'Q'.$key.' :'.cut($question->selectTitle(), 20);
+                }
+            }
+        }
+        $select_question[-1] = get_lang('ExitTest');
+
+        $list            = new LearnpathList(api_get_user_id());
+        $flat_list       = $list->get_flat_list();
+        $select_lp_id    = array();
+        $select_lp_id[0] = get_lang('SelectTargetLP');
+
+        foreach ($flat_list as $id => $details) {
+            $select_lp_id[$id] = cut($details['lp_name'], 20);
+        }
+
+        $temp_scenario = array();
+
+        if ($nb_answers < 1) {
+            $nb_answers = 1;
+            Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer'));
+        }
+
+        for ($i = 1; $i <= $nb_answers; ++$i) {
+            $form->addElement('html', '<tr>');
+            if (isset($answer) && is_object($answer)) {
+                if ($answer->correct[$i]) {
+                    $correct = $i;
+                }
+                $defaults['answer['.$i.']']    = $answer->answer[$i];
+                $defaults['comment['.$i.']']   = $answer->comment[$i];
+                $defaults['weighting['.$i.']'] = float_format($answer->weighting[$i], 1);
+
+                $item_list = explode('@@', $answer->destination[$i]);
+
+                $try       = $item_list[0];
+                $lp        = $item_list[1];
+                $list_dest = $item_list[2];
+                $url       = $item_list[3];
+
+                if ($try == 0) {
+                    $try_result = 0;
+                } else {
+                    $try_result = 1;
+                }
+                if ($url == 0) {
+                    $url_result = '';
+                } else {
+                    $url_result = $url;
+                }
+
+                $temp_scenario['url'.$i]         = $url_result;
+                $temp_scenario['try'.$i]         = $try_result;
+                $temp_scenario['lp'.$i]          = $lp;
+                $temp_scenario['destination'.$i] = $list_dest;
+            } else {
+                $defaults['answer[1]']    = get_lang('DefaultUniqueAnswer1');
+                $defaults['weighting[1]'] = 10;
+                $defaults['answer[2]']    = get_lang('DefaultUniqueAnswer2');
+                $defaults['weighting[2]'] = 0;
+
+                $temp_scenario['destination'.$i] = array('0');
+                $temp_scenario['lp'.$i]          = array('0');
+            }
+            $defaults['scenario'] = $temp_scenario;
+
+            $renderer = $form->defaultRenderer();
+
+            $renderer->setElementTemplate(
+                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
+                'correct'
+            );
+            $renderer->setElementTemplate(
+                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
+                'counter['.$i.']'
+            );
+            $renderer->setElementTemplate(
+                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
+                'answer['.$i.']'
+            );
+            $renderer->setElementTemplate(
+                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
+                'comment['.$i.']'
+            );
+            $renderer->setElementTemplate(
+                '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>',
+                'weighting['.$i.']'
+            );
+
+            $answer_number = $form->addElement('text', 'counter['.$i.']', null, ' value = "'.$i.'"');
+            $answer_number->freeze();
+
+            $form->addElement('radio', 'correct', null, null, $i, 'class="checkbox" style="margin-left: 0em;"');
+            $form->addElement('html_editor', 'answer['.$i.']', null, 'style="vertical-align:middle"', $editor_config);
+
+            $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required');
+
+            if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_END) {
+                // feedback
+                $form->addElement(
+                    'html_editor',
+                    'comment['.$i.']',
+                    null,
+                    'style="vertical-align:middle"',
+                    $editor_config
+                );
+            } elseif ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
+                $form->addElement(
+                    'html_editor',
+                    'comment['.$i.']',
+                    null,
+                    'style="vertical-align:middle"',
+                    $editor_config
+                );
+                // Direct feedback
+
+                //Adding extra feedback fields
+                $group                   = array();
+                $group['try'.$i]         = $form->createElement('checkbox', 'try'.$i, null, get_lang('TryAgain'));
+                $group['lp'.$i]          = $form->createElement(
+                    'select',
+                    'lp'.$i,
+                    get_lang('SeeTheory').': ',
+                    $select_lp_id
+                );
+                $group['destination'.$i] = $form->createElement(
+                    'select',
+                    'destination'.$i,
+                    get_lang('GoToQuestion').': ',
+                    $select_question
+                );
+                $group['url'.$i]         = $form->createElement(
+                    'text',
+                    'url'.$i,
+                    get_lang('Other').': ',
+                    array('class' => 'span2', 'placeholder' => get_lang('Other'))
+                );
+                $form->addGroup($group, 'scenario');
+
+                $renderer->setElementTemplate(
+                    '<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}',
+                    'scenario'
+                );
+
+            }
+            $form->addElement('text', 'weighting['.$i.']', null, array('class' => "span1", 'value' => '0'));
+            $form->addElement('html', '</tr>');
+        }
+
+        $form->addElement('html', '</table>');
+        $form->addElement('html', '<br />');
+
+        $navigator_info = api_get_navigator();
+
+        global $text, $class;
+
+        //ie6 fix
+        if ($obj_ex->edit_exercise_in_lp == true) {
+            if ($navigator_info['name'] == 'Internet Explorer' && $navigator_info['version'] == '6') {
+                $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'), 'class="btn minus"');
+                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn plus"');
+                $form->addElement('submit', 'submitQuestion', $text, 'class="'.$class.'"');
+            } else {
+                //setting the save button here and not in the question class.php
+                $form->addElement('style_submit_button', 'lessAnswers', get_lang('LessAnswer'), 'class="btn minus"');
+                $form->addElement('style_submit_button', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn plus"');
+                $form->addElement('style_submit_button', 'submitQuestion', $text, 'class="'.$class.'"');
+            }
+        }
+        $renderer->setElementTemplate('{element}&nbsp;', 'submitQuestion');
+        $renderer->setElementTemplate('{element}&nbsp;', 'lessAnswers');
+        $renderer->setElementTemplate('{element}&nbsp;', 'moreAnswers');
+
+        $form->addElement('html', '</div></div>');
+
+        //We check the first radio button to be sure a radio button will be check
+        if ($correct == 0) {
+            $correct = 1;
+        }
+        $defaults['correct'] = $correct;
+
+        if (!empty($this->id)) {
+            $form->setDefaults($defaults);
+        } else {
+            if ($this->isContent == 1) {
+                $form->setDefaults($defaults);
+            }
+        }
+        $form->setConstants(array('nb_answers' => $nb_answers));
+    }
+
+
+    /**
+     * abstract function which creates the form to create / edit the answers of the question
+     * @param the formvalidator instance
+     * @param the answers number to display
+     */
+    function processAnswersCreation($form)
+    {
+
+        $questionWeighting = $nbrGoodAnswers = 0;
+        $correct           = $form->getSubmitValue('correct');
+        $objAnswer         = new Answer($this->id);
+        $nb_answers        = $form->getSubmitValue('nb_answers');
+
+        for ($i = 1; $i <= $nb_answers; $i++) {
+            $answer    = trim($form->getSubmitValue('answer['.$i.']'));
+            $comment   = trim($form->getSubmitValue('comment['.$i.']'));
+            $weighting = trim($form->getSubmitValue('weighting['.$i.']'));
+
+            $scenario = $form->getSubmitValue('scenario');
+
+            //$list_destination = $form -> getSubmitValue('destination'.$i);
+            //$destination_str = $form -> getSubmitValue('destination'.$i);
+
+            $try         = $scenario['try'.$i];
+            $lp          = $scenario['lp'.$i];
+            $destination = $scenario['destination'.$i];
+            $url         = trim($scenario['url'.$i]);
+
+
+
+            $goodAnswer = ($correct == $i) ? true : false;
+
+            if ($goodAnswer) {
+                $nbrGoodAnswers++;
+                $weighting = abs($weighting);
+                if ($weighting > 0) {
+                    $questionWeighting += $weighting;
+                }
+            }
+
+            if (empty($try)) {
+                $try = 0;
+            }
+
+            if (empty($lp)) {
+                $lp = 0;
+            }
+
+            if (empty($destination)) {
+                $destination = 0;
+            }
+
+            if ($url == '') {
+                $url = 0;
+            }
+
+            //1@@1;2;@@2;4;4;@@http://www.chamilo.org
+            $dest = $try.'@@'.$lp.'@@'.$destination.'@@'.$url;
+            $objAnswer->createAnswer($answer, $goodAnswer, $comment, $weighting, $i, null, null, $dest);
+        }
+
+        // saves the answers into the data base
+        $objAnswer->save();
+
+        // sets the total weighting of the question
+        $this->updateWeighting($questionWeighting);
+        $this->save();
+    }
+
+    function return_header($feedback_type = null, $counter = null, $score = null, $show_media = false)
+    {
+        return parent::return_header($feedback_type, $counter, $score, $show_media);
+    }
+}

+ 3 - 2
main/inc/global.inc.php

@@ -778,7 +778,8 @@ if (is_array($language_files)) {
 }
 
 
-error_reporting(-1);
+//error_reporting(-1);
+error_reporting(E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR);
 
 if (api_get_setting('server_type') == 'test') {
     //error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
@@ -788,7 +789,7 @@ if (api_get_setting('server_type') == 'test') {
     - normal error reporting level
     - full fake register globals block
     */
-    error_reporting(E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR);
+    //error_reporting(E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR);
     /*
         // TODO: These obsolete variables $HTTP_* to be check whether they are actually used.
         if (!isset($HTTP_GET_VARS)) {

+ 76 - 23
main/inc/lib/exercise_show_functions.lib.php

@@ -56,20 +56,20 @@ class ExerciseShowFunctions {
 	 * @return void
 	 */
 	static function display_free_answer($answer, $exe_id, $questionId, $questionScore = null) {
-        global $feedback_type;        
-        
+        global $feedback_type;
+
         $comments = get_comments($exe_id, $questionId);
-        
+
         if (!empty($answer)) {
             echo '<tr><td>';
             echo nl2br(Security::remove_XSS($answer, COURSEMANAGERLOWSECURITY));
             echo '</td></tr>';
         }
-        
-        if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {            
-            if ($questionScore > 0 || !empty($comments)) {                
+
+        if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
+            if ($questionScore > 0 || !empty($comments)) {
             } else {
-                echo '<tr>';                
+                echo '<tr>';
                 echo Display::tag('td', Display::return_message(get_lang('notCorrectedYet')), array());
                 echo '</tr>';
             }
@@ -122,19 +122,19 @@ class ExerciseShowFunctions {
 	static function display_hotspot_answer($answerId, $answer, $studentChoice, $answerComment) {
 		global $feedback_type;
 		$hotspot_colors = array("", // $i starts from 1 on next loop (ugly fix)
-	            						"#4271B5",
-										"#FE8E16",
-										"#45C7F0",
-										"#BCD631",
-										"#D63173",
-										"#D7D7D7",
-										"#90AFDD",
-										"#AF8640",
-										"#4F9242",
-										"#F4EB24",
-										"#ED2024",
-										"#3B3B3B",
-										"#F7BDE2");
+            "#4271B5",
+            "#FE8E16",
+            "#45C7F0",
+            "#BCD631",
+            "#D63173",
+            "#D7D7D7",
+            "#90AFDD",
+            "#AF8640",
+            "#4F9242",
+            "#F4EB24",
+            "#ED2024",
+            "#3B3B3B",
+            "#F7BDE2");
 		?>
 		<table class="data_table">
 		<tr>
@@ -187,14 +187,15 @@ class ExerciseShowFunctions {
 	 */
 	static function display_unique_or_multiple_answer($answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $id, $questionId, $ans) {
 		global $feedback_type;
+
 		?>
 		<tr>
 		<td width="5%">
-			<img src="../img/<?php echo (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION))) ? 'radio':'checkbox'; echo $studentChoice?'_on':'_off'; ?>.gif"
+			<img src="../img/<?php echo (in_array($answerType, array(UNIQUE_ANSWER,UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION))) ? 'radio':'checkbox'; echo $studentChoice?'_on':'_off'; ?>.gif"
 			border="0" alt="" />
 		</td>
 		<td width="5%">
-			<img src="../img/<?php echo (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION))) ? 'radio':'checkbox'; echo $answerCorrect?'_on':'_off'; ?>.gif"
+			<img src="../img/<?php echo (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION))) ? 'radio':'checkbox'; echo $answerCorrect?'_on':'_off'; ?>.gif"
 			border="0" alt=" " />
 		</td>
 		<td width="40%">
@@ -237,6 +238,58 @@ class ExerciseShowFunctions {
 		<?php
 	}
 
+    static function display_unique_image_answer($answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $id, $questionId, $ans) {
+        global $feedback_type;
+        ?>
+    <tr>
+        <td width="5%">
+            <img src="../img/<?php echo (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION))) ? 'radio':'checkbox'; echo $studentChoice?'_on':'_off'; ?>.gif"
+                 border="0" alt="" />
+        </td>
+        <td width="5%">
+            <img src="../img/<?php echo (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION))) ? 'radio':'checkbox'; echo $answerCorrect?'_on':'_off'; ?>.gif"
+                 border="0" alt=" " />
+        </td>
+        <td width="40%">
+            <?php
+            echo $answer;
+            ?>
+        </td>
+
+        <?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
+        <td width="20%">
+            <?php
+            if ($studentChoice) {
+                if ($answerCorrect) {
+                    $color = 'green';
+                    //echo '<span style="font-weight: bold; color: #008000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                } else {
+                    $color = 'black';
+                    //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                }
+                echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br(make_clickable($answerComment)).'</span>';
+
+            } else {
+                if ($answerCorrect) {
+                    //echo '<span style="font-weight: bold; color: #000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                } else {
+                    //echo '<span style="font-weight: normal; color: #000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                }
+            }
+            ?>
+        </td>
+        <?php
+        if ($ans==1) {
+            $comm = get_comments($id,$questionId);
+        }
+        ?>
+        <?php } else { ?>
+        <td>&nbsp;</td>
+        <?php } ?>
+    </tr>
+        <?php
+    }
+
     /**
      * Display the answers to a multiple choice question
      *
@@ -285,7 +338,7 @@ class ExerciseShowFunctions {
 
         <?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
         <td width="20%">
-            <?php            
+            <?php
             $color = "black";
             if (isset($new_options[$studentChoice])) {
                 if ($studentChoice == $answerCorrect) {

+ 20 - 0
main/inc/lib/fckeditor/toolbars/default/unique_answer_image.php

@@ -0,0 +1,20 @@
+<?php
+// Chamilo LMS
+// See license terms in chamilo/documentation/license.txt
+
+// Training tools
+// Test, proposed answer to a question
+
+// For more information: http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options
+
+// This is the visible toolbar set when the editor has "normal" size.
+$config['ToolbarSets']['Normal'] = array(
+    array('FitWindow', 'Image', 'Source')
+);
+
+
+// Sets how the editor's toolbar should start - expanded or collapsed.
+// Possible values: true , false
+$config['ToolbarStartExpanded'] = true;
+
+