Browse Source

Merge branch '1.9.x' of ssh://github.com/chamilo/chamilo-lms into chamilo19

Julio Montoya 10 years ago
parent
commit
6e31136b34
100 changed files with 666 additions and 32 deletions
  1. 50 2
      main/auth/courses.php
  2. 160 0
      main/auth/courses_controller.php
  3. 228 0
      main/exercice/calculated_answer.class.php
  4. 113 11
      main/exercice/exercise.class.php
  5. 93 1
      main/exercice/exercise.lib.php
  6. 5 3
      main/exercice/exercise_submit.php
  7. 1 1
      main/exercice/fill_blanks.class.php
  8. 1 1
      main/exercice/freeanswer.class.php
  9. 1 1
      main/exercice/global_multiple_answer.class.php
  10. 1 1
      main/exercice/hotspot.class.php
  11. 1 1
      main/exercice/matching.class.php
  12. 1 1
      main/exercice/multiple_answer.class.php
  13. 1 1
      main/exercice/multiple_answer_combination.class.php
  14. 1 1
      main/exercice/multiple_answer_combination_true_false.class.php
  15. 1 1
      main/exercice/multiple_answer_true_false.class.php
  16. 6 4
      main/exercice/question.class.php
  17. 1 1
      main/exercice/unique_answer.class.php
  18. 1 1
      main/exercice/unique_answer_no_option.class.php
  19. BIN
      main/img/audio_question.png
  20. BIN
      main/img/calculated_answer.png
  21. BIN
      main/img/database.png
  22. BIN
      main/img/fill_in_blanks.gif
  23. BIN
      main/img/hotspot.gif
  24. BIN
      main/img/icons/128/audio_question.png
  25. BIN
      main/img/icons/128/calculated_answer.png
  26. BIN
      main/img/icons/128/database.png
  27. BIN
      main/img/icons/128/fill_in_blanks.png
  28. BIN
      main/img/icons/128/hotspot.png
  29. BIN
      main/img/icons/128/matching.png
  30. BIN
      main/img/icons/128/mcma.png
  31. BIN
      main/img/icons/128/mcmac.png
  32. BIN
      main/img/icons/128/mcmaco.png
  33. BIN
      main/img/icons/128/mcmagl.png
  34. BIN
      main/img/icons/128/mcmao.png
  35. BIN
      main/img/icons/128/mcua.png
  36. BIN
      main/img/icons/128/mcuao.png
  37. BIN
      main/img/icons/128/open_answer.png
  38. BIN
      main/img/icons/16/audio_question.png
  39. BIN
      main/img/icons/16/database.png
  40. BIN
      main/img/icons/16/fill_in_blanks.png
  41. BIN
      main/img/icons/16/hotspot.png
  42. BIN
      main/img/icons/16/matching.png
  43. BIN
      main/img/icons/16/mcma.png
  44. BIN
      main/img/icons/16/mcmac.png
  45. BIN
      main/img/icons/16/mcmaco.png
  46. BIN
      main/img/icons/16/mcmagl.png
  47. BIN
      main/img/icons/16/mcmao.png
  48. BIN
      main/img/icons/16/mcua.png
  49. BIN
      main/img/icons/16/mcuao.png
  50. BIN
      main/img/icons/16/open_answer.png
  51. BIN
      main/img/icons/22/audio_question.png
  52. BIN
      main/img/icons/22/database.png
  53. BIN
      main/img/icons/22/fill_in_blanks.png
  54. BIN
      main/img/icons/22/hotspot.png
  55. BIN
      main/img/icons/22/matching.png
  56. BIN
      main/img/icons/22/mcma.png
  57. BIN
      main/img/icons/22/mcmac.png
  58. BIN
      main/img/icons/22/mcmaco.png
  59. BIN
      main/img/icons/22/mcmagl.png
  60. BIN
      main/img/icons/22/mcmao.png
  61. BIN
      main/img/icons/22/mcua.png
  62. BIN
      main/img/icons/22/mcuao.png
  63. BIN
      main/img/icons/22/open_answer.png
  64. BIN
      main/img/icons/32/audio_question.png
  65. BIN
      main/img/icons/32/calculated_answer.png
  66. BIN
      main/img/icons/32/database.png
  67. BIN
      main/img/icons/32/fill_in_blanks.gif
  68. BIN
      main/img/icons/32/fill_in_blanks.png
  69. BIN
      main/img/icons/32/hotspot.gif
  70. BIN
      main/img/icons/32/hotspot.png
  71. BIN
      main/img/icons/32/matching.gif
  72. BIN
      main/img/icons/32/matching.png
  73. BIN
      main/img/icons/32/mcma.gif
  74. BIN
      main/img/icons/32/mcma.png
  75. BIN
      main/img/icons/32/mcmac.gif
  76. BIN
      main/img/icons/32/mcmac.png
  77. BIN
      main/img/icons/32/mcmaco.gif
  78. BIN
      main/img/icons/32/mcmaco.png
  79. BIN
      main/img/icons/32/mcmagl.gif
  80. BIN
      main/img/icons/32/mcmagl.png
  81. BIN
      main/img/icons/32/mcmao.gif
  82. BIN
      main/img/icons/32/mcmao.png
  83. BIN
      main/img/icons/32/mcua.gif
  84. BIN
      main/img/icons/32/mcua.png
  85. BIN
      main/img/icons/32/mcuao.gif
  86. BIN
      main/img/icons/32/mcuao.png
  87. BIN
      main/img/icons/32/open_answer.gif
  88. BIN
      main/img/icons/32/open_answer.png
  89. BIN
      main/img/icons/48/audio_question.png
  90. BIN
      main/img/icons/48/database.png
  91. BIN
      main/img/icons/48/fill_in_blanks.png
  92. BIN
      main/img/icons/48/hotspot.png
  93. BIN
      main/img/icons/48/matching.png
  94. BIN
      main/img/icons/48/mcma.png
  95. BIN
      main/img/icons/48/mcmac.png
  96. BIN
      main/img/icons/48/mcmaco.png
  97. BIN
      main/img/icons/48/mcmagl.png
  98. BIN
      main/img/icons/48/mcmao.png
  99. BIN
      main/img/icons/48/mcua.png
  100. BIN
      main/img/icons/48/mcuao.png

+ 50 - 2
main/auth/courses.php

@@ -76,8 +76,8 @@ if (api_is_platform_admin() || api_is_course_admin() || api_is_allowed_to_create
 }
 
 // filter actions
