function search_users($needle, $type)
{
    global $_configuration, $tbl_access_url_rel_user, $tbl_user, $user_anonymous, $current_user_id, $user_id;
    $xajax_response = new XajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        // xajax send utf8 datas... datas in db can be non-utf8 datas
        $charset = api_get_system_encoding();
        $needle = api_convert_encoding($needle, $charset, 'utf-8');
        $assigned_users_to_hrm = UserManager::get_users_followed_by_drh($user_id);
        $assigned_users_id = array_keys($assigned_users_to_hrm);
        $without_assigned_users = '';
        if (count($assigned_users_id) > 0) {
            $without_assigned_users = " AND user.user_id NOT IN(" . implode(',', $assigned_users_id) . ")";
        }
        if ($_configuration['multiple_access_urls']) {
            $sql = "SELECT user.user_id, username, lastname, firstname FROM {$tbl_user} user LEFT JOIN {$tbl_access_url_rel_user} au ON (au.user_id = user.user_id)\n\t\t\tWHERE  " . (api_sort_by_first_name() ? 'firstname' : 'lastname') . " LIKE '{$needle}%' AND status NOT IN(" . DRH . ", " . SESSIONADMIN . ") AND user.user_id NOT IN ({$user_anonymous}, {$current_user_id}, {$user_id}) {$without_assigned_users} AND access_url_id = " . api_get_current_access_url_id() . "";
        } else {
            $sql = "SELECT user_id, username, lastname, firstname FROM {$tbl_user} user\n\t\t\tWHERE  " . (api_sort_by_first_name() ? 'firstname' : 'lastname') . " LIKE '{$needle}%' AND status NOT IN(" . DRH . ", " . SESSIONADMIN . ") AND user_id NOT IN ({$user_anonymous}, {$current_user_id}, {$user_id}) {$without_assigned_users}";
        }
        $rs = Database::query($sql);
        $return .= '<select id="origin" name="NoAssignedUsersList[]" multiple="multiple" size="20" style="width:340px;">';
        while ($user = Database::fetch_array($rs)) {
            $person_name = api_get_person_name($user['firstname'], $user['lastname']);
            $return .= '<option value="' . $user['user_id'] . '" title="' . htmlspecialchars($person_name, ENT_QUOTES) . '">' . $person_name . ' (' . $user['username'] . ')</option>';
        }
        $return .= '</select>';
        $xajax_response->addAssign('ajax_list_users_multiple', 'innerHTML', api_utf8_encode($return));
    }
    return $xajax_response;
}
function search_sessions($needle, $type)
{
    global $tbl_session_rel_access_url, $tbl_session, $user_id;
    $xajax_response = new xajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        $needle = Database::escape_string($needle);
        $assigned_sessions_to_hrm = SessionManager::get_sessions_followed_by_drh($user_id);
        $assigned_sessions_id = array_keys($assigned_sessions_to_hrm);
        $without_assigned_sessions = '';
        if (count($assigned_sessions_id) > 0) {
            $without_assigned_sessions = " AND s.id NOT IN(" . implode(',', $assigned_sessions_id) . ")";
        }
        if (api_is_multiple_url_enabled()) {
            $sql = " SELECT s.id, s.name FROM {$tbl_session} s\n                        LEFT JOIN {$tbl_session_rel_access_url} a ON (s.id = a.session_id)\n                        WHERE  s.name LIKE '{$needle}%' {$without_assigned_sessions} AND access_url_id = " . api_get_current_access_url_id() . "";
        } else {
            $sql = "SELECT s.id, s.name FROM {$tbl_session} s\n                    WHERE  s.name LIKE '{$needle}%' {$without_assigned_sessions} ";
        }
        $rs = Database::query($sql);
        $return .= '<select class="form-control" id="origin" name="NoAssignedSessionsList[]" multiple="multiple" size="20">';
        while ($session = Database::fetch_array($rs)) {
            $return .= '<option value="' . $session['id'] . '" title="' . htmlspecialchars($session['name'], ENT_QUOTES) . '">' . $session['name'] . '</option>';
        }
        $return .= '</select>';
        $xajax_response->addAssign('ajax_list_sessions_multiple', 'innerHTML', api_utf8_encode($return));
    }
    return $xajax_response;
}
 /**
  * Search users by username, firstname or lastname, based on the given
  * search string
  * @param string Search string
  * @param int Deprecated param
  * @return string Xajax response block
  * @assert () === false
  */
 public static function search_users($needle, $id)
 {
     global $tbl_user, $tbl_access_url_rel_user;
     $xajax_response = new XajaxResponse();
     $return = '';
     if (!empty($needle)) {
         // xajax send utf8 datas... datas in db can be non-utf8 datas
         $charset = api_get_system_encoding();
         $needle = api_convert_encoding($needle, $charset, 'utf-8');
         $needle = Database::escape_string($needle);
         // search users where username or firstname or lastname begins likes $needle
         $order_clause = api_sort_by_first_name() ? ' ORDER BY firstname, lastname, username' : ' ORDER BY lastname, firstname, username';
         $sql = 'SELECT u.user_id, username, lastname, firstname FROM ' . $tbl_user . ' u ' . ' WHERE (username LIKE "' . $needle . '%" ' . ' OR firstname LIKE "' . $needle . '%" ' . ' OR lastname LIKE "' . $needle . '%") ' . $order_clause . ' LIMIT 11';
         $rs = Database::query($sql);
         $i = 0;
         while ($user = Database::fetch_array($rs)) {
             $i++;
             if ($i <= 10) {
                 $return .= '<a href="javascript: void(0);" onclick="javascript: add_user_to_url(\'' . addslashes($user['user_id']) . '\',\'' . api_get_person_name(addslashes($user['firstname']), addslashes($user['lastname'])) . ' (' . addslashes($user['username']) . ')' . '\')">' . api_get_person_name($user['firstname'], $user['lastname']) . ' (' . $user['username'] . ')</a><br />';
             } else {
                 $return .= '...<br />';
             }
         }
     }
     $xajax_response->addAssign('ajax_list_users', 'innerHTML', api_utf8_encode($return));
     return $xajax_response;
 }
/**
 * Get a list of courses (code, url, title, teacher, language) and return to caller
 * Function registered as service. Returns strings in UTF-8.
 * @param string Security key (the Dokeos install's API key)
 * @param mixed  Array or string. Type of visibility of course (public, public-registered, private, closed)
 * @return array Courses list (code=>[title=>'title',url='http://...',teacher=>'...',language=>''],code=>[...],...)
 */
function courses_list($security_key, $visibilities = 'public')
{
    global $_configuration;
    // Check if this script is launch by server and if security key is ok.
    if ($security_key != $_configuration['security_key']) {
        return array('error_msg' => 'Security check failed');
    }
    $vis = array('public' => '3', 'public-registered' => '2', 'private' => '1', 'closed' => '0');
    $courses_list = array();
    if (!is_array($visibilities)) {
        $tmp = $visibilities;
        $visibilities = array($tmp);
    }
    foreach ($visibilities as $visibility) {
        if (!in_array($visibility, array_keys($vis))) {
            return array('error_msg' => 'Security check failed');
        }
        $courses_list_tmp = CourseManager::get_courses_list(null, null, null, null, $vis[$visibility]);
        foreach ($courses_list_tmp as $index => $course) {
            $course_info = CourseManager::get_course_information($course['code']);
            $courses_list[$course['code']] = array('title' => api_utf8_encode($course_info['title']), 'url' => api_get_path(WEB_COURSE_PATH) . $course_info['directory'] . '/', 'teacher' => api_utf8_encode($course_info['tutor_name']), 'language' => $course_info['course_language']);
        }
    }
    return $courses_list;
}
 /**
  * Search sessions by name, based on a search string
  * @param string Search string
  * @param int Deprecated param
  * @return string Xajax response block
  * @assert () === false
  */
 function search_sessions($needle, $id)
 {
     global $tbl_session;
     $xajax_response = new XajaxResponse();
     $return = '';
     if (!empty($needle)) {
         // xajax send utf8 datas... datas in db can be non-utf8 datas
         $charset = api_get_system_encoding();
         $needle = api_convert_encoding($needle, $charset, 'utf-8');
         $needle = Database::escape_string($needle);
         // search sessiones where username or firstname or lastname begins likes $needle
         $sql = 'SELECT id, name FROM ' . $tbl_session . ' u
                 WHERE (name LIKE "' . $needle . '%")
                 ORDER BY name, id
                 LIMIT 11';
         $rs = Database::query($sql);
         $i = 0;
         while ($session = Database::fetch_array($rs)) {
             $i++;
             if ($i <= 10) {
                 $return .= '<a href="#" onclick="add_user_to_url(\'' . addslashes($session['id']) . '\',\'' . addslashes($session['name']) . ' (' . addslashes($session['id']) . ')' . '\')">' . $session['name'] . ' </a><br />';
             } else {
                 $return .= '...<br />';
             }
         }
     }
     $xajax_response->addAssign('ajax_list_courses', 'innerHTML', api_utf8_encode($return));
     return $xajax_response;
 }
 /**
  * Search for a list of available courses by title or code, based on
  * a given string
  * @param string String to search for
  * @param int Deprecated param
  * @return string A formatted, xajax answer block
  * @assert () === false
  */
 function search_courses($needle, $id)
 {
     global $tbl_course;
     $xajax_response = new XajaxResponse();
     $return = '';
     if (!empty($needle)) {
         // xajax send utf8 datas... datas in db can be non-utf8 datas
         $charset = api_get_system_encoding();
         $needle = api_convert_encoding($needle, $charset, 'utf-8');
         $needle = Database::escape_string($needle);
         // search courses where username or firstname or lastname begins likes $needle
         $sql = 'SELECT code, title FROM ' . $tbl_course . ' u ' . ' WHERE (title LIKE "' . $needle . '%" ' . ' OR code LIKE "' . $needle . '%" ' . ' ) ' . ' ORDER BY title, code ' . ' LIMIT 11';
         $rs = Database::query($sql);
         $i = 0;
         while ($course = Database::fetch_array($rs)) {
             $i++;
             if ($i <= 10) {
                 $return .= '<a href="javascript: void(0);" onclick="javascript: add_user_to_url(\'' . addslashes($course['code']) . '\',\'' . addslashes($course['title']) . ' (' . addslashes($course['code']) . ')' . '\')">' . $course['title'] . ' (' . $course['code'] . ')</a><br />';
             } else {
                 $return .= '...<br />';
             }
         }
     }
     $xajax_response->addAssign('ajax_list_courses', 'innerHTML', api_utf8_encode($return));
     return $xajax_response;
 }
function search_sessions($needle, $type)
{
    global $_configuration, $tbl_session_rel_access_url, $tbl_session, $user_id;
    $xajax_response = new XajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        // xajax send utf8 datas... datas in db can be non-utf8 datas
        $charset = api_get_system_encoding();
        $needle = api_convert_encoding($needle, $charset, 'utf-8');
        $assigned_sessions_to_hrm = SessionManager::get_sessions_followed_by_drh($user_id);
        $assigned_sessions_id = array_keys($assigned_sessions_to_hrm);
        $without_assigned_sessions = '';
        if (count($assigned_sessions_id) > 0) {
            $without_assigned_sessions = " AND s.id NOT IN(" . implode(',', $assigned_sessions_id) . ")";
        }
        if ($_configuration['multiple_access_urls']) {
            $sql = " SELECT s.id, s.name FROM {$tbl_session} s LEFT JOIN {$tbl_session_rel_access_url} a ON (s.id = a.session_id)\n\t\t\t\t\t\tWHERE  s.name LIKE '{$needle}%' {$without_assigned_sessions} AND access_url_id = " . api_get_current_access_url_id() . "";
        } else {
            $sql = "SELECT s.id, s.name FROM {$tbl_session} s\n\t\t\t\tWHERE  s.name LIKE '{$needle}%' {$without_assigned_sessions} ";
        }
        $rs = Database::query($sql);
        $return .= '<select id="origin" name="NoAssignedSessionsList[]" multiple="multiple" size="20" style="width:340px;">';
        while ($session = Database::fetch_array($rs)) {
            $return .= '<option value="' . $session['id'] . '" title="' . htmlspecialchars($session['name'], ENT_QUOTES) . '">' . $session['name'] . '</option>';
        }
        $return .= '</select>';
        $xajax_response->addAssign('ajax_list_sessions_multiple', 'innerHTML', api_utf8_encode($return));
    }
    return $xajax_response;
}
function search_courses($needle, $type)
{
    global $tbl_course, $tbl_course_rel_access_url, $user_id;
    $xajax_response = new xajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        // xajax send utf8 datas... datas in db can be non-utf8 datas
        $needle = Database::escape_string($needle);
        $assigned_courses_to_hrm = CourseManager::get_courses_followed_by_drh($user_id);
        $assigned_courses_code = array_keys($assigned_courses_to_hrm);
        foreach ($assigned_courses_code as &$value) {
            $value = "'" . $value . "'";
        }
        $without_assigned_courses = '';
        if (count($assigned_courses_code) > 0) {
            $without_assigned_courses = " AND c.code NOT IN(" . implode(',', $assigned_courses_code) . ")";
        }
        if (api_is_multiple_url_enabled()) {
            $sql = "SELECT c.code, c.title\n                    FROM {$tbl_course} c\n\t\t\t\t\tLEFT JOIN {$tbl_course_rel_access_url} a\n                    ON (a.c_id = c.id)\n                \tWHERE\n                \t\tc.code LIKE '{$needle}%' {$without_assigned_courses} AND\n                \t\taccess_url_id = " . api_get_current_access_url_id();
        } else {
            $sql = "SELECT c.code, c.title\n            \t\tFROM {$tbl_course} c\n                \tWHERE\n                \t\tc.code LIKE '{$needle}%'\n                \t\t{$without_assigned_courses} ";
        }
        $rs = Database::query($sql);
        $return .= '<select id="origin" name="NoAssignedCoursesList[]" multiple="multiple" size="20" style="width:340px;">';
        while ($course = Database::fetch_array($rs)) {
            $return .= '<option value="' . $course['code'] . '" title="' . htmlspecialchars($course['title'], ENT_QUOTES) . '">' . $course['title'] . ' (' . $course['code'] . ')</option>';
        }
        $return .= '</select>';
        $xajax_response->addAssign('ajax_list_courses_multiple', 'innerHTML', api_utf8_encode($return));
    }
    return $xajax_response;
}
Example #9
0
/**
 * Get a list of courses (code, url, title, teacher, language) for a specific
 * user and return to caller
 * Function registered as service. Returns strings in UTF-8.
 * @param string User name in Chamilo
 * @param string Signature (composed of the sha1(username+apikey)
 * @return array Courses list (code=>[title=>'title',url='http://...',teacher=>'...',language=>''],code=>[...],...)
 */
function WSCourseListOfUser($username, $signature)
{
    if (empty($username) or empty($signature)) {
        return -1;
    }
    global $_configuration;
    $info = api_get_user_info_from_username($username);
    $user_id = $info['user_id'];
    $list = UserManager::get_api_keys($user_id, 'dokeos');
    $key = '';
    foreach ($list as $key) {
        break;
    }
    $local_key = $username . $key;
    if (!api_is_valid_secret_key($signature, $local_key)) {
        return -1;
        // The secret key is incorrect.
    }
    $courses_list = array();
    $courses_list_tmp = CourseManager::get_courses_list_by_user_id($user_id);
    foreach ($courses_list_tmp as $index => $course) {
        $course_info = CourseManager::get_course_information($course['code']);
        $courses_list[] = array('code' => $course['code'], 'title' => api_utf8_encode($course_info['title']), 'url' => api_get_path(WEB_COURSE_PATH) . $course_info['directory'] . '/', 'teacher' => api_utf8_encode($course_info['tutor_name']), 'language' => $course_info['course_language']);
    }
    return $courses_list;
}
Example #10
0
function ConvertToXmlAttribute($value)
{
    if (IS_WINDOWS_OS || FindBadUtf8($value)) {
        return api_utf8_encode(htmlspecialchars($value));
    } else {
        return htmlspecialchars($value);
    }
}
Example #11
0
function search_coachs($needle)
{
    $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
    $xajax_response = new xajaxResponse();
    $return = '';
    if (!empty($needle)) {
        $order_clause = api_sort_by_first_name() ? ' ORDER BY firstname, lastname, username' : ' ORDER BY lastname, firstname, username';
        // search users where username or firstname or lastname begins likes $needle
        $sql = 'SELECT username, lastname, firstname
		        FROM ' . $tbl_user . ' user
				WHERE (username LIKE "' . $needle . '%"
				OR firstname LIKE "' . $needle . '%"
				OR lastname LIKE "' . $needle . '%")
				AND status=1' . $order_clause . ' LIMIT 10';
        if (api_is_multiple_url_enabled()) {
            $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
            $access_url_id = api_get_current_access_url_id();
            if ($access_url_id != -1) {
                $sql = 'SELECT username, lastname, firstname
                        FROM ' . $tbl_user . ' user
                        INNER JOIN ' . $tbl_user_rel_access_url . ' url_user
                        ON (url_user.user_id=user.user_id)
                        WHERE
                            access_url_id = ' . $access_url_id . '  AND
                            (
                                username LIKE "' . $needle . '%" OR
                                firstname LIKE "' . $needle . '%" OR
                                lastname LIKE "' . $needle . '%"
                            )
                            AND status=1' . $order_clause . '
                        LIMIT 10';
            }
        }
        $rs = Database::query($sql);
        while ($user = Database::fetch_array($rs)) {
            $return .= '<a href="javascript: void(0);" onclick="javascript: fill_coach_field(\'' . $user['username'] . '\')">' . api_get_person_name($user['firstname'], $user['lastname']) . ' (' . $user['username'] . ')</a><br />';
        }
    }
    $xajax_response->addAssign('ajax_list_coachs', 'innerHTML', api_utf8_encode($return));
    return $xajax_response;
}
Example #12
0
/**
 * Get a list of courses (code, url, title, teacher, language) and return to caller
 * Function registered as service. Returns strings in UTF-8.
 * @param string User name in Chamilo
 * @param string Signature (composed of the sha1(username+apikey)
 * @param mixed  Array or string. Type of visibility of course (public, public-registered, private, closed)
 * @return array Courses list (code=>[title=>'title',url='http://...',teacher=>'...',language=>''],code=>[...],...)
 */
