diff --git a/main/exercice/admin.php b/main/exercice/admin.php index 6c7a0862d2..ae96980dd4 100755 --- a/main/exercice/admin.php +++ b/main/exercice/admin.php @@ -71,24 +71,16 @@ define(ALLOWED_TO_INCLUDE,1); require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php'; require_once api_get_path(LIBRARY_PATH).'document.lib.php'; -/****************************/ /* stripslashes POST data */ -/****************************/ - if($_SERVER['REQUEST_METHOD'] == 'POST') { foreach($_POST as $key=>$val) { - if(is_string($val)) - { + if(is_string($val)) { $_POST[$key]=stripslashes($val); - } - elseif(is_array($val)) - { - foreach($val as $key2=>$val2) - { + } elseif(is_array($val)) { + foreach($val as $key2=>$val2) { $_POST[$key][$key2]=stripslashes($val2); } } - $GLOBALS[$key]=$_POST[$key]; } } @@ -180,8 +172,7 @@ if(!is_object($objExercise)) { $objExercise=new Exercise(); // creation of a new exercise if wrong or not specified exercise ID - if($exerciseId) - { + if($exerciseId) { $objExercise->read($exerciseId); } @@ -200,14 +191,11 @@ if(!$fromExercise) { $nbrQuestions=$objExercise->selectNbrQuestions(); // intializes the Question object -if($editQuestion || $newQuestion || $modifyQuestion || $modifyAnswers) -{ - if($editQuestion || $newQuestion) - { +if($editQuestion || $newQuestion || $modifyQuestion || $modifyAnswers) { + if($editQuestion || $newQuestion) { // reads question data - if($editQuestion) - { + if($editQuestion) { // question not found if(!$objQuestion = Question::read($editQuestion)) { @@ -434,10 +422,8 @@ echo Display::return_icon('preview.gif', get_lang('Preview')).'id.'">'.get_lang('ModifyExercise').''; echo ''; -if(isset($_GET['message'])) -{ - if (in_array($_GET['message'], array('ExerciseStored'))) - { +if(isset($_GET['message'])) { + if (in_array($_GET['message'], array('ExerciseStored'))) { Display::display_confirmation_message(get_lang($_GET['message'])); } } @@ -460,10 +446,10 @@ if($newQuestion || $editQuestion) { } if(isset($_GET['hotspotadmin'])) { - include('hotspot_admin.inc.php'); + require 'hotspot_admin.inc.php'; } if(!$newQuestion && !$modifyQuestion && !$editQuestion && !isset($_GET['hotspotadmin'])) { - include_once(api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php'); + require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php'; $form = new FormValidator('exercise_admin', 'post', api_get_self().'?exerciseId='.$_GET['exerciseId']); $form -> addElement ('hidden','edit','true'); //$objExercise -> createForm ($form,'simple'); @@ -479,7 +465,7 @@ if(!$newQuestion && !$modifyQuestion && !$editQuestion && !isset($_GET['hotspota $form -> display (); echo '
'; // question list management - include('question_list_admin.inc.php'); + require 'question_list_admin.inc.php'; } api_session_register('objExercise'); diff --git a/main/exercice/exercice.php b/main/exercice/exercice.php index 23ee6c77df..eaae323605 100755 --- a/main/exercice/exercice.php +++ b/main/exercice/exercice.php @@ -1,6 +1,5 @@ '-1' ORDER BY title LIMIT " . (int) $from . "," . (int) ($limitExPage +1); $result = Database::query($sql); } - -} -elseif ($show == 'test') { // only for students //fin +} elseif ($show == 'test') { // only for students $sql = "SELECT id,title,type,description, results_disabled FROM $TBL_EXERCICES WHERE active='1' ORDER BY title LIMIT " . (int) $from . "," . (int) ($limitExPage +1); $result = Database::query($sql); } @@ -677,23 +665,19 @@ $condition_session = api_get_session_condition($session_id,true,true); // only for administrator if ($is_allowedToEdit) { if ($show == 'test') { - $sql = "SELECT id, title, type, active, description, results_disabled, session_id, start_time FROM $TBL_EXERCICES WHERE active<>'-1' $condition_session ORDER BY title LIMIT " . (int) $from . "," . (int) ($limitExPage +1); + $sql = "SELECT id, title, type, active, description, results_disabled, session_id, start_time, end_time FROM $TBL_EXERCICES WHERE active<>'-1' $condition_session ORDER BY title LIMIT " . (int) $from . "," . (int) ($limitExPage +1); $result = Database::query($sql); } -} -elseif ($show == 'test') { // only for students - $sql = "SELECT id, title, type, description, results_disabled, session_id, start_time FROM $TBL_EXERCICES WHERE active='1' $condition_session ORDER BY title LIMIT " . (int) $from . "," . (int) ($limitExPage +1); +} elseif ($show == 'test') { // only for students + $sql = "SELECT id, title, type, description, results_disabled, session_id, start_time, end_time FROM $TBL_EXERCICES WHERE active='1' $condition_session ORDER BY title LIMIT " . (int) $from . "," . (int) ($limitExPage +1); $result = Database::query($sql); } -if ($show == 'test') { +if ($show == 'test') { $nbrExercises = Database :: num_rows($result); //get HotPotatoes files (active and inactive) - $res = Database::query("SELECT * - FROM $TBL_DOCUMENT - WHERE - path LIKE '" . Database :: escape_string($uploadPath) . "/%/%'"); - $nbrTests = Database :: num_rows($res); + $res = Database::query("SELECT * FROM $TBL_DOCUMENT WHERE path LIKE '" . Database :: escape_string($uploadPath) . "/%/%'"); + $nbrTests = Database :: num_rows($res); $res = Database::query("SELECT * FROM $TBL_DOCUMENT d, $TBL_ITEM_PROPERTY ip WHERE d.id = ip.ref @@ -821,11 +805,11 @@ if ($show == 'test') { } else { //student only ?> - + - time()) { - $is_actived_time = false; + + $time_limits = false; + if ($row['start_time'] != '0000-00-00 00:00:00' && $row['end_time'] != '0000-00-00 00:00:00') { + $time_limits = true; } - + + if ($time_limits) { + // check if start time + + $start_time = api_strtotime(api_get_local_time($row['start_time'])); + $end_time = api_strtotime(api_get_local_time($row['end_time'])); + $now = api_strtotime(api_get_local_time()); + + $is_actived_time = false; + if ($now > $start_time && $end_time > $now ) { + $is_actived_time = true; + } + } + if ($i % 2 == 0) $s_class = "row_odd"; else @@ -933,11 +929,14 @@ if ($show == 'test') { - - '.$row['title'].''; + } else { + echo $row['title']; + } } else { - echo $row['title']; + echo ''.$row['title'].''; } echo ''; $exid = $row['id']; @@ -965,11 +964,22 @@ if ($show == 'test') { ORDER BY exe_id DESC"; $qryres = Database::query($qry); $num = Database :: num_rows($qryres); - + //hide the results - if (!$is_actived_time) { $my_result_disabled = $row['results_disabled']; - if ($my_result_disabled == 0) { + + if ($time_limits) { + if ($my_result_disabled == 0) { + if ($num > 0) { + echo sprintf(get_lang('ExerciseWillBeActivatedFromXToY'), api_get_local_time($row['start_time']), api_get_local_time($row['end_time'])); + } else { + echo get_lang('NotAttempted'); + } + } else { + echo get_lang('CantShowResults'); + } + } else { + if ($my_result_disabled == 0) { if ($num > 0) { $row = Database :: fetch_array($qryres); $percentage = 0; @@ -980,15 +990,17 @@ if ($show == 'test') { printf("%1.2f\n", $percentage); echo " %)"; } else { - echo get_lang('WillBeActivated' .' '. $row['start_time']); + //echo get_lang('WillBeActivated' .' '. $row['start_time']); + echo get_lang('NotAttempted'); } } else { echo get_lang('CantShowResults'); } - echo ''; - } else { - echo get_lang('NotAttempted'); } + echo ''; + /*} else { + echo get_lang('NotAttempted'); + }*/ } // skips the last exercise, that is only used to know if we have or not to create a link "Next page" if ($i == $limitExPage) { @@ -1110,32 +1122,32 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { $exercise_where_query = 'te.exe_exo_id =ce.id AND '; } - $sql="SELECT ".(api_is_western_name_order() ? "firstname as userpart1, lastname userpart2" : "lastname as userpart1, firstname as userpart2").", ce.title as extitle, te.exe_result as exresult , - te.exe_weighting as exweight, te.exe_date as exdate, te.exe_id as exid, email as exemail, te.start_date as exstart, steps_counter as exstep,cuser.user_id as excruid,te.exe_duration as exduration - FROM $TBL_EXERCICES AS ce , $TBL_TRACK_EXERCICES AS te, $TBL_USER AS user,$tbl_course_rel_user AS cuser - WHERE user.user_id=cuser.user_id AND cuser.relation_type<>".COURSE_RELATION_TYPE_RRHH." AND te.exe_exo_id = ce.id AND te.status != 'incomplete' AND cuser.user_id=te.exe_user_id AND te.exe_cours_id='" . Database :: escape_string($_cid) . "' - $user_id_and $session_id_and AND ce.active <>-1 AND orig_lp_id = 0 AND orig_lp_item_id = 0 - AND cuser.course_code=te.exe_cours_id ORDER BY userpart2, te.exe_cours_id ASC, ce.title ASC, te.exe_date DESC"; - - $hpsql="SELECT ".(api_is_western_name_order() ? "firstname as userpart1, lastname userpart2" : "lastname as userpart1, firstname as userpart2").", tth.exe_name, - tth.exe_result , tth.exe_weighting, tth.exe_date - FROM $TBL_TRACK_HOTPOTATOES tth, $TBL_USER tu - WHERE tu.user_id=tth.exe_user_id AND tth.exe_cours_id = '" . Database :: escape_string($_cid) . " $user_id_and ' - ORDER BY tth.exe_cours_id ASC, tth.exe_date DESC"; + $sql="SELECT ".(api_is_western_name_order() ? "firstname as userpart1, lastname userpart2" : "lastname as userpart1, firstname as userpart2").", ce.title as extitle, te.exe_result as exresult , + te.exe_weighting as exweight, te.exe_date as exdate, te.exe_id as exid, email as exemail, te.start_date as exstart, steps_counter as exstep,cuser.user_id as excruid,te.exe_duration as exduration + FROM $TBL_EXERCICES AS ce , $TBL_TRACK_EXERCICES AS te, $TBL_USER AS user,$tbl_course_rel_user AS cuser + WHERE user.user_id=cuser.user_id AND cuser.relation_type<>".COURSE_RELATION_TYPE_RRHH." AND te.exe_exo_id = ce.id AND te.status != 'incomplete' AND cuser.user_id=te.exe_user_id AND te.exe_cours_id='" . Database :: escape_string($_cid) . "' + $user_id_and $session_id_and AND ce.active <>-1 AND orig_lp_id = 0 AND orig_lp_item_id = 0 + AND cuser.course_code=te.exe_cours_id ORDER BY userpart2, te.exe_cours_id ASC, ce.title ASC, te.exe_date DESC"; + + $hpsql="SELECT ".(api_is_western_name_order() ? "firstname as userpart1, lastname userpart2" : "lastname as userpart1, firstname as userpart2").", tth.exe_name, + tth.exe_result , tth.exe_weighting, tth.exe_date + FROM $TBL_TRACK_HOTPOTATOES tth, $TBL_USER tu + WHERE tu.user_id=tth.exe_user_id AND tth.exe_cours_id = '" . Database :: escape_string($_cid) . " $user_id_and ' + ORDER BY tth.exe_cours_id ASC, tth.exe_date DESC"; } else { // get only this user's results $user_id_and = ' AND te.exe_user_id = ' . api_get_user_id() . ' '; - $sql="SELECT ".(api_is_western_name_order() ? "firstname as userpart1, lastname userpart2" : "lastname as userpart1, firstname as userpart2").", ce.title as extitle, te.exe_result as exresult, " . - "te.exe_weighting as exweight, te.exe_date as exdate, te.exe_id as exid, email as exemail, " . - "te.start_date as exstart, steps_counter as exstep, cuser.user_id as excruid, te.exe_duration as exduration, ce.results_disabled as exdisabled - FROM $TBL_EXERCICES AS ce , $TBL_TRACK_EXERCICES AS te, $TBL_USER AS user,$tbl_course_rel_user AS cuser - WHERE user.user_id=cuser.user_id AND te.exe_exo_id = ce.id AND te.status != 'incomplete' AND cuser.user_id=te.exe_user_id - AND te.exe_cours_id='" . Database :: escape_string($_cid) . "' - AND cuser.relation_type<>".COURSE_RELATION_TYPE_RRHH." $user_id_and $session_id_and AND ce.active <>-1 AND" . - " orig_lp_id = 0 AND orig_lp_item_id = 0 AND cuser.course_code=te.exe_cours_id ORDER BY userpart2, te.exe_cours_id ASC, ce.title ASC," . - "te.exe_date DESC"; + $sql="SELECT ".(api_is_western_name_order() ? "firstname as userpart1, lastname userpart2" : "lastname as userpart1, firstname as userpart2").", ce.title as extitle, te.exe_result as exresult, " . + "te.exe_weighting as exweight, te.exe_date as exdate, te.exe_id as exid, email as exemail, " . + "te.start_date as exstart, steps_counter as exstep, cuser.user_id as excruid, te.exe_duration as exduration, ce.results_disabled as exdisabled + FROM $TBL_EXERCICES AS ce , $TBL_TRACK_EXERCICES AS te, $TBL_USER AS user,$tbl_course_rel_user AS cuser + WHERE user.user_id=cuser.user_id AND te.exe_exo_id = ce.id AND te.status != 'incomplete' AND cuser.user_id=te.exe_user_id + AND te.exe_cours_id='" . Database :: escape_string($_cid) . "' + AND cuser.relation_type<>".COURSE_RELATION_TYPE_RRHH." $user_id_and $session_id_and AND ce.active <>-1 AND" . + " orig_lp_id = 0 AND orig_lp_item_id = 0 AND cuser.course_code=te.exe_cours_id ORDER BY userpart2, te.exe_cours_id ASC, ce.title ASC," . + "te.exe_date DESC"; $hpsql = "SELECT '',exe_name, exe_result , exe_weighting, exe_date FROM $TBL_TRACK_HOTPOTATOES @@ -1147,7 +1159,6 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { while ($rowx = Database::fetch_array($resx,'ASSOC')) { $results[] = $rowx; } - //$results = getManyResultsXCol($sql, 12); $hpresults = getManyResultsXCol($hpsql, 5); $has_test_results = false; @@ -1157,16 +1168,13 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { $lang_nostartdate = get_lang('NoStartDate') . ' / '; if (is_array($results)) { - $has_test_results = true; - $users_array_id = array (); if ($_GET['gradebook'] == 'view') { $filter_by_no_revised = true; $from_gradebook = true; } $sizeof = sizeof($results); - $user_list_id = array (); $user_last_name = ''; $user_first_name = ''; @@ -1177,8 +1185,8 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { $more_details_list = ''; for ($i = 0; $i < $sizeof; $i++) { $revised = false; - $sql_exe = 'SELECT exe_id FROM ' . Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING) . ' - WHERE author != ' . "''" . ' AND exe_id = ' . "'" . Database :: escape_string($results[$i]['exid']) . "'" . ' LIMIT 1'; + $sql_exe = 'SELECT exe_id FROM ' . $TBL_TRACK_ATTEMPT_RECORDING . ' + WHERE author != ' . "''" . ' AND exe_id = ' . "'" . Database :: escape_string($results[$i]['exid']) . "'" . ' LIMIT 1'; $query = Database::query($sql_exe); if (Database :: num_rows($query) > 0) { @@ -1201,7 +1209,7 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { $user_last_name = $results[$i]['userpart2']; $user_list_id[] = $results[$i]['excruid']; $id = $results[$i]['exid']; - $mailid = $results[$i]['exemail']; + $user = $results[$i]['userpart1'] . $results[$i]['userpart2'];; $test = $results[$i]['extitle']; $quiz_name_list = $test; @@ -1223,15 +1231,15 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { } if ($results[$i]['exstart'] != "0000-00-00 00:00:00") { //echo ceil((($results[$i][4] - $results[$i][7]) / 60)) . ' ' . get_lang('MinMinutes'); - $exe_date_timestamp = api_strtotime($results[$i]['exdate'], date_default_timezone_get()); - $start_date_timestamp = api_strtotime($results[$i]['exstart'], date_default_timezone_get()); - + $exe_date_timestamp = api_strtotime($results[$i]['exdate'], date_default_timezone_get()); + $start_date_timestamp = api_strtotime($results[$i]['exstart'], date_default_timezone_get()); + $my_duration = ceil((($exe_date_timestamp - $start_date_timestamp) / 60)); - if ($my_duration == 1 ) { - $duration_list = $my_duration . ' ' . get_lang('MinMinute'); + if ($my_duration == 1 ) { + $duration_list = $my_duration . ' ' . get_lang('MinMinute'); } else { - $duration_list = $my_duration. ' ' . get_lang('MinMinutes'); - } + $duration_list = $my_duration. ' ' . get_lang('MinMinutes'); + } if ($results[$i]['exstep'] > 1) { //echo ' ( ' . $results[$i][8] . ' ' . get_lang('Steps') . ' )'; $duration_list = ' ( ' . $results[$i]['exstep'] . ' ' . get_lang('Steps') . ' )'; @@ -1242,7 +1250,7 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { //echo get_lang('NoLogOfDuration'); } // Date conversion - $date_list = api_get_local_time($results[$i]['exstart'], null, date_default_timezone_get()). ' / ' . api_get_local_time($results[$i]['exdate'], null, date_default_timezone_get()); + $date_list = api_get_local_time($results[$i]['exstart']). ' / ' . api_get_local_time($results[$i]['exdate']); // there are already a duration test period calculated?? //echo ''.sprintf(get_lang('DurationFormat'), $duration).''; @@ -1269,12 +1277,12 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { if ($revised) { //echo "".Display :: return_icon('edit.gif', get_lang('Edit')); //echo ' '; - $html_link.= "".Display :: return_icon('edit.gif', get_lang('Edit')); + $html_link.= "".Display :: return_icon('edit.gif', get_lang('Edit')); $html_link.= ' '; } else { //echo "".Display :: return_icon('quizz_small.gif', get_lang('Qualify')); //echo ' '; - $html_link.="".Display :: return_icon('quizz_small.gif', get_lang('Qualify')); + $html_link.="".Display :: return_icon('quizz_small.gif', get_lang('Qualify')); $html_link.=' '; } //echo ""; @@ -1305,7 +1313,7 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { $more_details_list = $html_link; if ($is_allowedToEdit || $is_tutor) { $list_info [] = array($user_first_name,$user_last_name,$quiz_name_list,$duration_list,$date_list,$result_list,$more_details_list); - } else { + } else { $list_info [] = array($quiz_name_list,$duration_list,$date_list,$result_list,$more_details_list); } //$list_info [] = array($user_list_name,$quiz_name_list,$duration_list,$date_list,$result_list,$more_details_list); @@ -1318,9 +1326,7 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { // Print HotPotatoes test results. if (is_array($hpresults)) { - $has_test_results = true; - for ($i = 0; $i < sizeof($hpresults); $i++) { $hp_title = GetQuizName($hpresults[$i][1], $documentPath); if ($hp_title == '') { @@ -1352,21 +1358,17 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) { $table->set_header(1, get_lang('FirstName')); $secuence = 0; } + $table->set_header(-$secuence + 2, get_lang('Exercice')); $table->set_header(-$secuence + 3, get_lang('Duration'),false); $table->set_header(-$secuence + 4, get_lang('Date')); $table->set_header(-$secuence + 5, get_lang('Result'),false); $table->set_header(-$secuence + 6, (($is_allowedToEdit||$is_tutor) ? get_lang('CorrectTest') : get_lang('ViewTest')), false); $table->display(); - } else { - echo get_lang('NoResult'); - } - } - if ($origin != 'learnpath') { //so we are not in learnpath tool Display :: display_footer(); } else { diff --git a/main/exercice/exercice_history.php b/main/exercice/exercice_history.php old mode 100644 new mode 100755 index 7713779eba..833d98878e --- a/main/exercice/exercice_history.php +++ b/main/exercice/exercice_history.php @@ -21,9 +21,7 @@ api_protect_course_script(true); $show=(isset($_GET['show']) && $_GET['show'] == 'result')?'result':'test'; // moved down to fix bug: http://www.dokeos.com/forum/viewtopic.php?p=18609#18609 /* ------------------------------------------------------------ Libraries ------------------------------------------------------------ */ require_once(api_get_path(LIBRARY_PATH).'document.lib.php'); @@ -31,9 +29,7 @@ require_once(api_get_path(LIBRARY_PATH).'document.lib.php'); include(api_get_path(LIBRARY_PATH).'usermanager.lib.php'); /* ------------------------------------------------------------ Constants and variables ------------------------------------------------------------ */ $is_allowedToEdit = api_is_allowed_to_edit(null,true); $is_tutor = api_is_allowed_to_edit(true); @@ -106,14 +102,10 @@ while($row = Database::fetch_array($query)){ } else { echo ''.get_lang('WithoutComment').''; } - - echo ''.$row['insert_date'].''; + echo ''.api_get_local_time($row['insert_date']).''; echo ''.(empty($row['firstname']) && empty($row['lastname']) ? ''.get_lang('OriginalValue').'' : api_get_person_name($row['firstname'], $row['lastname'])).''; echo ''; } echo ''; - Display::display_footer(); - -?> \ No newline at end of file diff --git a/main/exercice/exercice_submit.php b/main/exercice/exercice_submit.php index 286796db31..1db454842d 100755 --- a/main/exercice/exercice_submit.php +++ b/main/exercice/exercice_submit.php @@ -1,6 +1,5 @@ '; + +// Notice for unauthorized people. +api_protect_course_script(true); +$is_allowedToEdit = api_is_allowed_to_edit(null,true); + +//Blocking access in LPs +if ($origin == 'learnpath' && isset ($_GET['not_multiple_attempt']) && $_GET['not_multiple_attempt'] == strval(intval($_GET['not_multiple_attempt']))) { + $not_multiple_attempt = (int) $_GET['not_multiple_attempt']; + if ($not_multiple_attempt === 1) { + require_once '../inc/reduced_header.inc.php'; + echo '
 
'; + Display :: display_warning_message(get_lang('ReachedOneAttempt')); + exit; + } +} + +$htmlHeadXtra[] = ''; //jQuery +//$htmlHeadXtra[] = ''; //Not necessary to use jquery corner to do that effect use CSS3 if (api_get_setting('show_glossary_in_extra_tools') == 'true') { $htmlHeadXtra[] = ''; //Glossary $htmlHeadXtra[] = ''; } + //This library is necessary for the time control feature $htmlHeadXtra[] = ''; //jQuery -if (!ereg("MSIE",$_SERVER["HTTP_USER_AGENT"])) { - $htmlHeadXtra[] = ""; -} -/* ------------ ACCESS RIGHTS ------------ */ -// notice for unauthorized people. -api_protect_course_script(true); - -$is_allowedToEdit = api_is_allowed_to_edit(null,true); - $_configuration['live_exercise_tracking'] = true; -$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); +$stat_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); +$exercice_attemp_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); -// general parameters passed via POST/GET +$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 = $_REQUEST['origin']; } if (empty ($learnpath_id)) { - $learnpath_id = Security::remove_XSS($_REQUEST['learnpath_id']); + $learnpath_id = intval($_REQUEST['learnpath_id']); } if (empty ($learnpath_item_id)) { - $learnpath_item_id = Security::remove_XSS($_REQUEST['learnpath_item_id']); + $learnpath_item_id = intval($_REQUEST['learnpath_item_id']); } if (empty ($formSent)) { $formSent = $_REQUEST['formSent']; @@ -91,7 +94,7 @@ if (empty ($exerciseType)) { $exerciseType = $_REQUEST['exerciseType']; } if (empty ($exerciseId)) { - $exerciseId = Database::escape_string(intval($_REQUEST['exerciseId'])); + $exerciseId = intval($_REQUEST['exerciseId']); } if (empty ($choice)) { $choice = $_REQUEST['choice']; @@ -100,40 +103,27 @@ if (empty ($_REQUEST['choice'])) { $choice = $_REQUEST['choice2']; } if (empty ($questionNum)) { - $questionNum = Database :: escape_string($_REQUEST['questionNum']); + $questionNum = intval($_REQUEST['questionNum']); } if (empty ($nbrQuestions)) { - $nbrQuestions = Database :: escape_string($_REQUEST['nbrQuestions']); + $nbrQuestions = intval($_REQUEST['nbrQuestions']); } if (empty ($buttonCancel)) { $buttonCancel = $_REQUEST['buttonCancel']; } $error = ''; -if (!isset ($exerciseType)) { - $exe_start_date = time(); - $_SESSION['exercice_start_date'] = $exe_start_date; -} + // 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"); exit; } - -if ($origin == 'learnpath' && isset ($_GET['not_multiple_attempt']) && $_GET['not_multiple_attempt'] == strval(intval($_GET['not_multiple_attempt']))) { - $not_multiple_attempt = (int) $_GET['not_multiple_attempt']; - if ($not_multiple_attempt === 1) { - require_once '../inc/reduced_header.inc.php'; - echo '
 
'; - Display :: display_warning_message(get_lang('ReachedOneAttempt')); - exit; - } -} - if ($origin == 'builder') { /*******************************/ /* Clears the exercise session */ /*******************************/ + if ($debug) {error_log('origin = builder'); }; if (isset ($_SESSION['objExercise'])) { api_session_unregister('objExercise'); unset ($objExercise); @@ -164,199 +154,173 @@ if ($origin == 'builder') { } } -$course_code = api_get_course_id(); -$session_id = api_get_session_id(); - -$safe_lp_id = ($learnpath_id == '') ? 0 : (int) $learnpath_id; -$safe_lp_item_id = ($learnpath_item_id == '') ? 0 : (int) $learnpath_item_id; -$condition = ' WHERE ' . - 'exe_exo_id = ' . "'" . $exerciseId . "'" . ' AND ' . - 'exe_user_id = ' . "'" . api_get_user_id() . "'" . ' AND ' . - 'exe_cours_id = ' . "'" . $_course['id'] . "'" . ' AND ' . - 'status = ' . "'incomplete'" . ' AND ' . - 'orig_lp_id = ' . "'" . $safe_lp_id . "'" . ' AND ' . - 'orig_lp_item_id = ' . "'" . $safe_lp_item_id . "'" . ' AND ' . - 'session_id = ' . "'" . (int) $session_id . "'"; - -$TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST); -$sql_track_exercice = "SELECT type,feedback_type,expired_time FROM $TBL_EXERCICES WHERE id=$exerciseId"; -$result = Database::query($sql_track_exercice); -$exercise_row = Database :: fetch_array($result); -$exerciseType = $exercise_row['type']; -$exerciseFeedbackType = $exercise_row['feedback_type']; - -/* - * Time control feature - * if the expired time is major that zero(0) then - * the expired time is compute on this time - */ - -//Get the expired time of the current exercice in track_e_exercices -$total_minutes = $exercise_row["expired_time"]; +$safe_lp_id = ($learnpath_id == '') ? 0 : $learnpath_id; +$safe_lp_item_id = ($learnpath_item_id == '') ? 0 : $learnpath_item_id; -$total_seconds = $total_minutes*60; -$current_timestamp = time(); +// Loading the $objExercise variable -$current_expired_time_key = $course_code.'_'.$session_id.'_'.$exerciseId; - -//Disable for learning path -if ($exercise_row['expired_time'] != 0 && $origin != 'learnpath') { - if (!isset($_SESSION['expired_time'][$current_expired_time_key])) { - //In case that the current session php is broken - //Timer - Get expired_time for a student - $condition = ' WHERE ' . - 'exe_exo_id = '."'".Database::escape_string($exerciseId)."'".' AND ' . - 'exe_user_id = '."'".api_get_user_id()."'".' AND ' . - 'exe_cours_id = '."'".api_get_course_id()."'".' AND ' . - 'status = '."'incomplete'".' AND '. - 'session_id = '."'".$session_id."'"; - - $sql_track = 'SELECT exe_id,expired_time_control FROM '.$stat_table.$condition; - $rs_sql = Database::query($sql_track); - $exists_into_database = Database::num_rows($rs_sql); - $track_exercice_row = Database::fetch_array($rs_sql); - $expired_time_of_this_attempt = $track_exercice_row['expired_time_control']; - - //Get the last attempt of an exercice - $sql_track_attempt = 'SELECT max(tms) as last_attempt_date FROM '.$exercice_attemp_table.' WHERE exe_id="'.$track_exercice_row['exe_id'].'"'; - $rs_last_attempt = Database::query($sql_track_attempt); - $row_last_attempt = Database::fetch_array($rs_last_attempt); - $my_last_attempt_date = $row_last_attempt['last_attempt_date'];//Get the date of last attempt - $date_of_last_attempt = $my_last_attempt_date;// Necessary for to change the last attempt - - //change the date format - $my_last_attempt_date = strtotime($my_last_attempt_date); - $expired_time_of_this_attempt = strtotime($expired_time_of_this_attempt); +//if (!isset($_SESSION['objExercise']) || $origin == 'learnpath' || $_SESSION['objExercise']->id != $_REQUEST['exerciseId']) { +if (!isset ($_SESSION['objExercise']) || $_SESSION['objExercise']->id != $_REQUEST['exerciseId']) { + // Construction of Exercise + $objExercise = new Exercise(); + if ($debug) {error_log('Setting the $objExercise variable'); }; + unset($_SESSION['questionList']); - //New expired time - it is due to the possible closure of session - $new_expired_time_in_seconds = $expired_time_of_this_attempt - $my_last_attempt_date; + // 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'); }; + unset ($objExercise); + $error = get_lang('ExerciseNotFound'); + } else { + // saves the object into the session + api_session_register('objExercise'); + if ($debug) {error_log('$_SESSION[objExercise] was unset - set now - end'); }; + } +} - if ($exists_into_database == 1) { - $expected_time = $current_timestamp + $new_expired_time_in_seconds; +if (!isset ($objExercise) && isset($_SESSION['objExercise'])) { + if ($debug) {error_log('Loading $objExercise from session'); }; + $objExercise = $_SESSION['objExercise']; +} - $plugin_expired_time = date('M d, Y H:i:s', $expected_time); - $clock_expired_time = date('Y-m-d H:i:s' , $expected_time); - $new_last_attempt = date('Y-m-d H:i:s' , $current_timestamp); +if (!is_object($objExercise)) { + if ($debug) {error_log('$objExercise was not set, kill the script'); }; + header('Location: exercice.php'); + exit; +} - //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 = '".$track_exercice_row['exe_id']."'"; - Database::query($sql_track_e_exe); +$exerciseType = $objExercise->type; +$current_timestamp = time(); - // 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 = '".$new_last_attempt."' WHERE exe_id = '".$track_exercice_row['exe_id']."' and tms = '".$date_of_last_attempt."' "; - Database::query($sql_track_e_exe); +//Getting track exercise info +$exercise_stat_info = $objExercise->get_stat_track_exercise_info($safe_lp_id, $safe_lp_item_id); +if ($debug) {error_log('$objExercise->get_stat_track_exercise_info function called:: '.print_r($exercise_stat_info, 1)); }; - //Sessions that contain the expired time - $_SESSION['expired_time'][$current_expired_time_key] = $clock_expired_time; - $_SESSION['end_expired_time'][$current_expired_time_key] = date('M d, Y H:i:s',$expected_time); +/* + * 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 + */ +$time_control = false; +if ($objExercise->expired_time != 0 && $origin != 'learnpath') { + $time_control = true; +} +if ($time_control) { + //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 (!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'); }; + $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 + $last_attempt_date = get_last_attempt_date_of_exercise($exercise_stat_info['exe_id']); + + //This means that the user enters the exam but do not answer the first question we get the date from the track_e_exercises not from the track_et_attempt see #2069 + if (empty($last_attempt_date)) { + $diff = $current_timestamp - api_strtotime($exercise_stat_info['start_date'], 'UTC'); + $last_attempt_date = api_get_utc_datetime(api_strtotime($exercise_stat_info['start_date'],'UTC') + $diff); + } else { + //Recalculate the time control due #2069 + $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); } + + //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); } + + $expected_time = $current_timestamp + $new_expired_time_in_seconds; + if ($debug) {error_log('$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); + */ + + //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); } + 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] ); }; } else { $expected_time = $current_timestamp + $total_seconds; - - $plugin_expired_time = date('M d, Y H:i:s',$expected_time); - $clock_expired_time = date('Y-m-d H:i:s',$expected_time); + 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)); + + //$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); //Sessions that contain the expired time - $_SESSION['expired_time'][$current_expired_time_key] = $clock_expired_time; - $_SESSION['end_expired_time'][$current_expired_time_key] = date('M d, Y H:i:s',$expected_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] ); }; } - } else { - $plugin_expired_time = $_SESSION['end_expired_time'][$current_expired_time_key]; + // $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] ); }; } } // get time left for exipiring time -$time_left = strtotime($plugin_expired_time) - time(); +//$time_left = api_strtotime($plugin_expired_time) - api_strtotime(api_get_utc_datetime()); +// get time left for exipiring time +$time_left = api_strtotime($clock_expired_time,'UTC') - time(); /* * The time control feature is enable here - this feature is enable for a jquery plugin called epiclock * for more details of how it works see this link : http://eric.garside.name/docs.html?p=epiclock */ - -//Disable for learning path -if ($exercise_row['expired_time'] != 0 && $origin != 'learnpath') { //Sends the exercice form when the expired time is finished - $htmlHeadXtra[] = ""; +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'] && $exerciseType == ONE_PER_PAGE && $exerciseFeedbackType != EXERCISE_FEEDBACK_TYPE_DIRECT) { - $query = 'SELECT * FROM ' . $stat_table . $condition; - $result_select = Database::query($query); - if (Database :: num_rows($result_select) > 0) { - $getIncomplete = Database :: fetch_array($result_select); - $exe_id = $getIncomplete['exe_id']; +if ($_configuration['live_exercise_tracking'] && $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(',', $getIncomplete['data_tracking']); - $query = 'SELECT * FROM ' . $exercice_attemp_table . ' WHERE exe_id = ' . $getIncomplete['exe_id'] . ' ORDER BY tms ASC'; + $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); - while ($row = Database :: fetch_array($result)) { + while ($row = Database :: fetch_array($result,'ASSOC')) { $recorded['exerciseResult'][$row['question_id']] = 1; } - $exerciseResult = $_SESSION['exerciseResult'] = $recorded['exerciseResult']; - $exerciseType = ONE_PER_PAGE; + $exerciseResult = $_SESSION['exerciseResult'] = $recorded['exerciseResult']; $questionNum = count($recorded['exerciseResult']); $questionNum++; $questionList = $_SESSION['questionList'] = $recorded['questionList']; } - } else { - $table_recorded_not_exist = true; } } // if the user has submitted the form if ($formSent) { - if ($debug > 0) { - echo str_repeat(' ', 0) . '$formSent was set' . "
\n"; - } + if ($debug > 0) { error_log('$formSent was set'); } - // initializing + // Initializing if (!is_array($exerciseResult)) { $exerciseResult = array (); $exerciseResultCoordinates = array (); @@ -370,10 +334,7 @@ if ($formSent) { // if the user has answered at least one question if (is_array($choice)) { - if ($debug > 0) { - echo str_repeat(' ', 0) . '$choice is an array' . "
\n"; - } - + if ($debug > 0) {if ($debug > 0) { error_log('$choice is an array'); } } if ($exerciseType == ALL_ON_ONE_PAGE) { // $exerciseResult receives the content of the form. // Each choice of the student is stored into the array $choice @@ -383,10 +344,10 @@ if ($formSent) { // will be stored in the session at the end of this script) // The results will be stored by exercise_result.php if we are in // an exercise of type 1 (=all on one page) + //This seems not useful if (isset ($_POST['hotspot'])) { $exerciseResultCoordinates = $_POST['hotspot']; } - } else { // gets the question ID from $choice. It is the key of the array list ($key) = array_keys($choice); @@ -394,374 +355,23 @@ if ($formSent) { if (!isset ($exerciseResult[$key])) { // stores the user answer into the array $exerciseResult[$key] = $choice[$key]; - //saving each question - if ($_configuration['live_exercise_tracking'] && $exerciseType == ONE_PER_PAGE && $exerciseFeedbackType != EXERCISE_FEEDBACK_TYPE_DIRECT) { - + if ($_configuration['live_exercise_tracking'] && $exerciseType == ONE_PER_PAGE && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) { $nro_question = $questionNum; // - 1; - //START of saving and qualifying each question submitted - //------------------------------------------------------------------------------------------ - // define('ENABLED_LIVE_EXERCISE_TRACKING', 1); - require_once 'question.class.php'; - require_once 'answer.class.php'; - - $counter = 0; - $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER); - $table_ans = Database :: get_course_table(TABLE_QUIZ_ANSWER); - - //foreach($questionList as $questionId) - if (true) { - $exeId = $exe_id; - $questionId = $key; - $counter++; - // gets the student choice for this question - $choice = $exerciseResult[$questionId]; - // creates a temporary Question object - $objQuestionTmp = Question :: read($questionId); - - $questionName = $objQuestionTmp->selectTitle(); - $questionDescription = $objQuestionTmp->selectDescription(); - $questionWeighting = $objQuestionTmp->selectWeighting(); - $answerType = $objQuestionTmp->selectType(); - $quesId = $objQuestionTmp->selectId(); //added by priya saini - - // destruction of the Question object - unset ($objQuestionTmp); - - if (isset ($_POST['hotspot']) && isset($_POST['hotspot'][$key])) { - $exerciseResultCoordinates[$key] = $_POST['hotspot'][$key]; - } - - // construction of the Answer object - $objAnswerTmp = new Answer($questionId); - $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); - $questionScore = 0; - if ($answerType == FREE_ANSWER) { - $nbrAnswers = 1; - } - $real_answers = array(); - for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { - $answer = $objAnswerTmp->selectAnswer($answerId); - $answerComment = $objAnswerTmp->selectComment($answerId); - $answerCorrect = $objAnswerTmp->isCorrect($answerId); - $answerWeighting = $objAnswerTmp->selectWeighting($answerId); - $numAnswer=$objAnswerTmp->selectAutoId($answerId); - switch ($answerType) { - // for unique answer - case UNIQUE_ANSWER : - $studentChoice=($choice == $numAnswer)?1:0; - if ($studentChoice) { - $questionScore+=$answerWeighting; - $totalScore+=$answerWeighting; - } - break; - // for multiple answers - case MULTIPLE_ANSWER : - $studentChoice=$choice[$numAnswer]; - if ($studentChoice) { - $questionScore+=$answerWeighting; - $totalScore+=$answerWeighting; - } - break; - case MULTIPLE_ANSWER_COMBINATION: - $studentChoice=$choice[$numAnswer]; - - if ($answerCorrect == 1) { - if ($studentChoice) { - $real_answers[$answerId] = true; - } else { - $real_answers[$answerId] = false; - } - } else { - if ($studentChoice) { - $real_answers[$answerId] = false; - } else { - $real_answers[$answerId] = true; - } - } - - $final_answer = true; - foreach($real_answers as $my_answer) { - if (!$my_answer) { - $final_answer = false; - } - } - break; - // for fill in the blanks - case FILL_IN_BLANKS : - - // the question is encoded like this - // [A] B [C] D [E] F::10,10,10@1 - // number 1 before the "@" means that is a switchable fill in blank question - // [A] B [C] D [E] F::10,10,10@ or [A] B [C] D [E] F::10,10,10 - // means that is a normal fill blank question - - // first we explode the "::" - $pre_array = explode('::', $answer); - - // is switchable fill blank or not - $last = count($pre_array) - 1; - $is_set_switchable = explode('@', $pre_array[$last]); - - $switchable_answer_set = false; - if (isset ($is_set_switchable[1]) && $is_set_switchable[1] == 1) { - $switchable_answer_set = true; - } - - $answer = ''; - for ($k = 0; $k < $last; $k++) { - $answer .= $pre_array[$k]; - } - - // splits weightings that are joined with a comma - $answerWeighting = explode(',', $is_set_switchable[0]); - - // we save the answer because it will be modified - //$temp = $answer; - $temp = text_filter($answer); - - /* // Deprecated code - // TeX parsing - // 1. find everything between the [tex] and [/tex] tags - $startlocations = api_strpos($temp, '[tex]'); - $endlocations = api_strpos($temp, '[/tex]'); - - if ($startlocations !== false && $endlocations !== false) { - $texstring = api_substr($temp, $startlocations, $endlocations - $startlocations +6); - // 2. replace this by {texcode} - $temp = str_replace($texstring, '{texcode}', $temp); - } - */ - - $answer = ''; - $j = 0; - - //initialise answer tags - $user_tags = array (); - $correct_tags = array (); - $real_text = array (); - // the loop will stop at the end of the text - while (1) { - // quits the loop if there are no more blanks (detect '[') - if (($pos = api_strpos($temp, '[')) === false) { - // adds the end of the text - $answer = $temp; - /* // Deprecated code - // TeX parsing - replacement of texcode tags - $texstring = api_parse_tex($texstring); - $answer = str_replace("{texcode}", $texstring, $answer); - */ - $real_text[] = $answer; - break; //no more "blanks", quit the loop - } - // adds the piece of text that is before the blank - //and ends with '[' into a general storage array - $real_text[] = api_substr($temp, 0, $pos +1); - $answer .= api_substr($temp, 0, $pos +1); - //take the string remaining (after the last "[" we found) - $temp = api_substr($temp, $pos +1); - // quit the loop if there are no more blanks, and update $pos to the position of next ']' - if (($pos = api_strpos($temp, ']')) === false) { - // adds the end of the text - $answer .= $temp; - break; - } - $choice[$j] = trim($choice[$j]); - $user_tags[] = api_strtolower($choice[$j]); - //put the contents of the [] answer tag into correct_tags[] - $correct_tags[] = api_strtolower(substr($temp, 0, $pos)); - $j++; - $temp = api_substr($temp, $pos +1); - //$answer .= ']'; - } - - $answer = ''; - $real_correct_tags = $correct_tags; - $chosen_list = array (); - - for ($i = 0; $i < count($real_correct_tags); $i++) { - if ($i == 0) { - $answer .= $real_text[0]; - } - - if (!$switchable_answer_set) { - //needed to parse ' and " characters - $user_tags[$i] = stripslashes($user_tags[$i]); - if ($correct_tags[$i] == $user_tags[$i]) { - // gives the related weighting to the student - $questionScore += $answerWeighting[$i]; - // increments total score - $totalScore += $answerWeighting[$i]; - // adds the word in green at the end of the string - $answer .= $correct_tags[$i]; - } - // else if the word entered by the student IS NOT the same as the one defined by the professor - elseif (!empty ($user_tags[$i])) { - // adds the word in red at the end of the string, and strikes it - $answer .= '' . $user_tags[$i] . ''; - } else { - // adds a tabulation if no word has been typed by the student - $answer .= '   '; - } - } else { - // switchable fill in the blanks - if (in_array($user_tags[$i], $correct_tags)) { - $chosen_list[] = $user_tags[$i]; - $correct_tags = array_diff($correct_tags, $chosen_list); - - // gives the related weighting to the student - $questionScore += $answerWeighting[$i]; - // increments total score - $totalScore += $answerWeighting[$i]; - // adds the word in green at the end of the string - $answer .= $user_tags[$i]; - } - elseif (!empty ($user_tags[$i])) { - // else if the word entered by the student IS NOT the same as the one defined by the professor - // adds the word in red at the end of the string, and strikes it - $answer .= '' . $user_tags[$i] . ''; - } else { - // adds a tabulation if no word has been typed by the student - $answer .= '   '; - } - } - // adds the correct word, followed by ] to close the blank - $answer .= ' / ' . $real_correct_tags[$i] . ']'; - if (isset ($real_text[$i +1])) { - $answer .= $real_text[$i +1]; - } - } - - break; - // for free answer - case FREE_ANSWER : - $studentChoice = $choice; - - if ($studentChoice) { - //Score is at -1 because the question has'nt been corected - $questionScore = -1; - $totalScore += 0; - } - break; - // for matching - case MATCHING : - - $numAnswer=$objAnswerTmp->selectAutoId($answerId); - if ($answerCorrect) { - if ($answerCorrect == $choice[$numAnswer]) { - $questionScore+=$answerWeighting; - $totalScore+=$answerWeighting; - } - $matching[$numAnswer] = $choice[$numAnswer]; - } - break; - // for hotspot with no order - case HOT_SPOT : - $studentChoice = $choice[$answerId]; - if ($studentChoice) { - $questionScore += $answerWeighting; - $totalScore += $answerWeighting; - } - break; - // for hotspot with fixed order - case HOT_SPOT_ORDER : - $studentChoice = $choice['order'][$answerId]; - - if ($studentChoice == $answerId) { - $questionScore += $answerWeighting; - $totalScore += $answerWeighting; - $studentChoice = true; - } else { - $studentChoice = false; - } - break; - } // end switch Answertype - } // end for that loops over all answers of the current question - // destruction of Answer - - //we add the total score after dealing with the answers - if ($answerType == MULTIPLE_ANSWER_COMBINATION) { - if ($final_answer) { - //getting only the first score where we save the weight of all the question - $answerWeighting=$objAnswerTmp->selectWeighting(1); - $questionScore+=$answerWeighting; - $totalScore+=$answerWeighting; - } - } - - unset ($objAnswerTmp); - - $i++; - - $totalWeighting += $questionWeighting; - //added by priya saini - // Store results directly in the database - // For all in one page exercises, the results will be - // stored by exercise_results.php (using the session) - if ($_configuration['tracking_enabled']) { - if (empty ($choice)) { - $choice = 0; - } - if ($answerType == MULTIPLE_ANSWER) { - if ($choice != 0) { - $reply = array_keys($choice); - for ($i = 0; $i < sizeof($reply); $i++) { - $ans = $reply[$i]; - exercise_attempt($questionScore, $ans, $quesId, $exeId, $i); - } - } else { - exercise_attempt($questionScore, 0, $quesId, $exeId, 0); - } - } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { - if ($choice != 0) { - $reply = array_keys($choice); - for ($i = 0; $i < sizeof($reply); $i++) { - $ans = $reply[$i]; - exercise_attempt($questionScore, $ans, $quesId, $exeId, $i); - } - } else { - exercise_attempt($questionScore, 0, $quesId, $exeId, 0); - } - } elseif ($answerType == MATCHING) { - foreach ($matching as $j => $val) { - exercise_attempt($questionScore, $val, $quesId, $exeId, $j); - } - } elseif ($answerType == FREE_ANSWER) { - $answer = $choice; - exercise_attempt($questionScore, $answer, $quesId, $exeId, 0); - } elseif ($answerType == UNIQUE_ANSWER) { - $answer = $choice; - exercise_attempt($questionScore, $answer, $quesId, $exeId, 0); - } elseif ($answerType == HOT_SPOT) { - exercise_attempt($questionScore, $answer, $quesId, $exeId, 0); - if (is_array($exerciseResultCoordinates[$key])) { - foreach($exerciseResultCoordinates[$key] as $idx => $val) { - exercise_attempt_hotspot($exeId,$quesId,$idx,$choice[$idx],$val); - } - } - } else { - exercise_attempt($questionScore, $answer, $quesId, $exeId, 0); - } - } - } - // end huge foreach() block that loops over all questions - //at loops over all questions + $questionId = $key; + // gets the student choice for this question + $choice = $exerciseResult[$questionId]; if (isset($exe_id)) { - $sql_update = 'UPDATE ' . $stat_table . ' SET exe_result = exe_result + ' . (int) $totalScore . ',exe_weighting = exe_weighting + ' . (int) $totalWeighting . ' WHERE exe_id = ' . Database::escape_string($exe_id); - Database::query($sql_update); + //Manage the question and answer attempts + $objExercise->manage_answer($exe_id, $questionId, $choice); } - //END of saving and qualifying - //------------------------------------------------------------------------------------------ - // } } } - if ($debug > 0) { - echo str_repeat(' ', 0) . '$choice is an array - end' . "
\n"; - } + if ($debug > 0) { error_log('$choice is an array - end'); } } // the script "exercise_result.php" will take the variable $exerciseResult from the session @@ -771,131 +381,49 @@ if ($formSent) { // 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 ($debug > 0) { - echo str_repeat(' ', 0) . 'Redirecting to exercise_result.php - Remove debug option to let this happen' . "
\n"; - } - + if ($debug > 0) { error_log('Redirecting to exercise_result.php - Remove debug option to let this happen'); } 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) { header("Location: exercise_result.php?exerciseType=$exerciseType&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id"); + exit; } else { if ($exe_id != '') { //Verify if the current test is fraudulent - $current_time = time(); - - //The $exercise_row['expired_time'][$exerciseId] is never set. It means nothing. - //if (isset($_SESSION['expired_time'][$current_expired_time_key]) && $exercise_row['expired_time'][$exerciseId] != 0) { - if (isset($_SESSION['expired_time'][$current_expired_time_key])) { - $expired_date = $_SESSION['expired_time'][$current_expired_time_key]; - $expired_time = strtotime($expired_date); - - //Validation in case of fraud - $total_time_allowed = $expired_time + 30; - if ($total_time_allowed < $current_time) { - $sql_exe_result = ",exe_result = 0"; - } - + if (exercise_time_control_is_valid($exerciseId)) { + $sql_exe_result = ""; } else { - $sql_exe_result = ""; + $sql_exe_result = ",exe_result = 0"; } - - - //clean incomplete - $update_query = 'UPDATE ' . $stat_table . ' SET ' . "status = '', data_tracking='', exe_date = '" . date('Y-m-d H:i:s') . "' $sql_exe_result " . ' WHERE exe_id = ' . Database::escape_string($exe_id); + //Clean incomplete - @todo why setting to blank the data_tracking? + //$update_query = 'UPDATE ' . $stat_table . ' SET ' . "status = '', data_tracking='', exe_date = '" . api_get_utc_datetime() . "' $sql_exe_result " . ' WHERE exe_id = ' . Database::escape_string($exe_id); + $update_query = 'UPDATE ' . $stat_table . ' SET ' . "status = '', exe_date = '" . api_get_utc_datetime() . "' $sql_exe_result " . ' WHERE exe_id = ' . Database::escape_string($exe_id); + if ($debug) {error_log($update_query);}; Database::query($update_query); } header("Location: exercise_show.php?id=$exe_id&exerciseType=$exerciseType&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id"); - } - exit (); + exit; + } } else { header("Location: exercice_submit.php?exerciseId=$exerciseId"); - exit; - } - } - - if ($debug > 0) { - echo str_repeat(' ', 0) . '$formSent was set - end' . "
\n"; - } -} - -// if the object is not in the session - -//why destroying the exercise when a LP is loaded ? -//if (!isset($_SESSION['objExercise']) || $origin == 'learnpath' || $_SESSION['objExercise']->id != $_REQUEST['exerciseId']) { -if (!isset ($_SESSION['objExercise']) || $_SESSION['objExercise']->id != $_REQUEST['exerciseId']) { - if ($debug > 0) { - echo str_repeat(' ', 0) . '$_SESSION[objExercise] was unset' . "
\n"; - } - // construction of Exercise - $objExercise = new Exercise(); - unset ($_SESSION['questionList']); - - // if the specified exercise doesn't exist or is disabled - if (!$objExercise->read($exerciseId) || (!$objExercise->selectStatus() && !$is_allowedToEdit && ($origin != 'learnpath'))) { - unset ($objExercise); - $error = get_lang('ExerciseNotFound'); - //die(get_lang('ExerciseNotFound')); - } else { - // saves the object into the session - api_session_register('objExercise'); - if ($debug > 0) { - echo str_repeat(' ', 0) . '$_SESSION[objExercise] was unset - set now - end' . "
\n"; + exit; } } + if ($debug > 0) { error_log('$formSent was set - end'); } } -if (!isset ($objExercise) && isset ($_SESSION['objExercise'])) { - $objExercise = $_SESSION['objExercise']; -} -if (!is_object($objExercise)) { - header('Location: exercice.php'); - exit (); -} -$Exe_starttime = $objExercise->start_time; -$Exe_endtime = $objExercise->end_time; -$quizID = $objExercise->selectId(); -$exerciseAttempts = $objExercise->selectAttempts(); -$exerciseTitle = $objExercise->selectTitle(); -$exerciseDescription = $objExercise->selectDescription(); -$exerciseDescription = $exerciseDescription; -$exerciseSound = $objExercise->selectSound(); -$randomQuestions = $objExercise->isRandom(); -$exerciseType = $objExercise->selectType(); -$table_quiz_test = Database :: get_course_table(TABLE_QUIZ_TEST); +$exerciseTitle = $objExercise->selectTitle(); +$exerciseDescription= $objExercise->selectDescription(); +$exerciseSound = $objExercise->selectSound(); +$exerciseType = $objExercise->selectType(); //if (!isset($_SESSION['questionList']) || $origin == 'learnpath') { //in LP's is enabled the "remember question" feature? -$my_exe_id = Security :: remove_XSS($_GET['exerciseId']); -if (!isset ($_SESSION['questionList'])) { - if ($debug > 0) { - echo str_repeat(' ', 0) . '$_SESSION[questionList] was unset' . "
\n"; - } - // selects the list of question ID - $my_question_list = array (); - $questionList = ($randomQuestions ? $objExercise->selectRandomList() : $objExercise->selectQuestionList()); - // saves the question list into the session - $sql = 'SELECT random FROM ' . $table_quiz_test . ' WHERE id="' . Database :: escape_string($my_exe_id) . '";'; - $rs = Database::query($sql); - $row_number = Database :: fetch_array($rs); - $z = 0; - - if ($row_number['random'] <> 0) { - foreach ($questionList as $infoquestionList) { - if ($z < $row_number['random']) { - $my_question_list[$z] = $infoquestionList; - } else { - break; - } - $z++; - } - // $questionList=array(); - $questionList = $my_question_list; - } +if (!isset($_SESSION['questionList'])) { + // selects the list of question ID + $questionList = ($objExercise->isRandom() ? $objExercise->selectRandomList() : $objExercise->selectQuestionList()); api_session_register('questionList'); - if ($debug > 0) { - echo str_repeat(' ', 0) . '$_SESSION[questionList] was unset - set now - end' . "
\n"; - } + if ($debug > 0) { error_log('$_SESSION[questionList] was set'); } } if (!isset ($objExercise) && isset ($_SESSION['objExercise'])) { $questionList = $_SESSION['questionList']; @@ -903,7 +431,9 @@ if (!isset ($objExercise) && isset ($_SESSION['objExercise'])) { $quizStartTime = time(); api_session_register('quizStartTime'); -$nbrQuestions = sizeof($questionList); +//Real question count +$nbrQuestions = count($questionList); + // if questionNum comes from POST and not from GET if (!$questionNum || $_POST['questionNum']) { // only used for sequential exercises (see $exerciseType) @@ -917,151 +447,25 @@ if (!$questionNum || $_POST['questionNum']) { if (!empty ($_GET['gradebook']) && $_GET['gradebook'] == 'view') { $_SESSION['gradebook'] = Security :: remove_XSS($_GET['gradebook']); $gradebook = $_SESSION['gradebook']; -} -elseif (empty ($_GET['gradebook'])) { +} elseif (empty ($_GET['gradebook'])) { unset ($_SESSION['gradebook']); $gradebook = ''; } if (!empty ($gradebook) && $gradebook == 'view') { - $interbreadcrumb[] = array ( - 'url' => '../gradebook/' . $_SESSION['gradebook_dest'], - 'name' => get_lang('ToolGradebook') - ); + $interbreadcrumb[] = array ('url' => '../gradebook/' . Security::remove_XSS($_SESSION['gradebook_dest']),'name' => get_lang('ToolGradebook')); } -//$nameTools=get_lang('Exercice'); -$interbreadcrumb[] = array ( - "url" => "exercice.php?gradebook=$gradebook", - "name" => get_lang('Exercices') -); -$interbreadcrumb[] = array ( - "url" => api_get_self()."?gradebook=$gradebook", - "name" => $exerciseTitle -); +$interbreadcrumb[] = array ("url" => "exercice.php?gradebook=$gradebook", "name" => get_lang('Exercices')); +$interbreadcrumb[] = array ("url" => api_get_self()."?gradebook=$gradebook","name" => $objExercise->selectTitle()); if ($origin != 'learnpath') { //so we are not in learnpath tool - - $htmlHeadXtra[] = " - - - - - "; - Display :: display_header($nameTools, "Exercise"); + $htmlHeadXtra[] = $objExercise->show_lp_javascript(); + Display :: display_header($nameTools,get_lang('Exercises')); if (!api_is_allowed_to_session_edit() ) { Display :: display_warning_message(get_lang('SessionIsReadOnly')); } } else { - /* - * HTML HEADER - */ Display::display_reduced_header(); echo '
 
'; } @@ -1069,15 +473,13 @@ if ($origin != 'learnpath') { //so we are not in learnpath tool $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 ='".Database::escape_string($exerciseId)."'"; + $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; } } - // I'm in a preview mode if (api_is_course_admin() && $origin != 'learnpath') { echo '
'; @@ -1087,76 +489,63 @@ if (api_is_course_admin() && $origin != 'learnpath') { } else { echo Display::return_icon('edit_na.gif', get_lang('ModifyExercise')).''.get_lang('ModifyExercise').''; } - echo '
'; } -$exerciseTitle = text_filter($exerciseTitle); -echo "

" . $exerciseTitle . "

"; +$exerciseTitle = text_filter($objExercise->selectTitle()); +echo "

" . $exerciseTitle . "

"; $show_clock = true; - -if ($exerciseAttempts > 0) { - $user_id = api_get_user_id(); - $sql = "SELECT count(*) FROM $stat_table WHERE exe_exo_id = '$quizID' - AND exe_user_id = '$user_id' - AND status != 'incomplete' - AND orig_lp_id = $safe_lp_id - AND orig_lp_item_id = $safe_lp_item_id - AND exe_cours_id = '$course_code' AND session_id = '" . (int) $session_id . "'"; - - $aquery = Database::query($sql); - $attempt = Database :: fetch_array($aquery); - - if ($attempt[0] >= $exerciseAttempts) { +$user_id = api_get_user_id(); +if ($objExercise->selectAttempts() > 0) { + $attempt_count = get_attempt_count($user_id, $exerciseId, $safe_lp_id, $safe_lp_item_id); + if ($attempt_count >= $objExercise->selectAttempts()) { $show_clock = false; if (!api_is_allowed_to_edit(null,true)) { - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $exerciseAttempts), false); + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttempts'), $exerciseTitle, $objExercise->selectAttempts()), false); if ($origin != 'learnpath') Display :: display_footer(); exit; } else { - Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttemptsAdmin'), $exerciseTitle, $exerciseAttempts), false); + Display :: display_warning_message(sprintf(get_lang('ReachedMaxAttemptsAdmin'), $exerciseTitle, $objExercise->selectAttempts()), false); } } } -//Timer control -if ($show_clock && $exercise_row['expired_time'] != 0 && $origin != 'learnpath') { - echo '
'; - echo ''; -} - -if (!function_exists('convert_date_to_number')) { - function convert_date_to_number($default) { - // 2008-10-12 00:00:00 ---to--> 12345672218 (timestamp) - $parts = split(' ', $default); - list ($d_year, $d_month, $d_day) = split('-', $parts[0]); - list ($d_hour, $d_minute, $d_second) = split(':', $parts[1]); - return mktime($d_hour, $d_minute, $d_second, $d_month, $d_day, $d_year); - } -} +$limit_time_exists = (($objExercise->start_time != '0000-00-00 00:00:00') || ($objExercise->end_time != '0000-00-00 00:00:00')) ? true : false; -$limit_time_exists = (($Exe_starttime != '0000-00-00 00:00:00') || ($Exe_endtime != '0000-00-00 00:00:00')) ? true : false; -if ($limit_time_exists) { - $exercise_start_time = convert_date_to_number($Exe_starttime); - $exercise_end_time = convert_date_to_number($Exe_endtime); - $time_now = convert_date_to_number(date('Y-m-d H:i:s')); +if ($limit_time_exists) { + $exercise_start_time = api_strtotime($objExercise->start_time,'UTC'); + $exercise_end_time = api_strtotime($objExercise->end_time,'UTC'); + $time_now = time(); + $permission_to_start = (($time_now - $exercise_start_time) > 0) ? true : false; - if ($_SERVER['REQUEST_METHOD'] != 'POST') - $exercise_timeover = (($time_now - $exercise_end_time) > 0) ? true : false; - if (!$permission_to_start || $exercise_timeover) { // - if (!api_is_allowed_to_edit(null,true)) { + + if ($_SERVER['REQUEST_METHOD'] != 'POST') { + $exercise_timeover = (($time_now - $exercise_end_time) > 0) ? true : false; + } + + 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, $exerciseAttempts)); - Display :: display_footer(); + Display :: display_warning_message(sprintf($message_warning, $exerciseTitle, $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, $exerciseAttempts)); + Display :: display_warning_message(sprintf($message_warning, $exerciseTitle, $objExercise->selectAttempts())); + exit; } } } +//Timer control +if ($time_control) { + echo '
'; + echo ''; +} + if ($origin != 'learnpath') { echo '
'; } @@ -1164,10 +553,8 @@ if (!empty ($error)) { Display :: display_error_message($error, false); } else { if (!empty ($exerciseSound)) { - echo "", ", get_lang('Sound') .
-        "; + echo "", ", get_lang('Sound') . "; } - // Get number of hotspot questions for javascript validation $number_of_hotspot_questions = 0; $onsubmit = ''; @@ -1199,134 +586,75 @@ if (!empty ($error)) { if ($number_of_hotspot_questions > 0) { $onsubmit = "onsubmit=\"return validateFlashVar('" . $number_of_hotspot_questions . "', '" . get_lang('HotspotValidateError1') . "', '" . get_lang('HotspotValidateError2') . "');\""; } - $s = "

$exerciseDescription

"; - - if ($exerciseType == ONE_PER_PAGE) - { - $s2 = "&exerciseId=" . $exerciseId; - } - - $s .= "
- - - - - - - - - + echo "

$exerciseDescription

"; + $exercise_condition = ''; + if ($exerciseType == ONE_PER_PAGE) { + $exercise_condition = "&exerciseId=" . $exerciseId; + } + echo ' + + + + + + + + +
+ +
- "; - - echo $s; - $i = 1; - foreach ($questionList as $questionId) { - // for sequential exercises - if ($exerciseType == ONE_PER_PAGE) { - // if it is not the right question, goes to the next loop iteration - if ($questionNum != $i) { - $i++; - continue; - } else { - if ($exerciseFeedbackType != EXERCISE_FEEDBACK_TYPE_DIRECT) { - // if the user has already answered this question - if (isset ($exerciseResult[$questionId])) { - // construction of the Question object - $objQuestionTmp = Question :: read($questionId); - $questionName = $objQuestionTmp->selectTitle(); - // destruction of the Question object - unset ($objQuestionTmp); - Display :: display_normal_message(get_lang('AlreadyAnswered')); - $i++; - //echo ''; - break; - } - } - } - } - // shows the question and its answers - showQuestion($questionId, false, $origin, $i, $nbrQuestions); - $i++; - // for sequential exercises - if ($exerciseType == ONE_PER_PAGE) { - // quits the loop - break; - } - } - // end foreach() - //echo "
"; - echo '
'; - - $confirmation_alert = $exerciseType == 1? " onclick=\"javascript:if(!confirm('".get_lang("ConfirmYourChoice")."')) return false;\" ":""; - $submit_btn = ""; - if ($exercise_row['expired_time'] != 0) { - echo $submit_btn =""; - } else { - echo $submit_btn; - } - } +
'.get_lang('AlreadyAnswered').' "'.$questionName.'"
'; + + //Show list of questions + $i = 1; + foreach ($questionList as $questionId) { + // for sequential exercises + if ($exerciseType == ONE_PER_PAGE) { + // if it is not the right question, goes to the next loop iteration + if ($questionNum != $i) { + $i++; + continue; + } else { + if ($objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) { + // if the user has already answered this question + if (isset ($exerciseResult[$questionId])) { + // construction of the Question object + $objQuestionTmp = Question :: read($questionId); + $questionName = $objQuestionTmp->selectTitle(); + // destruction of the Question object + unset ($objQuestionTmp); + Display :: display_normal_message(get_lang('AlreadyAnswered')); + $i++; + break; + } + } + } + } + // shows the question and its answers + showQuestion($questionId, false, $origin, $i, $nbrQuestions); + $i++; + // for sequential exercises + if ($exerciseType == ONE_PER_PAGE) { + // quits the loop + break; + } + } + // end foreach() + echo $objExercise->show_button($nbrQuestions, $questionNum); + echo '
+
'; +} +if ($_configuration['live_exercise_tracking'] && $objExercise->feedbacktype != EXERCISE_FEEDBACK_TYPE_DIRECT) { + if (empty($exercise_stat_info)) { + $objExercise->save_stat_track_exercise_info($clock_expired_time, $safe_lp_id, $safe_lp_item_id,$questionList); } - echo '
'; //margin top -10 - echo ' - - - '; - $b = 2; } - - -if ($_configuration['live_exercise_tracking'] && $exerciseFeedbackType != EXERCISE_FEEDBACK_TYPE_DIRECT) { - - if ($table_recorded_not_exist) { //$table_recorded_not_exist - if ($exercise_row['expired_time'] != 0) { - $sql_fields = "expired_time_control, "; - $sql_fields_values = "'"."$clock_expired_time"."',"; - } else { - $sql_fields = ""; - $sql_fields_values = ""; - } - - if ($exerciseType == ONE_PER_PAGE) { - $sql = "INSERT INTO $stat_table($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) - VALUES($sql_fields_values '$exerciseId','" . api_get_user_id() . "','" . $_course['id'] . "','incomplete','" . $session_id . "','" . implode(',', $questionList) . "','" . date('Y-m-d H:i:s') . "',$safe_lp_id,$safe_lp_item_id)"; - - Database::query($sql); - } else { - $sql = "INSERT INTO $stat_table ($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 '$exerciseId','" . api_get_user_id() . "','" . $_course['id'] . "','incomplete','" . $session_id . "','" . date('Y-m-d H:i:s') . "',$safe_lp_id,$safe_lp_item_id)"; - Database::query($sql); - } - - } -} - if ($origin != 'learnpath') { //so we are not in learnpath tool echo ''; //End glossary div Display :: display_footer(); } else { echo ''; -} +} \ No newline at end of file diff --git a/main/exercice/exercise.class.php b/main/exercice/exercise.class.php index 55e317987d..4716306b68 100755 --- a/main/exercice/exercise.class.php +++ b/main/exercice/exercise.class.php @@ -5,19 +5,21 @@ * Exercise class: This class allows to instantiate an object of type Exercise * @package dokeos.exercise * @author Olivier Brouckaert +* @author Julio Montoya Cleaning exercises * @version $Id: exercise.class.php 22046 2009-07-14 01:45:19Z ivantcholakov $ */ define('ALL_ON_ONE_PAGE',1); define('ONE_PER_PAGE',2); +//0=>Feedback , 1=>DirectFeedback, 2=>NoFeedback define('EXERCISE_FEEDBACK_TYPE_END',0); define('EXERCISE_FEEDBACK_TYPE_DIRECT',1); define('EXERCISE_FEEDBACK_TYPE_EXAM',2); if(!class_exists('Exercise')): -class Exercise -{ +class Exercise { + public $id; public $exercise; public $description; @@ -34,27 +36,27 @@ class Exercise public $questionList; // array with the list of this exercise's questions public $results_disabled; public $expired_time; + /** - * constructor of the class + * Constructor of the class * * @author - Olivier Brouckaert */ - function Exercise() - { - $this->id=0; - $this->exercise=''; - $this->description=''; - $this->sound=''; - $this->type=1; - $this->random=0; - $this->random_answers=0; - $this->active=1; - $this->questionList=array(); - $this->timeLimit = 0; - $this->end_time = '0000-00-00 00:00:00'; - $this->start_time = '0000-00-00 00:00:00'; - $this->results_disabled =1; - $this->expired_time = '0000-00-00 00:00:00'; + function Exercise() { + $this->id = 0; + $this->exercise = ''; + $this->description = ''; + $this->sound = ''; + $this->type = 1; + $this->random = 0; + $this->random_answers = 0; + $this->active = 1; + $this->questionList = array(); + $this->timeLimit = 0; + $this->end_time = '0000-00-00 00:00:00'; + $this->start_time = '0000-00-00 00:00:00'; + $this->results_disabled = 1; + $this->expired_time = '0000-00-00 00:00:00'; } /** @@ -64,12 +66,7 @@ class Exercise * @param - integer $id - exercise ID * @return - boolean - true if exercise exists, otherwise false */ - function read($id) - { - global $_course; - global $_configuration; - global $questionList; - + function read($id) { $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); @@ -79,53 +76,50 @@ class Exercise $result=Database::query($sql); // if the exercise has been found - if($object=Database::fetch_object($result)) - { - $this->id=$id; - $this->exercise=$object->title; - $this->description=$object->description; - $this->sound=$object->sound; - $this->type=$object->type; - $this->random=$object->random; - $this->random_answers=$object->random_answers; - $this->active=$object->active; - $this->results_disabled =$object->results_disabled; - $this->attempts = $object->max_attempt; - $this->feedbacktype = $object->feedback_type; - $this->end_time = $object->end_time; - $this->start_time = $object->start_time; - $this->expired_time = $object->expired_time; - $sql="SELECT question_id, question_order FROM $TBL_EXERCICE_QUESTION,$TBL_QUESTIONS WHERE question_id=id AND exercice_id='".Database::escape_string($id)."' ORDER BY question_order"; + if ($object=Database::fetch_object($result)) { + $this->id = $id; + $this->exercise = $object->title; + $this->description = $object->description; + $this->sound = $object->sound; + $this->type = $object->type; + $this->random = $object->random; + $this->random_answers = $object->random_answers; + $this->active = $object->active; + $this->results_disabled = $object->results_disabled; + $this->attempts = $object->max_attempt; + $this->feedbacktype = $object->feedback_type; + + if ($object->end_time != '0000-00-00 00:00:00') { + $this->end_time = api_get_local_time($object->end_time); + } + if ($object->start_time != '0000-00-00 00:00:00') { + $this->start_time = api_get_local_time($object->start_time); + } + $this->expired_time = $object->expired_time; //control time + + $sql="SELECT question_id, question_order FROM $TBL_EXERCICE_QUESTION, $TBL_QUESTIONS WHERE question_id=id AND exercice_id='".Database::escape_string($id)."' ORDER BY question_order"; + $result=Database::query($sql); // fills the array with the question ID for this exercise // the key of the array is the question position - while($object=Database::fetch_object($result)) - { - // makes sure that the question position is unique - while(isset($this->questionList[$object->question_order])) - { - $object->question_order++; - } - - $this->questionList[$object->question_order]=$object->question_id; + + while ($new_object = Database::fetch_object($result)) { + $this->questionList[$new_object->question_order]= $new_object->question_id; } - //var_dump($this->end_time,$object->start_time); - if($this->random > 0){ - $this->questionList = $this->selectRandomList(); - } + //overload questions list with recorded questions list //load questions only for exercises of type 'one question per page' //this is needed only is there is no questions // - if ($this->type == 2 && $_configuration['live_exercise_tracking'] && $_SERVER['REQUEST_METHOD'] != 'POST' && defined('QUESTION_LIST_ALREADY_LOGGED')) - { + // @todo not sure were in the code this is used + global $_configuration, $questionList; + if ($this->type == 2 && $_configuration['live_exercise_tracking'] && $_SERVER['REQUEST_METHOD'] != 'POST' && defined('QUESTION_LIST_ALREADY_LOGGED')) { //if(empty($_SESSION['questionList'])) $this->questionList = $questionList; } return true; } - // exercise not found return false; } @@ -136,8 +130,7 @@ class Exercise * @author - Olivier Brouckaert * @return - integer - exercise ID */ - function selectId() - { + function selectId() { return $this->id; } @@ -147,8 +140,7 @@ class Exercise * @author - Olivier Brouckaert * @return - string - exercise title */ - function selectTitle() - { + function selectTitle() { return $this->exercise; } @@ -157,8 +149,7 @@ class Exercise * * @return - numeric - exercise attempts */ - function selectAttempts() - { + function selectAttempts() { return $this->attempts; } @@ -166,8 +157,7 @@ class Exercise * 0=>Feedback , 1=>DirectFeedback, 2=>NoFeedback * @return - numeric - exercise attempts */ - function selectFeedbackType() - { + function selectFeedbackType() { return $this->feedbacktype; } @@ -175,8 +165,7 @@ class Exercise /** * returns the time limit */ - function selectTimeLimit() - { + function selectTimeLimit() { return $this->timeLimit; } @@ -186,8 +175,7 @@ class Exercise * @author - Olivier Brouckaert * @return - string - exercise description */ - function selectDescription() - { + function selectDescription() { return $this->description; } @@ -197,8 +185,7 @@ class Exercise * @author - Olivier Brouckaert * @return - string - exercise description */ - function selectSound() - { + function selectSound() { return $this->sound; } @@ -208,8 +195,7 @@ class Exercise * @author - Olivier Brouckaert * @return - integer - exercise type */ - function selectType() - { + function selectType() { return $this->type; } @@ -219,8 +205,7 @@ class Exercise * @author - Carlos Vargas * @return - integer - results disabled exercise */ - function selectResultsDisabled() - { + function selectResultsDisabled() { return $this->results_disabled; } @@ -230,12 +215,10 @@ class Exercise * @author - Olivier Brouckaert * @return - integer - 0 if not random, otherwise the draws */ - function isRandom() - { + function isRandom() { if($this->random > 0){ return true; - } - else{ + } else { return false; } } @@ -245,11 +228,8 @@ class Exercise * * @author - Juan Carlos Ra�a */ - function selectRandomAnswers() - { - + function selectRandomAnswers() { $this->random_answers; - return $this->random_answers; } @@ -257,8 +237,7 @@ class Exercise /** * Same as isRandom() but has a name applied to values different than 0 or 1 */ - function getShuffle() - { + function getShuffle() { return $this->random; } @@ -268,8 +247,7 @@ class Exercise * @author - Olivier Brouckaert * @return - boolean - true if enabled, otherwise false */ - function selectStatus() - { + function selectStatus() { return $this->active; } @@ -279,8 +257,7 @@ class Exercise * @author - Olivier Brouckaert * @return - array - question ID list */ - function selectQuestionList() - { + function selectQuestionList() { return $this->questionList; } @@ -290,56 +267,41 @@ class Exercise * @author - Olivier Brouckaert * @return - integer - number of questions */ - function selectNbrQuestions() - { + function selectNbrQuestions() { return sizeof($this->questionList); } /** - * selects questions randomly in the question list + * Selects questions randomly in the question list * * @author - Olivier Brouckaert * @return - array - if the exercise is not set to take questions randomly, returns the question list * without randomizing, otherwise, returns the list with questions selected randomly */ - function selectRandomList() - { - $nbQuestions = $this->selectNbrQuestions(); - $temp_list = $this->questionList; - //error_log(print_r($temp_list,true)); - //error_log(count($temp_list)); - if (count($temp_list)<>0) { - shuffle($temp_list); - return array_combine(range(1,$nbQuestions),$temp_list); - } - - - $nbQuestions = $this->selectNbrQuestions(); - + function selectRandomList() { + $nbQuestions = $this->selectNbrQuestions(); + $temp_list = $this->questionList; + //Not a random exercise, or if there are not at least 2 questions - if($this->random == 0 || $nbQuestions < 2) - { + if($this->random == 0 || $nbQuestions < 2) { return $this->questionList; } - - $randQuestionList = array(); - $alreadyChosen = array(); - - for($i=0; $i < $this->random; $i++) - { - if($i < $nbQuestions){ - do - { - $rand=rand(1,$nbQuestions); - } - while(in_array($rand,$alreadyChosen)); - - $alreadyChosen[]=$rand; - $randQuestionList[$rand] = $this->questionList[$rand]; - } - } - - return $randQuestionList; + + if ($nbQuestions != 0) { + shuffle($temp_list); + $my_random_list = array_combine(range(1,$nbQuestions),$temp_list); + $my_question_list = array(); + $i = 0; + foreach ($my_random_list as $item) { + if ($i < $this->random) { + $my_question_list[$i] = $item; + } else { + break; + } + $i++; + } + return $my_question_list; + } } /** @@ -349,8 +311,7 @@ class Exercise * @param - integer $questionId - question ID * @return - boolean - true if in the list, otherwise false */ - function isInList($questionId) - { + function isInList($questionId) { if (is_array($this->questionList)) return in_array($questionId,$this->questionList); else @@ -363,8 +324,7 @@ class Exercise * @author - Olivier Brouckaert * @param - string $title - exercise title */ - function updateTitle($title) - { + function updateTitle($title) { $this->exercise=$title; } @@ -373,8 +333,7 @@ class Exercise * * @param - numeric $attempts - exercise max attempts */ - function updateAttempts($attempts) - { + function updateAttempts($attempts) { $this->attempts=$attempts; } @@ -384,8 +343,7 @@ class Exercise * * @param - numeric $attempts - exercise max attempts */ - function updateFeedbackType($feedback_type) - { + function updateFeedbackType($feedback_type) { $this->feedbacktype=$feedback_type; } @@ -395,8 +353,7 @@ class Exercise * @author - Olivier Brouckaert * @param - string $description - exercise description */ - function updateDescription($description) - { + function updateDescription($description) { $this->description=$description; } @@ -406,8 +363,7 @@ class Exercise * @author - Isaac flores * @param - int The expired time of the quiz */ - function updateExpiredTime($expired_time) - { + function updateExpiredTime($expired_time) { $this->expired_time = $expired_time; } @@ -418,45 +374,39 @@ class Exercise * @param - string $sound - exercise sound file * @param - string $delete - ask to delete the file */ - function updateSound($sound,$delete) - { + function updateSound($sound,$delete) { global $audioPath, $documentPath,$_course, $_user; $TBL_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT); $TBL_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY); - if($sound['size'] && (strstr($sound['type'],'audio') || strstr($sound['type'],'video'))) - { + if ($sound['size'] && (strstr($sound['type'],'audio') || strstr($sound['type'],'video'))) { $this->sound=$sound['name']; - if(@move_uploaded_file($sound['tmp_name'],$audioPath.'/'.$this->sound)) - { + if (@move_uploaded_file($sound['tmp_name'],$audioPath.'/'.$this->sound)) { $query="SELECT 1 FROM $TBL_DOCUMENT " ." WHERE path='".str_replace($documentPath,'',$audioPath).'/'.$this->sound."'"; $result=Database::query($query); - if(!Database::num_rows($result)) - { - /*$query="INSERT INTO $TBL_DOCUMENT(path,filetype) VALUES " - ." ('".str_replace($documentPath,'',$audioPath).'/'.$this->sound."','file')"; - Database::query($query);*/ - $id = add_document($_course,str_replace($documentPath,'',$audioPath).'/'.$this->sound,'file',$sound['size'],$sound['name']); - - //$id = Database::insert_id(); - //$time = time(); - //$time = date("Y-m-d H:i:s", $time); - // insert into the item_property table, using default visibility of "visible" - /*$query = "INSERT INTO $TBL_ITEM_PROPERTY " - ."(tool, ref, insert_user_id,to_group_id, insert_date, lastedit_date, lastedit_type) " - ." VALUES " - ."('".TOOL_DOCUMENT."', $id, $_user['user_id'], 0, '$time', '$time', 'DocumentAdded' )"; - Database::query($query);*/ - api_item_property_update($_course, TOOL_DOCUMENT, $id, 'DocumentAdded',$_user['user_id']); - item_property_update_on_folder($_course,str_replace($documentPath,'',$audioPath),$_user['user_id']); + if(!Database::num_rows($result)) { + /*$query="INSERT INTO $TBL_DOCUMENT(path,filetype) VALUES " + ." ('".str_replace($documentPath,'',$audioPath).'/'.$this->sound."','file')"; + Database::query($query);*/ + $id = add_document($_course,str_replace($documentPath,'',$audioPath).'/'.$this->sound,'file',$sound['size'],$sound['name']); + + //$id = Database::insert_id(); + //$time = time(); + //$time = date("Y-m-d H:i:s", $time); + // insert into the item_property table, using default visibility of "visible" + /*$query = "INSERT INTO $TBL_ITEM_PROPERTY " + ."(tool, ref, insert_user_id,to_group_id, insert_date, lastedit_date, lastedit_type) " + ." VALUES " + ."('".TOOL_DOCUMENT."', $id, $_user['user_id'], 0, '$time', '$time', 'DocumentAdded' )"; + Database::query($query);*/ + api_item_property_update($_course, TOOL_DOCUMENT, $id, 'DocumentAdded',$_user['user_id']); + item_property_update_on_folder($_course,str_replace($documentPath,'',$audioPath),$_user['user_id']); } } - } - elseif($delete && is_file($audioPath.'/'.$this->sound)) - { + } elseif($delete && is_file($audioPath.'/'.$this->sound)) { $this->sound=''; } } @@ -467,8 +417,7 @@ class Exercise * @author - Olivier Brouckaert * @param - integer $type - exercise type */ - function updateType($type) - { + function updateType($type) { $this->type=$type; } @@ -479,8 +428,7 @@ class Exercise * @author - Olivier Brouckaert * @param - integer $random - 0 if not random, otherwise the draws */ - function setRandom($random) - { + function setRandom($random) { $this->random=$random; } @@ -491,8 +439,7 @@ class Exercise * @author - Juan Carlos Ra�a * @param - integer $random_answers - random answers */ - function updateRandomAnswers($random_answers) - { + function updateRandomAnswers($random_answers) { $this->$random_answers = $random_answers; } @@ -501,8 +448,7 @@ class Exercise * * @author - Olivier Brouckaert */ - function enable() - { + function enable() { $this->active=1; } @@ -511,13 +457,11 @@ class Exercise * * @author - Olivier Brouckaert */ - function disable() - { + function disable() { $this->active=0; } - function disable_results() - { + function disable_results() { $this->results_disabled = true; } @@ -540,38 +484,37 @@ class Exercise * * @author - Olivier Brouckaert */ - function save($type_e='') - { + function save($type_e='') { global $_course,$_user; $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST); $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION); $TBL_QUIZ_QUESTION= Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); - $id = $this->id; - $exercise = $this->exercise; - $description = $this->description; - $sound = $this->sound; - $type = $this->type; - $attempts = $this->attempts; - $feedbacktype = $this->feedbacktype; - $random = $this->random; + $id = $this->id; + $exercise = $this->exercise; + $description = $this->description; + $sound = $this->sound; + $type = $this->type; + $attempts = $this->attempts; + $feedbacktype = $this->feedbacktype; + $random = $this->random; $random_answers = $this->random_answers; - $active = $this->active; - $session_id = api_get_session_id(); - $expired_time = $this->expired_time; + $active = $this->active; + $session_id = api_get_session_id(); if ($feedbacktype==1){ $results_disabled = 1; } else { $results_disabled = intval($this->results_disabled); } - $start_time = Database::escape_string($this->start_time); - $end_time = Database::escape_string($this->end_time); + + $expired_time = intval($this->expired_time); + $start_time = Database::escape_string(api_get_utc_datetime($this->start_time)); + $end_time = Database::escape_string(api_get_utc_datetime($this->end_time)); - // exercise already exists + // Exercise already exists if($id) { - $sql="UPDATE $TBL_EXERCICES SET title='".Database::escape_string($exercise)."', description='".Database::escape_string($description)."'"; @@ -747,8 +690,7 @@ class Exercise * @author - Olivier Brouckaert * @param - integer $id - question ID to move down */ - function moveDown($id) - { + function moveDown($id) { // there is a bug with some version of PHP with the key and prev functions // the script commented was tested in dev.dokeos.com with no success // Instead of using prev and next this was change with arrays. @@ -783,22 +725,18 @@ class Exercise */ $question_list =array(); - foreach($this->questionList as $position=>$questionId) - { + foreach($this->questionList as $position=>$questionId) { $question_list[]= $questionId; } $len=count($question_list); $orderlist=array_keys($this->questionList); - for($i=0;$i<$len;$i++) - { + for($i=0;$i<$len;$i++) { $questionId = $question_list[$i]; - if($questionId == $id) - { + if($questionId == $id) { $pos1=$orderlist[$i+1]; $pos2 =$orderlist[$i]; - if(!$pos2) - { + if(!$pos2) { //echo 'cant move!'; } break; @@ -818,27 +756,19 @@ class Exercise * @param - integer $questionId - question ID * @return - boolean - true if the question has been added, otherwise false */ - function addToList($questionId) - { + function addToList($questionId) { // checks if the question ID is not in the list - if(!$this->isInList($questionId)) - { + if(!$this->isInList($questionId)) { // selects the max position - if(!$this->selectNbrQuestions()) - { + if(!$this->selectNbrQuestions()) { $pos=1; - } - else - { + } else { if (is_array($this->questionList)) $pos=max(array_keys($this->questionList))+1; } - $this->questionList[$pos]=$questionId; - return true; } - return false; } @@ -849,18 +779,14 @@ class Exercise * @param - integer $questionId - question ID * @return - boolean - true if the question has been removed, otherwise false */ - function removeFromList($questionId) - { + function removeFromList($questionId) { // searches the position of the question ID in the list $pos=array_search($questionId,$this->questionList); // question not found - if($pos === false) - { + if($pos === false) { return false; - } - else - { + } else { // deletes the position from the array containing the wanted question ID unset($this->questionList[$pos]); @@ -874,7 +800,7 @@ class Exercise * * @author - Olivier Brouckaert */ - function delete(){ + function delete() { global $_course,$_user; $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST); $sql="UPDATE $TBL_EXERCICES SET active='-1' WHERE id='".Database::escape_string($this->id)."'"; @@ -890,8 +816,7 @@ class Exercise * Creates the form to create / edit an exercise * @param FormValidator $form the formvalidator instance (by reference) */ - function createForm ($form, $type='full') - { + function createForm ($form, $type='full') { global $id; if(empty($type)){ $type='full'; @@ -1017,7 +942,6 @@ class Exercise $check_option=$this -> selectType(); - // var_dump($check_option); if ($check_option==1 && isset($_GET['exerciseId'])) { $diplay = 'none'; @@ -1146,8 +1070,7 @@ class Exercise * function which process the creation of exercises * @param FormValidator $form the formvalidator instance */ - function processCreation($form,$type='') - { + function processCreation($form,$type='') { $this -> updateTitle($form -> getSubmitValue('exerciseTitle')); $this -> updateDescription($form -> getSubmitValue('exerciseDescription')); @@ -1170,11 +1093,10 @@ class Exercise } if($form -> getSubmitValue('enabletimercontrol') == 1) { - $expired_total_time = $form -> getSubmitValue('enabletimercontroltotalminutes'); - if ($this->expired_time == 0) { - $this->expired_time = $expired_total_time; - } - + $expired_total_time = $form -> getSubmitValue('enabletimercontroltotalminutes'); + if ($this->expired_time == 0) { + $this->expired_time = $expired_total_time; + } } else { $this->expired_time = 0; } @@ -1448,10 +1370,610 @@ class Exercise * * @param - string $status - exercise status */ - function updateStatus($status) - { + function updateStatus($status) { $this->active = $status; } + + public function get_stat_track_exercise_info($lp_id = 0, $lp_item_id = 0) { + $track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + if (empty($lp_id)) { + $lp_id = 0; + } + if (empty($lp_item_id)) { + $lp_item_id = 0; + } + $condition = ' WHERE exe_exo_id = ' . "'" . $this->id . "'" .' AND + exe_user_id = ' . "'" . api_get_user_id() . "'" . ' AND + exe_cours_id = ' . "'" . api_get_course_id() . "'" . ' AND + status = ' . "'incomplete'" . ' AND + orig_lp_id = ' . "'" . $lp_id . "'" . ' AND + orig_lp_item_id = ' . "'" . $lp_item_id . "'" . ' AND + session_id = ' . "'" . api_get_session_id() . "' LIMIT 1"; //Adding limit 1 just in case + + $sql_track = 'SELECT * FROM '.$track_exercises.$condition; + + $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 save_stat_track_exercise_info($clock_expired_time = 0, $safe_lp_id = 0, $safe_lp_item_id = 0, $questionList = array()) { + $track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + + if (empty($safe_lp_id)) { + $safe_lp_id = 0; + } + if (empty($safe_lp_item_id)) { + $safe_lp_item_id = 0; + } + if (empty($clock_expired_time)) { + $clock_expired_time = 0; + } + if ($this->expired_time != 0) { + $sql_fields = "expired_time_control, "; + $sql_fields_values = "'"."$clock_expired_time"."',"; + } else { + $sql_fields = ""; + $sql_fields_values = ""; + } + 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) + 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)"; + } 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)"; + } + Database::query($sql); + } + + public function show_button($nbrQuestions, $questionNum) { + $html = ''; + $html = '
'; + $confirmation_alert = $this->type == 1? " onclick=\"javascript:if(!confirm('".get_lang("ConfirmYourChoice")."')) return false;\" ":""; + $submit_btn = ''; + if ($this->expired_time != 0) { + $html .= $submit_btn =''; + } else { + $html .= $submit_btn; + } + } + } + $html .= '
'; //margin top -10 + return $html; + } + + + /** + * So the time control will work + */ + public function show_time_control_js($time_left) { + $time_left = intval($time_left); + return ""; + } + + /** + * Lp javascript for hotspots + */ + public function show_lp_javascript() { + + return " + + + + + "; + } + + + function manage_answer($exeId, $questionId, $choice) { + global $_configuration; + $exeId = intval($exeId); + //require_once 'question.class.php'; + //require_once 'answer.class.php'; + + // Creates a temporary Question object + $objQuestionTmp = Question :: read($questionId); + + $questionName = $objQuestionTmp->selectTitle(); + $questionDescription = $objQuestionTmp->selectDescription(); + $questionWeighting = $objQuestionTmp->selectWeighting(); + $answerType = $objQuestionTmp->selectType(); + $quesId = $objQuestionTmp->selectId(); //added by priya saini + $totalWeighting = 0; + $totalScore = 0; + + // Destruction of the Question object + unset ($objQuestionTmp); + error_log('$questionWeighting '.$questionWeighting); + + if (isset ($_POST['hotspot']) && isset($_POST['hotspot'][$questionId])) { + $exerciseResultCoordinates[$questionId] = $_POST['hotspot'][$questionId]; + } + + // construction of the Answer object + $objAnswerTmp = new Answer($questionId); + $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); + $questionScore = 0; + if ($answerType == FREE_ANSWER) { + $nbrAnswers = 1; + } + $real_answers = array(); + for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { + $answer = $objAnswerTmp->selectAnswer($answerId); + $answerComment = $objAnswerTmp->selectComment($answerId); + $answerCorrect = $objAnswerTmp->isCorrect($answerId); + $answerWeighting = $objAnswerTmp->selectWeighting($answerId); + $numAnswer=$objAnswerTmp->selectAutoId($answerId); + switch ($answerType) { + // for unique answer + case UNIQUE_ANSWER : + $studentChoice=($choice == $numAnswer)?1:0; + if ($studentChoice) { + $questionScore+=$answerWeighting; + $totalScore+=$answerWeighting; + } + break; + // for multiple answers + case MULTIPLE_ANSWER : + $studentChoice=$choice[$numAnswer]; + if ($studentChoice) { + $questionScore+=$answerWeighting; + $totalScore+=$answerWeighting; + } + break; + case MULTIPLE_ANSWER_COMBINATION: + $studentChoice=$choice[$numAnswer]; + + if ($answerCorrect == 1) { + if ($studentChoice) { + $real_answers[$answerId] = true; + } else { + $real_answers[$answerId] = false; + } + } else { + if ($studentChoice) { + $real_answers[$answerId] = false; + } else { + $real_answers[$answerId] = true; + } + } + + $final_answer = true; + foreach($real_answers as $my_answer) { + if (!$my_answer) { + $final_answer = false; + } + } + break; + // for fill in the blanks + case FILL_IN_BLANKS : + + // the question is encoded like this + // [A] B [C] D [E] F::10,10,10@1 + // number 1 before the "@" means that is a switchable fill in blank question + // [A] B [C] D [E] F::10,10,10@ or [A] B [C] D [E] F::10,10,10 + // means that is a normal fill blank question + + // first we explode the "::" + $pre_array = explode('::', $answer); + + // is switchable fill blank or not + $last = count($pre_array) - 1; + $is_set_switchable = explode('@', $pre_array[$last]); + + $switchable_answer_set = false; + if (isset ($is_set_switchable[1]) && $is_set_switchable[1] == 1) { + $switchable_answer_set = true; + } + + $answer = ''; + for ($k = 0; $k < $last; $k++) { + $answer .= $pre_array[$k]; + } + + // splits weightings that are joined with a comma + $answerWeighting = explode(',', $is_set_switchable[0]); + + // we save the answer because it will be modified + //$temp = $answer; + $temp = text_filter($answer); + + /* // Deprecated code + // TeX parsing + // 1. find everything between the [tex] and [/tex] tags + $startlocations = api_strpos($temp, '[tex]'); + $endlocations = api_strpos($temp, '[/tex]'); + + if ($startlocations !== false && $endlocations !== false) { + $texstring = api_substr($temp, $startlocations, $endlocations - $startlocations +6); + // 2. replace this by {texcode} + $temp = str_replace($texstring, '{texcode}', $temp); + } + */ + + $answer = ''; + $j = 0; + + //initialise answer tags + $user_tags = array (); + $correct_tags = array (); + $real_text = array (); + // the loop will stop at the end of the text + while (1) { + // quits the loop if there are no more blanks (detect '[') + if (($pos = api_strpos($temp, '[')) === false) { + // adds the end of the text + $answer = $temp; + /* // Deprecated code + // TeX parsing - replacement of texcode tags + $texstring = api_parse_tex($texstring); + $answer = str_replace("{texcode}", $texstring, $answer); + */ + $real_text[] = $answer; + break; //no more "blanks", quit the loop + } + // adds the piece of text that is before the blank + //and ends with '[' into a general storage array + $real_text[] = api_substr($temp, 0, $pos +1); + $answer .= api_substr($temp, 0, $pos +1); + //take the string remaining (after the last "[" we found) + $temp = api_substr($temp, $pos +1); + // quit the loop if there are no more blanks, and update $pos to the position of next ']' + if (($pos = api_strpos($temp, ']')) === false) { + // adds the end of the text + $answer .= $temp; + break; + } + $choice[$j] = trim($choice[$j]); + $user_tags[] = api_strtolower($choice[$j]); + //put the contents of the [] answer tag into correct_tags[] + $correct_tags[] = api_strtolower(substr($temp, 0, $pos)); + $j++; + $temp = api_substr($temp, $pos +1); + //$answer .= ']'; + } + + $answer = ''; + $real_correct_tags = $correct_tags; + $chosen_list = array (); + + for ($i = 0; $i < count($real_correct_tags); $i++) { + if ($i == 0) { + $answer .= $real_text[0]; + } + + if (!$switchable_answer_set) { + //needed to parse ' and " characters + $user_tags[$i] = stripslashes($user_tags[$i]); + if ($correct_tags[$i] == $user_tags[$i]) { + // gives the related weighting to the student + $questionScore += $answerWeighting[$i]; + // increments total score + $totalScore += $answerWeighting[$i]; + // adds the word in green at the end of the string + $answer .= $correct_tags[$i]; + } + // else if the word entered by the student IS NOT the same as the one defined by the professor + elseif (!empty ($user_tags[$i])) { + // adds the word in red at the end of the string, and strikes it + $answer .= '' . $user_tags[$i] . ''; + } else { + // adds a tabulation if no word has been typed by the student + $answer .= '   '; + } + } else { + // switchable fill in the blanks + if (in_array($user_tags[$i], $correct_tags)) { + $chosen_list[] = $user_tags[$i]; + $correct_tags = array_diff($correct_tags, $chosen_list); + + // gives the related weighting to the student + $questionScore += $answerWeighting[$i]; + // increments total score + $totalScore += $answerWeighting[$i]; + // adds the word in green at the end of the string + $answer .= $user_tags[$i]; + } + elseif (!empty ($user_tags[$i])) { + // else if the word entered by the student IS NOT the same as the one defined by the professor + // adds the word in red at the end of the string, and strikes it + $answer .= '' . $user_tags[$i] . ''; + } else { + // adds a tabulation if no word has been typed by the student + $answer .= '   '; + } + } + // adds the correct word, followed by ] to close the blank + $answer .= ' / ' . $real_correct_tags[$i] . ']'; + if (isset ($real_text[$i +1])) { + $answer .= $real_text[$i +1]; + } + } + + break; + // for free answer + case FREE_ANSWER : + $studentChoice = $choice; + + if ($studentChoice) { + //Score is at -1 because the question has'nt been corected + $questionScore = -1; + $totalScore += 0; + } + break; + // for matching + case MATCHING : + + $numAnswer=$objAnswerTmp->selectAutoId($answerId); + if ($answerCorrect) { + if ($answerCorrect == $choice[$numAnswer]) { + $questionScore+=$answerWeighting; + $totalScore+=$answerWeighting; + } + $matching[$numAnswer] = $choice[$numAnswer]; + } + break; + // for hotspot with no order + case HOT_SPOT : + $studentChoice = $choice[$answerId]; + if ($studentChoice) { + $questionScore += $answerWeighting; + $totalScore += $answerWeighting; + } + break; + // for hotspot with fixed order + case HOT_SPOT_ORDER : + $studentChoice = $choice['order'][$answerId]; + + if ($studentChoice == $answerId) { + $questionScore += $answerWeighting; + $totalScore += $answerWeighting; + $studentChoice = true; + } else { + $studentChoice = false; + } + break; + } // end switch Answertype + } // end for that loops over all answers of the current question + + // destruction of Answer + + //we add the total score after dealing with the answers + if ($answerType == MULTIPLE_ANSWER_COMBINATION) { + if ($final_answer) { + //getting only the first score where we save the weight of all the question + $answerWeighting=$objAnswerTmp->selectWeighting(1); + $questionScore+=$answerWeighting; + $totalScore+=$answerWeighting; + } + } + unset ($objAnswerTmp); + $i++; + + $totalWeighting += $questionWeighting; + //added by priya saini + // Store results directly in the database + // For all in one page exercises, the results will be + // stored by exercise_results.php (using the session) + if ($_configuration['tracking_enabled']) { + if (empty ($choice)) { + $choice = 0; + } + if ($answerType == MULTIPLE_ANSWER) { + if ($choice != 0) { + $reply = array_keys($choice); + for ($i = 0; $i < sizeof($reply); $i++) { + $ans = $reply[$i]; + exercise_attempt($questionScore, $ans, $quesId, $exeId, $i, $this->id); + } + } else { + exercise_attempt($questionScore, 0, $quesId, $exeId, 0, $this->id); + } + } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { + if ($choice != 0) { + $reply = array_keys($choice); + for ($i = 0; $i < sizeof($reply); $i++) { + $ans = $reply[$i]; + exercise_attempt($questionScore, $ans, $quesId, $exeId, $i, $this->id); + } + } else { + exercise_attempt($questionScore, 0, $quesId, $exeId, 0, $this->id); + } + } elseif ($answerType == MATCHING) { + foreach ($matching as $j => $val) { + exercise_attempt($questionScore, $val, $quesId, $exeId, $j, $this->id); + } + } elseif ($answerType == FREE_ANSWER) { + $answer = $choice; + exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $this->id); + } elseif ($answerType == UNIQUE_ANSWER) { + $answer = $choice; + exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $this->id); + } elseif ($answerType == HOT_SPOT) { + exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $this->id); + if (is_array($exerciseResultCoordinates[$questionId])) { + foreach($exerciseResultCoordinates[$questionId] as $idx => $val) { + exercise_attempt_hotspot($exeId,$quesId,$idx,$choice[$idx],$val,$this->id); + } + } + } else { + exercise_attempt($questionScore, $answer, $quesId, $exeId, 0,$this->id); + } + } + $stat_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + $sql_update = 'UPDATE ' . $stat_table . ' SET exe_result = exe_result + ' . (int) $totalScore . ',exe_weighting = exe_weighting + ' . (int) $totalWeighting . ' WHERE exe_id = ' . $exeId; + Database::query($sql_update); + + + } //End function } endif; ?> \ No newline at end of file diff --git a/main/exercice/exercise.lib.php b/main/exercice/exercise.lib.php index 8148b59c98..e4e57c387f 100755 --- a/main/exercice/exercise.lib.php +++ b/main/exercice/exercise.lib.php @@ -27,11 +27,6 @@ function showQuestion($questionId, $onlyAnswers = false, $origin = false, $curre // Change false to true in the following line to enable answer hinting. $debug_mark_answer = api_is_allowed_to_edit() && false; - if (!ereg("MSIE", $_SERVER["HTTP_USER_AGENT"])) { - //echo ''; - //echo ''; - } - // Reads question informations. if (!$objQuestionTmp = Question::read($questionId)) { // question not found @@ -49,8 +44,7 @@ function showQuestion($questionId, $onlyAnswers = false, $origin = false, $curre $questionName=text_filter($questionName); - $s="
- ".get_lang('Question').' '; + $s="
".get_lang('Question').' '; $s.=$current_item; //@todo I need the get the feedback type @@ -541,4 +535,69 @@ function showQuestion($questionId, $onlyAnswers = false, $origin = false, $curre } echo '
'; return $nbrAnswers; -} \ No newline at end of file +} + + +function get_exercise_track_exercise_info($exe_id) { + $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST); + $TBL_TRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + + $sql_fb_type='SELECT * FROM '.$TBL_EXERCICES.' as e INNER JOIN '.$TBL_TRACK_EXERCICES.' as te ON (e.id=te.exe_exo_id) WHERE te.exe_id='.Database::escape_string($exe_id); + $res_fb_type=Database::query($sql_fb_type); + $row_fb_type=Database::fetch_array($res_fb_type, 'ASSOC'); + return $row_fb_type; +} + + +/** + * Validates the time control key + */ +function exercise_time_control_is_valid($exercise_id) { + //Fast check + $exercise_id = intval($exercise_id); + $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST); + $sql = "SELECT expired_time FROM $TBL_EXERCICES WHERE id = $exercise_id"; + $result = Database::query($sql); + $row = Database::fetch_array($result, 'ASSOC'); + if (!empty($row['expired_time']) ) { + $current_expired_time_key = get_time_control_key($exercise_id); + if (isset($_SESSION['expired_time'][$current_expired_time_key])) { + $current_time = time(); + $expired_time = api_strtotime($_SESSION['expired_time'][$current_expired_time_key], 'UTC'); + $total_time_allowed = $expired_time + 30; + //error_log('expired time converted + 30: '.$total_time_allowed); + //error_log('$current_time: '.$current_time); + if ($total_time_allowed < $current_time) { + return false; + } + return true; + } else { + return false; + } + } else { + return true; + } +} + +/** + Deletes the time control token +*/ +function exercise_time_control_delete($exercise_id) { + $current_expired_time_key = get_time_control_key($exercise_id); + unset($_SESSION['expired_time'][$current_expired_time_key]); +} + +/** + Generates the time control key +*/ +function generate_time_control_key($exercise_id) { + $exercise_id = intval($exercise_id); + return api_get_course_int_id().'_'.api_get_session_id().'_'.$exercise_id.'_'.api_get_user_id(); +} +/** + Returns the time controller key +*/ +function get_time_control_key($exercise_id){ + $exercise_id = intval($exercise_id); + return api_get_course_int_id().'_'.api_get_session_id().'_'.$exercise_id.'_'.api_get_user_id(); +} diff --git a/main/exercice/exercise_admin.php b/main/exercice/exercise_admin.php index 370262eae7..6b1452881b 100755 --- a/main/exercice/exercise_admin.php +++ b/main/exercice/exercise_admin.php @@ -12,11 +12,11 @@ // name of the language file that needs to be included $language_file='exercice'; -include('exercise.class.php'); -include('question.class.php'); -include('answer.class.php'); -include('../inc/global.inc.php'); -include('exercise.lib.php'); +include 'exercise.class.php'; +include 'question.class.php'; +include 'answer.class.php'; +include '../inc/global.inc.php'; +include 'exercise.lib.php'; $this_section=SECTION_COURSES; if(!api_is_allowed_to_edit(null,true)) { diff --git a/main/exercice/exercise_result.php b/main/exercice/exercise_result.php index 418fa85d41..9e8b133463 100755 --- a/main/exercice/exercise_result.php +++ b/main/exercice/exercise_result.php @@ -15,9 +15,10 @@ * @todo split more code up in functions, move functions to library? */ /* INIT SECTION */ -require_once('exercise.class.php'); -require_once('question.class.php'); -require_once('answer.class.php'); +require_once 'exercise.class.php'; +require_once 'exercise.lib.php'; +require_once 'question.class.php'; +require_once 'answer.class.php'; if ($_GET['origin']=='learnpath') { require_once ('../newscorm/learnpath.class.php'); @@ -98,6 +99,8 @@ if ( empty ( $exerciseType ) ) { $exerciseType = $_REQUEST['exerciseType']; } + +//@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); @@ -150,126 +153,13 @@ if (!empty($gradebook) && $gradebook=='view') { $nameTools=get_lang('Exercice'); $interbreadcrumb[]=array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices')); -$htmlHeadXtra[] = " - - - - - "; +$htmlHeadXtra[] = $objExercise->show_lp_javascript(); if ($origin != 'learnpath') { //so we are not in learnpath tool Display::display_header($nameTools,"Exercise"); } else { - header('Content-Type: text/html; charset='.api_get_system_encoding()); - $document_language = api_get_language_isocode(); /* @@ -401,9 +291,7 @@ function display_hotspot_answer($answerId, $answer, $studentChoice, $answerComme
-
-
@@ -435,7 +323,7 @@ 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 '
'; - echo Display::return_icon('quiz.gif', get_lang('GoBackToEx')).''.get_lang('GoBackToEx').''; + echo Display::return_icon('back.png', get_lang('GoBackToEx')).''.get_lang('GoBackToEx').''; echo Display::return_icon('edit.gif', get_lang('ModifyExercise')).''.get_lang('ModifyExercise').''; echo '
'; } @@ -445,7 +333,7 @@ $exerciseTitle=text_filter($exerciseTitle); //show exercise title ?> -

:

+

:

@@ -710,8 +598,7 @@ foreach ($questionList as $questionId) { $correct_tags=array(); $real_text=array(); // the loop will stop at the end of the text - while(1) - { + while(1) { // quits the loop if there are no more blanks (detect '[') if(($pos = api_strpos($temp,'[')) === false) { @@ -772,9 +659,7 @@ foreach ($questionList as $questionId) { { // adds the word in red at the end of the string, and strikes it $answer.=''.$user_tags[$i].''; - } - else - { + } else { // adds a tabulation if no word has been typed by the student $answer.='   '; } @@ -791,13 +676,10 @@ foreach ($questionList as $questionId) { // adds the word in green at the end of the string $answer.=$user_tags[$i]; } // else if the word entered by the student IS NOT the same as the one defined by the professor - elseif(!empty($user_tags[$i])) - { + elseif(!empty($user_tags[$i])) { // adds the word in red at the end of the string, and strikes it $answer.=''.$user_tags[$i].''; - } - else - { + } else { // adds a tabulation if no word has been typed by the student $answer.='   '; } @@ -812,9 +694,7 @@ foreach ($questionList as $questionId) { // for free answer case FREE_ANSWER : $studentChoice=$choice; - - if($studentChoice) - { + if($studentChoice) { //Score is at -1 because the question has'nt been corected $questionScore=-1; $totalScore+=0; @@ -845,17 +725,13 @@ foreach ($questionList as $questionId) { case HOT_SPOT_ORDER : $studentChoice=$choice['order'][$answerId]; - if($studentChoice == $answerId) - { + if($studentChoice == $answerId) { $questionScore+=$answerWeighting; $totalScore+=$answerWeighting; $studentChoice = true; - } - else - { + } else { $studentChoice = false; } - break; } // end switch Answertype @@ -871,28 +747,18 @@ foreach ($questionList as $questionId) { } } elseif($answerType == FREE_ANSWER) { // to store the details of open questions in an array to be used in mail - $arrques[] = $questionName; $arrans[] = $choice; - - if($origin != 'learnpath') { display_free_answer($choice); } - - } - elseif($answerType == HOT_SPOT) - { + } elseif($answerType == HOT_SPOT) { if ($origin != 'learnpath') { display_hotspot_answer($answerId, $answer, $studentChoice, $answerComment); } - } - elseif($answerType == HOT_SPOT_ORDER) - { + } elseif($answerType == HOT_SPOT_ORDER) { display_hotspot_order_answer($answerId, $answer, $studentChoice, $answerComment); - } - elseif($answerType==MATCHING) - { + } elseif($answerType==MATCHING) { if ($origin != 'learnpath') { echo ''; echo ''.text_filter($answer_matching[$answerId]).''.text_filter($user_answer).' / '.text_filter($answer_matching[$answerCorrect]).''; @@ -970,43 +836,43 @@ foreach ($questionList as $questionId) { $reply = array_keys($choice); for ($i=0;$iid); } } else { - exercise_attempt($questionScore, 0 ,$quesId,$exeId,0); + exercise_attempt($questionScore, 0 ,$quesId,$exeId,0, $objExercise->id); } } elseif ($answerType==MULTIPLE_ANSWER_COMBINATION ) { if ($choice != 0) { $reply = array_keys($choice); for ($i=0;$iid); } } else { - exercise_attempt($questionScore, 0 ,$quesId,$exeId,0); + exercise_attempt($questionScore, 0 ,$quesId,$exeId,0, $objExercise->id); } } elseif ($answerType==MATCHING) { foreach ($matching as $j => $val) { - exercise_attempt($questionScore, $val, $quesId, $exeId, $j); + exercise_attempt($questionScore, $val, $quesId, $exeId, $j, $objExercise->id); } } elseif ($answerType==FREE_ANSWER) { $answer = $choice; - exercise_attempt($questionScore,$answer,$quesId,$exeId,0); + exercise_attempt($questionScore,$answer,$quesId,$exeId,0, $objExercise->id); } elseif ($answerType==UNIQUE_ANSWER) { // exercise_attempt($questionScore,$answer,$quesId,$exeId,0); // In fact, we are not storing the results by answer ID, but by *position*, which is stored in $choice - exercise_attempt($questionScore,$choice,$quesId,$exeId,0); + exercise_attempt($questionScore,$choice,$quesId,$exeId,0, $objExercise->id); } elseif ($answerType == HOT_SPOT) { - exercise_attempt($questionScore, $answer, $quesId, $exeId, 0); + exercise_attempt($questionScore, $answer, $quesId, $exeId, 0, $objExercise->id); if (is_array($exerciseResultCoordinates[$quesId])) { foreach($exerciseResultCoordinates[$quesId] as $idx => $val) { - exercise_attempt_hotspot($exeId,$quesId,$idx,$choice[$idx],$val); + exercise_attempt_hotspot($exeId,$quesId,$idx,$choice[$idx],$val, $objExercise->id); } } } else { - exercise_attempt($questionScore,$answer,$quesId,$exeId,0); + exercise_attempt($questionScore,$answer,$quesId,$exeId,0, $objExercise->id); } } } // end huge foreach() block that loops over all questions @@ -1042,9 +908,7 @@ foreach ($questionList as $questionId) { results_disabled) { echo ''."\n"; echo ''; } - } if ($origin != 'learnpath') { @@ -1125,7 +988,6 @@ if($num>1) { //this is a problem (it means that there is no admin for this course) } - // we are able to send emails to the teachers? if (api_get_course_setting('email_alert_manager_on_new_quiz') == 1 ) { // only for "simple tests" @@ -1182,7 +1044,6 @@ if (api_get_course_setting('email_alert_manager_on_new_quiz') == 1 ) { $msg1= str_replace("#i#",$i,$msg); $msg= str_replace("#course#",$courseName,$msg1); } - $msg.='
'.get_lang('ClickToCommentAndGiveFeedback').',
#url#
'; diff --git a/main/exercice/exercise_show.php b/main/exercice/exercise_show.php index 2a5551dc86..978b77adc8 100755 --- a/main/exercice/exercise_show.php +++ b/main/exercice/exercise_show.php @@ -17,6 +17,7 @@ require_once '../inc/global.inc.php'; require_once '../inc/lib/course.lib.php'; // including additional libraries require_once 'exercise.class.php'; +require_once 'exercise.lib.php'; require_once 'question.class.php'; //also defines answer type constants require_once 'answer.class.php'; require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php'; @@ -80,6 +81,7 @@ if ( empty ( $questionList ) ) { if ( empty ( $objExercise ) ) { $objExercise = $_SESSION['objExercise']; } + if ( empty ( $exeId ) ) { $exeId = $_REQUEST['id']; } @@ -87,51 +89,28 @@ if ( empty ( $exeId ) ) { if ( empty ( $action ) ) { $action = $_GET['action']; } -$current_user_id = api_get_user_id(); -$current_user_id = "'".$current_user_id."'"; -$current_attempt = $_SESSION['current_exercice_attempt'][$current_user_id]; -//Is fraudulent exercice $current_time = time(); - $emailId = $_REQUEST['email']; -$user_name = $_REQUEST['user']; -$test = $_REQUEST['test']; -$dt = $_REQUEST['dt']; -$marks = $_REQUEST['res']; $id = $_REQUEST['id']; -$sql_fb_type='SELECT feedback_type, exercises.id FROM '.$TBL_EXERCICES.' as exercises, '.$TBL_TRACK_EXERCICES.' as track_exercises WHERE exercises.id=track_exercises.exe_exo_id AND track_exercises.exe_id="'.Database::escape_string($id).'"'; -$res_fb_type=Database::query($sql_fb_type); -$row_fb_type=Database::fetch_row($res_fb_type); -$feedback_type = $row_fb_type[0]; -$exercise_id = intval($row_fb_type[1]); - -$course_code = api_get_course_id(); -$session_id = api_get_session_id(); -$current_expired_time_key = $course_code.'_'.$session_id.'_'.$exercise_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]; - $expired_time = strtotime($expired_date); - - //Validation in case of fraud - $total_time_allowed = $expired_time + 30; - if ($total_time_allowed < $current_time) { - $sql_fraud = "UPDATE $TBL_TRACK_ATTEMPT SET answer = 0, marks=0, position=0 WHERE exe_id = '$current_attempt' "; - Database::query($sql_fraud); - } +if (empty($id)) { + api_not_allowed(); } +$track_exercise_info = get_exercise_track_exercise_info($id); +$exercise_id = $track_exercise_info['id']; +$course_code = api_get_course_id(); +if (!exercise_time_control_is_valid($exercise_id)) { + $sql_fraud = "UPDATE $TBL_TRACK_ATTEMPT SET answer = 0, marks=0, position=0 WHERE exe_id = '{$track_exercise_info['exe_id']}' "; + Database::query($sql_fraud); +} //Unset session for clock time -unset($_SESSION['current_exercice_attempt'][$current_user_id]); -unset($_SESSION['expired_time'][$current_expired_time_key]); -unset($_SESSION['end_expired_time'][$current_expired_time_key]); +exercise_time_control_delete($exercise_id); $is_allowedToEdit=api_is_allowed_to_edit(null,true) || $is_courseTutor; $nameTools=get_lang('CorrectTest'); - -if (isset($_SESSION['gradebook'])){ +if (isset($_SESSION['gradebook'])) { $gradebook= $_SESSION['gradebook']; } @@ -143,7 +122,6 @@ if($origin=='user_course') { $interbreadcrumb[] = array ("url" => "../user/user.php?cidReq=".Security::remove_XSS($_GET['course']), "name" => get_lang("Users")); $interbreadcrumb[] = array("url" => "../mySpace/myStudents.php?student=".Security::remove_XSS($_GET['student'])."&course=".$_course['id']."&details=true&origin=".Security::remove_XSS($_GET['origin']) , "name" => get_lang("DetailsStudentInCourse")); } else if($origin=='tracking_course') { - //$interbreadcrumb[] = array ("url" => "../mySpace/index.php", "name" => get_lang('MySpace')); //$interbreadcrumb[] = array ("url" => "../mySpace/myStudents.php?student=".Security::remove_XSS($_GET['student']).'&details=true&origin='.$origin.'&course='.Security::remove_XSS($_GET['cidReq']), "name" => get_lang("DetailsStudentInCourse")); $interbreadcrumb[] = array ("url" => api_get_path(WEB_COURSE_PATH).$_course['directory'], 'name' => $_course['title']); @@ -186,20 +164,17 @@ if ($origin != 'learnpath') { height:75px; z-index:1; } - -->