-$actions = array('sortmycourses', 'createcoursecategory', 'subscribe', 'deletecoursecategory', 'display_courses', 'display_random_courses', 'subscribe_user_with_password');
-$action = 'display_random_courses';
+$actions = array('sortmycourses', 'createcoursecategory', 'subscribe', 'deletecoursecategory', 'display_courses', 'display_random_courses', 'subscribe_user_with_password', 'display_sessions');
+$action = CoursesAndSessionsCatalog::is(CATALOG_SESSIONS) ? 'display_sessions' : 'display_random_courses';
 $nameTools = get_lang('SortMyCourses');
 
 if (isset($_GET['action']) && in_array($_GET['action'],$actions)) {
@@ -99,6 +99,10 @@ if ($action == 'display_random_courses' || $action == 'display_courses' ) {
 	$nameTools = get_lang('CourseManagement');
 }
 
+if ($action == 'display_sessions') {
+    $nameTools = get_lang('Sessions');
+}
+
 // Breadcrumbs.
 $interbreadcrumb[] = array('url' => api_get_path(WEB_PATH).'user_portal.php', 'name' => get_lang('MyCourses'));
 
@@ -215,4 +219,48 @@ switch ($action) {
     case 'display_courses':
         $courses_controller->courses_categories($action, $_GET['category_code']);
         break;
+    case 'display_sessions':
+        $date = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
+        $hiddenLinks = isset($_GET['hidden_links']) ? intval($_GET['hidden_links']) == 1 : false;
+
+        $authModel = new Auth();
+        $sessions = $authModel->browseSessions($date);
+
+        $sessionsBlocks = array();
+
+        foreach ($sessions as $session) {
+            $sessionsBlocks[] = array(
+                'id' => $session['id'],
+                'name' => $session['name'],
+                'nbr_courses' => $session['nbr_courses'],
+                'nbr_users' => $session['nbr_users'],
+                'coach_name' => $session['coach_name'],
+                'is_subscribed' => $session['is_subscribed'],
+                'icon' => $courses_controller->getSessionIcon($session['name']),
+                'date' => SessionManager::getSessionFormattedDate($session),
+                'subscribe_button' => $courses_controller->getRegisterInSessionButton($session['name'])
+            );
+        }
+
+        $tpl = new Template();
+        $tpl->assign('action', $action);
+        $tpl->assign('showCourses', CoursesAndSessionsCatalog::showCourses());
+        $tpl->assign('showSessions', CoursesAndSessionsCatalog::showSessions());
+        $tpl->assign('api_get_self', api_get_self());
+        $tpl->assign('nameTools', $nameTools);
+
+        $tpl->assign('coursesCategoriesList', $courses_controller->getCoursesCategoriesBlock());
+
+        $tpl->assign('hiddenLinks', $hiddenLinks);
+        $tpl->assign('searchToken', Security::get_token());
+
+        $tpl->assign('searchDate', $date);
+        $tpl->assign('web_session_courses_ajax_url', api_get_path(WEB_AJAX_PATH) . 'course.ajax.php');
+        $tpl->assign('sessions_blocks', $sessionsBlocks);
+        $tpl->assign('already_subscribed_label', $courses_controller->getAlreadyRegisterInSessionLabel());
+
+        $conentTemplate = $tpl->get_template('auth/sessions_catalog.tpl');
+
+        $tpl->display($conentTemplate);
+        break;
 }

+ 160 - 0
main/auth/courses_controller.php

@@ -82,6 +82,8 @@ class CoursesController
     {
         $data = array();
         $browse_course_categories = $this->model->browse_course_categories();
+        
+        global $_configuration;
 
         if ($action == 'display_random_courses') {
             $data['browse_courses_in_category'] = $this->model->browse_courses_in_category(null, 10);
@@ -119,6 +121,12 @@ class CoursesController
         $data['message']          = $message;
         $data['content']          = $content;
         $data['error']            = $error;
+        
+        $data['catalogShowCoursesSessions'] = 0;
+        
+        if (isset($_configuration['catalog_show_courses_sessions'])) {
+            $data['catalogShowCoursesSessions'] = $_configuration['catalog_show_courses_sessions'];
+        }
 
         // render to the view
         $this->view->set_data($data);
@@ -320,4 +328,156 @@ class CoursesController
             $this->courses_categories('subcribe', $category_code, $message, $error);
         }
     }
+    
+    /**
+     * Get the html block for courses categories
+     * @param string $code Current category code
+     * @param boolean $hiddenLinks Whether hidden links
+     * @return string The HTML block
+     */
+    public function getCoursesCategoriesBlock($code = null, $hiddenLinks = false)
+    {
+        $categories = $this->model->browse_course_categories();
+
+        $html = '';
+
+        if (!empty($categories)) {
+
+            foreach ($categories[0] as $category) {
+                $categoryName = $category['name'];
+                $categoryCode = $category['code'];
+                $categoryCourses = $category['count_courses'];
+
+                $html .= '<li>';
+
+                if ($code == $categoryCode) {
+                    $html .= '<strong>';
+                    $html .= "$categoryName ($categoryCourses)";
+                    $html .= '</strong>';
+                } else {
+                    if (!empty($categoryCourses)) {
+                        $html .= '<a href="' . api_get_self() . '?action=display_courses&category_code=' . $categoryCode . '&hidden_links=' . $hiddenLinks . '">';
+                        $html .= "$categoryName ($categoryCourses)";
+                        $html .= '</a>';
+                    } else {
+                        $html .= "$categoryName ($categoryCourses)";
+                    }
+                }
+
+                if (!empty($categories[$categoryCode])) {
+                    $html .= '<ul class="nav nav-list">';
+
+                    foreach ($categories[$categoryCode] as $subCategory1) {
+                        $subCategory1Name = $subCategory1['name'];
+                        $subCategory1Code = $subCategory1['code'];
+                        $subCategory1Courses = $subCategory1['count_courses'];
+
+                        $html .= '<li>';
+
+                        if ($code == $subCategory1Code) {
+                            $html .= "<strong>$subCategory1Name ($subCategory1Courses)</strong>";
+                        } else {
+                            $html .= '<a href="' . api_get_self() . '?action=display_courses&category_code=' . $subCategory1Code . '&hidden_links=' . $hiddenLinks . '">';
+                            $html .= "$subCategory1Name ($subCategory1Courses)";
+                            $html .= '</a>';
+                        }
+
+                        if (!empty($categories[$subCategory1Code])) {
+                            $html .= '<ul class="nav nav-list">';
+
+                            foreach ($categories[$subCategory1Code] as $subCategory2) {
+                                $subCategory2Name = $subCategory2['name'];
+                                $subCategory2Code = $subCategory2['code'];
+                                $subCategory2Courses = $subCategory2['count_courses'];
+
+                                $html .= '<li>';
+
+                                if ($code == $subCategory2Code) {
+                                    $html .= "<strong>$subCategory2Name ($subCategory2Courses)</strong>";
+                                } else {
+                                    $html .= '<a href="' . api_get_self() . '?action=display_courses&category_code=' . $subCategory2Code . '&hidden_links=' . $hiddenLinks . '">';
+                                    $html .= "$subCategory2Name ($subCategory2Courses)";
+                                    $html .= '</a>';
+                                }
+
+                                if (!empty($categories[$subCategory2Code])) {
+                                    $html .= '<ul class="nav nav-list">';
+
+                                    foreach ($categories[$subCategory2Code] as $subCategory3) {
+                                        $subCategory3Name = $subCategory3['name'];
+                                        $subCategory3Code = $subCategory3['code'];
+                                        $subCategory3Courses = $subCategory3['count_courses'];
+
+                                        $html .= '<li>';
+
+                                        if ($code == $subCategory3Code) {
+                                            $html .= "<strong>$subCategory3Name ($subCategory3Courses)</strong>";
+                                        } else {
+                                            $html .= '<a href="' . api_get_self() . '?action=display_courses&category_code=' . $subCategory3Code . '&hidden_links=' . $hiddenLinks . '">';
+                                            $html .= "$subCategory3Name ($subCategory3Courses)";
+                                            $html .= '</a>';
+                                        }
+
+                                        $html .= '</li>';
+                                    }
+
+                                    $html .= '</ul>';
+                                }
+
+                                $html .= '</li>';
+                            }
+
+                            $html .= '</ul>';
+                        }
+
+                        $html .= '</li>';
+                    }
+
+                    $html .= '</ul>';
+                }
+
+                $html .= '</li>';
+            }
+        }
+
+        return $html;
+    }
+
+    /**
+     * Get a HTML button for subscribe to session
+     * @param string $sessionName The session name
+     * @return string The button
+     */
+    public function getRegisterInSessionButton($sessionName)
+    {
+        $sessionName = urlencode($sessionName);
+
+        $url = api_get_path(WEB_PATH) . "main/inc/email_editor.php?action=subscribe_me_to_session&session=$sessionName";
+
+        return Display::url(get_lang('Subscribe'), $url, array(
+                    'class' => 'btn btn-primary',
+        ));
+    }
+
+    /**
+     * Generate a label if the user has been  registered in session
+     * @return string The label
+     */
+    public function getAlreadyRegisterInSessionLabel()
+    {
+        $icon = Display::return_icon('students.gif', get_lang('Student'));
+
+        return Display::label($icon . ' ' . get_lang("AlreadyRegisteredToSession"), "info");
+    }
+
+    /**
+     * Get a icon for a session
+     * @param string $sessionName The session name
+     * @return string The icon
+     */
+    public function getSessionIcon($sessionName)
+    {
+        return Display::return_icon('window_list.png', $sessionName, null, ICON_SIZE_LARGE);
+    }
+
 }