function WSCourseList($username, $signature, $visibilities = 'public')
{
    if (empty($username) or empty($signature)) {
        return -1;
    }
    global $_configuration;
    $info = api_get_user_info_from_username($username);
    $user_id = $info['user_id'];
    if (!UserManager::is_admin($user_id)) {
        return -1;
    }
    $list = UserManager::get_api_keys($user_id, 'dokeos');
    $key = '';
    foreach ($list as $key) {
        break;
    }
    $local_key = $username . $key;
    if (!api_is_valid_secret_key($signature, $local_key) && !api_is_valid_secret_key($signature, $username . $_configuration['security_key'])) {
        return -1;
        // The secret key is incorrect.
    }
    //public-registered = open
    $vis = array('public' => '3', 'public-registered' => '2', 'private' => '1', 'closed' => '0');
    $courses_list = array();
    if (!is_array($visibilities)) {
        $visibilities = split(',', $visibilities);
    }
    foreach ($visibilities as $visibility) {
        if (!in_array($visibility, array_keys($vis))) {
            return array('error_msg' => 'Security check failed');
        }
        $courses_list_tmp = CourseManager::get_courses_list(null, null, null, null, $vis[$visibility]);
        foreach ($courses_list_tmp as $index => $course) {
            $course_info = CourseManager::get_course_information($course['code']);
            $courses_list[] = array('code' => $course['code'], 'title' => api_utf8_encode($course_info['title']), 'url' => api_get_path(WEB_COURSE_PATH) . $course_info['directory'] . '/', 'teacher' => api_utf8_encode($course_info['tutor_name']), 'language' => $course_info['course_language']);
        }
    }
    return $courses_list;
}
Example #13
0
 /**
  * Export the given HTML to PDF, using a global template
  * @param string the HTML content
  * @uses export/table_pdf.tpl
  */
 function html_to_pdf_with_template($content)
 {
     Display::display_no_header();
     //Assignments
     Display::$global_template->assign('pdf_content', $content);
     $organization = api_get_setting('Institution');
     $img = api_get_path(SYS_CODE_PATH) . 'css/' . api_get_visual_theme() . '/images/header-logo.png';
     if (file_exists($img)) {
         $img = api_get_path(WEB_CODE_PATH) . 'css/' . api_get_visual_theme() . '/images/header-logo.png';
         $organization = "<img src='{$img}'>";
     } else {
         if (!empty($organization)) {
             $organization = '<h2 align="left">' . $organization . '</h2>';
         }
     }
     Display::$global_template->assign('organization', $organization);
     //Showing only the current teacher/admin instead the all teacherlist name see BT#4080
     $user_info = api_get_user_info();
     $teacher_list = $user_info['complete_name'];
     $session_name = api_get_session_name(api_get_session_id());
     if (!empty($session_name)) {
         Display::$global_template->assign('pdf_session', $session_name);
     }
     Display::$global_template->assign('pdf_course', $this->params['course_code']);
     Display::$global_template->assign('pdf_date', api_format_date(api_get_utc_datetime(), DATE_TIME_FORMAT_LONG));
     Display::$global_template->assign('pdf_teachers', $teacher_list);
     Display::$global_template->assign('pdf_title', $this->params['pdf_title']);
     Display::$global_template->assign('add_signatures', $this->params['add_signatures']);
     //Getting template
     $tpl = Display::$global_template->get_template('export/table_pdf.tpl');
     $html = Display::$global_template->fetch($tpl);
     $html = api_utf8_encode($html);
     $css_file = api_get_path(TO_SYS, WEB_CSS_PATH) . '/print.css';
     $css = file_exists($css_file) ? @file_get_contents($css_file) : '';
     self::content_to_pdf($html, $css, $this->params['filename'], $this->params['course_code']);
 }
 /**
  * Search for a session based on a given search string
  * @param string A search string
  * @param string A search box type (single or anything else)
  * @return string XajaxResponse
  * @assert ('abc','single') !== ''
  */
 function search_courses($needle, $type)
 {
     global $tbl_session;
     $xajax_response = new XajaxResponse();
     $return = '';
     if (!empty($needle) && !empty($type)) {
         // xajax send utf8 datas... datas in db can be non-utf8 datas
         $charset = api_get_system_encoding();
         $needle = api_convert_encoding($needle, $charset, 'utf-8');
         $needle = Database::escape_string($needle);
         $sql = 'SELECT * FROM ' . $tbl_session . ' WHERE name LIKE "' . $needle . '%" ORDER BY id';
         $rs = Database::query($sql);
         $course_list = array();
         $return .= '<select id="origin" name="NoSessionCategoryList[]" multiple="multiple" size="20" style="width:340px;">';
         while ($course = Database::fetch_array($rs)) {
             $course_list[] = $course['id'];
             $return .= '<option value="' . $course['id'] . '" title="' . htmlspecialchars($course['name'], ENT_QUOTES) . '">' . $course['name'] . '</option>';
         }
         $return .= '</select>';
         $xajax_response->addAssign('ajax_list_courses_multiple', 'innerHTML', api_utf8_encode($return));
     }
     $_SESSION['course_list'] = $course_list;
     return $xajax_response;
 }
function search($needle, $type)
{
    global $elements_in;
    $xajax_response = new xajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        if ($type == 'single') {
        } else {
            $list = CourseManager::get_courses_list(0, 0, 2, 'ASC', -1, $needle);
        }
        if ($type == 'single') {
        } else {
            $return .= '<select id="elements_not_in" name="elements_not_in_name[]" multiple="multiple" size="15" style="width:360px;">';
            foreach ($list as $row) {
                if (!in_array($row['id'], array_keys($elements_in))) {
                    $return .= '<option value="' . $row['id'] . '">' . $row['title'] . ' (' . $row['visual_code'] . ')</option>';
                }
            }
            $return .= '</select>';
            $xajax_response->addAssign('ajax_list_multiple', 'innerHTML', api_utf8_encode($return));
        }
    }
    return $xajax_response;
}
function search_users($needle, $type)
{
    global $tbl_access_url_rel_user, $tbl_user, $user_anonymous, $current_user_id, $user_id, $userStatus;
    $xajax_response = new xajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        $assigned_users_to_hrm = array();
        switch ($userStatus) {
            case DRH:
                //no break;
            //no break;
            case PLATFORM_ADMIN:
                $assigned_users_to_hrm = UserManager::get_users_followed_by_drh($user_id);
                break;
            case STUDENT_BOSS:
                $assigned_users_to_hrm = UserManager::getUsersFollowedByStudentBoss($user_id);
                break;
        }
        $assigned_users_id = array_keys($assigned_users_to_hrm);
        $without_assigned_users = '';
        $westernOrder = api_is_western_name_order();
        if ($westernOrder) {
            $order_clause = " ORDER BY firstname, lastname";
        } else {
            $order_clause = " ORDER BY lastname, firstname";
        }
        if (count($assigned_users_id) > 0) {
            $without_assigned_users = " AND user.user_id NOT IN(" . implode(',', $assigned_users_id) . ")";
        }
        if (api_is_multiple_url_enabled()) {
            $sql = "SELECT user.user_id, username, lastname, firstname\n                    FROM {$tbl_user} user\n                    LEFT JOIN {$tbl_access_url_rel_user} au ON (au.user_id = user.user_id)\n                    WHERE\n                        " . (api_sort_by_first_name() ? 'firstname' : 'lastname') . " LIKE '{$needle}%' AND\n                        status NOT IN(" . DRH . ", " . SESSIONADMIN . ", " . STUDENT_BOSS . ") AND\n                        user.user_id NOT IN ({$user_anonymous}, {$current_user_id}, {$user_id})\n                        {$without_assigned_users} AND\n                        access_url_id = " . api_get_current_access_url_id() . "\n                    {$order_clause}\n                    ";
        } else {
            $sql = "SELECT user_id, username, lastname, firstname\n                    FROM {$tbl_user} user\n                    WHERE\n                        " . (api_sort_by_first_name() ? 'firstname' : 'lastname') . " LIKE '{$needle}%' AND\n                        status NOT IN(" . DRH . ", " . SESSIONADMIN . ", " . STUDENT_BOSS . ") AND\n                        user_id NOT IN ({$user_anonymous}, {$current_user_id}, {$user_id})\n                    {$without_assigned_users}\n                    {$order_clause}\n            ";
        }
        $rs = Database::query($sql);
        $xajax_response->addAssign('ajax_list_users_multiple', 'innerHTML', api_utf8_encode($return));
        if ($type == 'single') {
            $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
            $access_url_id = api_get_current_access_url_id();
            $sql = 'SELECT user.user_id, username, lastname, firstname
                    FROM ' . $tbl_user . ' user
                    INNER JOIN ' . $tbl_user_rel_access_url . ' url_user ON (url_user.user_id=user.user_id)
                    WHERE
                        access_url_id = ' . $access_url_id . '  AND
                        (
                            username LIKE "' . $needle . '%" OR
                            firstname LIKE "' . $needle . '%" OR
                            lastname LIKE "' . $needle . '%"
                        ) AND ';
            switch ($userStatus) {
                case DRH:
                    $sql .= " user.status <> 6 AND user.status <> " . DRH;
                    break;
                case STUDENT_BOSS:
                    $sql .= " user.status <> 6 AND user.status <> " . STUDENT_BOSS;
                    break;
            }
            $sql .= " {$order_clause} LIMIT 11";
            $rs = Database::query($sql);
            $i = 0;
            while ($user = Database::fetch_array($rs)) {
                $i++;
                if ($i <= 10) {
                    $person_name = api_get_person_name($user['firstname'], $user['lastname']);
                    $return .= '<a href="javascript: void(0);" onclick="javascript: add_user_to_user(\'' . $user['user_id'] . '\',\'' . $person_name . ' (' . $user['username'] . ')' . '\')">' . $person_name . ' (' . $user['username'] . ')</a><br />';
                } else {
                    $return .= '...<br />';
                }
            }
            $xajax_response->addAssign('ajax_list_users_single', 'innerHTML', api_utf8_encode($return));
        } else {
            $return .= '<select id="origin" class="form-control" name="NoAssignedUsersList[]" multiple="multiple" size="15" ">';
            while ($user = Database::fetch_array($rs)) {
                $person_name = api_get_person_name($user['firstname'], $user['lastname']);
                $return .= '<option value="' . $user['user_id'] . '" title="' . htmlspecialchars($person_name, ENT_QUOTES) . '">' . $person_name . ' (' . $user['username'] . ')</option>';
            }
            $return .= '</select>';
            $xajax_response->addAssign('ajax_list_users_multiple', 'innerHTML', api_utf8_encode($return));
        }
    }
    return $xajax_response;
}
function search($needle, $type)
{
    global $tbl_user, $elements_in;
    $xajax_response = new XajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        // xajax send utf8 datas... datas in db can be non-utf8 datas
        $charset = api_get_system_encoding();
        $needle = Database::escape_string($needle);
        $needle = api_convert_encoding($needle, $charset, 'utf-8');
        if ($type == 'single') {
            // search users where username or firstname or lastname begins likes $needle
            /*  $sql = 'SELECT user.user_id, username, lastname, firstname FROM '.$tbl_user.' user
                    WHERE (username LIKE "'.$needle.'%"
                    OR firstname LIKE "'.$needle.'%"
                OR lastname LIKE "'.$needle.'%") AND user.user_id<>"'.$user_anonymous.'"   AND user.status<>'.DRH.''.
                $order_clause.
                ' LIMIT 11';*/
        } else {
            $list = CourseManager::get_courses_list(0, 0, 2, 'ASC', -1, $needle);
        }
        $i = 0;
        if ($type == 'single') {
            /*
                        while ($user = Database :: fetch_array($rs)) {
                            $i++;
                            if ($i<=10) {
                                $person_name = api_get_person_name($user['firstname'], $user['lastname']);
                                $return .= '<a href="javascript: void(0);" onclick="javascript: add_user_to_session(\''.$user['user_id'].'\',\''.$person_name.' ('.$user['username'].')'.'\')">'.$person_name.' ('.$user['username'].')</a><br />';
                            } else {
                                $return .= '...<br />';
                            }
                        }
                        $xajax_response -> addAssign('ajax_list_users_single','innerHTML',api_utf8_encode($return));*/
        } else {
            $return .= '<select id="elements_not_in" name="elements_not_in_name[]" multiple="multiple" size="15" style="width:360px;">';
            foreach ($list as $row) {
                if (!in_array($row['id'], array_keys($elements_in))) {
                    $return .= '<option value="' . $row['id'] . '">' . $row['title'] . ' (' . $row['visual_code'] . ')</option>';
                }
            }
            $return .= '</select>';
            $xajax_response->addAssign('ajax_list_multiple', 'innerHTML', api_utf8_encode($return));
        }
    }
    return $xajax_response;
}
/**
 * Takes the first character in a string and returns its Unicode codepoint.
 * @param string $character				The input string.
 * @param string $encoding (optional)	The encoding of the input string. If it is omitted, the platform character set will be used by default.
 * @return int							Returns: the codepoint of the first character; or 0xFFFD (unknown character) when the input string is empty.
 * This is a multibyte aware version of the function ord().
 * @link http://php.net/manual/en/function.ord.php
 * Note the difference with the original funtion ord(): ord('') returns 0, api_ord('') returns 0xFFFD (unknown character).
 */
function api_ord($character, $encoding)
{
    return Patchwork\Utf8::ord(api_utf8_encode($character, $encoding));
}
function search_users($needle, $type)
{
    global $tbl_user, $tbl_session_rel_user, $id_session;
    $xajax_response = new XajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        //normal behaviour
        if ($type == 'any_session' && $needle == 'false') {
            $type = 'multiple';
            $needle = '';
        }
        // xajax send utf8 datas... datas in db can be non-utf8 datas
        $charset = api_get_system_encoding();
        $needle = Database::escape_string($needle);
        $needle = api_convert_encoding($needle, $charset, 'utf-8');
        $order_clause = api_sort_by_first_name() ? ' ORDER BY firstname, lastname, username' : ' ORDER BY lastname, firstname, username';
        $cond_user_id = '';
        //Only for single & multiple
        if (in_array($type, array('single', 'multiple'))) {
            if (!empty($id_session)) {
                $id_session = intval($id_session);
                // check id_user from session_rel_user table
                $sql = 'SELECT id_user FROM ' . $tbl_session_rel_user . '
                    WHERE id_session ="' . $id_session . '" AND relation_type<>' . SESSION_RELATION_TYPE_RRHH . ' ';
                $res = Database::query($sql);
                $user_ids = array();
                if (Database::num_rows($res) > 0) {
                    while ($row = Database::fetch_row($res)) {
                        $user_ids[] = (int) $row[0];
                    }
                }
                if (count($user_ids) > 0) {
                    $cond_user_id = ' AND user.user_id NOT IN(' . implode(",", $user_ids) . ')';
                }
            }
        }
        switch ($type) {
            case 'single':
                // search users where username or firstname or lastname begins likes $needle
                $sql = 'SELECT user.user_id, username, lastname, firstname, official_code
                        FROM ' . $tbl_user . ' user
                        WHERE (username LIKE "' . $needle . '%" OR firstname LIKE "' . $needle . '%"
                            OR lastname LIKE "' . $needle . '%") AND user.status<>6 AND user.status<>' . DRH . '' . $order_clause . ' LIMIT 11';
                break;
            case 'multiple':
                $sql = 'SELECT user.user_id, username, lastname, firstname, official_code
                        FROM ' . $tbl_user . ' user
                        WHERE ' . (api_sort_by_first_name() ? 'firstname' : 'lastname') . ' LIKE "' . $needle . '%" AND user.status<>' . DRH . ' AND user.status<>6 ' . $cond_user_id . $order_clause;
                break;
            case 'any_session':
                $sql = 'SELECT DISTINCT user.user_id, username, lastname, firstname, official_code
                        FROM ' . $tbl_user . ' user
                        LEFT OUTER JOIN ' . $tbl_session_rel_user . ' s ON (s.id_user = user.user_id)
                        WHERE   s.id_user IS null AND user.status<>' . DRH . ' AND
                                user.status<>6 ' . $cond_user_id . $order_clause;
                break;
        }
        if (api_is_multiple_url_enabled()) {
            $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
            $access_url_id = api_get_current_access_url_id();
            if ($access_url_id != -1) {
                switch ($type) {
                    case 'single':
                        $sql = 'SELECT user.user_id, username, lastname, firstname, official_code
                        FROM ' . $tbl_user . ' user
                        INNER JOIN ' . $tbl_user_rel_access_url . ' url_user ON (url_user.user_id=user.user_id)
                        WHERE access_url_id = ' . $access_url_id . '  AND (username LIKE "' . $needle . '%"
                        OR firstname LIKE "' . $needle . '%"
                        OR lastname LIKE "' . $needle . '%") AND user.status<>6 AND user.status<>' . DRH . ' ' . $order_clause . ' LIMIT 11';
                        break;
                    case 'multiple':
                        $sql = 'SELECT user.user_id, username, lastname, firstname , official_code
                        FROM ' . $tbl_user . ' user
                        INNER JOIN ' . $tbl_user_rel_access_url . ' url_user ON (url_user.user_id=user.user_id)
                        WHERE access_url_id = ' . $access_url_id . ' AND
                            ' . (api_sort_by_first_name() ? 'firstname' : 'lastname') . ' LIKE "' . $needle . '%" AND
                                user.status<>' . DRH . ' AND
                                user.status<>6 ' . $cond_user_id . $order_clause;
                        break;
                    case 'any_session':
                        $sql = 'SELECT DISTINCT user.user_id, username, lastname, firstname, official_code
                            FROM ' . $tbl_user . ' user
                            LEFT OUTER JOIN ' . $tbl_session_rel_user . ' s ON (s.id_user = user.user_id)
                            INNER JOIN ' . $tbl_user_rel_access_url . ' url_user ON (url_user.user_id=user.user_id)
                            WHERE
                                access_url_id = ' . $access_url_id . ' AND
                                s.id_user IS null AND
                                user.status<>' . DRH . ' AND
                                user.status<>6 ' . $cond_user_id . $order_clause;
                        break;
                }
            }
        }
        $rs = Database::query($sql);
        $i = 0;
        if ($type == 'single') {
            while ($user = Database::fetch_array($rs)) {
                $i++;
                if ($i <= 10) {
                    $person_name = api_get_person_name($user['firstname'], $user['lastname']) . ' (' . $user['username'] . ') ' . $user['official_code'];
                    $return .= '<a href="javascript: void(0);" onclick="javascript: add_user_to_session(\'' . $user['user_id'] . '\',\'' . $person_name . ' ' . '\')">' . $person_name . ' </a><br />';
                } else {
                    $return .= '...<br />';
                }
            }
            $xajax_response->addAssign('ajax_list_users_single', 'innerHTML', api_utf8_encode($return));
        } else {
            global $nosessionUsersList;
            $return .= '<select id="origin_users" name="nosessionUsersList[]" multiple="multiple" size="15" style="width:360px;">';
            while ($user = Database::fetch_array($rs)) {
                $person_name = api_get_person_name($user['firstname'], $user['lastname']) . ' (' . $user['username'] . ') ' . $user['official_code'];
                $return .= '<option value="' . $user['user_id'] . '">' . $person_name . ' </option>';
            }
            $return .= '</select>';
            $xajax_response->addAssign('ajax_list_users_multiple', 'innerHTML', api_utf8_encode($return));
        }
    }
    return $xajax_response;
}
/**
 * A reverse case-insensitive string comparison callback function for sorting.
 * @param string $string1		The first string.
 * @param string $string2		The second string.
 * @return int					Returns 0 if $string1 = $string2 or if there is an error; 1 if $string1 < $string2; -1 if $string1 > $string2.
 */
