courses.php 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * @package chamilo.auth
  5. * @todo check if unsubscribing from a course WITH group memberships works as it should
  6. * @todo constants are in uppercase, variables aren't
  7. */
  8. /*
  9. INIT SECTION
  10. */
  11. // Names of the language file that needs to be included.
  12. $language_file = array ('courses', 'registration');
  13. // Delete the globals['_cid'], we don't need it here.
  14. $cidReset = true; // Flag forcing the 'current course' reset
  15. // Including the global file.
  16. require_once '../inc/global.inc.php';
  17. if (api_get_setting('show_courses_descriptions_in_catalog') == 'true') {
  18. // additional html (javascript and style css)
  19. $htmlHeadXtra[] = '<script type="text/javascript">' .
  20. 'var GB_ROOT_DIR = "'.api_get_path(WEB_LIBRARY_PATH).'javascript/greybox/"' .
  21. '</script>';
  22. $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.js" type="text/javascript" language="javascript"></script>';
  23. $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/greybox/AJS.js" type="text/javascript" language="javascript"></script>';
  24. $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/greybox/AJS_fx.js" type="text/javascript" language="javascript"></script>';
  25. $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/greybox/gb_scripts.js" type="text/javascript" language="javascript"></script>';
  26. $htmlHeadXtra[] = '<link href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/greybox/gb_styles.css" rel="stylesheet" type="text/css" />';
  27. }
  28. // Section for the tabs.
  29. $this_section = SECTION_COURSES;
  30. // Acces rights: anonymous users can't do anything usefull here.
  31. api_block_anonymous_users();
  32. if (!(api_is_platform_admin() || api_is_course_admin() || api_is_allowed_to_create_course())) {
  33. if (api_get_setting('allow_students_to_browse_courses') == 'false') {
  34. api_not_allowed();
  35. }
  36. }
  37. // Include additional libraries.
  38. include_once api_get_path(LIBRARY_PATH).'debug.lib.inc.php';
  39. require_once api_get_path(LIBRARY_PATH).'course.lib.php';
  40. require_once api_get_path(LIBRARY_PATH).'mail.lib.inc.php';
  41. $ctok = $_SESSION['sec_token'];
  42. $stok = Security::get_token();
  43. // Database table definitions.
  44. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  45. $tbl_courses_nodes = Database::get_main_table(TABLE_MAIN_CATEGORY);
  46. $tbl_courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  47. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  48. // Filter.
  49. $safe = array();
  50. $safe['action'] = '';
  51. $actions = array('sortmycourses', 'createcoursecategory', 'subscribe', 'deletecoursecategory', 'unsubscribe');
  52. if (in_array(htmlentities($_GET['action']), $actions)) {
  53. $safe['action'] = htmlentities($_GET['action']);
  54. }
  55. // Title of the page.
  56. if ($safe['action'] == 'sortmycourses' || !isset($safe['action'])) {
  57. $nameTools = get_lang('SortMyCourses');
  58. }
  59. if ($safe['action'] == 'createcoursecategory') {
  60. $nameTools = get_lang('CreateCourseCategory');
  61. }
  62. if ($safe['action'] == 'subscribe') {
  63. $nameTools = get_lang('SubscribeToCourse');
  64. }
  65. // Breadcrumbs.
  66. $interbreadcrumb[] = array('url' => api_get_path(WEB_PATH).'user_portal.php', 'name' => get_lang('MyCourses'));
  67. if (empty($nameTools)) {
  68. $nameTools = get_lang('CourseManagement');
  69. } else {
  70. $interbreadcrumb[] = array('url' => api_get_path(WEB_CODE_PATH).'auth/courses.php', 'name' => get_lang('CourseManagement'));
  71. }
  72. // Displaying the header.
  73. Display::display_header($nameTools);
  74. /*
  75. ==============================================================================
  76. COMMANDS SECTION
  77. ==============================================================================
  78. */
  79. unset($message);
  80. // We are moving a course or category of the user up/down the list (=Sort My Courses).
  81. if (isset($_GET['move'])) {
  82. if (isset($_GET['course'])) {
  83. if ($ctok == $_GET['sec_token']) {
  84. $message = move_course($_GET['move'], $_GET['course'], $_GET['category']);
  85. }
  86. }
  87. if (isset($_GET['category']) and !$_GET['course']) {
  88. if ($ctok == $_GET['sec_token']) {
  89. $message = move_category($_GET['move'], $_GET['category']);
  90. }
  91. }
  92. }
  93. // We are moving the course of the user to a different user defined course category (=Sort My Courses).
  94. if (isset($_POST['submit_change_course_category'])) {
  95. if ($ctok == $_POST['sec_token']) {
  96. $message = store_changecoursecategory($_POST['course_2_edit_category'], $_POST['course_categories']);
  97. }
  98. }
  99. // We are creating a new user defined course category (= Create Course Category).
  100. if (isset($_POST['create_course_category']) && isset($_POST['title_course_category']) && strlen(trim($_POST['title_course_category'])) > 0) {
  101. if ($ctok == $_POST['sec_token']) {
  102. $message = store_course_category();
  103. }
  104. }
  105. if (isset($_POST['submit_edit_course_category']) && isset($_POST['title_course_category']) && strlen(trim($_POST['title_course_category'])) > 0) {
  106. if ($ctok == $_POST['sec_token']) {
  107. $message = store_edit_course_category();
  108. }
  109. }
  110. // We are subcribing to a course (=Subscribe to course).
  111. if (isset($_POST['subscribe'])) {
  112. if ($ctok == $_POST['sec_token']) {
  113. $message = subscribe_user($_POST['subscribe']);
  114. }
  115. }
  116. // We are unsubscribing from a course (=Unsubscribe from course).
  117. if (isset($_POST['unsubscribe'])) {
  118. if ($ctok == $_POST['sec_token']) {
  119. $message = remove_user_from_course($_user['user_id'], $_POST['unsubscribe']);
  120. }
  121. }
  122. // we are deleting a course category
  123. if ($safe['action'] == 'deletecoursecategory' && isset($_GET['id'])) {
  124. if ($ctok == $_GET['sec_token']) {
  125. $get_id_cat = Security::remove_XSS($_GET['id']);
  126. $message = delete_course_category($get_id_cat);
  127. }
  128. }
  129. /*
  130. ==============================================================================
  131. DISPLAY SECTION
  132. ==============================================================================
  133. */
  134. // Diplaying the tool title
  135. // api_display_tool_title($nameTools);
  136. // we are displaying any result messages;
  137. if (isset($message)) {
  138. Display::display_confirmation_message($message, false);
  139. }
  140. // The menu with the different options in the course management
  141. echo "<div id=\"actions\" class='actions'>";
  142. if ($safe['action'] != 'sortmycourses' && isset($safe['action'])) {
  143. echo "&nbsp;&nbsp;<a href=\"".api_get_self()."?action=sortmycourses\">".Display::return_icon('deplacer_fichier.gif', get_lang('SortMyCourses')).' '.get_lang('SortMyCourses')."</a>&nbsp;";
  144. } else {
  145. echo '&nbsp;&nbsp;<strong>'.Display::return_icon('deplacer_fichier.gif', get_lang('SortMyCourses')).' '.get_lang('SortMyCourses').'</strong>&nbsp;';
  146. }
  147. echo '&nbsp;';
  148. if ($safe['action'] != 'createcoursecategory') {
  149. echo "&nbsp;&nbsp;<a href=\"".api_get_self()."?action=createcoursecategory\">".Display::return_icon('folder_new.gif', get_lang('CreateCourseCategory')).' '.get_lang('CreateCourseCategory')."</a>&nbsp;";
  150. } else {
  151. echo '&nbsp;&nbsp;<strong>'.Display::return_icon('folder_new.gif', get_lang('CreateCourseCategory')).' '.get_lang('CreateCourseCategory').'</strong>&nbsp;';
  152. }
  153. echo '&nbsp;';
  154. if ($safe['action'] != 'subscribe') {
  155. echo "&nbsp;&nbsp;<a href=\"".api_get_self()."?action=subscribe\">".Display::return_icon('view_more_stats.gif', get_lang('SubscribeToCourse')).' '.get_lang('SubscribeToCourse')."</a>&nbsp;";
  156. } else {
  157. echo '&nbsp;&nbsp;<strong>'.Display::return_icon('view_more_stats.gif', get_lang('SubscribeToCourse')).' '.get_lang('SubscribeToCourse').'</strong>&nbsp;';
  158. }
  159. echo "</div>";
  160. echo "<div>";
  161. switch ($safe['action']) {
  162. case 'subscribe':
  163. //api_display_tool_title(get_lang('SubscribeToCourse'));
  164. courses_subscribing();
  165. break;
  166. case 'unsubscribe':
  167. //api_display_tool_title(get_lang('UnsubscribeFromCourse'));
  168. $user_courses = get_courses_of_user($_user['user_id']);
  169. display_courses($_user['user_id'], true, $user_courses);
  170. break;
  171. case 'createcoursecategory':
  172. //api_display_tool_title(get_lang('CreateCourseCategory'));
  173. display_create_course_category_form();
  174. break;
  175. case 'deletecoursecategory':
  176. case 'sortmycourses':
  177. default:
  178. //api_display_tool_title(get_lang('SortMyCourses'));
  179. display_search_courses();
  180. $user_courses = get_courses_of_user($_user['user_id']);
  181. display_courses($_user['user_id'], true, $user_courses);
  182. break;
  183. }
  184. echo '</div>';
  185. Display :: display_footer();
  186. /*
  187. ==============================================================================
  188. FUNCTIONS
  189. ==============================================================================
  190. */
  191. /**
  192. * Subscribe the user to a given course
  193. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  194. * @param string $course_code the code of the course the user wants to subscribe to
  195. * @return string we return the message that is displayed when the action is succesfull
  196. */
  197. function subscribe_user($course_code) {
  198. global $_user, $stok;
  199. $all_course_information = CourseManager::get_course_information($course_code);
  200. if ($all_course_information['registration_code'] == '' || $_POST['course_registration_code'] == $all_course_information['registration_code']) {
  201. if (api_is_platform_admin()) {
  202. $status_user_in_new_course = COURSEMANAGER;
  203. } else {
  204. $status_user_in_new_course=null;
  205. }
  206. if (CourseManager::add_user_to_course($_user['user_id'], $course_code, $status_user_in_new_course)) {
  207. $send = api_get_course_setting('email_alert_to_teacher_on_new_user_in_course', $course_code);
  208. if ($send == 1) {
  209. CourseManager::email_to_tutor($_user['user_id'], $course_code, $send_to_tutor_also = false);
  210. } else if ($send == 2){
  211. CourseManager::email_to_tutor($_user['user_id'], $course_code, $send_to_tutor_also = true);
  212. }
  213. return get_lang('EnrollToCourseSuccessful');
  214. } else {
  215. return get_lang('ErrorContactPlatformAdmin');
  216. }
  217. } else {
  218. $return = '';
  219. if (isset($_POST['course_registration_code']) && $_POST['course_registration_code'] != $all_course_information['registration_code']) {
  220. Display::display_error_message(get_lang('CourseRegistrationCodeIncorrect'));
  221. }
  222. $return .= get_lang('CourseRequiresPassword').'<br />';
  223. $return .= $all_course_information['visual_code'].' - '.$all_course_information['title'];
  224. $return .= "<form action=\"".$_SERVER["REQUEST_URI"]."\" method=\"post\">";
  225. $return .= '<input type="hidden" name="sec_token" value="'.$stok.'" />';
  226. $return .= "<input type=\"hidden\" name=\"subscribe\" value=\"".$all_course_information['code']."\" />";
  227. $return .= "<input type=\"text\" name=\"course_registration_code\" value=\"".$_POST['course_registration_code']."\" />";
  228. $return .= "<input type=\"submit\" name=\"submit_course_registration_code\" value=\"OK\" alt=\"".get_lang('SubmitRegistrationCode')."\" /></form>";
  229. return $return;
  230. }
  231. }
  232. /**
  233. * unsubscribe the user from a given course
  234. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  235. * @param int $user_id The user id of the user that is performing the unsubscribe action
  236. * @param string $course_code the course code of the course the user wants to unsubscribe from
  237. * @return string we return the message that is displayed when the action is succesfull
  238. */
  239. function remove_user_from_course($user_id, $course_code) {
  240. $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  241. // we check (once again) if the user is not course administrator
  242. // because the course administrator cannot unsubscribe himself
  243. // (s)he can only delete the course
  244. $sql_check = "SELECT * FROM $tbl_course_user WHERE user_id='".$user_id."' AND course_code='".$course_code."' AND status='1' ";
  245. $result_check = Database::query($sql_check);
  246. $number_of_rows = Database::num_rows($result_check);
  247. if ($number_of_rows > 0) {
  248. return false;
  249. }
  250. CourseManager::unsubscribe_user($user_id, $course_code);
  251. return get_lang('YouAreNowUnsubscribed');
  252. }
  253. /**
  254. * handles the display of the courses to which the user can subscribe
  255. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  256. */
  257. function courses_subscribing() {
  258. browse_courses();
  259. display_search_courses();
  260. }
  261. /**
  262. * Allows you to browse through the course categories (faculties) and subscribe to the courses of
  263. * this category (faculty)
  264. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  265. */
  266. function browse_courses() {
  267. browse_course_categories();
  268. if (!isset($_POST['search_course'])) {
  269. browse_courses_in_category();
  270. }
  271. }
  272. /**
  273. * Counts the number of courses in a given course category
  274. */
  275. function count_courses_in_category($category) {
  276. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  277. $TABLE_COURSE_FIELD = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD);
  278. $TABLE_COURSE_FIELD_VALUE = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
  279. // get course list auto-register
  280. $sql = "SELECT course_code FROM $TABLE_COURSE_FIELD_VALUE tcfv INNER JOIN $TABLE_COURSE_FIELD tcf ON " .
  281. " tcfv.field_id = tcf.id WHERE tcf.field_variable = 'special_course' AND tcfv.field_value = 1 ";
  282. $special_course_result = Database::query($sql);
  283. if(Database::num_rows($special_course_result)>0) {
  284. $special_course_list = array();
  285. while ($result_row = Database::fetch_array($special_course_result)) {
  286. $special_course_list[] = '"'.$result_row['course_code'].'"';
  287. }
  288. }
  289. $without_special_courses = '';
  290. if (!empty($special_course_list)) {
  291. $without_special_courses = ' AND course.code NOT IN ('.implode(',',$special_course_list).')';
  292. }
  293. $sql = "SELECT * FROM $tbl_course WHERE category_code".(empty($category) ? " IS NULL" : "='".$category."'").$without_special_courses;
  294. // Showing only the courses of the current Dokeos access_url_id.
  295. global $_configuration;
  296. if ($_configuration['multiple_access_urls']) {
  297. $url_access_id = api_get_current_access_url_id();
  298. if ($url_access_id != -1) {
  299. $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  300. $sql = "SELECT * FROM $tbl_course as course INNER JOIN $tbl_url_rel_course as url_rel_course
  301. ON (url_rel_course.course_code=course.code)
  302. WHERE access_url_id = $url_access_id AND category_code".(empty($category) ? " IS NULL" : "='".$category."'").$without_special_courses;
  303. }
  304. }
  305. return Database::num_rows(Database::query($sql));
  306. }
  307. /**
  308. * displays the browsing of the course categories (faculties)
  309. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  310. * @return HTML code containing a list with all the categories and subcategories and the navigation to go one category up(if needed)
  311. */
  312. function browse_course_categories() {
  313. global $stok;
  314. $tbl_courses_nodes = Database::get_main_table(TABLE_MAIN_CATEGORY);
  315. $category = Database::escape_string($_GET['category']);
  316. $safe_url_categ = Security::remove_XSS($_GET['category']);
  317. echo "<p><strong>".get_lang('CourseCategories')."</strong>";
  318. $sql = "SELECT * FROM $tbl_courses_nodes WHERE parent_id ".(empty($category) ? "IS NULL" : "='".$category."'")." GROUP BY code, parent_id ORDER BY tree_pos ASC";
  319. $result = Database::query($sql);
  320. echo "<ul>";
  321. while ($row = Database::fetch_array($result)) {
  322. $count_courses_in_categ = count_courses_in_category($row['code']);
  323. if ($row['children_count'] > 0 || $count_courses_in_categ > 0) {
  324. echo "<li><a href=\"".api_get_self()."?action=subscribe&amp;category=".$row['code']."&amp;up=".$safe_url_categ."&amp;sec_token=".$stok."\">".$row['name']."</a>".
  325. " (".$count_courses_in_categ.")</li>";
  326. } elseif ($row['nbChilds'] > 0) {
  327. echo "<li><a href=\"".api_get_self()."?action=subscribe&amp;category=".$row['code']."&amp;up=".$safe_url_categ."&amp;sec_token=".$stok."\">".$row['name']."</a></li>";
  328. } else {
  329. echo "<li>".$row['name']."</li>";
  330. }
  331. }
  332. echo "</ul>";
  333. if ($_GET['category']) {
  334. echo "<a href=\"".api_get_self()."?action=subscribe&amp;category=".Security::remove_XSS($_GET['up'])."&amp;sec_token=".$stok."\">".Display::return_icon('back.png',get_lang('UpOneCategory'),array('align'=>'absmiddle')).get_lang('UpOneCategory')."</a>";
  335. }
  336. }
  337. /**
  338. * Display all the courses in the given course category. I could have used a parameter here
  339. * but instead I use the already available $_GET['category']
  340. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  341. * @return HTML code: a table with all the courses in a given category (title, code, tutor) and a subscription icon if applicable)
  342. */
  343. function browse_courses_in_category() {
  344. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  345. $TABLE_COURSE_FIELD = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD);
  346. $TABLE_COURSE_FIELD_VALUE = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
  347. // get course list auto-register
  348. $sql = "SELECT course_code FROM $TABLE_COURSE_FIELD_VALUE tcfv INNER JOIN $TABLE_COURSE_FIELD tcf ON " .
  349. " tcfv.field_id = tcf.id WHERE tcf.field_variable = 'special_course' AND tcfv.field_value = 1 ";
  350. $special_course_result = Database::query($sql);
  351. if(Database::num_rows($special_course_result)>0) {
  352. $special_course_list = array();
  353. while ($result_row = Database::fetch_array($special_course_result)) {
  354. $special_course_list[] = '"'.$result_row['course_code'].'"';
  355. }
  356. }
  357. $without_special_courses = '';
  358. if (!empty($special_course_list)) {
  359. $without_special_courses = ' AND course.code NOT IN ('.implode(',',$special_course_list).')';
  360. }
  361. $category = Database::escape_string($_GET['category']);
  362. echo "<p><strong>".get_lang('CoursesInCategory')."</strong>";
  363. $my_category = (empty($category) ? " IS NULL" : "='".$category."'");
  364. $sql = "SELECT * FROM $tbl_course WHERE category_code".$my_category.$without_special_courses.' ORDER BY title, visual_code';
  365. //showing only the courses of the current Dokeos access_url_id
  366. global $_configuration;
  367. if ($_configuration['multiple_access_urls']) {
  368. $url_access_id = api_get_current_access_url_id();
  369. if ($url_access_id != -1) {
  370. $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  371. $sql = "SELECT * FROM $tbl_course as course INNER JOIN $tbl_url_rel_course as url_rel_course
  372. ON (url_rel_course.course_code=course.code)
  373. WHERE access_url_id = $url_access_id AND category_code".$my_category.$without_special_courses.' ORDER BY title, visual_code';
  374. }
  375. }
  376. $result = Database::query($sql);
  377. while ($row = Database::fetch_array($result)) {
  378. $row['registration_code'] = !empty($row['registration_code']);
  379. $courses[] = array('code' => $row['code'], 'directory' => $row['directory'], 'db' => $row['db_name'], 'visual_code' => $row['visual_code'], 'title' => $row['title'], 'tutor' => $row['tutor_name'], 'subscribe' => $row['subscribe'], 'unsubscribe' => $row['unsubscribe'], 'registration_code' => $registration_code);
  380. }
  381. display_subscribe_to_courses($courses);
  382. }
  383. /**
  384. * displays the form for searching for a course and the results if a query has been submitted.
  385. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  386. * @return HTML code: the form for searching for a course
  387. */
  388. function display_search_courses() {
  389. global $_user, $stok;
  390. echo "<p><strong>".get_lang('SearchCourse')."</strong><br />";
  391. echo "<form class=\"course_list\" method=\"post\" action=\"".api_get_self()."?action=subscribe\">",
  392. '<input type="hidden" name="sec_token" value="'.$stok.'">',
  393. "<input type=\"hidden\" name=\"search_course\" value=\"1\" />",
  394. "<input type=\"text\" name=\"search_term\" value=\"".(empty($_POST['search_term']) ? '' : Security::remove_XSS($_POST['search_term']))."\" />",
  395. "&nbsp;<button class=\"search\" type=\"submit\">",get_lang('_search'),"</button>",
  396. "</form>";
  397. if (isset($_POST['search_course'])) {
  398. echo "<p><strong>".get_lang('SearchResultsFor')." ".api_htmlentities($_POST['search_term'], ENT_QUOTES, api_get_system_encoding())."</strong><br />";
  399. $result_search_courses_array = search_courses($_POST['search_term']);
  400. display_subscribe_to_courses($result_search_courses_array);
  401. }
  402. }
  403. /**
  404. * This function displays the list of course that can be subscribed to.
  405. * This list can come from the search results or from the browsing of the platform course categories
  406. */
  407. function display_subscribe_to_courses($courses) {
  408. global $_user;
  409. // getting all the courses to which the user is subscribed to
  410. $user_courses = get_courses_of_user($_user['user_id']);
  411. $user_coursecodes = array();
  412. // we need only the course codes as these will be used to match against the courses of the category
  413. if ($user_courses != '') {
  414. foreach ($user_courses as $key => $value) {
  415. $user_coursecodes[] = $value['code'];
  416. }
  417. }
  418. if ($courses == 0) {
  419. return false;
  420. }
  421. echo "<table cellpadding=\"4\">\n";
  422. foreach ($courses as $key=>$course) {
  423. // displaying the course title, visual code and teacher/teaching staff
  424. echo "\t<tr>\n";
  425. if (api_get_setting('show_courses_descriptions_in_catalog') == 'true') {
  426. // block course description
  427. echo "\t\t<td>";
  428. $icon_title = get_lang('CourseDetails') . ' - ' . $course['title'];
  429. echo "<a href='".api_get_path(WEB_CODE_PATH)."inc/ajax/course_home.ajax.php?a=show_course_information&code=".$course['code']."' title='$icon_title' rel='gb_page_center[778]'>".Display::return_icon('synthese_view.gif', $icon_title)."</a>"; echo "\t\t</td>";
  430. }
  431. echo "\t\t<td>\n";
  432. echo "<strong>".$course['title']."</strong><br />";
  433. if (api_get_setting('display_coursecode_in_courselist') == 'true') {
  434. echo $course['visual_code'];
  435. }
  436. if (api_get_setting('display_coursecode_in_courselist') == 'true' && api_get_setting('display_teacher_in_courselist') == 'true') {
  437. echo " - ";
  438. }
  439. if (api_get_setting('display_teacher_in_courselist') == 'true') {
  440. echo $course['tutor'];
  441. }
  442. echo "\t\t</td>\n";
  443. echo "\t\t<td>\n";
  444. if ($course['registration_code']) {
  445. Display::display_icon('passwordprotected.png', '', array('style' => 'float:left;'));
  446. }
  447. display_subscribe_icon($course, $user_coursecodes);
  448. echo "\t\t</td>\n";
  449. echo "</tr>";
  450. }
  451. echo "</table>";
  452. }
  453. /**
  454. * Search the courses database for a course that matches the search term.
  455. * The search is done on the code, title and tutor field of the course table.
  456. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  457. * @param string $search_term: the string that the user submitted, what we are looking for
  458. * @return array an array containing a list of all the courses (the code, directory, dabase, visual_code, title, ... )
  459. * matching the the search term.
  460. */
  461. function search_courses($search_term) {
  462. $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE);
  463. $TABLE_COURSE_FIELD = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD);
  464. $TABLE_COURSE_FIELD_VALUE = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
  465. // get course list auto-register
  466. $sql = "SELECT course_code FROM $TABLE_COURSE_FIELD_VALUE tcfv INNER JOIN $TABLE_COURSE_FIELD tcf ON " .
  467. " tcfv.field_id = tcf.id WHERE tcf.field_variable = 'special_course' AND tcfv.field_value = 1 ";
  468. $special_course_result = Database::query($sql);
  469. if(Database::num_rows($special_course_result)>0) {
  470. $special_course_list = array();
  471. while ($result_row = Database::fetch_array($special_course_result)) {
  472. $special_course_list[] = '"'.$result_row['course_code'].'"';
  473. }
  474. }
  475. $without_special_courses = '';
  476. if (!empty($special_course_list)) {
  477. $without_special_courses = ' AND course.code NOT IN ('.implode(',',$special_course_list).')';
  478. }
  479. $search_term_safe = Database::escape_string($search_term);
  480. $sql_find = "SELECT * FROM $TABLECOURS WHERE (code LIKE '%".$search_term_safe."%' OR title LIKE '%".$search_term_safe."%' OR tutor_name LIKE '%".$search_term_safe."%') $without_special_courses ORDER BY title, visual_code ASC";
  481. global $_configuration;
  482. if ($_configuration['multiple_access_urls']) {
  483. $url_access_id = api_get_current_access_url_id();
  484. if ($url_access_id != -1) {
  485. $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  486. $sql_find = "SELECT * FROM $TABLECOURS as course INNER JOIN $tbl_url_rel_course as url_rel_course
  487. ON (url_rel_course.course_code=course.code)
  488. WHERE access_url_id = $url_access_id AND (code LIKE '%".$search_term_safe."%' OR title LIKE '%".$search_term_safe."%' OR tutor_name LIKE '%".$search_term_safe."%' ) $without_special_courses ORDER BY title, visual_code ASC ";
  489. }
  490. }
  491. $result_find = Database::query($sql_find);
  492. while ($row = Database::fetch_array($result_find)) {
  493. $courses[] = array('code' => $row['code'], 'directory' => $row['directory'], 'db' => $row['db_name'], 'visual_code' => $row['visual_code'], 'title' => $row['title'], 'tutor' => $row['tutor_name'], 'subscribe' => $row['subscribe'], 'unsubscribe' => $row['unsubscribe']);
  494. }
  495. return $courses;
  496. }
  497. /**
  498. * deletes a course category and moves all the courses that were in this category to main category
  499. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  500. * @param int $id: the id of the user_course_category
  501. * @return string a language variable saying that the deletion went OK.
  502. */
  503. function delete_course_category($id) {
  504. global $_user, $_configuration;
  505. $tucc = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  506. $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  507. $id = intval($id);
  508. $sql_delete = "DELETE FROM $tucc WHERE id='".$id."' and user_id='".$_user['user_id']."'";
  509. $sql_update = "UPDATE $TABLECOURSUSER SET user_course_cat='0' WHERE user_course_cat='".$id."' AND user_id='".$_user['user_id']."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
  510. Database::query($sql_delete);
  511. Database::query($sql_update);
  512. return get_lang('CourseCategoryDeleted');
  513. }
  514. /**
  515. * stores the user course category in the chamilo_user database
  516. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  517. * @return string a language variable saying that the user course category was stored
  518. */
  519. function store_course_category() {
  520. global $_user, $_configuration;
  521. $tucc = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  522. // step 1: we determine the max value of the user defined course categories
  523. $sql = "SELECT sort FROM $tucc WHERE user_id='".$_user['user_id']."' ORDER BY sort DESC";
  524. $result = Database::query($sql);
  525. $maxsort = Database::fetch_array($result);
  526. $nextsort = $maxsort['sort'] + 1;
  527. // step 2: we check if there is already a category with this name, if not we store it, else we give an error.
  528. $sql = "SELECT * FROM $tucc WHERE user_id='".$_user['user_id']."' AND title='".Database::escape_string($_POST['title_course_category'])."'ORDER BY sort DESC";
  529. $result = Database::query($sql);
  530. if (Database::num_rows($result) == 0) {
  531. $sql_insert = "INSERT INTO $tucc (user_id, title,sort) VALUES ('".$_user['user_id']."', '".api_htmlentities($_POST['title_course_category'], ENT_QUOTES, api_get_system_encoding())."', '".$nextsort."')";
  532. Database::query($sql_insert);
  533. Display::display_confirmation_message(get_lang("CourseCategoryStored"));
  534. } else {
  535. Display::display_error_message(get_lang('ACourseCategoryWithThisNameAlreadyExists'));
  536. }
  537. }
  538. /**
  539. * displays the form that is needed to create a course category.
  540. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  541. * @return HTML the form (input field + submit button) to create a user course category
  542. */
  543. function display_create_course_category_form()
  544. {
  545. global $_user, $_configuration, $stok;
  546. echo "<form name=\"create_course_category\" method=\"post\" action=\"".api_get_self()."?action=sortmycourses\">\n";
  547. echo '<input type="hidden" name="sec_token" value="'.$stok.'">';
  548. echo "<input type=\"text\" name=\"title_course_category\" />\n";
  549. echo "<button type=\"submit\" class=\"save\" name=\"create_course_category\">".get_lang('Ok')."</button>\n";
  550. echo "</form>\n";
  551. echo get_lang('ExistingCourseCategories');
  552. $tucc = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  553. $sql = "SELECT * FROM $tucc WHERE user_id='".$_user['user_id']."'";
  554. $result = Database::query($sql);
  555. if (Database::num_rows($result) > 0) {
  556. echo "<ul>\n";
  557. while ($row = Database::fetch_array($result)) {
  558. echo "\t<li>".$row['title']."</li>\n";
  559. }
  560. echo "</ul>\n";
  561. }
  562. }
  563. // ***************************************************************************
  564. // this function stores the changes in a course category
  565. //
  566. // ***************************************************************************
  567. /**
  568. * stores the changes in a course category (moving a course to a different course category)
  569. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  570. * @param string $course_code : the course_code of the course we are moving
  571. * int $newcategory : the id of the user course category we are moving the course to.
  572. * @return string a language variable saying that the course was moved.
  573. */
  574. function store_changecoursecategory($course_code, $newcategory) {
  575. global $_user;
  576. $course_code = Database::escape_string($course_code);
  577. $newcategory = Database::escape_string($newcategory);
  578. $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  579. $max_sort_value = api_max_sort_value($newcategory, $_user['user_id']); // max_sort_value($newcategory);
  580. $sql = "UPDATE $TABLECOURSUSER SET user_course_cat='".$newcategory."', sort='".($max_sort_value + 1)."' WHERE course_code='".$course_code."' AND user_id='".$_user['user_id']."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
  581. $result = Database::query($sql);
  582. return get_lang('EditCourseCategorySucces');
  583. }
  584. /**
  585. * moves the course one place up or down
  586. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  587. * @param string $direction : the direction we are moving the course to (up or down)
  588. * string $course2move : the course we are moving
  589. * @return string a language variable saying that the course was moved.
  590. */
  591. function move_course($direction, $course2move, $category) {
  592. global $_user;
  593. $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  594. $all_user_courses = get_courses_of_user($_user['user_id']);
  595. // we need only the courses of the category we are moving in
  596. $user_courses = array();
  597. foreach ($all_user_courses as $key => $course) {
  598. if ($course['user_course_category'] == $category) {
  599. $user_courses[] = $course;
  600. }
  601. }
  602. foreach ($user_courses as $key => $course) {
  603. if ($course2move == $course['code']) {
  604. // source_course is the course where we clicked the up or down icon
  605. $source_course = $course;
  606. // target_course is the course before/after the source_course (depending on the up/down icon)
  607. if ($direction == 'up') {
  608. $target_course = $user_courses[$key - 1];
  609. } else {
  610. $target_course = $user_courses[$key + 1];
  611. }
  612. } // if ($course2move == $course['code'])
  613. }
  614. if (count($target_course) > 0 && count($source_course) > 0) {
  615. $sql_update1 = "UPDATE $TABLECOURSUSER SET sort='".$target_course['sort']."' WHERE course_code='".$source_course['code']."' AND user_id='".$_user['user_id']."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
  616. $sql_update2 = "UPDATE $TABLECOURSUSER SET sort='".$source_course['sort']."' WHERE course_code='".$target_course['code']."' AND user_id='".$_user['user_id']."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
  617. Database::query($sql_update2);
  618. Database::query($sql_update1);
  619. return get_lang('CourseSortingDone');
  620. }
  621. return '';
  622. }
  623. /**
  624. * Moves the course one place up or down
  625. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  626. * @param string $direction : the direction we are moving the course to (up or down)
  627. * string $course2move : the course we are moving
  628. * @return string a language variable saying that the course was moved.
  629. */
  630. function move_category($direction, $category2move) {
  631. global $_user;
  632. // the database definition of the table that stores the user defined course categories
  633. $table_user_defined_category = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  634. $user_coursecategories = get_user_course_categories();
  635. $user_course_categories_info = get_user_course_categories_info();
  636. foreach ($user_coursecategories as $key => $category_id) {
  637. if ($category2move == $category_id) {
  638. // source_course is the course where we clicked the up or down icon
  639. //$source_category=get_user_course_category($category2move);
  640. $source_category = $user_course_categories_info[$category2move];
  641. // target_course is the course before/after the source_course (depending on the up/down icon)
  642. if ($direction == 'up') {
  643. $target_category = $user_course_categories_info[$user_coursecategories[$key - 1]];
  644. } else {
  645. $target_category = $user_course_categories_info[$user_coursecategories[$key + 1]];
  646. }
  647. } // if ($course2move == $course['code'])
  648. } // foreach ($user_courses as $key => $course)
  649. if (count($target_category) > 0 && count($source_category) > 0) {
  650. $sql_update1="UPDATE $table_user_defined_category SET sort='".$target_category['sort']."' WHERE id='".$source_category['id']."' AND user_id='".$_user['user_id']."'";
  651. $sql_update2="UPDATE $table_user_defined_category SET sort='".$source_category['sort']."' WHERE id='".$target_category['id']."' AND user_id='".$_user['user_id']."'";
  652. Database::query($sql_update2);
  653. Database::query($sql_update1);
  654. return get_lang('CategorySortingDone');
  655. }
  656. return '';
  657. }
  658. /**
  659. * displays everything that is needed when the user wants to manage his current courses (sorting, subscribing, unsubscribing, ...)
  660. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  661. * @param int $user_id: the user_id of the current user
  662. * string $parameter: determines weither we are displaying for the sorting, subscribing or unsubscribin
  663. array $user_courses: the courses to which the user is subscribed
  664. * @return html a table containing courses and the appropriate icons (sub/unsub/move)
  665. */
  666. function display_courses($user_id, $show_course_icons, $user_courses) {
  667. global $_user, $_configuration;
  668. echo "<table cellpadding=\"4\">\n";
  669. // building an array that contains all the id's of the user defined course categories
  670. // initially this was inside the display_courses_in_category function but when we do it here we have fewer
  671. // sql executions = performance increase.
  672. $all_user_categories = get_user_course_categories();
  673. // step 0: we display the course without a user category
  674. display_courses_in_category(0, 'true');
  675. // Step 1: We get all the categories of the user.
  676. $tucc = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  677. $sql = "SELECT * FROM $tucc WHERE user_id='".$_user['user_id']."' ORDER BY sort ASC";
  678. $result = Database::query($sql);
  679. while ($row = Database::fetch_array($result)) {
  680. if ($show_course_icons) {
  681. // The edit link is clicked.
  682. if (isset($_GET['categoryid']) && $_GET['categoryid'] == $row['id']) {
  683. // We display the edit form for the category.
  684. echo "<tr><td colspan=\"2\" class=\"user_course_category\">";
  685. echo '<a name="category'.$row['id'].'"></a>'; // display an internal anchor.
  686. display_edit_course_category_form($row['id']);
  687. } else {
  688. // We simply display the title of the category.
  689. echo "<tr><td colspan=\"2\" class=\"user_course_category\">";
  690. echo '<a name="category'.$row['id'].'"></a>'; // display an internal anchor.
  691. echo $row['title'];
  692. }
  693. echo "</td><td class=\"user_course_category\">";
  694. display_category_icons($row['id'], $all_user_categories);
  695. echo "</td></tr>";
  696. }
  697. // Step 2: Show the courses inside this category.
  698. display_courses_in_category($row['id'], $show_course_icons);
  699. }
  700. echo "</table>\n";
  701. }
  702. /**
  703. * This function displays all the courses in the particular user category;
  704. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  705. * @param int id: the id of the user defined course category
  706. * @return string: the name of the user defined course category
  707. */
  708. function display_courses_in_category($user_category_id, $showicons) {
  709. global $_user;
  710. // table definitions
  711. $TABLECOURS=Database::get_main_table(TABLE_MAIN_COURSE);
  712. $TABLECOURSUSER=Database::get_main_table(TABLE_MAIN_COURSE_USER);
  713. $TABLE_USER_COURSE_CATEGORY = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  714. $TABLE_COURSE_FIELD = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD);
  715. $TABLE_COURSE_FIELD_VALUE = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
  716. // get course list auto-register
  717. $sql = "SELECT course_code FROM $TABLE_COURSE_FIELD_VALUE tcfv INNER JOIN $TABLE_COURSE_FIELD tcf ON " .
  718. " tcfv.field_id = tcf.id WHERE tcf.field_variable = 'special_course' AND tcfv.field_value = 1 ";
  719. $special_course_result = Database::query($sql);
  720. if(Database::num_rows($special_course_result)>0) {
  721. $special_course_list = array();
  722. while ($result_row = Database::fetch_array($special_course_result)) {
  723. $special_course_list[] = '"'.$result_row['course_code'].'"';
  724. }
  725. }
  726. $without_special_courses = '';
  727. if (!empty($special_course_list)) {
  728. $without_special_courses = ' AND course.code NOT IN ('.implode(',',$special_course_list).')';
  729. }
  730. $sql_select_courses = "SELECT course.code, course.visual_code, course.subscribe subscr, course.unsubscribe unsubscr,
  731. course.title title, course.tutor_name tutor, course.db_name, course.directory, course_rel_user.status status,
  732. course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat
  733. FROM $TABLECOURS course,
  734. $TABLECOURSUSER course_rel_user
  735. WHERE course.code = course_rel_user.course_code
  736. AND course_rel_user.user_id = '".$_user['user_id']."'
  737. AND course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH."
  738. AND course_rel_user.user_course_cat='".$user_category_id."' $without_special_courses
  739. ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC";
  740. $result = Database::query($sql_select_courses);
  741. $number_of_courses = Database::num_rows($result);
  742. $key = 0;
  743. while ($course = Database::fetch_array($result)) {
  744. echo "\t<tr>\n";
  745. if (api_get_setting('show_courses_descriptions_in_catalog') == 'true') {
  746. // block course description
  747. echo "\t\t<td>";
  748. $icon_title = get_lang('CourseDetails') . ' - ' . $course['title'];
  749. echo "<a href='".api_get_path(WEB_CODE_PATH)."inc/ajax/course_home.ajax.php?a=show_course_information&code=".$course['code']."' title='$icon_title' rel='gb_page_center[778]'>".Display::return_icon('synthese_view.gif', $icon_title)."</a>";
  750. echo "\t\t</td>";
  751. }
  752. echo "\t\t<td>\n";
  753. echo '<a name="course'.$course['code'].'"></a>'; // display an internal anchor.
  754. echo "<strong>".$course['title']."</strong><br />";
  755. if (api_get_setting('display_coursecode_in_courselist') == 'true') {
  756. echo $course['visual_code'];
  757. }
  758. if (api_get_setting('display_coursecode_in_courselist') == 'true' && api_get_setting('display_teacher_in_courselist') == 'true') {
  759. echo " - ";
  760. }
  761. if (api_get_setting('display_teacher_in_courselist') == 'true') {
  762. echo $course['tutor'];
  763. }
  764. echo "\t\t</td>\n";
  765. // displaying the up/down/edit icons when we are sorting courses
  766. echo "\t\t<td valign=\"top\">\n";
  767. //if ($parameter == 'sorting')
  768. //{
  769. display_course_icons($key, $number_of_courses, $course);
  770. //}
  771. // displaying the delete icon when we are unsubscribing from courses
  772. //if($parameter == 'deleting')
  773. //{
  774. // display_unsubscribe_icons($course);
  775. //}
  776. // display the subscribing icon when we are to courses.
  777. //if ($parameter == 'subscribing')
  778. //{
  779. // display_subscribe_icon($course);
  780. //}
  781. echo "\t\t</td>\n";
  782. echo "\t</tr>\n";
  783. $key++;
  784. }
  785. }
  786. /**
  787. * gets the title of the user course category
  788. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  789. * @param int id: the id of the user defined course category
  790. * @return string: the name of the user defined course category
  791. */
  792. function get_user_course_category($id) {
  793. global $_user, $_configuration;
  794. $tucc = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  795. $id = intval($id);
  796. return Database::fetch_array(Database::query("SELECT * FROM $tucc WHERE user_id='".$_user['user_id']."' AND id='$id'"));
  797. }
  798. /**
  799. * displays the subscribe icon if the subscribing is allowed and if the user is not yet
  800. * subscribe to this course
  801. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  802. * @param string $current_course: the course code of the course we need to display the subscribe icon for
  803. * @return string a subscribe icon or the text that subscribing is not allowed or the user is already subscribed
  804. */
  805. function display_subscribe_icon($current_course, $user_coursecodes) {
  806. global $stok;
  807. // we display the icon to subscribe or the text already subscribed
  808. if (in_array($current_course['code'], $user_coursecodes)) {
  809. Display::display_icon('enroll_na.gif', get_lang('AlreadySubscribed'));
  810. } else {
  811. if ($current_course['subscribe'] == SUBSCRIBE_ALLOWED) {
  812. echo "<form action=\"".$_SERVER["REQUEST_URI"]."\" method=\"post\">";
  813. echo '<input type="hidden" name="sec_token" value="'.$stok.'">';
  814. echo "<input type=\"hidden\" name=\"subscribe\" value=\"".$current_course['code']."\" />";
  815. if (!empty($_POST['search_term'])) {
  816. echo '<input type="hidden" name="search_course" value="1" />';
  817. echo '<input type="hidden" name="search_term" value="'.Security::remove_XSS($_POST['search_term']).'" />';
  818. }
  819. echo "<input style=\"border-color:#fff\" type=\"image\" name=\"unsub\" src=\"".api_get_path(WEB_IMG_PATH)."enroll.gif\" title=\"".get_lang('Subscribe')."\" alt=\"".get_lang('Subscribe')."\" /></form>";
  820. } else {
  821. // echo get_lang('SubscribingNotAllowed');
  822. Display::display_icon('enroll_na.gif', get_lang('SubscribingNotAllowed'));
  823. }
  824. }
  825. }
  826. /**
  827. * Displays the subscribe icon if the subscribing is allowed and if the user is not yet
  828. * subscribed to this course
  829. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  830. * @param $key:
  831. * $number_of_courses
  832. * $course
  833. * $user_courses
  834. * @return html a small table containing the up/down icons and the edit icon (for moving to a different user course category)
  835. * @todo complete the comments on this function: the parameter section
  836. */
  837. function display_course_icons($key, $number_of_courses, $course) {
  838. global $safe, $stok;
  839. echo "<table><tr><td>";
  840. // the up icon
  841. if ($key > 0) {
  842. echo "<a href=\"courses.php?action=".$safe['action']."&amp;move=up&amp;course=".$course['code']."&amp;category=".$course['user_course_cat']."&amp;sec_token=".$stok."\">";
  843. Display::display_icon('up.gif', get_lang('Up'));
  844. echo '</a>';
  845. }
  846. echo "</td>";
  847. // the edit icon OR the edit dropdown list
  848. if (isset($_GET['edit']) && $course['code'] == $_GET['edit']) {
  849. echo "<td rowspan=\"2\" valign=\"top\">".display_change_course_category_form($_GET['edit'])."</td>";
  850. } else {
  851. echo "<td rowspan=\"2\" valign=\"middle\"><a href=\"courses.php?action=".$safe['action']."&amp;edit=".$course['code']."&amp;sec_token=".$stok."\">";
  852. Display::display_icon('edit.gif', get_lang('Edit'));
  853. echo "</a></td>";
  854. }
  855. echo "<td rowspan=\"2\" valign=\"top\" class=\"invisible\">";
  856. if ($course['status'] != 1) {
  857. if ($course['unsubscr'] == 1) {
  858. // changed link to submit to avoid action by the search tool indexer
  859. echo "<form action=\"".api_get_self()."\" method=\"post\" onsubmit=\"javascript: if (!confirm('".addslashes(api_htmlentities(get_lang("ConfirmUnsubscribeFromCourse"), ENT_QUOTES, api_get_system_encoding()))."')) return false;\">";
  860. echo '<input type="hidden" name="sec_token" value="'.$stok.'">';
  861. echo "<input type=\"hidden\" name=\"unsubscribe\" value=\"".$course['code']."\" />";
  862. echo '<input type="image" name="unsub" style="border-color:#fff" src="'.api_get_path(WEB_IMG_PATH).'delete.gif" title="'.get_lang('_unsubscribe').'" alt="'.get_lang('_unsubscribe').'" /></form>';
  863. } else {
  864. display_info_text(get_lang('UnsubscribeNotAllowed'));
  865. }
  866. } else {
  867. display_info_text(get_lang('CourseAdminUnsubscribeNotAllowed'));
  868. }
  869. echo "</td>";
  870. echo "</tr><tr><td>";
  871. if ($key < $number_of_courses - 1) {
  872. echo "<a href=\"courses.php?action=".$safe['action']."&amp;move=down&amp;course=".$course['code']."&amp;category=".$course['user_course_cat']."&amp;sec_token=".$stok."\">";
  873. Display::display_icon('down.gif', get_lang('Down'));
  874. echo '</a>';
  875. }
  876. echo "</td></tr></table>";
  877. }
  878. /**
  879. * displays the relevant icons for the category (if applicable):move up, move down, edit, delete
  880. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  881. * @param $current_category the id of the current category
  882. * $allcategories an associative array containing all the categories.
  883. * @return html: a small table containing the up/down icons and the edit icon (for moving to a different user course category)
  884. * @todo complete the comments on this function: the parameter section
  885. */
  886. function display_category_icons($current_category, $all_user_categories) {
  887. global $safe, $stok;
  888. $max_category_key = count($all_user_categories);
  889. if ($safe['action'] != 'unsubscribe') { // we are in the unsubscribe section then we do not show the icons.
  890. echo "<table>";
  891. echo "<tr>";
  892. echo "<td>";
  893. if ($current_category != $all_user_categories[0]) {
  894. echo "<a href=\"courses.php?action=".$safe['action']."&amp;move=up&amp;category=".$current_category."&amp;sec_token=".$stok."\">";
  895. echo Display::return_icon('up.gif', get_lang('Up')).'</a>';
  896. }
  897. echo "</td>";
  898. echo " <td rowspan=\"2\">";
  899. echo " <a href=\"courses.php?action=sortmycourses&amp;categoryid=".$current_category."&amp;sec_token=".$stok."#category".$current_category."\">";
  900. Display::display_icon('edit.gif', get_lang('Edit'));
  901. echo "</a>";
  902. echo "</td>";
  903. echo "<td rowspan=\"2\">";
  904. echo " <a href=\"courses.php?action=deletecoursecategory&amp;id=".$current_category."&amp;sec_token=".$stok."\">";
  905. Display::display_icon('delete.gif', get_lang('Delete'), array('onclick' => "javascript: if (!confirm('".addslashes(api_htmlentities(get_lang("CourseCategoryAbout2bedeleted"), ENT_QUOTES, api_get_system_encoding()))."')) return false;"));
  906. echo "</a>";
  907. echo "</td>";
  908. echo "</tr>";
  909. echo "<tr>";
  910. echo " <td>";
  911. if ($current_category != $all_user_categories[$max_category_key - 1]) {
  912. echo "<a href=\"courses.php?action=".$safe['action']."&amp;move=down&amp;category=".$current_category."&amp;sec_token=".$stok."\">";
  913. echo Display::return_icon('down.gif', get_lang('Down')).'</a>';
  914. }
  915. echo "</td>";
  916. echo " </tr>";
  917. echo "</table>";
  918. }
  919. }
  920. /**
  921. * This function displays the form (dropdown list) to move a course to a
  922. * different course_category (after the edit icon has been changed)
  923. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  924. * @param string $edit_course:
  925. * @return html a dropdown list containing all the user defined course categories and a submit button
  926. * @todo when editing (moving) a course inside a user defined course category to a different user defined category
  927. * the dropdown list should have the current course category selected.
  928. */
  929. function display_change_course_category_form($edit_course) {
  930. global $_user, $_configuration, $safe, $stok;
  931. $edit_course = Security::remove_XSS($edit_course);
  932. $DATABASE_USER_TOOLS = $_configuration['user_personal_database'];
  933. $tucc = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  934. $sql = "SELECT * FROM $tucc WHERE user_id='".$_user['user_id']."'";
  935. $result = Database::query($sql);
  936. $output = "<form name=\"edit_course_category\" method=\"post\" action=\"courses.php?action=".$safe['action']."\">\n";
  937. $output .= '<input type="hidden" name="sec_token" value="'.$stok.'">';
  938. $output .= "<input type=\"hidden\" name=\"course_2_edit_category\" value=\"".$edit_course."\" />";
  939. $output .= "\t<select name=\"course_categories\">\n";
  940. $output .= "\t\t<option value=\"0\">".get_lang("NoCourseCategory")."</option>";
  941. while ($row = Database::fetch_array($result)) {
  942. $output.="\t\t<option value=\"".$row['id']."\">".$row['title']."</option>";
  943. }
  944. $output .= "\t</select>\n";
  945. $output .= "\t<button class=\"save\" type=\"submit\" name=\"submit_change_course_category\">".get_lang('Ok')."</button>\n";
  946. $output .= "</form>";
  947. return $output;
  948. }
  949. /**
  950. * This function displays the unsubscribe part which can be
  951. * 1. the unsubscribe link
  952. * 2. text: you are course admin of this course (=> unsubscription is not possible
  953. * 3. text: you are not allowed to unsubscribe from this course
  954. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  955. * @param array $course: the array with all the course & course_rel_user information
  956. * @return html a delete icon or a text that unsubscribing is not possible (course admin) or not allowed.
  957. */
  958. function display_unsubscribe_icons($course) {
  959. global $stok;
  960. if ($course['status'] != 1) {
  961. if ($course['unsubscribe'] == 1) {
  962. // Changed link to submit to avoid action by the search tool indexer.
  963. echo "<form action=\"".api_get_self()."\" method=\"post\" onsubmit=\"javascript: if (!confirm('".addslashes(api_htmlentities(get_lang('ConfirmUnsubscribeFromCourse'), ENT_QUOTES, api_get_system_encoding()))."')) return false;\">";
  964. echo '<input type="hidden" name="sec_token" value="'.$stok.'">';
  965. echo "<input type=\"hidden\" name=\"unsubscribe\" value=\"".$course['code']."\" />";
  966. echo "<input type=\"image\" name=\"unsub\" src=\"".api_get_path(WEB_IMG_PATH)."delete.gif\" alt=\"".get_lang('_unsubscribe')."\" /></form>";
  967. } else {
  968. display_info_text(get_lang('UnsubscribeNotAllowed'));
  969. }
  970. } else {
  971. display_info_text(get_lang('CourseAdminUnsubscribeNotAllowed'));
  972. }
  973. }
  974. /**
  975. * retrieves all the courses that the user has already subscribed to
  976. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  977. * @param int $user_id: the id of the user
  978. * @return array an array containing all the information of the courses of the given user
  979. */
  980. function get_courses_of_user($user_id) {
  981. $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE);
  982. $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  983. $TABLE_COURSE_FIELD = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD);
  984. $TABLE_COURSE_FIELD_VALUE = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
  985. // get course list auto-register
  986. $sql = "SELECT course_code FROM $TABLE_COURSE_FIELD_VALUE tcfv INNER JOIN $TABLE_COURSE_FIELD tcf ON " .
  987. " tcfv.field_id = tcf.id WHERE tcf.field_variable = 'special_course' AND tcfv.field_value = 1 ";
  988. $special_course_result = Database::query($sql);
  989. if(Database::num_rows($special_course_result)>0) {
  990. $special_course_list = array();
  991. while ($result_row = Database::fetch_array($special_course_result)) {
  992. $special_course_list[] = '"'.$result_row['course_code'].'"';
  993. }
  994. }
  995. $without_special_courses = '';
  996. if (!empty($special_course_list)) {
  997. $without_special_courses = ' AND course.code NOT IN ('.implode(',',$special_course_list).')';
  998. }
  999. // Secondly we select the courses that are in a category (user_course_cat<>0) and sort these according to the sort of the category
  1000. $user_id = intval($user_id);
  1001. $sql_select_courses = "SELECT course.code k, course.visual_code vc, course.subscribe subscr, course.unsubscribe unsubscr,
  1002. course.title i, course.tutor_name t, course.db_name db, course.directory dir, course_rel_user.status status,
  1003. course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat
  1004. FROM $TABLECOURS course,
  1005. $TABLECOURSUSER course_rel_user
  1006. WHERE course.code = course_rel_user.course_code
  1007. AND course_rel_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
  1008. AND course_rel_user.user_id = '".$user_id."' $without_special_courses
  1009. ORDER BY course_rel_user.sort ASC";
  1010. $result = Database::query($sql_select_courses);
  1011. while ($row = Database::fetch_array($result)) {
  1012. // we only need the database name of the course
  1013. $courses[] = array('db' => $row['db'], 'code' => $row['k'], 'visual_code' => $row['vc'], 'title' => $row['i'], 'directory' => $row['dir'], 'status' => $row['status'], 'tutor' => $row['t'], 'subscribe' => $row['subscr'], 'unsubscribe' => $row['unsubscr'], 'sort' => $row['sort'], 'user_course_category' => $row['user_course_cat']);
  1014. }
  1015. return $courses;
  1016. }
  1017. /**
  1018. * retrieves the user defined course categories
  1019. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1020. * @return array containing all the IDs of the user defined courses categories, sorted by the "sort" field
  1021. */
  1022. function get_user_course_categories() {
  1023. global $_user;
  1024. $table_category = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  1025. $sql = "SELECT * FROM ".$table_category." WHERE user_id='".$_user['user_id']."' ORDER BY sort ASC";
  1026. $result = Database::query($sql);
  1027. while ($row = Database::fetch_array($result)) {
  1028. $output[] = $row['id'];
  1029. }
  1030. return $output;
  1031. }
  1032. /**
  1033. * Retrieves the user defined course categories and all the info that goes with it
  1034. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1035. * @return array containing all the info of the user defined courses categories with the id as key of the array
  1036. */
  1037. function get_user_course_categories_info() {
  1038. global $_user;
  1039. $table_category = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  1040. $sql = "SELECT * FROM ".$table_category." WHERE user_id='".$_user['user_id']."' ORDER BY sort ASC";
  1041. $result = Database::query($sql);
  1042. while ($row = Database::fetch_array($result)) {
  1043. $output[$row['id']] = $row;
  1044. }
  1045. return $output;
  1046. }
  1047. /**
  1048. * @author unknown
  1049. * @param string $text: the text that has to be written in grey
  1050. * @return string: the text with the grey formatting
  1051. * @todo move this to a stylesheet
  1052. * Added id grey to CSS
  1053. */
  1054. function display_info_text($text) {
  1055. //echo "<font color=\"#808080\">" . $text . "</font>\n";
  1056. echo $text;
  1057. }
  1058. /**
  1059. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1060. * @param string $edit_course:
  1061. * @return html output: the form
  1062. */
  1063. function display_edit_course_category_form($edit_course_category) {
  1064. global $safe, $stok;
  1065. echo "<form name=\"edit_course_category\" method=\"post\" action=\"courses.php?action=".$safe['action']."\">\n";
  1066. echo "\t<input type=\"hidden\" name=\"edit_course_category\" value=\"".$edit_course_category."\" />\n";
  1067. echo '<input type="hidden" name="sec_token" value="'.$stok.'">';
  1068. $info_this_user_course_category = get_user_course_category($edit_course_category);
  1069. echo "\t<input type=\"text\" name=\"title_course_category\" value=\"".$info_this_user_course_category['title']."\" />";
  1070. echo "\t<button class=\"save\" type=\"submit\" name=\"submit_edit_course_category\">".get_lang('Ok')."</button>\n";
  1071. echo "</form>";
  1072. }
  1073. /**
  1074. * Updates the user course category in the chamilo_user database
  1075. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1076. * @return string a language variable saying that the user course category was stored
  1077. */
  1078. function store_edit_course_category() {
  1079. global $_user, $_configuration;
  1080. $tucc = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  1081. $sql_update = "UPDATE $tucc SET title='".api_htmlentities($_POST['title_course_category'], ENT_QUOTES, api_get_system_encoding())."' WHERE id='".(int)$_POST['edit_course_category']."'";
  1082. Database::query($sql_update);
  1083. return get_lang('CourseCategoryEditStored');
  1084. }