+ 228 - 0
main/exercice/calculated_answer.class.php

@@ -0,0 +1,228 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ *  Class CalculatedAnswer
+ *  This class contains calculated answer form and answer processing functions
+ *
+ *  @author Imanol Losada
+ *  @package chamilo.exercise
+ **/
+class CalculatedAnswer extends Question
+{
+    static $typePicture = 'calculated_answer.png';
+    static $explanationLangVar = 'CalculatedAnswer';
+
+    /**
+     * Constructor
+     */
+    public function CalculatedAnswer()
+    {
+        parent::question();
+        $this -> type = CALCULATED_ANSWER;
+        $this -> isContent = $this-> getIsContent();
+    }
+
+    /**
+     * function which redefines Question::createAnswersForm
+     * @param the formvalidator instance
+     */
+    function createAnswersForm($form)
+    {
+        $defaults = array();
+
+        if (!empty($this->id)) {
+            $objAnswer = new answer($this->id);
+            $preArray = explode('@@', $objAnswer->selectAnswer(1));
+            $defaults['formula'] = array_pop($preArray);
+
+            $defaults['answer'] = array_shift($preArray);
+            $defaults['answer'] = preg_replace("/\[.*\]/", "", $defaults['answer']);
+
+            $defaults['weighting'] = $this->weighting;
+
+        } else {
+            $defaults['answer'] = get_lang('DefaultTextInBlanks');
+        }
+        $lowestValue = "1.00";
+        $highestValue = "20.00";
+
+        // javascript //
+        echo '<script>
+
+            function parseTextNumber(textNumber, floatValue) {
+                if (textNumber.indexOf(".") > -1) {
+                    textNumber = parseFloat(textNumber);
+                    floatValue.exists = "true";
+                } else {
+                    textNumber = parseInt(textNumber);
+                }
+                return textNumber;
+            }
+
+            function updateRandomValue(element) {
+                // "floatValue" helps to distinguish between an integer (10) and a float with all 0 decimals (10.00)
+                var floatValue = { exists: "false" };
+                var index = (element.name).match(/\[[^\]]*\]/g);
+                var lowestValue = parseTextNumber(document.getElementById("lowestValue"+index).value, floatValue);
+                var highestValue = parseTextNumber(document.getElementById("highestValue"+index).value, floatValue);
+                var result = Math.random() * (highestValue - lowestValue) + lowestValue;
+                if (floatValue.exists == "true") {
+                    result = parseFloat(result).toFixed(2);
+                } else {
+                    result = parseInt(result);
+                }
+                document.getElementById("randomValue"+index).innerHTML = "'.get_lang("ExampleValue").': " + result;
+           }
+
+            function FCKeditor_OnComplete(editorInstance) {
+                if (window.attachEvent) {
+                    editorInstance.EditorDocument.attachEvent("onkeyup", updateBlanks) ;
+                } else {
+                    editorInstance.EditorDocument.addEventListener("keyup", updateBlanks, true);
+                }
+            }
+
+            var firstTime = true;
+
+            function updateBlanks() {
+                if (firstTime) {
+                    field = document.getElementById("answer");
+                    var answer = field.value;
+                } else {
+                    var oEditor = FCKeditorAPI.GetInstance("answer");
+                    //var answer =  oEditor.GetXHTML(true);
+                    var answer = oEditor.EditorDocument.body.innerHTML;
+                }
+                var blanks = answer.match(/\[[^\]]*\]/g);
+                var fields = "<div class=\"control-group\"><label class=\"control-label\">'.get_lang('VariableRanges').'</label><div class=\"controls\"><table>";
+                if (blanks!=null) {
+                    if (typeof updateBlanks.randomValues === "undefined") {
+                        updateBlanks.randomValues = [];
+                    }
+                    for (i=0 ; i<blanks.length ; i++){
+                        if (document.getElementById("lowestValue["+i+"]") && document.getElementById("highestValue["+i+"]")) {
+                            lowestValue = document.getElementById("lowestValue["+i+"]").value;
+                            highestValue = document.getElementById("highestValue["+i+"]").value;
+                        } else {
+                            lowestValue = '.$lowestValue.'.toFixed(2);
+                            highestValue = '.$highestValue.'.toFixed(2);
+                            for (j=0; j<blanks.length; j++) {
+                                updateBlanks.randomValues[j] = parseFloat(Math.random() * (highestValue - lowestValue) + lowestValue).toFixed(2);
+                            }
+                        }
+                        fields += "<tr><td><label>"+blanks[i]+"</label></td><td><input class=\"span1\" style=\"margin-left: 0em;\" size=\"5\" value=\""+lowestValue+"\" type=\"text\" id=\"lowestValue["+i+"]\" name=\"lowestValue["+i+"]\" onblur=\"updateRandomValue(this)\"/></td><td><input class=\"span1\" style=\"margin-left: 0em; width:80px;\" size=\"5\" value=\""+highestValue+"\" type=\"text\" id=\"highestValue["+i+"]\" name=\"highestValue["+i+"]\" onblur=\"updateRandomValue(this)\"/></td><td><label class=\"span3\" id=\"randomValue["+i+"]\"/>'.get_lang('ExampleValue').': "+updateBlanks.randomValues[i]+"</label></td></tr>";
+                    }
+                }
+                document.getElementById("blanks_weighting").innerHTML = fields + "</table></div></div>";
+                if (firstTime) {
+                    firstTime = false;
+                }
+            }
+
+            window.onload = updateBlanks;
+
+        </script>';
+
+        // answer
+        $form->addElement('label', null, '<br /><br />'.get_lang('TypeTextBelow').', '.get_lang('And').' '.get_lang('UseTagForBlank'));
+        $form->addElement('html_editor', 'answer', '<img src="../img/fill_field.png">','id="answer" cols="122" rows="6" onkeyup="javascript: updateBlanks(this);"', array('ToolbarSet' => 'TestQuestionDescription', 'Width' => '100%', 'Height' => '350'));
+
+        $form->addRule('answer', get_lang('GiveText'),'required');
+        $form->addRule('answer', get_lang('DefineBlanks'),'regex','/\[.*\]/');
+
+        $form->addElement('label', null, get_lang('IfYouWantOnlyIntegerValuesWriteBothLimitsWithoutDecimals'));
+        $form->addElement('html', '<div id="blanks_weighting"></div>');
+
+        $form->addElement('label', null, get_lang('FormulaExample').': &radic;<span style="text-decoration:overline;">&nbsp;x &divide y&nbsp;</span> &times e <sup>(ln(pi))</sup> = sqrt([x]/[y])*(e^(ln(pi)))');
+        $form->addElement('text', 'formula', get_lang('Formula'), array('id' => 'formula', 'class' => 'span4'));
+        $form->addRule('formula', get_lang('GiveFormula'), 'required');
+
+        $form->addElement('text', 'weighting', get_lang('Weighting'), array('id' => 'weighting', 'class' => 'span1'));
+        $form->setDefaults(array('weighting' => '10'));
+
+        $form->addElement('text', 'answerVariations', get_lang('AnswerVariations'), array('class' => 'span1'));
+        $form->addRule('answerVariations', get_lang('GiveAnswerVariations'),'required');
+        $form->setDefaults(array('answerVariations' => '1'));
+
+        global $text, $class;
+        // setting the save button here and not in the question class.php
+        $form->addElement('style_submit_button', 'submitQuestion', $text, 'class="'.$class.'"');
+
+        if (!empty($this->id)) {
+            $form -> setDefaults($defaults);
+        } else {
+            if ($this->isContent == 1) {
+                $form->setDefaults($defaults);
+            }
+        }
+    }
+
+    /**
+     * abstract function which creates the form to create / edit the answers of the question
+     * @param FormValidator $form
+     */
+    function processAnswersCreation($form)
+    {
+        global $charset;
+        $answer = $form->getSubmitValue('answer');
+        $formula = $form->getSubmitValue('formula');
+        $lowestValues = $form->getSubmitValue('lowestValue');
+        $highestValues = $form->getSubmitValue('highestValue');
+        $answerVariations = $form->getSubmitValue('answerVariations');
+        $this->weighting = $form->getSubmitValue('weighting');
+        //Remove previous answers
+        Database::delete("c_quiz_answer", array('question_id = ?' => $this->id));
+        // Create as many answers as $answerVariations
+        for ($j=0 ; $j < $answerVariations; $j++) {
+            $auxAnswer = $answer;
+            $auxFormula = $formula;
+            $nb = preg_match_all('/\[[^\]]*\]/', $auxAnswer, $blanks);
+            if ($nb > 0) {
+                for ($i=0 ; $i < $nb; ++$i) {
+                    $blankItem = $blanks[0][$i];
+                    $replace = array("[", "]");
+                    $newBlankItem = str_replace($replace, "", $blankItem);
+                    $newBlankItem = "[".trim($newBlankItem)."]";
+                    $randomValue = mt_rand($lowestValues[$i],$highestValues[$i]);
+                    //$randomValue = mt_rand($lowestValues[$i]*100,$highestValues[$i]*100)/100;
+                    $auxAnswer = str_replace($blankItem, $randomValue, $auxAnswer);
+                    $auxFormula = str_replace($blankItem, $randomValue, $auxFormula);
+                }
+                require_once(api_get_path(LIBRARY_PATH).'evalmath.class.php');
+                $math = new EvalMath();
+                $result = $math->evaluate($auxFormula);
+                $result = number_format($result, 2, ".", "");
+                // Remove decimal trailing zeros
+                $result = rtrim($result, "0");
+                // If it is an integer (ends in .00) remove the decimal point
+                if (mb_substr($result, -1) === ".") {
+                    $result = str_replace(".", "", $result);
+                }
+                // Attach formula
+                $auxAnswer .= " [".$result."]@@".$formula;
+            }
+            $this->save();
+            $objAnswer = new answer($this->id);
+            $objAnswer->createAnswer($auxAnswer, 1, '', $this->weighting, array());
+            $objAnswer->position = array();
+            $objAnswer->save();
+
+        }
+    }
+
+    /**
+     * @param null $feedback_type
+     * @param null $counter
+     * @param null $score
+     * @return null|string
+     */
+    function return_header($feedback_type = null, $counter = null, $score = null)
+    {
+        $header = parent::return_header($feedback_type, $counter, $score);
+        $header .= '<table class="'.$this->question_table_class .'">
+            <tr>
+                <th>'.get_lang("Answer").'</th>
+            </tr>';
+        return $header;
+    }
+}