function _api_casercmp($string1, $string2)
{
    global $_api_collator, $_api_encoding;
    $result = collator_compare($_api_collator, api_strtolower(api_utf8_encode($string2, $_api_encoding), 'UTF-8'), api_strtolower(api_utf8_encode($string1, $_api_encoding), 'UTF-8'));
    return $result === false ? 0 : $result;
}
Example #21
0
    /**
     * // TODO: The output encoding should be equal to the system encoding.
     *
     * Exports the learning path as a SCORM package. This is the main function that
     * gathers the content, transforms it, writes the imsmanifest.xml file, zips the
     * whole thing and returns the zip.
     *
     * This method needs to be called in PHP5, as it will fail with non-adequate
     * XML package (like the ones for PHP4), and it is *not* a static method, so
     * you need to call it on a learnpath object.
     * @TODO The method might be redefined later on in the scorm class itself to avoid
     * creating a SCORM structure if there is one already. However, if the initial SCORM
     * path has been modified, it should use the generic method here below.
     * @TODO link this function with the export_lp() function in the same class
     * @param    string    Optional name of zip file. If none, title of learnpath is
     *                     domesticated and trailed with ".zip"
     * @return    string    Returns the zip package string, or null if error
     */
    public function scorm_export()
    {
        $_course = api_get_course_info();
        $course_id = api_get_course_int_id();
        $links_to_create = null;
        // Remove memory and time limits as much as possible as this might be a long process...
        if (function_exists('ini_set')) {
            api_set_memory_limit('128M');
            ini_set('max_execution_time', 600);
        }
        // Create the zip handler (this will remain available throughout the method).
        $archive_path = api_get_path(SYS_ARCHIVE_PATH);
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
        $temp_dir_short = uniqid();
        $temp_zip_dir = $archive_path . '/' . $temp_dir_short;
        $temp_zip_file = $temp_zip_dir . '/' . md5(time()) . '.zip';
        $zip_folder = new PclZip($temp_zip_file);
        $current_course_path = api_get_path(SYS_COURSE_PATH) . api_get_course_path();
        $root_path = $main_path = api_get_path(SYS_PATH);
        $files_cleanup = array();
        // Place to temporarily stash the zipfiles.
        // create the temp dir if it doesn't exist
        // or do a cleanup befor creating the zipfile.
        if (!is_dir($temp_zip_dir)) {
            mkdir($temp_zip_dir, api_get_permissions_for_new_directories());
        } else {
            // Cleanup: Check the temp dir for old files and delete them.
            $handle = opendir($temp_zip_dir);
            while (false !== ($file = readdir($handle))) {
                if ($file != '.' && $file != '..') {
                    unlink("{$temp_zip_dir}/{$file}");
                }
            }
            closedir($handle);
        }
        $zip_files = $zip_files_abs = $zip_files_dist = array();
        if (is_dir($current_course_path . '/scorm/' . $this->path) && is_file($current_course_path . '/scorm/' . $this->path . '/imsmanifest.xml')) {
            // Remove the possible . at the end of the path.
            $dest_path_to_lp = substr($this->path, -1) == '.' ? substr($this->path, 0, -1) : $this->path;
            $dest_path_to_scorm_folder = str_replace('//', '/', $temp_zip_dir . '/scorm/' . $dest_path_to_lp);
            mkdir($dest_path_to_scorm_folder, api_get_permissions_for_new_directories(), true);
            $zip_files_dist = api_copyr($current_course_path . '/scorm/' . $this->path, $dest_path_to_scorm_folder, array('imsmanifest'), $zip_files);
        }
        // Build a dummy imsmanifest structure. Do not add to the zip yet (we still need it).
        // This structure is developed following regulations for SCORM 1.2 packaging in the SCORM 1.2 Content
        // Aggregation Model official document, secion "2.3 Content Packaging".
        $xmldoc = new DOMDocument('1.0');
        // We are going to build a UTF-8 encoded manifest. Later we will recode it to the desired (and supported) encoding.
        $root = $xmldoc->createElement('manifest');
        $root->setAttribute('identifier', 'SingleCourseManifest');
        $root->setAttribute('version', '1.1');
        $root->setAttribute('xmlns', 'http://www.imsproject.org/xsd/imscp_rootv1p1p2');
        $root->setAttribute('xmlns:adlcp', 'http://www.adlnet.org/xsd/adlcp_rootv1p2');
        $root->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
        $root->setAttribute('xsi:schemaLocation', 'http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd');
        // Build mandatory sub-root container elements.
        $metadata = $xmldoc->createElement('metadata');
        $md_schema = $xmldoc->createElement('schema', 'ADL SCORM');
        $metadata->appendChild($md_schema);
        $md_schemaversion = $xmldoc->createElement('schemaversion', '1.2');
        $metadata->appendChild($md_schemaversion);
        $root->appendChild($metadata);
        $organizations = $xmldoc->createElement('organizations');
        $resources = $xmldoc->createElement('resources');
        // Build the only organization we will use in building our learnpaths.
        $organizations->setAttribute('default', 'chamilo_scorm_export');
        $organization = $xmldoc->createElement('organization');
        $organization->setAttribute('identifier', 'chamilo_scorm_export');
        // To set the title of the SCORM entity (=organization), we take the name given
        // in Chamilo and convert it to HTML entities using the Chamilo charset (not the
        // learning path charset) as it is the encoding that defines how it is stored
        // in the database. Then we convert it to HTML entities again as the "&" character
        // alone is not authorized in XML (must be &amp;).
        // The title is then decoded twice when extracting (see scorm::parse_manifest).
        $org_title = $xmldoc->createElement('title', api_utf8_encode($this->get_name()));
        $organization->appendChild($org_title);
        $folder_name = 'document';
        // Removes the learning_path/scorm_folder path when exporting see #4841
        $path_to_remove = null;
        $result = $this->generate_lp_folder($_course);
        if (isset($result['dir']) && strpos($result['dir'], 'learning_path')) {
            $path_to_remove = 'document' . $result['dir'];
            $path_to_replace = $folder_name . '/';
        }
        //Fixes chamilo scorm exports
        if ($this->ref == 'chamilo_scorm_export') {
            $path_to_remove = 'scorm/' . $this->path . '/document/';
        }
        // For each element, add it to the imsmanifest structure, then add it to the zip.
        // Always call the learnpathItem->scorm_export() method to change it to the SCORM format.
        $link_updates = array();
        foreach ($this->items as $index => $item) {
            if (!in_array($item->type, array(TOOL_QUIZ, TOOL_FORUM, TOOL_THREAD, TOOL_LINK, TOOL_STUDENTPUBLICATION))) {
                // Get included documents from this item.
                if ($item->type == 'sco') {
                    $inc_docs = $item->get_resources_from_source(null, api_get_path(SYS_COURSE_PATH) . api_get_course_path() . '/' . 'scorm/' . $this->path . '/' . $item->get_path());
                } else {
                    $inc_docs = $item->get_resources_from_source();
                }
                // Give a child element <item> to the <organization> element.
                $my_item_id = $item->get_id();
                $my_item = $xmldoc->createElement('item');
                $my_item->setAttribute('identifier', 'ITEM_' . $my_item_id);
                $my_item->setAttribute('identifierref', 'RESOURCE_' . $my_item_id);
                $my_item->setAttribute('isvisible', 'true');
                // Give a child element <title> to the <item> element.
                $my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8'));
                $my_item->appendChild($my_title);
                // Give a child element <adlcp:prerequisites> to the <item> element.
                $my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $this->get_scorm_prereq_string($my_item_id));
                $my_prereqs->setAttribute('type', 'aicc_script');
                $my_item->appendChild($my_prereqs);
                // Give a child element <adlcp:maxtimeallowed> to the <item> element - not yet supported.
                //$xmldoc->createElement('adlcp:maxtimeallowed','');
                // Give a child element <adlcp:timelimitaction> to the <item> element - not yet supported.
                //$xmldoc->createElement('adlcp:timelimitaction','');
                // Give a child element <adlcp:datafromlms> to the <item> element - not yet supported.
                //$xmldoc->createElement('adlcp:datafromlms','');
                // Give a child element <adlcp:masteryscore> to the <item> element.
                $my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score());
                $my_item->appendChild($my_masteryscore);
                // Attach this item to the organization element or hits parent if there is one.
                if (!empty($item->parent) && $item->parent != 0) {
                    $children = $organization->childNodes;
                    $possible_parent =& $this->get_scorm_xml_node($children, 'ITEM_' . $item->parent);
                    if (is_object($possible_parent)) {
                        $possible_parent->appendChild($my_item);
                    } else {
                        if ($this->debug > 0) {
                            error_log('Parent ITEM_' . $item->parent . ' of item ITEM_' . $my_item_id . ' not found');
                        }
                    }
                } else {
                    if ($this->debug > 0) {
                        error_log('No parent');
                    }
                    $organization->appendChild($my_item);
                }
                // Get the path of the file(s) from the course directory root.
                $my_file_path = $item->get_file_path('scorm/' . $this->path . '/');
                if (!empty($path_to_remove)) {
                    //From docs
                    $my_xml_file_path = str_replace($path_to_remove, $path_to_replace, $my_file_path);
                    //From quiz
                    if ($this->ref == 'chamilo_scorm_export') {
                        $path_to_remove = 'scorm/' . $this->path . '/';
                        $my_xml_file_path = str_replace($path_to_remove, '', $my_file_path);
                    }
                } else {
                    $my_xml_file_path = $my_file_path;
                }
                $my_sub_dir = dirname($my_file_path);
                $my_sub_dir = str_replace('\\', '/', $my_sub_dir);
                //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_QUOTES, 'UTF-8');
                $my_xml_sub_dir = $my_sub_dir;
                // Give a <resource> child to the <resources> element
                $my_resource = $xmldoc->createElement('resource');
                $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id());
                $my_resource->setAttribute('type', 'webcontent');
                $my_resource->setAttribute('href', $my_xml_file_path);
                // adlcp:scormtype can be either 'sco' or 'asset'.
                if ($item->type == 'sco') {
                    $my_resource->setAttribute('adlcp:scormtype', 'sco');
                } else {
                    $my_resource->setAttribute('adlcp:scormtype', 'asset');
                }
                // xml:base is the base directory to find the files declared in this resource.
                $my_resource->setAttribute('xml:base', '');
                // Give a <file> child to the <resource> element.
                $my_file = $xmldoc->createElement('file');
                $my_file->setAttribute('href', $my_xml_file_path);
                $my_resource->appendChild($my_file);
                // Dependency to other files - not yet supported.
                $i = 1;
                foreach ($inc_docs as $doc_info) {
                    if (count($doc_info) < 1 || empty($doc_info[0])) {
                        continue;
                    }
                    $my_dep = $xmldoc->createElement('resource');
                    $res_id = 'RESOURCE_' . $item->get_id() . '_' . $i;
                    $my_dep->setAttribute('identifier', $res_id);
                    $my_dep->setAttribute('type', 'webcontent');
                    $my_dep->setAttribute('adlcp:scormtype', 'asset');
                    $my_dep_file = $xmldoc->createElement('file');
                    // Check type of URL.
                    //error_log(__LINE__.'Now dealing with '.$doc_info[0].' of type '.$doc_info[1].'-'.$doc_info[2], 0);
                    if ($doc_info[1] == 'remote') {
                        // Remote file. Save url as is.
                        $my_dep_file->setAttribute('href', $doc_info[0]);
                        $my_dep->setAttribute('xml:base', '');
                    } elseif ($doc_info[1] == 'local') {
                        switch ($doc_info[2]) {
                            case 'url':
                                // Local URL - save path as url for now, don't zip file.
                                $abs_path = api_get_path(SYS_PATH) . str_replace(api_get_path(WEB_PATH), '', $doc_info[0]);
                                $current_dir = dirname($abs_path);
                                $current_dir = str_replace('\\', '/', $current_dir);
                                $file_path = realpath($abs_path);
                                $file_path = str_replace('\\', '/', $file_path);
                                $my_dep_file->setAttribute('href', $file_path);
                                $my_dep->setAttribute('xml:base', '');
                                if (strstr($file_path, $main_path) !== false) {
                                    // The calculated real path is really inside Chamilo's root path.
                                    // Reduce file path to what's under the DocumentRoot.
                                    $file_path = substr($file_path, strlen($root_path) - 1);
                                    //echo $file_path;echo '<br /><br />';
                                    //error_log(__LINE__.'Reduced url path: '.$file_path, 0);
                                    $zip_files_abs[] = $file_path;
                                    $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path);
                                    $my_dep_file->setAttribute('href', $file_path);
                                    $my_dep->setAttribute('xml:base', '');
                                } elseif (empty($file_path)) {
                                    /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH)));
                                      if (strpos($document_root, -1) == '/') {
                                          $document_root = substr(0, -1, $document_root);
                                      }*/
                                    $file_path = $_SERVER['DOCUMENT_ROOT'] . $abs_path;
                                    $file_path = str_replace('//', '/', $file_path);
                                    if (file_exists($file_path)) {
                                        $file_path = substr($file_path, strlen($current_dir));
                                        // We get the relative path.
                                        $zip_files[] = $my_sub_dir . '/' . $file_path;
                                        $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path);
                                        $my_dep_file->setAttribute('href', $file_path);
                                        $my_dep->setAttribute('xml:base', '');
                                    }
                                }
                                break;
                            case 'abs':
                                // Absolute path from DocumentRoot. Save file and leave path as is in the zip.
                                $my_dep_file->setAttribute('href', $doc_info[0]);
                                $my_dep->setAttribute('xml:base', '');
                                //$current_dir = str_replace('\\', '/', dirname($current_course_path.'/'.$item->get_file_path())).'/';
                                // The next lines fix a bug when using the "subdir" mode of Chamilo, whereas
                                // an image path would be constructed as /var/www/subdir/subdir/img/foo.bar
                                $abs_img_path_without_subdir = $doc_info[0];
                                $relp = api_get_path(REL_PATH);
                                // The url-append config param.
                                $pos = strpos($abs_img_path_without_subdir, $relp);
                                if ($pos === 0) {
                                    $abs_img_path_without_subdir = '/' . substr($abs_img_path_without_subdir, strlen($relp));
                                }
                                //$file_path = realpath(api_get_path(SYS_PATH).$doc_info[0]);
                                $file_path = realpath(api_get_path(SYS_PATH) . $abs_img_path_without_subdir);
                                $file_path = str_replace('\\', '/', $file_path);
                                $file_path = str_replace('//', '/', $file_path);
                                //error_log(__LINE__.'Abs path: '.$file_path, 0);
                                // Prepare the current directory path (until just under 'document') with a trailing slash.
                                $cur_path = substr($current_course_path, -1) == '/' ? $current_course_path : $current_course_path . '/';
                                // Check if the current document is in that path.
                                if (strstr($file_path, $cur_path) !== false) {
                                    // The document is in that path, now get the relative path
                                    // to the containing document.
                                    $orig_file_path = dirname($cur_path . $my_file_path) . '/';
                                    $orig_file_path = str_replace('\\', '/', $orig_file_path);
                                    $relative_path = '';
                                    if (strstr($file_path, $cur_path) !== false) {
                                        $relative_path = substr($file_path, strlen($orig_file_path));
                                        $file_path = substr($file_path, strlen($cur_path));
                                    } else {
                                        // This case is still a problem as it's difficult to calculate a relative path easily
                                        // might still generate wrong links.
                                        //$file_path = substr($file_path,strlen($cur_path));
                                        // Calculate the directory path to the current file (without trailing slash).
                                        $my_relative_path = dirname($file_path);
                                        $my_relative_path = str_replace('\\', '/', $my_relative_path);
                                        $my_relative_file = basename($file_path);
                                        // Calculate the directory path to the containing file (without trailing slash).
                                        $my_orig_file_path = substr($orig_file_path, 0, -1);
                                        $dotdot = '';
                                        $subdir = '';
                                        while (strstr($my_relative_path, $my_orig_file_path) === false && strlen($my_orig_file_path) > 1 && strlen($my_relative_path) > 1) {
                                            $my_relative_path2 = dirname($my_relative_path);
                                            $my_relative_path2 = str_replace('\\', '/', $my_relative_path2);
                                            $my_orig_file_path = dirname($my_orig_file_path);
                                            $my_orig_file_path = str_replace('\\', '/', $my_orig_file_path);
                                            $subdir = substr($my_relative_path, strlen($my_relative_path2) + 1) . '/' . $subdir;
                                            $dotdot += '../';
                                            $my_relative_path = $my_relative_path2;
                                        }
                                        $relative_path = $dotdot . $subdir . $my_relative_file;
                                    }
                                    // Put the current document in the zip (this array is the array
                                    // that will manage documents already in the course folder - relative).
                                    $zip_files[] = $file_path;
                                    // Update the links to the current document in the containing document (make them relative).
                                    $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $relative_path);
                                    $my_dep_file->setAttribute('href', $file_path);
                                    $my_dep->setAttribute('xml:base', '');
                                } elseif (strstr($file_path, $main_path) !== false) {
                                    // The calculated real path is really inside Chamilo's root path.
                                    // Reduce file path to what's under the DocumentRoot.
                                    $file_path = substr($file_path, strlen($root_path));
                                    //echo $file_path;echo '<br /><br />';
                                    //error_log('Reduced path: '.$file_path, 0);
                                    $zip_files_abs[] = $file_path;
                                    $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path);
                                    $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                    $my_dep->setAttribute('xml:base', '');
                                } elseif (empty($file_path)) {
                                    /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH)));
                                      if(strpos($document_root,-1) == '/') {
                                          $document_root = substr(0, -1, $document_root);
                                      }*/
                                    $file_path = $_SERVER['DOCUMENT_ROOT'] . $doc_info[0];
                                    $file_path = str_replace('//', '/', $file_path);
                                    if (file_exists($file_path)) {
                                        $file_path = substr($file_path, strlen($current_dir));
                                        // We get the relative path.
                                        $zip_files[] = $my_sub_dir . '/' . $file_path;
                                        $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path);
                                        $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                        $my_dep->setAttribute('xml:base', '');
                                    }
                                }
                                break;
                            case 'rel':
                                // Path relative to the current document. Save xml:base as current document's directory and save file in zip as subdir.file_path
                                if (substr($doc_info[0], 0, 2) == '..') {
                                    // Relative path going up.
                                    $current_dir = dirname($current_course_path . '/' . $item->get_file_path()) . '/';
                                    $current_dir = str_replace('\\', '/', $current_dir);
                                    $file_path = realpath($current_dir . $doc_info[0]);
                                    $file_path = str_replace('\\', '/', $file_path);
                                    //error_log($file_path.' <-> '.$main_path,0);
                                    if (strstr($file_path, $main_path) !== false) {
                                        // The calculated real path is really inside Chamilo's root path.
                                        // Reduce file path to what's under the DocumentRoot.
                                        $file_path = substr($file_path, strlen($root_path));
                                        //error_log('Reduced path: '.$file_path, 0);
                                        $zip_files_abs[] = $file_path;
                                        $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path);
                                        $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                        $my_dep->setAttribute('xml:base', '');
                                    }
                                } else {
                                    $zip_files[] = $my_sub_dir . '/' . $doc_info[0];
                                    $my_dep_file->setAttribute('href', $doc_info[0]);
                                    $my_dep->setAttribute('xml:base', $my_xml_sub_dir);
                                }
                                break;
                            default:
                                $my_dep_file->setAttribute('href', $doc_info[0]);
                                $my_dep->setAttribute('xml:base', '');
                                break;
                        }
                    }
                    $my_dep->appendChild($my_dep_file);
                    $resources->appendChild($my_dep);
                    $dependency = $xmldoc->createElement('dependency');
                    $dependency->setAttribute('identifierref', $res_id);
                    $my_resource->appendChild($dependency);
                    $i++;
                }
                //$my_dependency = $xmldoc->createElement('dependency');
                //$my_dependency->setAttribute('identifierref', '');
                $resources->appendChild($my_resource);
                $zip_files[] = $my_file_path;
                //error_log('File '.$my_file_path. ' added to $zip_files', 0);
            } else {
                // If the item is a quiz or a link or whatever non-exportable, we include a step indicating it.
                switch ($item->type) {
                    case TOOL_LINK:
                        $my_item = $xmldoc->createElement('item');
                        $my_item->setAttribute('identifier', 'ITEM_' . $item->get_id());
                        $my_item->setAttribute('identifierref', 'RESOURCE_' . $item->get_id());
                        $my_item->setAttribute('isvisible', 'true');
                        // Give a child element <title> to the <item> element.
                        $my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8'));
                        $my_item->appendChild($my_title);
                        // Give a child element <adlcp:prerequisites> to the <item> element.
                        $my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string());
                        $my_prereqs->setAttribute('type', 'aicc_script');
                        $my_item->appendChild($my_prereqs);
                        // Give a child element <adlcp:maxtimeallowed> to the <item> element - not yet supported.
                        //$xmldoc->createElement('adlcp:maxtimeallowed', '');
                        // Give a child element <adlcp:timelimitaction> to the <item> element - not yet supported.
                        //$xmldoc->createElement('adlcp:timelimitaction', '');
                        // Give a child element <adlcp:datafromlms> to the <item> element - not yet supported.
                        //$xmldoc->createElement('adlcp:datafromlms', '');
                        // Give a child element <adlcp:masteryscore> to the <item> element.
                        $my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score());
                        $my_item->appendChild($my_masteryscore);
                        // Attach this item to the organization element or its parent if there is one.
                        if (!empty($item->parent) && $item->parent != 0) {
                            $children = $organization->childNodes;
                            for ($i = 0; $i < $children->length; $i++) {
                                $item_temp = $children->item($i);
                                if ($item_temp->nodeName == 'item') {
                                    if ($item_temp->getAttribute('identifier') == 'ITEM_' . $item->parent) {
                                        $item_temp->appendChild($my_item);
                                    }
                                }
                            }
                        } else {
                            $organization->appendChild($my_item);
                        }
                        $my_file_path = 'link_' . $item->get_id() . '.html';
                        $sql = 'SELECT url, title FROM ' . Database::get_course_table(TABLE_LINK) . ' WHERE c_id = ' . $course_id . ' AND id=' . $item->path;
                        $rs = Database::query($sql);
                        if ($link = Database::fetch_array($rs)) {
                            $url = $link['url'];
                            $title = stripslashes($link['title']);
                            $links_to_create[$my_file_path] = array('title' => $title, 'url' => $url);
                            //$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8');
                            $my_xml_file_path = $my_file_path;
                            $my_sub_dir = dirname($my_file_path);
                            $my_sub_dir = str_replace('\\', '/', $my_sub_dir);
                            //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_QUOTES, 'UTF-8');
                            $my_xml_sub_dir = $my_sub_dir;
                            // Give a <resource> child to the <resources> element.
                            $my_resource = $xmldoc->createElement('resource');
                            $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id());
                            $my_resource->setAttribute('type', 'webcontent');
                            $my_resource->setAttribute('href', $my_xml_file_path);
                            // adlcp:scormtype can be either 'sco' or 'asset'.
                            $my_resource->setAttribute('adlcp:scormtype', 'asset');
                            // xml:base is the base directory to find the files declared in this resource.
                            $my_resource->setAttribute('xml:base', '');
                            // give a <file> child to the <resource> element.
                            $my_file = $xmldoc->createElement('file');
                            $my_file->setAttribute('href', $my_xml_file_path);
                            $my_resource->appendChild($my_file);
                            $resources->appendChild($my_resource);
                        }
                        break;
                    case TOOL_QUIZ:
                        require_once api_get_path(SYS_CODE_PATH) . 'exercice/exercise.class.php';
                        $exe_id = $item->path;
                        // Should be using ref when everything will be cleaned up in this regard.
                        $exe = new Exercise();
                        $exe->read($exe_id);
                        $my_item = $xmldoc->createElement('item');
                        $my_item->setAttribute('identifier', 'ITEM_' . $item->get_id());
                        $my_item->setAttribute('identifierref', 'RESOURCE_' . $item->get_id());
                        $my_item->setAttribute('isvisible', 'true');
                        // Give a child element <title> to the <item> element.
                        $my_title = $xmldoc->createElement('title', htmlspecialchars(api_utf8_encode($item->get_title()), ENT_QUOTES, 'UTF-8'));
                        $my_item->appendChild($my_title);
                        $my_max_score = $xmldoc->createElement('max_score', $item->get_max());
                        //$my_item->appendChild($my_max_score);
                        // Give a child element <adlcp:prerequisites> to the <item> element.
                        $my_prereqs = $xmldoc->createElement('adlcp:prerequisites', $item->get_prereq_string());
                        $my_prereqs->setAttribute('type', 'aicc_script');
                        $my_item->appendChild($my_prereqs);
                        // Give a child element <adlcp:masteryscore> to the <item> element.
                        $my_masteryscore = $xmldoc->createElement('adlcp:masteryscore', $item->get_mastery_score());
                        $my_item->appendChild($my_masteryscore);
                        // Attach this item to the organization element or hits parent if there is one.
                        if (!empty($item->parent) && $item->parent != 0) {
                            $children = $organization->childNodes;
                            for ($i = 0; $i < $children->length; $i++) {
                                $item_temp = $children->item($i);
                                if ($item_temp->nodeName == 'item') {
                                    if ($item_temp->getAttribute('identifier') == 'ITEM_' . $item->parent) {
                                        $item_temp->appendChild($my_item);
                                    }
                                }
                            }
                        } else {
                            $organization->appendChild($my_item);
                        }
                        // Include export scripts.
                        require_once api_get_path(SYS_CODE_PATH) . 'exercice/export/scorm/scorm_export.php';
                        // Get the path of the file(s) from the course directory root
                        //$my_file_path = $item->get_file_path('scorm/'.$this->path.'/');
                        $my_file_path = 'quiz_' . $item->get_id() . '.html';
                        // Write the contents of the exported exercise into a (big) html file
                        // to later pack it into the exported SCORM. The file will be removed afterwards.
                        $contents = export_exercise($exe_id, true);
                        $tmp_file_path = $archive_path . $temp_dir_short . '/' . $my_file_path;
                        $res = file_put_contents($tmp_file_path, $contents);
                        if ($res === false) {
                            error_log('Could not write into file ' . $tmp_file_path . ' ' . __FILE__ . ' ' . __LINE__, 0);
                        }
                        $files_cleanup[] = $tmp_file_path;
                        //error_log($tmp_path); die();
                        //$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8');
                        $my_xml_file_path = $my_file_path;
                        $my_sub_dir = dirname($my_file_path);
                        $my_sub_dir = str_replace('\\', '/', $my_sub_dir);
                        //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_QUOTES, 'UTF-8');
                        $my_xml_sub_dir = $my_sub_dir;
                        // Give a <resource> child to the <resources> element.
                        $my_resource = $xmldoc->createElement('resource');
                        $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id());
                        $my_resource->setAttribute('type', 'webcontent');
                        $my_resource->setAttribute('href', $my_xml_file_path);
                        // adlcp:scormtype can be either 'sco' or 'asset'.
                        $my_resource->setAttribute('adlcp:scormtype', 'sco');
                        // xml:base is the base directory to find the files declared in this resource.
                        $my_resource->setAttribute('xml:base', '');
                        // Give a <file> child to the <resource> element.
                        $my_file = $xmldoc->createElement('file');
                        $my_file->setAttribute('href', $my_xml_file_path);
                        $my_resource->appendChild($my_file);
                        // Get included docs.
                        $inc_docs = $item->get_resources_from_source(null, $tmp_file_path);
                        // Dependency to other files - not yet supported.
                        $i = 1;
                        foreach ($inc_docs as $doc_info) {
                            if (count($doc_info) < 1 || empty($doc_info[0])) {
                                continue;
                            }
                            $my_dep = $xmldoc->createElement('resource');
                            $res_id = 'RESOURCE_' . $item->get_id() . '_' . $i;
                            $my_dep->setAttribute('identifier', $res_id);
                            $my_dep->setAttribute('type', 'webcontent');
                            $my_dep->setAttribute('adlcp:scormtype', 'asset');
                            $my_dep_file = $xmldoc->createElement('file');
                            // Check type of URL.
                            //error_log(__LINE__.'Now dealing with '.$doc_info[0].' of type '.$doc_info[1].'-'.$doc_info[2], 0);
                            if ($doc_info[1] == 'remote') {
                                // Remote file. Save url as is.
                                $my_dep_file->setAttribute('href', $doc_info[0]);
                                $my_dep->setAttribute('xml:base', '');
                            } elseif ($doc_info[1] == 'local') {
                                switch ($doc_info[2]) {
                                    case 'url':
                                        // Local URL - save path as url for now, don't zip file.
                                        // Save file but as local file (retrieve from URL).
                                        $abs_path = api_get_path(SYS_PATH) . str_replace(api_get_path(WEB_PATH), '', $doc_info[0]);
                                        $current_dir = dirname($abs_path);
                                        $current_dir = str_replace('\\', '/', $current_dir);
                                        $file_path = realpath($abs_path);
                                        $file_path = str_replace('\\', '/', $file_path);
                                        $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                        $my_dep->setAttribute('xml:base', '');
                                        if (strstr($file_path, $main_path) !== false) {
                                            // The calculated real path is really inside the chamilo root path.
                                            // Reduce file path to what's under the DocumentRoot.
                                            $file_path = substr($file_path, strlen($root_path));
                                            //echo $file_path;echo '<br /><br />';
                                            //error_log('Reduced path: '.$file_path, 0);
                                            $zip_files_abs[] = $file_path;
                                            $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => 'document/' . $file_path);
                                            $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                            $my_dep->setAttribute('xml:base', '');
                                        } elseif (empty($file_path)) {
                                            /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH),api_get_path(REL_PATH)));
                                              if (strpos($document_root,-1) == '/') {
                                                  $document_root = substr(0, -1, $document_root);
                                              }*/
                                            $file_path = $_SERVER['DOCUMENT_ROOT'] . $abs_path;
                                            $file_path = str_replace('//', '/', $file_path);
                                            if (file_exists($file_path)) {
                                                $file_path = substr($file_path, strlen($current_dir));
                                                // We get the relative path.
                                                $zip_files[] = $my_sub_dir . '/' . $file_path;
                                                $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => 'document/' . $file_path);
                                                $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                                $my_dep->setAttribute('xml:base', '');
                                            }
                                        }
                                        break;
                                    case 'abs':
                                        // Absolute path from DocumentRoot. Save file and leave path as is in the zip.
                                        $current_dir = dirname($current_course_path . '/' . $item->get_file_path()) . '/';
                                        $current_dir = str_replace('\\', '/', $current_dir);
                                        $file_path = realpath($doc_info[0]);
                                        $file_path = str_replace('\\', '/', $file_path);
                                        $my_dep_file->setAttribute('href', $file_path);
                                        $my_dep->setAttribute('xml:base', '');
                                        if (strstr($file_path, $main_path) !== false) {
                                            // The calculated real path is really inside the chamilo root path.
                                            // Reduce file path to what's under the DocumentRoot.
                                            $file_path = substr($file_path, strlen($root_path));
                                            //echo $file_path;echo '<br /><br />';
                                            //error_log('Reduced path: '.$file_path, 0);
                                            $zip_files_abs[] = $file_path;
                                            $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path);
                                            $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                            $my_dep->setAttribute('xml:base', '');
                                        } elseif (empty($file_path)) {
                                            /*$document_root = substr(api_get_path(SYS_PATH), 0, strpos(api_get_path(SYS_PATH), api_get_path(REL_PATH)));
                                              if (strpos($document_root,-1) == '/') {
                                                  $document_root = substr(0, -1, $document_root);
                                              }*/
                                            $file_path = $_SERVER['DOCUMENT_ROOT'] . $doc_info[0];
                                            $file_path = str_replace('//', '/', $file_path);
                                            if (file_exists($file_path)) {
                                                $file_path = substr($file_path, strlen($current_dir));
                                                // We get the relative path.
                                                $zip_files[] = $my_sub_dir . '/' . $file_path;
                                                $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path);
                                                $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                                $my_dep->setAttribute('xml:base', '');
                                            }
                                        }
                                        break;
                                    case 'rel':
                                        // Path relative to the current document. Save xml:base as current document's directory and save file in zip as subdir.file_path
                                        if (substr($doc_info[0], 0, 2) == '..') {
                                            // Relative path going up.
                                            $current_dir = dirname($current_course_path . '/' . $item->get_file_path()) . '/';
                                            $current_dir = str_replace('\\', '/', $current_dir);
                                            $file_path = realpath($current_dir . $doc_info[0]);
                                            $file_path = str_replace('\\', '/', $file_path);
                                            //error_log($file_path.' <-> '.$main_path, 0);
                                            if (strstr($file_path, $main_path) !== false) {
                                                // The calculated real path is really inside Chamilo's root path.
                                                // Reduce file path to what's under the DocumentRoot.
                                                $file_path = substr($file_path, strlen($root_path));
                                                $file_path_dest = $file_path;
                                                // File path is courses/CHAMILO/document/....
                                                $info_file_path = explode('/', $file_path);
                                                if ($info_file_path[0] == 'courses') {
                                                    // Add character "/" in file path.
                                                    $file_path_dest = 'document/' . $file_path;
                                                }
                                                //error_log('Reduced path: '.$file_path, 0);
                                                $zip_files_abs[] = $file_path;
                                                $link_updates[$my_file_path][] = array('orig' => $doc_info[0], 'dest' => $file_path_dest);
                                                $my_dep_file->setAttribute('href', 'document/' . $file_path);
                                                $my_dep->setAttribute('xml:base', '');
                                            }
                                        } else {
                                            $zip_files[] = $my_sub_dir . '/' . $doc_info[0];
                                            $my_dep_file->setAttribute('href', $doc_info[0]);
                                            $my_dep->setAttribute('xml:base', $my_xml_sub_dir);
                                        }
                                        break;
                                    default:
                                        $my_dep_file->setAttribute('href', $doc_info[0]);
                                        // ../../courses/
                                        $my_dep->setAttribute('xml:base', '');
                                        break;
                                }
                            }
                            $my_dep->appendChild($my_dep_file);
                            $resources->appendChild($my_dep);
                            $dependency = $xmldoc->createElement('dependency');
                            $dependency->setAttribute('identifierref', $res_id);
                            $my_resource->appendChild($dependency);
                            $i++;
                        }
                        $resources->appendChild($my_resource);
                        $zip_files[] = $my_file_path;
                        break;
                    default:
                        // Get the path of the file(s) from the course directory root
                        $my_file_path = 'non_exportable.html';
                        //$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_COMPAT, 'UTF-8');
                        $my_xml_file_path = $my_file_path;
                        $my_sub_dir = dirname($my_file_path);
                        $my_sub_dir = str_replace('\\', '/', $my_sub_dir);
                        //$my_xml_sub_dir = api_htmlentities(api_utf8_encode($my_sub_dir), ENT_COMPAT, 'UTF-8');
                        $my_xml_sub_dir = $my_sub_dir;
                        // Give a <resource> child to the <resources> element.
                        $my_resource = $xmldoc->createElement('resource');
                        $my_resource->setAttribute('identifier', 'RESOURCE_' . $item->get_id());
                        $my_resource->setAttribute('type', 'webcontent');
                        $my_resource->setAttribute('href', $folder_name . '/' . $my_xml_file_path);
                        // adlcp:scormtype can be either 'sco' or 'asset'.
                        $my_resource->setAttribute('adlcp:scormtype', 'asset');
                        // xml:base is the base directory to find the files declared in this resource.
                        $my_resource->setAttribute('xml:base', '');
                        // Give a <file> child to the <resource> element.
                        $my_file = $xmldoc->createElement('file');
                        $my_file->setAttribute('href', 'document/' . $my_xml_file_path);
                        $my_resource->appendChild($my_file);
                        $resources->appendChild($my_resource);
                        break;
                }
            }
        }
        $organizations->appendChild($organization);
        $root->appendChild($organizations);
        $root->appendChild($resources);
        $xmldoc->appendChild($root);
        // TODO: Add a readme file here, with a short description and a link to the Reload player
        // then add the file to the zip, then destroy the file (this is done automatically).
        // http://www.reload.ac.uk/scormplayer.html - once done, don't forget to close FS#138
        //error_log(print_r($zip_files,true), 0);
        foreach ($zip_files as $file_path) {
            if (empty($file_path)) {
                continue;
            }
            //error_log(__LINE__.'getting document from '.$sys_course_path.$_course['path'].'/'.$file_path.' removing '.$sys_course_path.$_course['path'].'/',0);
            $dest_file = $archive_path . $temp_dir_short . '/' . $file_path;
            $this->create_path($dest_file);
            //error_log('copy '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/'.$file_path.' to '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/'.$file_path,0);
            //echo $main_path.$file_path.'<br />';
            @copy($sys_course_path . $_course['path'] . '/' . $file_path, $dest_file);
            // Check if the file needs a link update.
            if (in_array($file_path, array_keys($link_updates))) {
                $string = file_get_contents($dest_file);
                unlink($dest_file);
                foreach ($link_updates[$file_path] as $old_new) {
                    //error_log('Replacing '.$old_new['orig'].' by '.$old_new['dest'].' in '.$file_path, 0);
                    // This is an ugly hack that allows .flv files to be found by the flv player that
                    // will be added in document/main/inc/lib/flv_player/flv_player.swf and that needs
                    // to find the flv to play in document/main/, so we replace main/ in the flv path by
                    // ../../.. to return from inc/lib/flv_player to the document/main path.
                    if (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 5) == 'main/') {
                        $old_new['dest'] = str_replace('main/', '../../../', $old_new['dest']);
                    } elseif (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 6) == 'video/') {
                        $old_new['dest'] = str_replace('video/', '../../../../video/', $old_new['dest']);
                    }
                    //Fix to avoid problems with default_course_document
                    if (strpos("main/default_course_document", $old_new['dest'] === false)) {
                        $new_dest = str_replace('document/', $mult . 'document/', $old_new['dest']);
                    } else {
                        //$new_dest = str_replace('main/default_course_document', $mult.'document/main/default_course_document', $old_new['dest']);
                        $new_dest = $old_new['dest'];
                    }
                    //$string = str_replace($old_new['orig'], $old_new['dest'], $string);
                    $string = str_replace($old_new['orig'], $new_dest, $string);
                    //Add files inside the HTMLs
                    $new_path = str_replace('/courses/', '', $old_new['orig']);
                    //var_dump($sys_course_path.$new_path); var_dump($archive_path.$temp_dir_short.'/'.$old_new['dest']); echo '---';
                    if (file_exists($sys_course_path . $new_path)) {
                        copy($sys_course_path . $new_path, $archive_path . $temp_dir_short . '/' . $old_new['dest']);
                    }
                }
                file_put_contents($dest_file, $string);
            }
        }
        foreach ($zip_files_abs as $file_path) {
            if (empty($file_path)) {
                continue;
            }
            //error_log(__LINE__.'checking existence of '.$main_path.$file_path.'', 0);
            if (!is_file($main_path . $file_path) || !is_readable($main_path . $file_path)) {
                continue;
            }
            //error_log(__LINE__.'getting document from '.$main_path.$file_path.' removing '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/', 0);
            $dest_file = $archive_path . $temp_dir_short . '/document/' . $file_path;
            $this->create_path($dest_file);
            //error_log('Created path '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/document/'.$file_path, 0);
            //error_log('copy '.api_get_path(SYS_COURSE_PATH).$_course['path'].'/'.$file_path.' to '.api_get_path(SYS_ARCHIVE_PATH).$temp_dir_short.'/'.$file_path, 0);
            //echo $main_path.$file_path.' - '.$dest_file.'<br />';
            copy($main_path . $file_path, $dest_file);
            // Check if the file needs a link update.
            if (in_array($file_path, array_keys($link_updates))) {
                $string = file_get_contents($dest_file);
                unlink($dest_file);
                foreach ($link_updates[$file_path] as $old_new) {
                    //error_log('Replacing '.$old_new['orig'].' by '.$old_new['dest'].' in '.$file_path, 0);
                    // This is an ugly hack that allows .flv files to be found by the flv player that
                    // will be added in document/main/inc/lib/flv_player/flv_player.swf and that needs
                    // to find the flv to play in document/main/, so we replace main/ in the flv path by
                    // ../../.. to return from inc/lib/flv_player to the document/main path.
                    if (substr($old_new['dest'], -3) == 'flv' && substr($old_new['dest'], 0, 5) == 'main/') {
                        $old_new['dest'] = str_replace('main/', '../../../', $old_new['dest']);
                    }
                    $string = str_replace($old_new['orig'], $old_new['dest'], $string);
                }
                file_put_contents($dest_file, $string);
            }
        }
        if (is_array($links_to_create)) {
            foreach ($links_to_create as $file => $link) {
                $file_content = '<!DOCTYPE html>
    <head>
                   <meta charset="' . api_get_language_isocode() . '" />
        <title>' . $link['title'] . '</title>
    </head>
    <body dir="' . api_get_text_direction() . '">
                        <div style="text-align:center">
                        <a href="' . $link['url'] . '">' . $link['title'] . '</a></div>
    </body>
</html>';
                file_put_contents($archive_path . $temp_dir_short . '/' . $file, $file_content);
            }
        }
        // Add non exportable message explanation.
        $lang_not_exportable = get_lang('ThisItemIsNotExportable');
        $file_content = '<!DOCTYPE html>
    <head>
            <meta charset="' . api_get_language_isocode() . '" />
        <title>' . $lang_not_exportable . '</title>
        <meta http-equiv="Content-Type" content="text/html; charset=' . api_get_system_encoding() . '" />
    </head>
        <body dir="' . api_get_text_direction() . '">';
        $file_content .= <<<EOD
        <style>
            .error-message {
                font-family: arial, verdana, helvetica, sans-serif;
                border-width: 1px;
                border-style: solid;
                left: 50%;
                margin: 10px auto;
                min-height: 30px;
                padding: 5px;
                right: 50%;
                width: 500px;
                background-color: #FFD1D1;
                border-color: #FF0000;
                color: #000;
            }
        </style>
    <body>
        <div class="error-message">
            {$lang_not_exportable}
        </div>
    </body>
