diff --git a/public/main/exercise/exercise_report.php b/public/main/exercise/exercise_report.php index 066cf1d564c..08a4fb21a5a 100644 --- a/public/main/exercise/exercise_report.php +++ b/public/main/exercise/exercise_report.php @@ -123,6 +123,22 @@ header('Location: '.$urlExportPdf); exit; + case 'send_email': + $attemptId = (int) $_GET['attemptId']; + ExerciseLib::sendExerciseResultByEmail($attemptId); + Display::addFlash(Display::return_message(get_lang('Email content logged to error_log'))); + header('Location: '.api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exercise_id); + exit; + case 'send_all_emails': + $sessionId = api_get_session_id(); + $courseId = api_get_course_int_id(); + $attempts = ExerciseLib::getReviewedAttemptsInfo($exercise_id, $sessionId); + foreach ($attempts as $attempt) { + ExerciseLib::sendExerciseResultByEmail($attempt['exe_id']); + } + Display::addFlash(Display::return_message(get_lang('All emails sent successfully'))); + header('Location: '.api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exercise_id); + exit; } if (!empty($_REQUEST['export_report']) && '1' == $_REQUEST['export_report']) { @@ -470,6 +486,11 @@ api_get_self().'?'.api_get_cidreq().'&action=export_all_results&exerciseId='.$exercise_id ); + $actions .= Display::url( + Display::getMdiIcon(ActionIcon::SEND_ALL_EMAILS, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Send all by email')), + api_get_self().'?'.api_get_cidreq().'&action=send_all_emails&exerciseId='.$exercise_id + ); + // clean result before a selected date icon if ($allowClean) { $actions .= Display::url( @@ -731,7 +752,7 @@ //for the top bar 'editoptions' => ['value' => $group_parameters], ], - ['name' => 'duration', 'index' => 'exe_duration', 'width' => '150', 'align' => 'left', 'search' => 'true'], + ['name' => 'duration', 'index' => 'exe_duration', 'width' => '80', 'align' => 'left', 'search' => 'true'], ['name' => 'start_date', 'index' => 'start_date', 'width' => '150', 'align' => 'left', 'search' => 'true'], ['name' => 'exe_date', 'index' => 'exe_date', 'width' => '150', 'align' => 'left', 'search' => 'true'], ['name' => 'score', 'index' => 'score', 'width' => '120', 'align' => 'center', 'search' => 'true'], @@ -755,8 +776,8 @@ ), ], ], - ['name' => 'lp', 'index' => 'orig_lp_id', 'width' => '150', 'align' => 'left', 'search' => 'false'], - ['name' => 'actions', 'index' => 'actions', 'width' => '180', 'align' => 'left', 'search' => 'false', 'sortable' => 'false'], + ['name' => 'lp', 'index' => 'orig_lp_id', 'width' => '130', 'align' => 'left', 'search' => 'false'], + ['name' => 'actions', 'index' => 'actions', 'width' => '240', 'align' => 'left', 'search' => 'false', 'sortable' => 'false'], ]; if ('true' === $officialCodeInList) { diff --git a/public/main/inc/lib/exercise.lib.php b/public/main/inc/lib/exercise.lib.php index 644db38d147..8b3886f3aa6 100644 --- a/public/main/inc/lib/exercise.lib.php +++ b/public/main/inc/lib/exercise.lib.php @@ -2357,6 +2357,10 @@ public static function get_exam_results_data( .Display::getMdiIcon(ActionIcon::EXPORT_PDF, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Export to PDF')) .''; + $sendMailUrl = api_get_path(WEB_CODE_PATH).'exercise/exercise_report.php?'.api_get_cidreq().'&action=send_email&exerciseId='.$exercise_id.'&attemptId='.$results[$i]['exe_id']; + $emailLink = '' + .Display::getMdiIcon(ActionIcon::SEND_SINGLE_EMAIL, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Send by email')) + .''; $filterByUser = isset($_GET['filter_by_user']) ? (int) $_GET['filter_by_user'] : 0; $delete_link = ' '', + 'subject' => 'No exercise info found', + 'message' => 'Attempt ID not found or invalid.', + ]; + } + + $studentId = $trackExerciseInfo['exe_user_id']; + $courseInfo = api_get_course_info(); + $teacherId = api_get_user_id(); + + if ( + empty($trackExerciseInfo['orig_lp_id']) || + empty($trackExerciseInfo['orig_lp_item_id']) + ) { + $url = api_get_path(WEB_CODE_PATH).'exercise/result.php?id='.$trackExerciseInfo['exe_id'].'&'.api_get_cidreq() + .'&show_headers=1&id_session='.api_get_session_id(); + } else { + $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?action=view&item_id=' + .$trackExerciseInfo['orig_lp_item_id'].'&lp_id='.$trackExerciseInfo['orig_lp_id'].'&'.api_get_cidreq() + .'&id_session='.api_get_session_id(); + } + + $message = self::getEmailNotification( + $teacherId, + $courseInfo, + $trackExerciseInfo['title'], + $url + ); + + return [ + 'to' => $studentId, + 'subject' => get_lang('Corrected test result'), + 'message' => $message, + ]; + } + + /** + * Sends the exercise result email to the student. + */ + public static function sendExerciseResultByEmail(int $attemptId): void + { + $content = self::getEmailContentForAttempt($attemptId); + + if (empty($content['to'])) { + return; + } + + MessageManager::send_message_simple( + $content['to'], + $content['subject'], + $content['message'], + api_get_user_id() + ); + } + + /** + * Returns all reviewed attempts for a given exercise and session. + */ + public static function getReviewedAttemptsInfo(int $exerciseId, int $sessionId): array + { + $courseId = api_get_course_int_id(); + $trackTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + $qualifyTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_QUALIFY); + + $sessionCondition = api_get_session_condition($sessionId, true, false, 't.session_id'); + + $sql = " + SELECT DISTINCT t.exe_id + FROM $trackTable t + INNER JOIN $qualifyTable q ON (t.exe_id = q.exe_id AND q.author > 0) + WHERE + t.c_id = $courseId AND + t.exe_exo_id = $exerciseId + $sessionCondition + "; + + return Database::store_result(Database::query($sql)); + } + /** * @param $score * @param $weight diff --git a/src/CoreBundle/Component/Utils/ActionIcon.php b/src/CoreBundle/Component/Utils/ActionIcon.php index 0eabb681b92..f0bb326063f 100644 --- a/src/CoreBundle/Component/Utils/ActionIcon.php +++ b/src/CoreBundle/Component/Utils/ActionIcon.php @@ -104,6 +104,10 @@ enum ActionIcon: string case SAVE_FORM = 'content-save'; // Send a message case SEND_MESSAGE = 'send'; + // Send all examsheets by email + case SEND_ALL_EMAILS = 'email-multiple'; + // Send a single examsheet by email + case SEND_SINGLE_EMAIL = 'email-outline'; // Add an attachment case ADD_ATTACHMENT = 'paperclip-plus'; // ? See RESTORE_BACKUP