First commit for Chamilo 1.9 Exercises: Adding "remind question" and "save question now" + some new UI interfaces improvements see BT#2683 and BT#2682. Requires DB changes

skala
Julio Montoya 14 years ago
parent 336cf0c64f
commit c6ffa3daf0
  1. 126
      main/css/base.css
  2. 193
      main/exercice/exercise.class.php
  3. 347
      main/exercice/exercise.lib.php
  4. 223
      main/exercice/exercise_reminder.php
  5. 182
      main/exercice/exercise_result.php
  6. 2
      main/exercice/exercise_show.php
  7. 628
      main/exercice/exercise_submit.php
  8. 2
      main/exercice/question.class.php
  9. 2
      main/exercice/result.php
  10. 175
      main/inc/ajax/exercise.ajax.php
  11. 18
      main/inc/lib/display.lib.php
  12. 66
      main/inc/lib/events.lib.inc.php
  13. 9
      main/inc/lib/exercise_show_functions.lib.php
  14. 2
      main/install/db_stats.sql

@ -765,6 +765,29 @@ button:hover {
}
/* blue */
.blue {
color: #fff !important;
border: solid 1px #0076a3;
background: #0095cd;
background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5));
background: -moz-linear-gradient(top, #00adee, #0078a5);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee', endColorstr='#0078a5');
}
.blue:hover {
background: #007ead;
background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e));
background: -moz-linear-gradient(top, #0095cc, #00678e);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc', endColorstr='#00678e');
}
.blue:active {
color: #80bed6;
background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee));
background: -moz-linear-gradient(top, #0078a5, #00adee);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5', endColorstr='#00adee');
}
/* orange */
@ -792,7 +815,7 @@ button:hover {
/* green */
.green {
color: #e8f0de;
color: #fef4e9 !important;
border: solid 1px #538312;
background: #64991e;
background: -webkit-gradient(linear, left top, left bottom, from(#7db72f), to(#4e7d0e));
@ -2474,7 +2497,6 @@ div.admin_section h4 {
width:33%;
}
.exercise_overview_options .right_option {
float:right;
margin:12px 5px;
@ -2482,6 +2504,106 @@ div.admin_section h4 {
font-size : 14px;
}
.remind_highlight {
background-color: #FFF7C0;
}
.main_question {
}
.exercise_header {
border-bottom: 1px dotted #ccc;
margin-bottom:20px;
}
/* Table */
.exercise_options {
width:720px;
border-collapse: collapse;
border-spacing: 0;
}
.exercise_options th {
background-color: #F2F2F2;
border-bottom: 1px solid #DDDDDD;
line-height: normal;
padding: 8px 10px;
text-align: center;
vertical-align: middle;
}
.question_options {
margin-left:14px;
min-height:150px;
}
.question_description {
padding:0px 0px 0px 16px;
}
.exercise_description {
padding:0px 0px 10px 0px;
}
.exercise_title {
font-size: 1.6em;
font-weight: bold;
padding:10px 0px 10px 0px;
}
.question_title {
font-size: 1.2em;
font-weight: bold;
margin: 15px 0px;
}
.question_no_answer {
background-color: #FFF7C0;
padding: 5px 0px 5px 0px;
margin: 5px 0px 5px 0px;
}
.exercise_reminder_container {
}
.question_answer {
display: block;
float: left;
margin: 0;
width: 100%;
margin: 0 0 0 0px;
}
.question_answer label {
color: #222222;
display: block;
font-size: 100%;
line-height: 150%;
margin: -27px 0 0 23px;
padding: 0 0 5px;
width: 88%;
}
.exercise_actions {
background: #f5f5f5;
margin-top: 18px;
margin-bottom: 18px;
padding: 17px 20px 18px 50px;
border-top: 1px solid #ddd;
-webkit-border-radius: 0 0 3px 3px;
-moz-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
}
.exercise_save_now_button img {
position: relative;
top: 4px;
}
.exercise_actions a, .exercise_actions div {
margin-right:10px;
}
.exercise_save_now_button, .exercise_button{
/* padding:10px; */
}
.red_alert {
color:red;
font-weight: bold;

@ -1509,8 +1509,12 @@ class Exercise {
* @param array question list
*/
public function save_stat_track_exercise_info($clock_expired_time = 0, $safe_lp_id = 0, $safe_lp_item_id = 0, $safe_lp_item_view_id = 0, $questionList = array(), $weight) {
public function save_stat_track_exercise_info($clock_expired_time = 0, $safe_lp_id = 0, $safe_lp_item_id = 0, $safe_lp_item_view_id = 0, $questionList = array(), $weight = 0) {
$track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
$safe_lp_id = intval($safe_lp_id);
$safe_lp_item_id = intval($safe_lp_item_id);
$safe_lp_item_view_id = intval($safe_lp_item_view_id);
if (empty($safe_lp_id)) {
$safe_lp_id = 0;
}
@ -1528,63 +1532,72 @@ class Exercise {
$sql_fields_values = "";
}
array_map('intval', $questionList);
$weight = Database::escape_string($weight);
if ($this->type == ONE_PER_PAGE) {
$sql = "INSERT INTO $track_exercises ($sql_fields exe_exo_id, exe_user_id, exe_cours_id, status,session_id, data_tracking, start_date, orig_lp_id, orig_lp_item_id, exe_weighting)
VALUES($sql_fields_values '".$this->id."','" . api_get_user_id() . "','" . api_get_course_id() . "','incomplete','" . api_get_session_id() . "','" . implode(',', $questionList) . "', '" . api_get_utc_datetime() . "', '$safe_lp_id', '$safe_lp_item_id', '$weight' )";
} else {
$sql = "INSERT INTO $track_exercises ($sql_fields exe_exo_id, exe_user_id, exe_cours_id, status, session_id, start_date, orig_lp_id, orig_lp_item_id)
VALUES($sql_fields_values '".$this->id."','" . api_get_user_id() . "','" . api_get_course_id() . "','incomplete','" . api_get_session_id() . "','" . api_get_utc_datetime() . "', '$safe_lp_id', '$safe_lp_item_id' , '$weight' )";
VALUES($sql_fields_values '".$this->id."','".api_get_user_id()."','".api_get_course_id()."','incomplete','".api_get_session_id()."','".api_get_utc_datetime()."', '$safe_lp_id', '$safe_lp_item_id')";
}
Database::query($sql);
$id = Database::insert_id();
return $id;
}
public function show_button($nbrQuestions, $questionNum, $exerciseId) {
global $origin, $learnpath_id,$learnpath_item_id;
$nbrQuestions = intval($nbrQuestions);
$exerciseId = intval($exerciseId);
public function show_button($question_id, $questionNum) {
global $origin, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id;
$nbrQuestions = count($this->get_validated_question_list());
$html = '';
$html = '<div style="margin-top:-10px;">';
$confirmation_alert = $this->type == 1? " onclick=\"javascript:if(!confirm('".get_lang("ConfirmYourChoice")."')) return false;\" ":"";
$submit_btn = '<button class="next" type="submit" name="submit" name="submit_save" id="submit_save" '.$confirmation_alert.' >';
$html = $label = '';
$confirmation_alert = $this->type == ALL_ON_ONE_PAGE? " onclick=\"javascript:if(!confirm('".get_lang("ConfirmYourChoice")."')) return false;\" ":"";
$hotspot_get = isset($_POST['hotspot']) ? Security::remove_XSS($_POST['hotspot']):null;
if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT && $this->type == ONE_PER_PAGE) {
$submit_btn = '';
$html .='<script src="' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/thickbox.js" type="text/javascript"></script>';
$html .='<style type="text/css" media="all">@import "' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/thickbox.css";</style>';
$html .='<style type="text/css" media="all">@import "' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/thickbox.css";</style>';
$html .= api_get_jquery_ui_js();
$html .='
<script>
$html .='<script>
$(function() {
$(".button").button();
});
</script>';
//$html .='<br /><a href="exercise_submit_modal.php?learnpath_id='.$learnpath_id.'&learnpath_item_id='.$learnpath_item_id.'&origin='.$origin.'&hotspot='.$hotspot_get.'&nbrQuestions='.$nbrQuestions.'&questionnum='.$questionNum.'&exerciseType='.$exerciseType.'&exerciseId='.$exerciseId.'&placeValuesBeforeTB_=savedValues&TB_iframe=true&height=480&width=640&modal=true" title="" class="thickbox button" id="validationButton">';
$html .='<a href="exercise_submit_modal.php?learnpath_id='.$learnpath_id.'&learnpath_item_id='.$learnpath_item_id.'&origin='.$origin.'&hotspot='.$hotspot_get.'&nbrQuestions='.$nbrQuestions.'&questionnum='.$questionNum.'&exerciseType='.$this->type.'&exerciseId='.$exerciseId.'&placeValuesBeforeTB_=savedValues&TB_iframe=true&height=480&width=640&modal=true" title="" class="thickbox button" id="validationButton">';
$html .='<a href="exercise_submit_modal.php?learnpath_id='.$safe_lp_id.'&learnpath_item_id='.$safe_lp_item_id.'&learnpath_item_view_id='.$safe_lp_item_view_id.'&origin='.$origin.'&hotspot='.$hotspot_get.'&nbrQuestions='.$nbrQuestions.'&questionnum='.$questionNum.'&exerciseType='.$this->type.'&exerciseId='.$this->id.'&placeValuesBeforeTB_=savedValues&TB_iframe=true&height=480&width=640&modal=true" title="" class="thickbox button" id="validationButton">';
$html .= get_lang('ValidateAnswer').'</a>';
$html .='<br />';
} else {
//User
if (api_is_allowed_to_session_edit()) {
if ($this->type == ALL_ON_ONE_PAGE || $nbrQuestions == $questionNum) {
$submit_btn .= get_lang('ValidateAnswer');
$name_btn = get_lang('ValidateAnswer');
$label = get_lang('ValidateAnswer');
$class = 'accept';
} else {
$submit_btn .= get_lang('NextQuestion');
$name_btn = get_lang('NextQuestion');
$label = get_lang('NextQuestion');
$class = 'next';
}
$submit_btn .= '</button>';
if ($this->expired_time != 0) {
$html .= $submit_btn ='<button class="next" type="submit" id="submit_save" value="'.$name_btn.'" name="submit_save"/>'.$name_btn.'</button>';
/*if ($this->type == ALL_ON_ONE_PAGE && $nbrQuestions > 1) {
$all_button = '<a href="javascript://" class="a_button orange medium" onclick="save_now_all(); ">'.get_lang('SaveForNow').'</a>';
$all_button .= '&nbsp;<span id="save_all_reponse"></span>';
$html .= $all_button;
}*/
if ($this->type == ONE_PER_PAGE) {
$all_button = '<a href="javascript://" class="a_button blue medium" onclick="save_now('.$question_id.'); ">'.$label.'</a>';
//$all_button .= '&nbsp;<span id="save_all_reponse"></span>';
$all_button .= '<span id="save_for_now_'.$question_id.'"></span>&nbsp;';
$html .= $all_button;
} else {
$html .= $submit_btn;
$all_button = '<a href="javascript://" class="a_button green" onclick="validate_all(); ">'.get_lang('ValidateAnswer').'</a>';
$all_button .= '&nbsp;<span id="save_all_reponse"></span>';
$html .= $all_button;
}
}
}
$html .= '</div>'; //margin top -10
$html = Display::span($html, array('class'=>'exercise_button'));
return $html;
}
/**
@ -1779,7 +1792,7 @@ class Exercise {
if ($debug) error_log('manage_answer $from_database '.$from_database);
if ($debug) error_log('manage_answer $show_result '.$show_result);
if ($debug) error_log('manage_answer $propagate_neg '.$propagate_neg);
if ($debug) error_log('manage_answer $$hotspot_delineation_result '.print_r($hotspot_delineation_result, 1));
if ($debug) error_log('manage_answer $hotspot_delineation_result '.print_r($hotspot_delineation_result, 1));
$extra_data = array();
$html = '';
@ -1896,7 +1909,6 @@ class Exercise {
$studentChoice =$choice[$numAnswer];
}
if (!empty($studentChoice)) {
if ($studentChoice == $answerCorrect ) {
$questionScore += $true_score;
@ -2242,7 +2254,9 @@ class Exercise {
}
// for hotspot with no order
case HOT_SPOT :
if ($from_database) {
if ($show_result) {
$TBL_TRACK_HOTSPOT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
$query = "SELECT hotspot_correct FROM ".$TBL_TRACK_HOTSPOT." where hotspot_exe_id = '".$exeId."' and hotspot_question_id= '".$questionId."' AND hotspot_answer_id='".Database::escape_string($answerId)."'";
@ -2869,16 +2883,19 @@ class Exercise {
if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER) {
// We made an extra table for the answers
if ($show_result) {
if ($origin != 'learnpath') {
echo '</table></td></tr>';
echo '<tr>
<td colspan="2">';
echo '<i>'.get_lang('HotSpot').'</i><br /><br />';
echo '<object type="application/x-shockwave-flash" data="'.api_get_path(WEB_CODE_PATH).'plugin/hotspot/hotspot_solution.swf?modifyAnswers='.Security::remove_XSS($questionId).'&exe_id=&from_db=0" width="552" height="352">';
echo '<param name="movie" value="'.api_get_path(WEB_PLUGIN_PATH).'plugin/hotspot/hotspot_solution.swf?modifyAnswers='.Security::remove_XSS($questionId).'&exe_id=&from_db=0" />
</object>
</td>
echo '<object type="application/x-shockwave-flash" data="'.api_get_path(WEB_CODE_PATH).'plugin/hotspot/hotspot_solution.swf?modifyAnswers='.Security::remove_XSS($questionId).'&exe_id='.$exeId.'&from_db=1" width="552" height="352">
<param name="movie" value="../plugin/hotspot/hotspot_solution.swf?modifyAnswers='.Security::remove_XSS($questionId).'&exe_id='.$exeId.'&from_db=1" />
</object>';
echo '</td>
</tr>';
}
@ -3291,5 +3308,113 @@ class Exercise {
return $is_visible;
}
function save_attempt() {
}
function added_in_lp() {
$TBL_LP_ITEM = Database::get_course_table(TABLE_LP_ITEM);
$sql = "SELECT max_score FROM $TBL_LP_ITEM WHERE item_type = '".TOOL_QUIZ."' AND path = '".$this->id."'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
return true;
}
return false;
}
function get_validated_question_list() {
return ($this->isRandom() ? $this->selectRandomList() : $this->selectQuestionList());
}
public function get_stat_track_exercise_info_by_exe_id($exe_id) {
$track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
$exe_id = intval($exe_id);
$sql_track = "SELECT * FROM $track_exercises WHERE exe_id = $exe_id ";
$result = Database::query($sql_track);
$new_array = array();
if (Database::num_rows($result) > 0 ) {
$new_array = Database::fetch_array($result, 'ASSOC');
}
return $new_array;
}
public function edit_question_to_remind($exe_id, $question_id, $action = 'add') {
$exercise_info = self::get_stat_track_exercise_info_by_exe_id($exe_id);
$question_id = intval($question_id);
$exe_id = intval($exe_id);
$track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
if ($exercise_info) {
if (empty($exercise_info['questions_to_check'])) {
if ($action == 'add') {
$sql = "UPDATE $track_exercises SET questions_to_check = '$question_id' WHERE exe_id = $exe_id ";
$result = Database::query($sql);
}
} else {
$remind_list = explode(',',$exercise_info['questions_to_check']);
$remind_list_string = '';
if ($action == 'add') {
if (!in_array($question_id, $remind_list)) {
$remind_list[] = $question_id;
if (!empty($remind_list)) {
sort($remind_list);
array_filter($remind_list);
}
$remind_list_string = implode(',', $remind_list);
}
} elseif ($action == 'delete') {
if (!empty($remind_list)) {
if (in_array($question_id, $remind_list)) {
$remind_list = array_flip($remind_list);
unset($remind_list[$question_id]);
$remind_list = array_flip($remind_list);
if (!empty($remind_list)) {
sort($remind_list);
array_filter($remind_list);
$remind_list_string = implode(',', $remind_list);
}
}
}
}
$remind_list_string = Database::escape_string($remind_list_string);
$sql = "UPDATE $track_exercises SET questions_to_check = '$remind_list_string' WHERE exe_id = $exe_id ";
$result = Database::query($sql);
}
}
}
public function fill_in_blank_answer_to_string($answer) {
api_preg_match_all('/\[[^]]+\]/', $answer, $teacher_answer_list);
$result = '';
if (!empty($teacher_answer_list)) {
$teacher_answer_list = $teacher_answer_list[0];
$i = 0;
foreach($teacher_answer_list as $teacher_item) {
$value = null;
//Cleaning student answer list
$value = strip_tags($teacher_item);
$value = api_substr($value,1, api_strlen($value)-2);
$value = explode('/', $value);
if (!empty($value[0])) {
$value = trim($value[0]);
$value = str_replace('&nbsp;', '', $value);
$result .= $value;
}
}
}
return $result;
}
}
endif;

@ -24,12 +24,13 @@ require_once dirname(__FILE__).'/../inc/lib/fckeditor/fckeditor.php';
* @param int current item from the list of questions
* @param int number of total questions
* */
function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false) {
function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array()) {
$s = '';
// Text direction for the current language
$is_ltr_text_direction = api_get_text_direction() != 'rtl';
$remind_question = 1;
// Change false to true in the following line to enable answer hinting.
$debug_mark_answer = api_is_allowed_to_edit() && false;
@ -42,55 +43,34 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$answerType = $objQuestionTmp->selectType();
$pictureName = $objQuestionTmp->selectPicture();
$html = '';
if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) {
// Question is not a hotspot
if (!$only_questions) {
$questionName = $objQuestionTmp->selectTitle();
$questionDescription = $objQuestionTmp->selectDescription();
$questionName = text_filter($questionName);
if ($show_title) {
$s='<div id="question_title" class="sectiontitle">'.get_lang('Question').' ';
$s.=$current_item;
//@todo I need the get the feedback type
//if($answerType != 1)
//$s.=' / '.$total_item;
echo $s;
echo ' : ';
echo $questionName.'</div>';
echo Display::div($current_item.'. '.$objQuestionTmp->selectTitle(), array('class'=>'question_title'));
}
$s='';
$s.='<table class="exercise_questions" style="margin:4px 4px 4px 0px; padding:2px;">
<tr><td valign="top" colspan="2">';
$questionDescription=text_filter($questionDescription);
$s.=$questionDescription;
$s.='</td></tr></table>';
if (!empty($questionDescription)) {
echo Display::div($questionDescription, array('class'=>'question_description'));
}
//@deprecated
if (!empty($pictureName)) {
$s.="<tr>
<td align='center' colspan='2'><img src='../document/download.php?doc_url=%2Fimages%2F'".$pictureName."' border='0'></td>
</tr>";
//echo "<img src='../document/download.php?doc_url=%2Fimages%2F'".$pictureName."' border='0'>";
}
$s.= '</table>';
}
$s .= '<div class="rounded exercise_questions" style="width: 720px; padding: 3px;">';
$option_ie = '';
/*
if (!ereg("MSIE",$_SERVER["HTTP_USER_AGENT"])) {
$s .= '<div class="rounded exercise_questions" style="width: 720px; padding: 3px;">';
} else {
$option_ie="margin-left:10px";
}*/
echo '<div class="question_options">';
if ($answerType == FREE_ANSWER && $freeze) {
return '';
}
$s .= '<table width="720" class="exercise_options" style="width: 720px;'.$option_ie.' background-color:#fff;">';
//$s .= '<table width="720" class="exercise_options" style="width: 720px;'.$option_ie.' background-color:#fff;">';
$s .= '<table class="exercise_options">';
// construction of the Answer object (also gets all answers details)
$objAnswerTmp = new Answer($questionId);
@ -127,6 +107,11 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
}
}
$i = 1;
$select_items[0]['id'] = 0;
$select_items[0]['letter'] = '--';
$select_items[0]['answer'] = '';
foreach ($answer_matching as $id => $value) {
$select_items[$i]['id'] = $value['id'];
$select_items[$i]['letter'] = $cpt1[$id];
@ -134,65 +119,20 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$i ++;
}
$num_suggestions = ($nbrAnswers - $x) + 1;
} elseif ($answerType == FREE_ANSWER) {
$fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer']:null;
$oFCKeditor = new FCKeditor("choice[".$questionId."]") ;
$oFCKeditor->ToolbarSet = 'TestFreeAnswer';
$oFCKeditor->Width = '100%';
$oFCKeditor->Height = '200';
$oFCKeditor->Value = '' ;
$oFCKeditor->Value = $fck_content;
$s .= '<tr><td colspan="3">';
$s .= $oFCKeditor->CreateHtml();
$s .= '</td></tr>';
}
?>
<style>
</style>
<script>
$(function() {
/*
var $options = $( "#options" );
$( "div", $options ).draggable({
revert: "invalid", // when not dropped, the item will revert back to its initial position
cursor: "move",
});
var $question_1 = $( "#question_1" );
$question_1.droppable({
accept: "#options div",
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function( event, ui ) {
//$( this ).addClass( "ui-state-highlight" );
}
});
var $question_2 = $( "#question_2" );
$question_2.droppable({
accept: "#options div",
hoverClass: "ui-state-active",
drop: function( event, ui ) {
//$( this ).addClass( "ui-state-highlight" );
}
});
$options.droppable({
accept: "#options div",
hoverClass: "ui-state-active",
drop: function( event, ui ) {
}
});*/
});
</script>
<?php
// Now navigate through the possible answers, using the max number of
// answers for the question as a limiter
@ -207,19 +147,20 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$s.= Display::tag('tr',$header, array('style'=>'text-align:left;'));
}
$matching_correct_answer = 0;
$user_choice_array = array();
if (!empty($user_choice)) {
foreach($user_choice as $item) {
$user_choice_array[] = $item['answer'];
}
}
for ($answerId=1; $answerId <= $nbrAnswers; $answerId++) {
$answer = $objAnswerTmp->selectAnswer($answerId);
$answerCorrect = $objAnswerTmp->isCorrect($answerId);
$numAnswer = $objAnswerTmp->selectAutoId($answerId);
if ($answerType == FILL_IN_BLANKS) {
// splits text and weightings that are joined with the character '::'
list($answer) = explode('::',$answer);
//getting the matches
$answer = api_ereg_replace('\[[^]]+\]','<input type="text" name="choice['.$questionId.'][]" size="10" />',($answer));
}
// Unique answer
if ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) {
// set $debug_mark_answer to true at function start to
@ -232,16 +173,25 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$selected = 'checked';
}
}
$answer = text_filter($answer);
$input_id = 'choice-'.$questionId.'-'.$answerId;
if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer ) {
$attributes = array('id' =>$input_id, 'class'=>'checkbox','checked'=>1, 'selected'=>1);
} else {
$attributes = array('id' =>$input_id, 'class'=>'checkbox');
}
$answer = Security::remove_XSS($answer, STUDENT);
$s .= Display::input('hidden','choice2['.$questionId.']','0').
'<tr><td colspan="3"><div class="u-m-answer"><p style="float: '.($is_ltr_text_direction ? 'left' : 'right').'; padding-'.($is_ltr_text_direction ? 'right' : 'left').': 4px;">'.
'<span>'.Display::input('radio','choice['.$questionId.']', $numAnswer, array('class'=>'checkbox','selected'=>$selected)).'</span></p>'.
'<div style="margin-'.($is_ltr_text_direction ? 'left' : 'right').': 24px;">'.
$answer.
'</div></div></td></tr>';
$s .= Display::input('hidden','choice2['.$questionId.']','0');
//@todo fix $is_ltr_text_direction
//<p style="float: '.($is_ltr_text_direction ? 'left' : 'right').'; padding-'.($is_ltr_text_direction ? 'right' : 'left').': 4px;">
//$s .= '<div style="margin-'.($is_ltr_text_direction ? 'left' : 'right').': 24px;">'.
$s .= '<tr><td colspan="3">';
$s .= '<span class="question_answer">';
$s .= Display::input('radio', 'choice['.$questionId.']', $numAnswer, $attributes);
$s .= Display::tag('label', $answer, array('for'=>$input_id)).'</span>';
$s .= '</td></tr>';
} elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
// multiple answers
@ -254,34 +204,51 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$selected = 'checked="checked"';
}
}
$answer = text_filter($answer);
$input_id = 'choice-'.$questionId.'-'.$answerId;
$answer = Security::remove_XSS($answer, STUDENT);
if (in_array($numAnswer, $user_choice_array)) {
$attributes = array('id' =>$input_id, 'class'=>'checkbox','checked'=>1, 'selected'=>1);
} else {
$attributes = array('id' =>$input_id, 'class'=>'checkbox');
}
$answer = Security::remove_XSS($answer, STUDENT);
if ($answerType == MULTIPLE_ANSWER) {
$s .= '<input type="hidden" name="choice2['.$questionId.']" value="0" />';
$s .= '<tr><td colspan="3"><div class="u-m-answer"><p style="float: '.($is_ltr_text_direction ? 'left' : 'right').'; padding-'.($is_ltr_text_direction ? 'right' : 'left').': 4px;">';
$s .= '<tr><td colspan="3">';
$s .= '<span class="question_answer">';
$options = array('type'=>'checkbox','name'=>'choice['.$questionId.']['.$numAnswer.']', 'class'=>'checkbox');
if ($debug_mark_answer) {
if ($answerCorrect) {
$options['checked'] = 'checked';
//$options['checked'] = 'checked';
}
}
$s .= Display::tag('span', Display::tag('input','',$options ));
$s .= '</p>';
$s .= '<div style="margin-'.($is_ltr_text_direction ? 'left' : 'right').': 24px;">'.
$answer.
'</div></div></td></tr>';
$s .= Display::tag('span', Display::input('checkbox', 'choice['.$questionId.']['.$numAnswer.']', $numAnswer, $attributes));
$s .= Display::tag('label', $answer, array('for'=>$input_id)).'</span></td></tr>';
} elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
$options = array('type'=>'radio','name'=>'choice['.$questionId.']['.$numAnswer.']', 'class'=>'checkbox');
$s .= '<input type="hidden" name="choice2['.$questionId.']" value="0" />';
$my_choice = array();
if (!empty($user_choice_array)) {
foreach ($user_choice_array as $item) {
$item = explode(':', $item);
$my_choice[$item[0]] = $item[1];
}
}
$s .='<tr>';
$s .= Display::tag('td', $answer);
if (!empty($quiz_question_options)) {
foreach ($quiz_question_options as $id=>$item) {
$options['value'] = $id;
$s .= Display::tag('td', Display::tag('input','',$options ));
if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) {
$attributes = array('class'=>'checkbox','checked'=>1, 'selected'=>1);
} else {
$attributes = array('class'=>'checkbox');
}
$s .= Display::tag('td', Display::input('radio', 'choice['.$questionId.']['.$numAnswer.']', $id, $attributes));
}
}
$s.='<tr>';
@ -298,57 +265,123 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$selected = 'checked="checked"';
}
}
$answer = text_filter($answer);
$input_id = 'choice-'.$questionId.'-'.$answerId;
if (in_array($numAnswer, $user_choice_array)) {
$attributes = array('id'=>$input_id, 'class'=>'checkbox','checked'=>1, 'selected'=>1);
} else {
$attributes = array('id'=>$input_id, 'class'=>'checkbox');
}
$answer = Security::remove_XSS($answer, STUDENT);
$s .= '<input type="hidden" name="choice2['.$questionId.']" value="0" />'.
'<tr><td colspan="3"><div class="u-m-answer"><p style="float: '.($is_ltr_text_direction ? 'left' : 'right').'; padding-'.($is_ltr_text_direction ? 'right' : 'left').': 4px;">'.
'<span><input class="checkbox" type="checkbox" name="choice['.$questionId.']['.$numAnswer.']" value="1" '.$selected.' /></span></p>'.
'<div style="margin-'.($is_ltr_text_direction ? 'left' : 'right').': 24px;">'.
$answer.
'</div></div></td></tr>';
'<tr><td colspan="3">';
$s .= '<span class="question_answer">';
$s .= Display::tag('span', Display::input('checkbox', 'choice['.$questionId.']['.$numAnswer.']', 1, $attributes));
$s .= Display::tag('label', $answer, array('for'=>$input_id)).'</span></td></tr>';
} elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
// multiple answers
// set $debug_mark_answer to true at function start to
// show the correct answer with a suffix '-x'
$s .= '<input type="hidden" name="choice2['.$questionId.']" value="0" />';
$help = $selected = '';
if ($debug_mark_answer) {
if ($answerCorrect) {
$help = 'x-';
$selected = 'checked="checked"';
$my_choice = array();
if (!empty($user_choice_array)) {
foreach ($user_choice_array as $item) {
$item = explode(':', $item);
$my_choice[$item[0]] = $item[1];
}
}
$answer = text_filter($answer);
$answer = Security::remove_XSS($answer, STUDENT);
$options = array('type'=>'radio','name'=>'choice['.$questionId.']['.$numAnswer.']', 'class'=>'checkbox');
$s .='<tr>';
$s .= Display::tag('td', $answer);
foreach ($objQuestionTmp->options as $key => $item) {
$options['value'] = $key;
$s .= Display::tag('td', Display::tag('input','',$options ));
//$options['value'] = $key;
if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) {
$attributes = array('class'=>'checkbox','checked'=>1, 'selected'=>1);
} else {
$attributes = array('class'=>'checkbox');
}
$s .= Display::tag('td', Display::input('radio','choice['.$questionId.']['.$numAnswer.']', $key, $attributes));
}
$s.='<tr>';
} elseif ($answerType == FILL_IN_BLANKS) {
// fill in blanks
$s .= '<tr><td colspan="3">'.$answer.'</td></tr>';
/*
// splits text and weightings that are joined with the character '::'
list($answer) = explode('::',$answer);
//getting the matches
$answer = api_ereg_replace('\[[^]]+\]','<input type="text" name="choice['.$questionId.'][]" size="10" />',($answer));
$answer = api_preg_replace('/\[[^]]+\]/', Display::input('text', "choice[$questionId][]", '', $attributes), $answer);
api_preg_match_all('/\[[^]]+\]/', $answer, $fill_list);
if (isset($user_choice[0]['answer'])) {
api_preg_match_all('/\[[^]]+\]/', $user_choice[0]['answer'], $user_fill_list);
$user_fill_list = $user_fill_list[0];
}*/
list($answer) = explode('::',$answer);
api_preg_match_all('/\[[^]]+\]/', $answer, $teacher_answer_list);
if (isset($user_choice[0]['answer'])) {
api_preg_match_all('/\[[^]]+\]/', $user_choice[0]['answer'], $student_answer_list);
$student_answer_list = $student_answer_list[0];
}
//var_dump($teacher_answer_list, $student_answer_list);
if (!empty($teacher_answer_list) && !empty($student_answer_list)) {
$teacher_answer_list = $teacher_answer_list[0];
$i = 0;
foreach($teacher_answer_list as $teacher_item) {
$value = null;
if (isset($student_answer_list[$i]) && !empty($student_answer_list[$i])) {
//Cleaning student answer list
$value = strip_tags($student_answer_list[$i]);
$value = api_substr($value,1, api_strlen($value)-2);
$value = explode('/', $value);
if (!empty($value[0])) {
$value = trim($value[0]);
$value = str_replace('&nbsp;', '', $value);
}
$answer = api_preg_replace('/\['.$teacher_item.'+\]/', Display::input('text', "choice[$questionId][]", $value), $answer);
}
$i++;
}
} else {
$answer = api_preg_replace('/\[[^]]+\]/', Display::input('text', "choice[$questionId][]", '', $attributes), $answer);
}
$s .= '<tr><td colspan="3">'.$answer.'</td></tr>';
} elseif ($answerType == MATCHING) {
// matching type, showing suggestions and answers
// TODO: replace $answerId by $numAnswer
if ($answerCorrect != 0) {
// only show elements to be answered (not the contents of
// the select boxes, who are corrrect = 0)
$s .= '<tr><td width="45%" valign="top">';
$parsed_answer = text_filter($answer);
$question_list[] = $parsed_answer;
$parsed_answer = $answer;
//$question_list[] = $parsed_answer;
//left part questions
$s .= ' <span style="float:left; width:8%;"><b>'.$lines_count.'</b>.&nbsp;</span>
<span style="float:left; width:92%;">'.$parsed_answer.'</span></td>';
//middle part (matches selects)
$s .= '<td width="10%" valign="top" align="center">&nbsp;&nbsp;
<select name="choice['.$questionId.']['.$numAnswer.']">
<option value="0">--</option>';
<select name="choice['.$questionId.']['.$numAnswer.']">';
// fills the list-box
foreach ($select_items as $key=>$val) {
// set $debug_mark_answer to true at function start to
@ -357,13 +390,17 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
if ($debug_mark_answer) {
if ($val['id'] == $answerCorrect) {
$help = '-x';
$selected = 'selected="selected"';
//$selected = 'selected="selected"';
}
}
if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) {
$selected = 'selected="selected"';
}
$s .= '<option value="'.$val['id'].'" '.$selected.'>'.$val['letter'].$help.'</option>';
} // end foreach()
$s .= '</select>&nbsp;&nbsp;</td>';
$s .= '</select></td>';
//print_r($select_items);
//right part (answers)
$s.='<td width="45%" valign="top" >';
@ -382,7 +419,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
// if it remains answers to shown at the right side
while (isset($select_items[$lines_count])) {
$s .= '<tr>
<td colspan="2">&nbsp;</td>
<td colspan="2"></td>
<td valign="top">';
$s.='<b>'.$select_items[$lines_count]['letter'].'.</b> '.$select_items[$lines_count]['answer'];
$s.="</td>
@ -390,35 +427,13 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
$lines_count++;
} // end while()
} // end if()
$matching_correct_answer++;
}
}
} // end for()
/*
//Adding divs for the new MATCHING interface
if ($answerType == MATCHING && !$freeze) {
echo '<div id="questions">';
echo Display::tag('h2','Questions');
$i = 1;
foreach ($question_list as $key=>$val) {
echo Display::tag('div', Display::tag('p',$val), array('id'=>'question_'.$i, 'class'=>'question_item ui-widget-header'));
$i++;
}
echo '</div>';
echo Display::tag('h2','Options');
echo '<div id="options" class=" ui-widget-header">';
foreach ($select_items as $key=>$val) {
echo Display::tag('div', Display::tag('p',$val['answer']), array('id'=>'option_'.$i, 'class'=>'option_item ui-widget-content'));
}
echo '</ul>';
}*/
$s .= '</table>';
$s .= '</div>';
$s .= '</div><br />';
// destruction of the Answer object
unset($objAnswerTmp);
@ -429,7 +444,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
if ($origin != 'export') {
echo $s;
} else {
return($s);
return $s;
}
} elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
// Question is a HOT_SPOT
@ -486,16 +501,14 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
if (!$only_questions) {
if ($show_title) {
echo '<div id="question_title" class="sectiontitle">'.get_lang('Question').' '.$current_item.' : '.$questionName.'</div>';
echo '<div class="question_title">'.$current_item.'. '.$questionName.'</div>';
}
//@todo I need to the get the feedback type
//if($answerType == 2)
// $s.=' / '.$total_item;
echo '<input type="hidden" name="hidden_hotspot_id" value="'.$questionId.'" />';
echo '<table class="exercise_questions" >
<tr>
<td valign="top" colspan="2">';
echo $questionDescription=text_filter($questionDescription);
echo $questionDescription;
echo '</td></tr>';
}
$canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
@ -638,7 +651,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
</td></tr>';
echo $s;
}
echo '</table><br />';
echo '</table>';
return $nbrAnswers;
}