+ 113 - 11
main/exercice/exercise.class.php

@@ -1736,7 +1736,7 @@ class Exercise
         return $id;
     }
 
-    public function show_button($question_id, $questionNum, $questions_in_media = array()) {
+    public function show_button($question_id, $questionNum, $questions_in_media = array(), $currentAnswer = '') {
         global $origin, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id;
 
         $nbrQuestions = $this->get_count_question_list();
@@ -1779,7 +1779,7 @@ class Exercise
                         $questions_in_media = "['".implode("','",$questions_in_media)."']";
                         $all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_question_list('.$questions_in_media.'); ">'.$label.'</a>';
                     } else {
-                        $all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_now('.$question_id.'); ">'.$label.'</a>';
+                        $all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_now('.$question_id.', \'\', \''.$currentAnswer.'\'); ">'.$label.'</a>';
                     }
                     $all_button .= '<span id="save_for_now_'.$question_id.'" class="exercise_save_mini_message"></span>&nbsp;';
 
@@ -2123,7 +2123,7 @@ class Exercise
             error_log('$answerType: '.$answerType);
         }
 
-        if ($answerType == FREE_ANSWER || $answerType == ORAL_EXPRESSION) {
+        if ($answerType == FREE_ANSWER || $answerType == ORAL_EXPRESSION || $answerType == CALCULATED_ANSWER) {
             $nbrAnswers = 1;
         }
 
@@ -2521,6 +2521,102 @@ class Exercise
                         }
                     }
                     break;
