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();