</html>
EOD;
        if (!is_dir($archive_path . $temp_dir_short . '/document')) {
            @mkdir($archive_path . $temp_dir_short . '/document', api_get_permissions_for_new_directories());
        }
        file_put_contents($archive_path . $temp_dir_short . '/document/non_exportable.html', $file_content);
        // Add the extra files that go along with a SCORM package.
        $main_code_path = api_get_path(SYS_CODE_PATH) . 'newscorm/packaging/';
        $extra_files = scandir($main_code_path);
        foreach ($extra_files as $extra_file) {
            if (strpos($extra_file, '.') === 0) {
                continue;
            } else {
                $dest_file = $archive_path . $temp_dir_short . '/' . $extra_file;
                $this->create_path($dest_file);
                copy($main_code_path . $extra_file, $dest_file);
            }
        }
        // Finalize the imsmanifest structure, add to the zip, then return the zip.
        $manifest = @$xmldoc->saveXML();
        $manifest = Text::api_utf8_decode_xml($manifest);
        // The manifest gets the system encoding now.
        file_put_contents($archive_path . '/' . $temp_dir_short . '/imsmanifest.xml', $manifest);
        $zip_folder->add($archive_path . '/' . $temp_dir_short, PCLZIP_OPT_REMOVE_PATH, $archive_path . '/' . $temp_dir_short . '/');
        // Clean possible temporary files.
        foreach ($files_cleanup as $file) {
            $res = unlink($file);
            if ($res === false) {
                error_log('Could not delete temp file ' . $file . ' ' . __FILE__ . ' ' . __LINE__, 0);
            }
        }
        // Send file to client
        $name = api_replace_dangerous_char($this->get_name()) . '.zip';
        DocumentManager::file_send_for_download($temp_zip_file, true, $name);
    }
 /**
  * This function was originally found in the exercise_show.php
  * @param int       $exeId
  * @param int       $questionId
  * @param int       $choice the user selected
  * @param string    $from  function is called from 'exercise_show' or 'exercise_result'
  * @param array     $exerciseResultCoordinates the hotspot coordinates $hotspot[$question_id] = coordinates
  * @param bool      $saved_results save results in the DB or just show the reponse
  * @param bool      $from_database gets information from DB or from the current selection
  * @param bool      $show_result show results or not
  * @param int       $propagate_neg
  * @param array     $hotspot_delineation_result
  *
  * @todo    reduce parameters of this function
  * @return  string  html code
  */
 public function manage_answer($exeId, $questionId, $choice, $from = 'exercise_show', $exerciseResultCoordinates = array(), $saved_results = true, $from_database = false, $show_result = true, $propagate_neg = 0, $hotspot_delineation_result = array())
 {
     global $debug;
     //needed in order to use in the exercise_attempt() for the time
     global $learnpath_id, $learnpath_item_id;
     require_once api_get_path(LIBRARY_PATH) . 'geometry.lib.php';
     $feedback_type = $this->selectFeedbackType();
     $results_disabled = $this->selectResultsDisabled();
     if ($debug) {
         error_log("<------ manage_answer ------> ");
         error_log('exe_id: ' . $exeId);
         error_log('$from:  ' . $from);
         error_log('$saved_results: ' . intval($saved_results));
         error_log('$from_database: ' . intval($from_database));
         error_log('$show_result: ' . $show_result);
         error_log('$propagate_neg: ' . $propagate_neg);
         error_log('$exerciseResultCoordinates: ' . print_r($exerciseResultCoordinates, 1));
         error_log('$hotspot_delineation_result: ' . print_r($hotspot_delineation_result, 1));
         error_log('$learnpath_id: ' . $learnpath_id);
         error_log('$learnpath_item_id: ' . $learnpath_item_id);
         error_log('$choice: ' . print_r($choice, 1));
     }
     $extra_data = array();
     $final_overlap = 0;
     $final_missing = 0;
     $final_excess = 0;
     $overlap_color = 0;
     $missing_color = 0;
     $excess_color = 0;
     $threadhold1 = 0;
     $threadhold2 = 0;
     $threadhold3 = 0;
     $arrques = null;
     $arrans = null;
     $questionId = intval($questionId);
     $exeId = intval($exeId);
     $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
     $table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
     // Creates a temporary Question object
     $course_id = $this->course_id;
     $objQuestionTmp = Question::read($questionId, $course_id);
     if ($objQuestionTmp === false) {
         return false;
     }
     $questionName = $objQuestionTmp->selectTitle();
     $questionWeighting = $objQuestionTmp->selectWeighting();
     $answerType = $objQuestionTmp->selectType();
     $quesId = $objQuestionTmp->selectId();
     $extra = $objQuestionTmp->extra;
     $next = 1;
     //not for now
     // Extra information of the question
     if (!empty($extra)) {
         $extra = explode(':', $extra);
         if ($debug) {
             error_log(print_r($extra, 1));
         }
         // Fixes problems with negatives values using intval
         $true_score = floatval(trim($extra[0]));
         $false_score = floatval(trim($extra[1]));
         $doubt_score = floatval(trim($extra[2]));
     }
     $totalWeighting = 0;
     $totalScore = 0;
     // Destruction of the Question object
     unset($objQuestionTmp);
     // Construction of the Answer object
     $objAnswerTmp = new Answer($questionId);
     $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
     if ($debug) {
         error_log('Count of answers: ' . $nbrAnswers);
         error_log('$answerType: ' . $answerType);
     }
     if ($answerType == FREE_ANSWER || $answerType == ORAL_EXPRESSION || $answerType == CALCULATED_ANSWER) {
         $nbrAnswers = 1;
     }
     $nano = null;
     if ($answerType == ORAL_EXPRESSION) {
         $exe_info = Event::get_exercise_results_by_attempt($exeId);
         $exe_info = isset($exe_info[$exeId]) ? $exe_info[$exeId] : null;
         $params = array();
         $params['course_id'] = $course_id;
         $params['session_id'] = api_get_session_id();
         $params['user_id'] = isset($exe_info['exe_user_id']) ? $exe_info['exe_user_id'] : api_get_user_id();
         $params['exercise_id'] = isset($exe_info['exe_exo_id']) ? $exe_info['exe_exo_id'] : $this->id;
         $params['question_id'] = $questionId;
         $params['exe_id'] = isset($exe_info['exe_id']) ? $exe_info['exe_id'] : $exeId;
         $nano = new Nanogong($params);
         //probably this attempt came in an exercise all question by page
         if ($feedback_type == 0) {
             $nano->replace_with_real_exe($exeId);
         }
     }
     $user_answer = '';
     // Get answer list for matching
     $sql = "SELECT id_auto, id, answer\n                FROM {$table_ans}\n                WHERE c_id = {$course_id} AND question_id = {$questionId}";
     $res_answer = Database::query($sql);
     $answerMatching = array();
     while ($real_answer = Database::fetch_array($res_answer)) {
         $answerMatching[$real_answer['id_auto']] = $real_answer['answer'];
     }
     $real_answers = array();
     $quiz_question_options = Question::readQuestionOption($questionId, $course_id);
     $organs_at_risk_hit = 0;
     $questionScore = 0;
     if ($debug) {
         error_log('Start answer loop ');
     }
     $answer_correct_array = array();
     for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
         $answer = $objAnswerTmp->selectAnswer($answerId);
         $answerComment = $objAnswerTmp->selectComment($answerId);
         $answerCorrect = $objAnswerTmp->isCorrect($answerId);
         $answerWeighting = (double) $objAnswerTmp->selectWeighting($answerId);
         $answerAutoId = $objAnswerTmp->selectAutoId($answerId);
         $answer_correct_array[$answerId] = (bool) $answerCorrect;
         if ($debug) {
             error_log("answer auto id: {$answerAutoId} ");
             error_log("answer correct: {$answerCorrect} ");
         }
         // Delineation
         $delineation_cord = $objAnswerTmp->selectHotspotCoordinates(1);
         $answer_delineation_destination = $objAnswerTmp->selectDestination(1);
         switch ($answerType) {
             // for unique answer
             case UNIQUE_ANSWER:
             case UNIQUE_ANSWER_IMAGE:
             case UNIQUE_ANSWER_NO_OPTION:
                 if ($from_database) {
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE\n                                    exe_id = '" . $exeId . "' AND\n                                    question_id= '" . $questionId . "'";
                     $result = Database::query($sql);
                     $choice = Database::result($result, 0, "answer");
                     $studentChoice = $choice == $answerAutoId ? 1 : 0;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                         $totalScore += $answerWeighting;
                     }
                 } else {
                     $studentChoice = $choice == $answerAutoId ? 1 : 0;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                         $totalScore += $answerWeighting;
                     }
                 }
                 break;
                 // for multiple answers
             // for multiple answers
             case MULTIPLE_ANSWER_TRUE_FALSE:
                 if ($from_database) {
                     $choice = array();
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE\n                                    exe_id = {$exeId} AND\n                                    question_id = " . $questionId;
                     $result = Database::query($sql);
                     while ($row = Database::fetch_array($result)) {
                         $ind = $row['answer'];
                         $values = explode(':', $ind);
                         $my_answer_id = isset($values[0]) ? $values[0] : '';
                         $option = isset($values[1]) ? $values[1] : '';
                         $choice[$my_answer_id] = $option;
                     }
                 }
                 $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                 if (!empty($studentChoice)) {
                     if ($studentChoice == $answerCorrect) {
                         $questionScore += $true_score;
                     } else {
                         if ($quiz_question_options[$studentChoice]['name'] == "Don't know" || $quiz_question_options[$studentChoice]['name'] == "DoubtScore") {
                             $questionScore += $doubt_score;
                         } else {
                             $questionScore += $false_score;
                         }
                     }
                 } else {
                     // If no result then the user just hit don't know
                     $studentChoice = 3;
                     $questionScore += $doubt_score;
                 }
                 $totalScore = $questionScore;
                 break;
             case MULTIPLE_ANSWER:
                 //2
                 if ($from_database) {
                     $choice = array();
                     $sql = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $choice[$ind] = 1;
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     $real_answers[$answerId] = (bool) $studentChoice;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                     }
                 } else {
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     $real_answers[$answerId] = (bool) $studentChoice;
                     if (isset($studentChoice)) {
                         $questionScore += $answerWeighting;
                     }
                 }
                 $totalScore += $answerWeighting;
                 if ($debug) {
                     error_log("studentChoice: {$studentChoice}");
                 }
                 break;
             case GLOBAL_MULTIPLE_ANSWER:
                 if ($from_database) {
                     $choice = array();
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $choice[$ind] = 1;
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     $real_answers[$answerId] = (bool) $studentChoice;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                     }
                 } else {
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     if (isset($studentChoice)) {
                         $questionScore += $answerWeighting;
                     }
                     $real_answers[$answerId] = (bool) $studentChoice;
                 }
                 $totalScore += $answerWeighting;
                 if ($debug) {
                     error_log("studentChoice: {$studentChoice}");
                 }
                 break;
             case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE:
                 if ($from_database) {
                     $sql = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                WHERE exe_id = {$exeId} AND question_id= " . $questionId;
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $result = explode(':', $ind);
                         if (isset($result[0])) {
                             $my_answer_id = isset($result[0]) ? $result[0] : '';
                             $option = isset($result[1]) ? $result[1] : '';
                             $choice[$my_answer_id] = $option;
                         }
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : '';
                     if ($answerCorrect == $studentChoice) {
                         //$answerCorrect = 1;
                         $real_answers[$answerId] = true;
                     } else {
                         //$answerCorrect = 0;
                         $real_answers[$answerId] = false;
                     }
                 } else {
                     $studentChoice = $choice[$answerAutoId];
                     if ($answerCorrect == $studentChoice) {
                         //$answerCorrect = 1;
                         $real_answers[$answerId] = true;
                     } else {
                         //$answerCorrect = 0;
                         $real_answers[$answerId] = false;
                     }
                 }
                 break;
             case MULTIPLE_ANSWER_COMBINATION:
                 if ($from_database) {
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE exe_id = {$exeId} AND question_id= {$questionId}";
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $choice[$ind] = 1;
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     if ($answerCorrect == 1) {
                         if ($studentChoice) {
                             $real_answers[$answerId] = true;
                         } else {
                             $real_answers[$answerId] = false;
                         }
                     } else {
                         if ($studentChoice) {
                             $real_answers[$answerId] = false;
                         } else {
                             $real_answers[$answerId] = true;
                         }
                     }
                 } else {
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     if ($answerCorrect == 1) {
                         if ($studentChoice) {
                             $real_answers[$answerId] = true;
                         } else {
                             $real_answers[$answerId] = false;
                         }
                     } else {
                         if ($studentChoice) {
                             $real_answers[$answerId] = false;
                         } else {
                             $real_answers[$answerId] = true;
                         }
                     }
                 }
                 break;
             case FILL_IN_BLANKS:
                 $str = '';
                 if ($from_database) {
                     $sql = "SELECT answer\n                                    FROM {$TBL_TRACK_ATTEMPT}\n                                    WHERE\n                                        exe_id = {$exeId} AND\n                                        question_id= " . intval($questionId);
                     $result = Database::query($sql);
                     $str = Database::result($result, 0, 'answer');
                 }
                 if ($saved_results == false && strpos($str, 'font color') !== false) {
                     // the question is encoded like this
                     // [A] B [C] D [E] F::10,10,10@1
                     // number 1 before the "@" means that is a switchable fill in blank question
                     // [A] B [C] D [E] F::10,10,10@ or  [A] B [C] D [E] F::10,10,10
                     // means that is a normal fill blank question
                     // first we explode the "::"
                     $pre_array = explode('::', $answer);
                     // is switchable fill blank or not
                     $last = count($pre_array) - 1;
                     $is_set_switchable = explode('@', $pre_array[$last]);
                     $switchable_answer_set = false;
                     if (isset($is_set_switchable[1]) && $is_set_switchable[1] == 1) {
                         $switchable_answer_set = true;
                     }
                     $answer = '';
                     for ($k = 0; $k < $last; $k++) {
                         $answer .= $pre_array[$k];
                     }
                     // splits weightings that are joined with a comma
                     $answerWeighting = explode(',', $is_set_switchable[0]);
                     // we save the answer because it will be modified
                     $temp = $answer;
                     $answer = '';
                     $j = 0;
                     //initialise answer tags
                     $user_tags = $correct_tags = $real_text = array();
                     // the loop will stop at the end of the text
                     while (1) {
                         // quits the loop if there are no more blanks (detect '[')
                         if (($pos = api_strpos($temp, '[')) === false) {
                             // adds the end of the text
                             $answer = $temp;
                             $real_text[] = $answer;
                             break;
                             //no more "blanks", quit the loop
                         }
                         // adds the piece of text that is before the blank
                         //and ends with '[' into a general storage array
                         $real_text[] = api_substr($temp, 0, $pos + 1);
                         $answer .= api_substr($temp, 0, $pos + 1);
                         //take the string remaining (after the last "[" we found)
                         $temp = api_substr($temp, $pos + 1);
                         // quit the loop if there are no more blanks, and update $pos to the position of next ']'
                         if (($pos = api_strpos($temp, ']')) === false) {
                             // adds the end of the text
                             $answer .= $temp;
                             break;
                         }
                         if ($from_database) {
                             $queryfill = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                          WHERE\n                                            exe_id = '" . $exeId . "' AND\n                                            question_id= " . intval($questionId) . "";
                             $resfill = Database::query($queryfill);
                             $str = Database::result($resfill, 0, 'answer');
                             api_preg_match_all('#\\[([^[]*)\\]#', $str, $arr);
                             $str = str_replace('\\r\\n', '', $str);
                             $choice = $arr[1];
                             if (isset($choice[$j])) {
                                 $tmp = api_strrpos($choice[$j], ' / ');
                                 $choice[$j] = api_substr($choice[$j], 0, $tmp);
                                 $choice[$j] = trim($choice[$j]);
                                 // Needed to let characters ' and " to work as part of an answer
                                 $choice[$j] = stripslashes($choice[$j]);
                             } else {
                                 $choice[$j] = null;
                             }
                         } else {
                             // This value is the user input, not escaped while correct answer is escaped by fckeditor
                             $choice[$j] = api_htmlentities(trim($choice[$j]));
                         }
                         $user_tags[] = $choice[$j];
                         //put the contents of the [] answer tag into correct_tags[]
                         $correct_tags[] = api_substr($temp, 0, $pos);
                         $j++;
                         $temp = api_substr($temp, $pos + 1);
                     }
                     $answer = '';
                     $real_correct_tags = $correct_tags;
                     $chosen_list = array();
                     for ($i = 0; $i < count($real_correct_tags); $i++) {
                         if ($i == 0) {
                             $answer .= $real_text[0];
                         }
                         if (!$switchable_answer_set) {
                             // Needed to parse ' and " characters
                             $user_tags[$i] = stripslashes($user_tags[$i]);
                             if ($correct_tags[$i] == $user_tags[$i]) {
                                 // gives the related weighting to the student
                                 $questionScore += $answerWeighting[$i];
                                 // increments total score
                                 $totalScore += $answerWeighting[$i];
                                 // adds the word in green at the end of the string
                                 $answer .= $correct_tags[$i];
                             } elseif (!empty($user_tags[$i])) {
                                 // else if the word entered by the student IS NOT the same as the one defined by the professor
                                 // adds the word in red at the end of the string, and strikes it
                                 $answer .= '<font color="red"><s>' . $user_tags[$i] . '</s></font>';
                             } else {
                                 // adds a tabulation if no word has been typed by the student
                                 $answer .= '';
                                 // remove &nbsp; that causes issue
                             }
                         } else {
                             // switchable fill in the blanks
                             if (in_array($user_tags[$i], $correct_tags)) {
                                 $chosen_list[] = $user_tags[$i];
                                 $correct_tags = array_diff($correct_tags, $chosen_list);
                                 // gives the related weighting to the student
                                 $questionScore += $answerWeighting[$i];
                                 // increments total score
                                 $totalScore += $answerWeighting[$i];
                                 // adds the word in green at the end of the string
                                 $answer .= $user_tags[$i];
                             } elseif (!empty($user_tags[$i])) {
                                 // else if the word entered by the student IS NOT the same as the one defined by the professor
                                 // adds the word in red at the end of the string, and strikes it
                                 $answer .= '<font color="red"><s>' . $user_tags[$i] . '</s></font>';
                             } else {
                                 // adds a tabulation if no word has been typed by the student
                                 $answer .= '';
                                 // remove &nbsp; that causes issue
                             }
                         }
                         // adds the correct word, followed by ] to close the blank
                         $answer .= ' / <font color="green"><b>' . $real_correct_tags[$i] . '</b></font>]';
                         if (isset($real_text[$i + 1])) {
                             $answer .= $real_text[$i + 1];
                         }
                     }
                 } else {
                     // insert the student result in the track_e_attempt table, field answer
                     // $answer is the answer like in the c_quiz_answer table for the question
                     // student data are choice[]
                     $listCorrectAnswers = FillBlanks::getAnswerInfo($answer);
                     $switchableAnswerSet = $listCorrectAnswers["switchable"];
                     $answerWeighting = $listCorrectAnswers["tabweighting"];
                     // user choices is an array $choice
                     // get existing user data in n the BDD
                     if ($from_database) {
                         $sql = "SELECT answer\n                                    FROM {$TBL_TRACK_ATTEMPT}\n                                    WHERE\n                                        exe_id = {$exeId} AND\n                                        question_id= " . intval($questionId);
                         $result = Database::query($sql);
                         $str = Database::result($result, 0, 'answer');
                         $listStudentResults = FillBlanks::getAnswerInfo($str, true);
                         $choice = $listStudentResults['studentanswer'];
                     }
                     // loop other all blanks words
                     if (!$switchableAnswerSet) {
                         // not switchable answer, must be in the same place than teacher order
                         for ($i = 0; $i < count($listCorrectAnswers['tabwords']); $i++) {
                             $studentAnswer = isset($choice[$i]) ? trim($choice[$i]) : '';
                             // This value is the user input, not escaped while correct answer is escaped by fckeditor
                             // Works with cyrillic alphabet and when using ">" chars see #7718 #7610 #7618
                             if (!$from_database) {
                                 $studentAnswer = htmlentities(api_utf8_encode($studentAnswer));
                             }
                             $correctAnswer = $listCorrectAnswers['tabwords'][$i];
                             $isAnswerCorrect = 0;
                             if (FillBlanks::isGoodStudentAnswer($studentAnswer, $correctAnswer)) {
                                 // gives the related weighting to the student
                                 $questionScore += $answerWeighting[$i];
                                 // increments total score
                                 $totalScore += $answerWeighting[$i];
                                 $isAnswerCorrect = 1;
                             }
                             $listCorrectAnswers['studentanswer'][$i] = $studentAnswer;
                             $listCorrectAnswers['studentscore'][$i] = $isAnswerCorrect;
                         }
                     } else {
                         // switchable answer
                         $listStudentAnswerTemp = $choice;
                         $listTeacherAnswerTemp = $listCorrectAnswers['tabwords'];
                         // for every teacher answer, check if there is a student answer
                         for ($i = 0; $i < count($listStudentAnswerTemp); $i++) {
                             $studentAnswer = trim($listStudentAnswerTemp[$i]);
                             $found = false;
                             for ($j = 0; $j < count($listTeacherAnswerTemp); $j++) {
                                 $correctAnswer = $listTeacherAnswerTemp[$j];
                                 if (!$found) {
                                     if (FillBlanks::isGoodStudentAnswer($studentAnswer, $correctAnswer)) {
                                         $questionScore += $answerWeighting[$i];
                                         $totalScore += $answerWeighting[$i];
                                         $listTeacherAnswerTemp[$j] = "";
                                         $found = true;
                                     }
                                 }
                             }
                             $listCorrectAnswers['studentanswer'][$i] = $studentAnswer;
                             if (!$found) {
                                 $listCorrectAnswers['studentscore'][$i] = 0;
                             } else {
                                 $listCorrectAnswers['studentscore'][$i] = 1;
                             }
                         }
                     }
                     $answer = FillBlanks::getAnswerInStudentAttempt($listCorrectAnswers);
                 }
                 break;
                 // for calculated answer
             // for calculated answer
             case CALCULATED_ANSWER:
                 $calculatedAnswer = Session::read('calculatedAnswerId');
                 $answer = $objAnswerTmp->selectAnswer($calculatedAnswer[$questionId]);
                 $preArray = explode('@@', $answer);
                 $last = count($preArray) - 1;
                 $answer = '';
                 for ($k = 0; $k < $last; $k++) {
                     $answer .= $preArray[$k];
                 }
                 $answerWeighting = array($answerWeighting);
                 // we save the answer because it will be modified
                 $temp = $answer;
                 $answer = '';
                 $j = 0;
                 //initialise answer tags
                 $userTags = $correctTags = $realText = array();
                 // the loop will stop at the end of the text
                 while (1) {
                     // quits the loop if there are no more blanks (detect '[')
                     if (($pos = api_strpos($temp, '[')) === false) {
                         // adds the end of the text
                         $answer = $temp;
                         $realText[] = $answer;
                         break;
                         //no more "blanks", quit the loop
                     }
                     // adds the piece of text that is before the blank
                     //and ends with '[' into a general storage array
                     $realText[] = api_substr($temp, 0, $pos + 1);
                     $answer .= api_substr($temp, 0, $pos + 1);
                     //take the string remaining (after the last "[" we found)
                     $temp = api_substr($temp, $pos + 1);
                     // quit the loop if there are no more blanks, and update $pos to the position of next ']'
                     if (($pos = api_strpos($temp, ']')) === false) {
                         // adds the end of the text
                         $answer .= $temp;
                         break;
                     }
                     if ($from_database) {
                         $queryfill = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                          WHERE\n                                            exe_id = '" . $exeId . "' AND\n                                            question_id= " . intval($questionId) . "";
                         $resfill = Database::query($queryfill);
                         $str = Database::result($resfill, 0, 'answer');
                         api_preg_match_all('#\\[([^[]*)\\]#', $str, $arr);
                         $str = str_replace('\\r\\n', '', $str);
                         $choice = $arr[1];
                         if (isset($choice[$j])) {
                             $tmp = api_strrpos($choice[$j], ' / ');
                             $choice[$j] = api_substr($choice[$j], 0, $tmp);
                             $choice[$j] = trim($choice[$j]);
                             // Needed to let characters ' and " to work as part of an answer
                             $choice[$j] = stripslashes($choice[$j]);
                         } else {
                             $choice[$j] = null;
                         }
                     } else {
                         // This value is the user input, not escaped while correct answer is escaped by fckeditor
                         $choice[$j] = api_htmlentities(trim($choice[$j]));
                     }
                     $userTags[] = $choice[$j];
                     //put the contents of the [] answer tag into correct_tags[]
                     $correctTags[] = api_substr($temp, 0, $pos);
                     $j++;
                     $temp = api_substr($temp, $pos + 1);
                 }
                 $answer = '';
                 $realCorrectTags = $correctTags;
                 for ($i = 0; $i < count($realCorrectTags); $i++) {
                     if ($i == 0) {
                         $answer .= $realText[0];
                     }
                     // Needed to parse ' and " characters
                     $userTags[$i] = stripslashes($userTags[$i]);
                     if ($correctTags[$i] == $userTags[$i]) {
                         // gives the related weighting to the student
                         $questionScore += $answerWeighting[$i];
                         // increments total score
                         $totalScore += $answerWeighting[$i];
                         // adds the word in green at the end of the string
                         $answer .= $correctTags[$i];
                     } elseif (!empty($userTags[$i])) {
                         // else if the word entered by the student IS NOT the same as the one defined by the professor
                         // adds the word in red at the end of the string, and strikes it
                         $answer .= '<font color="red"><s>' . $userTags[$i] . '</s></font>';
                     } else {
                         // adds a tabulation if no word has been typed by the student
                         $answer .= '';
                         // remove &nbsp; that causes issue
                     }
                     // adds the correct word, followed by ] to close the blank
                     $answer .= ' / <font color="green"><b>' . $realCorrectTags[$i] . '</b></font>]';
                     if (isset($realText[$i + 1])) {
                         $answer .= $realText[$i + 1];
                     }
                 }
                 break;
                 // for free answer
             // for free answer
             case FREE_ANSWER:
                 if ($from_database) {
                     $query = "SELECT answer, marks FROM " . $TBL_TRACK_ATTEMPT . "\n                                   WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resq = Database::query($query);
                     $data = Database::fetch_array($resq);
                     $choice = $data['answer'];
                     $choice = str_replace('\\r\\n', '', $choice);
                     $choice = stripslashes($choice);
                     $questionScore = $data['marks'];
                     if ($questionScore == -1) {
                         $totalScore += 0;
                     } else {
                         $totalScore += $questionScore;
                     }
                     if ($questionScore == '') {
                         $questionScore = 0;
                     }
                     $arrques = $questionName;
                     $arrans = $choice;
                 } else {
                     $studentChoice = $choice;
                     if ($studentChoice) {
                         //Fixing negative puntation see #2193
                         $questionScore = 0;
                         $totalScore += 0;
                     }
                 }
                 break;
             case ORAL_EXPRESSION:
                 if ($from_database) {
                     $query = "SELECT answer, marks FROM " . $TBL_TRACK_ATTEMPT . "\n                                   WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resq = Database::query($query);
                     $choice = Database::result($resq, 0, 'answer');
                     $choice = str_replace('\\r\\n', '', $choice);
                     $choice = stripslashes($choice);
                     $questionScore = Database::result($resq, 0, "marks");
                     if ($questionScore == -1) {
                         $totalScore += 0;
                     } else {
                         $totalScore += $questionScore;
                     }
                     $arrques = $questionName;
                     $arrans = $choice;
                 } else {
                     $studentChoice = $choice;
                     if ($studentChoice) {
                         //Fixing negative puntation see #2193
                         $questionScore = 0;
                         $totalScore += 0;
                     }
                 }
                 break;
             case DRAGGABLE:
                 //no break
             //no break
             case MATCHING_DRAGGABLE:
                 //no break
             //no break
             case MATCHING:
                 if ($from_database) {
                     $sql = 'SELECT id, answer, id_auto
                             FROM ' . $table_ans . '
                             WHERE
                                 c_id = ' . $course_id . ' AND
                                 question_id = "' . $questionId . '" AND
                                 correct = 0';
                     $res_answer = Database::query($sql);
                     // Getting the real answer
                     $real_list = array();
                     while ($real_answer = Database::fetch_array($res_answer)) {
                         $real_list[$real_answer['id_auto']] = $real_answer['answer'];
                     }
                     $sql = 'SELECT id, answer, correct, id_auto, ponderation
                             FROM ' . $table_ans . '
                             WHERE
                                 c_id = ' . $course_id . ' AND
                                 question_id="' . $questionId . '" AND
                                 correct <> 0
                             ORDER BY id_auto';
                     $res_answers = Database::query($sql);
                     $questionScore = 0;
                     while ($a_answers = Database::fetch_array($res_answers)) {
                         $i_answer_id = $a_answers['id'];
                         //3
                         $s_answer_label = $a_answers['answer'];
                         // your daddy - your mother
                         $i_answer_correct_answer = $a_answers['correct'];
                         //1 - 2
                         $i_answer_id_auto = $a_answers['id_auto'];
                         // 3 - 4
                         $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                    WHERE\n                                        exe_id = '{$exeId}' AND\n                                        question_id = '{$questionId}' AND\n                                        position = '{$i_answer_id_auto}'";
                         $res_user_answer = Database::query($sql);
                         if (Database::num_rows($res_user_answer) > 0) {
                             //  rich - good looking
                             $s_user_answer = Database::result($res_user_answer, 0, 0);
                         } else {
                             $s_user_answer = 0;
                         }
                         $i_answerWeighting = $a_answers['ponderation'];
                         $user_answer = '';
                         if (!empty($s_user_answer)) {
                             if ($answerType == DRAGGABLE) {
                                 if ($s_user_answer == $i_answer_correct_answer) {
                                     $questionScore += $i_answerWeighting;
                                     $totalScore += $i_answerWeighting;
                                     $user_answer = Display::label(get_lang('Correct'), 'success');
                                 } else {
                                     $user_answer = Display::label(get_lang('Incorrect'), 'danger');
                                 }
                             } else {
                                 if ($s_user_answer == $i_answer_correct_answer) {
                                     $questionScore += $i_answerWeighting;
                                     $totalScore += $i_answerWeighting;
                                     if (isset($real_list[$i_answer_id])) {
                                         $user_answer = Display::span($real_list[$i_answer_id]);
                                     }
                                 } else {
                                     $user_answer = Display::span($real_list[$s_user_answer], ['style' => 'color: #FF0000; text-decoration: line-through;']);
                                 }
                             }
                         } elseif ($answerType == DRAGGABLE) {
                             $user_answer = Display::label(get_lang('Incorrect'), 'danger');
                         }
                         if ($show_result) {
                             echo '<tr>';
                             echo '<td>' . $s_answer_label . '</td>';
                             echo '<td>' . $user_answer;
                             if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
                                 if (isset($real_list[$i_answer_correct_answer])) {
                                     echo Display::span($real_list[$i_answer_correct_answer], ['style' => 'color: #008000; font-weight: bold;']);
                                 }
                             }
                             echo '</td>';
                             echo '</tr>';
                         }
                     }
                     break 2;
                     // break the switch and the "for" condition
                 } else {
                     if ($answerCorrect) {
                         if (isset($choice[$answerAutoId]) && $answerCorrect == $choice[$answerAutoId]) {
                             $questionScore += $answerWeighting;
                             $totalScore += $answerWeighting;
                             $user_answer = Display::span($answerMatching[$choice[$answerAutoId]]);
                         } else {
                             if (isset($answerMatching[$choice[$answerAutoId]])) {
                                 $user_answer = Display::span($answerMatching[$choice[$answerAutoId]], ['style' => 'color: #FF0000; text-decoration: line-through;']);
                             }
                         }
                         $matching[$answerAutoId] = $choice[$answerAutoId];
                     }
                     break;
                 }
             case HOT_SPOT:
                 if ($from_database) {
                     $TBL_TRACK_HOTSPOT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
                     $sql = "SELECT hotspot_correct\n                                FROM {$TBL_TRACK_HOTSPOT}\n                                WHERE\n                                    hotspot_exe_id = '" . $exeId . "' AND\n                                    hotspot_question_id= '" . $questionId . "' AND\n                                    hotspot_answer_id = " . intval($answerAutoId) . "";
                     $result = Database::query($sql);
                     $studentChoice = Database::result($result, 0, "hotspot_correct");
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                         $totalScore += $answerWeighting;
                     }
                 } else {
                     if (!isset($choice[$answerAutoId])) {
                         $choice[$answerAutoId] = 0;
                     } else {
                         $studentChoice = $choice[$answerAutoId];
                         $choiceIsValid = false;
                         if (!empty($studentChoice)) {
                             $hotspotType = $objAnswerTmp->selectHotspotType($answerId);
                             $hotspotCoordinates = $objAnswerTmp->selectHotspotCoordinates($answerId);
                             $choicePoint = Geometry::decodePoint($studentChoice);
                             switch ($hotspotType) {
                                 case 'square':
                                     $hotspotProperties = Geometry::decodeSquare($hotspotCoordinates);
                                     $choiceIsValid = Geometry::pointIsInSquare($hotspotProperties, $choicePoint);
                                     break;
                                 case 'circle':
                                     $hotspotProperties = Geometry::decodeEllipse($hotspotCoordinates);
                                     $choiceIsValid = Geometry::pointIsInEllipse($hotspotProperties, $choicePoint);
                                     break;
                                 case 'poly':
                                     $hotspotProperties = Geometry::decodePolygon($hotspotCoordinates);
                                     $choiceIsValid = Geometry::pointIsInPolygon($hotspotProperties, $choicePoint);
                                     break;
                             }
                         }
                         $choice[$answerAutoId] = 0;
                         if ($choiceIsValid) {
                             $questionScore += $answerWeighting;
                             $totalScore += $answerWeighting;
                             $choice[$answerAutoId] = 1;
                         }
                     }
                 }
                 break;
                 // @todo never added to chamilo
                 //for hotspot with fixed order
             // @todo never added to chamilo
             //for hotspot with fixed order
             case HOT_SPOT_ORDER:
                 $studentChoice = $choice['order'][$answerId];
                 if ($studentChoice == $answerId) {
                     $questionScore += $answerWeighting;
                     $totalScore += $answerWeighting;
                     $studentChoice = true;
                 } else {
                     $studentChoice = false;
                 }
                 break;
                 // for hotspot with delineation
             // for hotspot with delineation
             case HOT_SPOT_DELINEATION:
                 if ($from_database) {
                     // getting the user answer
                     $TBL_TRACK_HOTSPOT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
                     $query = "SELECT hotspot_correct, hotspot_coordinate\n                                    FROM {$TBL_TRACK_HOTSPOT}\n                                    WHERE\n                                        hotspot_exe_id = '" . $exeId . "' AND\n                                        hotspot_question_id= '" . $questionId . "' AND\n                                        hotspot_answer_id='1'";
                     //by default we take 1 because it's a delineation
                     $resq = Database::query($query);
                     $row = Database::fetch_array($resq, 'ASSOC');
                     $choice = $row['hotspot_correct'];
                     $user_answer = $row['hotspot_coordinate'];
                     // THIS is very important otherwise the poly_compile will throw an error!!
                     // round-up the coordinates
                     $coords = explode('/', $user_answer);
                     $user_array = '';
                     foreach ($coords as $coord) {
                         list($x, $y) = explode(';', $coord);
                         $user_array .= round($x) . ';' . round($y) . '/';
                     }
                     $user_array = substr($user_array, 0, -1);
                 } else {
                     if (!empty($studentChoice)) {
                         $newquestionList[] = $questionId;
                     }
                     if ($answerId === 1) {
                         $studentChoice = $choice[$answerId];
                         $questionScore += $answerWeighting;
                         if ($hotspot_delineation_result[1] == 1) {
                             $totalScore += $answerWeighting;
                             //adding the total
                         }
                     }
                 }
                 $_SESSION['hotspot_coord'][1] = $delineation_cord;
                 $_SESSION['hotspot_dest'][1] = $answer_delineation_destination;
                 break;
         }
         // end switch Answertype
         if ($show_result) {
             if ($debug) {
                 error_log('show result ' . $show_result);
             }
             if ($from == 'exercise_result') {
                 if ($debug) {
                     error_log('Showing questions $from ' . $from);
                 }
                 //display answers (if not matching type, or if the answer is correct)
                 if (!in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE]) || $answerCorrect) {
                     if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, GLOBAL_MULTIPLE_ANSWER))) {
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, 0, 0, $results_disabled);
                         //}
                     } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                         //if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, $questionId, 0, $results_disabled);
                         //}
                     } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                         //	if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_multiple_answer_combination_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, 0, 0, $results_disabled);
                         //}
                     } elseif ($answerType == FILL_IN_BLANKS) {
                         //if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_fill_in_blanks_answer($feedback_type, $answer, 0, 0, $results_disabled);
                         //	}
                     } elseif ($answerType == CALCULATED_ANSWER) {
                         //if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_calculated_answer($feedback_type, $answer, 0, 0);
                         //  }
                     } elseif ($answerType == FREE_ANSWER) {
                         //if($origin != 'learnpath') {
                         ExerciseShowFunctions::display_free_answer($feedback_type, $choice, $exeId, $questionId, $questionScore);
                         //}
                     } elseif ($answerType == ORAL_EXPRESSION) {
                         // to store the details of open questions in an array to be used in mail
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_oral_expression_answer($feedback_type, $choice, 0, 0, $nano);
                         //}
                     } elseif ($answerType == HOT_SPOT) {
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_hotspot_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment, $results_disabled);
                         //	}
                     } elseif ($answerType == HOT_SPOT_ORDER) {
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_hotspot_order_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment);
                         //}
                     } elseif ($answerType == HOT_SPOT_DELINEATION) {
                         $user_answer = $_SESSION['exerciseResultCoordinates'][$questionId];
                         //round-up the coordinates
                         $coords = explode('/', $user_answer);
                         $user_array = '';
                         foreach ($coords as $coord) {
                             list($x, $y) = explode(';', $coord);
                             $user_array .= round($x) . ';' . round($y) . '/';
                         }
                         $user_array = substr($user_array, 0, -1);
                         if ($next) {
                             $user_answer = $user_array;
                             // we compare only the delineation not the other points
                             $answer_question = $_SESSION['hotspot_coord'][1];
                             $answerDestination = $_SESSION['hotspot_dest'][1];
                             //calculating the area
                             $poly_user = convert_coordinates($user_answer, '/');
                             $poly_answer = convert_coordinates($answer_question, '|');
                             $max_coord = poly_get_max($poly_user, $poly_answer);
                             $poly_user_compiled = poly_compile($poly_user, $max_coord);
                             $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                             $poly_results = poly_result($poly_answer_compiled, $poly_user_compiled, $max_coord);
                             $overlap = $poly_results['both'];
                             $poly_answer_area = $poly_results['s1'];
                             $poly_user_area = $poly_results['s2'];
                             $missing = $poly_results['s1Only'];
                             $excess = $poly_results['s2Only'];
                             //$overlap = round(polygons_overlap($poly_answer,$poly_user));
                             // //this is an area in pixels
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' - Polygons results are ' . print_r($poly_results, 1), 0);
                             }
                             if ($overlap < 1) {
                                 //shortcut to avoid complicated calculations
                                 $final_overlap = 0;
                                 $final_missing = 100;
                                 $final_excess = 100;
                             } else {
                                 // the final overlap is the percentage of the initial polygon
                                 // that is overlapped by the user's polygon
                                 $final_overlap = round((double) $overlap / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final overlap is ' . $final_overlap, 0);
                                 }
                                 // the final missing area is the percentage of the initial polygon
                                 // that is not overlapped by the user's polygon
                                 $final_missing = 100 - $final_overlap;
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final missing is ' . $final_missing, 0);
                                 }
                                 // the final excess area is the percentage of the initial polygon's size
                                 // that is covered by the user's polygon outside of the initial polygon
                                 $final_excess = round(((double) $poly_user_area - (double) $overlap) / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final excess is ' . $final_excess, 0);
                                 }
                             }
                             //checking the destination parameters parsing the "@@"
                             $destination_items = explode('@@', $answerDestination);
                             $threadhold_total = $destination_items[0];
                             $threadhold_items = explode(';', $threadhold_total);
                             $threadhold1 = $threadhold_items[0];
                             // overlap
                             $threadhold2 = $threadhold_items[1];
                             // excess
                             $threadhold3 = $threadhold_items[2];
                             //missing
                             // if is delineation
                             if ($answerId === 1) {
                                 //setting colors
                                 if ($final_overlap >= $threadhold1) {
                                     $overlap_color = true;
                                     //echo 'a';
                                 }
                                 //echo $excess.'-'.$threadhold2;
                                 if ($final_excess <= $threadhold2) {
                                     $excess_color = true;
                                     //echo 'b';
                                 }
                                 //echo '--------'.$missing.'-'.$threadhold3;
                                 if ($final_missing <= $threadhold3) {
                                     $missing_color = true;
                                     //echo 'c';
                                 }
                                 // if pass
                                 if ($final_overlap >= $threadhold1 && $final_missing <= $threadhold3 && $final_excess <= $threadhold2) {
                                     $next = 1;
                                     //go to the oars
                                     $result_comment = get_lang('Acceptable');
                                     $final_answer = 1;
                                     // do not update with  update_exercise_attempt
                                 } else {
                                     $next = 0;
                                     $result_comment = get_lang('Unacceptable');
                                     $comment = $answerDestination = $objAnswerTmp->selectComment(1);
                                     $answerDestination = $objAnswerTmp->selectDestination(1);
                                     //checking the destination parameters parsing the "@@"
                                     $destination_items = explode('@@', $answerDestination);
                                 }
                             } elseif ($answerId > 1) {
                                 if ($objAnswerTmp->selectHotspotType($answerId) == 'noerror') {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - answerId is of type noerror', 0);
                                     }
                                     //type no error shouldn't be treated
                                     $next = 1;
                                     continue;
                                 }
                                 if ($debug > 0) {
                                     error_log(__LINE__ . ' - answerId is >1 so we\'re probably in OAR', 0);
                                 }
                                 //check the intersection between the oar and the user
                                 //echo 'user';	print_r($x_user_list);		print_r($y_user_list);
                                 //echo 'official';print_r($x_list);print_r($y_list);
                                 //$result = get_intersection_data($x_list,$y_list,$x_user_list,$y_user_list);
                                 $inter = $result['success'];
                                 //$delineation_cord=$objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $poly_answer = convert_coordinates($delineation_cord, '|');
                                 $max_coord = poly_get_max($poly_user, $poly_answer);
                                 $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                                 $overlap = poly_touch($poly_user_compiled, $poly_answer_compiled, $max_coord);
                                 if ($overlap == false) {
                                     //all good, no overlap
                                     $next = 1;
                                     continue;
                                 } else {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - Overlap is ' . $overlap . ': OAR hit', 0);
                                     }
                                     $organs_at_risk_hit++;
                                     //show the feedback
                                     $next = 0;
                                     $comment = $answerDestination = $objAnswerTmp->selectComment($answerId);
                                     $answerDestination = $objAnswerTmp->selectDestination($answerId);
                                     $destination_items = explode('@@', $answerDestination);
                                     $try_hotspot = $destination_items[1];
                                     $lp_hotspot = $destination_items[2];
                                     $select_question_hotspot = $destination_items[3];
                                     $url_hotspot = $destination_items[4];
                                 }
                             }
                         } else {
                             // the first delineation feedback
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' first', 0);
                             }
                         }
                     } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
                         echo '<tr>';
                         echo Display::tag('td', $answerMatching[$answerId]);
                         echo Display::tag('td', "{$user_answer} / " . Display::tag('strong', $answerMatching[$answerCorrect], ['style' => 'color: #008000; font-weight: bold;']));
                         echo '</tr>';
                     }
                 }
             } else {
                 if ($debug) {
                     error_log('Showing questions $from ' . $from);
                 }
                 switch ($answerType) {
                     case UNIQUE_ANSWER:
                     case UNIQUE_ANSWER_IMAGE:
                     case UNIQUE_ANSWER_NO_OPTION:
                     case MULTIPLE_ANSWER:
                     case GLOBAL_MULTIPLE_ANSWER:
                     case MULTIPLE_ANSWER_COMBINATION:
                         if ($answerId == 1) {
                             ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, $answerId, $results_disabled);
                         } else {
                             ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, "", $results_disabled);
                         }
                         break;
                     case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE:
                         if ($answerId == 1) {
                             ExerciseShowFunctions::display_multiple_answer_combination_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, $answerId, $results_disabled);
                         } else {
                             ExerciseShowFunctions::display_multiple_answer_combination_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, "", $results_disabled);
                         }
                         break;
                     case MULTIPLE_ANSWER_TRUE_FALSE:
                         if ($answerId == 1) {
                             ExerciseShowFunctions::display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, $answerId, $results_disabled);
                         } else {
                             ExerciseShowFunctions::display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, "", $results_disabled);
                         }
                         break;
                     case FILL_IN_BLANKS:
                         ExerciseShowFunctions::display_fill_in_blanks_answer($feedback_type, $answer, $exeId, $questionId, $results_disabled, $str);
                         break;
                     case CALCULATED_ANSWER:
                         ExerciseShowFunctions::display_calculated_answer($feedback_type, $answer, $exeId, $questionId);
                         break;
                     case FREE_ANSWER:
                         echo ExerciseShowFunctions::display_free_answer($feedback_type, $choice, $exeId, $questionId, $questionScore);
                         break;
                     case ORAL_EXPRESSION:
                         echo '<tr>
                             <td valign="top">' . ExerciseShowFunctions::display_oral_expression_answer($feedback_type, $choice, $exeId, $questionId, $nano) . '</td>
                             </tr>
                             </table>';
                         break;
                     case HOT_SPOT:
                         ExerciseShowFunctions::display_hotspot_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment, $results_disabled);
                         break;
                     case HOT_SPOT_DELINEATION:
                         $user_answer = $user_array;
                         if ($next) {
                             //$tbl_track_e_hotspot = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
                             // Save into db
                             /*	$sql = "INSERT INTO $tbl_track_e_hotspot (
                                 * hotspot_user_id,
                                 *  hotspot_course_code,
                                 *  hotspot_exe_id,
                                 *  hotspot_question_id,
                                 *  hotspot_answer_id,
                                 *  hotspot_correct,
                                 *  hotspot_coordinate
                                 *  )
                                VALUES (
                                 * '".Database::escape_string($_user['user_id'])."',
                                 *  '".Database::escape_string($_course['id'])."',
                                 *  '".Database::escape_string($exeId)."', '".Database::escape_string($questionId)."',
                                 *  '".Database::escape_string($answerId)."',
                                 *  '".Database::escape_string($studentChoice)."',
                                 *  '".Database::escape_string($user_array)."')";
                                $result = Database::query($sql,__FILE__,__LINE__);
                                 */
                             $user_answer = $user_array;
                             // we compare only the delineation not the other points
                             $answer_question = $_SESSION['hotspot_coord'][1];
                             $answerDestination = $_SESSION['hotspot_dest'][1];
                             //calculating the area
                             $poly_user = convert_coordinates($user_answer, '/');
                             $poly_answer = convert_coordinates($answer_question, '|');
                             $max_coord = poly_get_max($poly_user, $poly_answer);
                             $poly_user_compiled = poly_compile($poly_user, $max_coord);
                             $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                             $poly_results = poly_result($poly_answer_compiled, $poly_user_compiled, $max_coord);
                             $overlap = $poly_results['both'];
                             $poly_answer_area = $poly_results['s1'];
                             $poly_user_area = $poly_results['s2'];
                             $missing = $poly_results['s1Only'];
                             $excess = $poly_results['s2Only'];
                             //$overlap = round(polygons_overlap($poly_answer,$poly_user)); //this is an area in pixels
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' - Polygons results are ' . print_r($poly_results, 1), 0);
                             }
                             if ($overlap < 1) {
                                 //shortcut to avoid complicated calculations
                                 $final_overlap = 0;
                                 $final_missing = 100;
                                 $final_excess = 100;
                             } else {
                                 // the final overlap is the percentage of the initial polygon that is overlapped by the user's polygon
                                 $final_overlap = round((double) $overlap / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final overlap is ' . $final_overlap, 0);
                                 }
                                 // the final missing area is the percentage of the initial polygon that is not overlapped by the user's polygon
                                 $final_missing = 100 - $final_overlap;
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final missing is ' . $final_missing, 0);
                                 }
                                 // the final excess area is the percentage of the initial polygon's size that is covered by the user's polygon outside of the initial polygon
                                 $final_excess = round(((double) $poly_user_area - (double) $overlap) / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final excess is ' . $final_excess, 0);
                                 }
                             }
                             //checking the destination parameters parsing the "@@"
                             $destination_items = explode('@@', $answerDestination);
                             $threadhold_total = $destination_items[0];
                             $threadhold_items = explode(';', $threadhold_total);
                             $threadhold1 = $threadhold_items[0];
                             // overlap
                             $threadhold2 = $threadhold_items[1];
                             // excess
                             $threadhold3 = $threadhold_items[2];
                             //missing
                             // if is delineation
                             if ($answerId === 1) {
                                 //setting colors
                                 if ($final_overlap >= $threadhold1) {
                                     $overlap_color = true;
                                     //echo 'a';
                                 }
                                 //echo $excess.'-'.$threadhold2;
                                 if ($final_excess <= $threadhold2) {
                                     $excess_color = true;
                                     //echo 'b';
                                 }
                                 //echo '--------'.$missing.'-'.$threadhold3;
                                 if ($final_missing <= $threadhold3) {
                                     $missing_color = true;
                                     //echo 'c';
                                 }
                                 // if pass
                                 if ($final_overlap >= $threadhold1 && $final_missing <= $threadhold3 && $final_excess <= $threadhold2) {
                                     $next = 1;
                                     //go to the oars
                                     $result_comment = get_lang('Acceptable');
                                     $final_answer = 1;
                                     // do not update with  update_exercise_attempt
                                 } else {
                                     $next = 0;
                                     $result_comment = get_lang('Unacceptable');
                                     $comment = $answerDestination = $objAnswerTmp->selectComment(1);
                                     $answerDestination = $objAnswerTmp->selectDestination(1);
                                     //checking the destination parameters parsing the "@@"
                                     $destination_items = explode('@@', $answerDestination);
                                 }
                             } elseif ($answerId > 1) {
                                 if ($objAnswerTmp->selectHotspotType($answerId) == 'noerror') {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - answerId is of type noerror', 0);
                                     }
                                     //type no error shouldn't be treated
                                     $next = 1;
                                     continue;
                                 }
                                 if ($debug > 0) {
                                     error_log(__LINE__ . ' - answerId is >1 so we\'re probably in OAR', 0);
                                 }
                                 //check the intersection between the oar and the user
                                 //echo 'user';	print_r($x_user_list);		print_r($y_user_list);
                                 //echo 'official';print_r($x_list);print_r($y_list);
                                 //$result = get_intersection_data($x_list,$y_list,$x_user_list,$y_user_list);
                                 $inter = $result['success'];
                                 //$delineation_cord=$objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $poly_answer = convert_coordinates($delineation_cord, '|');
                                 $max_coord = poly_get_max($poly_user, $poly_answer);
                                 $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                                 $overlap = poly_touch($poly_user_compiled, $poly_answer_compiled, $max_coord);
                                 if ($overlap == false) {
                                     //all good, no overlap
                                     $next = 1;
                                     continue;
                                 } else {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - Overlap is ' . $overlap . ': OAR hit', 0);
                                     }
                                     $organs_at_risk_hit++;
                                     //show the feedback
                                     $next = 0;
                                     $comment = $answerDestination = $objAnswerTmp->selectComment($answerId);
                                     $answerDestination = $objAnswerTmp->selectDestination($answerId);
                                     $destination_items = explode('@@', $answerDestination);
                                     $try_hotspot = $destination_items[1];
                                     $lp_hotspot = $destination_items[2];
                                     $select_question_hotspot = $destination_items[3];
                                     $url_hotspot = $destination_items[4];
                                 }
                             }
                         } else {
                             // the first delineation feedback
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' first', 0);
                             }
                         }
                         break;
                     case HOT_SPOT_ORDER:
                         ExerciseShowFunctions::display_hotspot_order_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment);
                         break;
                     case DRAGGABLE:
                         //no break
                     //no break
                     case MATCHING_DRAGGABLE:
                         //no break
                     //no break
                     case MATCHING:
                         echo '<tr>';
                         echo Display::tag('td', $answerMatching[$answerId]);
                         echo Display::tag('td', "{$user_answer} / " . Display::tag('strong', $answerMatching[$answerCorrect], ['style' => 'color: #008000; font-weight: bold;']));
                         echo '</tr>';
                         break;
                 }
             }
         }
         if ($debug) {
             error_log(' ------ ');
         }
     }
     // end for that loops over all answers of the current question
     if ($debug) {
         error_log('-- end answer loop --');
     }
     $final_answer = true;
     foreach ($real_answers as $my_answer) {
         if (!$my_answer) {
             $final_answer = false;
         }
     }
     //we add the total score after dealing with the answers
     if ($answerType == MULTIPLE_ANSWER_COMBINATION || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
         if ($final_answer) {
             //getting only the first score where we save the weight of all the question
             $answerWeighting = $objAnswerTmp->selectWeighting(1);
             $questionScore += $answerWeighting;
             $totalScore += $answerWeighting;
         }
     }
     //Fixes multiple answer question in order to be exact
     //if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
     /* if ($answerType == GLOBAL_MULTIPLE_ANSWER) {
                 $diff = @array_diff($answer_correct_array, $real_answers);
     
                 // All good answers or nothing works like exact
     
                 $counter = 1;
                 $correct_answer = true;
                 foreach ($real_answers as $my_answer) {
                     if ($debug)
                         error_log(" my_answer: $my_answer answer_correct_array[counter]: ".$answer_correct_array[$counter]);
                     if ($my_answer != $answer_correct_array[$counter]) {
                         $correct_answer = false;
                         break;
                     }
                     $counter++;
                 }
     
                 if ($debug) error_log(" answer_correct_array: ".print_r($answer_correct_array, 1)."");
                 if ($debug) error_log(" real_answers: ".print_r($real_answers, 1)."");
                 if ($debug) error_log(" correct_answer: ".$correct_answer);
     
                 if ($correct_answer == false) {
                     $questionScore = 0;
                 }
     
                 // This makes the result non exact
                 if (!empty($diff)) {
                     $questionScore = 0;
                 }
             }*/
     $extra_data = array('final_overlap' => $final_overlap, 'final_missing' => $final_missing, 'final_excess' => $final_excess, 'overlap_color' => $overlap_color, 'missing_color' => $missing_color, 'excess_color' => $excess_color, 'threadhold1' => $threadhold1, 'threadhold2' => $threadhold2, 'threadhold3' => $threadhold3);
     if ($from == 'exercise_result') {
         // if answer is hotspot. To the difference of exercise_show.php,
         //  we use the results from the session (from_db=0)
         // TODO Change this, because it is wrong to show the user
         //  some results that haven't been stored in the database yet
         if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER || $answerType == HOT_SPOT_DELINEATION) {
             if ($debug) {
                 error_log('$from AND this is a hotspot kind of question ');
             }
             $my_exe_id = 0;
             $from_database = 0;
             if ($answerType == HOT_SPOT_DELINEATION) {
                 if (0) {
                     if ($overlap_color) {
                         $overlap_color = 'green';
                     } else {
                         $overlap_color = 'red';
                     }
                     if ($missing_color) {
                         $missing_color = 'green';
                     } else {
                         $missing_color = 'red';
                     }
                     if ($excess_color) {
                         $excess_color = 'green';
                     } else {
                         $excess_color = 'red';
                     }
                     if (!is_numeric($final_overlap)) {
                         $final_overlap = 0;
                     }
                     if (!is_numeric($final_missing)) {
                         $final_missing = 0;
                     }
                     if (!is_numeric($final_excess)) {
                         $final_excess = 0;
                     }
                     if ($final_overlap > 100) {
                         $final_overlap = 100;
                     }
                     $table_resume = '<table class="data_table">
                             <tr class="row_odd" >
                                 <td></td>
                                 <td ><b>' . get_lang('Requirements') . '</b></td>
                                 <td><b>' . get_lang('YourAnswer') . '</b></td>
                             </tr>
                             <tr class="row_even">
                                 <td><b>' . get_lang('Overlap') . '</b></td>
                                 <td>' . get_lang('Min') . ' ' . $threadhold1 . '</td>
                                 <td><div style="color:' . $overlap_color . '">' . ($final_overlap < 0 ? 0 : intval($final_overlap)) . '</div></td>
                             </tr>
                             <tr>
                                 <td><b>' . get_lang('Excess') . '</b></td>
                                 <td>' . get_lang('Max') . ' ' . $threadhold2 . '</td>
                                 <td><div style="color:' . $excess_color . '">' . ($final_excess < 0 ? 0 : intval($final_excess)) . '</div></td>
                             </tr>
                             <tr class="row_even">
                                 <td><b>' . get_lang('Missing') . '</b></td>
                                 <td>' . get_lang('Max') . ' ' . $threadhold3 . '</td>
                                 <td><div style="color:' . $missing_color . '">' . ($final_missing < 0 ? 0 : intval($final_missing)) . '</div></td>
                             </tr>
                         </table>';
                     if ($next == 0) {
                         $try = $try_hotspot;
                         $lp = $lp_hotspot;
                         $destinationid = $select_question_hotspot;
                         $url = $url_hotspot;
                     } else {
                         //show if no error
                         //echo 'no error';
                         $comment = $answerComment = $objAnswerTmp->selectComment($nbrAnswers);
                         $answerDestination = $objAnswerTmp->selectDestination($nbrAnswers);
                     }
                     echo '<h1><div style="color:#333;">' . get_lang('Feedback') . '</div></h1>
                         <p style="text-align:center">';
                     $message = '<p>' . get_lang('YourDelineation') . '</p>';
                     $message .= $table_resume;
                     $message .= '<br />' . get_lang('ResultIs') . ' ' . $result_comment . '<br />';
                     if ($organs_at_risk_hit > 0) {
                         $message .= '<p><b>' . get_lang('OARHit') . '</b></p>';
                     }
                     $message .= '<p>' . $comment . '</p>';
                     echo $message;
                 } else {
                     echo $hotspot_delineation_result[0];
                     //prints message
                     $from_database = 1;
                     // the hotspot_solution.swf needs this variable
                 }
                 //save the score attempts
                 if (1) {
                     //getting the answer 1 or 0 comes from exercise_submit_modal.php
                     $final_answer = $hotspot_delineation_result[1];
                     if ($final_answer == 0) {
                         $questionScore = 0;
                     }
                     // we always insert the answer_id 1 = delineation
                     Event::saveQuestionAttempt($questionScore, 1, $quesId, $exeId, 0);
                     //in delineation mode, get the answer from $hotspot_delineation_result[1]
                     Event::saveExerciseAttemptHotspot($exeId, $quesId, 1, $hotspot_delineation_result[1], $exerciseResultCoordinates[$quesId]);
                 } else {
                     if ($final_answer == 0) {
                         $questionScore = 0;
                         $answer = 0;
                         Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0);
                         if (is_array($exerciseResultCoordinates[$quesId])) {
                             foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) {
                                 Event::saveExerciseAttemptHotspot($exeId, $quesId, $idx, 0, $val);
                             }
                         }
                     } else {
                         Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0);
                         if (is_array($exerciseResultCoordinates[$quesId])) {
                             foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) {
                                 Event::saveExerciseAttemptHotspot($exeId, $quesId, $idx, $choice[$idx], $val);
                             }
                         }
                     }
                 }
                 $my_exe_id = $exeId;
             }
         }
         if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER) {
             // We made an extra table for the answers
             if ($show_result) {
                 //	if ($origin != 'learnpath') {
                 echo '</table></td></tr>';
                 echo "\n                        <tr>\n                            <td colspan=\"2\">\n                                <p><em>" . get_lang('HotSpot') . "</em></p>\n                                <div id=\"hotspot-solution-{$questionId}\"></div>\n\n                                <script>\n                                    \$(document).on('ready', function () {\n                                        new HotspotQuestion({\n                                            questionId: {$questionId},\n                                            exerciseId: {$exeId},\n                                            selector: '#hotspot-solution-{$questionId}',\n                                            for: 'solution'\n                                        });\n                                    });\n                                </script>\n                            </td>\n                        </tr>\n                    ";
                 //	}
             }
         }
         //if ($origin != 'learnpath') {
         if ($show_result) {
             echo '</table>';
         }
         //	}
     }
     unset($objAnswerTmp);
     $totalWeighting += $questionWeighting;
     // Store results directly in the database
     // For all in one page exercises, the results will be
     // stored by exercise_results.php (using the session)
     if ($saved_results) {
         if ($debug) {
             error_log("Save question results {$saved_results}");
         }
         if ($debug) {
             error_log(print_r($choice, 1));
         }
         if (empty($choice)) {
             $choice = 0;
         }
         if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
             if ($choice != 0) {
                 $reply = array_keys($choice);
                 for ($i = 0; $i < sizeof($reply); $i++) {
                     $ans = $reply[$i];
                     Event::saveQuestionAttempt($questionScore, $ans . ':' . $choice[$ans], $quesId, $exeId, $i, $this->id);
                     if ($debug) {
                         error_log('result =>' . $questionScore . ' ' . $ans . ':' . $choice[$ans]);
                     }
                 }
             } else {
                 Event::saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
             }
         } elseif ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
             if ($choice != 0) {
                 $reply = array_keys($choice);
                 if ($debug) {
                     error_log("reply " . print_r($reply, 1) . "");
                 }
                 for ($i = 0; $i < sizeof($reply); $i++) {
                     $ans = $reply[$i];
                     Event::saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
                 }
             } else {
                 Event::saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
             }
         } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
             if ($choice != 0) {
                 $reply = array_keys($choice);
                 for ($i = 0; $i < sizeof($reply); $i++) {
                     $ans = $reply[$i];
                     Event::saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
                 }
             } else {
                 Event::saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
             }
         } elseif (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) {
             if (isset($matching)) {
                 foreach ($matching as $j => $val) {
                     Event::saveQuestionAttempt($questionScore, $val, $quesId, $exeId, $j, $this->id);
                 }
             }
         } elseif ($answerType == FREE_ANSWER) {
             $answer = $choice;
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
         } elseif ($answerType == ORAL_EXPRESSION) {
             $answer = $choice;
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id, $nano);
         } elseif (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION])) {
             $answer = $choice;
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
             //            } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
         } elseif ($answerType == HOT_SPOT) {
             $answer = [];
             if (isset($exerciseResultCoordinates[$questionId]) && !empty($exerciseResultCoordinates[$questionId])) {
                 Database::delete(Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT), ['hotspot_exe_id = ? AND hotspot_question_id = ? AND c_id = ?' => [$exeId, $questionId, api_get_course_int_id()]]);
                 foreach ($exerciseResultCoordinates[$questionId] as $idx => $val) {
                     $answer[] = $val;
                     Event::saveExerciseAttemptHotspot($exeId, $quesId, $idx, $choice[$idx], $val, false, $this->id);
                 }
             }
             Event::saveQuestionAttempt($questionScore, implode('|', $answer), $quesId, $exeId, 0, $this->id);
         } else {
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
         }
     }
     if ($propagate_neg == 0 && $questionScore < 0) {
         $questionScore = 0;
     }
     if ($saved_results) {
         $stat_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
         $sql = 'UPDATE ' . $stat_table . ' SET
                     exe_result = exe_result + ' . floatval($questionScore) . '
                 WHERE exe_id = ' . $exeId;
         if ($debug) {
             error_log($sql);
         }
         Database::query($sql);
     }
     $return_array = array('score' => $questionScore, 'weight' => $questionWeighting, 'extra' => $extra_data, 'open_question' => $arrques, 'open_answer' => $arrans, 'answer_type' => $answerType);
     return $return_array;
 }
    /**
     * Searches a course, given a search string and a type of search box
     * @param string $needle Search string
     * @param string $type Type of search box ('single' or anything else)
     * @return string XajaxResponse
     * @assert ('abc', 'single') !== null
     * @assert ('abc', 'multiple') !== null
     */
    public static function search_courses($needle, $type)
    {
        global $tbl_course, $tbl_session_rel_course, $id_session;
        $course_title = null;
        $xajax_response = new xajaxResponse();
        $return = '';
        if (!empty($needle) && !empty($type)) {
            // xajax send utf8 datas... datas in db can be non-utf8 datas
            $charset = api_get_system_encoding();
            $needle = api_convert_encoding($needle, $charset, 'utf-8');
            $cond_course_code = '';
            if (!empty($id_session)) {
                $id_session = intval($id_session);
                // check course_code from session_rel_course table
                $sql = 'SELECT c_id FROM ' . $tbl_session_rel_course . '
						WHERE session_id = ' . $id_session;
                $res = Database::query($sql);
                $course_codes = '';
                if (Database::num_rows($res) > 0) {
                    while ($row = Database::fetch_row($res)) {
                        $course_codes .= '\'' . $row[0] . '\',';
                    }
                    $course_codes = substr($course_codes, 0, strlen($course_codes) - 1);
                    $cond_course_code = ' AND course.id NOT IN(' . $course_codes . ') ';
                }
            }
            if ($type == 'single') {
                // search users where username or firstname or lastname begins likes $needle
                $sql = 'SELECT
							course.code,
						 	course.visual_code,
						 	course.title,
						 	session_rel_course.session_id
						FROM ' . $tbl_course . ' course
						LEFT JOIN ' . $tbl_session_rel_course . ' session_rel_course
							ON course.id = session_rel_course.c_id
							AND session_rel_course.session_id = ' . intval($id_session) . '
						WHERE
							course.visual_code LIKE "' . $needle . '%" OR
							course.title LIKE "' . $needle . '%"';
            } else {
                $sql = 'SELECT course.code, course.visual_code, course.title
						FROM ' . $tbl_course . ' course
						WHERE
							course.visual_code LIKE "' . $needle . '%" ' . $cond_course_code . '
						ORDER BY course.code ';
            }
            if (api_is_multiple_url_enabled()) {
                $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
                $access_url_id = api_get_current_access_url_id();
                if ($access_url_id != -1) {
                    if ($type == 'single') {
                        $sql = 'SELECT
						            course.code,
						            course.visual_code,
						            course.title,
						            session_rel_course.session_id
								FROM ' . $tbl_course . ' course
								LEFT JOIN ' . $tbl_session_rel_course . ' session_rel_course
									ON course.id = session_rel_course.c_id
									AND session_rel_course.session_id = ' . intval($id_session) . '
								INNER JOIN ' . $tbl_course_rel_access_url . ' url_course
								ON (url_course.c_id = course.id)
								WHERE
									access_url_id = ' . $access_url_id . ' AND
									(course.visual_code LIKE "' . $needle . '%" OR
									course.title LIKE "' . $needle . '%" )';
                    } else {
                        $sql = 'SELECT course.code, course.visual_code, course.title
								FROM ' . $tbl_course . ' course, ' . $tbl_course_rel_access_url . ' url_course
								WHERE
									url_course.c_id = course.id AND
									access_url_id = ' . $access_url_id . ' AND
									course.visual_code LIKE "' . $needle . '%" ' . $cond_course_code . '
								ORDER BY course.code ';
                    }
                }
            }
            $rs = Database::query($sql);
            $course_list = array();
            if ($type == 'single') {
                while ($course = Database::fetch_array($rs)) {
                    $course_list[] = $course['code'];
                    $course_title = str_replace("'", "\\'", $course_title);
                    $return .= '<a href="javascript: void(0);" onclick="javascript: add_course_to_session(\'' . $course['code'] . '\',\'' . $course_title . ' (' . $course['visual_code'] . ')' . '\')">' . $course['title'] . ' (' . $course['visual_code'] . ')</a><br />';
                }
                $xajax_response->addAssign('ajax_list_courses_single', 'innerHTML', api_utf8_encode($return));
            } else {
                $return .= '<select id="origin" name="NoSessionCoursesList[]" multiple="multiple" size="20" style="width:340px;">';
                while ($course = Database::fetch_array($rs)) {
                    $course_list[] = $course['code'];
                    $course_title = str_replace("'", "\\'", $course_title);
                    $return .= '<option value="' . $course['code'] . '" title="' . htmlspecialchars($course['title'] . ' (' . $course['visual_code'] . ')', ENT_QUOTES) . '">' . $course['title'] . ' (' . $course['visual_code'] . ')</option>';
                }
                $return .= '</select>';
                $xajax_response->addAssign('ajax_list_courses_multiple', 'innerHTML', api_utf8_encode($return));
            }
        }
        $_SESSION['course_list'] = $course_list;
        return $xajax_response;
    }