+                // for calculated answer
+                case CALCULATED_ANSWER:
+                    $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]);
+                    $preArray = explode('@@', $answer);
+                    $last = count($preArray) - 1;
+                    $answer = '';
+                    for ($k = 0; $k < $last; $k++) {
+                        $answer .= $preArray[$k];
+                    }
+                    $answerWeighting = array($answerWeighting);
+                    // we save the answer because it will be modified
+                    $temp = $answer;
+                    $answer = '';
+                    $j = 0;
+                    //initialise answer tags
+                    $userTags = $correctTags = $realText = array();
+                    // the loop will stop at the end of the text
+                    while (1) {
+                        // quits the loop if there are no more blanks (detect '[')
+                        if (($pos = api_strpos($temp, '[')) === false) {
+                            // adds the end of the text
+                            $answer = $temp;
+                            $realText[] = $answer;
+                            break; //no more "blanks", quit the loop
+                        }
+                        // adds the piece of text that is before the blank
+                        //and ends with '[' into a general storage array
+                        $realText[] = api_substr($temp, 0, $pos +1);
+                        $answer .= api_substr($temp, 0, $pos +1);
+                        //take the string remaining (after the last "[" we found)
+                        $temp = api_substr($temp, $pos +1);
+                        // quit the loop if there are no more blanks, and update $pos to the position of next ']'
+                        if (($pos = api_strpos($temp, ']')) === false) {
+                            // adds the end of the text
+                            $answer .= $temp;
+                            break;
+                        }
+                        if ($from_database) {
+                            $queryfill = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT."
+                                          WHERE
+                                            exe_id = '".$exeId."' AND
+                                            question_id= '".Database::escape_string($questionId)."'";
+                            $resfill = Database::query($queryfill);
+                            $str = Database::result($resfill, 0, 'answer');
+                            api_preg_match_all('#\[([^[]*)\]#', $str, $arr);
+                            $str = str_replace('\r\n', '', $str);
+                            $choice = $arr[1];
+                            if (isset($choice[$j])) {
+                                $tmp = api_strrpos($choice[$j], ' / ');
+                                $choice[$j] = api_substr($choice[$j], 0, $tmp);
+                                $choice[$j] = trim($choice[$j]);
+                                // Needed to let characters ' and " to work as part of an answer
+                                $choice[$j] = stripslashes($choice[$j]);
+                            } else {
+                                $choice[$j] = null;
+                            }
+                        } else {
+                            // This value is the user input, not escaped while correct answer is escaped by fckeditor
+                            $choice[$j] = api_htmlentities(trim($choice[$j]));
+                        }
+                        $userTags[] = $choice[$j];
+                        //put the contents of the [] answer tag into correct_tags[]
+                        $correctTags[] = api_substr($temp, 0, $pos);
+                        $j++;
+                        $temp = api_substr($temp, $pos +1);
+                    }
+                    $answer = '';
+                    $realCorrectTags = $correctTags;
+                    for ($i = 0; $i < count($realCorrectTags); $i++) {
+                        if ($i == 0) {
+                            $answer .= $realText[0];
+                        }
+                        // Needed to parse ' and " characters
+                        $userTags[$i] = stripslashes($userTags[$i]);
+                        if ($correctTags[$i] == $userTags[$i]) {
+                            // gives the related weighting to the student
+                            $questionScore += $answerWeighting[$i];
+                            // increments total score
+                            $totalScore += $answerWeighting[$i];
+                            // adds the word in green at the end of the string
+                            $answer .= $correctTags[$i];
+                        } elseif (!empty($userTags[$i])) {
+                            // else if the word entered by the student IS NOT the same as the one defined by the professor
+                            // adds the word in red at the end of the string, and strikes it
+                            $answer .= '<font color="red"><s>' . $userTags[$i] . '</s></font>';
+                        } else {
+                            // adds a tabulation if no word has been typed by the student
+                            $answer .= ''; // remove &nbsp; that causes issue
+                        }
+                        // adds the correct word, followed by ] to close the blank
+                        $answer .= ' / <font color="green"><b>' . $realCorrectTags[$i] . '</b></font>]';
+                        if (isset($realText[$i +1])) {
+                            $answer .= $realText[$i +1];
+                        }
+                    }
+                    break;
                 // for free answer
                 case FREE_ANSWER:
                     if ($from_database) {
@@ -2745,32 +2841,36 @@ class Exercise
                             //if ($origin != 'learnpath') {
                             ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, 0, 0, $results_disabled);
                             //}
-                        } elseif($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
+                        } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                             //if ($origin!='learnpath') {
                             ExerciseShowFunctions::display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect,0,$questionId,0, $results_disabled);
                             //}
