diff --git a/main/inc/lib/tracking.lib.php b/main/inc/lib/tracking.lib.php index 1e618cc4c0..680d036bdb 100755 --- a/main/inc/lib/tracking.lib.php +++ b/main/inc/lib/tracking.lib.php @@ -520,7 +520,7 @@ class Tracking { * @param bool Returns an array of the type [sum_score, num_score] if set to true * @return string Value (number %) Which represents a round integer explain in got in 3. */ - public static function get_avg_student_score($student_id, $course_code, $lp_ids=array(), $session_id = null, $return_array = false) { + public static function get_avg_student_score($student_id, $course_code, $lp_ids=array(), $session_id = null, $return_array = false, $get_only_latest_attempt_results = false) { // get global tables names $course_table = Database :: get_main_table(TABLE_MAIN_COURSE); @@ -543,19 +543,18 @@ class Tracking { // Compose a filter based on optional learning paths list given $condition_lp = ""; - if(count($lp_ids) > 0) { + if (count($lp_ids) > 0) { $condition_lp =" AND id IN(".implode(',',$lp_ids).") "; - } + } // Compose a filter based on optional session id $condition_session = ""; - if (isset($session_id)) { - $session_id = intval($session_id); - if (count($lp_ids) > 0) { - $condition_session = " AND session_id = $session_id "; - } else { - $condition_session = " WHERE session_id = $session_id "; - } + + $session_id = intval($session_id); + if (count($lp_ids) > 0) { + $condition_session = " AND session_id = $session_id "; + } else { + $condition_session = " WHERE session_id = $session_id "; } // Check the real number of LPs corresponding to the filter in the @@ -566,26 +565,23 @@ class Tracking { } else { $sql = "SELECT DISTINCT(id), use_max_score FROM $lp_table WHERE 1 $condition_lp "; } - - $res_row_lp = Database::query($sql); + + $res_row_lp = Database::query($sql); $count_row_lp = Database::num_rows($res_row_lp); + $lp_list = $use_max_score = array(); - while ($row_lp = Database::fetch_array($res_row_lp)) { $lp_list[] = $row_lp['id']; $use_max_score[$row_lp['id']] = $row_lp['use_max_score']; - } + } - // Init local variables that will be used through the calculation - $lp_scorm_score_total = 0; + // Init local variables that will be used through the calculation $lp_scorm_result_score_total = 0; - - $lp_scorm_loop=0; - $lp_count = 0; - $progress = 0; + $progress = 0; // prepare filter on users $condition_user1 = ""; + if (is_array($student_id)) { array_walk($student_id,'intval'); $condition_user1 =" AND user_id IN (".implode(',',$student_id).") "; @@ -593,17 +589,19 @@ class Tracking { $condition_user1 =" AND user_id = '$student_id' "; } - if ($count_row_lp>0 && !empty($student_id)) { + if ($count_row_lp > 0 && !empty($student_id)) { - // Get all views through learning paths filter + // Getting latest LP result for a student + //@todo problem when a course have more than 1500 users - $sql = "SELECT MAX(view_count) as vc, id, progress, lp_id, user_id FROM $lp_view_table ". - "WHERE lp_id IN (".implode(',',$lp_list).") $condition_user1 AND session_id= $session_id GROUP BY lp_id,user_id"; - //var_dump( $sql ); + $sql = "SELECT MAX(view_count) as vc, id, progress, lp_id, user_id FROM $lp_view_table + WHERE lp_id IN (".implode(',',$lp_list).") $condition_user1 AND session_id = $session_id GROUP BY lp_id, user_id"; + //var_dump($sql); $rs_last_lp_view_id = Database::query($sql); $global_count_item = 0; $global_result = 0; - + $list = array(); + if (Database::num_rows($rs_last_lp_view_id) > 0) { // Cycle through each line of the results (grouped by lp_id, user_id) while ($row_lp_view = Database::fetch_array($rs_last_lp_view_id)) { @@ -612,26 +610,53 @@ class Tracking { $progress = $row_lp_view['progress']; $lp_id = $row_lp_view['lp_id']; $user_id = $row_lp_view['user_id']; - - // For the currently analysed view, get the score and - // max_score of each item if it is a sco or a TOOL_QUIZ - $sql_max_score = "SELECT lp_iv.score as score,lp_i.max_score, lp_iv.max_score as max_score_item_view, lp_i.path, lp_i.item_type, lp_i.id as iid". - " FROM $lp_item_view_table as lp_iv INNER JOIN $lp_item_table as lp_i ". - " ON lp_i.id = lp_iv.lp_item_id ". - " AND (lp_i.item_type='sco' OR lp_i.item_type='".TOOL_QUIZ."') ". - " WHERE lp_view_id='$lp_view_id'"; - //echo $sql_max_score; echo '
'; - - $res_max_score = Database::query($sql_max_score); + + //Getting + + if ($get_only_latest_attempt_results) { + //if (1) { + //Getting lp_items done by the user + $sql = "SELECT DISTINCT lp_item_id FROM $lp_item_view_table WHERE lp_view_id = $lp_view_id ORDER BY lp_item_id"; + $res_lp_item = Database::query($sql); + + while ($row_lp_item = Database::fetch_array($res_lp_item,'ASSOC')) { + $my_lp_item_id = $row_lp_item['lp_item_id']; + + //Getting the most recent attempt + $sql = "SELECT lp_iv.score as score,lp_i.max_score, lp_iv.max_score as max_score_item_view, lp_i.path, lp_i.item_type, lp_i.id as iid + FROM $lp_item_view_table as lp_iv INNER JOIN $lp_item_table as lp_i ON lp_i.id = lp_iv.lp_item_id AND (lp_i.item_type='sco' OR lp_i.item_type='".TOOL_QUIZ."') + WHERE lp_item_id = $my_lp_item_id AND lp_view_id = $lp_view_id ORDER BY view_count DESC LIMIT 1"; + $res_lp_item_result = Database::query($sql); + + + while ($row_max_score = Database::fetch_array($res_lp_item_result,'ASSOC')) { + $list[]= $row_max_score; + } + } + } else { + // For the currently analysed view, get the score and + // max_score of each item if it is a sco or a TOOL_QUIZ + $sql_max_score = "SELECT lp_iv.score as score,lp_i.max_score, lp_iv.max_score as max_score_item_view, lp_i.path, lp_i.item_type, lp_i.id as iid + FROM $lp_item_view_table as lp_iv INNER JOIN $lp_item_table as lp_i ON lp_i.id = lp_iv.lp_item_id AND (lp_i.item_type='sco' OR lp_i.item_type='".TOOL_QUIZ."') + WHERE lp_view_id = $lp_view_id "; + //echo $sql_max_score; echo '
'; + + $res_max_score = Database::query($sql_max_score); + + while ($row_max_score = Database::fetch_array($res_max_score,'ASSOC')) { + $list[]= $row_max_score; + } + } + //var_dump($list); + $count_total_loop = 0; - $num_rows_max_score = Database::num_rows($res_max_score); - + // Go through each scorable element of this view $count_items = 0; $lp_partial_total = 0; $score_of_scorm_calculate = 0; - - while ($row_max_score = Database::fetch_array($res_max_score,'ASSOC')) { + + foreach ($list as $row_max_score) { $max_score = $row_max_score['max_score']; //Came from the original lp_item $max_score_item_view = $row_max_score['max_score_item_view']; //Came from the lp_item_view $score = $row_max_score['score']; @@ -663,13 +688,9 @@ class Tracking { $item_path = $row_max_score['path']; // Get last attempt to this exercise through // the current lp for the current user - $sql_last_attempt = "SELECT exe_id FROM $tbl_stats_exercices ". - " WHERE exe_exo_id = '$item_path' ". - " AND exe_user_id = '$user_id' ". - // " AND orig_lp_id = '$lp_id' ". //lp_id is already defined by the item_id - " AND orig_lp_item_id = '$item_id' ". - " AND exe_cours_id = '$course_code' AND session_id = $session_id". - " ORDER BY exe_date DESC limit 1"; + $sql_last_attempt = "SELECT exe_id FROM $tbl_stats_exercices + WHERE exe_exo_id = '$item_path' AND exe_user_id = $user_id AND orig_lp_item_id = $item_id AND exe_cours_id = '$course_code' AND session_id = $session_id + ORDER BY exe_date DESC limit 1"; $result_last_attempt = Database::query($sql_last_attempt); $num = Database :: num_rows($result_last_attempt); @@ -680,21 +701,19 @@ class Tracking { // the max_scores of all questions that it was // made of (we need to make this call dynamic // because of random questions selection) - $sql = "SELECT SUM(t.ponderation) as maxscore ". - " FROM ( SELECT distinct question_id, marks, ponderation ". - " FROM $tbl_stats_attempts AS at " . - " INNER JOIN $tbl_quiz_questions AS q ". - " ON (q.id = at.question_id) ". - " WHERE exe_id ='$id_last_attempt' ) AS t"; + $sql = "SELECT SUM(t.ponderation) as maxscore FROM + ( SELECT distinct question_id, marks, ponderation FROM $tbl_stats_attempts AS at INNER JOIN $tbl_quiz_questions AS q ON (q.id = at.question_id) + WHERE exe_id ='$id_last_attempt' ) AS t"; $res_max_score_bis = Database::query($sql); $row_max_score_bis = Database :: fetch_array($res_max_score_bis); if (!empty($row_max_score_bis['maxscore'])) { $max_score = $row_max_score_bis['maxscore']; } if (!empty($max_score)) { - $lp_scorm_result_score_total += ($score/$max_score); - $lp_partial_total += ($score/$max_score); - $current_value = $score/$max_score; + $lp_scorm_result_score_total += $score/$max_score; + $lp_partial_total += $score/$max_score; + $current_value = $score/$max_score; + //echo $score.' '.$max_score.'
'; } } else { //$lp_scorm_result_score_total += 0; @@ -711,6 +730,8 @@ class Tracking { } } //end while + + $global_count_item +=$count_items; //echo 'lp_view '.$lp_view_id.' - $count_items '.$count_items.' lp partiual '.$lp_partial_total.'
'; diff --git a/main/mySpace/myStudents.php b/main/mySpace/myStudents.php index 4a4ab6a318..76a7ef7a1e 100755 --- a/main/mySpace/myStudents.php +++ b/main/mySpace/myStudents.php @@ -557,8 +557,11 @@ if ($timezone !== null) { 'absmiddle', 'hspace' => '3px')); ?> - 'absmiddle', 'hspace' => '3px')); ?> + 'absmiddle', 'hspace' => '3px')); ?> + + 'absmiddle', 'hspace' => '3px')); ?> + 'absmiddle','hspace' => '3px')); ?> @@ -590,6 +593,7 @@ if ($timezone !== null) { get_lang('Learnpath', ''), get_lang('Time', ''), get_lang('Score', ''), + get_lang('LatestScore', ''), get_lang('Progress', ''), get_lang('LastConnexion', '') ); @@ -639,6 +643,8 @@ if ($timezone !== null) { // Quizz in lp $score = Tracking :: get_avg_student_score($student_id, $course_code, array($lp_id),$session_id); + // Latest exercise results in a LP + $score_latest = Tracking :: get_avg_student_score($student_id, $course_code, array($lp_id),$session_id, false, true); if ($i % 2 == 0) $css_class = "row_odd"; else $css_class = "row_even"; @@ -650,63 +656,51 @@ if ($timezone !== null) { api_html_entity_decode(stripslashes($lp_name), ENT_QUOTES, $charset), api_time_to_hms($total_time), $score . '%', + $score_latest . '%', $progress.'%', $start_time - ); -?> - - - - - - - - - '; + + echo Display::tag('td', stripslashes($lp_name)); + echo Display::tag('td', api_time_to_hms($total_time), array('align'=>'center')); + if (!is_null($score)) { if (is_numeric($score)) { - echo $score.'%'; - } else { - // if result == '-' means that the LP does not have exercises if result is 0 means the LP have an exercise - echo $score ; + $score = $score.'%'; } } + echo Display::tag('td', $score, array('align'=>'center')); + + if (!is_null($score_latest)) { + if (is_numeric($score_latest)) { + $score_latest = $score_latest.'%'; + } + } + echo Display::tag('td', $score_latest, array('align'=>'center')); if (is_numeric($progress)) { $progress = $progress.'%'; } else { $progress = '-'; } -?> - - - - - - 'center')); + //Do not change with api_convert_and_format_date, because this value came from the lp_item_view table + //which implies several other changes not a priority right now + echo Display::tag('td', $start_time, array('align'=>'center')); -?> - - - - - - - ','lp_tracking.php?course='.Security::remove_XSS($_GET['course']).$from.'&origin='.Security::remove_XSS($_GET['origin']).'&lp_id='.$learnpath['id'].'&student_id='.$info_user['user_id'].'&session_id='.$session_id); + echo Display::tag('td', $link, array('align'=>'center')); } - echo ''; - + if (api_is_course_admin()) { echo ''; if($any_result === true) { @@ -716,8 +710,7 @@ if ($timezone !== null) { } echo ''; echo ''; - } - + } $data_learnpath[$i][] = $lp_name; $data_learnpath[$i][] = $progress . '%'; $i++; @@ -726,7 +719,7 @@ if ($timezone !== null) { echo ''.get_lang('NoLearnpath').''; } ?> - + @@ -745,7 +738,6 @@ if ($timezone !== null) { get_lang('Attempts') ); - $t_quiz = Database :: get_course_table(TABLE_QUIZ_TEST, $info_course['db_name']); $sql_exercices = "SELECT quiz.title,id FROM " . $t_quiz . " AS quiz diff --git a/main/newscorm/lp_stats.php b/main/newscorm/lp_stats.php index 309934ce2f..dfd9743978 100755 --- a/main/newscorm/lp_stats.php +++ b/main/newscorm/lp_stats.php @@ -7,10 +7,10 @@ * This script must be included by lp_controller.php to get basic initialisation * @package chamilo.learnpath * @author Yannick Warnier + * @todo clean this file like the exercise files J.M */ require_once 'learnpath.class.php'; -//require_once 'scorm.class.php'; require_once 'resourcelinker.inc.php'; require_once api_get_path(LIBRARY_PATH).'tracking.lib.php'; require_once api_get_path(LIBRARY_PATH).'course.lib.php'; @@ -32,8 +32,10 @@ $session_condition = api_get_session_condition($session_id); //$list = $_SESSION['oLP']->get_flat_ordered_items_list($lp_id); //$user_id = $_user['user_id']; +//When origin is not set that means that the lp_stats are viewed from the "man running" icon if (!isset($origin)) $origin = ''; +//Origin = tracking means that teachers see that info in the Reporting tool if ($origin != 'tracking') { //$w = $tablewidth -20; $htmlHeadXtra[] = '