courses.php 54 KB

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