diff --git a/main/auth/inscription.php b/main/auth/inscription.php index caa267c8b8..eb476f5b0d 100644 --- a/main/auth/inscription.php +++ b/main/auth/inscription.php @@ -15,7 +15,6 @@ if (!empty($_POST['language'])) { //quick hack to adapt the registration form re require_once '../inc/global.inc.php'; require_once api_get_path(CONFIGURATION_PATH).'profile.conf.php'; require_once api_get_path(LIBRARY_PATH).'mail.lib.inc.php'; -require_once api_get_path(LIBRARY_PATH).'events_dispatcher.lib.php'; if (!empty($_SESSION['user_language_choice'])) { $user_selected_language = $_SESSION['user_language_choice']; diff --git a/main/inc/conf/events.conf.dist.php b/main/inc/conf/events.conf.dist.php new file mode 100644 index 0000000000..e80fc09a39 --- /dev/null +++ b/main/inc/conf/events.conf.dist.php @@ -0,0 +1,99 @@ + array( // key for "user registration" event + 'actions' => array( // we link this event to a bunch of functions that will be triggered when the event is fired + 'event_send_mail' // don't forget to actually write this function at the end of this file + ), + 'self_sent' => true, // this key states that we can't add user to this event through the admin panel + 'name_lang_var' => get_lang('userRegistrationTitle'), + 'desc_lang_var' => get_lang('userRegistrationComment'), + 'available_keyvars' => array( // keys used for the mail template + 'url' => 'portal', + 'sitename' => 'sitename', + 'firstname' => 'firstname', + 'lastname' => 'lastname', + 'username' => 'username', + 'usermail' => 'usermail', + 'password' => 'password', + 'user_lang' => 'language', + 'admin_name' => 'administrator_name', + 'admin_surname' => 'administrator_surname', + 'admin_phone' => 'administrator_phone', + 'admin_email' => 'administrator_email', + ) + ), +); + +/**============================================================================ + * + * Filter functions + * + */ + +/** + * user_registration - send_mail filter + * @param array $values (passing by reference) + * @return boolean + */ +function user_registration_event_send_mail_filter_func(&$values) +{ + return true; +} + +/** + * For the sake of genericity, this function is a switch. + * It's called by EventsDispatcher and fires the good function + * with the good require_once. + * + * @param string $event_name + * @param array $params + */ +function event_send_mail($event_name, $params) +{ + require_once api_get_path(LIBRARY_PATH).'events_email.class.php'; + EventsMail::send_mail($event_name, $params); +} + +/** + * Internal function checking if the mail was already sent from that user to that user + * @param string $event_name + * @param int $user_from + * @param int $user_to + * @return boolean + */ +function check_if_mail_already_sent($event_name, $user_from, $user_to = null) +{ + if ($user_to == null) + { + $sql = 'SELECT COUNT(*) as total FROM ' . Database::get_main_table(TABLE_EVENT_SENT) . ' + WHERE user_from = '.$user_from.' AND event_type_name = "'.$event_name.'"; + '; + } + else + { + $sql = 'SELECT COUNT(*) as total FROM ' . Database::get_main_table(TABLE_EVENT_SENT) . ' + WHERE user_from = '.$user_from.' AND user_to = '.$user_to.' AND event_type_name = "'.$event_name.'"; + '; + } + + $result = Database::store_result(Database::query($sql), 'ASSOC'); + + return $result[0]["total"]; +} + +?> diff --git a/main/inc/lib/events.lib.inc.php b/main/inc/lib/events.lib.inc.php index 92f8e8af52..94e90c21a8 100644 --- a/main/inc/lib/events.lib.inc.php +++ b/main/inc/lib/events.lib.inc.php @@ -13,19 +13,17 @@ */ /* INIT SECTION */ - - $TABLETRACK_LOGIN = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_LOGIN); $TABLETRACK_OPEN = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_OPEN); $TABLETRACK_ACCESS = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ACCESS); +$course_tracking_table = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); $TABLETRACK_DOWNLOADS = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS); -$TABLETRACK_UPLOADS = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_UPLOADS); +$TABLETRACK_UPLOADS = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_UPLOADS); $TABLETRACK_LINKS = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_LINKS); $TABLETRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); -//$TABLETRACK_SUBSCRIPTIONS = $_configuration['statistics_database'].".track_e_subscriptions"; // this table is never use $TABLETRACK_LASTACCESS = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_LASTACCESS); //for "what's new" notification -$TABLETRACK_DEFAULT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_DEFAULT); -$course_tracking_table = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); +$TABLETRACK_DEFAULT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_DEFAULT); + /* FUNCTIONS */ /** @@ -71,8 +69,8 @@ function event_open() { * @desc Record information for login event * (when an user identifies himself with username & password) */ -function event_login() { - global $_configuration; +function event_login() { + global $_user; global $TABLETRACK_LOGIN; @@ -107,33 +105,33 @@ function event_login() { * @desc Record information for access event for courses */ function event_access_course() { - global $_configuration; - global $_user; - global $_cid; - global $TABLETRACK_ACCESS; - global $TABLETRACK_LASTACCESS; //for "what's new" notification - + global $_user, $TABLETRACK_ACCESS, $TABLETRACK_LASTACCESS; + $id_session = api_get_session_id(); - $reallyNow = api_get_utc_datetime(); + $now = api_get_utc_datetime(); + $_cid = api_get_course_id(); + if ($_user['user_id']) { $user_id = "'".$_user['user_id']."'"; } else { $user_id = "0"; // no one } $sql = "INSERT INTO ".$TABLETRACK_ACCESS." (access_user_id, access_cours_code, access_date, access_session_id) VALUES - (".$user_id.", '".$_cid."', '".$reallyNow."','".$id_session."')"; + (".$user_id.", '".$_cid."', '".$now."','".$id_session."')"; $res = Database::query($sql); + // added for "what's new" notification - $sql = "UPDATE $TABLETRACK_LASTACCESS SET access_date = '$reallyNow' + $sql = "UPDATE $TABLETRACK_LASTACCESS SET access_date = '$now' WHERE access_user_id = $user_id AND access_cours_code = '$_cid' AND access_tool IS NULL AND access_session_id=".$id_session; $res = Database::query($sql); + if (Database::affected_rows() == 0) { $sql = "INSERT INTO $TABLETRACK_LASTACCESS (access_user_id, access_cours_code, access_date, access_session_id) - VALUES (".$user_id.", '".$_cid."', '$reallyNow', '".$id_session."')"; + VALUES (".$user_id.", '".$_cid."', '$now', '".$id_session."')"; $res = Database::query($sql); } - // end "what's new" notification - return 1; + // end "what's new" notification + return 1; } /** @@ -154,8 +152,7 @@ function event_access_tool($tool, $id_session=0) { global $_configuration; global $_user; global $_cid; - global $TABLETRACK_ACCESS; - global $_configuration; + global $TABLETRACK_ACCESS; global $_course; global $TABLETRACK_LASTACCESS; //for "what's new" notification @@ -167,9 +164,10 @@ function event_access_tool($tool, $id_session=0) { // only if user comes from the course $_cid //if( eregi($_configuration['root_web'].$_cid,$_SERVER['HTTP_REFERER'] ) ) //$pos = strpos($_SERVER['HTTP_REFERER'],$_configuration['root_web'].$_cid); - $pos = strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_COURSE_PATH).$_course['path'])); + + $pos = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_COURSE_PATH).$_course['path'])) : false; // added for "what's new" notification - $pos2 = strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower($_configuration['root_web']."index")); + $pos2 = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower($_configuration['root_web']."index")) : false; // end "what's new" notification if ($pos !== false || $pos2 !== false) { $sql = "INSERT INTO ".$TABLETRACK_ACCESS." @@ -213,17 +211,14 @@ function event_access_tool($tool, $id_session=0) { * and later again. * Doing this twice causes an error, I remove one of them. */ -function event_download($doc_url) { - global $_configuration, $_user, $_cid; +function event_download($doc_url) { $tbl_stats_downloads = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS); $doc_url = Database::escape_string($doc_url); $reallyNow = api_get_utc_datetime(); - if ($_user['user_id']) { - $user_id = "'".$_user['user_id']."'"; - } else { - $user_id = "0"; - } + $user_id = "'".api_get_user_id()."'"; + $_cid = api_get_course_id(); + $sql = "INSERT INTO $tbl_stats_downloads ( down_user_id, down_cours_id, @@ -249,8 +244,7 @@ function event_download($doc_url) { * used in the works tool to record informations when * an user upload 1 work */ -function event_upload($doc_id) { - global $_configuration; +function event_upload($doc_id) { global $_user; global $_cid; global $TABLETRACK_UPLOADS; @@ -286,7 +280,7 @@ function event_upload($doc_id) { * it will be used in a redirection page */ function event_link($link_id) { - global $_configuration, $_user, $TABLETRACK_LINKS; + global $_user, $TABLETRACK_LINKS; $reallyNow = api_get_utc_datetime(); if (isset($_user['user_id']) && $_user['user_id']!='') { $user_id = "'".Database::escape_string($_user['user_id'])."'"; @@ -327,48 +321,67 @@ function event_link($link_id) { * @author Julio Montoya Armas Reworked 2010 * @desc Record result of user when an exercice was done */ -function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$learnpath_id=0, $learnpath_item_id=0, $learnpath_item_view_id = 0, $duration) { +function update_event_exercice($exeid, $exo_id, $score, $weighting,$session_id,$learnpath_id=0, $learnpath_item_id=0, $learnpath_item_view_id = 0, $duration, $question_list, $status = '', $remind_list = array()) { require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php'; - if ($exeid!='') { + if ($exeid != '') { // Validation in case of fraud with actived control time if (!exercise_time_control_is_valid($exo_id)) { $score = 0; } - $now = time(); + + /* start_date wouldn't be updated + $start_date_condition = ''; //Validation in case of wrong start_date if (isset($_SESSION['exercice_start_date'])) { $start_date = $_SESSION['exercice_start_date']; $diff = abs($start_date - $now); if ($diff > 14400) { // 14400 = 4h*60*60 more than 4h of diff $start_date = $now - 1800; // Now - 30min - } + } + }*/ + + if (!isset($status) || empty($status)) { + $status = ''; + } else { + $status = Database::escape_string($status); } $TABLETRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + $question_list = array_map('intval', $question_list); + + if (!empty($remind_list)) { + $remind_list = array_map('intval', $remind_list); + $remind_list = array_filter($remind_list); + $remind_list = implode(",", $remind_list); + } else { + $remind_list = ''; + } $sql = "UPDATE $TABLETRACK_EXERCICES SET - exe_exo_id = '".Database::escape_string($exo_id)."', - exe_result = '".Database::escape_string($score)."', - exe_weighting = '".Database::escape_string($weighting)."', - session_id = '".Database::escape_string($session_id)."', - orig_lp_id = '".Database::escape_string($learnpath_id)."', - orig_lp_item_id = '".Database::escape_string($learnpath_item_id)."', - orig_lp_item_view_id = '".Database::escape_string($learnpath_item_view_id)."', - exe_duration = '".Database::escape_string($duration)."', - exe_date = '".api_get_utc_datetime()."', - status = '', - start_date = '".api_get_utc_datetime($start_date)."' + exe_exo_id = '".Database::escape_string($exo_id)."', + exe_result = '".Database::escape_string($score)."', + exe_weighting = '".Database::escape_string($weighting)."', + session_id = '".Database::escape_string($session_id)."', + orig_lp_id = '".Database::escape_string($learnpath_id)."', + orig_lp_item_id = '".Database::escape_string($learnpath_item_id)."', + orig_lp_item_view_id = '".Database::escape_string($learnpath_item_view_id)."', + exe_duration = '".Database::escape_string($duration)."', + exe_date = '".api_get_utc_datetime()."', + status = '".$status."', + questions_to_check = '".$remind_list."', + data_tracking = '".implode(',', $question_list)."' WHERE exe_id = '".Database::escape_string($exeid)."'"; - $res = @Database::query($sql); + $res = Database::query($sql); - //Deleting control time session track - exercise_time_control_delete($exo_id); - //error_log('update_event_exercice'); - //error_log($sql); - return $res; + if ($debug) error_log('update_event_exercice called '); + if ($debug) error_log("$sql"); - } else + //Deleting control time session track + //exercise_time_control_delete($exo_id); + return $res; + } else { return false; + } } /** @@ -385,9 +398,11 @@ function create_event_exercice($exo_id) { $tbl_exe = Database::get_course_table(TABLE_QUIZ_TEST); $now = api_get_utc_datetime(); $uid = api_get_user_id(); + + $course_id = api_get_course_int_id(); // First, check the exercise exists - $sql_exe_id="SELECT exercises.id FROM $tbl_exe as exercises WHERE exercises.id=$exo_id"; + $sql_exe_id="SELECT exercises.id FROM $tbl_exe as exercises WHERE c_id = $course_id AND exercises.id=$exo_id"; $res_exe_id=Database::query($sql_exe_id); if ($res_exe_id === false) { return false; } //sql error if (Database::num_rows($res_exe_id)<1) { return false;} //exe not found @@ -432,51 +447,70 @@ function create_event_exercice($exo_id) { * @param integer Position * @return boolean Result of the insert query */ -function exercise_attempt($score, $answer, $quesId, $exeId, $j, $exercise_id = 0) { - global $_configuration; +function exercise_attempt($score, $answer, $question_id, $exe_id, $position, $exercise_id = 0, $nano = null) { require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php'; - $score = Database::escape_string($score); - $answer = Database::escape_string($answer); - $quesId = Database::escape_string($quesId); - $exeId = Database::escape_string($exeId); - $j = Database::escape_string($j); + global $debug; + $score = Database::escape_string($score); + $answer = Database::escape_string($answer); + $question_id = Database::escape_string($question_id); + $exe_id = Database::escape_string($exe_id); + $position = Database::escape_string($position); + $now = api_get_utc_datetime(); + $user_id = api_get_user_id(); $TBL_TRACK_ATTEMPT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); + + if ($debug) error_log("----- entering exercise_attempt function ------"); + + if ($debug) error_log("answer: $answer"); + if ($debug) error_log("score: $score"); + if ($debug) error_log("question_id : $question_id"); + if ($debug) error_log("position: $position"); - //Validation in case of fraud with actived control time - + //Validation in case of fraud with actived control time if (!exercise_time_control_is_valid($exercise_id)) { + if ($debug) error_log("exercise_time_control_is_valid is false"); $score = 0; - $answer = 0; - $j = 0; + $answer = 0; } - $reallyNow = api_get_utc_datetime(); - $user_id = api_get_user_id(); + + if (!empty($user_id)) { $user_id = "'".$user_id."'"; } else { // anonymous $user_id = api_get_anonymous_id(); + } + + $file = ''; + if (isset($nano)) { + $file = Database::escape_string(basename($nano->load_filename_if_exists(false))); } - $sql = "INSERT INTO $TBL_TRACK_ATTEMPT (exe_id, user_id, question_id, answer, marks, course_code, session_id, position, tms ) + $sql = "INSERT INTO $TBL_TRACK_ATTEMPT (exe_id, user_id, question_id, answer, marks, course_code, session_id, position, tms, filename) VALUES ( - ".$exeId.", + ".$exe_id.", ".$user_id.", - '".$quesId."', + '".$question_id."', '".$answer."', '".$score."', '".api_get_course_id()."', '".api_get_session_id()."', - '".$j."', - '".$reallyNow."' - )"; - //error_log($sql); - if (!empty($quesId) && !empty($exeId) && !empty($user_id)) { + '".$position."', + '".$now."', + '".$file."' + )"; + + if ($debug) error_log("Saving question attempt: "); + if ($debug) error_log($sql); + if ($debug) error_log(""); + + if (!empty($question_id) && !empty($exe_id) && !empty($user_id)) { $res = Database::query($sql); if (defined('ENABLED_LIVE_EXERCISE_TRACKING')){ $recording_table = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING); - $recording_changes = "INSERT INTO $recording_table (exe_id, question_id, marks, insert_date, author, session_id) VALUES ('$exeId','$quesId','$score','".api_get_utc_datetime()."','', '".api_get_session_id()."') "; + if ($debug) error_log("Saving e attempt recording "); + $recording_changes = "INSERT INTO $recording_table (exe_id, question_id, marks, insert_date, author, session_id) VALUES ('$exe_id','$question_id','$score','".api_get_utc_datetime()."','', '".api_get_session_id()."') "; Database::query($recording_changes); } return $res; @@ -524,193 +558,288 @@ function exercise_attempt_hotspot($exe_id, $question_id, $answer_id, $correct, $ * @param integer User ID (defaults to null) * @param string Course code (defaults to null) */ -function event_system($event_type, $event_value_type, $event_value, $timestamp = null, $user_id=null, $course_code=null) { - global $_configuration; - global $_user; +function event_system($event_type, $event_value_type, $event_value, $datetime = null, $user_id = null, $course_code = null) { global $TABLETRACK_DEFAULT; - $event_type = Database::escape_string($event_type); - $event_value_type = Database::escape_string($event_value_type); - $event_value = Database::escape_string($event_value); - $timestamp = Database::escape_string($timestamp); - $user_id = Database::escape_string($user_id); - $course_code = Database::escape_string($course_code); + $event_type = Database::escape_string($event_type); + $event_value_type = Database::escape_string($event_value_type); - if(!isset($timestamp)) { - $timestamp = api_get_utc_datetime(); - } - if(!isset($user_id)) { - $user_id = 0; + //Clean the user_info + if ($event_value_type == LOG_USER_OBJECT) { + if (is_array($event_value)) { + unset($event_value['complete_name']); + unset($event_value['firstName']); + unset($event_value['lastName']); + unset($event_value['avatar_small']); + unset($event_value['avatar']); + unset($event_value['password']); + unset($event_value['lastLogin']); + unset($event_value['picture_uri']); + $event_value = serialize($event_value); + } + } + + $event_value = Database::escape_string($event_value); + $course_info = api_get_course_info($course_code); + + if (!empty($course_info)) { + $course_id = $course_info['real_id']; + $course_code = $course_info['code']; + $course_code = Database::escape_string($course_code); + } else { + $course_id = null; + $course_code = null; + } + + if (!isset($datetime)) { + $datetime = api_get_utc_datetime(); } - if(!isset($course_code)) { - $course_code = ''; + + $datetime = Database::escape_string($datetime); + + if (!isset($user_id)) { + $user_id = api_get_user_id(); } + + $user_id = intval($user_id); + $sql = "INSERT INTO $TABLETRACK_DEFAULT (default_user_id, default_cours_code, + c_id, default_date, default_event_type, default_value_type, default_value ) - VALUES - ('$user_id.', + VALUES('$user_id.', '$course_code', - '$timestamp', + '$course_id', + '$datetime', '$event_type', '$event_value_type', '$event_value')"; $res = Database::query($sql); - + + //Sending notifications to users @todo check this + $send_event_setting = api_get_setting('activate_send_event_by_mail'); + if (!empty($send_event_setting) && $send_event_setting == 'true') { + global $language_file; + + //prepare message + list($message, $subject) = get_event_message_and_subject($event_type); + $mail_body=$message; + if (is_array($notification_infos)) { + foreach ($notification_infos as $variable => $value) { + $mail_body = str_replace('%'.$variable.'%',$value,$mail_body); + } + } + + //prepare mail common variables + if (empty($subject)) { + $subject = $event_type; + } + $mail_subject = '['.api_get_setting('siteName').'] '.$subject; + $sender_name = api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'), null, PERSON_NAME_EMAIL_ADDRESS); + $email_admin = api_get_setting('emailAdministrator'); + $emailfromaddr = api_get_setting('emailAdministrator'); + $emailfromname = api_get_setting('siteName'); + + //Send mail to all subscribed users + $users_arr = get_users_subscribed_to_event($event_type); + foreach ($users_arr as $user) { + $recipient_name = api_get_person_name($user['firstname'], $user['lastname']); + $email = $user['email']; + @api_mail($recipient_name, $email, $mail_subject, $mail_body, $sender_name, $email_admin); + } + } return true; } +/** + * Get the message and the subject for a event + * + * @param string event's name + */ function get_event_message_and_subject($event_name){ - $event_name = Database::escape_string($event_name); - $sql = 'SELECT m.message, m.subject FROM '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE).' e,' - .Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' m + $event_name = Database::escape_string($event_name); + $sql = 'SELECT m.message, m.subject FROM '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE).' e,' + .Database::get_main_table(TABLE_MAIN_EVENT_TYPE_MESSAGE).' m WHERE m.event_type_id = e.id '. "AND e.name = '$event_name'"; - $res = Database::store_result(Database::query($sql),'ASSOC'); - - $ret = array(); + $res = Database::store_result(Database::query($sql),'ASSOC'); + + $ret = array(); - if ( isset($res[0]['message']) ) { - $ret[0] = $res[0]['message']; - }else { - $ret[0] = ''; - } + if ( isset($res[0]['message']) ) { + $ret[0] = $res[0]['message']; + } else { + $ret[0] = ''; + } - if ( isset($res[0]['subject']) ) { - $ret[1] = $res[0]['subject']; - }else { - $ret[1] = ''; - } + if ( isset($res[0]['subject']) ) { + $ret[1] = $res[0]['subject']; + } else { + $ret[1] = ''; + } - return $ret; + return $ret; } /** - * Gets every record from event_type_message + * Get every email stored in the database * - * @param type $etId + * @param int $etId * @return type */ -function get_all_event_types($etId=0) +function get_all_event_types() { global $event_config; - $etId = intval($etId); - $sql = 'SELECT etm.id, event_type_name, activated, language_id, message, subject, dokeos_folder + $sql = 'SELECT etm.id, event_type_name, activated, language_id, message, subject, dokeos_folder FROM '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' etm INNER JOIN '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' l ON etm.language_id = l.id; '; - $eventsTypes = Database::store_result(Database::query($sql),'ASSOC'); + $events_types = Database::store_result(Database::query($sql),'ASSOC'); // echo $sql; - $to_return = array(); - foreach ($eventsTypes as $et){ - $et['nameLangVar'] = get_lang($event_config[$et["event_type_name"]]["name_lang_var"]); - $et['descLangVar'] = get_lang($event_config[$et["event_type_name"]]["desc_lang_var"]); - $to_return[] = $et; - } - return $to_return; + $to_return = array(); + foreach ($events_types as $et) { + $et['nameLangVar'] = get_lang($event_config[$et["event_type_name"]]["name_lang_var"]); + $et['descLangVar'] = get_lang($event_config[$et["event_type_name"]]["desc_lang_var"]); + $to_return[] = $et; + } + return $to_return; } +/** + * Get users linked to an event + * + * @param int $etId + * @return type + */ function get_users_subscribed_to_event($event_name){ - $event_name = Database::escape_string($event_name); - $sql = 'SELECT u.* FROM '. Database::get_main_table(TABLE_MAIN_USER).' u,' + $event_name = Database::escape_string($event_name); + $sql = 'SELECT u.* FROM '. Database::get_main_table(TABLE_MAIN_USER).' u,' .Database::get_main_table(TABLE_MAIN_EVENT_TYPE).' e,' .Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' ue WHERE ue.user_id = u.user_id AND e.name = \''.$event_name.'\' AND e.id = ue.event_type_id'; - return Database::store_result(Database::query($sql),'ASSOC'); + return Database::store_result(Database::query($sql),'ASSOC'); } +/** + * Get the users related to one event + * + * @param string $event_name + */ function get_event_users($event_name) { - $etId = intval($etId); - - $sql = 'SELECT user.* FROM '.Database::get_main_table(TABLE_MAIN_USER).' user + $sql = 'SELECT user.* FROM '.Database::get_main_table(TABLE_MAIN_USER).' user JOIN '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' relUser ON relUser.user_id = user.user_id WHERE relUser.event_type_name = "'.$event_name.'" '; - $eventsTypes = Database::store_result(Database::query($sql),'ASSOC'); + $events_types = Database::store_result(Database::query($sql),'ASSOC'); - return $eventsTypes; + return $events_types; } /** * Save the new message for one event and for one language * - * @param type $etId - * @param type $users - * @param type $message - * @param type $subject - * @param type $eventMessageLanguage + * @param string $eventName + * @param array $users + * @param string $message + * @param string $subject + * @param string $eventMessageLanguage + * @param int $activated */ -function save_event_type_message($eventName,$users,$message,$subject, $eventMessageLanguage, $activated) +function save_event_type_message($event_name,$users,$message,$subject, $event_message_language, $activated) { - $etId = intval($etId); - - // Deletes then re-adds the users linked to the event - $sql = 'DELETE FROM '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' - WHERE event_type_name = "'.$eventName.'" + // Deletes then re-adds the users linked to the event + $sql = 'DELETE FROM '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' + WHERE event_type_name = "'.$event_name.'" '; - Database::query($sql); + Database::query($sql); - foreach($users as $user) { - $sql = 'INSERT INTO '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' + foreach ($users as $user) { + $sql = 'INSERT INTO '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' (user_id,event_type_name) - VALUES('.intval($user).',"'. Database::escape_string($eventName).'") + VALUES('.intval($user).',"'. Database::escape_string($event_name).'") '; - Database::query($sql); - } + Database::query($sql); + } - // check if this template in this language already exists or not - $sql = 'SELECT COUNT(id) as total FROM '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' - WHERE event_type_name = "'.$eventName.'" AND language_id = (SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' - WHERE dokeos_folder = "'.$eventMessageLanguage.'") + // check if this template in this language already exists or not + $sql = 'SELECT COUNT(id) as total FROM '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' + WHERE event_type_name = "'.$event_name.'" AND language_id = (SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' + WHERE dokeos_folder = "'.$event_message_language.'") '; - $sql = Database::store_result(Database::query($sql),'ASSOC'); + $sql = Database::store_result(Database::query($sql),'ASSOC'); - if($sql[0]["total"] > 0) // if already exists, we update - { - $sql = 'UPDATE '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' + // if already exists, we update + if ($sql[0]["total"] > 0) { + $sql = 'UPDATE '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' SET message = "'.Database::escape_string($message).'", subject = "'.Database::escape_string($subject).'", activated = '.$activated.' - WHERE event_type_name = "'.Database::escape_string($eventName).'" AND language_id = (SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' - WHERE dokeos_folder = "'.$eventMessageLanguage.'") + WHERE event_type_name = "'.Database::escape_string($event_name).'" AND language_id = (SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' + WHERE dokeos_folder = "'.$event_message_language.'") '; - Database::query($sql); - } - else // else we create a new record - { - // gets the language_-_id - $lang_id = '(SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' - WHERE dokeos_folder = "'.$eventMessageLanguage.'")'; - $lang_id = Database::store_result(Database::query($lang_id),'ASSOC'); + Database::query($sql); + } else { // else we create a new record + // gets the language_-_id + $lang_id = '(SELECT id FROM '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' + WHERE dokeos_folder = "'.$event_message_language.'")'; + $lang_id = Database::store_result(Database::query($lang_id),'ASSOC'); - $sql = 'INSERT INTO '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' + $sql = 'INSERT INTO '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' (event_type_name, language_id, message, subject, activated) - VALUES("'.Database::escape_string($eventName).'", '.$lang_id[0]["id"].', "'.Database::escape_string($message).'", + VALUES("'.Database::escape_string($event_name).'", '.$lang_id[0]["id"].', "'.Database::escape_string($message).'", "'.Database::escape_string($subject).'", '.$activated.') '; - Database::query($sql); - } + Database::query($sql); + } - // set activated at every save - $sql = 'UPDATE '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' + // set activated at every save + $sql = 'UPDATE '.Database::get_main_table(TABLE_MAIN_EVENT_EMAIL_TEMPLATE).' SET activated = '.$activated.' - WHERE event_type_name = "'.Database::escape_string($eventName).'" + WHERE event_type_name = "'.Database::escape_string($event_name).'" '; - Database::query($sql); + Database::query($sql); +} + +function eventType_mod($etId,$users,$message,$subject) { + $etId = intval($etId); + + $sql = 'DELETE FROM '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' + WHERE event_type_id = '.$etId.' + '; + + Database::query($sql); + + foreach($users as $user) { + $sql = 'INSERT INTO '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_REL_USER).' + (user_id,event_type_id) + VALUES('.intval($user).','.$etId.') + '; + + Database::query($sql); + } + + $sql = 'UPDATE '.Database::get_main_table(TABLE_MAIN_EVENT_TYPE_MESSAGE).' + SET message = "'.Database::escape_string($message).'", + subject = "'.Database::escape_string($subject).'" + WHERE event_type_id = '.$etId.' + '; + + + Database::query($sql); } @@ -746,13 +875,19 @@ function get_attempt_count($user_id, $exerciseId, $lp_id, $lp_item_id,$lp_item_v $lp_item_id = intval($lp_item_id); $lp_item_view_id= intval($lp_item_view_id); - $sql = "SELECT count(*) as count FROM $stat_table WHERE exe_exo_id = '$exerciseId' - AND exe_user_id = '$user_id' AND status != 'incomplete' - AND orig_lp_id = $lp_id AND orig_lp_item_id = $lp_item_id AND orig_lp_item_view_id = $lp_item_view_id AND exe_cours_id = '".api_get_course_id()."' AND session_id = '" . api_get_session_id() . "'"; + $sql = "SELECT count(*) as count FROM $stat_table WHERE + exe_exo_id = $exerciseId AND + exe_user_id = $user_id AND + status != 'incomplete' AND + orig_lp_id = $lp_id AND + orig_lp_item_id = $lp_item_id AND + orig_lp_item_view_id = $lp_item_view_id AND + exe_cours_id = '".api_get_course_id()."' AND + session_id = '" . api_get_session_id() . "'"; $query = Database::query($sql); if (Database::num_rows($query) > 0 ) { - $attempt = Database :: fetch_array($query,'ASSOC'); + $attempt = Database :: fetch_array($query,'ASSOC'); return $attempt['count']; } else { return 0; @@ -760,10 +895,43 @@ function get_attempt_count($user_id, $exerciseId, $lp_id, $lp_item_id,$lp_item_v } + +function get_attempt_count_not_finished($user_id, $exerciseId, $lp_id, $lp_item_id) { + $stat_table = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + $user_id = intval($user_id); + $exerciseId = intval($exerciseId); + $lp_id = intval($lp_id); + $lp_item_id = intval($lp_item_id); + $lp_item_view_id= intval($lp_item_view_id); + + $sql = "SELECT count(*) as count FROM $stat_table WHERE + exe_exo_id = $exerciseId AND + exe_user_id = $user_id AND + status != 'incomplete' AND + orig_lp_id = $lp_id AND + orig_lp_item_id = $lp_item_id AND + exe_cours_id = '".api_get_course_id()."' AND + session_id = '" . api_get_session_id() . "'"; + + $query = Database::query($sql); + if (Database::num_rows($query) > 0 ) { + $attempt = Database :: fetch_array($query,'ASSOC'); + return $attempt['count']; + } else { + return 0; + } +} + + + function delete_student_lp_events($user_id, $lp_id, $course, $session_id) { - $lp_view_table = Database::get_course_table(TABLE_LP_VIEW, $course['dbName']); - $lp_item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW, $course['dbName']); + $lp_view_table = Database::get_course_table(TABLE_LP_VIEW); + $lp_item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW); + $course_id = $course['real_id']; + if (empty($course_id)) { + $course_id = api_get_course_int_id(); + } $track_e_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); $track_attempts = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); @@ -774,15 +942,18 @@ function delete_student_lp_events($user_id, $lp_id, $course, $session_id) { $session_id = intval($session_id); //make sure we have the exact lp_view_id - $sqlview = "SELECT id FROM $lp_view_table WHERE user_id = $user_id AND lp_id = $lp_id AND session_id = $session_id "; + $sqlview = "SELECT id FROM $lp_view_table WHERE c_id = $course_id AND user_id = $user_id AND lp_id = $lp_id AND session_id = $session_id "; $resultview = Database::query($sqlview); - $view = Database::fetch_array($resultview, 'ASSOC'); - $lp_view_id = $view['id']; - $sql_delete = "DELETE FROM $lp_item_view_table WHERE lp_view_id = $view_id "; - $result = Database::query($sql_delete); + if (Database::num_rows($sqlview)) { + $view = Database::fetch_array($resultview, 'ASSOC'); + $lp_view_id = $view['id']; + + $sql_delete = "DELETE FROM $lp_item_view_table WHERE c_id = $course_id AND lp_view_id = $lp_view_id "; + $result = Database::query($sql_delete); + } - $sql_delete = "DELETE FROM $lp_view_table WHERE user_id = $user_id AND lp_id= $lp_id AND session_id= $session_id "; + $sql_delete = "DELETE FROM $lp_view_table WHERE c_id = $course_id AND user_id = $user_id AND lp_id= $lp_id AND session_id= $session_id "; $result = Database::query($sql_delete); $select_all_attempts = "SELECT exe_id FROM $track_e_exercises WHERE exe_user_id = $user_id AND session_id= $session_id AND exe_cours_id = '{$course['code']}' AND orig_lp_id = $lp_id"; @@ -833,23 +1004,26 @@ function delete_all_incomplete_attempts($user_id, $exercise_id, $course_code, $s * @return array with the results * */ -function get_all_exercise_results($exercise_id, $course_code, $session_id = 0) { +function get_all_exercise_results($exercise_id, $course_code, $session_id = 0, $load_question_list = true) { $TABLETRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); $TBL_TRACK_ATTEMPT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $course_code = Database::escape_string($course_code); $exercise_id = intval($exercise_id); $session_id = intval($session_id); - $sql = "SELECT * FROM $TABLETRACK_EXERCICES WHERE status = '' AND exe_cours_id = '$course_code' AND exe_exo_id = '$exercise_id' AND session_id = $session_id AND orig_lp_id =0 AND orig_lp_item_id = 0 ORDER BY exe_id"; + $sql = "SELECT * FROM $TABLETRACK_EXERCICES + WHERE status = '' AND exe_cours_id = '$course_code' AND exe_exo_id = '$exercise_id' AND session_id = $session_id AND orig_lp_id =0 AND orig_lp_item_id = 0 ORDER BY exe_id"; $res = Database::query($sql); $list = array(); while($row = Database::fetch_array($res,'ASSOC')) { $list[$row['exe_id']] = $row; - $sql = "SELECT * FROM $TBL_TRACK_ATTEMPT WHERE exe_id = {$row['exe_id']}"; - $res_question = Database::query($sql); - while($row_q = Database::fetch_array($res_question,'ASSOC')) { - $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q; - } + if ($load_question_list) { + $sql = "SELECT * FROM $TBL_TRACK_ATTEMPT WHERE exe_id = {$row['exe_id']}"; + $res_question = Database::query($sql); + while($row_q = Database::fetch_array($res_question,'ASSOC')) { + $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q; + } + } } return $list; } @@ -857,7 +1031,6 @@ function get_all_exercise_results($exercise_id, $course_code, $session_id = 0) { /** * Gets all exercise results (NO Exercises in LPs ) from a given exercise id, course, session - * @param int exercise id * @param string course code * @param int session id * @return array with the results @@ -873,7 +1046,7 @@ function get_all_exercise_results_by_course($course_code, $session_id = 0, $get_ if ($get_count) { $select = 'count(*) as count'; } - $sql = "SELECT $select FROM $table_track_exercises WHERE status = '' AND exe_cours_id = '$course_code' AND session_id = $session_id AND orig_lp_id =0 AND orig_lp_item_id = 0 ORDER BY exe_id"; + $sql = "SELECT $select FROM $table_track_exercises WHERE status = '' AND exe_cours_id = '$course_code' AND session_id = $session_id AND orig_lp_id = 0 AND orig_lp_item_id = 0 ORDER BY exe_id"; $res = Database::query($sql); if ($get_count) { $row = Database::fetch_array($res,'ASSOC'); @@ -892,37 +1065,131 @@ function get_all_exercise_results_by_course($course_code, $session_id = 0, $get_ } } +/** +* Gets all exercise results (NO Exercises in LPs) from a given exercise id, course, session +* @param int exercise id +* @param string course code +* @param int session id +* @return array with the results +* +*/ +function get_all_exercise_results_by_user($user_id, $course_code, $session_id = 0) { + $table_track_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); + $table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); + $course_code = Database::escape_string($course_code); + $exercise_id = intval($exercise_id); + $session_id = intval($session_id); + $user_id = intval($user_id); + $sql = "SELECT * FROM $table_track_exercises WHERE status = '' AND exe_user_id = $user_id AND exe_cours_id = '$course_code' AND session_id = $session_id AND orig_lp_id = 0 AND orig_lp_item_id = 0 ORDER by exe_id"; + + $res = Database::query($sql); + $list = array(); + while($row = Database::fetch_array($res,'ASSOC')) { + $list[$row['exe_id']] = $row; + $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}"; + $res_question = Database::query($sql); + while($row_q = Database::fetch_array($res_question,'ASSOC')) { + $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q; + } + } + //echo '
'; print_r($list);
+	return $list;
+}
 
 /**
- * Gets all exercise results (NO Exercises in LPs) from a given exercise id, course, session
+* Gets exercise results (NO Exercises in LPs) from a given exercise id, course, session
+* @param   int     exercise id
+* @param   string  course code
+* @param   int     session id
+* @return  array   with the results
+*
+*/
+function get_exercise_results_by_attempt($exe_id) {
+	$table_track_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+	$table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+	$table_track_attempt_recording   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);	
+	$exe_id 		= intval($exe_id);
+	
+	$sql = "SELECT * FROM $table_track_exercises WHERE status = '' AND exe_id = $exe_id";    
+
+	$res = Database::query($sql);
+	$list = array();
+	if (Database::num_rows($res)) {
+	 	$row = Database::fetch_array($res,'ASSOC');
+	 	
+		//Checking if this attempt was revised by a teacher
+		$sql_revised = 'SELECT exe_id FROM ' . $table_track_attempt_recording . ' WHERE author != "" AND exe_id = '.$exe_id.' LIMIT 1';
+		$res_revised = Database::query($sql_revised);
+		$row['attempt_revised'] = 0;
+		if (Database::num_rows($res_revised) > 0) {
+			$row['attempt_revised'] = 1;
+		}
+		$list[$exe_id] = $row;
+		$sql = "SELECT * FROM $table_track_attempt WHERE exe_id = $exe_id ORDER BY tms ASC";
+		$res_question = Database::query($sql);
+		while ($row_q = Database::fetch_array($res_question,'ASSOC')) {
+			$list[$exe_id]['question_list'][$row_q['question_id']] = $row_q;
+		}
+	}
+	// echo '
'; print_r($list); echo "
"; + return $list; +} + +/** + * Gets exercise results (NO Exercises in LPs) from a given user, exercise id, course, session, lp_id, lp_item_id + * @param int user id * @param int exercise id * @param string course code * @param int session id + * @param int lp id + * @param int lp item id + * @param string order asc or desc * @return array with the results * */ -function get_all_exercise_results_by_user($user_id, $exercise_id, $course_code, $session_id = 0) { +function get_exercise_results_by_user($user_id, $exercise_id, $course_code, $session_id = 0, $lp_id = 0, $lp_item_id = 0, $order = null) { $table_track_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES); $table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); - $course_code = Database::escape_string($course_code); - $exercise_id = intval($exercise_id); - $session_id = intval($session_id); - $user_id = intval($user_id); + $table_track_attempt_recording = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING); + $course_code = Database::escape_string($course_code); + $exercise_id = intval($exercise_id); + $session_id = intval($session_id); + $user_id = intval($user_id); + $lp_id = intval($lp_id); + $lp_item_id = intval($lp_item_id); + + if (!in_array(strtolower($order), array('asc', 'desc'))) { + $order = 'asc'; + } - $sql = "SELECT * FROM $table_track_exercises WHERE status = '' AND exe_user_id = $user_id AND exe_cours_id = '$course_code' AND exe_exo_id = $exercise_id AND session_id = $session_id AND orig_lp_id = 0 AND orig_lp_item_id = 0 ORDER by exe_id"; + $sql = "SELECT * FROM $table_track_exercises + WHERE status = '' AND + exe_user_id = $user_id AND + exe_cours_id = '$course_code' AND + exe_exo_id = $exercise_id AND + session_id = $session_id AND + orig_lp_id = $lp_id AND + orig_lp_item_id = $lp_item_id + ORDER by exe_id $order "; $res = Database::query($sql); $list = array(); while($row = Database::fetch_array($res,'ASSOC')) { + //Checking if this attempt was revised by a teacher + $sql_revised = 'SELECT exe_id FROM ' . $table_track_attempt_recording . ' WHERE author != "" AND exe_id = '.$row['exe_id'].' LIMIT 1'; + $res_revised = Database::query($sql_revised); + $row['attempt_revised'] = 0; + if (Database::num_rows($res_revised) > 0) { + $row['attempt_revised'] = 1; + } $list[$row['exe_id']] = $row; $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}"; $res_question = Database::query($sql); - while($row_q = Database::fetch_array($res_question,'ASSOC')) { + while ($row_q = Database::fetch_array($res_question,'ASSOC')) { $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q; } - } - //echo '
'; print_r($list);
+    }    
     return $list;
 }
 
