courses_categories.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * View (MVC patter) for courses categories
  5. * @author Christian Fasanando <christian1827@gmail.com> - Beeznest
  6. * @package chamilo.auth
  7. */
  8. if (isset($_REQUEST['action']) && Security::remove_XSS($_REQUEST['action']) !== 'subscribe') {
  9. $stok = Security::get_token();
  10. } else {
  11. $stok = Security::getTokenFromSession();
  12. }
  13. $action = !empty($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : 'display_courses';
  14. $showCourses = CoursesAndSessionsCatalog::showCourses();
  15. $showSessions = CoursesAndSessionsCatalog::showSessions();
  16. $pageCurrent = isset($pageCurrent) ? $pageCurrent : isset($_GET['pageCurrent']) ? intval($_GET['pageCurrent']) : 1;
  17. $pageLength = isset($pageLength) ? $pageLength : isset($_GET['pageLength']) ? intval($_GET['pageLength']) : CoursesAndSessionsCatalog::PAGE_LENGTH;
  18. $pageTotal = intval(ceil(intval($countCoursesInCategory) / $pageLength));
  19. $cataloguePagination = $pageTotal > 1 ? CourseCategory::getCatalogPagination($pageCurrent, $pageLength, $pageTotal) : '';
  20. $searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : '';
  21. $codeType = isset($_REQUEST['category_code']) ? Security::remove_XSS($_REQUEST['category_code']) : '';
  22. if ($showSessions && isset($_POST['date'])) {
  23. $date = $_POST['date'];
  24. } else {
  25. $date = date('Y-m-d');
  26. }
  27. $userInfo = api_get_user_info();
  28. $code = isset($code) ? $code : null;
  29. ?>
  30. <script>
  31. $(document).ready( function() {
  32. $('.star-rating li a').on('click', function(event) {
  33. var id = $(this).parents('ul').attr('id');
  34. $('#vote_label2_' + id).html("<?php echo get_lang('Loading'); ?>");
  35. $.ajax({
  36. url: $(this).attr('data-link'),
  37. success: function(data) {
  38. $("#rating_wrapper_"+id).html(data);
  39. if (data == 'added') {
  40. //$('#vote_label2_' + id).html("{'Saved'|get_lang}");
  41. }
  42. if (data == 'updated') {
  43. //$('#vote_label2_' + id).html("{'Saved'|get_lang}");
  44. }
  45. }
  46. });
  47. });
  48. var getSessionId = function (el) {
  49. var parts = el.id.split('_');
  50. return parseInt(parts[1], 10);
  51. };
  52. <?php if ($showSessions) { ?>
  53. $('#date').datepicker({
  54. dateFormat: 'yy-mm-dd'
  55. });
  56. <?php } ?>
  57. });
  58. </script>
  59. <div class="row">
  60. <div class="col-md-12">
  61. <h2 class="title-courses"><?php echo get_lang('CourseManagement'); ?></h2>
  62. <div class="search-courses">
  63. <div class="row">
  64. <?php if ($showCourses) { ?>
  65. <div class="col-md-<?php echo($showSessions ? '4' : '6'); ?>">
  66. <?php if (!isset($_GET['hidden_links']) || intval($_GET['hidden_links']) != 1) { ?>
  67. <form method="post"
  68. action="<?php echo CourseCategory::getCourseCategoryUrl(1, $pageLength, 'ALL', 0, 'subscribe'); ?>">
  69. <input type="hidden" name="sec_token" value="<?php echo $stok; ?>">
  70. <input type="hidden" name="search_course" value="1"/>
  71. <label><?php echo get_lang('Search'); ?></label>
  72. <div class="input-group">
  73. <input class="form-control" type="text" name="search_term"
  74. value="<?php echo(empty($_POST['search_term'])
  75. ? ''
  76. : api_htmlentities($searchTerm)); ?>"/>
  77. <div class="input-group-btn">
  78. <button class="btn btn-default" type="submit">
  79. <em class="fa fa-search"></em> <?php echo get_lang('Search'); ?>
  80. </button>
  81. </div>
  82. </div>
  83. </form>
  84. <?php } ?>
  85. </div>
  86. <div class="col-md-<?php echo($showSessions ? '4' : '6'); ?>">
  87. <?php
  88. $webAction = api_get_path(WEB_CODE_PATH).'auth/courses.php';
  89. $form = '<form action="'.$webAction.'" method="GET">';
  90. $form .= '<input type="hidden" name="action" value="'.$action.'">';
  91. $form .= '<input type="hidden" name="pageCurrent" value="'.$pageCurrent.'">';
  92. $form .= '<input type="hidden" name="pageLength" value="'.$pageLength.'">';
  93. $form .= '<div class="form-group">';
  94. $form .= '<label>'.get_lang('CourseCategories').'</label>';
  95. $form .= '<select name="category_code" onchange="submit();" class="selectpicker show-tick form-control">';
  96. foreach ($browse_course_categories[0] as $category) {
  97. $categoryCode = $category['code'];
  98. $countCourse = $category['count_courses'];
  99. $form .= '<option '.($categoryCode == $codeType ? 'selected="selected" ' : '')
  100. .' value="'.$category['code'].'">'.$category['name'].' ('.$countCourse.') </option>';
  101. if (!empty($browse_course_categories[$categoryCode])) {
  102. foreach ($browse_course_categories[$categoryCode] as $subCategory) {
  103. $subCategoryCode = $subCategory['code'];
  104. $form .= '<option '
  105. .($subCategoryCode == $codeType
  106. ? 'selected="selected" '
  107. : '')
  108. .' value="'.$subCategory['code'].'">---'.$subCategory['name'].' ('.$subCategory['count_courses'].')</option>';
  109. }
  110. }
  111. }
  112. $form .= '</select>';
  113. $form .= '</div>';
  114. $form .= '</form>';
  115. echo $form;
  116. ?>
  117. </div>
  118. <?php } ?>
  119. <?php if ($showSessions) { ?>
  120. <div class="col-md-4">
  121. <div class="return-catalog">
  122. <a class="btn btn-default btn-lg btn-block"
  123. href="<?php echo CourseCategory::getCourseCategoryUrl(1, $pageLength, null, 0, 'display_sessions'); ?>">
  124. <em class="fa fa-arrow-right"></em> <?php echo get_lang('SessionList'); ?>
  125. </a>
  126. </div>
  127. </div>
  128. <?php } ?>
  129. </div>
  130. </div>
  131. </div>
  132. </div>
  133. <?php
  134. if ($showCourses && $action != 'display_sessions') {
  135. if (!empty($message)) {
  136. echo Display::return_message($message, 'confirmation', false);
  137. }
  138. if (!empty($error)) {
  139. echo Display::return_message($error, 'error', false);
  140. }
  141. if (!empty($content)) {
  142. echo $content;
  143. }
  144. if (!empty($searchTerm)) {
  145. echo "<p><strong>".get_lang('SearchResultsFor')." ".$searchTerm."</strong><br />";
  146. }
  147. $ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
  148. $user_id = api_get_user_id();
  149. $categoryList = CourseManager::getCategoriesList();
  150. if (!empty($browse_courses_in_category)) {
  151. echo '<div class="grid-courses row">';
  152. foreach ($browse_courses_in_category as $course) {
  153. $course_hidden = $course['visibility'] == COURSE_VISIBILITY_HIDDEN;
  154. if ($course_hidden) {
  155. continue;
  156. }
  157. $userRegisteredInCourse = CourseManager::is_user_subscribed_in_course($user_id, $course['code']);
  158. $userRegisteredInCourseAsTeacher = CourseManager::is_course_teacher($user_id, $course['code']);
  159. $userRegistered = $userRegisteredInCourse && $userRegisteredInCourseAsTeacher;
  160. $course_public = $course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD;
  161. $course_open = $course['visibility'] == COURSE_VISIBILITY_OPEN_PLATFORM;
  162. $course_private = $course['visibility'] == COURSE_VISIBILITY_REGISTERED;
  163. $course_closed = $course['visibility'] == COURSE_VISIBILITY_CLOSED;
  164. $course_subscribe_allowed = $course['subscribe'] == 1;
  165. $course_unsubscribe_allowed = $course['unsubscribe'] == 1;
  166. $count_connections = $course['count_connections'];
  167. $creation_date = substr($course['creation_date'], 0, 10);
  168. // display the course bloc
  169. $html = '<div class="col-xs-12 col-sm-6 col-md-4"><div class="items items-courses">';
  170. $course['category_title'] = '';
  171. if (isset($course['category'])) {
  172. $course['category_title'] = isset($categoryList[$course['category']]) ? $categoryList[$course['category']] : '';
  173. }
  174. // Display thumbnail
  175. $html .= returnThumbnail($course, $userRegistered);
  176. $separator = null;
  177. $subscribeButton = return_register_button($course, $stok, $code, $searchTerm);
  178. // Start buy course validation
  179. // display the course price and buy button if the buycourses plugin is enabled and this course is configured
  180. $plugin = BuyCoursesPlugin::create();
  181. $isThisCourseInSale = $plugin->buyCoursesForGridCatalogValidator(
  182. $course['real_id'],
  183. BuyCoursesPlugin::PRODUCT_TYPE_COURSE
  184. );
  185. if ($isThisCourseInSale) {
  186. // set the Price label
  187. $separator = $isThisCourseInSale['html'];
  188. // set the Buy button instead register.
  189. if ($isThisCourseInSale['verificator']) {
  190. $subscribeButton = $plugin->returnBuyCourseButton(
  191. $course['real_id'],
  192. BuyCoursesPlugin::PRODUCT_TYPE_COURSE
  193. );
  194. }
  195. }
  196. // end buy course validation
  197. // display course title and button bloc
  198. $html .= '<div class="description">';
  199. $html .= return_title($course, $userRegisteredInCourse);
  200. $html .= return_teacher($course);
  201. // display button line
  202. $html .= '<div class="toolbar row">';
  203. $html .= $separator ? '<div class="col-sm-4">'.$separator.'</div>' : '';
  204. $html .= '<div class="col-sm-8">';
  205. // if user registered as student
  206. if ($userRegisteredInCourse) {
  207. $html .= return_already_registered_label('student');
  208. if (!$course_closed) {
  209. if ($course_unsubscribe_allowed) {
  210. $html .= return_unregister_button($course, $stok, $searchTerm, $code);
  211. }
  212. }
  213. } elseif ($userRegisteredInCourseAsTeacher) {
  214. // if user registered as teacher
  215. if ($course_unsubscribe_allowed) {
  216. $html .= return_unregister_button($course, $stok, $searchTerm, $code);
  217. }
  218. } else {
  219. // if user not registered in the course
  220. if (!$course_closed) {
  221. if (!$course_private) {
  222. if ($course_subscribe_allowed) {
  223. $html .= $subscribeButton;
  224. }
  225. }
  226. }
  227. }
  228. $html .= '</div>';
  229. $html .= '</div>';
  230. $html .= '</div>';
  231. $html .= '</div>';
  232. $html .= '</div>';
  233. echo $html;
  234. }
  235. echo '</div>';
  236. } else {
  237. if (!isset($_REQUEST['subscribe_user_with_password']) &&
  238. !isset($_REQUEST['subscribe_course'])
  239. ) {
  240. echo Display::return_message(
  241. get_lang('ThereAreNoCoursesInThisCategory'),
  242. 'warning'
  243. );
  244. }
  245. }
  246. }
  247. echo '<div class="col-md-12">';
  248. echo $cataloguePagination;
  249. echo '</div>';
  250. /**
  251. * Display the course catalog image of a course
  252. * @param array $course
  253. * @param bool $registeredUser
  254. *
  255. * @return string HTML string
  256. */
  257. function returnThumbnail($course, $registeredUser)
  258. {
  259. $html = '';
  260. $title = cut($course['title'], 70);
  261. $linkCourse = api_get_course_url($course['code']);
  262. // course path
  263. $course_path = api_get_path(SYS_COURSE_PATH).$course['directory'];
  264. if (file_exists($course_path.'/course-pic.png')) {
  265. // redimensioned image 85x85
  266. $courseMediumImage = api_get_path(WEB_COURSE_PATH).$course['directory'].'/course-pic.png';
  267. } else {
  268. // without picture
  269. $courseMediumImage = Display::return_icon(
  270. 'session_default.png',
  271. null,
  272. null,
  273. null,
  274. null,
  275. true
  276. );
  277. }
  278. $html .= '<div class="image">';
  279. if (!$registeredUser) {
  280. $html .= '<img class="img-responsive"'
  281. .' src="'.$courseMediumImage.'" '
  282. .' alt="'.api_htmlentities($title).'"/>';
  283. } else {
  284. $html .= '<a href="'.$linkCourse.'" title="'.$course['title'].'">'
  285. .'<img class="img-responsive" src="'.$courseMediumImage.'" '
  286. .'alt="'.api_htmlentities($title).'"/></a>';
  287. }
  288. $categoryTitle = isset($course['category_title']) ? $course['category_title'] : '';
  289. if (!empty($categoryTitle)) {
  290. $html .= '<span class="category">'.$categoryTitle.'</span>';
  291. $html .= '<div class="cribbon"></div>';
  292. }
  293. $html .= '<div class="user-actions">';
  294. $html .= return_description_button($course);
  295. $html .= '</div></div>';
  296. return $html;
  297. }
  298. /**
  299. * @param array $courseInfo
  300. * @return string
  301. */
  302. function return_teacher($courseInfo)
  303. {
  304. $teachers = CourseManager::getTeachersFromCourse($courseInfo['real_id']);
  305. $length = count($teachers);
  306. if (!$length) {
  307. return '';
  308. }
  309. $html = '<div class="block-author">';
  310. if ($length > 6) {
  311. $html .= '<a
  312. id="plist"
  313. data-trigger="focus"
  314. tabindex="0" role="button"
  315. class="btn btn-default panel_popover"
  316. data-toggle="popover"
  317. title="'.addslashes(get_lang('CourseTeachers')).'"
  318. data-html="true"
  319. >
  320. <i class="fa fa-graduation-cap" aria-hidden="true"></i>
  321. </a>';
  322. $html .= '<div id="popover-content-plist" class="hide">';
  323. foreach ($teachers as $value) {
  324. $name = $value['firstname'].' '.$value['lastname'];
  325. $html .= '<div class="popover-teacher">';
  326. $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
  327. <img src="'.$value['avatar'].'" alt="'.get_lang('UserPicture').'"/></a>';
  328. $html .= '<div class="teachers-details"><h5>
  329. <a href="'.$value['url'].'" class="ajax" data-title="'.$name.'">'
  330. . $name.'</a></h5></div>';
  331. $html .= '</div>';
  332. }
  333. $html .= '</div>';
  334. } else {
  335. foreach ($teachers as $value) {
  336. $name = $value['firstname'].' '.$value['lastname'];
  337. if ($length > 2) {
  338. $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
  339. <img src="'.$value['avatar'].'" alt="'.get_lang('UserPicture').'"/></a>';
  340. } else {
  341. $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
  342. <img src="'.$value['avatar'].'" alt="'.get_lang('UserPicture').'"/></a>';
  343. $html .= '<div class="teachers-details"><h5>
  344. <a href="'.$value['url'].'" class="ajax" data-title="'.$name.'">'
  345. . $name.'</a></h5><p>'.get_lang('Teacher').'</p></div>';
  346. }
  347. }
  348. }
  349. $html .= '</div>';
  350. return $html;
  351. }
  352. /**
  353. * Display the title of a course in course catalog
  354. * @param array $course
  355. * @param bool $registeredUser
  356. *
  357. * @return string HTML string
  358. */
  359. function return_title($course, $registeredUser)
  360. {
  361. $linkCourse = api_get_course_url($course['code']);
  362. $html = '<div class="block-title"><h4 class="title">';
  363. if (!$registeredUser) {
  364. $html .= $course['title'];
  365. } else {
  366. $html .= '<a title="'.$course['title'].'" href="'.$linkCourse.'">'.$course['title'].'</a>';
  367. }
  368. $html .= '</h4></div>';
  369. if (api_get_configuration_value('hide_course_rating') === false) {
  370. $ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
  371. $rating = Display::return_rating_system(
  372. 'star_'.$course['real_id'],
  373. $ajax_url.'&course_id='.$course['real_id'],
  374. $course['point_info']
  375. );
  376. $html .= '<div class="ranking">'.$rating.'</div>';
  377. }
  378. return $html;
  379. }
  380. /**
  381. * Display the description button of a course in the course catalog
  382. * @param array $course
  383. *
  384. * @return string HTML string
  385. */
  386. function return_description_button($course)
  387. {
  388. $title = $course['title'];
  389. $html = '';
  390. if (api_get_setting('show_courses_descriptions_in_catalog') == 'true') {
  391. $html = Display::url(
  392. Display::returnFontAwesomeIcon('info-circle'),
  393. api_get_path(WEB_CODE_PATH).'inc/ajax/course_home.ajax.php?a=show_course_information&code='.$course['code'],
  394. array(
  395. 'class' => 'ajax btn btn-default btn-sm',
  396. 'data-title' => $title,
  397. 'title' => get_lang('Description'),
  398. 'aria-label' => get_lang('Description'),
  399. 'data-size' => 'lg'
  400. )
  401. );
  402. }
  403. return $html;
  404. }
  405. /**
  406. * Display the goto course button of a course in the course catalog
  407. * @param $course
  408. * @return string HTML string
  409. */
  410. function return_goto_button($course)
  411. {
  412. $title = get_lang('GoToCourse');
  413. $html = Display::url(
  414. Display::returnFontAwesomeIcon('share'),
  415. api_get_course_url($course['code']),
  416. array(
  417. 'class' => 'btn btn-default btn-sm',
  418. 'title' => $title,
  419. 'aria-label' => $title,
  420. )
  421. );
  422. return $html.PHP_EOL;
  423. }
  424. /**
  425. * Display the already registerd text in a course in the course catalog
  426. * @param $in_status
  427. *
  428. * @return string HTML string
  429. */
  430. function return_already_registered_label($in_status)
  431. {
  432. $icon = '<em class="fa fa-check"></em>';
  433. $title = get_lang("YouAreATeacherOfThisCourse");
  434. if ($in_status == 'student') {
  435. $icon = '<em class="fa fa-check"></em>';
  436. $title = get_lang("AlreadySubscribed");
  437. }
  438. $html = Display::tag(
  439. 'span',
  440. $icon.' '.$title,
  441. array(
  442. 'id' => 'register',
  443. 'class' => 'label-subscribed text-success',
  444. 'title' => $title,
  445. 'aria-label' => $title,
  446. )
  447. );
  448. return $html.PHP_EOL;
  449. }
  450. /**
  451. * Display the register button of a course in the course catalog
  452. * @param $course
  453. * @param $stok
  454. * @param $code
  455. * @param $search_term
  456. *
  457. * @return string
  458. */
  459. function return_register_button($course, $stok, $code, $search_term)
  460. {
  461. $title = get_lang('Subscribe');
  462. $html = Display::url(
  463. Display::returnFontAwesomeIcon('check').' '.$title,
  464. api_get_self().'?action=subscribe_course&sec_token='.$stok.
  465. '&subscribe_course='.$course['code'].'&search_term='.$search_term.'&category_code='.$code,
  466. array('class' => 'btn btn-success btn-sm', 'title' => $title, 'aria-label' => $title)
  467. );
  468. return $html;
  469. }
  470. /**
  471. * Display the unregister button of a course in the course catalog
  472. * @param $course
  473. * @param $stok
  474. * @param $search_term
  475. * @param $code
  476. *
  477. * @return string
  478. */
  479. function return_unregister_button($course, $stok, $search_term, $code)
  480. {
  481. $title = get_lang('Unsubscription');
  482. $html = Display::url(
  483. Display::returnFontAwesomeIcon('sign-in').' '.$title,
  484. api_get_self().'?action=unsubscribe&sec_token='.$stok
  485. .'&unsubscribe='.$course['code'].'&search_term='.$search_term.'&category_code='.$code,
  486. array('class' => 'btn btn-danger btn-sm', 'title' => $title, 'aria-label' => $title)
  487. );
  488. return $html;
  489. }