Esempio n. 1
0
/**
 * 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)
 * @param   bool
 * @see SortableTable#get_table_data($from)
 */
function get_user_data($from, $number_of_items, $column, $direction, $get_count = false)
{
    $user_table = Database::get_main_table(TABLE_MAIN_USER);
    $admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
    $select = "SELECT\n                 u.user_id\t\t\t\tAS col0,\n                 u.official_code\t\tAS col2,\n\t\t\t\t " . (api_is_western_name_order() ? "u.firstname \t\t\tAS col3,\n                 u.lastname \t\t\tAS col4," : "u.lastname \t\t\tAS col3,\n                 u.firstname \t\t\tAS col4,") . "\n                 u.username\t\t\t\tAS col5,\n                 u.email\t\t\t\tAS col6,\n                 u.status\t\t\t\tAS col7,\n                 u.active\t\t\t\tAS col8,\n                 u.user_id\t\t\t\tAS col9,\n                 u.registration_date    AS col10,\n                 u.expiration_date      AS exp,\n                 u.password\n    ";
    if ($get_count) {
        $select = "SELECT count(u.user_id) as total_rows";
    }
    $sql = "{$select} FROM {$user_table} u ";
    // adding the filter to see the user's only of the current access_url
    if ((api_is_platform_admin() || api_is_session_admin()) && api_get_multiple_access_url()) {
        $access_url_rel_user_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
        $sql .= " INNER JOIN {$access_url_rel_user_table} url_rel_user ON (u.user_id=url_rel_user.user_id)";
    }
    if (isset($_GET['keyword_extra_data'])) {
        $keyword_extra_data = Database::escape_string($_GET['keyword_extra_data']);
        if (!empty($keyword_extra_data)) {
            $extra_info = UserManager::get_extra_field_information_by_name($keyword_extra_data);
            $field_id = $extra_info['id'];
            $sql .= " INNER JOIN user_field_values ufv ON u.user_id=ufv.user_id AND ufv.field_id={$field_id} ";
        }
    }
    if (isset($_GET['keyword'])) {
        $keyword = Database::escape_string(trim($_GET['keyword']));
        $sql .= " WHERE (u.firstname LIKE '%" . $keyword . "%' OR u.lastname LIKE '%" . $keyword . "%' OR concat(u.firstname,' ',u.lastname) LIKE '%" . $keyword . "%' OR concat(u.lastname,' ',u.firstname) LIKE '%" . $keyword . "%' OR u.username LIKE '%" . $keyword . "%'  OR u.official_code LIKE '%" . $keyword . "%' OR u.email LIKE '%" . $keyword . "%' )";
    } elseif (isset($_GET['keyword_firstname'])) {
        $keyword_firstname = Database::escape_string($_GET['keyword_firstname']);
        $keyword_lastname = Database::escape_string($_GET['keyword_lastname']);
        $keyword_email = Database::escape_string($_GET['keyword_email']);
        $keyword_officialcode = Database::escape_string($_GET['keyword_officialcode']);
        $keyword_username = Database::escape_string($_GET['keyword_username']);
        $keyword_status = Database::escape_string($_GET['keyword_status']);
        $query_admin_table = '';
        $and_conditions = array();
        if ($keyword_status == SESSIONADMIN) {
            $keyword_status = '%';
            $query_admin_table = " , {$admin_table} a ";
            $and_conditions[] = ' a.user_id = u.user_id ';
        }
        if (isset($_GET['keyword_extra_data'])) {
            if (!empty($_GET['keyword_extra_data']) && !empty($_GET['keyword_extra_data_text'])) {
                $keyword_extra_data_text = Database::escape_string($_GET['keyword_extra_data_text']);
                $and_conditions[] = " ufv.field_value LIKE '%" . trim($keyword_extra_data_text) . "%' ";
            }
        }
        $keyword_active = isset($_GET['keyword_active']);
        $keyword_inactive = isset($_GET['keyword_inactive']);
        $sql .= $query_admin_table . " WHERE ( ";
        if (!empty($keyword_firstname)) {
            $and_conditions[] = "u.firstname LIKE '%" . $keyword_firstname . "%' ";
        }
        if (!empty($keyword_lastname)) {
            $and_conditions[] = "u.lastname LIKE '%" . $keyword_lastname . "%' ";
        }
        if (!empty($keyword_username)) {
            $and_conditions[] = "u.username LIKE '%" . $keyword_username . "%'  ";
        }
        if (!empty($keyword_email)) {
            $and_conditions[] = "u.email LIKE '%" . $keyword_email . "%' ";
        }
        if (!empty($keyword_officialcode)) {
            $and_conditions[] = "u.official_code LIKE '%" . $keyword_officialcode . "%' ";
        }
        if (!empty($keyword_status)) {
            $and_conditions[] = "u.status LIKE '" . $keyword_status . "' ";
        }
        if ($keyword_active && !$keyword_inactive) {
            $and_conditions[] = "  u.active='1' ";
        } elseif ($keyword_inactive && !$keyword_active) {
            $and_conditions[] = "  u.active='0' ";
        }
        if (!empty($and_conditions)) {
            $sql .= implode(' AND ', $and_conditions);
        }
        $sql .= " ) ";
    }
    // adding the filter to see the user's only of the current access_url
    if ((api_is_platform_admin() || api_is_session_admin()) && api_get_multiple_access_url()) {
        $sql .= " AND url_rel_user.access_url_id=" . api_get_current_access_url_id();
    }
    $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);
    // Returns counts and exits function.
    if ($get_count) {
        $res = Database::query($sql);
        $user = Database::fetch_array($res);
        return $user['total_rows'];
    }
    $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)) {
        $userInfo = api_get_user_info($user[0]);
        $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="' . $userInfo['profile_url'] . '" title="' . get_lang('Info') . '">
                            <img src="' . $user_profile['file'] . '" ' . $user_profile['style'] . ' alt="' . $userInfo['complete_name'] . '" title="' . $userInfo['complete_name'] . '" /></a></center>';
        } else {
            $photo = '<center><img src="' . $user_profile['file'] . '" ' . $user_profile['style'] . ' alt="' . $userInfo['complete_name'] . '" title="' . $userInfo['complete_name'] . '" /></center>';
        }
        if ($user[7] == 1 && $user[10] != '0000-00-00 00:00:00') {
            // check expiration date
            $expiration_time = api_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], Display::url($user[2], $userInfo['profile_url']), Display::url($user[3], $userInfo['profile_url']), $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_verified = '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_verified);
        $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' or $mode == 'review' or $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();
                $sql = "INSERT INTO {$item_view_table} " . "(c_id, total_time, " . "start_time, " . "score, " . "status, " . "max_score, " . "lp_item_id, " . "lp_view_id, " . "view_count, " . "suspend_data, " . "lesson_location)" . "VALUES" . "({$course_id}, " . $this->get_total_time() . "," . "" . $this->current_start_time . "," . "" . $this->get_score() . "," . "'" . $this->get_status(false) . "'," . "'" . $this->get_max() . "'," . "" . $this->db_id . "," . "" . $this->view_id . "," . "" . $this->get_attempt_id() . "," . "'" . Database::escape_string($this->current_data) . "'," . "'" . $this->lesson_location . "')";
                if (self::debug > 2) {
                    error_log('learnpathItem::write_to_db() - Inserting into item_view forced: ' . $sql, 0);
                }
                $res = Database::query($sql);
                $this->db_item_view_id = Database::insert_id();
                $inserted = true;
            }
            $check_attempts = self::check_attempts($this->get_attempt_id());
            if (!$check_attempts) {
                return false;
            }
            $item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW);
            $check = "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 = " . $this->get_attempt_id();
            if (self::debug > 2) {
                error_log('learnpathItem::write_to_db() - Querying item_view: ' . $check, 0);
            }
            $check_res = Database::query($check);
            // Depending on what we want (really), we'll update or insert a new row
            // now save into DB.
            $res = 0;
            if (!$inserted && Database::num_rows($check_res) < 1) {
                $sql = "INSERT INTO {$item_view_table} " . "(c_id, total_time, " . "start_time, " . "score, " . "status, " . "max_score, " . "lp_item_id, " . "lp_view_id, " . "view_count, " . "suspend_data, " . "lesson_location)" . "VALUES" . "({$course_id}, " . $this->get_total_time() . "," . "" . $this->current_start_time . "," . "" . $this->get_score() . "," . "'" . $this->get_status(false) . "'," . "'" . $this->get_max() . "'," . "" . $this->db_id . "," . "" . $this->view_id . "," . "" . $this->get_attempt_id() . "," . "'" . Database::escape_string($this->current_data) . "'," . "'" . $this->lesson_location . "')";
                if (self::debug > 2) {
                    error_log('learnpathItem::write_to_db() - Inserting into item_view: ' . $sql, 0);
                }
                $res = Database::query($sql);
                $this->db_item_view_id = Database::insert_id();
            } else {
                $sql = '';
                if ($this->type == 'hotpotatoes') {
                    $sql = "UPDATE {$item_view_table} " . "SET 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 = '" . Database::escape_string($this->current_data) . "'," . " lesson_location = '" . $this->lesson_location . "' " . "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();
                } else {
                    // For all other content types...
                    if ($this->type == 'quiz') {
                        $my_status = ' ';
                        $total_time = ' ';
                        if (!empty($_REQUEST['exeId'])) {
                            $TBL_TRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
                            $safe_exe_id = Database::escape_string($_REQUEST['exeId']);
                            $sql = 'SELECT start_date,exe_date FROM ' . $TBL_TRACK_EXERCICES . ' WHERE exe_id = ' . (int) $safe_exe_id;
                            $res = Database::query($sql);
                            $row_dates = Database::fetch_array($res);
                            $time_start_date = api_convert_sql_date($row_dates['start_date']);
                            $time_exe_date = api_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_verified = '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_verified);
                            $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) {
                                //&& $this->type!='dir'
                                $total_time = " total_time = total_time +" . $this->get_total_time() . ", ";
                                $my_status = " status = '" . $this->get_status(false) . "' ,";
                            } else {
                                // Verified into data base.
                                if (!in_array($row_verified['status'], $case_completed) && $my_type_lp == 2) {
                                    //&& $this->type!='dir'
                                    $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') {
                                    //&& $this->type!='dir'
                                    $total_time = " total_time = total_time +" . $this->get_total_time() . ", ";
                                    $my_status = " status = '" . $this->get_status(false) . "' ,";
                                } else {
                                    //&& !in_array($row_verified['status'], $case_completed)
                                    //is lp dokeos
                                    if ($my_type_lp == 1 && $this->type != 'chapter') {
                                        $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 dokeos LP.
                                $total_time = " total_time = total_time +" . $this->get_total_time() . ", ";
                                $my_status = " status = '" . $this->get_status(false) . "' ,";
                            }
                            // Code added by Isaac Flores.
                            // This code line fixes the problem of wrong status.
                            if ($my_type_lp == 2) {
                                // Verify current status in multiples attempts.
                                $sql_status = '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_status);
                                $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_tim in db
                        $sql = "UPDATE {$item_view_table} " . " SET " . " score = " . $this->get_score() . ", " . $my_status . " max_score = '" . $this->get_max() . "'," . " suspend_data = '" . Database::escape_string($this->current_data) . "'," . " lesson_location = '" . $this->lesson_location . "' " . "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();
                    } else {
                        $sql = "UPDATE {$item_view_table} " . "SET " . $total_time . " start_time = " . $this->get_current_start_time() . ", " . " score = " . $this->get_score() . ", " . $my_status . " max_score = '" . $this->get_max() . "'," . " suspend_data = '" . Database::escape_string($this->current_data) . "'," . " lesson_location = '" . $this->lesson_location . "' " . "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();
                    }
                    $this->current_start_time = time();
                }
                if (self::debug > 2) {
                    error_log('learnpathItem::write_to_db() - Updating item_view: ' . $sql, 0);
                }
                $res = 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} " . "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();
                $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);
                        $iva_sql = "SELECT id FROM {$iva_table} " . "WHERE c_id = {$course_id} AND lp_iv_id = {$lp_iv_id} " . "AND (order_id = {$index} " . "OR interaction_id = '" . Database::escape_string($interaction[0]) . "')";
                        $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];
                            $ivau_sql = "UPDATE {$iva_table} " . "SET interaction_id = '" . Database::escape_string($interaction[0]) . "'," . "interaction_type = '" . Database::escape_string($interaction[1]) . "'," . "weighting = '" . Database::escape_string($interaction[3]) . "'," . "completion_time = '" . Database::escape_string($interaction[2]) . "'," . "correct_responses = '" . Database::escape_string($correct_resp) . "'," . "student_response = '" . Database::escape_string($interaction[5]) . "'," . "result = '" . Database::escape_string($interaction[6]) . "'," . "latency = '" . Database::escape_string($interaction[7]) . "'" . "WHERE c_id = {$course_id} AND id = {$iva_id}";
                            Database::query($ivau_sql);
                        } else {
                            // Insert new one.
                            $ivai_sql = "INSERT INTO {$iva_table} (c_id, order_id, lp_iv_id, interaction_id, interaction_type, " . "weighting, completion_time, correct_responses, " . "student_response, result, latency)" . "VALUES" . "({$course_id}, " . $index . "," . $lp_iv_id . ",'" . Database::escape_string($interaction[0]) . "','" . Database::escape_string($interaction[1]) . "'," . "'" . Database::escape_string($interaction[3]) . "','" . Database::escape_string($interaction[2]) . "','" . Database::escape_string($correct_resp) . "'," . "'" . Database::escape_string($interaction[5]) . "','" . Database::escape_string($interaction[6]) . "','" . Database::escape_string($interaction[7]) . "'" . ")";
                            Database::query($ivai_sql);
                        }
                    }
                }
            }
        }
        if (self::debug > 2) {
            error_log('End of learnpathItem::write_to_db()', 0);
        }
        return true;
    }