@ -0,0 +1,223 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Exercise reminder overview
* Then it shows the results on the screen.
* @package chamilo.exercise
* @author Julio Montoya Armas switchable fill in blank option added
*/
/* INIT SECTION */
require_once 'exercise.class.php';
require_once 'exercise.lib.php';
require_once 'question.class.php';
require_once 'answer.class.php';
// Name of the language file that needs to be included
$language_file='exercice';
require_once '../inc/global.inc.php';
if ($_GET['origin']=='learnpath') {
require_once '../newscorm/learnpath.class.php';
require_once '../newscorm/learnpathItem.class.php';
require_once '../newscorm/scorm.class.php';
require_once '../newscorm/scormItem.class.php';
require_once '../newscorm/aicc.class.php';
require_once '../newscorm/aiccItem.class.php';
}
require_once api_get_path(LIBRARY_PATH).'exercise_show_functions.lib.php';
require_once api_get_path(LIBRARY_PATH).'mail.lib.inc.php';
$this_section = SECTION_COURSES;
/* ACCESS RIGHTS */
// notice for unauthorized people.
api_protect_course_script(true);
if($debug>0){error_log('Entered exercise_result.php: '.print_r($_POST,1));}
// general parameters passed via POST/GET
if ( empty ( $origin ) ) { $origin = Security::remove_XSS($_REQUEST['origin']);}
if ( empty ( $learnpath_id ) ) { $learnpath_id = intval($_REQUEST['learnpath_id']);}
if ( empty ( $learnpath_item_id ) ) { $learnpath_item_id = intval($_REQUEST['learnpath_item_id']);}
if ( empty ( $learnpath_item_view_id ) ) { $learnpath_item_view_id = intval($_REQUEST['learnpath_item_view_id']);}
if ( empty ($exerciseId)) { $exerciseId = intval($_REQUEST['exerciseId']);}
if ( empty ($objExercise)) { $objExercise = $_SESSION['objExercise'];}
if (!$objExercise) {
//Redirect to the exercise overview
//Check if the exe_id exists
header("Location: overview.php?exerciseId=".$exerciseId);
exit;
}
if (isset($_SESSION['exe_id'])) {
$exe_id = intval($_SESSION['exe_id']);
}
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
if (!empty($exercise_stat_info['data_tracking'])) {
$question_list = explode(',', $exercise_stat_info['data_tracking']);
}
if (empty($exercise_stat_info) || empty($question_list)) {
api_not_allowed();
}
$nameTools = get_lang('Exercice');
$interbreadcrumb[] = array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices'));
if ($origin != 'learnpath') {
//so we are not in learnpath tool
Display::display_header($nameTools,get_lang('Exercise'));
} else {
Display::display_reduced_header();
}
/* DISPLAY AND MAIN PROCESS */
// I'm in a preview mode as course admin. Display the action menu.
if (api_is_course_admin() && $origin != 'learnpath') {
echo '<div class="actions">';
echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'), array(), 32).'</a>';
echo '<a href="exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$objExercise->id.'">'.Display::return_icon('edit.png', get_lang('ModifyExercise'), array(), 32).'</a>';
echo '</div>';
}
$user_info = api_get_user_info(api_get_user_id());
echo $exercise_header = $objExercise->show_exercise_result_header(api_get_person_name($user_info['firstName'], $user_info['lastName']), null, 'review');
echo Display::div(get_lang('QuestionsToReview'), array('class'=>'question_title'));
echo Display::div('', array('id'=>'message'));
echo '<script>
lp_data = $.param({"learnpath_id": '.$learnpath_id.', "learnpath_item_id" : '.$learnpath_item_id.', "learnpath_item_view_id": '.$learnpath_item_view_id.'});
function final_submit() {
//Normal inputs
window.location = "exercise_result.php?origin='.$origin.'&exe_id='.$exe_id.'&" + lp_data;
}
function review_questions() {
var is_checked = 1;
$("input[type=checkbox]").each(function () {
if ($(this).attr("checked") == "checked") {
is_checked = 2;
return false;
}
});
if (is_checked == 1) {
$("#message").addClass("warning-message");
$("#message").html("'.addslashes(get_lang('SelectAQuestionToReview')).'");
}
window.location = "exercise_submit.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'&reminder=2&origin='.$origin.'&" + lp_data;
}
function save_remind_item(obj, question_id) {
var action = "";
if ($(obj).is(\':checked\')) {
action = "add";
} else {
action = "delete";
}
$.ajax({
url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=add_question_to_reminder",
data: "question_id="+question_id+"&exe_id='.$exe_id.'&action="+action,
success: function(return_value) {
},
});
}
</script>';
$attempt_list = get_all_exercise_event_by_exe_id($exe_id);
$remind_list = $exercise_stat_info['questions_to_check'];
$remind_list = explode(',', $remind_list);
$exercise_result = array();
foreach ($attempt_list as $question_id => $options) {
//echo $question_id.'<br />';
foreach($options as $item) {
$question_obj = Question::read($item['question_id']);
switch($question_obj->type) {
case FILL_IN_BLANKS:
$item['answer'] = $objExercise->fill_in_blank_answer_to_string($item['answer']);
break;
case HOT_SPOT:
//var_dump($item['answer']);
break;
}
if ($item['answer'] != '0' && !empty($item['answer'])) {
$exercise_result[] = $question_id;
break;
}
}
}
$rows = array(Display::div('', array('class'=>'question_no_answer', 'style'=>'width:20px;height:10px;')), get_lang('QuestionWithNoAnswer'));
echo Display::table(array() , $rows, array('class'=>'t'));
$table = '';
$counter = 0;
// Loop over all question to show results for each of them, one by one
foreach ($question_list as $questionId) {
// destruction of the Question object
unset($objQuestionTmp);
// creates a temporary Question object
$objQuestionTmp = Question :: read($questionId);
// initialize question information
$quesId = $objQuestionTmp->selectId();
$check_id = 'remind_list['.$questionId.']';
$attributes = array('id'=>$check_id, 'onclick'=>"save_remind_item(this, '$questionId');");
if (in_array($questionId, $remind_list)) {
$attributes['checked'] = 1;
}
$label_attributes = array();
$label_attributes['class'] = '';
$label_attributes['for'] = $check_id;
//Check if the question doesn't have an answer
if (!in_array($questionId, $exercise_result)) {
$label_attributes['class'] = "question_no_answer";
}
$checkbox = Display::input('checkbox', 'remind_list['.$questionId.']', '', $attributes);
$url = 'exercise_submit.php?exerciseId='.$objExercise->id.'&num='.$counter.'&reminder=1';
$counter++;
if ($objExercise->type == ONE_PER_PAGE) {
$question_title = Display::url($counter.'. '.cut($objQuestionTmp->selectTitle(), 40), $url);
$question_title = $counter.'. '.cut($objQuestionTmp->selectTitle(), 40);
} else {
$question_title = $counter.'. '.cut($objQuestionTmp->selectTitle(), 40);
}
$question_title = Display::tag('label', $question_title, $label_attributes);
$table .= Display::div($checkbox.$question_title, array('class'=>'exercise_reminder_item'));
} // end foreach() block that loops over all questions
echo Display::div($table, array('class'=>'exercise_reminder_container'));
$exercise_actions = Display::url(get_lang('ValidateAnswers'), 'javascript://', array('onclick'=>'final_submit();', 'class'=>'a_button green'));
$exercise_actions .= Display::url(get_lang('ReviewQuestions'), 'javascript://', array('onclick'=>'review_questions();','class'=>'a_button white medium '));
echo Display::div('', array('class'=>'clear'));
echo Display::div($exercise_actions, array('class'=>'exercise_actions'));
if ($origin != 'learnpath') {
//we are not in learnpath tool
Display::display_footer();
}

@ -44,43 +44,29 @@ $this_section=SECTION_COURSES;
api_protect_course_script(true);
// Database table definitions
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
$TBL_TRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
$TBL_TRACK_ATTEMPT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$main_user_table = Database::get_main_table(TABLE_MAIN_USER);
$main_admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
$main_course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
if($debug>0){error_log('Entered exercise_result.php: '.print_r($_POST,1));}
// general parameters passed via POST/GET
if ( empty ( $origin ) ) { $origin = Security::remove_XSS($_REQUEST['origin']);}
if ( empty ( $learnpath_id ) ) { $learnpath_id = intval($_REQUEST['learnpath_id']);}
if ( empty ( $learnpath_item_id ) ) { $learnpath_item_id = intval($_REQUEST['learnpath_item_id']);}
if ( empty ( $learnpath_item_view_id ) ) { $learnpath_item_view_id = intval($_REQUEST['learnpath_item_view_id']);}
if ( empty ( $formSent ) ) { $formSent = $_REQUEST['formSent'];}
if ( empty ( $exerciseResult ) ) { $exerciseResult = $_SESSION['exerciseResult'];}
if ( empty ( $exerciseResultCoordinates)){ $exerciseResultCoordinates = $_SESSION['exerciseResultCoordinates'];}
if ( empty ( $questionId ) ) { $questionId = $_REQUEST['questionId'];}
if ( empty ( $choice ) ) { $choice = $_REQUEST['choice'];}
if ( empty ( $questionNum ) ) { $questionNum = $_REQUEST['questionNum'];}
if ( empty ( $nbrQuestions ) ) { $nbrQuestions = $_REQUEST['nbrQuestions'];}
if ( empty ( $questionList ) ) { $questionList = $_SESSION['questionList'];}
if ( empty ( $objExercise ) ) { $objExercise = $_SESSION['objExercise'];}
if ( empty ( $exerciseType ) ) { $exerciseType = $_REQUEST['exerciseType'];}
if ( empty ( $remind_list ) ) { $remind_list = $_REQUEST['remind_list'];}
//@todo There should be some doc about this settings
$_configuration['live_exercise_tracking'] = false;
if ($_configuration['live_exercise_tracking']) define('ENABLED_LIVE_EXERCISE_TRACKING',1);
$exe_id = isset($_REQUEST['exe_id']) ? intval($_REQUEST['exe_id']) : 0;
if ($_configuration['live_exercise_tracking'] && $exerciseType == 1){
$_configuration['live_exercise_tracking'] = false;
if (empty($objExercise)) {
//Redirect to the exercise overview
//Check if the exe_id exists
$objExercise = new Exercise();
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
if (!empty($exercise_stat_info) && isset($exercise_stat_info['exe_exo_id'])) {
header("Location: overview.php?exerciseId=".$exercise_stat_info['exe_exo_id']);
exit;
}
api_not_allowed();
}
$arrques = array();
$arrans = array();
// set admin name as person who sends the results e-mail (lacks policy about whom should really send the results)
@ -92,13 +78,6 @@ $from_name = api_get_person_name($uinfo['firstname'], $uinfo['lastname'], null,
$str = $_SERVER['REQUEST_URI'];
$url = api_get_path(WEB_CODE_PATH).'exercice/exercice.php?'.api_get_cidreq().'&show=result';
// if the above variables are empty or incorrect, we don't have any result to show, so stop the script
if (!is_array($exerciseResult) || !is_array($questionList) || !is_object($objExercise)) {
if ($debug) {error_log('Exit exercise result'); error_log('$exerciseResult: '.print_r($exerciseResult,1)); error_log('$questionList:'.print_r($questionList,1));error_log('$objExercise:'.print_r($objExercise,1));}
header('Location: exercice.php');
exit();
}
$gradebook = '';
if (isset($_SESSION['gradebook'])) {
$gradebook= $_SESSION['gradebook'];
@ -107,31 +86,17 @@ if (!empty($gradebook) && $gradebook=='view') {
$interbreadcrumb[]= array ('url' => '../gradebook/'.$_SESSION['gradebook_dest'], 'name' => get_lang('ToolGradebook'));
}
$nameTools = get_lang('Result');
$nameTools = get_lang('Exercice');
$interbreadcrumb[]= array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices'));
//$htmlHeadXtra[] = $objExercise->show_lp_javascript();
if ($origin != 'learnpath') {
//so we are not in learnpath tool
Display::display_header($nameTools,get_lang('Exercise'));
} else {
header('Content-Type: text/html; charset='.api_get_system_encoding());
$document_language = api_get_language_isocode();
/* HTML HEADER */
?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $document_language; ?>" lang="<?php echo $document_language; ?>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $charset; ?>" />
<link rel="stylesheet" type="text/css" href="<?php echo api_get_path(WEB_CODE_PATH).'css/'.api_get_setting('stylesheets').'/default.css'; ?>" />
</head>
<body dir="<?php echo api_get_text_direction(); ?>">
<?php
Display::display_reduced_header();
}
//Hide results
$show_results = false;
$show_only_score = false;
@ -154,31 +119,36 @@ if (api_is_course_admin() && $origin != 'learnpath') {
echo '</div>';
}
$exerciseTitle = $objExercise->selectTitle();
$feedback_type = $objExercise->feedbacktype;
//show exercise title
if($origin == 'learnpath') { ?>
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
if (!empty($exercise_stat_info['data_tracking'])) {
$question_list = explode(',', $exercise_stat_info['data_tracking']);
}
$safe_lp_id = $exercise_stat_info['orig_lp_id'];
$safe_lp_item_id = $exercise_stat_info['orig_lp_item_id'];
$safe_lp_item_view_id = $exercise_stat_info['orig_lp_item_view_id'];
if ($origin == 'learnpath') {
?>
<form method="get" action="exercice.php?<?php echo api_get_cidreq() ?>">
<input type="hidden" name="origin" value="<?php echo $origin; ?>" />
<input type="hidden" name="learnpath_id" value="<?php echo $learnpath_id; ?>" />
<input type="hidden" name="learnpath_item_id" value="<?php echo $learnpath_item_id; ?>" />
<input type="hidden" name="learnpath_item_view_id" value="<?php echo $learnpath_item_view_id; ?>" />
<input type="hidden" name="learnpath_id" value="<?php echo $safe_lp_id; ?>" />
<input type="hidden" name="learnpath_item_id" value="<?php echo $safe_lp_item_id; ?>" />
<input type="hidden" name="learnpath_item_view_id" value="<?php echo $safe_lp_item_view_id; ?>" />
<?php
}
$i = $totalScore = $totalWeighting=0;
if ($debug>0){error_log ("ExerciseResult: ".print_r($exerciseResult,1)); error_log("QuestionList: ".print_r($questionList,1));}
$safe_lp_id = $learnpath_id==''?0:(int)$learnpath_id;
$safe_lp_item_id = $learnpath_item_id==''?0:(int)$learnpath_item_id;
$safe_lp_item_view_id = $learnpath_item_view_id==''?0:(int)$learnpath_item_view_id;
$i = $total_score = $total_weight = 0;
//We check if the user attempts before sending to the exercise_result.php
if ($objExercise->selectAttempts() > 0) {
$attempt_count = get_attempt_count(api_get_user_id(), $objExercise->id, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id);
if ($attempt_count >= $objExercise->selectAttempts()) {
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false);
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $objExercise->selectTitle(), $objExercise->selectAttempts()), false);
if ($origin != 'learnpath') {
//we are not in learnpath tool
Display::display_footer();
@ -187,18 +157,17 @@ if ($objExercise->selectAttempts() > 0) {
}
}
// Create an empty exercise
if (api_is_allowed_to_session_edit()) {
$exeId = create_event_exercice($objExercise->selectId());
}
$user_info = api_get_user_info(api_get_user_id());
if ($show_results || $show_only_score) {
echo $exercise_header = $objExercise->show_exercise_result_header(api_get_person_name($user_info['firstName'], $user_info['lastName']));
}
Display :: display_confirmation_message(get_lang('Saved').'<br /><br />',false);
$counter = 1;
// Loop over all question to show results for each of them, one by one
foreach ($questionList as $questionId) {
foreach ($question_list as $questionId) {
// destruction of the Question object
unset($objQuestionTmp);
@ -207,64 +176,34 @@ foreach ($questionList as $questionId) {
// creates a temporary Question object
$objQuestionTmp = Question :: read($questionId);
// initialize question information
$questionName = $objQuestionTmp->selectTitle();
$questionDescription = $objQuestionTmp->selectDescription();
$questionWeighting = $objQuestionTmp->selectWeighting();
$answerType = $objQuestionTmp->selectType();
$quesId = $objQuestionTmp->selectId();
//this variable commes from exercise_submit_modal.php
$hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$quesId];
//$hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$quesId];
if ($show_results) {
// show titles
if ($origin != 'learnpath') {
echo $objQuestionTmp->return_header($objExercise->feedbacktype, $counter );
echo $objQuestionTmp->return_header($objExercise->feedback_type, $counter);
$counter++;
if ($answerType == HOT_SPOT) {
?>
<tr>
<td valign="top" colspan="2">
<table width="552" border="1" bordercolor="#A4A4A4" style="border-collapse: collapse;">
<tr>
<td width="152" valign="top">
<i><?php echo get_lang("CorrectAnswer"); ?></i><br /><br />
</td>
<td width="100" valign="top">
<i><?php echo get_lang('HotspotHit'); ?></i><br /><br />
</td>
<?php if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
<td width="300" valign="top">
<i><?php echo get_lang("Comment"); ?></i><br /><br />
</td>
<?php } else { ?>
<td>&nbsp;</td>
<?php } ?>
</tr>
<?php
}
}
}
// We're inside *one* question. Go through each possible answer for this question
$result = $objExercise->manage_answer($exeId, $questionId, $choice,'exercise_result', $exerciseResultCoordinates, true, false, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result);
$totalScore += $result['score'];
$totalWeighting += $result['weight'];
$result = $objExercise->manage_answer($exercise_stat_info['exe_id'], $questionId, null ,'exercise_result', array(), false, true, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result);
}
$total_score += $result['score'];
$total_weight += $result['weight'];
} // end foreach() block that loops over all questions
if ($origin != 'learnpath') {
if ($show_results || $show_only_score) {
echo '<div id="question_score">';
echo get_lang('YourTotalScore')." ";
if ($objExercise->selectPropagateNeg() == 0 && $totalScore < 0) {
$totalScore = 0;
if ($objExercise->selectPropagateNeg() == 0 && $total_score < 0) {
$total_score = 0;
}
echo show_score($totalScore, $totalWeighting, false);
echo show_score($total_score, $total_weight, false);
echo '</div>';
}
/* <button type="submit" class="save"><?php echo get_lang('Finish');?></button> */
}
// Tracking of results
@ -272,29 +211,26 @@ if ($show_results || $show_only_score) {
$quizDuration = (!empty($_SESSION['quizStartTime']) ? time() - $_SESSION['quizStartTime'] : 0);
$feed = $objExercise->feedbacktype;
if (api_is_allowed_to_session_edit()) {
update_event_exercice($exeId, $objExercise->selectId(), $totalScore, $totalWeighting, api_get_session_id(), $safe_lp_id,$safe_lp_item_id,$safe_lp_item_view_id, $quizDuration, $questionList);
update_event_exercice($exercise_stat_info['exe_id'], $objExercise->selectId(), $total_score, $total_weight, api_get_session_id(), $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $quiz_duration, $question_list, '');
api_session_unregister('objExercise');
api_session_unregister('exe_id');
}
if ($origin != 'learnpath') {
Display :: display_normal_message(get_lang('ExerciseFinished').'<br /><a href="exercice.php" />'.get_lang('Back').'</a>',false);
Display::display_footer();
} else {
Display :: display_normal_message(get_lang('ExerciseFinished').'<br /><br />',false);
$lp_mode = $_SESSION['lp_mode'];
$url = '../newscorm/lp_controller.php?cidReq='.api_get_course_id().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exeId.'&fb_type='.$objExercise->feedbacktype;
$url = '../newscorm/lp_controller.php?cidReq='.api_get_course_id().'&action=view&lp_id='.$safe_lp_id.'&lp_item_id='.$safe_lp_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$feed;
//echo $total_score.','.$total_weight; exit;
$href = ($lp_mode == 'fullscreen')?' window.opener.location.href="'.$url.'" ':' top.location.href="'.$url.'" ';
echo '<script language="javascript" type="text/javascript">'.$href.'</script>'."\n";
//record the results in the learning path, using the SCORM interface (API)
echo '<script language="javascript" type="text/javascript">window.parent.API.void_save_asset('.$totalScore.','.$totalWeighting.');</script>'."\n";
echo '<script language="javascript" type="text/javascript">window.parent.API.void_save_asset('.$total_score.','.$total_weight.');</script>'."\n";
echo '</body></html>';
}
if ($origin != 'learnpath') {
//we are not in learnpath tool
Display::display_footer();
}
// Send notification..
if (!api_is_allowed_to_edit(null,true)) {
$objExercise->send_notification($arrques, $arrans, $origin);

@ -276,7 +276,7 @@ foreach ($questionList as $questionId) {
$quesId = $objQuestionTmp->selectId();
if ($show_results) {
echo $objQuestionTmp->return_header($feedback_type, $counter);
echo $objQuestionTmp->return_header($counter);
}
$counter++;

@ -17,7 +17,11 @@
* the administrator
* @package chamilo.exercise
* @author Olivier Brouckaert
* @author Julio Montoya multiple fill in blank option added (2008) and Cleaning exercises (2010), Adding hotspot delineation support (2011)
* @author Julio Montoya <gugli100@gmail.com>
* Fill in blank option added (2008)
* Cleaning exercises (2010),
* Adding hotspot delineation support (2011)
* Adding reminder + ajax support (2011)
*/
/**
* Code
@ -27,7 +31,7 @@ require_once 'question.class.php';
require_once 'answer.class.php';
require_once 'exercise.lib.php';
//$debug = 1; //debug value is set in the exercise.class.php file
$debug = 1; //debug value is set in the exercise.class.php file
// name of the language file that needs to be included
$language_file = 'exercice';
@ -36,34 +40,28 @@ require_once '../inc/global.inc.php';
$this_section = SECTION_COURSES;
if($debug) { error_log('Entered exercise_submit.php: '.print_r($_POST,1)); }
if ($debug) { error_log('--- Enter to the exercise_submit.php ---- '); error_log('0. POST variables : '.print_r($_POST,1)); }
// Notice for unauthorized people.
api_protect_course_script(true);
$is_allowedToEdit = api_is_allowed_to_edit(null,true);
$htmlHeadXtra[] = api_get_jquery_js();
if (api_get_setting('show_glossary_in_extra_tools') == 'true') {
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/glossary.js" type="text/javascript" language="javascript"></script>'; //Glossary
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.highlight.js" type="text/javascript" language="javascript"></script>';
}
//@todo we should only enable this when there is a time control
//This library is necessary for the time control feature
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.epiclock.min.js" type="text/javascript" language="javascript"></script>'; //jQuery
$_configuration['live_exercise_tracking'] = true;
//Table calls
$stat_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
$exercice_attemp_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$TBL_EXERCICE_QUESTION = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST);
$TBL_QUESTIONS = Database :: get_course_table(TABLE_QUIZ_QUESTION);
$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER);
// General parameters passed via POST/GET
if (empty ($origin)) {
$origin = Security::remove_XSS($_REQUEST['origin']);
}
@ -85,9 +83,6 @@ if (empty ($exerciseResult)) {
if (empty ($exerciseResultCoordinates)) {
$exerciseResultCoordinates = $_REQUEST['exerciseResultCoordinates'];
}
if (empty ($exerciseType)) {
$exerciseType = $_REQUEST['exerciseType'];
}
if (empty ($exerciseId)) {
$exerciseId = intval($_REQUEST['exerciseId']);
}
@ -100,15 +95,24 @@ if (empty($_REQUEST['choice'])) {
if (empty ($questionNum)) {
$questionNum = intval($_REQUEST['questionNum']);
}
if (empty ($nbrQuestions)) {
$nbrQuestions = intval($_REQUEST['nbrQuestions']);
if (empty ($current_question)) {
$current_question = intval($_REQUEST['num']);
}
if (empty ($buttonCancel)) {
$buttonCancel = $_REQUEST['buttonCancel'];
}
$reminder = isset($_GET['reminder']) ? intval($_GET['reminder']) : 0;
$remind_question_id = isset($_GET['remind_question_id']) ? intval($_GET['remind_question_id']) : 0;
if ($remind_question_id == -1) {
header('Location: exercise_reminder.php?origin='.$origin.'&exerciseId='.$exerciseId);
exit;
}
$error = '';
// if the user has clicked on the "Cancel" button
// If the user has clicked on the "Cancel" button
if ($buttonCancel) {
// returns to the exercise list
header("Location: exercice.php?origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
@ -127,63 +131,86 @@ if (api_is_allowed_to_edit(null,true) && $_GET['preview'] == 1 ) {
api_session_unregister('objExercise');
}
// Loading the $objExercise variable
// 1. Loading the $objExercise variable
if (!isset ($_SESSION['objExercise']) || $_SESSION['objExercise']->id != $_REQUEST['exerciseId']) {
// Construction of Exercise
$objExercise = new Exercise();
if ($debug) {error_log('Setting the $objExercise variable'); };
if ($debug) {error_log('1. Setting the $objExercise variable'); };
unset($_SESSION['questionList']);
// if the specified exercise doesn't exist or is disabled
if (!$objExercise->read($exerciseId) || (!$objExercise->selectStatus() && !$is_allowedToEdit && ($origin != 'learnpath'))) {
if ($debug) {error_log('Error while reading the exercise'); };
if ($debug) {error_log('1.1. Error while reading the exercise'); };
unset ($objExercise);
$error = get_lang('ExerciseNotFound');
} else {
// saves the object into the session
// Saves the object into the session
api_session_register('objExercise');
if ($debug) {error_log('$_SESSION[objExercise] was unset - set now - end'); };
if ($debug) {error_log('1.1. $_SESSION[objExercise] was unset - set now - end'); };
}
}
//2. Checking if $objExercise is set
if (!isset($objExercise) && isset($_SESSION['objExercise'])) {
if ($debug) {error_log('Loading $objExercise from session'); };
if ($debug) { error_log('2. Loading $objExercise from session'); };
$objExercise = $_SESSION['objExercise'];
}
//3. $objExercise is not set, then return to the exercise list
if (!is_object($objExercise)) {
if ($debug) {error_log('$objExercise was not set, kill the script'); };
if ($debug) {error_log('3. $objExercise was not set, kill the script'); };
header('Location: exercice.php');
exit;
}
$exerciseType = $objExercise->type;
$current_timestamp = time();
//Getting track exercise info
//4. Setting the exe_id (attempt id)
$exe_id = null;
if (isset($_SESSION['exe_id'])) {
$exe_id = $_SESSION['exe_id'];
}
//4. Getting user exercise info (if the user took the exam before)
$exercise_stat_info = $objExercise->get_stat_track_exercise_info($safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id);
//$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
$my_remind_list = array();
if ($debug) {error_log('$objExercise->get_stat_track_exercise_info function called:: '.print_r($exercise_stat_info, 1)); };
if ($debug) { error_log('5. $objExercise->get_stat_track_exercise_info function called:: '.print_r($exercise_stat_info, 1)); };
if (!empty($exercise_stat_info['questions_to_check'])) {
$my_remind_list = $exercise_stat_info['questions_to_check'];
$my_remind_list = explode(',', $my_remind_list);
$my_remind_list = array_filter($my_remind_list);
}
$params = 'exe_id'.$exe_id.'&exerciseId='.$exerciseId.'&origin='.$origin.'&learnpath_id='.$learnpath_id.'&learnpath_item_id='.$learnpath_item_id.'&learnpath_item_view_id='.$learnpath_item_view_id;
if ($reminder == 2 && empty($my_remind_list)) {
header('Location: exercise_reminder.php?'.$params);
exit;
}
/*
* Time control feature
* if the expired time is major that zero(0) then the expired time is compute on this time. Disable for learning path
* 6. Loading Time control parameters
* If the expired time is major that zero(0) then the expired time is compute on this time. Disable for learning path
*/
$time_control = false;
if ($objExercise->expired_time != 0 && $origin != 'learnpath') {
$time_control = true;
}
if ($time_control) {
if ($debug) error_log('6.1. Time control is enabled');
//Get the expired time of the current exercice in track_e_exercices
$total_seconds = $objExercise->expired_time*60;
//Generating the time control key
$current_expired_time_key = generate_time_control_key($objExercise->id);
if ($debug) {error_log('$current_expired_time_key '.$current_expired_time_key); };
if ($debug) {error_log('6.2. $current_expired_time_key '.$current_expired_time_key); };
if (!isset($_SESSION['expired_time'][$current_expired_time_key])) {
//Timer - Get expired_time for a student
if (!empty($exercise_stat_info)) {
if ($debug) {error_log('Seems that the session ends and the user want to retake the exam'); };
if ($debug) {error_log('6.3 Seems that the session ends and the user want to retake the exam'); };
$expired_time_of_this_attempt = $exercise_stat_info['expired_time_control'];
if ($debug) {error_log('$expired_time_of_this_attempt: '.$expired_time_of_this_attempt); }
//Get the last attempt of an exercice
@ -198,64 +225,47 @@ if ($time_control) {
$diff = $current_timestamp - api_strtotime($last_attempt_date,'UTC');
$last_attempt_date = api_get_utc_datetime(api_strtotime($last_attempt_date,'UTC') + $diff);
}
if ($debug) {error_log('$last_attempt_date: '.$last_attempt_date); }
if ($debug) {error_log('6.4. $last_attempt_date: '.$last_attempt_date); }
//New expired time - it is due to the possible closure of session
$new_expired_time_in_seconds = api_strtotime($expired_time_of_this_attempt, 'UTC') - api_strtotime($last_attempt_date,'UTC');
if ($debug) {error_log('$new_expired_time_in_seconds: '.$new_expired_time_in_seconds); }
if ($debug) {error_log('6.5. $new_expired_time_in_seconds: '.$new_expired_time_in_seconds); }
$expected_time = $current_timestamp + $new_expired_time_in_seconds;
if ($debug) {error_log('$expected_time1: '.$expected_time); }
if ($debug) {error_log('6.6. $expected_time1: '.$expected_time); }
//$plugin_expired_time = date('M d, Y H:i:s', $expected_time);
$clock_expired_time = api_get_utc_datetime($expected_time);
if ($debug) {error_log('$clock_expired_time: '.$clock_expired_time); }
//@todo check this validation with Fasa: With this change the user can log out and login from the system and the counter will not work
/*
//We modify the "expired_time_control" field in track_e_exercices for this attempt
$sql_track_e_exe = "UPDATE $stat_table SET expired_time_control = '".$clock_expired_time."' WHERE exe_id = '".$exercise_stat_info['exe_id']."'";
if ($debug) {error_log('$sql_track_e_exe1: '.$sql_track_e_exe); }
Database::query($sql_track_e_exe);
*/
if ($debug) {error_log('6.7. $clock_expired_time: '.$clock_expired_time); }
// First we update the attempt to today
// How the expired time is changed into "track_e_exercices" table,then the last attempt for this student should be changed too,so
$sql_track_e_exe = "UPDATE $exercice_attemp_table SET tms = '".api_get_utc_datetime()."' WHERE exe_id = '".$exercise_stat_info['exe_id']."' AND tms = '".$last_attempt_date."' ";
if ($debug) {error_log('$sql_track_e_exe2: '.$sql_track_e_exe); }
if ($debug) {error_log('6.8. $sql_track_e_exe2: '.$sql_track_e_exe); }
Database::query($sql_track_e_exe);
//Sessions that contain the expired time
$_SESSION['expired_time'][$current_expired_time_key] = $clock_expired_time;
if ($debug) {error_log('1. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); };
if ($debug) {error_log('6.9. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); };
} else {
$expected_time = $current_timestamp + $total_seconds;
if ($debug) error_log('$current_timestamp '.$current_timestamp);
if ($debug) error_log('$expected_time '.$expected_time);
//$expected_time = api_strtotime(api_get_utc_datetime($expected_time));
if ($debug) error_log('6.3. $current_timestamp '.$current_timestamp);
if ($debug) error_log('6.4. $expected_time '.$expected_time);
//$plugin_expired_time = date('M d, Y H:i:s', $expected_time);
//$clock_expired_time = date('Y-m-d H:i:s', $expected_time);
$clock_expired_time = api_get_utc_datetime($expected_time);
if ($debug) error_log('$expected_time '.$clock_expired_time);
if ($debug) error_log('6.5. $expected_time '.$clock_expired_time);
//Sessions that contain the expired time
$_SESSION['expired_time'][$current_expired_time_key] = $clock_expired_time;
// $_SESSION['end_expired_time'][$current_expired_time_key] = $plugin_expired_time;
if ($debug) {error_log('2. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); };
//if ($debug) {error_log('2. Setting the $_SESSION[end_expired_time]: '.$_SESSION['end_expired_time'][$current_expired_time_key] ); };
if ($debug) {error_log('6.6. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); };
}
} else {
// $plugin_expired_time = $_SESSION['end_expired_time'][$current_expired_time_key];
$clock_expired_time = $_SESSION['expired_time'][$current_expired_time_key];
if ($debug) {error_log('Getting the $_SESSION[end_expired_time]: '.$_SESSION['end_expired_time'][$current_expired_time_key] ); };
if ($debug) {error_log('6.2. Getting the $_SESSION[end_expired_time]: '.$_SESSION['end_expired_time'][$current_expired_time_key] ); };
}
}
// get time left for exipiring time
//$time_left = api_strtotime($plugin_expired_time) - api_strtotime(api_get_utc_datetime());
// get time left for exipiring time
// Get time left for exipiring time
$time_left = api_strtotime($clock_expired_time,'UTC') - time();
/*
@ -266,11 +276,11 @@ if ($time_control) { //Sends the exercice form when the expired time is finished
$htmlHeadXtra[] = $objExercise->show_time_control_js($time_left);
}
if ($_configuration['live_exercise_tracking'] && $objExercise->type == ONE_PER_PAGE && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
/*
if ($objExercise->type == ONE_PER_PAGE && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (!empty($exercise_stat_info)) {
$exe_id = $exercise_stat_info['exe_id'];
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
define('QUESTION_LIST_ALREADY_LOGGED', 1);
$recorded['questionList'] = explode(',', $exercise_stat_info['data_tracking']);
$query = 'SELECT * FROM ' . $exercice_attemp_table . ' WHERE exe_id = ' . $exercise_stat_info['exe_id'] . ' ORDER BY tms ASC';
$result = Database::query($query);
@ -278,17 +288,43 @@ if ($_configuration['live_exercise_tracking'] && $objExercise->type == ONE_PER_P
$recorded['exerciseResult'][$row['question_id']] = 1;
}
$exerciseResult = $_SESSION['exerciseResult'] = $recorded['exerciseResult'];
$questionNum = count($recorded['exerciseResult']);
$questionNum++;
$current_question = count($recorded['exerciseResult']);
$current_question++;
$questionList = $_SESSION['questionList'] = $recorded['questionList'];
}
}
}*/
// if the user has submitted the form
$exercise_title = $objExercise->selectTitle();
$exercise_description = $objExercise->selectDescription();
$exercise_sound = $objExercise->selectSound();
//if (!isset($_SESSION['questionList']) || $origin == 'learnpath') {
//in LP's is enabled the "remember question" feature?
if (!isset($_SESSION['questionList'])) {
// selects the list of question ID
$questionList = $objExercise->get_validated_question_list();
api_session_register('questionList');
if ($debug > 0) { error_log('$_SESSION[questionList] was set'); }
}
if (!isset($objExercise) && isset($_SESSION['objExercise'])) {
$questionList = $_SESSION['questionList'];
}
// if the user has submitted the form
if ($debug) error_log('7 Question list loaded '.print_r($questionList, 1));
$quizStartTime = time();
api_session_register('quizStartTime');
//Real question count
$question_count = 0;
if (!empty($questionList)) {
$question_count = count($questionList);
}
if ($formSent && isset($_POST)) {
if ($debug > 0) { error_log('$formSent was set'); }
if ($debug > 0) { error_log('8. $formSent was set'); }
// Initializing
if (!is_array($exerciseResult)) {
@ -301,18 +337,18 @@ if ($formSent && isset($_POST)) {
$hotspot_id = (int)($_REQUEST['hidden_hotspot_id']);
$choice = array($hotspot_id => '');
}
// if the user has answered at least one question
if (is_array($choice)) {
if ($debug) { error_log('$choice is an array '.print_r($choice, 1)); }
if ($debug) { error_log('8.1. $choice is an array '.print_r($choice, 1)); }
// Also store hotspot spots in the session ($exerciseResultCoordinates
// will be stored in the session at the end of this script)
if (isset($_POST['hotspot'])) {
$exerciseResultCoordinates = $_POST['hotspot'];
if ($debug) { error_log('$_POST[hotspot] data '.print_r($exerciseResultCoordinates, 1)); }
if ($debug) { error_log('8.2. $_POST[hotspot] data '.print_r($exerciseResultCoordinates, 1)); }
}
if ($exerciseType == ALL_ON_ONE_PAGE) {
if ($objExercise->type == ALL_ON_ONE_PAGE) {
// $exerciseResult receives the content of the form.
// Each choice of the student is stored into the array $choice
$exerciseResult = $choice;
@ -324,42 +360,43 @@ if ($formSent && isset($_POST)) {
// stores the user answer into the array
$exerciseResult[$key] = $choice[$key];
//saving each question
if ($_configuration['live_exercise_tracking'] && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
$nro_question = $questionNum; // - 1;
//START of saving and qualifying each question submitted
define('ENABLED_LIVE_EXERCISE_TRACKING', 1);
if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) {
$nro_question = $current_question; // - 1;
$questionId = $key;
// gets the student choice for this question
$choice = $exerciseResult[$questionId];
if (isset($exe_id)) {
//Manage the question and answer attempts
if ($debug > 0) { error_log('manage_answer exe_id: '.$exe_id.' - $questionId: '.$questionId.' Choice'.print_r($choice,1)); }
if ($debug > 0) { error_log('8.3. manage_answer exe_id: '.$exe_id.' - $questionId: '.$questionId.' Choice'.print_r($choice,1)); }
$objExercise->manage_answer($exe_id, $questionId, $choice,'exercise_show',$exerciseResultCoordinates, true, false,false, $objExercise->propagate_neg);
}
//END of saving and qualifying
}
}
}
if ($debug > 0) { error_log('$choice is an array - end'); }
if ($debug > 0) { error_log('8.3. $choice is an array - end'); }
if ($debug > 0) { error_log('8.4. $exerciseResult '.print_r($exerciseResult,1)); }
}
// the script "exercise_result.php" will take the variable $exerciseResult from the session
api_session_register('exerciseResult');
api_session_register('remind_list');
api_session_register('exerciseResultCoordinates');
// if all questions on one page OR if it is the last question (only for an exercise with one question per page)
if ($exerciseType == ALL_ON_ONE_PAGE || $questionNum >= $nbrQuestions) {
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
if ($exerciseType == ALL_ON_ONE_PAGE) {
if ($objExercise->type == ALL_ON_ONE_PAGE) {
if ($debug) { error_log('Exercise ALL_ON_ONE_PAGE -> Redirecting to exercise_result.php'); }
//We check if the user attempts before sending to the exercise_result.php
if ($objExercise->selectAttempts() > 0) {
$attempt_count = get_attempt_count(api_get_user_id(), $exerciseId, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id);
if ($attempt_count >= $objExercise->selectAttempts()) {
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false);
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false);
if ($origin != 'learnpath') {
//so we are not in learnpath tool
echo '</div>'; //End glossary div
@ -369,7 +406,7 @@ if ($formSent && isset($_POST)) {
}
}
}
header("Location: exercise_result.php?exerciseType=$exerciseType&origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id");
header("Location: exercise_result.php?origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id");
exit;
} else {
//Time control is only enabled for ONE PER PAGE
@ -382,54 +419,91 @@ if ($formSent && isset($_POST)) {
$sql_exe_result = ", exe_result = 0";
if ($debug) { error_log('exercise_time_control_is_valid is NOT valid then exe_result = 0 '); }
}
/*
//Clean incomplete - @todo why setting to blank the status?
$update_query = "UPDATE $stat_table SET status = '', exe_date = '".api_get_utc_datetime() ."' , orig_lp_item_view_id = '$safe_lp_item_view_id' $sql_exe_result WHERE exe_id = ".$exe_id;
if ($debug) { error_log('Updating track_e_exercises '.$update_query); }
Database::query($update_query);
Database::query($update_query);*/
}
if ($debug) { error_log('Redirecting to exercise_show.php'); }
header("Location: exercise_show.php?id=$exe_id&exerciseType=$exerciseType&origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id");
header("Location: exercise_show.php?id=$exe_id&origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id");
exit;
}
} else {
if ($debug) { error_log('Redirecting to exercise_submit.php'); }
header("Location: exercise_submit.php?exerciseId=$exerciseId");
header("Location: exercise_submit.php?exerciseId=$exerciseId&origin=$origin");
exit;
}
}
if (!empty($remind_list)) {
//header("Location: exercise_reminder.php?origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id");
exit;
}
if ($debug > 0) { error_log('$formSent was set - end'); }
}
$exerciseTitle = $objExercise->selectTitle();
$exerciseDescription = $objExercise->selectDescription();
$exerciseSound = $objExercise->selectSound();
$exerciseType = $objExercise->selectType();
// if questionNum comes from POST and not from GET
//if (!isset($_SESSION['questionList']) || $origin == 'learnpath') {
//in LP's is enabled the "remember question" feature?
if (!isset($_SESSION['questionList'])) {
// selects the list of question ID
$questionList = ($objExercise->isRandom() ? $objExercise->selectRandomList() : $objExercise->selectQuestionList());
api_session_register('questionList');
if ($debug > 0) { error_log('$_SESSION[questionList] was set'); }
if (!$current_question || $_REQUEST['num']) {
if (!$current_question) {
$current_question = 1;
} else {
$current_question++;
}
if (!isset ($objExercise) && isset ($_SESSION['objExercise'])) {
$questionList = $_SESSION['questionList'];
}
$quizStartTime = time();
api_session_register('quizStartTime');
//Real question count
$nbrQuestions = count($questionList);
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
if ($objExercise->type == ALL_ON_ONE_PAGE) {
if ($debug) { error_log('Exercise ALL_ON_ONE_PAGE -> Redirecting to exercise_result.php'); }
// if questionNum comes from POST and not from GET
if (!$questionNum || $_POST['questionNum']) {
// only used for sequential exercises (see $exerciseType)
if (!$questionNum) {
$questionNum = 1;
//We check if the user attempts before sending to the exercise_result.php
if ($objExercise->selectAttempts() > 0) {
$attempt_count = get_attempt_count(api_get_user_id(), $exerciseId, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id);
if ($attempt_count >= $objExercise->selectAttempts()) {
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false);
if ($origin != 'learnpath') {
//so we are not in learnpath tool
echo '</div>'; //End glossary div
Display :: display_footer();
} else {
echo '</body></html>';
}
exit;
}
}
//header("Location: exercise_result.php?origin=$origin&learnpath_id=$safe_lp_id&learnpath_item_id=$safe_lp_item_id&learnpath_item_view_id=$safe_lp_item_view_id");
//exit;
} else {
//Time control is only enabled for ONE PER PAGE
if (!empty($exe_id) && is_numeric($exe_id)) {
//Verify if the current test is fraudulent
if (exercise_time_control_is_valid($exerciseId)) {
$sql_exe_result = "";
if ($debug) { error_log('exercise_time_control_is_valid is valid'); }
} else {
$sql_exe_result = ", exe_result = 0";
if ($debug) { error_log('exercise_time_control_is_valid is NOT valid then exe_result = 0 '); }
}
/*
//Clean incomplete - @todo why setting to blank the status?
$update_query = "UPDATE $stat_table SET status = '', exe_date = '".api_get_utc_datetime() ."' , orig_lp_item_view_id = '$safe_lp_item_view_id' $sql_exe_result WHERE exe_id = ".$exe_id;
//if ($debug) { error_log('Updating track_e_exercises '.$update_query); }
Database::query($update_query);*/
}
//if ($debug) { error_log('Redirecting to exercise_show.php'); }
header('Location: exercise_reminder.php?'.$params);
exit;
}
} else {
$questionNum++;
if ($debug) { error_log('Redirecting to exercise_submit.php'); }
//header("Location: exercise_submit.php?exerciseId=$exerciseId");
exit;
}
}
@ -449,7 +523,6 @@ $interbreadcrumb[] = array ("url" => "exercice.php?gradebook=$gradebook", "name"
$interbreadcrumb[] = array ("url" => "#","name" => $objExercise->name);
if ($origin != 'learnpath') { //so we are not in learnpath tool
//$htmlHeadXtra[] = $objExercise->show_lp_javascript();
Display :: display_header($nameTools,'Exercises');
if (!api_is_allowed_to_session_edit() ) {
Display :: display_warning_message(get_lang('SessionIsReadOnly'));
@ -459,30 +532,27 @@ if ($origin != 'learnpath') { //so we are not in learnpath tool
echo '<div style="height:10px">&nbsp;</div>';
}
$show_quiz_edition = true;
if (isset($exerciseId) && !empty($exerciseId)) {
$TBL_LP_ITEM = Database::get_course_table(TABLE_LP_ITEM);
$sql="SELECT max_score FROM $TBL_LP_ITEM WHERE item_type = '".TOOL_QUIZ."' AND path ='".$exerciseId."'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
$show_quiz_edition = false;
}
}
$show_quiz_edition = $objExercise->added_in_lp();
// I'm in a preview mode
if (api_is_course_admin() && $origin != 'learnpath') {
echo '<div class="actions">';
echo '<a href="exercice.php?show=test&id_session='.api_get_session_id().'">' . Display :: return_icon('back.png', get_lang('BackToExercisesList'),'','32').'</a>';
if ($show_quiz_edition) {
if ($show_quiz_edition == false) {
echo '<a href="exercise_admin.php?' . api_get_cidreq() . '&modifyExercise=yes&exerciseId=' . $objExercise->id . '">'.Display :: return_icon('settings.png', get_lang('ModifyExercise'),'','32').'</a>';
//echo Display :: return_icon('wizard.gif', get_lang('QuestionList')) . '<a href="exercice/admin.php?' . api_get_cidreq() . '&exerciseId=' . $objExercise->id . '">' . get_lang('QuestionList') . '</a>';
} else {
echo '<a href="#">'.Display::return_icon('settings_na.png', get_lang('ModifyExercise'),'','32').'</a>';
}
echo '</div>';
}
/*
$exercise_header = Display::div($exercise_title, array('class'=>'exercise_title'));
if (!empty($exercise_description)) {
$exercise_header .= Display::div($exercise_description, array('class'=>'exercise_description'));
}
echo Display::div($exercise_header, array('class'=>'exercise_header'));*/
$exerciseTitle = $objExercise->selectTitle();
echo Display::tag('h1', $exerciseTitle);
$show_clock = true;
$user_id = api_get_user_id();
if ($objExercise->selectAttempts() > 0) {
@ -502,7 +572,7 @@ if ($objExercise->selectAttempts() > 0) {
$last_attempt_info = $exercise_stat_info[$max_exe_id];
echo Display::div(get_lang('Date').': '.api_get_local_time($last_attempt_info['exe_date']), array('id'=>''));
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false);
Display::display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false);
if (!empty($last_attempt_info['question_list'])) {
foreach($last_attempt_info['question_list'] as $question_data) {
@ -510,29 +580,27 @@ if ($objExercise->selectAttempts() > 0) {
$marks = $question_data['marks'];
$question_info = Question::read($question_id);
echo Display::div($question_info->question, array('id'=>'question_title','class'=>'sectiontitle'));
echo Display::div($question_info->question, array('class'=>'question_title'));
echo Display::div(get_lang('Score').' '.$marks, array('id'=>'question_score'));
}
}
$score = show_score($last_attempt_info['exe_result'], $last_attempt_info['exe_weighting']);
echo Display::div(get_lang('YourTotalScore').' '.$score, array('id'=>'question_score'));
} else {
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false);
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false);
}
} else {
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false);
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), false);
}
if ($origin != 'learnpath')
Display :: display_footer();
exit;
} else {
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttemptsAdmin'), $exerciseTitle, $objExercise->selectAttempts()), false);
Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttemptsAdmin'), $exercise_title, $objExercise->selectAttempts()), false);
}
}
}
//@todo create a function and move to the exercise class
$limit_time_exists = (($objExercise->start_time != '0000-00-00 00:00:00') || ($objExercise->end_time != '0000-00-00 00:00:00')) ? true : false;
if ($limit_time_exists) {
@ -556,14 +624,14 @@ if ($limit_time_exists) {
if (!$permission_to_start || $exercise_timeover) {
if (!api_is_allowed_to_edit(null,true)) {
$message_warning = $permission_to_start ? get_lang('ReachedTimeLimit') : get_lang('ExerciseNoStartedYet');
Display :: display_warning_message(sprintf($message_warning, $exerciseTitle, $objExercise->selectAttempts()));
Display :: display_warning_message(sprintf($message_warning, $exercise_title, $objExercise->selectAttempts()));
if ($origin != 'learnpath') {
Display :: display_footer();
}
exit;
} else {
$message_warning = $permission_to_start ? get_lang('ReachedTimeLimitAdmin') : get_lang('ExerciseNoStartedAdmin');
Display :: display_warning_message(sprintf($message_warning, $exerciseTitle, $objExercise->selectAttempts()));
Display :: display_warning_message(sprintf($message_warning, $exercise_title, $objExercise->selectAttempts()));
exit;
}
}
@ -573,7 +641,7 @@ if ($limit_time_exists) {
global $_custom;
if (isset($_custom['exercises_hidden_when_no_start_date']) && $_custom['exercises_hidden_when_no_start_date']) {
if (empty($objExercise->start_time) || $objExercise->start_time == '0000-00-00 00:00:00') {
Display :: display_warning_message(sprintf(get_lang('ExerciseNoStartedYet'), $exerciseTitle, $objExercise->selectAttempts()));
Display :: display_warning_message(sprintf(get_lang('ExerciseNoStartedYet'), $exercise_title, $objExercise->selectAttempts()));
if ($origin != 'learnpath') {
Display :: display_footer();
}
@ -590,25 +658,76 @@ if ($origin != 'learnpath') {
echo '<div id="highlight-plugin" class="glossary-content">';
}
//var_dump('$remind_question_id . '.$remind_question_id);
if ($reminder == 2) {
$data_tracking = $exercise_stat_info['data_tracking'];
$data_tracking = explode(',', $data_tracking);
$current_question = 1; //set by default the 1st question
if (!empty($my_remind_list)) {
//Checking which questions we are going to call from the remind list
for ($i = 0; $i < count($data_tracking); $i++) {
for($j = 0; $j < count($my_remind_list); $j++) {
if (!empty($remind_question_id)) {
if ($remind_question_id == $my_remind_list[$j]) {
if ($remind_question_id == $data_tracking[$i]) {
if (isset($my_remind_list[$j+1])) {
$remind_question_id = $my_remind_list[$j+1];
$current_question = $i + 1;
} else {
$remind_question_id = -1; //We end the remind list we go to the exercise_reminder.php please
$current_question = $i + 1; // last question
}
break 2;
}
}
} else {
if ($my_remind_list[$j] == $data_tracking[$i]) {
if (isset($my_remind_list[$j+1])) {
$remind_question_id = $my_remind_list[$j+1];
$current_question = $i + 1; // last question
} else {
$remind_question_id = -1; //We end the remind list we go to the exercise_reminder.php please
$current_question = $i + 1; // last question
}
break 2;
}
}
}
}
} else {
header("Location: exercise_reminder.php?$params");
exit;
}
//var_dump($remind_question_id, $my_remind_list, $data_tracking, $current_question);
}
if (!empty($error)) {
Display :: display_error_message($error, false);
} else {
if (!empty ($exerciseSound)) {
echo "<a href=\"../document/download.php?doc_url=%2Faudio%2F" . Security::remove_XSS($exerciseSound) . "\" target=\"_blank\">", "<img src=\"../img/sound.gif\" border=\"0\" align=\"absmiddle\" alt=", get_lang('Sound') . "\" /></a>";
if (!empty ($exercise_sound)) {
echo "<a href=\"../document/download.php?doc_url=%2Faudio%2F" . Security::remove_XSS($exercise_sound) . "\" target=\"_blank\">", "<img src=\"../img/sound.gif\" border=\"0\" align=\"absmiddle\" alt=", get_lang('Sound') . "\" /></a>";
}
// Get number of hotspot questions for javascript validation
$number_of_hotspot_questions = 0;
$onsubmit = '';
$i = 0;
if (!empty($questionList) && is_array($questionList)) {
//i have a doubt in this line cvargas
//var_dump($questionList);
if (!strcmp($questionList[0], '') === 0) {
foreach ($questionList as $questionId) {
$i++;
$objQuestionTmp = Question::read($questionId);
// for sequential exercises
if (!empty($objQuestionTmp)) {
if ($exerciseType == ONE_PER_PAGE) {
if ($objExercise->type == ONE_PER_PAGE) {
// if it is not the right question, goes to the next loop iteration
if ($questionNum != $i) {
if ($current_question != $i) {
continue;
} else {
if ($objQuestionTmp->selectType() == HOT_SPOT || $objQuestionTmp->selectType() == HOT_SPOT_DELINEATION) {
@ -623,38 +742,179 @@ if (!empty ($error)) {
}
}
}
}
if ($number_of_hotspot_questions > 0) {
$onsubmit = "onsubmit=\"return validateFlashVar('" . $number_of_hotspot_questions . "', '" . get_lang('HotspotValidateError1') . "', '" . get_lang('HotspotValidateError2') . "');\"";
}
echo "<p>$exerciseDescription</p>";
$exercise_condition = '';
if ($exerciseType == ONE_PER_PAGE) {
$exercise_condition = "&exerciseId=" . $exerciseId;
echo '<script>
$(function() {
//$(".exercise_save_now_button").hide();
$(".main_question").mouseover(function() {
//$(this).find(".exercise_save_now_button").show();
//$(this).addClass("question_highlight");
});
$(".main_question").mouseout(function() {
//$(this).find(".exercise_save_now_button").hide();
$(this).removeClass("question_highlight");
});
});
function save_now(question_id) {
//1. Normal choice inputs
var my_choice = $(\'*[name*="choice[\'+question_id+\']"]\').serialize();
//2. Reminder checkbox
var remind_list = $(\'*[name*="remind_list"]\').serialize();
//3. Hotspots
var hotspot = $(\'*[name*="hotspot[\'+question_id+\']"]\').serialize();
//Checking FCK
if (typeof(FCKeditorAPI) !== "undefined") {
var oEditor = FCKeditorAPI.GetInstance("choice["+question_id+"]") ;
var fck_content = "";
if (oEditor) {
fck_content = oEditor.GetHTML();
my_choice = {};
my_choice["choice["+question_id+"]"] = fck_content;
my_choice = $.param(my_choice);
}
}
echo '<form id="exercise_form" method="post" action="'.api_get_self().'?'.api_get_cidreq().'&autocomplete=off&gradebook='.$gradebook.$exercise_condition .'" name="frm_exercise" '.$onsubmit.'>
if ($(\'input[name="remind_list[\'+question_id+\']"]\').is(\':checked\')) {
$("#question_div_"+question_id).addClass("remind_highlight");
} else {
$("#question_div_"+question_id).removeClass("remind_highlight");
}
// Only for the first time
lp_data = $.param({"learnpath_id": '.$safe_lp_id.', "learnpath_item_id" : '.$safe_lp_item_id.', "learnpath_item_view_id": '.$safe_lp_item_view_id.'});
$("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('loading1.gif')).'");
$.ajax({
url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=save_exercise_by_now",
data: "type=simple&question_id="+question_id+"&"+my_choice+"&"+hotspot+"&"+lp_data+"&"+remind_list,
success: function(return_value) {
if (return_value == "ok") {
$("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('accept.png', get_lang('Ok'), array(), 22)).'");
} else if (return_value == "error") {
$("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('error.png', get_lang('Error'), array(), 22)).'");
} else if (return_value == "one_per_page") {
var url = "";
if ('.$reminder.' == 1 ) {
url = "exercise_reminder.php?'.$params.'&num='.$current_question.'";
} else if ('.$reminder.' == 2 ) {
url = "exercise_submit.php?origin='.$origin.'&exerciseId='.$exerciseId.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'&reminder=2&" + lp_data;
} else {
url = "exercise_submit.php?origin='.$origin.'&exerciseId='.$exerciseId.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'&" + lp_data;
}
window.location = url;
}
},
});
return false;
}
function save_now_all(validate) {
//1. Input choice
var my_choice = $(\'*[name*="choice"]\').serialize();
//2. Reminder
var remind_list = $(\'*[name*="remind_list"]\').serialize();
//3. Hotspots
var hotspot = $(\'*[name*="hotspot"]\').serialize();
//Question list
var question_list = ['.implode(',', $questionList).'];
var free_answers = {};
$.each(question_list, function(index, my_question_id) {
//Checking FCK
if (typeof(FCKeditorAPI) !== "undefined") {
var oEditor = FCKeditorAPI.GetInstance("choice["+my_question_id+"]") ;
var fck_content = "";
if (oEditor) {
fck_content = oEditor.GetHTML();
//alert(index + " " +my_question_id + " " +fck_content);
free_answers["free_choice["+my_question_id+"]"] = fck_content;
}
}
});
//lok+(fgt)= data base
free_answers = $.param(free_answers);
lp_data = $.param({"learnpath_id": '.$safe_lp_id.', "learnpath_item_id" : '.$safe_lp_item_id.', "learnpath_item_view_id": '.$safe_lp_item_view_id.'});
$("#save_all_reponse").html("'.addslashes(Display::return_icon('loading1.gif')).'");
$.ajax({
url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=save_exercise_by_now",
data: "type=all&"+my_choice+"&"+hotspot+"&"+lp_data+"&"+free_answers+"&"+remind_list,
success: function(return_value) {
if (return_value == "ok") {
//$("#save_all_reponse").html("'.addslashes(Display::return_icon('accept.png')).'");
if (validate == "validate") {
window.location = "exercise_reminder.php?'.$params.'&" + lp_data;
} else {
$("#save_all_reponse").html("'.addslashes(Display::return_icon('accept.png')).'");
}
} else {
$("#save_all_reponse").html("'.addslashes(Display::return_icon('wrong.gif')).'");
}
},
});
return false;
}
function validate_all() {
save_now_all("validate");
return false;
}
</script>';
echo '<form id="exercise_form" method="post" action="'.api_get_self().'?'.api_get_cidreq().'&autocomplete=off&gradebook='.$gradebook."&exerciseId=" . $exerciseId .'" name="frm_exercise" '.$onsubmit.'>
<input type="hidden" name="formSent" value="1" />
<input type="hidden" name="exerciseType" value="' . $exerciseType . '" />
<input type="hidden" name="exerciseId" value="'.$exerciseId . '" />
<input type="hidden" name="questionNum" value="' . $questionNum . '" />
<input type="hidden" name="nbrQuestions" value="' . $nbrQuestions . '" />
<input type="hidden" name="num" value="'.$current_question . '" />
<input type="hidden" name="origin" value="'.$origin . '" />
<input type="hidden" name="learnpath_id" value="' . $learnpath_id . '" />
<input type="hidden" name="learnpath_item_id" value="'. $learnpath_item_id . '" />
<table id="question_list" width="100%" border="0" cellpadding="1" cellspacing="0">
<tr>
<td>
<table width="100%" cellpadding="3" cellspacing="0" border="0">';
<input type="hidden" name="learnpath_id" value="'.$safe_lp_id . '" />
<input type="hidden" name="learnpath_item_id" value="'.$safe_lp_item_id . '" />
<input type="hidden" name="learnpath_item_view_id" value="'.$safe_lp_item_view_id . '" />';
//Show list of questions
$i = 1;
if (is_array($questionList)) {
$attempt_list = array();
if (isset($exe_id)) {
$attempt_list = get_all_exercise_event_by_exe_id($exe_id);
}
if (!empty($attempt_list) && $current_question == 1) {
Display::display_normal_message(get_lang('YouTriedToResolveThisExerciseEarlier'));
}
$remind_list = array();
if (isset($exercise_stat_info['questions_to_check']) && !empty($exercise_stat_info['questions_to_check'])) {
$remind_list = explode(',', $exercise_stat_info['questions_to_check']);
}
foreach ($questionList as $questionId) {
// for sequential exercises
if ($exerciseType == ONE_PER_PAGE) {
if ($objExercise->type == ONE_PER_PAGE) {
// if it is not the right question, goes to the next loop iteration
if ($questionNum != $i) {
if ($current_question != $i) {
$i++;
continue;
} else {
@ -673,23 +933,61 @@ if (!empty ($error)) {
}
}
}
$user_choice = $attempt_list[$questionId];
$remind_highlight = '';
$exercise_actions = '';
$is_remind_on = false;
$attributes = array('id' =>'remind_list['.$questionId.']');
if (in_array($questionId, $remind_list)) {
$is_remind_on = true;
$attributes['checked'] = 1;
$remind_question = true;
$remind_highlight = ' remind_highlight ';
}
//Showing the question
echo '<div id="question_div_'.$questionId.'" class="main_question '.$remind_highlight.'" >';
// shows the question and its answers
showQuestion($questionId, false, $origin, $i);
showQuestion($questionId, false, $origin, $i, true, false, $user_choice);
if ($objExercise->type == ONE_PER_PAGE) {
$exercise_actions .= $objExercise->show_button($questionId, $current_question);
}
if ($objExercise->type == ALL_ON_ONE_PAGE) {
$button = '<a href="javascript://" class="a_button orange medium" onclick="save_now(\''.$questionId.'\'); ">'.get_lang('SaveForNow').'</a>';
$button .= '<span id="save_for_now_'.$questionId.'"></span>&nbsp;';
$exercise_actions .= Display::span($button, array('class'=>'exercise_save_now_button'));
}
$remind_question_div = Display::input('checkbox', 'remind_list['.$questionId.']', '', $attributes);
$remind_question_div .= Display::tag('label', get_lang('RemindQuestion'), array('for' =>'remind_list['.$questionId.']'));
$exercise_actions .= Display::span($remind_question_div, array('class'=>'exercise_save_now_button'));
echo Display::div($exercise_actions, array('class'=>'exercise_actions'));
echo '</div>';
$i++;
// for sequential exercises
if ($exerciseType == ONE_PER_PAGE) {
if ($objExercise->type == ONE_PER_PAGE) {
// quits the loop
break;
}
}
}
// end foreach()
echo $objExercise->show_button($nbrQuestions, $questionNum, $exerciseId);
echo '</table>
</td>
</tr>
</table></form>';
if ($objExercise->type == ALL_ON_ONE_PAGE) {
$exercise_actions = $objExercise->show_button($questionId, $current_question);
echo Display::div($exercise_actions, array('class'=>'exercise_actions'));
}
echo '</form>';
}
/*
if ($objExercise->type == ONE_PER_PAGE) {
if (empty($exercise_stat_info)) {
$total_weight = 0;
@ -699,7 +997,7 @@ if ($objExercise->type == ONE_PER_PAGE) {
}
$objExercise->save_stat_track_exercise_info($clock_expired_time, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $questionList, $total_weight);
}
}
}*/
if ($origin != 'learnpath') {
//so we are not in learnpath tool
echo '</div>'; //End glossary div

@ -1254,7 +1254,7 @@ abstract class Question
return $result;
}
function return_header($feedback_type, $counter = null) {
function return_header($feedback_type = null, $counter = null) {
$counter_label = '';
if (!empty($counter)) {
$counter_label = intval($counter);

@ -163,6 +163,7 @@ if (!empty($question_list)) {
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
} elseif ($answerType == HOT_SPOT) {
//@todo move this in the manage_answer function
if ($show_results) {
echo '<table width="500" border="0"><tr>
<td valign="top" align="center" style="padding-left:0px;" >
@ -183,6 +184,7 @@ if (!empty($question_list)) {
</tr>
</table><br/>';
}
} else if($answerType == HOT_SPOT_DELINEATION) {
$question_result = $objExercise->manage_answer($id, $questionId, $choice,'exercise_show', array(), false, true, $show_results, $objExercise->selectPropagateNeg(), 'database');

@ -4,6 +4,10 @@
* Responses to AJAX calls
*/
require_once '../../exercice/exercise.class.php';
require_once '../../exercice/question.class.php';
require_once '../../exercice/answer.class.php';
require_once '../../exercice/exercise.lib.php';
require_once '../global.inc.php';
api_protect_course_script(true);
$action = $_REQUEST['a'];
@ -21,6 +25,177 @@ switch ($action) {
Display::display_confirmation_message(get_lang('Saved'));
}
break;
case 'add_question_to_reminder':
$objExercise = $_SESSION['objExercise'];
if (empty($objExercise)) {
echo 0;
exit;
} else {
$objExercise->edit_question_to_remind($_REQUEST['exe_id'], $_REQUEST['question_id'], $_REQUEST['action']);
}
break;
case 'save_exercise_by_now':
//Use have permissions?
if (api_is_allowed_to_session_edit()) {
//"all" or "simple" strings means that there's one or all questions
$type = $_REQUEST['type'];
//Normal questions choices
$choice = $_REQUEST['choice'];
//All Hotspot coordinates from all questions
$hot_spot_coordinates = $_REQUEST['hotspot'];
//There is a reminder?
$remind_list = isset($_REQUEST['remind_list']) && !empty($_REQUEST['remind_list'])? array_keys($_REQUEST['remind_list']) : null;
//Lp ids
$safe_lp_id = $_REQUEST['learnpath_id'];
$safe_lp_item_id = $_REQUEST['learnpath_item_id'];
$safe_lp_item_view_id = $_REQUEST['learnpath_item_view_id'];
//Exercise information
$question_id = intval($_REQUEST['question_id']);
$question_list = $_SESSION['questionList'];
$objExercise = $_SESSION['objExercise'];
if (empty($question_list) || empty($objExercise)) {
echo 0;
exit;
}
$exe_id = null;
if (isset($_SESSION['exe_id'])) {
$exe_id = $_SESSION['exe_id'];
}
//Getting information of the current exercise
$exercise_stat_info = $objExercise->get_stat_track_exercise_info($safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id);
//$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
$attempt_list = array();
//First time here we create an attempt (getting the exe_id)
if (empty($exercise_stat_info)) {
//$exe_id = create_event_exercice($objExercise->selectId());
$current_expired_time_key = get_time_control_key($objExercise->id);
if (isset($_SESSION['expired_time'][$current_expired_time_key])) { //Only for exercice of type "One page"
$expired_date = $_SESSION['expired_time'][$current_expired_time_key];
} else {
$expired_date = '0000-00-00 00:00:00';
}
$exe_id = $objExercise->save_stat_track_exercise_info($expired_date, $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $question_list, 0); //total weight 0 by now
$total_score = $total_weight = 0;
} else {
//We know the user we get the exe_id
$exe_id = $exercise_stat_info['exe_id'];
$total_score = $exercise_stat_info['exe_result'];
//Getting the list of attempts
$attempt_list = get_all_exercise_event_by_exe_id($exe_id);
}
//Updating Reminder algorythm
if ($objExercise->type == ONE_PER_PAGE) {
$bd_reminder_list = explode(',', $exercise_stat_info['questions_to_check']);
if (empty($remind_list)) {
$remind_list = $bd_reminder_list;
$new_list = array();
foreach($bd_reminder_list as $item) {
if ($item != $question_id) {
$new_list[] = $item;
}
}
$remind_list = $new_list;
} else {
if (isset($remind_list[0])) {
if (!in_array($remind_list[0], $bd_reminder_list)) {
array_push($bd_reminder_list, $remind_list[0]);
}
$remind_list = $bd_reminder_list;
}
}
}
//No exe id? Can't save answer
if (empty($exe_id)) {
//Fires an error
echo 'error';
exit;
} else {
$_SESSION['exe_id'] = $exe_id;
}
// Getting the total weight if the request is simple
$total_weight = 0;
if ($type == 'simple') {
foreach($question_list as $my_question_id) {
$objQuestionTmp = Question :: read($my_question_id);
$total_weight += $objQuestionTmp->selectWeighting();
}
}
unset($objQuestionTmp);
//Looping the question list
foreach($question_list as $my_question_id) {
if ($type == 'simple' && $question_id != $my_question_id) {
continue;
}
$my_choice = $choice[$my_question_id];
// creates a temporary Question object
$objQuestionTmp = Question::read($my_question_id);
//Getting free choice data
if ($objQuestionTmp->type == FREE_ANSWER && $type == 'all') {
$my_choice = isset($_REQUEST['free_choice'][$my_question_id]) && !empty($_REQUEST['free_choice'][$my_question_id])? $_REQUEST['free_choice'][$my_question_id]: null;
}
if ($type == 'all') {
$total_weight += $objQuestionTmp->selectWeighting();
}
//this variable commes from exercise_submit_modal.php
$hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$my_question_id];
// Deleting old attempt
if (isset($attempt_list) && !empty($attempt_list[$my_question_id])) {
delete_attempt($exe_id, api_get_user_id() , api_get_course_id(), api_get_session_id(), $my_question_id);
if ($objQuestionTmp->type == HOT_SPOT) {
delete_attempt_hotspot($exe_id, api_get_user_id() , api_get_course_id(), $my_question_id);
}
$total_score -= $attempt_list[$my_question_id]['marks'];
}
// We're inside *one* question. Go through each possible answer for this question
$result = $objExercise->manage_answer($exe_id, $my_question_id, $my_choice,'exercise_result', $hot_spot_coordinates, true, false, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result, true);
$total_score += $result['score'];
update_event_exercice($exe_id, $objExercise->selectId(), $total_score, $total_weight, api_get_session_id(), $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id, $quizDuration, $question_list, 'incomplete', $remind_list);
// Destruction of the Question object
unset($objQuestionTmp);
}
}
if ($objExercise->type == ONE_PER_PAGE) {
echo 'one_per_page';
exit;
}
echo 'ok';
break;
default:
echo '';
}

@ -964,25 +964,33 @@ class Display {
}); */
}
public static function table($headers, $rows) {
/*
require_once api_get_path(LIBRARY_PATH).'pear/HTML/Table.php';
$table = new HTML_Table(array('class' => 'data_table'));
public static function table($headers, $rows, $attributes = array()) {
if (empty($attributes)) {
$attributes['class'] = 'data_table';
}
//require_once api_get_path(LIBRARY_PATH).'pear/HTML/Table.php';
$table = new HTML_Table($attributes);
$row = 0;
$column = 0;
//Course headers
if (!empty($headers)) {
foreach ($headers as $item) {
$table->setHeaderContents($row, $column, $item);
$column++;
}
$row = 1;
$column = 0;
}
if (!empty($rows)) {
foreach($rows as $content) {
$table->setCellContents($row, $column, $content);
$column++;
}
return $table->toHtml();*/
}
return $table->toHtml();
}
/**

@ -305,7 +305,7 @@ function event_link($link_id) {
* @author Julio Montoya Armas <gugli100@gmail.com> Reworked 2010
* @desc Record result of user when an exercice was done
*/
function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$learnpath_id=0, $learnpath_item_id=0, $learnpath_item_view_id = 0, $duration , $question_list) {
function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$learnpath_id=0, $learnpath_item_id=0, $learnpath_item_view_id = 0, $duration, $question_list, $status = '', $remind_list = array()) {
require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php';
if ($exeid != '') {
// Validation in case of fraud with actived control time
@ -322,9 +322,24 @@ function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$
}
}
if (!isset($status) || empty($status)) {
$status = '';
} else {
$status = Database::escape_string($status);
}
$TABLETRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
array_map('intval', $question_list);
if (!empty($remind_list)) {
array_map('intval', $remind_list);
$remind_list = array_filter($remind_list);
$remind_list = implode(",", $remind_list);
} else {
$remind_list = '';
}
$sql = "UPDATE $TABLETRACK_EXERCICES SET
exe_exo_id = '".Database::escape_string($exo_id)."',
exe_result = '".Database::escape_string($score)."',
@ -335,11 +350,12 @@ function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$
orig_lp_item_view_id = '".Database::escape_string($learnpath_item_view_id)."',
exe_duration = '".Database::escape_string($duration)."',
exe_date = '".api_get_utc_datetime()."',
status = '',
status = '".$status."',
questions_to_check = '".$remind_list."',
start_date = '".api_get_utc_datetime($start_date)."',
data_tracking = '".implode(',', $question_list)."'
WHERE exe_id = '".Database::escape_string($exeid)."'";
$res = @Database::query($sql);
$res = Database::query($sql);
//Deleting control time session track
exercise_time_control_delete($exo_id);
@ -1020,3 +1036,47 @@ function get_comments($id,$question_id) {
return $comm;
}
function get_all_exercise_event_by_exe_id($exe_id) {
$table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$exe_id = intval($exe_id);
$list = array();
$sql = "SELECT * FROM $table_track_attempt WHERE exe_id = $exe_id ORDER BY position";
$res_question = Database::query($sql);
if (Database::num_rows($res_question))
while($row_q = Database::fetch_array($res_question,'ASSOC')) {
$list[$row_q['question_id']][] = $row_q;
}
return $list;
}
function delete_attempt($exe_id, $user_id, $course_code, $session_id, $question_id) {
$table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$exe_id = intval($exe_id);
$user_id = intval($user_id);
$course_code = Database::escape_string($course_code);
$session_id = intval($session_id);
$question_id = intval($question_id);
$sql = "DELETE FROM $table_track_attempt WHERE exe_id = $exe_id AND user_id = $user_id AND course_code = '$course_code' AND session_id = $session_id AND question_id = $question_id ";
Database::query($sql);
}
function delete_attempt_hotspot($exe_id, $user_id, $course_code, $question_id) {
$table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
$exe_id = intval($exe_id);
$user_id = intval($user_id);
$course_code = Database::escape_string($course_code);
//$session_id = intval($session_id);
$question_id = intval($question_id);
$sql = "DELETE FROM $table_track_attempt WHERE hotspot_exe_id = $exe_id AND hotspot_user_id = $user_id AND hotspot_course_code = '$course_code' AND hotspot_question_id = $question_id ";
Database::query($sql);
}

@ -60,9 +60,11 @@ class ExerciseShowFunctions {
function display_free_answer($answer,$id,$questionId) {
global $feedback_type;
if (empty($id)) {
if (!empty($answer)) {
echo '<tr>';
echo Display::tag('td',nl2br(Security::remove_XSS($answer,COURSEMANAGERLOWSECURITY)), array('width'=>'55%'));
echo '</tr>';
}
if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<tr>';
echo Display::tag('td',get_lang('notCorrectedYet'), array('width'=>'45%'));
@ -72,12 +74,11 @@ class ExerciseShowFunctions {
}
} else {
echo '<tr>';
echo '<td>';
if (!empty($answer)) {
echo '<td>';
echo nl2br(Security::remove_XSS($answer,COURSEMANAGERLOWSECURITY));
}
echo '</td>';
}
if(!api_is_allowed_to_edit(null,true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<td>';
$comm = get_comments($id,$questionId);
@ -112,6 +113,7 @@ class ExerciseShowFunctions {
"#3B3B3B",
"#F7BDE2");
?>
<table class="data_table">
<tr>
<td width="100px" valign="top" align="left">
<div style="width:100%;">
@ -133,7 +135,6 @@ class ExerciseShowFunctions {
<?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
<td valign="top" align="left" >
<?php
$answerComment=text_filter($answerComment);
if($studentChoice) {
echo '<span style="font-weight: bold; color: #008000;">'.nl2br(make_clickable($answerComment)).'</span>';
} else {

@ -117,6 +117,8 @@ ALTER TABLE track_e_exercices ADD orig_lp_item_id int NOT NULL default 0;
ALTER TABLE track_e_exercices ADD exe_duration int UNSIGNED NOT NULL default 0;
ALTER TABLE track_e_exercices ADD COLUMN expired_time_control datetime NOT NULL DEFAULT '0000-00-00 00:00:00';
ALTER TABLE track_e_exercices ADD COLUMN orig_lp_item_view_id INT NOT NULL DEFAULT 0;
ALTER TABLE track_e_exercices ADD COLUMN questions_to_check TEXT NOT NULL DEFAULT '';
CREATE TABLE track_e_attempt (
exe_id int default NULL,

Loading…
Cancel
Save