diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index b09f1602b5..6b003d9418 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -5654,7 +5654,7 @@ EOT; return $total; } - public static function getWrongQuestionResults($courseId, $exerciseId, $limit = 10) + public static function getWrongQuestionResults($courseId, $exerciseId, $sessionId = 0, $limit = 10) { $courseId = (int) $courseId; $exerciseId = (int) $exerciseId; @@ -5664,6 +5664,11 @@ EOT; $attemptTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $trackTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + $sessionCondition = ''; + if (!empty($sessionId)) { + $sessionCondition = api_get_session_condition($sessionId, true, false, 'te.session_id'); + } + $sql = "SELECT q.question, question_id, count(q.iid) count FROM $attemptTable t INNER JOIN $questionTable q @@ -5675,6 +5680,7 @@ EOT; t.marks != q.ponderation AND exe_exo_id = $exerciseId AND status != 'incomplete' + $sessionCondition GROUP BY q.iid ORDER BY count DESC LIMIT $limit @@ -5684,4 +5690,54 @@ EOT; return Database::store_result($result, 'ASSOC'); } + + public static function getExerciseResultsCount($type, $courseId, $exerciseId, $sessionId = 0) + { + $courseId = (int) $courseId; + $exerciseId = (int) $exerciseId; + + $trackTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + + $sessionCondition = ''; + if (!empty($sessionId)) { + $sessionCondition = api_get_session_condition($sessionId, true, false, 'te.session_id'); + } + + $selectCount = 'count(DISTINCT te.exe_id)'; + $scoreCondition = ''; + switch ($type) { + case 'correct_student': + $selectCount = 'count(DISTINCT te.exe_user_id)'; + $scoreCondition = ' AND exe_result = exe_weighting '; + break; + case 'wrong_student': + $selectCount = 'count(DISTINCT te.exe_user_id)'; + $scoreCondition = ' AND exe_result != exe_weighting '; + break; + case 'correct': + $scoreCondition = ' AND exe_result = exe_weighting '; + break; + case 'wrong': + $scoreCondition = ' AND exe_result != exe_weighting '; + break; + } + + $sql = "SELECT $selectCount count + FROM $trackTable te + WHERE + c_id = $courseId AND + exe_exo_id = $exerciseId AND + status != 'incomplete' + $scoreCondition + $sessionCondition + "; + $result = Database::query($sql); + $totalRow = Database::fetch_array($result, 'ASSOC'); + $total = 0; + if ($totalRow) { + $total = (int) $totalRow['count']; + } + + return $total; + } } diff --git a/main/mySpace/course.php b/main/mySpace/course.php index 6cf6fd4a4a..82dfa8b796 100755 --- a/main/mySpace/course.php +++ b/main/mySpace/course.php @@ -102,11 +102,23 @@ if (api_is_platform_admin(true, true)) { ); $menu_items[] = Display::url( Display::return_icon('session.png', get_lang('Sessions'), [], ICON_SIZE_MEDIUM), - 'session.php' + api_get_path(WEB_CODE_PATH).'mySpace/session.php' ); + + $menu_items[] = Display::url( + get_lang('QuestionStats'), + api_get_path(WEB_CODE_PATH).'mySpace/question_stats_global.php' + ); + + $menu_items[] = Display::url( + get_lang('QuestionStatsDetail'), + api_get_path(WEB_CODE_PATH).'mySpace/question_stats_global_detail.php' + ); + if (api_can_login_as($user_id)) { - $link = ''. - Display::return_icon('login_as.png', get_lang('LoginAs'), null, ICON_SIZE_MEDIUM).'  '; + $link = ''. + Display::return_icon('login_as.png', get_lang('LoginAs'), null, ICON_SIZE_MEDIUM).'  '; $menu_items[] = $link; } } diff --git a/main/mySpace/question_stats_global.php b/main/mySpace/question_stats_global.php new file mode 100644 index 0000000000..77d76cc04f --- /dev/null +++ b/main/mySpace/question_stats_global.php @@ -0,0 +1,162 @@ + "index.php", "name" => get_lang('MySpace')]; + +$courseIdList = isset($_REQUEST['courses']) ? $_REQUEST['courses'] : []; +$exercises = isset($_REQUEST['exercises']) ? $_REQUEST['exercises'] : []; + +$courseOptions = []; +$exercisesList = []; +$selectedExercises = []; +if (!empty($courseIdList)) { + foreach ($courseIdList as $courseId) { + $courseInfo = api_get_course_info_by_id($courseId); + $courseExerciseList = ExerciseLib::get_all_exercises( + $courseInfo, + 0, + false, + null, + false, + 3 + ); + + if (!empty($courseExerciseList)) { + foreach ($courseExerciseList as $exercise) { + $exerciseId = $exercise['iid']; + if (in_array( $exerciseId, $exercises)) { + $selectedExercises[$courseId][] = $exerciseId; + } + } + $exercisesList += array_column($courseExerciseList, 'title', 'iid'); + } + $courseOptions[$courseId] = $courseInfo['name']; + } +} + +$exercisesList = array_unique($exercisesList); + +$form = new FormValidator('search_form', 'GET', api_get_self()); +$form->addSelectAjax( + 'courses', + get_lang('Course'), + $courseOptions, + [ + 'url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_course', + 'multiple' => true + ] +); + +if (!empty($courseIdList)) { + $form->addSelect( + 'exercises', + get_lang('Exercise'), + $exercisesList, + [ + 'multiple' => true, + ] + ); +} + +$form->setDefaults(['course_id_list' => array_keys($courseOptions)]); +$form->addButtonSearch(get_lang('Search')); + +$tableContent = ''; +if ($form->validate()) { + $headers = [ + get_lang('Course'), + get_lang('Exercise'), + get_lang('Question'), + get_lang('WrongAnswer').' / '.get_lang('Total'), + '%', + ]; + /*$table = new HTML_Table(['class' => 'table table-hover table-striped']); + $row = 0; + $column = 0; + foreach ($headers as $header) { + $table->setHeaderContents($row, $column, $header); + $column++; + } + $row++;*/ + $scoreDisplay = new ScoreDisplay(); + $exercises = $form->getSubmitValue('exercises'); + if ($exercises) { + $orderedData = []; + foreach ($selectedExercises as $courseId => $exerciseList) { + foreach ($exerciseList as $exerciseId) { + $questions = ExerciseLib::getWrongQuestionResults($courseId, $exerciseId, null,10); + foreach ($questions as $data) { + $questionId = (int) $data['question_id']; + $total = ExerciseLib::getTotalQuestionAnswered($courseId, $exerciseId, $questionId); + /*$column = 0; + $table->setCellContents($row, $column++, $courseOptions[$courseId]); + $table->setCellContents($row, $column++, $exercisesList[$exerciseId]); + $table->setCellContents($row, $column++, $data['question']); + $table->setCellContents($row, $column++, $data['count'].' / '.$total); + $percentage = $data['count']/$total; + $table->setCellContents( + $row, + $column++, + $scoreDisplay->display_score([$data['count'], $total], SCORE_AVERAGE) + ); + $row++;*/ + $orderedData[] = [ + $courseOptions[$courseId], + $exercisesList[$exerciseId], + $data['question'], + $data['count'].' / '.$total, + $scoreDisplay->display_score([$data['count'], $total], SCORE_AVERAGE), + ]; + } + } + } + + $table = new SortableTableFromArray( + $orderedData, + 1, + 20, + 'question_tracking' + ); + $table->column = 4; + $column = 0; + foreach ($headers as $header) { + $table->set_header($column, $header, false); + $column++; + } + + $tableContent = $table->return_table(); + } +} + +$nameTools = get_lang('ExerciseManagement'); +$htmlHeadXtra[] = ''; + + +Display::display_header($nameTools, get_lang('Exercise')); +$form->display(); +echo $tableContent; + +Display::display_footer(); diff --git a/main/mySpace/question_stats_global_detail.php b/main/mySpace/question_stats_global_detail.php new file mode 100644 index 0000000000..4069cf2e7f --- /dev/null +++ b/main/mySpace/question_stats_global_detail.php @@ -0,0 +1,163 @@ + "index.php", "name" => get_lang('MySpace')]; + +$courseIdList = isset($_REQUEST['courses']) ? $_REQUEST['courses'] : []; +$exercises = isset($_REQUEST['exercises']) ? $_REQUEST['exercises'] : []; + +$courseOptions = []; +$exercisesList = []; +$selectedExercises = []; +if (!empty($courseIdList)) { + foreach ($courseIdList as $courseId) { + $courseInfo = api_get_course_info_by_id($courseId); + $courseExerciseList = ExerciseLib::get_all_exercises( + $courseInfo, + 0, + false, + null, + false, + 3 + ); + + if (!empty($courseExerciseList)) { + foreach ($courseExerciseList as $exercise) { + $exerciseId = $exercise['iid']; + if (in_array( $exerciseId, $exercises)) { + $selectedExercises[$courseId][] = $exerciseId; + } + } + $exercisesList += array_column($courseExerciseList, 'title', 'iid'); + } + $courseOptions[$courseId] = $courseInfo['name']; + } +} + +$exercisesList = array_unique($exercisesList); + +$form = new FormValidator('search_form', 'GET', api_get_self()); +$form->addSelectAjax( + 'courses', + get_lang('Course'), + $courseOptions, + [ + 'url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_course', + 'multiple' => true + ] +); + +if (!empty($courseIdList)) { + $form->addSelect( + 'exercises', + get_lang('Exercise'), + $exercisesList, + [ + 'multiple' => true, + ] + ); +} + +$form->setDefaults(['course_id_list' => array_keys($courseOptions)]); +$form->addButtonSearch(get_lang('Search')); + +$tableContent = ''; +if ($form->validate()) { + $headers = [ + get_lang('Session'), + get_lang('CorrectAttempts'), + get_lang('WrongAttempts'), + get_lang('StudentWithCorrectAnswers'), + get_lang('StudentWithWrongAnswers') + ]; + $scoreDisplay = new ScoreDisplay(); + $exercises = $form->getSubmitValue('exercises'); + + if ($exercises) { + foreach ($selectedExercises as $courseId => $exerciseList) { + $sessions = SessionManager::get_session_by_course($courseId ); + $courseTitle = $courseOptions[$courseId]; + + foreach ($exerciseList as $exerciseId) { + $exerciseTitle = $exercisesList[$exerciseId]; + $tableContent .= Display::page_subheader2($courseTitle.' - '.$exerciseTitle); + + $orderedData = []; + foreach ($sessions as $session) { + $sessionId = $session['id']; + $correctCount = ExerciseLib::getExerciseResultsCount('correct', $courseId, $exerciseId, $sessionId); + $wrongCount = ExerciseLib::getExerciseResultsCount('wrong', $courseId, $exerciseId, $sessionId); + + $correctCountStudent = ExerciseLib::getExerciseResultsCount( + 'correct_student', + $courseId, + $exerciseId, + $sessionId + ); + $wrongCountStudent = ExerciseLib::getExerciseResultsCount( + 'wrong_student', + $courseId, + $exerciseId, + $sessionId + ); + + $questions = ExerciseLib::getWrongQuestionResults($courseId, $exerciseId, $sessionId, 10); + $orderedData[] = [ + $session['name'], + $correctCount, + $wrongCount, + $correctCountStudent, + $wrongCountStudent + ]; + } + + $table = new SortableTableFromArray( + $orderedData, + 1, + 20, + uniqid('question_tracking_') + ); + $column = 0; + foreach ($headers as $header) { + $table->set_header($column, $header, false); + $column++; + } + $tableContent .= $table->return_table(); + } + } + + } +} + +$nameTools = get_lang('ExerciseManagement'); +$htmlHeadXtra[] = ''; + + +Display::display_header($nameTools, get_lang('Exercise')); +$form->display(); +echo $tableContent; + +Display::display_footer();