Esempio n. 3
0
 /**
  * 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_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
     $user_id = api_get_user_id();
     $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']);
     $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
     //$sqlLastTrackInCourse = "SELECT * FROM $t_track_e_access USE INDEX (c_id, access_user_id)
     $sqlLastTrackInCourse = "SELECT * FROM {$t_track_e_access}\n                                 WHERE  c_id = " . $course_id . " AND\n                                        access_user_id = '{$user_id}' AND\n                                        access_session_id ='" . $course_info['id_session'] . "'";
     $resLastTrackInCourse = Database::query($sqlLastTrackInCourse);
     $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 tet.*, tet.lastedit_date last_date, tet.tool tool, tet.ref ref, " . " tet.lastedit_type type, tet.to_group_id group_id, " . " ctt.image image, ctt.link link " . " FROM {$tool_edit_table} tet, {$course_tool_table} ctt " . " WHERE tet.c_id = {$course_id} AND\n                        \t\tctt.c_id = {$course_id} AND\n                        \t\ttet.lastedit_date > '{$oldestTrackDate}' " . " AND ctt.name = tet.tool " . " AND ctt.visibility = '1' " . " AND tet.lastedit_user_id != {$user_id} AND tet.id_session = '" . $course_info['id_session'] . "' " . " 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']))) {
             // 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 ($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;
                 }
             }
             $notifications[$item_property['tool']] = $item_property;
         }
     }
     // Show all tool icons where there is something new.
     $retvalue = '&nbsp;';
     while (list($key, $notification) = each($notifications)) {
         $lastDate = date('d/m/Y H:i', api_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 . '&amp;ref=' . $notification['ref'] . '&amp;gidReq=' . $notification['to_group_id'] . '&amp;id_session=' . $my_course['id_session'] . '">' . Display::return_icon($notification['image'], $label) . '</a>&nbsp;';
     }
     return $retvalue;
 }