diff --git a/main/exercice/exercice.php b/main/exercice/exercice.php index 6d524bfb19..72ccf9694d 100644 --- a/main/exercice/exercice.php +++ b/main/exercice/exercice.php @@ -533,7 +533,7 @@ if (!empty($exercise_list)) { $title = Display::tag('font', $row['title'], array('style'=>'color:grey')); } else { $title = $row['title']; - } + } $count = intval(count_exercise_result_not_validated($my_exercise_id, $course_code, $session_id)); @@ -556,8 +556,11 @@ if (!empty($exercise_list)) { if ($session_id == $row['session_id']) { //Settings - $actions = Display::url(Display::return_icon('edit.png',get_lang('Edit'),'',22), 'admin.php?'.api_get_cidreq().'&exerciseId='.$row['id']); - $actions .=''.Display :: return_icon('test_results.png', get_lang('Results'),'',22).''; + $actions = Display::url(Display::return_icon('edit.png',get_lang('Edit'),'',22), 'admin.php?'.api_get_cidreq().'&exerciseId='.$row['id']); + + //Exercise results + $actions .=''.Display :: return_icon('test_results.png', get_lang('Results'),'',22).''; + //Export $actions .= Display::url(Display::return_icon('cd.gif', get_lang('CopyExercise')), '', array('onclick'=>"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToCopy'),ENT_QUOTES,$charset))." ".addslashes($row['title'])."?"."')) return false;",'href'=>'exercice.php?'.api_get_cidreq().'&choice=copy_exercise&sec_token='.$token.'&exerciseId='.$row['id'])); //Clean exercise @@ -572,9 +575,8 @@ if (!empty($exercise_list)) { $actions .= Display::url(Display::return_icon('export_qti2.png','IMS/QTI','','22'), 'exercice.php?choice=exportqti2&exerciseId='.$row['id']); } else { // not session - $actions = Display::return_icon('edit_na.png', get_lang('ExerciseEditionNotAvailableInSession')); - - $actions .=''.Display :: return_icon('test_results.png', get_lang('Results'),'',22).''; + $actions = Display::return_icon('edit_na.png', get_lang('ExerciseEditionNotAvailableInSession')); + $actions .=''.Display :: return_icon('test_results.png', get_lang('Results'),'',22).''; $actions .= Display::url(Display::return_icon('cd.gif', get_lang('CopyExercise')), '', array('onclick'=>"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToCopy'),ENT_QUOTES,$charset))." ".addslashes($row['title'])."?"."')) return false;",'href'=>'exercice.php?'.api_get_cidreq().'&choice=copy_exercise&sec_token='.$token.'&exerciseId='.$row['id'])); } @@ -653,7 +655,7 @@ if (!empty($exercise_list)) { WHERE exe_exo_id = ".$row['id']." AND exe_user_id = ".api_get_user_id()." AND exe_cours_id = '".api_get_course_id()."' AND - status <> 'incomplete' AND + status <> 'incomplete' AND orig_lp_id = 0 AND orig_lp_item_id = 0 AND session_id = '" . api_get_session_id() . "' @@ -710,15 +712,26 @@ if (!empty($exercise_list)) { } else { $attempt_text = get_lang('CantShowResults'); } - } + } + + $class_tip = ''; if (empty($num)) { $num = ''; - } + } else { + $class_tip = 'link_tooltip'; + //@todo use sprintf and show the results validated by the teacher + if ($num == 1 ) { + $num = $num.' '.get_lang('Result'); + } else { + $num = $num.' '.get_lang('Results'); + } + $num = ''; + } $item .= Display::tag('td', $attempt_text); //See results - $actions =' '.$num.' '.Display::return_icon('test_results.png', get_lang('Results'),'',22).' '; + $actions = ''.$num.Display::return_icon('test_results.png', get_lang('Results'),'',22).' '; } $class = 'row_even'; if ($count % 2) { diff --git a/main/exercice/exercise.lib.php b/main/exercice/exercise.lib.php index a52bcbdde8..a67810f967 100644 --- a/main/exercice/exercise.lib.php +++ b/main/exercice/exercise.lib.php @@ -27,8 +27,6 @@ $main_course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER); $TBL_TRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); $TBL_TRACK_ATTEMPT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); - - /** * Shows a question * @@ -352,8 +350,6 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu api_preg_match_all('/\[[^]]+\]/', $user_choice[0]['answer'], $student_answer_list); $student_answer_list = $student_answer_list[0]; } - - //var_dump($teacher_answer_list, $student_answer_list); if (!empty($teacher_answer_list) && !empty($student_answer_list)) { $teacher_answer_list = $teacher_answer_list[0]; @@ -756,6 +752,8 @@ function get_count_exam_results() { // I know it's bad to add a static integer here... but // it factorise function get_exam_results_data // and I think it worths it. + //This is not bad for the hardcoded value, this is bad because you call 2 times get_exam_results_data()! jm + //@todo use a real count select I know the sql constructions are $tabres = get_exam_results_data(0, 9999999, 0, "ASC"); return count($tabres); } @@ -771,21 +769,13 @@ function get_exam_results_data($from, $number_of_items, $column, $direction) { $is_tutor = api_is_allowed_to_edit(true); $is_tutor_course = api_is_course_tutor(); - $tbl_course_rel_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER); - $TBL_USER = Database :: get_main_table(TABLE_MAIN_USER); - $TBL_DOCUMENT = Database :: get_course_table(TABLE_DOCUMENT); - $TBL_ITEM_PROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY); - $TBL_EXERCICE_ANSWER = Database :: get_course_table(TABLE_QUIZ_ANSWER); - $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_USER = Database :: get_main_table(TABLE_MAIN_USER); + $TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST); $TBL_TRACK_EXERCICES = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); $TBL_TRACK_HOTPOTATOES = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES); $TBL_TRACK_ATTEMPT = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); - $TBL_TRACK_ATTEMPT_RECORDING= Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING); - $TBL_LP_ITEM_VIEW = Database :: get_course_table(TABLE_LP_ITEM_VIEW); - $TBL_LP_ITEM = Database :: get_course_table(TABLE_LP_ITEM); - $TBL_LP_VIEW = Database :: get_course_table(TABLE_LP_VIEW); + $TBL_TRACK_ATTEMPT_RECORDING= Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING); $TBL_GROUP_REL_USER = Database :: get_course_table(TABLE_GROUP_USER); $session_id_and = ' AND te.session_id = ' . api_get_session_id() . ' '; @@ -992,7 +982,7 @@ function get_exam_results_data($from, $number_of_items, $column, $direction) { $number_of_items = intval($number_of_items); $sql .= " ORDER BY col$column $direction "; $sql .= " LIMIT $from, $number_of_items"; - + $results = array(); $resx = Database::query($sql); @@ -1006,7 +996,7 @@ function get_exam_results_data($from, $number_of_items, $column, $direction) { $lang_nostartdate = get_lang('NoStartDate') . ' / '; if (is_array($results)) { - $users_array_id = array (); + $users_array_id = array(); if ($_GET['gradebook'] == 'view') { $filter_by_no_revised = true; $from_gradebook = true; @@ -1137,12 +1127,12 @@ function get_exam_results_data($from, $number_of_items, $column, $direction) { } } else { $attempt_url = api_get_path(WEB_CODE_PATH).'exercice/result.php?'.api_get_cidreq().'&id='.$results[$i]['exid'].'&id_session='.api_get_session_id().'&height=500&width=750'; - $attempt_link = Display::url(get_lang('Show'), $attempt_url, array('class'=>'thickbox'))."   "; + $attempt_link = Display::url(get_lang('Show'), $attempt_url, array('class'=>'thickbox a_button white small'))."   "; $html_link.= $attempt_link; if ($revised) { - $html_link.= Display::span(get_lang('Validated'), array('class'=>'label_tag notice')); + $html_link.= Display::span(get_lang('Validated'), array('class'=>'label_tag success')); } else { $html_link.= Display::span(get_lang('NotValidated'), array('class'=>'label_tag notice')); } diff --git a/main/exercice/exercise_report.php b/main/exercice/exercise_report.php index 41a4f43ff2..ec917a0eb5 100644 --- a/main/exercice/exercise_report.php +++ b/main/exercice/exercise_report.php @@ -27,7 +27,6 @@ $htmlHeadXtra[] = api_get_jquery_ui_js(); // Access control api_protect_course_script(true); - // including additional libraries require_once 'exercise.class.php'; require_once 'exercise.lib.php'; @@ -62,17 +61,17 @@ $TBL_LP_ITEM = Database :: get_course_table(TABLE_LP_ITEM); $course_id = api_get_course_int_id(); +$exercise_id = isset($_REQUEST['exerciseId']) ? intval($_REQUEST['exerciseId']) : null; - -if (empty ($exerciseId)) { - $exerciseId = intval($_REQUEST['exerciseId']); +if (empty($exercise_id)) { + api_not_allowed(); } -// + // filter display by student group // if $_GET['filterByGroup'] = -1 => do not filter // else, filter by group_id (0 for no group) -// + $filterByGroup = -1; if (isset($_GET['filterByGroup']) && is_numeric($_GET['filterByGroup'])) { $filterByGroup = Security::remove_XSS($_GET['filterByGroup']); @@ -142,7 +141,7 @@ if ($_REQUEST['comments'] == 'update' && ($is_allowedToEdit || $is_tutor) && $_G $from = $teacher_info['mail']; $from_name = api_get_person_name($teacher_info['firstname'], $teacher_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS); - $url = api_get_path(WEB_CODE_PATH) . 'exercice/exercise_report.php?' . api_get_cidreq() . '&id_session='.$session_id.'&exerciseId='.$exerciseId; + $url = api_get_path(WEB_CODE_PATH) . 'exercice/exercise_report.php?' . api_get_cidreq() . '&id_session='.$session_id.'&exerciseId='.$exercise_id; $my_post_info = array(); $post_content_id = array(); @@ -252,11 +251,9 @@ if ($is_allowedToEdit && $origin != 'learnpath') { Display::return_icon('save.png', get_lang('Export'),'',32).''; } } else { - $actions .= '' . Display :: return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').''; + $actions .= '' . Display :: return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').''; } - - //Deleting an attempt if ($_GET['delete'] == 'delete' && ($is_allowedToEdit || api_is_coach()) && !empty ($_GET['did']) && $_GET['did'] == strval(intval($_GET['did']))) { $sql = 'DELETE FROM ' . $TBL_TRACK_EXERCICES . ' WHERE exe_id = ' . intval($_GET['did']); //_GET[did] filtered by entry condition @@ -265,7 +262,7 @@ if ($_GET['delete'] == 'delete' && ($is_allowedToEdit || api_is_coach()) && !emp Database::query($sql); $filter=Security::remove_XSS($_GET['filter']); - header('Location: exercise_report.php?cidReq=' . Security::remove_XSS($_GET['cidReq']) . '&filter=' . $filter . '&exerciseId='.$exerciseId.'&filter_by_user='.$_GET['filter_by_user']); + header('Location: exercise_report.php?cidReq=' . Security::remove_XSS($_GET['cidReq']) . '&filter=' . $filter . '&exerciseId='.$exercise_id.'&filter_by_user='.$_GET['filter_by_user']); exit; } @@ -311,10 +308,14 @@ if (api_is_allowed_to_edit(null,true)) { $actions .= Display::return_icon('group.gif', get_lang("FilterByGroup")); $actions .= displayGroupMenu("groupFilter", $filterByGroup, "doFilterByGroup()")." "; } + //Live results + $actions .=''.Display :: return_icon('activity_monitor.png', get_lang('LiveResults'),'',32).''; } + + $parameters=array('cidReq'=>Security::remove_XSS($_GET['cidReq']),'filter' => Security::remove_XSS($_GET['filter']),'gradebook' =>Security::remove_XSS($_GET['gradebook'])); -$exercise_id = intval($_GET['exerciseId']); + if (!empty($exercise_id)) $parameters['exerciseId'] = $exercise_id; if (!empty($_GET['path'])) { @@ -339,7 +340,7 @@ if ($is_allowedToEdit || $is_tutor) { $table->set_header(6, get_lang('Date')); $table->set_header(7, get_lang('Score'),false); $table->set_header(8, get_lang('Status'), false); - $table->set_header(9, get_lang('CorrectTest'), false); + $table->set_header(9, get_lang('Actions'), false); } else { $table->set_header(0, get_lang('Exercice')); @@ -350,13 +351,12 @@ if ($is_allowedToEdit || $is_tutor) { } $content = $table->return_table(); - if ($is_allowedToEdit || $is_tutor) { $nameTools = get_lang('StudentScore'); $interbreadcrumb[] = array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices')); $objExerciseTmp = new Exercise(); - if ($objExerciseTmp->read($exerciseId)) { - $interbreadcrumb[] = array("url" => "admin.php?exerciseId=".$exerciseId, "name" => $objExerciseTmp->name); + if ($objExerciseTmp->read($exercise_id)) { + $interbreadcrumb[] = array("url" => "admin.php?exerciseId=".$exercise_id, "name" => $objExerciseTmp->name); } } else { $nameTools = get_lang('YourScore'); @@ -400,9 +400,9 @@ $extra = ''; $extra .= '
'; - $extra .= Display::tag('p', Display::input('radio', 'export_format', 'csv', array('checked'=>'1', 'id'=>'export_format_csv_label')). Display::tag('label', get_lang('ExportAsCSV'), array('for'=>'export_format_csv_label'))); - $extra .= Display::tag('p', Display::input('radio', 'export_format', 'xls', array('id'=>'export_format_xls_label')). Display::tag('label', get_lang('ExportAsXLS'), array('for'=>'export_format_xls_label'))); - $extra .= Display::tag('p', Display::input('checkbox', 'load_extra_data', '0',array('id'=>'load_extra_data_id')). Display::tag('label', get_lang('LoadExtraData'), array('for'=>'load_extra_data_id'))); +$extra .= Display::tag('p', Display::input('radio', 'export_format', 'csv', array('checked'=>'1', 'id'=>'export_format_csv_label')). Display::tag('label', get_lang('ExportAsCSV'), array('for'=>'export_format_csv_label'))); +$extra .= Display::tag('p', Display::input('radio', 'export_format', 'xls', array('id'=>'export_format_xls_label')). Display::tag('label', get_lang('ExportAsXLS'), array('for'=>'export_format_xls_label'))); +$extra .= Display::tag('p', Display::input('checkbox', 'load_extra_data', '0',array('id'=>'load_extra_data_id')). Display::tag('label', get_lang('LoadExtraData'), array('for'=>'load_extra_data_id'))); $extra .= '
'; if ($is_allowedToEdit) echo $extra; diff --git a/main/exercice/live_stats.php b/main/exercice/live_stats.php index 48074d1051..9287be591c 100644 --- a/main/exercice/live_stats.php +++ b/main/exercice/live_stats.php @@ -10,6 +10,13 @@ require_once 'exercise.lib.php'; $this_section = SECTION_COURSES; $exercise_id = (isset($_GET['exerciseId']) && !empty($_GET['exerciseId'])) ? intval($_GET['exerciseId']) : 0; +// Access control +api_protect_course_script(true); + +if (!api_is_allowed_to_edit()) { + api_not_allowed(); +} + $objExercise = new Exercise(); $result = $objExercise->read($exercise_id); @@ -29,20 +36,19 @@ Display::display_header($tool_name); //jqgrid will use this URL to do the selects -$minutes = 60; - -$url = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=get_live_stats&exercise_id='.$objExercise->id.'&minutes='.$minutes; +$minutes = 30; +$url = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=get_live_stats&exercise_id='.$objExercise->id.'&minutes='.$minutes; //The order is important you need to check the the $column variable in the model.ajax.php file -$columns = array(get_lang('Firstname'), get_lang('Lastname'), get_lang('Date'), get_lang('QuestionsAlreadyAnswered'), get_lang('Score')); +$columns = array(get_lang('FirstName'), get_lang('LastName'), get_lang('Date'), get_lang('QuestionsAlreadyAnswered'), get_lang('Score')); //Column config $column_model = array( - array('name'=>'firstname', 'index'=>'firstname', 'width'=>'100', 'align'=>'left'), - array('name'=>'lastname', 'index'=>'lastname', 'width'=>'100', 'align'=>'left'), - array('name'=>'start_date', 'index'=>'start_date', 'width'=>'100', 'align'=>'left'), - array('name'=>'question', 'index'=>'count_questions', 'width'=>'100', 'align'=>'left'), - array('name'=>'score', 'index'=>'score', 'width'=>'100', 'align'=>'left','sortable'=>'false'), + array('name'=>'firstname', 'index'=>'firstname', 'width'=>'100', 'align'=>'left'), + array('name'=>'lastname', 'index'=>'lastname', 'width'=>'100', 'align'=>'left'), + array('name'=>'start_date', 'index'=>'start_date', 'width'=>'100', 'align'=>'left'), + array('name'=>'question', 'index'=>'count_questions', 'width'=>'100', 'align'=>'left'), + array('name'=>'score', 'index'=>'score', 'width'=>'100', 'align'=>'left','sortable'=>'false'), ); //Autowidth $extra_params['autowidth'] = 'true'; @@ -59,16 +65,30 @@ $action_links = 'function action_formatter(cellvalue, options, rowObject) { */ ?> ' . Display :: return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').''; +echo $actions = Display::div($actions, array('class'=> 'actions')); + echo '

'.$objExercise->name.'

'; +echo Display::tag('h4', get_lang('StudentsWhoAreTakingTheExerciseRightNow')); + echo Display::grid_html('live_stats'); Display::display_footer(); \ No newline at end of file diff --git a/main/exercice/overview.php b/main/exercice/overview.php index 52b3541c24..26a8afa87e 100644 --- a/main/exercice/overview.php +++ b/main/exercice/overview.php @@ -114,9 +114,9 @@ if (!empty($attempts)) { $counter--; $score = show_score($attempt_result['exe_result'], $attempt_result['exe_weighting']); $attempt_url = api_get_path(WEB_CODE_PATH).'exercice/result.php?'.api_get_cidreq().'&id='.$attempt_result['exe_id'].'&id_session='.api_get_session_id().'&height=500&width=750'; - $attempt_link = Display::url(get_lang('Show'), $attempt_url, array('class'=>'thickbox')); + $attempt_link = Display::url(get_lang('Show'), $attempt_url, array('class'=>'thickbox a_button white small')); - $teacher_revised = Display::span(get_lang('Validated'), array('class'=>'label_tag notice')); + $teacher_revised = Display::span(get_lang('Validated'), array('class'=>'label_tag success')); //$attempt_link = get_lang('NoResult'); //$attempt_link = Display::return_icon('quiz_na.png', get_lang('NoResult'), array(), 22); if ($attempt_result['attempt_revised'] == 0) { diff --git a/main/img/icons/32/activity_monitor.png b/main/img/icons/32/activity_monitor.png new file mode 100644 index 0000000000..539879b3b0 Binary files /dev/null and b/main/img/icons/32/activity_monitor.png differ diff --git a/main/inc/ajax/exercise.ajax.php b/main/inc/ajax/exercise.ajax.php index 65adbb22af..560328ba93 100644 --- a/main/inc/ajax/exercise.ajax.php +++ b/main/inc/ajax/exercise.ajax.php @@ -15,6 +15,10 @@ $course_id = api_get_course_int_id(); switch ($action) { case 'get_live_stats': + if (!api_is_allowed_to_edit(null, true)) { + break; + } + // 1. Setting variables needed by jqgrid $action = $_GET['a']; $exercise_id = intval($_GET['exercise_id']); @@ -61,18 +65,18 @@ switch ($action) { $start = 0; } - - $sql = "SELECT count_questions, 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_user_id, count(question_id) as count_questions, status, start_date, exe_result, exe_weighting, exe_result/exe_weighting as score, exe_duration, questions_to_check, orig_lp_id - FROM $track_attempt a INNER JOIN $track_exercise t - WHERE a.exe_id = t.exe_id AND exe_user_id = a.user_id AND $where_condition - group by exe_user_id - ) as aa + 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 "; + ORDER BY $sidx $sord LIMIT $start, $limit"; + //echo $sql; $result = Database::query($sql); $results = array(); @@ -101,8 +105,7 @@ switch ($action) { $i++; } } - echo json_encode($response); - + echo json_encode($response); break; case 'update_question_order': if (api_is_allowed_to_edit(null, true)) {