Exercise: Improve PDF export of exercise results. Export all exercises in a course + allow for dates range - refs BT#20691

pull/4722/head
Yannick Warnier 2 years ago
parent 796008a6d2
commit 3ae178001c
  1. 18
      main/admin/export_exercise_results.php
  2. 34
      main/exercise/exercise.class.php
  3. 5
      main/exercise/exercise.php
  4. 14
      main/exercise/exercise_report.php
  5. 70
      main/inc/lib/exercise.lib.php
  6. 1
      main/lang/english/trad4all.inc.php
  7. 1
      main/lang/french/trad4all.inc.php
  8. 1
      main/lang/spanish/trad4all.inc.php

@ -144,6 +144,18 @@ $form
)
->setSelected($exerciseId);
$form->addDateTimePicker('start_date', get_lang('StartDate'));
$form->addDateTimePicker('end_date', get_lang('EndDate'));
$form->addRule('start_date', get_lang('InvalidDate'), 'datetime');
$form->addRule('end_date', get_lang('InvalidDate'), 'datetime');
$form->addRule(
['start_date', 'end_date'],
get_lang('StartDateShouldBeBeforeEndDate'),
'date_compare',
'lte'
);
$form->addHidden('course_id_changed', '0');
$form->addHidden('exercise_id_changed', '0');
$form->addButtonExport(get_lang('Export'), 'name');
@ -155,7 +167,11 @@ if ($form->validate()) {
$sessionId = (int) $values['session_id'];
$courseId = (int) $values['selected_course'];
$exerciseId = (int) $values['exerciseId'];
ExerciseLib::exportExerciseAllResultsZip($sessionId, $courseId, $exerciseId);
$filterDates = [
'start_date' => (!empty($values['start_date']) ? $values['start_date'] : ''),
'end_date' => (!empty($values['end_date']) ? $values['end_date'] : ''),
];
ExerciseLib::exportExerciseAllResultsZip($sessionId, $courseId, $exerciseId, $filterDates);
}
}