Example #24
0
 /**
  * Export the given HTML to PDF, using a global template
  *
  * @uses export/table_pdf.tpl
  * @param $content
  * @param bool|false $saveToFile
  * @param bool|false $returnHtml
  *
  * @return string
  */
 public function html_to_pdf_with_template($content, $saveToFile = false, $returnHtml = false)
 {
     if (empty($this->template)) {
         $tpl = new Template('', false, false, false);
     } else {
         $tpl = $this->template;
     }
     // Assignments
     // Assignments
     $tpl->assign('pdf_content', $content);
     $organization = api_get_setting('Institution');
     $img = api_get_path(SYS_CSS_PATH) . 'themes/' . api_get_visual_theme() . '/images/header-logo.png';
     // Search for classic logo
     if (file_exists($img)) {
         $img = api_get_path(WEB_CSS_PATH) . 'themes/' . api_get_visual_theme() . '/images/header-logo.png';
         $organization = "<img src='{$img}'>";
     } else {
         // Just use the platform title.
         if (!empty($organization)) {
             $organization = '<h2 align="left">' . $organization . '</h2>';
         }
     }
     // Use custom logo image.
     $pdfLogo = api_get_setting('pdf_logo_header');
     if ($pdfLogo === 'true') {
         $visualTheme = api_get_visual_theme();
         $img = api_get_path(SYS_CSS_PATH) . 'themes/' . $visualTheme . '/images/pdf_logo_header.png';
         if (file_exists($img)) {
             $img = api_get_path(WEB_CSS_PATH) . 'themes/' . $visualTheme . '/images/pdf_logo_header.png';
             $organization = "<img src='{$img}'>";
         }
     }
     $tpl->assign('organization', $organization);
     //Showing only the current teacher/admin instead the all teacher list name see BT#4080
     if (isset($this->params['show_real_course_teachers']) && $this->params['show_real_course_teachers']) {
         if (isset($this->params['session_info']) && !empty($this->params['session_info'])) {
             $teacher_list = SessionManager::getCoachesByCourseSessionToString($this->params['session_info']['id'], $this->params['course_info']['real_id']);
         } else {
             $teacher_list = CourseManager::get_teacher_list_from_course_code_to_string($this->params['course_code']);
         }
     } else {
         $user_info = api_get_user_info();
         if ($this->params['show_teacher_as_myself']) {
             $teacher_list = $user_info['complete_name'];
         }
     }
     $tpl->assign('pdf_course', $this->params['course_code']);
     $tpl->assign('pdf_course_info', $this->params['course_info']);
     $tpl->assign('pdf_session_info', $this->params['session_info']);
     $tpl->assign('pdf_date', $this->params['pdf_date']);
     $tpl->assign('pdf_teachers', $teacher_list);
     $tpl->assign('pdf_title', $this->params['pdf_title']);
     $tpl->assign('pdf_student_info', $this->params['student_info']);
     $tpl->assign('show_grade_generated_date', $this->params['show_grade_generated_date']);
     $tpl->assign('add_signatures', $this->params['add_signatures']);
     // Getting template
     $tableTemplate = $tpl->get_template('export/table_pdf.tpl');
     $html = $tpl->fetch($tableTemplate);
     $html = api_utf8_encode($html);
     $css_file = api_get_path(TO_SYS, WEB_CSS_PATH) . '/print.css';
     $css = file_exists($css_file) ? @file_get_contents($css_file) : '';
     $html = self::content_to_pdf($html, $css, $this->params['filename'], $this->params['course_code'], 'D', $saveToFile, null, $returnHtml);
     if ($returnHtml) {
         return $html;
     }
 }
