'$now' "; $sql = "SELECT COUNT(DISTINCT exe_id) FROM $track_exercise WHERE $where_condition "; $result = Database::query($sql); $count = Database::fetch_row($result); $count = $count[0]; //3. Calculating first, end, etc $total_pages = 0; if ($count > 0) { if (!empty($limit)) { $total_pages = ceil($count / $limit); } } if ($page > $total_pages) { $page = $total_pages; } $start = $limit * $page - $limit; if ($start < 0) { $start = 0; } $sql = "SELECT exe_id, exe_user_id, firstname, lastname, aa.status, start_date, exe_result, exe_weighting, exe_result/exe_weighting as score, exe_duration, questions_to_check, orig_lp_id FROM $user_table u INNER JOIN ( SELECT t.exe_id, t.exe_user_id, status, start_date, exe_result, exe_weighting, exe_result/exe_weighting as score, exe_duration, questions_to_check, orig_lp_id FROM $track_exercise t LEFT JOIN $track_attempt a ON (a.exe_id = t.exe_id AND t.exe_user_id = a.user_id) WHERE t.status = 'incomplete' AND $where_condition GROUP BY exe_user_id ) as aa ON aa.exe_user_id = user_id ORDER BY $sidx $sord LIMIT $start, $limit"; $result = Database::query($sql); $results = array(); while ($row = Database::fetch_array($result, 'ASSOC')) { $results[] = $row; } $oExe = new Exercise(); $oExe->read($exercise_id); $response = new stdClass(); $response->page = $page; $response->total = $total_pages; $response->records = $count; $i = 0; if (!empty($results)) { foreach ($results as $row) { $sql = "SELECT SUM(count_question_id) as count_question_id FROM ( SELECT 1 as count_question_id FROM $track_attempt a WHERE user_id = {$row['exe_user_id']} AND exe_id = {$row['exe_id']} GROUP by question_id ) as count_table"; $result_count = Database::query($sql); $count_questions = Database::fetch_array( $result_count, 'ASSOC' ); $count_questions = $count_questions['count_question_id']; $row['count_questions'] = $count_questions; $response->rows[$i]['id'] = $row['exe_id']; if (!empty($oExe->expired_time)) { $remaining = strtotime($row['start_date']) + ($oExe->expired_time * 60) - strtotime(api_get_utc_datetime(time())); $h = floor($remaining / 3600); $m = floor(($remaining - ($h * 3600)) / 60); $s = ($remaining - ($h * 3600) - ($m * 60)); $timeInfo = api_format_date( $row['start_date'], DATE_TIME_FORMAT_LONG ).' ['.($h > 0 ? $h.':' : '').sprintf("%02d", $m).':'.sprintf("%02d", $s).']'; } else { $timeInfo = api_format_date( $row['start_date'], DATE_TIME_FORMAT_LONG ); } $array = array( $row['firstname'], $row['lastname'], $timeInfo, $row['count_questions'], round($row['score'] * 100).'%' ); $response->rows[$i]['cell'] = $array; $i++; } } echo json_encode($response); break; case 'update_exercise_list_order': if (api_is_allowed_to_edit(null, true)) { $new_list = $_REQUEST['exercise_list']; $table = Database::get_course_table(TABLE_QUIZ_ORDER); $counter = 1; //Drop all Database::query("DELETE FROM $table WHERE session_id = $session_id AND c_id = $course_id"); //Insert all foreach ($new_list as $new_order_id) { Database::insert( $table, array( 'exercise_order' => $counter, 'session_id' => $session_id, 'exercise_id' => intval($new_order_id), 'c_id' => $course_id ) ); $counter++; } echo Display::return_message(get_lang('Saved'), 'confirmation'); } break; case 'update_question_order': $course_info = api_get_course_info_by_id($course_id); $course_id = $course_info['real_id']; $exercise_id = isset($_REQUEST['exercise_id']) ? $_REQUEST['exercise_id'] : null; if (empty($exercise_id)) { return Display::return_message(get_lang('Error'), 'error'); } if (api_is_allowed_to_edit(null, true)) { $new_question_list = $_POST['question_id_list']; $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); $counter = 1; foreach ($new_question_list as $new_order_id) { Database::update( $TBL_QUESTIONS, array('question_order' => $counter), array('question_id = ? AND c_id = ? AND exercice_id = ? ' => array(intval($new_order_id), $course_id, $exercise_id))) ; $counter++; } echo Display::return_message(get_lang('Saved'), 'confirmation'); } break; case 'add_question_to_reminder': /** @var Exercise $objExercise */ $objExercise = Session::read('objExercise'); if (empty($objExercise)) { echo 0; exit; } else { $objExercise->edit_question_to_remind( $_REQUEST['exe_id'], $_REQUEST['question_id'], $_REQUEST['action'] ); } break; case 'save_exercise_by_now': $course_info = api_get_course_info_by_id($course_id); $course_id = $course_info['real_id']; // Use have permissions? if (api_is_allowed_to_session_edit()) { // "all" or "simple" strings means that there's one or all questions exercise type $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null; // Questions choices. $choice = isset($_REQUEST['choice']) ? $_REQUEST['choice'] : null; // Hot spot coordinates from all questions. $hot_spot_coordinates = isset($_REQUEST['hotspot']) ? $_REQUEST['hotspot'] : null; // There is a reminder? $remind_list = isset($_REQUEST['remind_list']) && !empty($_REQUEST['remind_list']) ? array_keys($_REQUEST['remind_list']) : null; // Needed in manage_answer. $learnpath_id = isset($_REQUEST['learnpath_id']) ? intval($_REQUEST['learnpath_id']) : 0; $learnpath_item_id = isset($_REQUEST['learnpath_item_id']) ? intval($_REQUEST['learnpath_item_id']) : 0; // Attempt id. $exe_id = $_REQUEST['exe_id']; if ($debug) { error_log("exe_id = $exe_id"); error_log("type = $type"); error_log("choice = ".print_r($choice, 1)." "); error_log("hot_spot_coordinates = ".print_r($hot_spot_coordinates, 1)); error_log("remind_list = ".print_r($remind_list, 1)); } // Exercise information. /** @var Exercise $objExercise */ $objExercise = Session::read('objExercise'); // Question info. $question_id = isset($_REQUEST['question_id']) ? intval($_REQUEST['question_id']) : null; $question_list = Session::read('questionList'); // If exercise or question is not set then exit. if (empty($question_list) || empty($objExercise)) { echo 'error'; if ($debug) { if (empty($question_list)) { error_log("question_list is empty"); } if (empty($objExercise)) { error_log("objExercise is empty"); } } exit; } // Getting information of the current exercise. $exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); $exercise_id = $exercise_stat_info['exe_exo_id']; $attempt_list = array(); // First time here we create an attempt (getting the exe_id). if (!empty($exercise_stat_info)) { // We know the user we get the exe_id. $exe_id = $exercise_stat_info['exe_id']; $total_score = $exercise_stat_info['exe_result']; //Getting the list of attempts $attempt_list = Event::getAllExerciseEventByExeId($exe_id); } // Updating Reminder algorythm. if ($objExercise->type == ONE_PER_PAGE) { $bd_reminder_list = explode(',', $exercise_stat_info['questions_to_check']); if (empty($remind_list)) { $remind_list = $bd_reminder_list; $new_list = array(); foreach ($bd_reminder_list as $item) { if ($item != $question_id) { $new_list[] = $item; } } $remind_list = $new_list; } else { if (isset($remind_list[0])) { if (!in_array($remind_list[0], $bd_reminder_list)) { array_push($bd_reminder_list, $remind_list[0]); } $remind_list = $bd_reminder_list; } } } // No exe id? Can't save answer. if (empty($exe_id)) { // Fires an error. echo 'error'; if ($debug) { error_log("exe_id is empty"); } exit; } Session::write('exe_id', $exe_id); // Getting the total weight if the request is simple $total_weight = 0; if ($type == 'simple') { foreach ($question_list as $my_question_id) { $objQuestionTmp = Question::read($my_question_id, $course_id); $total_weight += $objQuestionTmp->selectWeighting(); } } unset($objQuestionTmp); // Looping the question list foreach ($question_list as $my_question_id) { if ($debug) { error_log("Saving question_id = $my_question_id "); } if ($type == 'simple' && $question_id != $my_question_id) { continue; } $my_choice = isset($choice[$my_question_id]) ? $choice[$my_question_id] : null; if ($debug) { error_log("my_choice = ".print_r($my_choice, 1).""); } // Creates a temporary Question object $objQuestionTmp = Question::read($my_question_id, $course_id); // Getting free choice data. if ( ($objQuestionTmp->type == FREE_ANSWER || $objQuestionTmp->type == ORAL_EXPRESSION) && $type == 'all' ) { $my_choice = isset($_REQUEST['free_choice'][$my_question_id]) && !empty($_REQUEST['free_choice'][$my_question_id]) ? $_REQUEST['free_choice'][$my_question_id] : null; } if ($type == 'all') { $total_weight += $objQuestionTmp->selectWeighting(); } // This variable came from exercise_submit_modal.php. $hotspot_delineation_result = null; if (isset($_SESSION['hotspot_delineation_result']) && isset($_SESSION['hotspot_delineation_result'][$objExercise->selectId()])) { $hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$my_question_id]; } if ($type == 'simple') { // Getting old attempt in order to decrees the total score. $old_result = $objExercise->manage_answer( $exe_id, $my_question_id, null, 'exercise_show', array(), false, true, false, $objExercise->selectPropagateNeg(), array() ); // Removing old score. $total_score = $total_score - $old_result['score']; } // Deleting old attempt if (isset($attempt_list) && !empty($attempt_list[$my_question_id])) { if ($debug) { error_log("delete_attempt exe_id : $exe_id, my_question_id: $my_question_id"); } Event::delete_attempt( $exe_id, api_get_user_id(), $course_id, $session_id, $my_question_id ); if ($objQuestionTmp->type == HOT_SPOT) { Event::delete_attempt_hotspot( $exe_id, api_get_user_id(), $course_id, $session_id, $my_question_id ); } if (isset($attempt_list[$my_question_id]) && isset($attempt_list[$my_question_id]['marks']) ) { $total_score -= $attempt_list[$my_question_id]['marks']; } } // We're inside *one* question. Go through each possible answer for this question $result = $objExercise->manage_answer( $exe_id, $my_question_id, $my_choice, 'exercise_result', $hot_spot_coordinates, true, false, false, $objExercise->selectPropagateNeg(), $hotspot_delineation_result ); // Adding the new score. $total_score += $result['score']; if ($debug) { error_log("total_score: $total_score "); error_log("total_weight: $total_weight "); } $duration = 0; $now = time(); if ($type == 'all') { $exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); } $key = ExerciseLib::get_time_control_key( $exercise_id, $exercise_stat_info['orig_lp_id'], $exercise_stat_info['orig_lp_item_id'] ); if (isset($_SESSION['duration_time'][$key]) && !empty($_SESSION['duration_time'][$key])) { $duration = $now - $_SESSION['duration_time'][$key]; if (!empty($exercise_stat_info['exe_duration'])) { $duration += $exercise_stat_info['exe_duration']; } $duration = intval($duration); } else { if (!empty($exercise_stat_info['exe_duration'])) { $duration = $exercise_stat_info['exe_duration']; } } $_SESSION['duration_time'][$key] = time(); Event::update_event_exercise( $exe_id, $objExercise->selectId(), $total_score, $total_weight, $session_id, $exercise_stat_info['orig_lp_id'], $exercise_stat_info['orig_lp_item_id'], $exercise_stat_info['orig_lp_item_view_id'], $duration, $question_list, 'incomplete', $remind_list ); // Destruction of the Question object unset($objQuestionTmp); if ($debug) { error_log(" -- end question -- "); } } if ($debug) { error_log(" ------ end ajax call ------- "); } } if ($objExercise->type == ONE_PER_PAGE) { echo 'one_per_page'; exit; } echo 'ok'; break; case 'show_question': $isAllowedToEdit = api_is_allowed_to_edit(null, true, false, false); if (!$isAllowedToEdit) { api_not_allowed(true); exit; } $questionId = isset($_GET['question']) ? intval($_GET['question']) : 0; $exerciseId = isset($_REQUEST['exercise']) ? intval($_REQUEST['exercise']) : 0; if (!$questionId || !$exerciseId) { break; } $objExercise = new Exercise(); $objExercise->read($exerciseId); $objQuestion = Question::read($questionId); $objQuestion->get_question_type_name(); echo '
'.$objQuestion->get_question_type_name().'
'; //echo get_lang('Level').': '.$objQuestionTmp->selectLevel(); ExerciseLib::showQuestion( $questionId, false, null, null, false, true, false, true, $objExercise->feedback_type, true ); break; default: echo ''; } exit;