/** * Get the users to display on the current page (fill the sortable-table) * @param int offset of first user to recover * @param int Number of users to get * @param int Column to sort on * @param string Order (ASC,DESC) * @see SortableTable#get_table_data($from) */ function get_user_data($from, $number_of_items, $column, $direction) { $sql = prepare_user_sql_query(false); /* @todo will not work because now we use the salt field $checkPassStrength = isset($_GET['check_easy_passwords']) && $_GET['check_easy_passwords'] == 1 ? true : false; if ($checkPassStrength) { $easyPasswordList = api_get_easy_password_list(); $easyPasswordList = array_map('api_get_encrypted_password', $easyPasswordList); $easyPasswordList = array_map(array('Database', 'escape_string'), $easyPasswordList); $easyPassword = implode("' OR password LIKE '", $easyPasswordList); $sql .= "AND password LIKE '$easyPassword' "; }*/ if (!in_array($direction, array('ASC', 'DESC'))) { $direction = 'ASC'; } $column = intval($column); $from = intval($from); $number_of_items = intval($number_of_items); $preventSessionAdminsToManageAllUsers = api_get_setting('prevent_session_admins_to_manage_all_users'); if (api_is_session_admin() && $preventSessionAdminsToManageAllUsers === 'true') { $sql .= " WHERE u.creator_id = " . api_get_user_id(); } $sql .= " ORDER BY col{$column} {$direction} "; $sql .= " LIMIT {$from},{$number_of_items}"; $res = Database::query($sql); $users = array(); $t = time(); while ($user = Database::fetch_row($res)) { $userPicture = UserManager::getUserPicture($user[0], USER_IMAGE_SIZE_SMALL); $photo = '<img src="' . $userPicture . '" width="22" height="22" alt="' . api_get_person_name($user[2], $user[3]) . '" title="' . api_get_person_name($user[2], $user[3]) . '" />'; if ($user[7] == 1 && !empty($user[10])) { // check expiration date $expiration_time = convert_sql_date($user[10]); // if expiration date is passed, store a special value for active field if ($expiration_time < $t) { $user[7] = '-1'; } } // forget about the expiration date field $users[] = array($user[0], $photo, $user[1], $user[2], $user[3], $user[4], $user[5], $user[6], $user[7], api_get_local_time($user[9]), $user[0]); } return $users; }
/** * Returns the "what's new" icon notifications * * The general logic of this function is to track the last time the user * entered the course and compare to what has changed inside this course * since then, based on the item_property table inside this course. Note that, * if the user never entered the course before, he will not see notification * icons. This function takes session ID into account (if any) and only shows * the corresponding notifications. * @param array Course information array, containing at least elements 'db' and 'k' * @return string The HTML link to be shown next to the course */ public static function show_notification($course_info) { $t_track_e_access = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_LASTACCESS); $course_tool_table = Database::get_course_table(TABLE_TOOL_LIST); $tool_edit_table = Database::get_course_table(TABLE_ITEM_PROPERTY); $course_code = Database::escape_string($course_info['code']); $user_id = api_get_user_id(); $course_id = $course_info['real_id']; $course_info['id_session'] = intval($course_info['id_session']); // Get the user's last access dates to all tools of this course $sql = "SELECT *\n FROM {$t_track_e_access} USE INDEX (access_cours_code, access_user_id)\n WHERE\n access_cours_code = '" . $course_code . "' AND\n access_user_id = '{$user_id}' AND\n access_session_id ='" . $course_info['id_session'] . "'"; $resLastTrackInCourse = Database::query($sql); $oldestTrackDate = $oldestTrackDateOrig = '3000-01-01 00:00:00'; while ($lastTrackInCourse = Database::fetch_array($resLastTrackInCourse)) { $lastTrackInCourseDate[$lastTrackInCourse['access_tool']] = $lastTrackInCourse['access_date']; if ($oldestTrackDate > $lastTrackInCourse['access_date']) { $oldestTrackDate = $lastTrackInCourse['access_date']; } } if ($oldestTrackDate == $oldestTrackDateOrig) { //if there was no connexion to the course ever, then take the // course creation date as a reference $course_table = Database::get_main_table(TABLE_MAIN_COURSE); $sql = "SELECT course.creation_date " . "FROM {$course_table} course " . "WHERE course.code = '" . $course_code . "'"; $res = Database::query($sql); if ($res && Database::num_rows($res) > 0) { $row = Database::fetch_array($res); } $oldestTrackDate = $row['creation_date']; } // Get the last edits of all tools of this course. $sql = "SELECT\n tet.*,\n tet.lastedit_date last_date,\n tet.tool tool,\n tet.ref ref,\n tet.lastedit_type type,\n tet.to_group_id group_id,\n ctt.image image,\n ctt.link link\n FROM {$tool_edit_table} tet, {$course_tool_table} ctt\n WHERE\n tet.c_id = {$course_id} AND\n ctt.c_id = {$course_id} AND\n tet.lastedit_date > '{$oldestTrackDate}' " . " AND (ctt.name = tet.tool OR (ctt.name = 'student_publication' AND tet.tool = 'work')) " . " AND ctt.visibility = '1' " . " AND tet.lastedit_user_id != {$user_id} AND tet.id_session = '" . $course_info['id_session'] . "'\n ORDER BY tet.lastedit_date"; $res = Database::query($sql); // Get the group_id's with user membership. $group_ids = GroupManager::get_group_ids($course_info['real_id'], $user_id); $group_ids[] = 0; //add group 'everyone' $notifications = array(); // Filter all last edits of all tools of the course while ($res && ($item_property = Database::fetch_array($res))) { // First thing to check is if the user never entered the tool // or if his last visit was earlier than the last modification. if ((!isset($lastTrackInCourseDate[$item_property['tool']]) || $lastTrackInCourseDate[$item_property['tool']] < $item_property['lastedit_date']) && (in_array($item_property['to_group_id'], $group_ids) && ($item_property['tool'] != TOOL_DROPBOX && $item_property['tool'] != TOOL_NOTEBOOK && $item_property['tool'] != TOOL_CHAT)) && ($item_property['visibility'] == '1' || $course_info['status'] == '1' && $item_property['visibility'] == '0' || !isset($item_property['visibility']))) { if ($course_info['real_id'] == 1) { // var_dump($item_property); } // Also drop announcements and events that are not for the user or his group. if (($item_property['tool'] == TOOL_ANNOUNCEMENT || $item_property['tool'] == TOOL_CALENDAR_EVENT) && ($item_property['to_user_id'] != $user_id && (!isset($item_property['to_group_id']) || !in_array($item_property['to_group_id'], $group_ids)))) { continue; } // If it's a survey, make sure the user's invited. Otherwise drop it. if ($item_property['tool'] == TOOL_SURVEY) { $survey_info = survey_manager::get_survey($item_property['ref'], 0, $course_code); if (!empty($survey_info)) { $invited_users = SurveyUtil::get_invited_users($survey_info['code'], $course_code); if (!in_array($user_id, $invited_users['course_users'])) { continue; } } } // If it's a learning path, ensure it is currently visible to the user if ($item_property['tool'] == TOOL_LEARNPATH) { require_once api_get_path(SYS_CODE_PATH) . 'newscorm/learnpath.class.php'; if (!learnpath::is_lp_visible_for_student($item_property['ref'], $user_id, $course_code)) { continue; } } if ($item_property['tool'] == 'work' && $item_property['type'] == 'DirectoryCreated') { $item_property['lastedit_type'] = 'WorkAdded'; } $notifications[$item_property['tool']] = $item_property; } } // Show all tool icons where there is something new. $retvalue = ' '; while (list($key, $notification) = each($notifications)) { $lastDate = date('d/m/Y H:i', convert_sql_date($notification['lastedit_date'])); $type = $notification['lastedit_type']; if (empty($course_info['id_session'])) { $my_course['id_session'] = 0; } else { $my_course['id_session'] = $course_info['id_session']; } $label = get_lang('TitleNotification') . ": " . get_lang($type) . " ({$lastDate})"; $retvalue .= '<a href="' . api_get_path(WEB_CODE_PATH) . $notification['link'] . '?cidReq=' . $course_code . '&ref=' . $notification['ref'] . '&gidReq=' . $notification['to_group_id'] . '&id_session=' . $my_course['id_session'] . '">' . Display::return_icon($notification['image'], $label) . '</a> '; } return $retvalue; }
/** * Get the users to display on the current page (fill the sortable-table) * @param int offset of first user to recover * @param int Number of users to get * @param int Column to sort on * @param string Order (ASC,DESC) * @see SortableTable#get_table_data($from) */ function get_user_data($from, $number_of_items, $column, $direction) { $sql = prepare_user_sql_query(false); $checkPassStrength = isset($_GET['check_easy_passwords']) && $_GET['check_easy_passwords'] == 1 ? true : false; if ($checkPassStrength) { $easyPasswordList = api_get_easy_password_list(); $easyPasswordList = array_map('api_get_encrypted_password', $easyPasswordList); $easyPasswordList = array_map(array('Database', 'escape_string'), $easyPasswordList); $easyPassword = implode("' OR password LIKE '", $easyPasswordList); $sql .= "AND password LIKE '{$easyPassword}' "; } if (!in_array($direction, array('ASC', 'DESC'))) { $direction = 'ASC'; } $column = intval($column); $from = intval($from); $number_of_items = intval($number_of_items); global $_configuration; if (api_is_session_admin() && isset($_configuration['prevent_session_admins_to_manage_all_users']) && $_configuration['prevent_session_admins_to_manage_all_users'] == 'true') { $sql .= " WHERE u.creator_id = " . api_get_user_id(); } $sql .= " ORDER BY col{$column} {$direction} "; $sql .= " LIMIT {$from},{$number_of_items}"; $res = Database::query($sql); $users = array(); $t = time(); while ($user = Database::fetch_row($res)) { $image_path = UserManager::get_user_picture_path_by_id($user[0], 'web', false, true); $user_profile = UserManager::get_picture_user($user[0], $image_path['file'], 22, USER_IMAGE_SIZE_SMALL, ' width="22" height="22" '); if (!api_is_anonymous()) { $photo = '<center><a href="' . api_get_path(WEB_PATH) . 'whoisonline.php?origin=user_list&id=' . $user[0] . '" title="' . get_lang('Info') . '"> <img src="' . $user_profile['file'] . '" ' . $user_profile['style'] . ' alt="' . api_get_person_name($user[2], $user[3]) . '" title="' . api_get_person_name($user[2], $user[3]) . '" /></a></center>'; } else { $photo = '<center><img src="' . $user_profile['file'] . '" ' . $user_profile['style'] . ' alt="' . api_get_person_name($user[2], $user[3]) . '" title="' . api_get_person_name($user[2], $user[3]) . '" /></center>'; } if ($user[7] == 1 && $user[10] != '0000-00-00 00:00:00') { // check expiration date $expiration_time = convert_sql_date($user[10]); // if expiration date is passed, store a special value for active field if ($expiration_time < $t) { $user[7] = '-1'; } } // forget about the expiration date field $users[] = array($user[0], $photo, $user[1], $user[2], $user[3], $user[4], $user[5], $user[6], $user[7], api_get_local_time($user[9]), $user[0]); } return $users; }
/** * Writes the current data to the database * @return boolean Query result */ public function write_to_db() { if (self::debug > 0) { error_log('learnpathItem::write_to_db()', 0); } // Check the session visibility. if (!api_is_allowed_to_session_edit()) { if (self::debug > 0) { error_log('return false api_is_allowed_to_session_edit'); } return false; } $course_id = api_get_course_int_id(); $mode = $this->get_lesson_mode(); $credit = $this->get_credit(); $item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW); $sql = 'SELECT status FROM ' . $item_view_table . ' WHERE c_id = ' . $course_id . ' AND lp_item_id="' . $this->db_id . '" AND lp_view_id="' . $this->view_id . '" AND view_count="' . $this->get_attempt_id() . '" '; $rs_verified = Database::query($sql); $row_verified = Database::fetch_array($rs_verified); $my_case_completed = array('completed', 'passed', 'browsed', 'failed'); $save = true; if (isset($row_verified) && isset($row_verified['status'])) { if (in_array($row_verified['status'], $my_case_completed)) { $save = false; } } if (($save === false && $this->type == 'sco' || $this->type == 'sco' && ($credit == 'no-credit' || $mode == 'review' || $mode == 'browse')) && ($this->seriousgame_mode != 1 && $this->type == 'sco')) { if (self::debug > 1) { error_log("This info shouldn't be saved as the credit or lesson mode info prevent it"); error_log('learnpathItem::write_to_db() - credit(' . $credit . ') or' . ' lesson_mode(' . $mode . ') prevent recording!', 0); } } else { // Check the row exists. $inserted = false; // This a special case for multiple attempts and Chamilo exercises. if ($this->type == 'quiz' && $this->get_prevent_reinit() == 0 && $this->get_status() == 'completed') { // We force the item to be restarted. $this->restart(); $params = array("c_id" => $course_id, "total_time" => $this->get_total_time(), "start_time" => $this->current_start_time, "score" => $this->get_score(), "status" => $this->get_status(false), "max_score" => $this->get_max(), "lp_item_id" => $this->db_id, "lp_view_id" => $this->view_id, "view_count" => $this->get_attempt_id(), "suspend_data" => $this->current_data, "lesson_location" => $this->lesson_location); if (self::debug > 2) { error_log('learnpathItem::write_to_db() - Inserting into item_view forced: ' . print_r($params, 1), 0); } $this->db_item_view_id = Database::insert($item_view_table, $params); if ($this->db_item_view_id) { $sql = "UPDATE {$item_view_table} SET id = iid\n WHERE iid = " . $this->db_item_view_id; Database::query($sql); $inserted = true; } } $item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW); $sql = "SELECT * FROM {$item_view_table}\n WHERE\n c_id = {$course_id} AND\n lp_item_id = " . $this->db_id . " AND\n lp_view_id = " . $this->view_id . " AND\n view_count = " . intval($this->get_attempt_id()); if (self::debug > 2) { error_log('learnpathItem::write_to_db() - Querying item_view: ' . $sql, 0); } $check_res = Database::query($sql); // Depending on what we want (really), we'll update or insert a new row // now save into DB. if (!$inserted && Database::num_rows($check_res) < 1) { $params = array("c_id" => $course_id, "total_time" => $this->get_total_time(), "start_time" => $this->current_start_time, "score" => $this->get_score(), "status" => $this->get_status(false), "max_score" => $this->get_max(), "lp_item_id" => $this->db_id, "lp_view_id" => $this->view_id, "view_count" => $this->get_attempt_id(), "suspend_data" => $this->current_data, "lesson_location" => $this->lesson_location); if (self::debug > 2) { error_log('learnpathItem::write_to_db() - Inserting into item_view forced: ' . print_r($params, 1), 0); } $this->db_item_view_id = Database::insert($item_view_table, $params); if ($this->db_item_view_id) { $sql = "UPDATE {$item_view_table} SET id = iid\n WHERE iid = " . $this->db_item_view_id; Database::query($sql); } } else { if ($this->type == 'hotpotatoes') { $params = array('total_time' => $this->get_total_time(), 'start_time' => $this->get_current_start_time(), 'score' => $this->get_score(), 'status' => $this->get_status(false), 'max_score' => $this->get_max(), 'suspend_data' => $this->current_data, 'lesson_location' => $this->lesson_location); $where = array('c_id = ? AND lp_item_id = ? AND lp_view_id = ? AND view_count = ?' => array($course_id, $this->db_id, $this->view_id, $this->get_attempt_id())); Database::update($item_view_table, $params, $where); } else { // For all other content types... $my_status = ' '; $total_time = ' '; if ($this->type == 'quiz') { if (!empty($_REQUEST['exeId'])) { $TBL_TRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); $safe_exe_id = intval($_REQUEST['exeId']); $sql = "SELECT start_date,exe_date\n FROM {$TBL_TRACK_EXERCICES}\n WHERE exe_id = {$safe_exe_id}"; $res = Database::query($sql); $row_dates = Database::fetch_array($res); $time_start_date = convert_sql_date($row_dates['start_date']); $time_exe_date = convert_sql_date($row_dates['exe_date']); $mytime = (int) $time_exe_date - (int) $time_start_date; $total_time = " total_time = " . $mytime . ", "; } } else { $my_type_lp = learnpath::get_type_static($this->lp_id); // This is a array containing values finished $case_completed = array('completed', 'passed', 'browsed', 'failed'); // Is not multiple attempts if ($this->seriousgame_mode == 1 && $this->type == 'sco') { $total_time = " total_time = total_time +" . $this->get_total_time() . ", "; $my_status = " status = '" . $this->get_status(false) . "' ,"; } elseif ($this->get_prevent_reinit() == 1) { // Process of status verified into data base. $sql = 'SELECT status FROM ' . $item_view_table . ' WHERE c_id = ' . $course_id . ' AND lp_item_id="' . $this->db_id . '" AND lp_view_id="' . $this->view_id . '" AND view_count="' . $this->get_attempt_id() . '" '; $rs_verified = Database::query($sql); $row_verified = Database::fetch_array($rs_verified); // Get type lp: 1=lp dokeos and 2=scorm. // If not is completed or passed or browsed and learning path is scorm. if (!in_array($this->get_status(false), $case_completed) && $my_type_lp == 2) { $total_time = " total_time = total_time +" . $this->get_total_time() . ", "; $my_status = " status = '" . $this->get_status(false) . "' ,"; } else { // Verified into database. if (!in_array($row_verified['status'], $case_completed) && $my_type_lp == 2) { $total_time = " total_time = total_time +" . $this->get_total_time() . ", "; $my_status = " status = '" . $this->get_status(false) . "' ,"; } elseif (in_array($row_verified['status'], $case_completed) && $my_type_lp == 2 && $this->type != 'sco') { $total_time = " total_time = total_time +" . $this->get_total_time() . ", "; $my_status = " status = '" . $this->get_status(false) . "' ,"; } else { if ($my_type_lp == 3 && $this->type == 'au' || $my_type_lp == 1 && $this->type != 'chapter') { // Is AICC or Chamilo LP $total_time = " total_time = total_time + " . $this->get_total_time() . ", "; $my_status = " status = '" . $this->get_status(false) . "' ,"; } } } } else { // Multiple attempts are allowed. if (in_array($this->get_status(false), $case_completed) && $my_type_lp == 2) { // Reset zero new attempt ? $my_status = " status = '" . $this->get_status(false) . "' ,"; } elseif (!in_array($this->get_status(false), $case_completed) && $my_type_lp == 2) { $total_time = " total_time = " . $this->get_total_time() . ", "; $my_status = " status = '" . $this->get_status(false) . "' ,"; } else { // It is chamilo LP. $total_time = " total_time = total_time +" . $this->get_total_time() . ", "; $my_status = " status = '" . $this->get_status(false) . "' ,"; } // This code line fixes the problem of wrong status. if ($my_type_lp == 2) { // Verify current status in multiples attempts. $sql = 'SELECT status FROM ' . $item_view_table . ' WHERE c_id = ' . $course_id . ' AND lp_item_id="' . $this->db_id . '" AND lp_view_id="' . $this->view_id . '" AND view_count="' . $this->get_attempt_id() . '" '; $rs_status = Database::query($sql); $current_status = Database::result($rs_status, 0, 'status'); if (in_array($current_status, $case_completed)) { $my_status = ''; $total_time = ''; } else { $total_time = " total_time = total_time +" . $this->get_total_time() . ", "; } } } } if ($this->type == 'sco') { //IF scorm scorm_update_time has already updated total_time in db //" . //start_time = ".$this->get_current_start_time().", " . //scorm_init_time does it ////" max_time_allowed = '".$this->get_max_time_allowed()."'," . $sql = "UPDATE {$item_view_table} SET\n score = " . $this->get_score() . ",\n {$my_status}\n max_score = '" . $this->get_max() . "',\n suspend_data = '" . Database::escape_string($this->current_data) . "',\n lesson_location = '" . $this->lesson_location . "'\n WHERE\n c_id = {$course_id} AND\n lp_item_id = " . $this->db_id . " AND\n lp_view_id = " . $this->view_id . " AND\n view_count = " . $this->get_attempt_id(); } else { //" max_time_allowed = '".$this->get_max_time_allowed()."'," . $sql = "UPDATE {$item_view_table} SET\n {$total_time}\n start_time = " . $this->get_current_start_time() . ",\n score = " . $this->get_score() . ",\n {$my_status}\n max_score = '" . $this->get_max() . "',\n suspend_data = '" . Database::escape_string($this->current_data) . "',\n lesson_location = '" . $this->lesson_location . "'\n WHERE\n c_id = {$course_id} AND\n lp_item_id = " . $this->db_id . " AND\n lp_view_id = " . $this->view_id . " AND\n view_count = " . $this->get_attempt_id(); } $this->current_start_time = time(); } if (self::debug > 2) { error_log('learnpathItem::write_to_db() - Updating item_view: ' . $sql, 0); } Database::query($sql); } if (is_array($this->interactions) && count($this->interactions) > 0) { // Save interactions. $tbl = Database::get_course_table(TABLE_LP_ITEM_VIEW); $sql = "SELECT id FROM {$tbl}\n WHERE\n c_id = {$course_id} AND\n lp_item_id = " . $this->db_id . " AND\n lp_view_id = " . $this->view_id . " AND\n view_count = " . $this->get_attempt_id(); $res = Database::query($sql); if (Database::num_rows($res) > 0) { $row = Database::fetch_array($res); $lp_iv_id = $row[0]; if (self::debug > 2) { error_log('learnpathItem::write_to_db() - Got item_view_id ' . $lp_iv_id . ', now checking interactions ', 0); } foreach ($this->interactions as $index => $interaction) { $correct_resp = ''; if (is_array($interaction[4]) && !empty($interaction[4][0])) { foreach ($interaction[4] as $resp) { $correct_resp .= $resp . ','; } $correct_resp = substr($correct_resp, 0, strlen($correct_resp) - 1); } $iva_table = Database::get_course_table(TABLE_LP_IV_INTERACTION); //also check for the interaction ID as it must be unique for this SCO view $iva_sql = "SELECT id FROM {$iva_table}\n WHERE\n c_id = {$course_id} AND\n lp_iv_id = {$lp_iv_id} AND\n (\n order_id = {$index} OR\n interaction_id = '" . Database::escape_string($interaction[0]) . "'\n )\n "; $iva_res = Database::query($iva_sql); // id(0), type(1), time(2), weighting(3), correct_responses(4), student_response(5), result(6), latency(7) if (Database::num_rows($iva_res) > 0) { // Update (or don't). $iva_row = Database::fetch_array($iva_res); $iva_id = $iva_row[0]; // Insert new one. $params = array('interaction_id' => $interaction[0], 'interaction_type' => $interaction[1], 'weighting' => $interaction[3], 'completion_time' => $interaction[2], 'correct_responses' => $correct_resp, 'student_response' => $interaction[5], 'result' => $interaction[6], 'latency' => $interaction[7]); Database::update($iva_table, $params, array('c_id = ? AND id = ?' => array($course_id, $iva_id))); } else { // Insert new one. $params = array('c_id' => $course_id, 'order_id' => $index, 'lp_iv_id' => $lp_iv_id, 'interaction_id' => $interaction[0], 'interaction_type' => $interaction[1], 'weighting' => $interaction[3], 'completion_time' => $interaction[2], 'correct_responses' => $correct_resp, 'student_response' => $interaction[5], 'result' => $interaction[6], 'latency' => $interaction[7]); $insertId = Database::insert($iva_table, $params); if ($insertId) { $sql = "UPDATE {$iva_table} SET id = iid\n WHERE iid = {$insertId}"; Database::query($sql); } } } } } } if (self::debug > 2) { error_log('End of learnpathItem::write_to_db()', 0); } return true; }
/** * Returns the "what's new" icon notifications * * The general logic of this function is to track the last time the user * entered the course and compare to what has changed inside this course * since then, based on the item_property table inside this course. Note that, * if the user never entered the course before, he will not see notification * icons. This function takes session ID into account (if any) and only shows * the corresponding notifications. * @param array Course information array, containing at least elements 'db' and 'k' * @return string The HTML link to be shown next to the course */ public static function show_notification($course_info) { if (empty($course_info)) { return ''; } $t_track_e_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS); $course_tool_table = Database::get_course_table(TABLE_TOOL_LIST); $tool_edit_table = Database::get_course_table(TABLE_ITEM_PROPERTY); $course_code = Database::escape_string($course_info['code']); $user_id = api_get_user_id(); $course_id = intval($course_info['real_id']); $sessionId = intval($course_info['id_session']); // Get the user's last access dates to all tools of this course $sql = "SELECT *\n FROM {$t_track_e_access}\n WHERE\n c_id = {$course_id} AND\n access_user_id = '{$user_id}' AND\n access_session_id ='" . $sessionId . "'"; $resLastTrackInCourse = Database::query($sql); $oldestTrackDate = $oldestTrackDateOrig = '3000-01-01 00:00:00'; while ($lastTrackInCourse = Database::fetch_array($resLastTrackInCourse)) { $lastTrackInCourseDate[$lastTrackInCourse['access_tool']] = $lastTrackInCourse['access_date']; if ($oldestTrackDate > $lastTrackInCourse['access_date']) { $oldestTrackDate = $lastTrackInCourse['access_date']; } } if ($oldestTrackDate == $oldestTrackDateOrig) { //if there was no connexion to the course ever, then take the // course creation date as a reference $oldestTrackDate = $course_info['creation_date']; } $sessionCondition = api_get_session_condition($sessionId, true, false, 'tet.session_id'); // Get the last edits of all tools of this course. $sql = "SELECT\n tet.*,\n tet.lastedit_date last_date,\n tet.tool tool,\n tet.ref ref,\n tet.lastedit_type type,\n tet.to_group_id group_id,\n ctt.image image,\n ctt.link link\n FROM {$tool_edit_table} tet\n INNER JOIN {$course_tool_table} ctt\n ON tet.c_id = ctt.c_id\n WHERE\n tet.c_id = {$course_id} AND\n tet.lastedit_date > '{$oldestTrackDate}' " . " AND (ctt.name = tet.tool OR (ctt.name = 'student_publication' AND tet.tool = 'work'))\n AND ctt.visibility = '1'\n AND tet.lastedit_user_id != {$user_id} {$sessionCondition}\n ORDER BY tet.lastedit_date"; $res = Database::query($sql); // Get the group_id's with user membership. $group_ids = GroupManager::get_group_ids($course_info['real_id'], $user_id); $group_ids[] = 0; //add group 'everyone' $notifications = array(); // Filter all last edits of all tools of the course while ($res && ($item_property = Database::fetch_array($res, 'ASSOC'))) { // First thing to check is if the user never entered the tool // or if his last visit was earlier than the last modification. if ((!isset($lastTrackInCourseDate[$item_property['tool']]) || $lastTrackInCourseDate[$item_property['tool']] < $item_property['lastedit_date']) && (in_array($item_property['to_group_id'], $group_ids) && ($item_property['tool'] != TOOL_NOTEBOOK && $item_property['tool'] != TOOL_CHAT)) && ($item_property['visibility'] == '1' || $course_info['status'] == '1' && $item_property['visibility'] == '0' || !isset($item_property['visibility']))) { // Also drop announcements and events that are not for the user or his group. if (($item_property['tool'] == TOOL_ANNOUNCEMENT || $item_property['tool'] == TOOL_CALENDAR_EVENT) && ($item_property['to_user_id'] != $user_id && (!isset($item_property['to_group_id']) || !in_array($item_property['to_group_id'], $group_ids)))) { continue; } // If it's a survey, make sure the user's invited. Otherwise drop it. if ($item_property['tool'] == TOOL_SURVEY) { $survey_info = SurveyManager::get_survey($item_property['ref'], 0, $course_code); if (!empty($survey_info)) { $invited_users = SurveyUtil::get_invited_users($survey_info['code'], $course_code); if (!in_array($user_id, $invited_users['course_users'])) { continue; } } } // If it's a learning path, ensure it is currently visible to the user if ($item_property['tool'] == TOOL_LEARNPATH) { if (!learnpath::is_lp_visible_for_student($item_property['ref'], $user_id, $course_code)) { continue; } } if ($item_property['tool'] == TOOL_DROPBOX) { $item_property['link'] = 'dropbox/dropbox_download.php?id=' . $item_property['ref']; } if ($item_property['tool'] == 'work' && $item_property['type'] == 'DirectoryCreated') { $item_property['lastedit_type'] = 'WorkAdded'; } $notifications[$item_property['tool']] = $item_property; } } // Show all tool icons where there is something new. $return = ' '; foreach ($notifications as $notification) { $lastDate = date('d/m/Y H:i', convert_sql_date($notification['lastedit_date'])); $type = $notification['lastedit_type']; $label = get_lang('TitleNotification') . ": " . get_lang($type) . " ({$lastDate})"; if (strpos($notification['link'], '?') === false) { $notification['link'] = $notification['link'] . '?notification=1'; } else { $notification['link'] = $notification['link'] . '¬ification=1'; } $return .= Display::url(Display::return_icon($notification['image'], $label), api_get_path(WEB_CODE_PATH) . $notification['link'] . '&cidReq=' . $course_code . '&ref=' . $notification['ref'] . '&gidReq=' . $notification['to_group_id'] . '&id_session=' . $sessionId) . ' '; } return $return; }
LoginCheck(isset($_user['user_id']) ? $_user['user_id'] : ''); } // ===== end "who is logged in?" module section ===== //Update of the logout_date field in the table track_e_login // (needed for the calculation of the total connection time) if (!isset($_SESSION['login_as']) && isset($_user)) { // if $_SESSION['login_as'] is set, then the user is an admin logged as the user $tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); $sql = "SELECT login_id, login_date\n FROM {$tbl_track_login}\n WHERE\n login_user_id='" . $_user["user_id"] . "'\n ORDER BY login_date DESC\n LIMIT 0,1"; $q_last_connection = Database::query($sql); if (Database::num_rows($q_last_connection) > 0) { $i_id_last_connection = Database::result($q_last_connection, 0, 'login_id'); // is the latest logout_date still relevant? $sql = "SELECT logout_date FROM {$tbl_track_login}\n WHERE login_id = {$i_id_last_connection}"; $q_logout_date = Database::query($sql); $res_logout_date = convert_sql_date(Database::result($q_logout_date, 0, 'logout_date')); if ($res_logout_date < time() - $_configuration['session_lifetime']) { // it isn't, we should create a fresh entry Event::event_login($_user['user_id']); // now that it's created, we can get its ID and carry on $i_id_last_connection = Database::result($q_last_connection, 0, 'login_id'); } $now = api_get_utc_datetime(time()); $sql = "UPDATE {$tbl_track_login} SET logout_date = '{$now}'\n WHERE login_id='{$i_id_last_connection}'"; Database::query($sql); $tableUser = Database::get_main_table(TABLE_MAIN_USER); $sql = "UPDATE {$tableUser} SET last_login = '******'\n WHERE user_id = " . $_user["user_id"]; Database::query($sql); } } // Add language_measure_frequency to your main/inc/conf/configuration.php in