/**
 * Note: Try to avoid using this function. Use api_preg_replace() with Perl-compatible regular expression syntax.
 *
 * Scans string for matches to pattern, then replaces the matched text with replacement, ignoring case, with extended multibyte support.
 * By default this function uses the platform character set.
 * @param string $pattern                The regular expression pattern.
 * @param string $replacement            The replacement text.
 * @param string $string                The searched string.
 * @param string $option (optional)        Matching condition.
 * If i is specified for the matching condition parameter, the case will be ignored.
 * If x is specified, white space will be ignored.
 * If m is specified, match will be executed in multiline mode and line break will be included in '.'.
 * If p is specified, match will be executed in POSIX mode, line break will be considered as normal character.
 * If e is specified, replacement string will be evaluated as PHP expression.
 * @return mixed                        The modified string is returned. If no matches are found within the string, then it will be returned unchanged. FALSE will be returned on error.
 * This function is aimed at replacing the functions eregi_replace() and mb_eregi_replace() for human-language strings.
 * @link http://php.net/manual/en/function.eregi-replace
 * @link http://php.net/manual/en/function.mb-eregi-replace
 */
function api_eregi_replace($pattern, $replacement, $string, $option = null)
{
    $encoding = _api_mb_regex_encoding();
    if (_api_mb_supports($encoding)) {
        if (is_null($option)) {
            return @mb_eregi_replace($pattern, $replacement, $string);
        }
        return @mb_eregi_replace($pattern, $replacement, $string, $option);
    }
    if (MBSTRING_INSTALLED && api_is_encoding_supported($encoding)) {
        _api_mb_regex_encoding('UTF-8');
        if (is_null($option)) {
            $result = api_utf8_decode(@mb_eregi_replace(api_utf8_encode($pattern, $encoding), api_utf8_encode($replacement, $encoding), api_utf8_encode($string, $encoding)), $encoding);
        } else {
            $result = api_utf8_decode(@mb_eregi_replace(api_utf8_encode($pattern, $encoding), api_utf8_encode($replacement, $encoding), api_utf8_encode($string, $encoding), $option), $encoding);
        }
        _api_mb_regex_encoding($encoding);
        return $result;
    }
    return eregi_replace($pattern, $replacement, $string);
}
Example #26
0
    /**
     * Export the given HTML to PDF, using a global template
     * @param string $content the HTML content
     *
     * @uses export/table_pdf.tpl
     */
    public function html_to_pdf_with_template($content)
    {
        global $_configuration;
        Display :: display_no_header();

        // Assignments
        Display::$global_template->assign('pdf_content', $content);

        $organization = api_get_setting('Institution');
        $img = api_get_path(SYS_CODE_PATH).'css/'.api_get_visual_theme().'/images/header-logo.png';

        // Search for classic logo
        if (file_exists($img)) {
            $img = api_get_path(WEB_CODE_PATH).'css/'.api_get_visual_theme().'/images/header-logo.png';
            $organization = "<img src='$img'>";
        } else {
            // Just use the platform title.
            if (!empty($organization)) {
                $organization = '<h2 align="left">'.$organization.'</h2>';
            }
        }

        // Use custom logo image.
        if (isset($_configuration['pdf_logo_header']) &&
            $_configuration['pdf_logo_header']
        ) {
            $img = api_get_path(SYS_CODE_PATH).'css/'.api_get_visual_theme().'/images/pdf_logo_header.png';
            if (file_exists($img)) {
                $img = api_get_path(WEB_CODE_PATH) . 'css/' . api_get_visual_theme() . '/images/pdf_logo_header.png';
                $organization = "<img src='$img'>";
            }
        }

        Display::$global_template->assign('organization', $organization);

        //Showing only the current teacher/admin instead the all teacher list name see BT#4080

        if (isset($this->params['show_real_course_teachers']) &&
            $this->params['show_real_course_teachers']
        ) {
            if (isset($this->params['session_info']) &&
                !empty($this->params['session_info'])
            ) {
                $teacher_list = SessionManager::getCoachesByCourseSessionToString(
                    $this->params['session_info']['id'],
                    $this->params['course_code']

                );
            } else {
                $teacher_list = CourseManager::get_teacher_list_from_course_code_to_string(
                    $this->params['course_code']
                );
            }
        } else {
            $user_info = api_get_user_info();
            $teacher_list = $user_info['complete_name'];
        }

        Display::$global_template->assign('pdf_course', $this->params['course_code']);
        Display::$global_template->assign('pdf_course_info', $this->params['course_info']);
        Display::$global_template->assign('pdf_session_info', $this->params['session_info']);
        Display::$global_template->assign('pdf_date', api_format_date(api_get_local_time(), DATE_TIME_FORMAT_LONG));
        Display::$global_template->assign('pdf_teachers', $teacher_list);
        Display::$global_template->assign('pdf_title', $this->params['pdf_title']);
        Display::$global_template->assign('add_signatures', $this->params['add_signatures']);

        // Getting template
        $tpl = Display::$global_template->get_template('export/table_pdf.tpl');
        $html = Display::$global_template->fetch($tpl);
        $html = api_utf8_encode($html);

        $css_file = api_get_path(TO_SYS, WEB_CSS_PATH).'/print.css';
        $css = file_exists($css_file) ? @file_get_contents($css_file) : '';
        self::content_to_pdf($html, $css, $this->params['filename'], $this->params['course_code']);
    }
