Adding email notification for students in exercise see BT#7379

1.10.x
Julio Montoya 11 years ago
parent f8ac02edc1
commit 5c8b1abdf1
  1. 215
      main/exercice/exercise.class.php
  2. 16
      main/inc/lib/exercise.lib.php
  3. 10
      main/template/default/layout/footer.tpl
  4. 23
      main/template/default/mail/exercise/end_exercise_notification_to_user.tpl

@ -89,7 +89,10 @@ class Exercise
public $categoryWithQuestionList; public $categoryWithQuestionList;
public $mediaList; public $mediaList;
public $loadQuestionAJAX = false; public $loadQuestionAJAX = false;
// Notification send to the teacher.
public $emailNotificationTemplate = null; public $emailNotificationTemplate = null;
// Notification send to the student.
public $emailNotificationTemplateToUser = null;
public $countQuestions = 0; public $countQuestions = 0;
public $fastEdition = false; public $fastEdition = false;
public $modelType = 1; public $modelType = 1;
@ -100,6 +103,8 @@ class Exercise
public $globalCategoryId = null; public $globalCategoryId = null;
public $onSuccessMessage = null; public $onSuccessMessage = null;
public $onFailedMessage = null; public $onFailedMessage = null;
public $emailAlert;
public $notifyUserByEmail = 0;
/** /**
* Constructor of the class * Constructor of the class
@ -201,6 +206,8 @@ class Exercise
$this->onSuccessMessage = $object->on_success_message; $this->onSuccessMessage = $object->on_success_message;
$this->onFailedMessage= $object->on_failed_message; $this->onFailedMessage= $object->on_failed_message;
$this->emailNotificationTemplate = $object->email_notification_template; $this->emailNotificationTemplate = $object->email_notification_template;
$this->emailNotificationTemplateToUser = $object->email_notification_template_to_user;
$this->notifyUserByEmail = $object->notify_user_by_email;
$this->modelType = $object->model_type; $this->modelType = $object->model_type;
$this->questionSelectionType = $object->question_selection_type; $this->questionSelectionType = $object->question_selection_type;
$this->hideQuestionTitle = $object->hide_question_title; $this->hideQuestionTitle = $object->hide_question_title;
@ -378,6 +385,22 @@ class Exercise
return $this->emailNotificationTemplate; return $this->emailNotificationTemplate;
} }
/**
* @return string
*/
public function selectEmailNotificationTemplateToUser()
{
return $this->emailNotificationTemplateToUser;
}
/**
* @return string
*/
public function getNotifyUserByEmail()
{
return $this->notifyUserByEmail;
}
/** /**
* @return int * @return int
*/ */
@ -1203,6 +1226,23 @@ class Exercise
$this->emailNotificationTemplate = $text; $this->emailNotificationTemplate = $text;
} }
/**
* @param string $text
*/
public function updateEmailNotificationTemplateToUser($text)
{
$this->emailNotificationTemplateToUser = $text;
}
/**
* @param string $value
*/
public function setNotifyUserByEmail($value)
{
$this->notifyUserByEmail = $value;
}
/** /**
* @param int $value * @param int $value
*/ */
@ -1458,6 +1498,8 @@ class Exercise
on_success_message = '".Database::escape_string($this->getOnSuccessMessage())."', on_success_message = '".Database::escape_string($this->getOnSuccessMessage())."',
on_failed_message = '".Database::escape_string($this->getOnFailedMessage())."', on_failed_message = '".Database::escape_string($this->getOnFailedMessage())."',
email_notification_template = '".Database::escape_string($this->selectEmailNotificationTemplate())."', email_notification_template = '".Database::escape_string($this->selectEmailNotificationTemplate())."',
email_notification_template_to_user = '".Database::escape_string($this->selectEmailNotificationTemplateToUser())."',
notify_user_by_email = '".Database::escape_string($this->getNotifyUserByEmail())."',
model_type = '".$this->getModelType()."', model_type = '".$this->getModelType()."',
question_selection_type = '".$this->getQuestionSelectionType()."', question_selection_type = '".$this->getQuestionSelectionType()."',
hide_question_title = '".$this->getHideQuestionTitle()."', hide_question_title = '".$this->getHideQuestionTitle()."',
@ -1500,6 +1542,8 @@ class Exercise
on_success_message, on_success_message,
on_failed_message, on_failed_message,
email_notification_template, email_notification_template,
email_notification_template_to_user,
notify_user_by_email,
results_disabled, results_disabled,
model_type, model_type,
question_selection_type, question_selection_type,
@ -1530,6 +1574,8 @@ class Exercise
'".Database::escape_string($this->getOnSuccessMessage())."', '".Database::escape_string($this->getOnSuccessMessage())."',
'".Database::escape_string($this->getOnFailedMessage())."', '".Database::escape_string($this->getOnFailedMessage())."',
'".Database::escape_string($this->selectEmailNotificationTemplate())."', '".Database::escape_string($this->selectEmailNotificationTemplate())."',
'".Database::escape_string($this->selectEmailNotificationTemplateToUser())."',
'".Database::escape_string($this->getNotifyUserByEmail())."',
'".Database::escape_string($results_disabled)."', '".Database::escape_string($results_disabled)."',
'".Database::escape_string($this->getModelType())."', '".Database::escape_string($this->getModelType())."',
'".Database::escape_string($this->getQuestionSelectionType())."', '".Database::escape_string($this->getQuestionSelectionType())."',
@ -2244,16 +2290,44 @@ class Exercise
if ($this->emailAlert) { if ($this->emailAlert) {
// Text when ending an exam // Email notification template
$form->add_html_editor( $form->add_html_editor(
'email_notification_template', 'email_notification_template',
array(get_lang('EmailNotificationTemplate'), get_lang('EmailNotificationTemplateDescription')), array(get_lang('EmailNotificationTemplateToTeacher'), get_lang('EmailNotificationTemplateToTeacherDescription')),
null, null,
false, false,
$editor_config $editor_config
); );
} }
$group = array(
$form->createElement(
'radio', 'notify_user_by_email', null, get_lang('Yes'), '1', array('id' => 'notify_user_by_email_on', 'class' => 'advanced_options_open', 'rel' => 'notify_user_by_email_options')
),
$form->createElement(
'radio', 'notify_user_by_email', null, get_lang('No'), '0', array('id' => 'notify_user_by_email_off', 'class' => 'advanced_options_close', 'rel' => 'notify_user_by_email_options')
)
);
$form->addGroup($group, null, get_lang('NotifyUserByEmail'));
$hide = 'style="display:none"';
if ($this->notifyUserByEmail == 1) {
$hide = null;
}
$form->addElement('html', '<div id="notify_user_by_email_options" '.$hide.'>');
// Email notification template to user
$form->add_html_editor(
'email_notification_template_to_user',
array(get_lang('EmailNotificationTemplateToUser'), get_lang('EmailNotificationTemplateToUserDescription')),
null,
false,
$editor_config
);
$form->addElement('html', '</div>');
// End advanced setting. // End advanced setting.
$form->addElement('html', '</div>'); $form->addElement('html', '</div>');
$form->addElement('html', '</div>'); $form->addElement('html', '</div>');
@ -2304,6 +2378,8 @@ class Exercise
$defaults['on_success_message'] = $this->getOnSuccessMessage(); $defaults['on_success_message'] = $this->getOnSuccessMessage();
$defaults['on_failed_message'] = $this->getOnFailedMessage(); $defaults['on_failed_message'] = $this->getOnFailedMessage();
$defaults['email_notification_template'] = $this->selectEmailNotificationTemplate(); $defaults['email_notification_template'] = $this->selectEmailNotificationTemplate();
$defaults['email_notification_template_to_user'] = $this->selectEmailNotificationTemplateToUser();
$defaults['notify_user_by_email'] = $this->getNotifyUserByEmail();
$defaults['model_type'] = $this->getModelType(); $defaults['model_type'] = $this->getModelType();
$defaults['question_selection_type'] = $this->getQuestionSelectionType(); $defaults['question_selection_type'] = $this->getQuestionSelectionType();
$defaults['score_type_model'] = $this->getScoreTypeModel(); $defaults['score_type_model'] = $this->getScoreTypeModel();
@ -2390,6 +2466,8 @@ class Exercise
$this->setOnSuccessMessage($form->getSubmitValue('on_success_message')); $this->setOnSuccessMessage($form->getSubmitValue('on_success_message'));
$this->setOnFailedMessage($form->getSubmitValue('on_failed_message')); $this->setOnFailedMessage($form->getSubmitValue('on_failed_message'));
$this->updateEmailNotificationTemplate($form->getSubmitValue('email_notification_template')); $this->updateEmailNotificationTemplate($form->getSubmitValue('email_notification_template'));
$this->updateEmailNotificationTemplateToUser($form->getSubmitValue('email_notification_template_to_user'));
$this->setNotifyUserByEmail($form->getSubmitValue('notify_user_by_email'));
$this->setModelType($form->getSubmitValue('model_type')); $this->setModelType($form->getSubmitValue('model_type'));
$this->setQuestionSelectionType($form->getSubmitValue('question_selection_type')); $this->setQuestionSelectionType($form->getSubmitValue('question_selection_type'));
$this->setHideQuestionTitle($form->getSubmitValue('hide_question_title')); $this->setHideQuestionTitle($form->getSubmitValue('hide_question_title'));
@ -4895,6 +4973,9 @@ class Exercise
return $return_array; return $return_array;
} }
/**
* @return array
*/
public function returnNotificationTag() public function returnNotificationTag()
{ {
return array( return array(
@ -4905,17 +4986,20 @@ class Exercise
'{{ exercise.start_time }}', '{{ exercise.start_time }}',
'{{ exercise.end_time }}', '{{ exercise.end_time }}',
'{{ exercise.question_and_answer_ids }}', '{{ exercise.question_and_answer_ids }}',
'{{ exercise.assert_count }}' '{{ exercise.assert_count }}',
'{{ exercise_result_message }}' // if success or failed
); );
} }
/** /**
* @param $exeId * @param int $exeId
* @param array
* @param bool
* @return bool * @return bool
*/ */
public function sendCustomNotification($exeId, $exerciseResult = array()) public function sendCustomNotification($exeId, $exerciseResult = array(), $exerciseWasPassed = false)
{ {
if ($this->emailAlert) { if (!empty($this->emailNotificationTemplate) or !empty($this->emailNotificationTemplateToUser)) {
// Getting attempt info // Getting attempt info
$trackExerciseInfo = ExerciseLib::get_exercise_track_exercise_info($exeId); $trackExerciseInfo = ExerciseLib::get_exercise_track_exercise_info($exeId);
@ -4923,18 +5007,21 @@ class Exercise
if (empty($trackExerciseInfo)) { if (empty($trackExerciseInfo)) {
return false; return false;
} }
}
if ($this->emailAlert) {
if (!empty($this->emailNotificationTemplate)) { if (!empty($this->emailNotificationTemplate)) {
$twig = new \Twig_Environment(new \Twig_Loader_String()); $twig = new \Twig_Environment(new \Twig_Loader_String());
$twig->addFilter('var_dump', new Twig_Filter_Function('var_dump')); $twig->addFilter('var_dump', new Twig_Filter_Function('var_dump'));
$template = $this->emailNotificationTemplate; $template = "{% autoescape false %} ".$this->emailNotificationTemplate."{% endautoescape %}";
} else { } else {
global $app; global $app;
$twig = $app['twig']; $twig = $app['twig'];
$template = 'default/mail/exercise/end_exercise_notification.tpl'; $template = 'default/mail/exercise/end_exercise_notification.tpl';
} }
$userInfo = UserManager::get_user_info_by_id($trackExerciseInfo['exe_user_id']); $userInfo = api_get_user_info($trackExerciseInfo['exe_user_id'], false, false, true);
$courseInfo = api_get_course_info_by_id($trackExerciseInfo['c_id']); $courseInfo = api_get_course_info_by_id($trackExerciseInfo['c_id']);
$twig->addGlobal('student', $userInfo); $twig->addGlobal('student', $userInfo);
@ -4943,6 +5030,12 @@ class Exercise
$twig->addGlobal('exercise.end_time', $trackExerciseInfo['end_time']); $twig->addGlobal('exercise.end_time', $trackExerciseInfo['end_time']);
$twig->addGlobal('course', $courseInfo); $twig->addGlobal('course', $courseInfo);
if ($exerciseWasPassed) {
$twig->addGlobal('exercise_result_message', $this->getOnSuccessMessage());
} else {
$twig->addGlobal('exercise_result_message', $this->getOnFailedMessage());
}
$resultInfo = array(); $resultInfo = array();
$resultInfoToString = null; $resultInfoToString = null;
$countCorrectToString = null; $countCorrectToString = null;
@ -4982,19 +5075,96 @@ class Exercise
try { try {
$twig->parse($twig->tokenize($template)); $twig->parse($twig->tokenize($template));
$content = $twig->render($template); $content = $twig->render($template);
$subject = get_lang('ExerciseResult');
if (!empty($teachers)) {
foreach ($teachers as $user_id => $teacher_data) {
MessageManager::send_message_simple($user_id, $subject, $content);
}
}
} catch (Twig_Error_Syntax $e) { } catch (Twig_Error_Syntax $e) {
// $template contains one or more syntax errors // $template contains one or more syntax errors
Display::display_warning_message(get_lang('ThereIsAnErrorInTheTemplate'));
echo $e->getMessage(); echo $e->getMessage();
} }
}
// Student who finish the exercise // Message send only to student.
$subject = get_lang('ExerciseResult'); if ($this->notifyUserByEmail == 1) {
if (!empty($teachers)) { // Message send only to student.
foreach ($teachers as $user_id => $teacher_data) {
MessageManager::send_message_simple($user_id, $subject, $content); if (!empty($this->emailNotificationTemplateToUser)) {
$twig = new \Twig_Environment(new \Twig_Loader_String());
$twig->addFilter('var_dump', new Twig_Filter_Function('var_dump'));
$template = "{% autoescape false %} ".$this->emailNotificationTemplateToUser."{% endautoescape %}";
} else {
global $app;
$twig = $app['twig'];
$template = 'default/mail/exercise/end_exercise_notification_to_user.tpl';
}
$userInfo = api_get_user_info($trackExerciseInfo['exe_user_id'], false, false, true);
$courseInfo = api_get_course_info_by_id($trackExerciseInfo['c_id']);
$twig->addGlobal('student', $userInfo);
$twig->addGlobal('exercise', $this);
$twig->addGlobal('exercise.start_time', $trackExerciseInfo['start_time']);
$twig->addGlobal('exercise.end_time', $trackExerciseInfo['end_time']);
$twig->addGlobal('course', $courseInfo);
if ($exerciseWasPassed) {
$twig->addGlobal('exercise_result_message', $this->getOnSuccessMessage());
} else {
$twig->addGlobal('exercise_result_message', $this->getOnFailedMessage());
}
$resultInfo = array();
$resultInfoToString = null;
$countCorrectToString = null;
if (!empty($exerciseResult)) {
$countCorrect = array();
$countCorrect['correct'] = 0;
$countCorrect['total'] = 0;
$counter = 1;
foreach ($exerciseResult as $questionId => $result) {
$resultInfo[$questionId] = isset($result['details']['user_choices']) ? $result['details']['user_choices'] : null;
$correct = $result['score']['pass'] ? 1 : 0;
$countCorrect['correct'] += $correct;
$countCorrect['total'] = $counter;
$counter++;
}
if (!empty($resultInfo)) {
$resultInfoToString = json_encode($resultInfo);
}
if (!empty($countCorrect)) {
$countCorrectToString = json_encode($countCorrect);
} }
} }
$twig->addGlobal('question_and_answer_ids', $resultInfoToString);
$twig->addGlobal('asserts', $countCorrectToString);
try {
$twig->parse($twig->tokenize($template));
$content = $twig->render($template);
// Student who finish the exercise
MessageManager::send_message_simple(api_get_user_id(), get_lang('ExerciseResult'), $content);
} catch (Twig_Error_Syntax $e) {
// $template contains one or more syntax errors
Display::display_warning_message(get_lang('ThereIsAnErrorInTheTemplate'));
echo $e->getMessage();
}
} }
} }
@ -6598,13 +6768,12 @@ class Exercise
return $this->displayQuestionListByAttempt($exeId, false, true); return $this->displayQuestionListByAttempt($exeId, false, true);
} }
/** /**
* Display the exercise results * Display the exercise results
* @param int attempt id (exe_id) * @param int $exe_id
* @param bool save users results (true) or just show the results (false) * @param bool $saveUserResult save users results (true) or just show the results (false)
* @param bool return array with exercise result info * @param bool $returnExerciseResult return array with exercise result info
* @param mixed * @return mixed
*/ */
public function displayQuestionListByAttempt($exe_id, $saveUserResult = false, $returnExerciseResult = false) public function displayQuestionListByAttempt($exe_id, $saveUserResult = false, $returnExerciseResult = false)
{ {
@ -6857,7 +7026,8 @@ class Exercise
// Send notification. // Send notification.
if (!api_is_allowed_to_edit(null, true)) { if (!api_is_allowed_to_edit(null, true)) {
$this->sendCustomNotification($exe_id, $exerciseResultInfo); $isSuccess = ExerciseLib::is_success_exercise_result($total_score, $total_weight, $this->selectPassPercentage());
$this->sendCustomNotification($exe_id, $exerciseResultInfo, $isSuccess);
$this->sendNotificationForOpenQuestions($question_list_answers, $origin, $exe_id); $this->sendNotificationForOpenQuestions($question_list_answers, $origin, $exe_id);
$this->sendNotificationForOralQuestions($question_list_answers, $origin, $exe_id); $this->sendNotificationForOralQuestions($question_list_answers, $origin, $exe_id);
} }
@ -7834,8 +8004,11 @@ class Exercise
} }
/** /**
* @param int $exeId * @param $exeId
* @param array $exercise_stat_info * @param $exercise_stat_info
* @param $remindList
* @param $currentQuestion
* @return int|null
*/ */
public static function getNextQuestionId($exeId, $exercise_stat_info, $remindList, $currentQuestion) public static function getNextQuestionId($exeId, $exercise_stat_info, $remindList, $currentQuestion)
{ {

@ -15,6 +15,7 @@
*/ */
use ChamiloSession as Session; use ChamiloSession as Session;
class ExerciseLib class ExerciseLib
{ {
@ -720,6 +721,12 @@ class ExerciseLib
return $html; return $html;
} }
/**
* @param float $score
* @param float $weight
* @param bool $pass_percentage
* @return bool
*/
public static function is_success_exercise_result($score, $weight, $pass_percentage) public static function is_success_exercise_result($score, $weight, $pass_percentage)
{ {
$percentage = Text::float_format(($score / ($weight != 0 ? $weight : 1)) * 100, 1); $percentage = Text::float_format(($score / ($weight != 0 ? $weight : 1)) * 100, 1);
@ -731,18 +738,21 @@ class ExerciseLib
return false; return false;
} }
/**
* @param float $score
* @param float $weight
* @param bool $pass_percentage
* @return string
*/
public static function show_success_message($score, $weight, $pass_percentage) public static function show_success_message($score, $weight, $pass_percentage)
{ {
$res = ""; $res = "";
if (self::is_pass_pourcentage_enabled($pass_percentage)) { if (self::is_pass_pourcentage_enabled($pass_percentage)) {
$is_success = self::is_success_exercise_result($score, $weight, $pass_percentage); $is_success = self::is_success_exercise_result($score, $weight, $pass_percentage);
$icon = '';
if ($is_success) { if ($is_success) {
$html = get_lang('CongratulationsYouPassedTheTest'); $html = get_lang('CongratulationsYouPassedTheTest');
$icon = Display::return_icon('completed.png', get_lang('Correct'), array(), ICON_SIZE_MEDIUM); $icon = Display::return_icon('completed.png', get_lang('Correct'), array(), ICON_SIZE_MEDIUM);
} else { } else {
//$html .= Display::return_message(get_lang('YouDidNotReachTheMinimumScore'), 'warning');
$html = get_lang('YouDidNotReachTheMinimumScore'); $html = get_lang('YouDidNotReachTheMinimumScore');
$icon = Display::return_icon('warning.png', get_lang('Wrong'), array(), ICON_SIZE_MEDIUM); $icon = Display::return_icon('warning.png', get_lang('Wrong'), array(), ICON_SIZE_MEDIUM);
} }

@ -161,6 +161,16 @@ $(document).ready( function() {
}); });
}); });
$(".advanced_options_open").on("click", function() {
var id = $(this).attr('rel');
$("#"+id).show();
});
$(".advanced_options_close").on("click", function() {
var id = $(this).attr('rel');
$("#"+id).hide();
});
$(function() { $(function() {
$('a').tooltip({ $('a').tooltip({
placement: 'right', placement: 'right',

@ -0,0 +1,23 @@
<h3> {{ 'ExerciseResult' | get_lang }} </h3>
{{ 'UserInformation' | get_lang }}
1. {{ student.username }}
2. {{ student.firstname }}
3. {{ student.lastname }}
4. {{ student.official_code }}
5. {{ exercise.title }}
6. {{ exercise.start_time }}
7. {{ exercise.end_time }}
8. {{ course.title }}
9. {{ course.code }}
10. Result message: {{ exercise_result_message }}
Loading…
Cancel
Save