-                        } elseif($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE ) {
+                        } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE ) {
                             //	if ($origin!='learnpath') {
                             ExerciseShowFunctions::display_multiple_answer_combination_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect,0,0,0, $results_disabled);
                             //}
-                        } elseif($answerType == FILL_IN_BLANKS) {
+                        } elseif ($answerType == FILL_IN_BLANKS) {
                             //if ($origin!='learnpath') {
                             ExerciseShowFunctions::display_fill_in_blanks_answer($feedback_type, $answer,0,0);
                             //	}
-                        } elseif($answerType == FREE_ANSWER) {
+                        } elseif ($answerType == CALCULATED_ANSWER) {
+                            //if ($origin!='learnpath') {
+                            ExerciseShowFunctions::display_calculated_answer($feedback_type, $answer,0,0);
+                            //  }
+                        } elseif ($answerType == FREE_ANSWER) {
                             //if($origin != 'learnpath') {
                             ExerciseShowFunctions::display_free_answer($feedback_type, $choice, $exeId, $questionId, $questionScore);
                             //}
-                        } elseif($answerType == ORAL_EXPRESSION) {
+                        } elseif ($answerType == ORAL_EXPRESSION) {
                             // to store the details of open questions in an array to be used in mail
                             //if ($origin != 'learnpath') {
                             ExerciseShowFunctions::display_oral_expression_answer($feedback_type, $choice, 0, 0, $nano);
                             //}
-                        } elseif($answerType == HOT_SPOT) {
+                        } elseif ($answerType == HOT_SPOT) {
                             //if ($origin != 'learnpath') {
                             ExerciseShowFunctions::display_hotspot_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment, $results_disabled);
                             //	}
-                        } elseif($answerType == HOT_SPOT_ORDER) {
+                        } elseif ($answerType == HOT_SPOT_ORDER) {
                             //if ($origin != 'learnpath') {
                             ExerciseShowFunctions::display_hotspot_order_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment);
                             //}
@@ -2964,6 +3064,9 @@ class Exercise
                         case FILL_IN_BLANKS:
                             ExerciseShowFunctions::display_fill_in_blanks_answer($feedback_type, $answer,$exeId,$questionId);
                             break;
+                        case CALCULATED_ANSWER:
+                            ExerciseShowFunctions::display_calculated_answer($feedback_type, $answer, $exeId, $questionId);
+                            break;
                         case FREE_ANSWER:
                             echo ExerciseShowFunctions::display_free_answer($feedback_type, $choice, $exeId, $questionId, $questionScore);
                             break;
@@ -3197,7 +3300,6 @@ class Exercise
             'threadhold2'=>$threadhold2,
             'threadhold3'=> $threadhold3,
         );
-
         if ($from == 'exercise_result') {
             // if answer is hotspot. To the difference of exercise_show.php, we use the results from the session (from_db=0)
             // TODO Change this, because it is wrong to show the user some results that haven't been stored in the database yet

+ 93 - 1
main/exercice/exercise.lib.php

@@ -534,8 +534,100 @@ function showQuestion(
                             $attributes
                         ), $answer);*/
                 }
-    			$s .= $answer;
+                $s .= $answer;
 