function search_sessions($needle, $type)
{
    global $session_in_promotion;
    $xajax_response = new xajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        $session_list = SessionManager::get_sessions_list(array('s.name' => array('operator' => 'LIKE', 'value' => "{$needle}%")));
        $return .= '<select id="session_not_in_promotion" name="session_not_in_promotion_name[]" multiple="multiple" size="15" style="width:360px;">';
        foreach ($session_list as $row) {
            if (!in_array($row['id'], array_keys($session_in_promotion))) {
                $return .= '<option value="' . $row['id'] . '">' . $row['name'] . '</option>';
            }
        }
        $return .= '</select>';
        $xajax_response->addAssign('ajax_list_multiple', 'innerHTML', api_utf8_encode($return));
    }
    return $xajax_response;
}
function search_sessions($needle, $type)
{
    global $elements_in;
    $xajax_response = new xajaxResponse();
    $return = '';
    if (!empty($needle) && !empty($type)) {
        if ($type == 'single') {
            // search users where username or firstname or lastname begins likes $needle
            /*  $sql = 'SELECT user.user_id, username, lastname, firstname FROM '.$tbl_user.' user
                    WHERE (username LIKE "'.$needle.'%"
                    OR firstname LIKE "'.$needle.'%"
                OR lastname LIKE "'.$needle.'%") AND user.user_id<>"'.$user_anonymous.'"   AND user.status<>'.DRH.''.
                $order_clause.
                ' LIMIT 11';*/
        } else {
            if ($type == 'searchbox') {
                $session_list = SessionManager::get_sessions_list(array('s.name' => array('operator' => 'LIKE', 'value' => "%{$needle}%")));
            } else {
                $session_list = SessionManager::get_sessions_list(array('s.name' => array('operator' => 'LIKE', 'value' => "{$needle}%")));
            }
        }
        $i = 0;
        if ($type == 'single') {
        } else {
            $return .= '<select id="elements_not_in" name="elements_not_in_name[]" multiple="multiple" size="15" style="width:360px;">';
            foreach ($session_list as $row) {
                if (!in_array($row['id'], array_keys($elements_in))) {
                    $return .= '<option value="' . $row['id'] . '">' . $row['name'] . '</option>';
                }
            }
            $return .= '</select>';
            $xajax_response->addAssign('ajax_list_multiple', 'innerHTML', api_utf8_encode($return));
        }
    }
    return $xajax_response;
}
Example #29
0
 /**
  * @param $needle
  * @return xajaxResponse
  */
 public static function searchUserGroupAjax($needle)
 {
     $response = new xajaxResponse();
     $return = '';
     if (!empty($needle)) {
         // xajax send utf8 datas... datas in db can be non-utf8 datas
         $charset = api_get_system_encoding();
         $needle = api_convert_encoding($needle, $charset, 'utf-8');
         $needle = Database::escape_string($needle);
         // search courses where username or firstname or lastname begins likes $needle
         $sql = 'SELECT id, name FROM ' . Database::get_main_table(TABLE_USERGROUP) . ' u
                 WHERE name LIKE "' . $needle . '%"
                 ORDER BY name
                 LIMIT 11';
         $result = Database::query($sql);
         $i = 0;
         while ($data = Database::fetch_array($result)) {
             $i++;
             if ($i <= 10) {
                 $return .= '<a
                 href="javascript: void(0);"
                 onclick="javascript: add_user_to_url(\'' . addslashes($data['id']) . '\',\'' . addslashes($data['name']) . ' \')">' . $data['name'] . ' </a><br />';
             } else {
                 $return .= '...<br />';
             }
         }
     }
     $response->addAssign('ajax_list_courses', 'innerHTML', api_utf8_encode($return));
     return $response;
 }
