courses_controller.php 33 KB

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