+            } elseif ($answerType == CALCULATED_ANSWER) {
+                /*
+                 * In the CALCULATED_ANSWER test
+                 * you mustn't have [ and ] in the textarea
+                 * you mustn't have @@ in the textarea
+                 * the text to find mustn't be empty or contains only spaces
+                 * the text to find mustn't contains HTML tags
+                 * the text to find mustn't contains char "
+                 */
+                if ($origin !== null) {
+                    global $exe_id;
+                    $trackAttempts = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+                    $sqlTrackAttempt = 'SELECT answer FROM '.$trackAttempts.' WHERE exe_id='.$exe_id.' AND question_id='.$questionId;
+                    $rsLastAttempt = Database::query($sqlTrackAttempt);
+                    $rowLastAttempt = Database::fetch_array($rsLastAttempt);
+                    $answer = $rowLastAttempt['answer'];
+                    if (empty($answer)) {
+                        $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(1, $nbrAnswers);
+                        $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]);
+                    }
+                }
+                list($answer) = explode('@@', $answer);
+                // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]]
+                api_preg_match_all('/\[[^]]+\]/', $answer, $correctAnswerList);
+                // get student answer to display it if student go back to previous calculated answer question in a test
+                if (isset($user_choice[0]['answer'])) {
+                    api_preg_match_all('/\[[^]]+\]/', $answer, $studentAnswerList);
+                    $studentAnswerListTobecleaned = $studentAnswerList[0];
+                    $studentAnswerList = array();
+
+                    for ($i=0; $i < count($studentAnswerListTobecleaned); $i++) {
+                        $answerCorrected = $studentAnswerListTobecleaned[$i];
+                        $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected);
+                        $answerCorrected = api_preg_replace('/^\[/', '', $answerCorrected);
+                        $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected);
+                        $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected);
+                        $answerCorrected = '['.$answerCorrected.']';
+                        $studentAnswerList[] = $answerCorrected;
+                    }
+                }
+                // If display preview of answer in test view for exemple, set the student answer to the correct answers
+                if ($debug_mark_answer) {
+                    // contain the rights answers surronded with brackets
+                    $studentAnswerList = $correctAnswerList[0];
+                }
+                /*
+                Split the response by bracket
+                tabComments is an array with text surrounding the text to find
+                we add a space before and after the answerQuestion to be sure to
+                have a block of text before and after [xxx] patterns
+                so we have n text to find ([xxx]) and n+1 block of texts before,
+                between and after the text to find
+                */
+                $tabComments = api_preg_split('/\[[^]]+\]/', ' '.$answer.' ');
+                if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
+                    $answer = "";
+                    $i = 0;
+                    foreach ($studentAnswerList as $studentItem) {
+                        // remove surronding brackets
+                        $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2);
+                        $size = strlen($studentItem);
+                        $attributes['class'] = detectInputAppropriateClass($size);
+
+                        $answer .= $tabComments[$i].
+                            Display::input(
+                                'text',
+                                "choice[$questionId][]",
+                                $studentResponse,
+                                $attributes
+                            );
+                        $i++;
+                    }
+                    $answer .= $tabComments[$i];
+                } else {
+                    // display exercise with empty input fields
+                    // every [xxx] are replaced with an empty input field
+                    foreach ($correctAnswerList[0] as $item) {
+                        $size = strlen($item);
+                        $attributes['class'] = detectInputAppropriateClass($size);
+                        $answer = str_replace(
+                            $item,
+                            Display::input('text', "choice[$questionId][]", '', $attributes),
+                            $answer
+                        );
+                    }
+                }
+                if ($origin !== null) {
+                    $s = $answer;
+                    break;
+                } else {
+                    $s .= $answer;
+                }
             } elseif ($answerType == MATCHING) {
     			// matching type, showing suggestions and answers
     			// TODO: replace $answerId by $numAnswer

+ 5 - 3
main/exercice/exercise_submit.php

@@ -82,6 +82,7 @@ $choice = empty($choice) ? isset($_REQUEST['choice2']) ? $_REQUEST['choice2'] :
 
 //From submit modal
 $current_question = isset($_REQUEST['num']) ? intval($_REQUEST['num']) : null;
+$currentAnswer = isset($_REQUEST['num_answer']) ? intval($_REQUEST['num_answer']) : null;
 
 //Error message
 $error = '';
@@ -415,7 +416,7 @@ if ($formSent && isset($_POST)) {
                     if (isset($exe_id)) {
                     	//Manage the question and answer attempts
                         if ($debug) { error_log('8.3. manage_answer exe_id: '.$exe_id.' - $questionId: '.$questionId.' Choice'.print_r($choice,1)); }
-                    	$objExercise->manage_answer(
+                        $objExercise->manage_answer(
                             $exe_id,
                             $questionId,
                             $choice,
@@ -424,7 +425,8 @@ if ($formSent && isset($_POST)) {
                             true,
                             false,
                             false,
-                            $objExercise->propagate_neg
+                            $objExercise->propagate_neg,
+                            array()
                         );
                     }
                     //END of saving and qualifying
@@ -442,7 +444,6 @@ if ($formSent && isset($_POST)) {
     Session::write('exerciseResultCoordinates',$exerciseResultCoordinates);
 
     // if all questions on one page OR if it is the last question (only for an exercise with one question per page)
-
     if ($objExercise->type == ALL_ON_ONE_PAGE || $current_question >= $question_count) {
         if (api_is_allowed_to_session_edit()) {
             // goes to the script that will show the result of the exercise
@@ -973,6 +974,7 @@ if (!empty($error)) {
          <input type="hidden" name="formSent"				value="1" />
          <input type="hidden" name="exerciseId" 			value="'.$exerciseId . '" />
          <input type="hidden" name="num" 					value="'.$current_question.'" id="num_current_id" />
+         <input type="hidden" name="num_answer"             value="'.$currentAnswer.'" id="num_current_answer_id" />
          <input type="hidden" name="exe_id" 				value="'.$exe_id . '" />
          <input type="hidden" name="origin" 				value="'.$origin . '" />
          <input type="hidden" name="learnpath_id" 			value="'.$learnpath_id . '" />

+ 1 - 1
main/exercice/fill_blanks.class.php

@@ -10,7 +10,7 @@
  **/
 class FillBlanks extends Question
 {
-	static $typePicture = 'fill_in_blanks.gif';
+	static $typePicture = 'fill_in_blanks.png';
 	static $explanationLangVar = 'FillBlanks';
 
     /**

+ 1 - 1
main/exercice/freeanswer.class.php

@@ -10,7 +10,7 @@
  */
 class FreeAnswer extends Question
 {
-    static $typePicture = 'open_answer.gif';
+    static $typePicture = 'open_answer.png';
     static $explanationLangVar = 'FreeAnswer';
 
     /**

+ 1 - 1
main/exercice/global_multiple_answer.class.php

@@ -6,7 +6,7 @@
  */
 class GlobalMultipleAnswer extends Question
 {
-    static $typePicture = 'mcmagl.gif';
+    static $typePicture = 'mcmagl.png';
     static $explanationLangVar = 'GlobalMultipleAnswer';
 
     /**

+ 1 - 1
main/exercice/hotspot.class.php

@@ -12,7 +12,7 @@
  **/
 class HotSpot extends Question
 {
-	static $typePicture = 'hotspot.gif';
+	static $typePicture = 'hotspot.png';
 	static $explanationLangVar = 'HotSpot';
 
 	function HotSpot() {

+ 1 - 1
main/exercice/matching.class.php

@@ -13,7 +13,7 @@
  */
 class Matching extends Question
 {
-    static $typePicture = 'matching.gif';
+    static $typePicture = 'matching.png';
     static $explanationLangVar = 'Matching';
 
     /**

+ 1 - 1
main/exercice/multiple_answer.class.php

@@ -12,7 +12,7 @@
  **/
 class MultipleAnswer extends Question
 {
-	static $typePicture = 'mcma.gif';
+	static $typePicture = 'mcma.png';
 	static $explanationLangVar = 'MultipleSelect';
 
 	/**

+ 1 - 1
main/exercice/multiple_answer_combination.class.php

@@ -12,7 +12,7 @@
 class MultipleAnswerCombination extends Question
 {
 
-	static $typePicture = 'mcmac.gif';
+	static $typePicture = 'mcmac.png';
 	static $explanationLangVar = 'MultipleSelectCombination';
 
 	/**

+ 1 - 1
main/exercice/multiple_answer_combination_true_false.class.php

@@ -11,7 +11,7 @@
  **/
 class MultipleAnswerCombinationTrueFalse extends MultipleAnswerCombination
 {
-	static $typePicture = 'mcmaco.gif';
+	static $typePicture = 'mcmaco.png';
 	static $explanationLangVar = 'MultipleAnswerCombinationTrueFalse';
     var    $options;
 

+ 1 - 1
main/exercice/multiple_answer_true_false.class.php

@@ -11,7 +11,7 @@
  */
 class MultipleAnswerTrueFalse extends Question
 {
-	static $typePicture = 'mcmao.gif';
+	static $typePicture = 'mcmao.png';
 	static $explanationLangVar = 'MultipleAnswerTrueFalse';
     public $options;
 

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

@@ -17,6 +17,7 @@ define('MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE',    12);
 define('ORAL_EXPRESSION',                           13);
 define('GLOBAL_MULTIPLE_ANSWER',                    14);
 define('MEDIA_QUESTION',                            15);
+define('CALCULATED_ANSWER',                         16);
 
 //Some alias used in the QTI exports
 define('MCUA',				1);
@@ -68,6 +69,7 @@ abstract class Question
         MULTIPLE_ANSWER_TRUE_FALSE =>   array('multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'),
         MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE =>   array('multiple_answer_combination_true_false.class.php', 'MultipleAnswerCombinationTrueFalse'),
         GLOBAL_MULTIPLE_ANSWER =>		array('global_multiple_answer.class.php' , 'GlobalMultipleAnswer'),
+        CALCULATED_ANSWER =>			array('calculated_answer.class.php' , 'CalculatedAnswer')
         //MEDIA_QUESTION =>               array('media_question.class.php' , 'MediaQuestion')
     );
 
@@ -1395,9 +1397,9 @@ abstract class Question
 			if ($objExercise->exercise_was_added_in_lp == true) {
                 $img = pathinfo($img);
 				$img = $img['filename'].'_na.'.$img['extension'];
-				echo Display::return_icon($img,$explanation);
+				echo Display::return_icon($img, $explanation, null, ICON_SIZE_BIG);
 			} else {
-                echo '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes&answerType='.$i.'">'.Display::return_icon($img, $explanation).'</a>';
+                echo '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes&answerType='.$i.'">'.Display::return_icon($img, $explanation, null, ICON_SIZE_BIG).'</a>';
 			}
 			echo '</div>';
 			echo '</li>';
@@ -1406,14 +1408,14 @@ abstract class Question
 		echo '<li>';
 		echo '<div class="icon_image_content">';
 		if ($objExercise->exercise_was_added_in_lp == true) {
-            echo Display::return_icon('database_na.png', get_lang('GetExistingQuestion'));
+            echo Display::return_icon('database_na.png', get_lang('GetExistingQuestion'), null, ICON_SIZE_BIG);
 		} else {
 			if ($feedback_type==1) {
 				echo $url = '<a href="question_pool.php?'.api_get_cidreq().'&type=1&fromExercise='.$exerciseId.'">';
 			} else {
 				echo $url = '<a href="question_pool.php?'.api_get_cidreq().'&fromExercise='.$exerciseId.'">';
 			}
-			echo Display::return_icon('database.png', get_lang('GetExistingQuestion'));
+			echo Display::return_icon('database.png', get_lang('GetExistingQuestion'), null, ICON_SIZE_BIG);
 		}
 		echo '</a>';
 		echo '</div></li>';

+ 1 - 1
main/exercice/unique_answer.class.php

@@ -15,7 +15,7 @@
 
 class UniqueAnswer extends Question
 {
-    static $typePicture = 'mcua.gif';
+    static $typePicture = 'mcua.png';
     static $explanationLangVar = 'UniqueSelect';
 
     /**

+ 1 - 1
main/exercice/unique_answer_no_option.class.php

@@ -12,7 +12,7 @@
  */
 class UniqueAnswerNoOption extends Question
 {
-	static $typePicture = 'mcuao.gif';
+	static $typePicture = 'mcuao.png';
 	static $explanationLangVar = 'UniqueAnswerNoOption';
 
 	/**

BIN
main/img/audio_question.png


BIN
main/img/calculated_answer.png


BIN
main/img/database.png


BIN
main/img/fill_in_blanks.gif


BIN
main/img/hotspot.gif


BIN
main/img/icons/128/audio_question.png


BIN
main/img/icons/128/calculated_answer.png


BIN
main/img/icons/128/database.png


BIN
main/img/icons/128/fill_in_blanks.png


BIN
main/img/icons/128/hotspot.png


BIN
main/img/icons/128/matching.png


BIN
main/img/icons/128/mcma.png


BIN
main/img/icons/128/mcmac.png


BIN
main/img/icons/128/mcmaco.png


BIN
main/img/icons/128/mcmagl.png


BIN
main/img/icons/128/mcmao.png


BIN
main/img/icons/128/mcua.png


BIN
main/img/icons/128/mcuao.png


BIN
main/img/icons/128/open_answer.png


BIN
main/img/icons/16/audio_question.png


BIN
main/img/icons/16/database.png


BIN
main/img/icons/16/fill_in_blanks.png


BIN
main/img/icons/16/hotspot.png


BIN
main/img/icons/16/matching.png


BIN
main/img/icons/16/mcma.png


BIN
main/img/icons/16/mcmac.png


BIN
main/img/icons/16/mcmaco.png


BIN
main/img/icons/16/mcmagl.png


BIN
main/img/icons/16/mcmao.png


BIN
main/img/icons/16/mcua.png


BIN
main/img/icons/16/mcuao.png


BIN
main/img/icons/16/open_answer.png


BIN
main/img/icons/22/audio_question.png


BIN
main/img/icons/22/database.png


BIN
main/img/icons/22/fill_in_blanks.png


BIN
main/img/icons/22/hotspot.png


BIN
main/img/icons/22/matching.png


BIN
main/img/icons/22/mcma.png


BIN
main/img/icons/22/mcmac.png


BIN
main/img/icons/22/mcmaco.png


BIN
main/img/icons/22/mcmagl.png


BIN
main/img/icons/22/mcmao.png


BIN
main/img/icons/22/mcua.png


BIN
main/img/icons/22/mcuao.png


BIN
main/img/icons/22/open_answer.png


BIN
main/img/icons/32/audio_question.png


BIN
main/img/icons/32/calculated_answer.png


BIN
main/img/icons/32/database.png


BIN
main/img/icons/32/fill_in_blanks.gif


BIN
main/img/icons/32/fill_in_blanks.png


BIN
main/img/icons/32/hotspot.gif


BIN
main/img/icons/32/hotspot.png


BIN
main/img/icons/32/matching.gif


BIN
main/img/icons/32/matching.png


BIN
main/img/icons/32/mcma.gif


BIN
main/img/icons/32/mcma.png


BIN
main/img/icons/32/mcmac.gif


BIN
main/img/icons/32/mcmac.png


BIN
main/img/icons/32/mcmaco.gif


BIN
main/img/icons/32/mcmaco.png


BIN
main/img/icons/32/mcmagl.gif


BIN
main/img/icons/32/mcmagl.png


BIN
main/img/icons/32/mcmao.gif


BIN
main/img/icons/32/mcmao.png


BIN
main/img/icons/32/mcua.gif


BIN
main/img/icons/32/mcua.png


BIN
main/img/icons/32/mcuao.gif


BIN
main/img/icons/32/mcuao.png


BIN
main/img/icons/32/open_answer.gif


BIN
main/img/icons/32/open_answer.png


BIN
main/img/icons/48/audio_question.png


BIN
main/img/icons/48/database.png


BIN
main/img/icons/48/fill_in_blanks.png


BIN
main/img/icons/48/hotspot.png


BIN
main/img/icons/48/matching.png


BIN
main/img/icons/48/mcma.png


BIN
main/img/icons/48/mcmac.png


BIN
main/img/icons/48/mcmaco.png


BIN
main/img/icons/48/mcmagl.png


BIN
main/img/icons/48/mcmao.png


BIN
main/img/icons/48/mcua.png


BIN
main/img/icons/48/mcuao.png


Some files were not shown because too many files changed in this diff