courses_controller.php 33 KB

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