@@ -944,8 +1211,8 @@ function count_exercise_attempts_by_user($user_id, $exercise_id, $course_code, $
 	$session_id            = intval($session_id);
 	$user_id               = intval($user_id);
 	
-	$sql = "SELECT count(*) as count FROM $TABLETRACK_EXERCICES WHERE status = ''  AND exe_user_id = '$user_id' AND exe_cours_id = '$course_code' AND exe_exo_id = '$exercise_id' AND session_id = $session_id  AND orig_lp_id =0 AND orig_lp_item_id = 0 ORDER BY exe_id";
-	
+	$sql = "SELECT count(*) as count FROM $TABLETRACK_EXERCICES 
+			WHERE status = ''  AND exe_user_id = '$user_id' AND exe_cours_id = '$course_code' AND exe_exo_id = '$exercise_id' AND session_id = $session_id  AND orig_lp_id =0 AND orig_lp_item_id = 0 ORDER BY exe_id";
 	$res = Database::query($sql);
 	$result = 0;
 	if (Database::num_rows($res) > 0 ) {		
@@ -961,6 +1228,7 @@ function count_exercise_attempts_by_user($user_id, $exercise_id, $course_code, $
  * @param   string  course code
  * @param   int     session id
  * @return  array   with the results
+ * @todo rename this function
  * 
  */
 function get_best_exercise_results_by_user($exercise_id, $course_code, $session_id = 0) {
@@ -981,11 +1249,7 @@ function get_best_exercise_results_by_user($exercise_id, $course_code, $session_
 		while($row_q = Database::fetch_array($res_question,'ASSOC')) {
 			$list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
 		}		
-	}
-	/*
-	echo count($list);
-	echo '
'; - echo '
'; print_r($list);*/
+	}	
 	//Getting the best results of every student	
 	$best_score_return = array();
 	
@@ -996,13 +1260,80 @@ function get_best_exercise_results_by_user($exercise_id, $course_code, $session_
 	    if ($current_best_score[$user_id] > $best_score_return[$user_id]['exe_result']) {
 	        $best_score_return[$user_id] = $student_result;
 	    }
-	}
-	/*
-	echo count($best_score_return);
-	echo '
'; print_r($best_score_return);*/
+    }
 	return $best_score_return;
 }
 
+function get_best_attempt_exercise_results_per_user($user_id, $exercise_id, $course_code, $session_id = 0) {
+    $table_track_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+    $table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+    $course_code           = Database::escape_string($course_code);
+    $exercise_id           = intval($exercise_id);
+    $session_id            = intval($session_id);
+    $user_id               = intval($user_id);
+    
+    $sql = "SELECT * FROM $table_track_exercises 
+            WHERE   status = ''  AND 
+                    exe_cours_id = '$course_code' AND 
+                    exe_exo_id = '$exercise_id' AND 
+                    session_id = $session_id  AND 
+                    exe_user_id = $user_id AND
+                    orig_lp_id =0 AND 
+                    orig_lp_item_id = 0 
+                    ORDER BY exe_id";
+    
+    $res = Database::query($sql);
+    $list = array();
+    while($row = Database::fetch_array($res,'ASSOC')) {     
+        $list[$row['exe_id']] = $row;  /*     
+        $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
+        $res_question = Database::query($sql);
+        while($row_q = Database::fetch_array($res_question,'ASSOC')) {
+            $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
+        }       */
+    }   
+    //Getting the best results of every student
+    $best_score_return = array(); 
+    $best_score_return['exe_result'] = 0;
+    
+    foreach($list as $result) {
+        $current_best_score = $result;
+        if ($current_best_score['exe_result'] > $best_score_return['exe_result']) {
+            $best_score_return = $result;
+        }
+    }    
+    if (!isset($best_score_return['exe_weighting'])) {
+        $best_score_return = array();
+    }
+    return $best_score_return;
+}
+
+
+
+function count_exercise_result_not_validated($exercise_id, $course_code, $session_id = 0) {
+    $table_track_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+    $table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);     
+    $course_code           = Database::escape_string($course_code);    
+    $session_id     = intval($session_id);
+    $exercise_id    = intval($exercise_id);
+        
+    $status = Database::escape_string($status);
+        
+    $sql = "SELECT count(e.exe_id) as count FROM $table_track_exercises e LEFT JOIN $table_track_attempt a  ON e.exe_id = a.exe_id 
+            WHERE   exe_exo_id = $exercise_id AND 
+                    exe_cours_id = '$course_code' AND
+                    e.session_id = $session_id  AND 
+                    orig_lp_id = 0 AND
+                    marks IS NULL AND
+                    status = '' AND
+                    orig_lp_item_id = 0 ORDER BY e.exe_id";                          
+    $res = Database::query($sql);
+    $row = Database::fetch_array($res,'ASSOC');
+    
+    return $row['count'];
+    
+}
+
 
 /**
  * Gets all exercise BEST results attempts (NO Exercises in LPs ) from a given exercise id, course, session per user
@@ -1018,7 +1349,7 @@ function get_count_exercises_attempted_by_course($course_code, $session_id = 0)
 	$course_code           = Database::escape_string($course_code);	
 	$session_id            = intval($session_id);
 	
-	$sql = "SELECT DISTINCT exe_exo_id, exe_user_id FROM $table_track_exercises WHERE status = ''  AND exe_cours_id = '$course_code' AND session_id = $session_id  AND orig_lp_id =0 AND orig_lp_item_id = 0 ORDER BY exe_id";	
+	$sql = "SELECT DISTINCT exe_exo_id, exe_user_id FROM $table_track_exercises WHERE status = '' AND exe_cours_id = '$course_code' AND session_id = $session_id  AND orig_lp_id =0 AND orig_lp_item_id = 0 ORDER BY exe_id";	
 	$res = Database::query($sql);
 	$count = 0;
 	if (Database::num_rows($res) > 0) {
@@ -1040,8 +1371,7 @@ function get_all_exercise_event_from_lp($exercise_id, $course_code, $session_id
 	$table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
     $course_code = Database::escape_string($course_code);
     $exercise_id = intval($exercise_id);
-    $session_id = intval($session_id);
-    
+    $session_id = intval($session_id);    
   
     $sql = "SELECT * FROM $table_track_exercises WHERE status = ''  AND exe_cours_id = '$course_code' AND exe_exo_id = '$exercise_id' AND session_id = $session_id AND orig_lp_id !=0 AND orig_lp_item_id != 0";
     
@@ -1057,34 +1387,13 @@ function get_all_exercise_event_from_lp($exercise_id, $course_code, $session_id
     }
     return $list;
 }
-/*
-function get_all_exercise_event_from_lp($exercise_id, $course_db, $session_id ) {
-	$lp_item_table = Database  :: get_course_table(TABLE_LP_ITEM,$course_db);
-	$lp_item_view_table = Database  :: get_course_table(TABLE_LP_ITEM_VIEW,$course_db);
-	$lp_view_table = Database  :: get_course_table(TABLE_LP_VIEW,$course_db);
-	
-	$exercise_id 	= intval($exercise_id);
-	$session_id 	= intval($session_id);
-	
-	$sql = "SELECT  title, user_id, score , iv.max_score, status, session_id 
-			FROM $lp_item_table as i INNER JOIN $lp_item_view_table iv ON (i.id = iv.lp_item_id ) INNER JOIN $lp_view_table v ON iv.lp_view_id = v.id 
-			WHERE path = $exercise_id AND status ='completed' AND session_id = $session_id";
-	$res = Database::query($sql);
-	$list = array();	
-	
-	while($row = Database::fetch_array($res,'ASSOC')) {		
-		$list[$row['exe_id']]['question_list'][$row['question_id']] = $row;				
-	}
-	//echo '
'; print_r($list);
-	return $list;
-}*/
 
 
-
-function get_all_exercises_from_lp($lp_id, $course_db) {
-	$lp_item_table = Database  :: get_course_table(TABLE_LP_ITEM,$course_db);
+function get_all_exercises_from_lp($lp_id, $course_id) {
+	$lp_item_table = Database  :: get_course_table(TABLE_LP_ITEM);
+	$course_id = intval($course_id);
 	$lp_id = intval($lp_id);
-	$sql = "SELECT * FROM $lp_item_table WHERE lp_id = '".$lp_id."'  ORDER BY parent_item_id, display_order";
+	$sql = "SELECT * FROM $lp_item_table WHERE c_id = $course_id AND lp_id = '".$lp_id."'  ORDER BY parent_item_id, display_order";
 	$res = Database::query($sql);
 	$my_exercise_list = array();	
 	while($row = Database::fetch_array($res,'ASSOC')) {
@@ -1110,23 +1419,67 @@ function get_comments($id,$question_id) {
     $comm = Database::result($sqlres,0,"teacher_comment");
     return $comm;
 }
- 
-/** 
+
+
+function get_all_exercise_event_by_exe_id($exe_id) {
+	$table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+	$exe_id = intval($exe_id);
+	$list = array();
+
+	$sql = "SELECT * FROM $table_track_attempt WHERE exe_id = $exe_id ORDER BY position";
+	$res_question = Database::query($sql);
+	if (Database::num_rows($res_question))
+	while($row_q = Database::fetch_array($res_question,'ASSOC')) {
+		$list[$row_q['question_id']][] = $row_q;
+	}
+	return $list;
+}
+
+
+function delete_attempt($exe_id, $user_id, $course_code, $session_id, $question_id) {
+	$table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+
+	$exe_id          = intval($exe_id);
+	$user_id         = intval($user_id);
+	$course_code     = Database::escape_string($course_code);
+	$session_id      = intval($session_id);
+	$question_id     = intval($question_id);
+
+	$sql = "DELETE FROM $table_track_attempt WHERE exe_id = $exe_id AND user_id = $user_id AND course_code = '$course_code' AND session_id = $session_id AND question_id = $question_id ";
+	Database::query($sql);
+}
+
+function delete_attempt_hotspot($exe_id, $user_id, $course_code, $question_id) {
+	$table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
+
+	$exe_id          = intval($exe_id);
+	$user_id         = intval($user_id);
+	$course_code     = Database::escape_string($course_code);
+	//$session_id      = intval($session_id);
+	$question_id     = intval($question_id);
+
+	$sql = "DELETE FROM $table_track_attempt WHERE hotspot_exe_id = $exe_id AND hotspot_user_id = $user_id AND hotspot_course_code = '$course_code' AND hotspot_question_id = $question_id ";
+	Database::query($sql);
+}
+
+/**
  * User logs in for the first time to a course
- * @param	string 	Course code
- * @param	int	User ID
- * @param	int	Session ID
  */
 function event_course_login($course_code, $user_id, $session_id) {
-    global $course_tracking_table;
-    //@todo use api_get_utc_datetime
-    $time		 = api_get_datetime();
-    $course_code = Database::escape_string($course_code);
-    $user_id	 = Database::escape_string($user_id);
-    $session_id  = Database::escape_string($session_id);
-    $sql	= "INSERT INTO $course_tracking_table(course_code, user_id, login_course_date, logout_course_date, counter, session_id)
-         VALUES('".$course_code."', '".$user_id."', '$time', '$time', '1', '".$session_id."')";
-    Database::query($sql);
-    //Course catalog stats modifications see #4191
+	global $course_tracking_table;
+	
+	//@todo use api_get_utc_datetime
+	$time		 = api_get_datetime();
+	
+	$course_code = Database::escape_string($course_code);
+	$user_id	 = Database::escape_string($user_id);
+	$session_id  = Database::escape_string($session_id);
+	
+	$sql	= "INSERT INTO $course_tracking_table(course_code, user_id, login_course_date, logout_course_date, counter, session_id) 
+			  VALUES('".$course_code."', '".$user_id."', '$time', '$time', '1', '".$session_id."')";
+	Database::query($sql);
+	
+	
+    //Course catalog stats modifications see #4191    
     CourseManager::update_course_ranking(null, null, null, null, true, false);
 }
diff --git a/main/inc/lib/events_dispatcher.class.php b/main/inc/lib/events_dispatcher.class.php
index 69dffc919f..607ff42677 100644
--- a/main/inc/lib/events_dispatcher.class.php
+++ b/main/inc/lib/events_dispatcher.class.php
@@ -18,7 +18,7 @@ class EventsDispatcher
         // and execute every actions with the values
         foreach ($event_config[$event_name]["actions"] as $func) 
         {
-            if(!function_exists($func)) // if the function doesn't exist, we log
+            if (!function_exists($func)) // if the function doesn't exist, we log
             {
                 error_log("EventsDispatcher warning : ".$func." does not exist.");
             }
@@ -33,7 +33,7 @@ class EventsDispatcher
                 error_log("EventsDispatcher warning : ".$event_name."_".$func."_filter_func does not exist.");
             }
 
-            if(!$execute) // if the filter says we cannot send the mail, we get out of here
+            if (!$execute) // if the filter says we cannot send the mail, we get out of here
             {
                 return false;
             }
diff --git a/main/inc/lib/events_email.class.php b/main/inc/lib/events_email.class.php
index 3c96abae4c..a95cee4f2a 100644
--- a/main/inc/lib/events_email.class.php
+++ b/main/inc/lib/events_email.class.php
@@ -1,19 +1,21 @@
 ", $message);                  
                     @api_mail_html($recipient_name, $user_info["mail"], $subject, $message, $sender_name, $email_admin, null, array($values['certificate_pdf_file']));
@@ -98,8 +101,8 @@ class EventsMail
                     @api_mail($recipient_name, $user_info["mail"], $subject, $message, $sender_name, $email_admin);
                 }
                 
-                // If the mail only need to be send once (we know that thanks to the events.conf, we log it in the table
-                if($event_config[$event_name]["sending_mail_once"])
+                // If the mail only need to be send once (we know that thanks to the events.conf), we log it in the table
+                if ($event_config[$event_name]["sending_mail_once"])
                 {
                     $sql = 'INSERT INTO ' . Database::get_main_table(TABLE_EVENT_SENT) . ' 
                         (user_from, user_to, event_type_name)
@@ -148,7 +151,7 @@ class EventsMail
             @api_mail($recipient_name, $value["email"], $subject, $message, $sender_name, $email_admin);
             
             // If the mail only need to be send once (we know that thanks to the events.conf, we log it in the table
-            if($event_config[$event_name]["sending_mail_once"])
+            if ($event_config[$event_name]["sending_mail_once"])
             {
                 $sql = 'INSERT INTO ' . Database::get_main_table(TABLE_EVENT_SENT) . ' 
                     (user_from, user_to, event_type_name)
@@ -163,10 +166,13 @@ class EventsMail
      * Checks if a message in a language exists, if the event is activated 
      * and if "manage event" is checked in admin panel.
      * If yes to three, we can use this class, else we still use api_mail. 
+     *
+     * @param string $event_name
+     * @return boolean 
      */
     public static function check_if_using_class($event_name) 
     {
-	if(api_get_setting('activate_email_template') === 'false')
+	if (api_get_setting('activate_email_template') === 'false')
 	{
 		return false;
 	}
@@ -191,9 +197,9 @@ class EventsMail
     /**
      * Get the record containing the good message and subject
      *
-     * @param type $event_name
-     * @param type $language
-     * @return type 
+     * @param string $event_name
+     * @param string $language
+     * @return array 
      */
     private static function getMessage($event_name, $language)
     {
@@ -207,10 +213,10 @@ class EventsMail
     /**
      * Get the correct message, meaning in the specified language or in english if previous one doesn't exist
      *
-     * @param type $message
-     * @param type $subject
-     * @param type $language
-     * @param type $result 
+     * @param string $message
+     * @param string $subject
+     * @param string $language
+     * @param array $result 
      */
     private static function getCorrectMessage(&$message, &$subject, $language, $result)
     {
@@ -231,12 +237,12 @@ class EventsMail
     }
     
     /**
-     * Replaces the %key% by the good values
+     * Replaces the ((key)) by the good values
      *
-     * @param type $message
-     * @param type $subject
-     * @param type $event_config
-     * @param type $event_name 
+     * @param string $message
+     * @param string $subject
+     * @param array $event_config
+     * @param string $event_name 
      */
     private static function formatMessage(&$message, &$subject, $event_config, $event_name, &$event_data)
     {
diff --git a/main/inc/lib/usermanager.lib.php b/main/inc/lib/usermanager.lib.php
index bd21aa9dd4..758831f293 100644
--- a/main/inc/lib/usermanager.lib.php
+++ b/main/inc/lib/usermanager.lib.php
@@ -170,7 +170,6 @@ class UserManager {
 			if(EventsMail::check_if_using_class('user_registration'))
                         {
                             $values["about_user"] = $return;
-                            $values["portal"] = $_configuration['root_web'];
                             $values["password"] = $original_password;
                             
                             $values["send_to"] = array($return);
@@ -182,9 +181,9 @@ class UserManager {
                         {
                             @api_mail_html($recipient_name, $email, $emailsubject, $emailbody, $sender_name, $email_admin);  
                         }
+			/* ENDS MANAGE EVENT WITH MAIL */ 
               
 			}
-			/* ENDS MANAGE EVENT WITH MAIL */ 
           
 
 			// Add event to system log			
diff --git a/main/install/install_files.inc.php b/main/install/install_files.inc.php
index c5abdb00a8..1028c05103 100644
--- a/main/install/install_files.inc.php
+++ b/main/install/install_files.inc.php
@@ -30,6 +30,7 @@ if (defined('SYSTEM_INSTALLATION')) {
 	copy(api_get_path(CONFIGURATION_PATH).'course_info.conf.dist.php', api_get_path(CONFIGURATION_PATH).'course_info.conf.php');
 	copy(api_get_path(CONFIGURATION_PATH).'mail.conf.dist.php', api_get_path(CONFIGURATION_PATH).'mail.conf.php');
 	copy(api_get_path(CONFIGURATION_PATH).'profile.conf.dist.php', api_get_path(CONFIGURATION_PATH).'profile.conf.php');
+	copy(api_get_path(CONFIGURATION_PATH).'events.conf.dist.php', api_get_path(CONFIGURATION_PATH).'events.conf.php');
 } else {
 	echo 'You are not allowed here !';
 }
diff --git a/main/install/update-files-1.8.8-1.9.0.inc.php b/main/install/update-files-1.8.8-1.9.0.inc.php
index dfece002e4..7ddcaddbde 100644
--- a/main/install/update-files-1.8.8-1.9.0.inc.php
+++ b/main/install/update-files-1.8.8-1.9.0.inc.php
@@ -68,6 +68,11 @@ EOP;
         fwrite($fh,$string);
 	fwrite($fh, '?>');
 	fclose($fh);
+	//Adds events.conf file
+	if (! file_exists(api_get_path(CONFIGURATION_PATH).'events.conf.php')) {
+		copy(api_get_path(CONFIGURATION_PATH).'events.conf.dist.php', api_get_path(CONFIGURATION_PATH).'events.conf.php');
+	}
+
 
 } else {