courses_categories.php 20 KB

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