function search_courses($id_session, $type)
{
    global $tbl_course, $tbl_session_rel_course, $course_list;
    $xajax_response = new xajaxResponse();
    $select_destination = '';
    $return = null;
    if (!empty($type)) {
        $id_session = intval($id_session);
        if ($type == 'origin') {
            $course_list = SessionManager::get_course_list_by_session_id($id_session);
            $temp_course_list = array();
            $return .= '<select id="origin" name="SessionCoursesListOrigin[]" class="form-control" onclick="javascript: checkSelected(this.id,\'copy_option_2\',\'title_option2\',\'destination\');">';
            foreach ($course_list as $course) {
                $temp_course_list[] = "'{$course['code']}'";
                $return .= '<option value="' . $course['code'] . '" title="' . @htmlspecialchars($course['title'] . ' (' . $course['visual_code'] . ')', ENT_QUOTES, api_get_system_encoding()) . '">' . $course['title'] . ' (' . $course['visual_code'] . ')</option>';
            }
            $return .= '</select>';
            $_SESSION['course_list'] = $temp_course_list;
            $_SESSION['session_origin'] = $id_session;
            // Build select for destination sessions where is not included current session from select origin
            if (!empty($id_session)) {
                $sessions = SessionManager::get_sessions_list(array(), array('name', 'ASC'));
                $select_destination .= '<select name="sessions_list_destination" class="form-control" onchange = "javascript: xajax_search_courses(this.value,\'destination\');">';
                $select_destination .= '<option value = "0">-- ' . get_lang('SelectASession') . ' --</option>';
                foreach ($sessions as $session) {
                    if ($id_session == $session['id']) {
                        continue;
                    }
                    if (!empty($session['category_name'])) {
                        $session['category_name'] = ' (' . $session['category_name'] . ') ';
                    }
                    $select_destination .= '<option value="' . $session['id'] . '">' . $session['name'] . ' ' . $session['category_name'] . '</option>';
                }
                $select_destination .= '</select>';
                $xajax_response->addAssign('ajax_sessions_list_destination', 'innerHTML', api_utf8_encode($select_destination));
            } else {
                $select_destination .= '<select name="sessions_list_destination" class="form-control" onchange = "javascript: xajax_search_courses(this.value,\'destination\');">';
                $select_destination .= '<option value = "0">' . get_lang('ThereIsNotStillASession') . '</option>';
                $select_destination .= '</select>';
                $xajax_response->addAssign('ajax_sessions_list_destination', 'innerHTML', api_utf8_encode($select_destination));
            }
            // Select multiple destination empty
            $select_multiple_empty = '<select id="destination" name="SessionCoursesListDestination[]" class="form-control"></select>';
            // Send response by ajax
            $xajax_response->addAssign('ajax_list_courses_origin', 'innerHTML', api_utf8_encode($return));
            $xajax_response->addAssign('ajax_list_courses_destination', 'innerHTML', api_utf8_encode($select_multiple_empty));
        } else {
            //Left Select - Destination
            $list_courses_origin = implode(',', $_SESSION['course_list']);
            $session_origin = $_SESSION['session_origin'];
            // Search courses by id_session where course codes is include en courses list destination
            $sql = "SELECT c.code, c.visual_code, c.title, src.session_id\n                    FROM {$tbl_course} c, {$tbl_session_rel_course} src\n                    WHERE src.c_id = c.id\n                    AND src.session_id = '" . intval($id_session) . "'";
            //AND c.code IN ($list_courses_origin)";
            $rs = Database::query($sql);
            $course_list_destination = array();
            $return .= '<select id="destination" name="SessionCoursesListDestination[]" class="form-control">';
            while ($course = Database::fetch_array($rs)) {
                $course_list_destination[] = $course['code'];
                $return .= '<option value="' . $course['code'] . '" title="' . @htmlspecialchars($course['title'] . ' (' . $course['visual_code'] . ')', ENT_QUOTES, api_get_system_encoding()) . '">' . $course['title'] . ' (' . $course['visual_code'] . ')</option>';
            }
            $return .= '</select>';
            $_SESSION['course_list_destination'] = $course_list_destination;
            // Send response by ajax
            $xajax_response->addAssign('ajax_list_courses_destination', 'innerHTML', api_utf8_encode($return));
        }
    }
    return $xajax_response;
}