courses_controller.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\SequenceResource;
  4. /**
  5. * Class CoursesController
  6. *
  7. * This file contains class used like controller,
  8. * it should be included inside a dispatcher file (e.g: index.php)
  9. * @author Christian Fasanando <christian1827@gmail.com> - BeezNest
  10. * @package chamilo.auth
  11. */
  12. class CoursesController
  13. {
  14. private $toolname;
  15. private $view;
  16. private $model;
  17. /**
  18. * Constructor
  19. */
  20. public function __construct()
  21. {
  22. $this->toolname = 'auth';
  23. $actived_theme_path = api_get_template();
  24. $this->view = new View($this->toolname, $actived_theme_path);
  25. $this->model = new Auth();
  26. }
  27. /**
  28. * It's used for listing courses,
  29. * render to courses_list view
  30. * @param string action
  31. * @param string confirmation message(optional)
  32. * @param string $action
  33. */
  34. public function courses_list($action, $message = '')
  35. {
  36. $data = array();
  37. $user_id = api_get_user_id();
  38. $data['user_courses'] = $this->model->get_courses_of_user($user_id);
  39. $data['user_course_categories'] = $this->model->get_user_course_categories();
  40. $data['courses_in_category'] = $this->model->get_courses_in_category();
  41. $data['all_user_categories'] = $this->model->get_user_course_categories();
  42. $data['action'] = $action;
  43. $data['message'] = $message;
  44. // render to the view
  45. $this->view->set_data($data);
  46. $this->view->set_layout('catalog_layout');
  47. $this->view->set_template('courses_list');
  48. $this->view->render();
  49. }
  50. /**
  51. * It's used for listing categories,
  52. * render to categories_list view
  53. * @param string $action
  54. * @param string $message confirmation message(optional)
  55. * @param string $error error message(optional)
  56. */
  57. public function categories_list($action, $message='', $error='')
  58. {
  59. $data = array();
  60. $data['user_course_categories'] = $this->model->get_user_course_categories();
  61. $data['action'] = $action;
  62. $data['message'] = $message;
  63. $data['error'] = $error;
  64. // render to the view
  65. $this->view->set_data($data);
  66. $this->view->set_layout('catalog_layout');
  67. $this->view->set_template('categories_list');
  68. $this->view->render();
  69. }
  70. /**
  71. * It's used for listing courses with categories,
  72. * render to courses_categories view
  73. * @param string $action
  74. * @param string $category_code
  75. * @param string $message
  76. * @param string $error
  77. * @param string $content
  78. * @param array $limit will be used if $random_value is not set.
  79. * This array should contains 'start' and 'length' keys
  80. * @internal param \action $string
  81. * @internal param \Category $string code (optional)
  82. */
  83. public function courses_categories(
  84. $action,
  85. $category_code = null,
  86. $message = '',
  87. $error = '',
  88. $content = null,
  89. $limit = array()
  90. ) {
  91. $data = array();
  92. $browse_course_categories = $this->model->browse_course_categories();
  93. $data['countCoursesInCategory'] = $this->model->count_courses_in_category($category_code);
  94. if ($action === 'display_random_courses') {
  95. // Random value is used instead limit filter
  96. $data['browse_courses_in_category'] = $this->model->browse_courses_in_category(null, 12);
  97. $data['countCoursesInCategory'] = count($data['browse_courses_in_category']);
  98. } else {
  99. if (!isset($category_code)) {
  100. $category_code = $browse_course_categories[0][1]['code']; // by default first category
  101. }
  102. $limit = isset($limit) ? $limit : CourseCategory::getLimitArray();
  103. $data['browse_courses_in_category'] = $this->model->browse_courses_in_category($category_code, null, $limit);
  104. }
  105. $data['browse_course_categories'] = $browse_course_categories;
  106. $data['code'] = Security::remove_XSS($category_code);
  107. // getting all the courses to which the user is subscribed to
  108. $curr_user_id = api_get_user_id();
  109. $user_courses = $this->model->get_courses_of_user($curr_user_id);
  110. $user_coursecodes = array();
  111. // we need only the course codes as these will be used to match against the courses of the category
  112. if ($user_courses != '') {
  113. foreach ($user_courses as $key => $value) {
  114. $user_coursecodes[] = $value['code'];
  115. }
  116. }
  117. if (api_is_drh()) {
  118. $courses = CourseManager::get_courses_followed_by_drh(api_get_user_id());
  119. foreach ($courses as $course) {
  120. $user_coursecodes[] = $course['code'];
  121. }
  122. }
  123. $data['user_coursecodes'] = $user_coursecodes;
  124. $data['action'] = $action;
  125. $data['message'] = $message;
  126. $data['content'] = $content;
  127. $data['error'] = $error;
  128. $data['catalogShowCoursesSessions'] = 0;
  129. $showCoursesSessions = intval('catalog_show_courses_sessions');
  130. if ($showCoursesSessions > 0) {
  131. $data['catalogShowCoursesSessions'] = $showCoursesSessions;
  132. }
  133. // render to the view
  134. $this->view->set_data($data);
  135. $this->view->set_layout('catalog_layout');
  136. $this->view->set_template('courses_categories');
  137. $this->view->render();
  138. }
  139. /**
  140. * @param string $search_term
  141. * @param string $message
  142. * @param string $error
  143. * @param string $content
  144. * @param $limit
  145. * @param boolean $justVisible Whether to search only in courses visibles in the catalogue
  146. */
  147. public function search_courses(
  148. $search_term,
  149. $message = '',
  150. $error = '',
  151. $content = null,
  152. $limit = array(),
  153. $justVisible = false
  154. ) {
  155. $data = array();
  156. $limit = !empty($limit) ? $limit : CourseCategory::getLimitArray();
  157. $browse_course_categories = $this->model->browse_course_categories();
  158. $data['countCoursesInCategory'] = $this->model->count_courses_in_category('ALL', $search_term);
  159. $data['browse_courses_in_category'] = $this->model->search_courses($search_term, $limit, $justVisible);
  160. $data['browse_course_categories'] = $browse_course_categories;
  161. $data['search_term'] = Security::remove_XSS($search_term); //filter before showing in template
  162. // getting all the courses to which the user is subscribed to
  163. $curr_user_id = api_get_user_id();
  164. $user_courses = $this->model->get_courses_of_user($curr_user_id);
  165. $user_coursecodes = array();
  166. // we need only the course codes as these will be used to match against the courses of the category
  167. if ($user_courses != '') {
  168. foreach ($user_courses as $value) {
  169. $user_coursecodes[] = $value['code'];
  170. }
  171. }
  172. $data['user_coursecodes'] = $user_coursecodes;
  173. $data['message'] = $message;
  174. $data['content'] = $content;
  175. $data['error'] = $error;
  176. $data['action'] = 'display_courses';
  177. // render to the view
  178. $this->view->set_data($data);
  179. $this->view->set_layout('catalog_layout');
  180. $this->view->set_template('courses_categories');
  181. $this->view->render();
  182. }
  183. /**
  184. * Auto user subscription to a course
  185. */
  186. public function subscribe_user($course_code, $search_term, $category_code)
  187. {
  188. $courseInfo = api_get_course_info($course_code);
  189. if (empty($courseInfo)) {
  190. return false;
  191. }
  192. $message = '';
  193. $error = '';
  194. $content = '';
  195. $result = [];
  196. // The course must be open in order to access the auto subscription
  197. if (in_array(
  198. $courseInfo['visibility'],
  199. array(COURSE_VISIBILITY_CLOSED, COURSE_VISIBILITY_REGISTERED, COURSE_VISIBILITY_HIDDEN))
  200. ) {
  201. $error = get_lang('SubscribingNotAllowed');
  202. } else {
  203. $result = $this->model->subscribe_user($course_code);
  204. if (!$result) {
  205. $error = get_lang('CourseRegistrationCodeIncorrect');
  206. } else {
  207. // Redirect directly to the course after subscription
  208. $message = isset($result['message']) ? $result['message'] : '';
  209. $content = isset($result['content']) ? $result['content'] : '';
  210. }
  211. }
  212. if (!empty($search_term)) {
  213. $this->search_courses($search_term, $message, $error, $content);
  214. } else {
  215. $this->courses_categories('subscribe', $category_code, $message, $error, $content);
  216. }
  217. return $result;
  218. }
  219. /**
  220. * Create a category
  221. * render to listing view
  222. * @param string Category title
  223. */
  224. public function add_course_category($category_title)
  225. {
  226. $result = $this->model->store_course_category($category_title);
  227. if ($result) {
  228. Display::addFlash(Display::return_message(get_lang('CourseCategoryStored')));
  229. } else {
  230. Display::addFlash(Display::return_message(get_lang('ACourseCategoryWithThisNameAlreadyExists'), 'error'));
  231. }
  232. $action = 'sortmycourses';
  233. $this->courses_list($action);
  234. }
  235. /**
  236. * Change course category
  237. * render to listing view
  238. * @param string $course_code
  239. * @param int $category_id
  240. */
  241. public function change_course_category($course_code, $category_id)
  242. {
  243. $courseInfo = api_get_course_info($course_code);
  244. $courseId = $courseInfo['real_id'];
  245. $result = $this->model->updateCourseCategory($courseId, $category_id);
  246. if ($result) {
  247. Display::addFlash(Display::return_message(get_lang('EditCourseCategorySucces')));
  248. }
  249. $action = 'sortmycourses';
  250. $this->courses_list($action);
  251. }
  252. /**
  253. * Move up/down courses inside a category
  254. * render to listing view
  255. * @param string $move move to up or down
  256. * @param string $course_code
  257. * @param int $category_id Category id
  258. */
  259. public function move_course($move, $course_code, $category_id)
  260. {
  261. $result = $this->model->move_course($move, $course_code, $category_id);
  262. if ($result) {
  263. Display::addFlash(Display::return_message(get_lang('CourseSortingDone')));
  264. }
  265. $action = 'sortmycourses';
  266. $this->courses_list($action);
  267. }
  268. /**
  269. * Move up/down categories
  270. * render to listing view
  271. * @param string $move move to up or down
  272. * @param int $category_id Category id
  273. */
  274. public function move_category($move, $category_id)
  275. {
  276. $result = $this->model->move_category($move, $category_id);
  277. if ($result) {
  278. Display::addFlash(Display::return_message(get_lang('CategorySortingDone')));
  279. }
  280. $action = 'sortmycourses';
  281. $this->courses_list($action);
  282. }
  283. /**
  284. * Edit course category
  285. * render to listing view
  286. * @param string $title Category title
  287. * @param int $category Category id
  288. */
  289. public function edit_course_category($title, $category)
  290. {
  291. $result = $this->model->store_edit_course_category($title, $category);
  292. if ($result) {
  293. Display::addFlash(Display::return_message(get_lang('CourseCategoryEditStored')));
  294. }
  295. $action = 'sortmycourses';
  296. $this->courses_list($action);
  297. }
  298. /**
  299. * Delete a course category
  300. * render to listing view
  301. * @param int Category id
  302. */
  303. public function delete_course_category($category_id)
  304. {
  305. $result = $this->model->delete_course_category($category_id);
  306. if ($result) {
  307. Display::addFlash(Display::return_message(get_lang('CourseCategoryDeleted')));
  308. }
  309. $action = 'sortmycourses';
  310. $this->courses_list($action);
  311. }
  312. /**
  313. * Unsubscribe user from a course
  314. * render to listing view
  315. * @param string $course_code
  316. * @param string $search_term
  317. * @param string $category_code
  318. */
  319. public function unsubscribe_user_from_course($course_code, $search_term = null, $category_code = null)
  320. {
  321. $result = $this->model->remove_user_from_course($course_code);
  322. $message = '';
  323. $error = '';
  324. if ($result) {
  325. Display::addFlash(Display::return_message(get_lang('YouAreNowUnsubscribed')));
  326. }
  327. $action = 'sortmycourses';
  328. if (!empty($search_term)) {
  329. $this->search_courses($search_term, $message, $error);
  330. } else {
  331. $this->courses_categories('subcribe', $category_code, $message, $error);
  332. }
  333. }
  334. /**
  335. * Get the html block for courses categories
  336. * @param string $code Current category code
  337. * @param boolean $hiddenLinks Whether hidden links
  338. * @param array $limit
  339. * @return string The HTML block
  340. */
  341. public function getCoursesCategoriesBlock($code = null, $hiddenLinks = false, $limit = null)
  342. {
  343. $categories = $this->model->browse_course_categories();
  344. $html = '';
  345. if (!empty($categories)) {
  346. $action = 'display_courses';
  347. foreach ($categories[0] as $category) {
  348. $categoryName = $category['name'];
  349. $categoryCode = $category['code'];
  350. $categoryCourses = $category['count_courses'];
  351. $html .= '<li>';
  352. if ($code == $categoryCode) {
  353. $html .= '<strong>';
  354. $html .= "$categoryName ($categoryCourses)";
  355. $html .= '</strong>';
  356. } else {
  357. if (!empty($categoryCourses)) {
  358. $html .= '<a href="' . CourseCategory::getCourseCategoryUrl(
  359. 1,
  360. $limit['length'],
  361. $categoryCode,
  362. $hiddenLinks,
  363. $action
  364. ) . '">';
  365. $html .= "$categoryName ($categoryCourses)";
  366. $html .= '</a>';
  367. } else {
  368. $html .= "$categoryName ($categoryCourses)";
  369. }
  370. }
  371. if (!empty($categories[$categoryCode])) {
  372. $html .= '<ul class="nav nav-list">';
  373. foreach ($categories[$categoryCode] as $subCategory1) {
  374. $subCategory1Name = $subCategory1['name'];
  375. $subCategory1Code = $subCategory1['code'];
  376. $subCategory1Courses = $subCategory1['count_courses'];
  377. $html .= '<li>';
  378. if ($code == $subCategory1Code) {
  379. $html .= "<strong>$subCategory1Name ($subCategory1Courses)</strong>";
  380. } else {
  381. $html .= '<a href="' . CourseCategory::getCourseCategoryUrl(
  382. 1,
  383. $limit['length'],
  384. $categoryCode,
  385. $hiddenLinks,
  386. $action
  387. ) . '">';
  388. $html .= "$subCategory1Name ($subCategory1Courses)";
  389. $html .= '</a>';
  390. }
  391. if (!empty($categories[$subCategory1Code])) {
  392. $html .= '<ul class="nav nav-list">';
  393. foreach ($categories[$subCategory1Code] as $subCategory2) {
  394. $subCategory2Name = $subCategory2['name'];
  395. $subCategory2Code = $subCategory2['code'];
  396. $subCategory2Courses = $subCategory2['count_courses'];
  397. $html .= '<li>';
  398. if ($code == $subCategory2Code) {
  399. $html .= "<strong>$subCategory2Name ($subCategory2Courses)</strong>";
  400. } else {
  401. $html .= '<a href="' . CourseCategory::getCourseCategoryUrl(
  402. 1,
  403. $limit['length'],
  404. $categoryCode,
  405. $hiddenLinks,
  406. $action
  407. ) . '">';
  408. $html .= "$subCategory2Name ($subCategory2Courses)";
  409. $html .= '</a>';
  410. }
  411. if (!empty($categories[$subCategory2Code])) {
  412. $html .= '<ul class="nav nav-list">';
  413. foreach ($categories[$subCategory2Code] as $subCategory3) {
  414. $subCategory3Name = $subCategory3['name'];
  415. $subCategory3Code = $subCategory3['code'];
  416. $subCategory3Courses = $subCategory3['count_courses'];
  417. $html .= '<li>';
  418. if ($code == $subCategory3Code) {
  419. $html .= "<strong>$subCategory3Name ($subCategory3Courses)</strong>";
  420. } else {
  421. $html .= '<a href="' . CourseCategory::getCourseCategoryUrl(
  422. 1,
  423. $limit['length'],
  424. $categoryCode,
  425. $hiddenLinks,
  426. $action
  427. ) . '">';
  428. $html .= "$subCategory3Name ($subCategory3Courses)";
  429. $html .= '</a>';
  430. }
  431. $html .= '</li>';
  432. }
  433. $html .= '</ul>';
  434. }
  435. $html .= '</li>';
  436. }
  437. $html .= '</ul>';
  438. }
  439. $html .= '</li>';
  440. }
  441. $html .= '</ul>';
  442. }
  443. $html .= '</li>';
  444. }
  445. }
  446. return $html;
  447. }
  448. /**
  449. * Get a HTML button for subscribe to session
  450. * @param int $sessionId The session ID
  451. * @param string $sessionName The session name
  452. * @param boolean $checkRequirements Optional.
  453. * Whether the session has requirement. Default is false
  454. * @return string The button HTML
  455. */
  456. public function getRegisteredInSessionButton(
  457. $sessionId,
  458. $sessionName,
  459. $checkRequirements = false
  460. ) {
  461. if ($checkRequirements) {
  462. $url = api_get_path(WEB_AJAX_PATH);
  463. $url .= 'sequence.ajax.php?';
  464. $url .= http_build_query([
  465. 'a' => 'get_requirements',
  466. 'id' => intval($sessionId),
  467. 'type' => SequenceResource::SESSION_TYPE,
  468. ]);
  469. return Display::toolbarButton(
  470. null,
  471. $url,
  472. 'shield',
  473. 'default',
  474. [
  475. 'class' => 'btn-sm ajax',
  476. 'data-title' => get_lang('CheckRequirements'),
  477. 'data-size' => 'md',
  478. 'title' => get_lang('CheckRequirements')
  479. ]
  480. );
  481. }
  482. $catalogSessionAutoSubscriptionAllowed = false;
  483. if (api_get_setting('catalog_allow_session_auto_subscription') === 'true') {
  484. $catalogSessionAutoSubscriptionAllowed = true;
  485. }
  486. $url = api_get_path(WEB_CODE_PATH);
  487. if ($catalogSessionAutoSubscriptionAllowed) {
  488. $url .= 'auth/courses.php?';
  489. $url .= http_build_query([
  490. 'action' => 'subscribe_to_session',
  491. 'session_id' => intval($sessionId)
  492. ]);
  493. $result = Display::toolbarButton(
  494. null,
  495. $url,
  496. 'sign-in',
  497. 'success',
  498. [
  499. 'class' => 'btn-sm ajax',
  500. 'data-title' => get_lang('AreYouSureToSubscribe'),
  501. 'data-size' => 'md',
  502. 'title' => get_lang('Subscribe')
  503. ]
  504. );
  505. } else {
  506. $url .= 'inc/email_editor.php?';
  507. $url .= http_build_query([
  508. 'action' => 'subscribe_me_to_session',
  509. 'session' => Security::remove_XSS($sessionName),
  510. ]);
  511. $result = Display::toolbarButton(
  512. null,
  513. $url,
  514. 'sign-in',
  515. 'success',
  516. ['class' => 'btn-sm']
  517. );
  518. }
  519. $hook = HookResubscribe::create();
  520. if (!empty($hook)) {
  521. $hook->setEventData(array(
  522. 'session_id' => intval($sessionId),
  523. ));
  524. try {
  525. $hook->notifyResubscribe(HOOK_EVENT_TYPE_PRE);
  526. } catch (Exception $exception) {
  527. $result = $exception->getMessage();
  528. }
  529. }
  530. return $result;
  531. }
  532. /**
  533. * Generate a label if the user has been registered in session
  534. * @return string The label
  535. */
  536. public function getAlreadyRegisteredInSessionLabel()
  537. {
  538. $icon = '<em class="fa fa-graduation-cap"></em>';
  539. return Display::div(
  540. $icon,
  541. array('class' => 'btn btn-default btn-sm registered', 'title' => get_lang("AlreadyRegisteredToSession"))
  542. );
  543. }
  544. /**
  545. * Get a icon for a session
  546. * @param string $sessionName The session name
  547. * @return string The icon
  548. */
  549. public function getSessionIcon($sessionName)
  550. {
  551. return Display::return_icon('window_list.png', $sessionName, null,ICON_SIZE_MEDIUM);
  552. }
  553. /**
  554. * Return Session Catalogue rendered view
  555. * @param string $action
  556. * @param string $nameTools
  557. * @param array $limit
  558. */
  559. public function sessionsList($action, $nameTools, $limit = array())
  560. {
  561. $date = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
  562. $hiddenLinks = isset($_GET['hidden_links']) ? intval($_GET['hidden_links']) == 1 : false;
  563. $limit = isset($limit) ? $limit : CourseCategory::getLimitArray();
  564. $countSessions = $this->model->countSessions($date);
  565. $sessions = $this->model->browseSessions($date, $limit);
  566. $pageTotal = intval(ceil(intval($countSessions) / $limit['length']));
  567. // Do NOT show pagination if only one page or less
  568. $cataloguePagination = $pageTotal > 1 ?
  569. CourseCategory::getCatalogPagination($limit['current'], $limit['length'], $pageTotal) :
  570. '';
  571. $sessionsBlocks = $this->getFormatedSessionsBlock($sessions);
  572. // Get session list catalogue URL
  573. //$sessionUrl = CourseCategory::getCourseCategoryUrl(1, $limit['length'], null, 0, 'display_sessions');
  574. // Get session search catalogue URL
  575. $courseUrl = CourseCategory::getCourseCategoryUrl(1, $limit['length'], null, 0, 'subscribe');
  576. $tpl = new Template();
  577. $tpl->assign('show_courses', CoursesAndSessionsCatalog::showCourses());
  578. $tpl->assign('show_sessions', CoursesAndSessionsCatalog::showSessions());
  579. $tpl->assign('show_tutor', (api_get_setting('show_session_coach')==='true' ? true : false));
  580. $tpl->assign('course_url', $courseUrl);
  581. $tpl->assign('catalog_pagination', $cataloguePagination);
  582. $tpl->assign('hidden_links', $hiddenLinks);
  583. $tpl->assign('search_token', Security::get_token());
  584. $tpl->assign('search_date', $date);
  585. $tpl->assign('web_session_courses_ajax_url', api_get_path(WEB_AJAX_PATH) . 'course.ajax.php');
  586. $tpl->assign('sessions', $sessionsBlocks);
  587. $tpl->assign('already_subscribed_label', $this->getAlreadyRegisteredInSessionLabel());
  588. $contentTemplate = $tpl->get_template('auth/session_catalog.tpl');
  589. $tpl->display($contentTemplate);
  590. }
  591. /**
  592. * Show the Session Catalogue with filtered session by course tags
  593. * @param array $limit Limit info
  594. */
  595. public function sessionsListByCoursesTag(array $limit)
  596. {
  597. $searchTag = isset($_POST['search_tag']) ? $_POST['search_tag'] : null;
  598. $searchDate = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
  599. $hiddenLinks = isset($_GET['hidden_links']) ? intval($_GET['hidden_links']) == 1 : false;
  600. $courseUrl = CourseCategory::getCourseCategoryUrl(1, $limit['length'], null, 0, 'subscribe');
  601. $sessions = $this->model->browseSessionsByTags($searchTag, $limit);
  602. $sessionsBlocks = $this->getFormatedSessionsBlock($sessions);
  603. $tpl = new Template();
  604. $tpl->assign('show_courses', CoursesAndSessionsCatalog::showCourses());
  605. $tpl->assign('show_sessions', CoursesAndSessionsCatalog::showSessions());
  606. $tpl->assign('show_tutor', (api_get_setting('show_session_coach')==='true' ? true : false));
  607. $tpl->assign('course_url', $courseUrl);
  608. $tpl->assign('already_subscribed_label', $this->getAlreadyRegisteredInSessionLabel());
  609. $tpl->assign('hidden_links', $hiddenLinks);
  610. $tpl->assign('search_token', Security::get_token());
  611. $tpl->assign('search_date', Security::remove_XSS($searchDate));
  612. $tpl->assign('search_tag', Security::remove_XSS($searchTag));
  613. $tpl->assign('sessions', $sessionsBlocks);
  614. $contentTemplate = $tpl->get_template('auth/session_catalog.tpl');
  615. $tpl->display($contentTemplate);
  616. }
  617. /**
  618. * Show the Session Catalogue with filtered session by a query term
  619. * @param array $limit
  620. */
  621. public function sessionListBySearch(array $limit)
  622. {
  623. $q = isset($_REQUEST['q']) ? Security::remove_XSS($_REQUEST['q']) : null;
  624. $hiddenLinks = isset($_GET['hidden_links']) ? intval($_GET['hidden_links']) == 1 : false;
  625. $courseUrl = CourseCategory::getCourseCategoryUrl(1, $limit['length'], null, 0, 'subscribe');
  626. $searchDate = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
  627. $sessions = $this->model->browseSessionsBySearch($q, $limit);
  628. $sessionsBlocks = $this->getFormatedSessionsBlock($sessions);
  629. $tpl = new Template();
  630. $tpl->assign('show_courses', CoursesAndSessionsCatalog::showCourses());
  631. $tpl->assign('show_sessions', CoursesAndSessionsCatalog::showSessions());
  632. $tpl->assign('show_tutor', (api_get_setting('show_session_coach')==='true' ? true : false));
  633. $tpl->assign('course_url', $courseUrl);
  634. $tpl->assign('already_subscribed_label', $this->getAlreadyRegisteredInSessionLabel());
  635. $tpl->assign('hidden_links', $hiddenLinks);
  636. $tpl->assign('search_token', Security::get_token());
  637. $tpl->assign('search_date', Security::remove_XSS($searchDate));
  638. $tpl->assign('search_tag', Security::remove_XSS($q));
  639. $tpl->assign('sessions', $sessionsBlocks);
  640. $contentTemplate = $tpl->get_template('auth/session_catalog.tpl');
  641. $tpl->display($contentTemplate);
  642. }
  643. /**
  644. * Get the formated data for sessions block to be displayed on Session Catalog page
  645. * @param array $sessions The session list
  646. * @return array
  647. */
  648. private function getFormatedSessionsBlock(array $sessions)
  649. {
  650. $extraFieldValue = new ExtraFieldValue('session');
  651. $userId = api_get_user_id();
  652. $sessionsBlocks = [];
  653. $entityManager = Database::getManager();
  654. $sessionRelCourseRepo = $entityManager->getRepository('ChamiloCoreBundle:SessionRelCourse');
  655. $extraFieldRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraField');
  656. $extraFieldRelTagRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
  657. $tagsField = $extraFieldRepo->findOneBy([
  658. 'extraFieldType' => Chamilo\CoreBundle\Entity\ExtraField::COURSE_FIELD_TYPE,
  659. 'variable' => 'tags',
  660. ]);
  661. /** @var \Chamilo\CoreBundle\Entity\Session $session */
  662. foreach ($sessions as $session) {
  663. $sessionDates = SessionManager::parseSessionDates([
  664. 'display_start_date' => $session->getDisplayStartDate(),
  665. 'display_end_date' => $session->getDisplayEndDate(),
  666. 'access_start_date' => $session->getAccessStartDate(),
  667. 'access_end_date' => $session->getAccessEndDate(),
  668. 'coach_access_start_date' => $session->getCoachAccessStartDate(),
  669. 'coach_access_end_date' => $session->getCoachAccessEndDate(),
  670. ]);
  671. $imageField = $extraFieldValue->get_values_by_handler_and_field_variable($session->getId(), 'image');
  672. $sessionCourseTags = [];
  673. if (!is_null($tagsField)) {
  674. $sessionRelCourses = $sessionRelCourseRepo->findBy([
  675. 'session' => $session,
  676. ]);
  677. foreach ($sessionRelCourses as $sessionRelCourse) {
  678. $courseTags = $extraFieldRelTagRepo->getTags(
  679. $tagsField,
  680. $sessionRelCourse->getCourse()->getId()
  681. );
  682. foreach ($courseTags as $tag) {
  683. $sessionCourseTags[] = $tag->getTag();
  684. }
  685. }
  686. }
  687. if (!empty($sessionCourseTags)) {
  688. $sessionCourseTags = array_unique($sessionCourseTags);
  689. }
  690. $repo = $entityManager->getRepository('ChamiloCoreBundle:SequenceResource');
  691. $sequences = $repo->getRequirementsAndDependenciesWithinSequences(
  692. $session->getId(),
  693. SequenceResource::SESSION_TYPE
  694. );
  695. $hasRequirements = false;
  696. foreach ($sequences['sequences'] as $sequence) {
  697. if (count($sequence['requirements']) === 0) {
  698. continue;
  699. }
  700. $hasRequirements = true;
  701. break;
  702. }
  703. $cat = $session->getCategory();
  704. if (empty($cat)) {
  705. $cat = null;
  706. $catName = '';
  707. } else {
  708. $catName = $cat->getName();
  709. }
  710. $coachId = $session->getGeneralCoach()->getId();
  711. $coachName = $session->getGeneralCoach()->getCompleteName();
  712. $actions = null;
  713. if (api_is_platform_admin()) {
  714. $actions = api_get_path(WEB_CODE_PATH) .'session/resume_session.php?id_session='.$session->getId();
  715. }
  716. $isThisSessionOnSale = $session->getBuyCoursePluginPrice();
  717. $sessionsBlock = array(
  718. 'id' => $session->getId(),
  719. 'name' => $session->getName(),
  720. 'image' => isset($imageField['value']) ? $imageField['value'] : null,
  721. 'nbr_courses' => $session->getNbrCourses(),
  722. 'nbr_users' => $session->getNbrUsers(),
  723. 'coach_id' => $coachId,
  724. 'coach_url' => api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&user_id=' . $coachId,
  725. 'coach_name' => $coachName,
  726. 'coach_avatar' => UserManager::getUserPicture($coachId, USER_IMAGE_SIZE_SMALL),
  727. 'is_subscribed' => SessionManager::isUserSubscribedAsStudent($session->getId(), $userId),
  728. 'icon' => $this->getSessionIcon($session->getName()),
  729. 'date' => $sessionDates['display'],
  730. 'price' => $isThisSessionOnSale['html'],
  731. 'subscribe_button' => isset($isThisSessionOnSale['buy_button']) ? $isThisSessionOnSale['buy_button'] : $this->getRegisteredInSessionButton(
  732. $session->getId(),
  733. $session->getName(),
  734. $hasRequirements
  735. ),
  736. 'show_description' => $session->getShowDescription(),
  737. 'description' => $session->getDescription(),
  738. 'category' => $catName,
  739. 'tags' => $sessionCourseTags,
  740. 'edit_actions' => $actions
  741. );
  742. $sessionsBlock = array_merge($sessionsBlock, $sequences);
  743. $sessionsBlocks[] = $sessionsBlock;
  744. }
  745. return $sessionsBlocks;
  746. }
  747. }