@ -8420,13 +8420,16 @@ class Exercise
}
/**
* Get array of exercise details and user results
* @param int $courseId
* @param int $sessionId
* @param array $quizId
* @param bool $checkOnlyActiveUsers
* @param array $filterDates Limit the results exported to those within this range ('start_date' to 'end_date')
*
* @return array exercises
*/
public function getExerciseAndResult($courseId, $sessionId, $quizId = [], $status = null)
public function getExerciseAndResult($courseId, $sessionId, $quizId = [], $checkOnlyActiveUsers = false, $filterDates = [])
{
if (empty($quizId)) {
return [];
@ -8438,16 +8441,30 @@ class Exercise
$ids = is_array($quizId) ? $quizId : [$quizId];
$ids = array_map('intval', $ids);
$ids = implode(',', $ids);
$track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$trackExcercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$tblQuiz = Database::get_course_table(TABLE_QUIZ_TEST);
$tblUser = Database::get_main_table(TABLE_MAIN_USER);
$condition = '';
if (isset($status)) {
$condition .= " AND te.status = '$status' ";
$innerJoinUser = '';
if ($checkOnlyActiveUsers) {
$condition .= " AND te.status = '' ";
$innerJoinUser .= " INNER JOIN $tblUser u ON u.user_id = te. exe_user_id";
}
if (!empty($filterDates)) {
if (!empty($filterDates['start_date'])) {
$condition .= " AND te.exe_date >= '".Database::escape_string($filterDates['start_date'])."' ";
}
if (!empty($filterDates['end_date'])) {
$condition .= " AND te.exe_date <= '".Database::escape_string($filterDates['end_date'])."' ";
}
}
if (0 != $sessionId) {
$sql = "SELECT * FROM $track_exercises te
INNER JOIN c_quiz cq ON cq.iid = te.exe_exo_id
$sql = "SELECT * FROM $trackExcercises te
INNER JOIN $tblQuiz cq ON cq.iid = te.exe_exo_id
$innerJoinUser
WHERE
te.c_id = %s AND
te.session_id = %s AND
@ -8457,8 +8474,9 @@ class Exercise
$sql = sprintf($sql, $courseId, $sessionId, $ids);
} else {
$sql = "SELECT * FROM $track_exercises te
INNER JOIN c_quiz cq ON cq.iid = te.exe_exo_id
$sql = "SELECT * FROM $trackExcercises te
INNER JOIN $tblQuiz cq ON cq.iid = te.exe_exo_id
$innerJoinUser
WHERE
te.c_id = %s AND
cq.iid IN (%s)

@ -660,6 +660,11 @@ if ($is_allowedToEdit && $origin !== 'learnpath') {
);
}
$actionsLeft .= Display::url(
Display::return_icon('export_pdf.png', get_lang('ExportAllExercisesAllResults'), [], ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH).'exercise/exercise_report.php?'.api_get_cidreq().'&action=export_all_exercises_results'
);
if ($limitTeacherAccess) {
if (api_is_platform_admin()) {
$actionsLeft .= $cleanAll;

@ -58,9 +58,12 @@ $course_id = api_get_course_int_id();
$exercise_id = isset($_REQUEST['exerciseId']) ? (int) $_REQUEST['exerciseId'] : 0;
$locked = api_resource_is_locked_by_gradebook($exercise_id, LINK_EXERCISE);
$sessionId = api_get_session_id();
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
if (empty($exercise_id)) {
api_not_allowed(true);
if ('export_all_exercises_results' !== $action) {
if (empty($exercise_id)) {
api_not_allowed(true);
}
}
$blockPage = true;
@ -149,8 +152,13 @@ if (!empty($_REQUEST['export_report']) && $_REQUEST['export_report'] == '1') {
$objExerciseTmp = new Exercise();
$exerciseExists = $objExerciseTmp->read($exercise_id);
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
switch ($action) {
case 'export_all_exercises_results':
$sessionId = api_get_session_id();
$courseId = api_get_course_int_id();
ExerciseLib::exportAllExercisesResultsZip($sessionId, $courseId);
break;
case 'export_all_results':
$sessionId = api_get_session_id();
$courseId = api_get_course_int_id();

@ -7190,17 +7190,75 @@ EOT;
curl_close($ch);
}
public static function exportAllExercisesResultsZip(
int $sessionId,
int $courseId,
$filterDates = []
) {
$exercises = self::get_all_exercises_for_course_id(
null,
$sessionId,
$courseId,
true
);
$exportOk = false;
if (!empty($exercises)) {
$exportName = 'S'.$sessionId.'-C'.$courseId.'-ALL';
$baseDir = api_get_path(SYS_ARCHIVE_PATH);
$folderName = 'pdfexport-'.$exportName;
$exportFolderPath = $baseDir.$folderName;
if (!is_dir($exportFolderPath)) {
@mkdir($exportFolderPath);
}
foreach ($exercises as $exercise) {
$exerciseId = $exercise['iid'];
self::exportExerciseAllResultsZip($sessionId, $courseId, $exerciseId, [], $exportFolderPath);
}
// If export folder is not empty will be zipped.
$isFolderPathEmpty = (file_exists($exportFolderPath) && 2 == count(scandir($exportFolderPath)));
if (is_dir($exportFolderPath) && !$isFolderPathEmpty) {
$exportOk = true;
$exportFilePath = $baseDir.$exportName.'.zip';
$zip = new \PclZip($exportFilePath);
$zip->create($exportFolderPath, PCLZIP_OPT_REMOVE_PATH, $exportFolderPath);
rmdirr($exportFolderPath);
DocumentManager::file_send_for_download($exportFilePath, true, $exportName.'.zip');
exit;
}
}
if (!$exportOk) {
Display::addFlash(
Display::return_message(
get_lang('ExportExerciseNoResult'),
'warning',
false
)
);
}
return false;
}
public static function exportExerciseAllResultsZip(
int $sessionId,
int $courseId,
int $exerciseId
int $exerciseId,
$filterDates = [],
string $mainPath = ''
) {
$objExerciseTmp = new Exercise($courseId);
$exeResults = $objExerciseTmp->getExerciseAndResult(
$courseId,
$sessionId,
$exerciseId,
''
true,
$filterDates
);
$exportOk = false;
@ -7232,8 +7290,12 @@ EOT;
$zip->create($exportFolderPath, PCLZIP_OPT_REMOVE_PATH, $exportFolderPath);
rmdirr($exportFolderPath);
DocumentManager::file_send_for_download($exportFilePath, true, $exportName.'.zip');
exit;
if (!empty($mainPath) && file_exists($exportFilePath)) {
@rename($exportFilePath, $mainPath.'/'.$exportName.'.zip');
} else {
DocumentManager::file_send_for_download($exportFilePath, true, $exportName.'.zip');
exit;
}
}
}

@ -9024,4 +9024,5 @@ $AddEmailPicture = "Add picture for headers";
$AddEmailPictureComment = "This picture will be used in the course header and in the e-mails sent and PDFs generated from this course. The picture will have a ratio of 25:7. You can crop the picture you upload.";
$DeleteEmailPicture = "Delete picture for headers";
$AddPictureComment = "The final picture must be in a 16:9 ratio, but you can crop the picture you upload.";
$ExportAllExercisesAllResults = "Export all results of all tests";
?>

@ -8958,4 +8958,5 @@ $AddEmailPicture = "Ajouter une image pour les en-têtes";
$AddEmailPictureComment = "L'image sera utilisée dans les en-têtes de ce cours mais également des e-mails envoyés et des PDFs générés depuis ce cours. L'image doit avoir un ratio de 25:7. Vous pouvez recouper l'image au moment de l'envoi.";
$DeleteEmailPicture = "Supprimer l'image d'en-tête";
$AddPictureComment = "L'image finale doit avoir un format 16:9, mais vous pouvez la recouper lors de l'envoi.";
$ExportAllExercisesAllResults = "Exporter tous les résultats de tous les exercices";
?>

@ -9049,4 +9049,5 @@ $AddEmailPicture = "Añadir imagen de cabecera";
$AddEmailPictureComment = "Esta imagen será usada en la cabecera de este curso y la de los e-mails enviados desde este curso, pero también en los PDFs generados desde este curso. La imagen final tiene que tener una proporción de 25:7, pero la puede recortar al momento de subirla.";
$DeleteEmailPicture = "Eliminar la imagen de cabecera";
$AddPictureComment = "La imagen final tiene que tener una proporción de 16:9, pero la puede recortar durante la subida.";
$ExportAllExercisesAllResults = "Exportar todos los resultados de todos los ejercicios";
?>
Loading…
Cancel
Save