Rest.php 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\Course;
  4. use Chamilo\CoreBundle\Entity\ExtraFieldValues;
  5. use Chamilo\CourseBundle\Entity\Repository\CAnnouncementRepository;
  6. use Chamilo\CourseBundle\Entity\Repository\CNotebookRepository;
  7. use Chamilo\CourseBundle\Entity\CLpCategory;
  8. use Chamilo\CoreBundle\Entity\Session;
  9. use Chamilo\UserBundle\Entity\User;
  10. use Chamilo\CourseBundle\Entity\CNotebook;
  11. /**
  12. * Class RestApi
  13. */
  14. class Rest extends WebService
  15. {
  16. const SERVIVE_NAME = 'MsgREST';
  17. const EXTRA_FIELD_GCM_REGISTRATION = 'gcm_registration_id';
  18. const GET_AUTH = 'authenticate';
  19. const GET_USER_MESSAGES = 'user_messages';
  20. const SAVE_GCM_ID = 'gcm_id';
  21. const GET_USER_COURSES = 'user_courses';
  22. const GET_PROFILE = 'user_profile';
  23. const GET_COURSE_INFO = 'course_info';
  24. const GET_COURSE_DESCRIPTIONS = 'course_descriptions';
  25. const GET_COURSE_DOCUMENTS = 'course_documents';
  26. const GET_COURSE_ANNOUNCEMENTS = 'course_announcements';
  27. const GET_COURSE_ANNOUNCEMENT = 'course_announcement';
  28. const GET_COURSE_AGENDA = 'course_agenda';
  29. const GET_COURSE_NOTEBOOKS = 'course_notebooks';
  30. const GET_COURSE_FORUM_CATEGORIES = 'course_forumcategories';
  31. const GET_COURSE_FORUM = 'course_forum';
  32. const GET_COURSE_FORUM_THREAD = 'course_forumthread';
  33. const GET_COURSE_LEARNPATHS = 'course_learnpaths';
  34. const GET_COURSE_LEARNPATH = 'course_learnpath';
  35. const SAVE_FORUM_POST = 'save_forum_post';
  36. const GET_USER_SESSIONS = 'user_sessions';
  37. const SAVE_USER_MESSAGE = 'save_user_message';
  38. const GET_MESSAGE_USERS = 'message_users';
  39. const SAVE_COURSE_NOTEBOOK = 'save_course_notebook';
  40. const SAVE_FORUM_THREAD = 'save_forum_thread';
  41. const EXTRAFIELD_GCM_ID = 'gcm_registration_id';
  42. /**
  43. * @var Session
  44. */
  45. private $session;
  46. /**
  47. * @var Course
  48. */
  49. private $course;
  50. /**
  51. * Rest constructor.
  52. * @param string $username
  53. * @param string $apiKey
  54. */
  55. public function __construct($username, $apiKey)
  56. {
  57. parent::__construct($username, $apiKey);
  58. }
  59. /**
  60. * Set the current course
  61. * @param int $id
  62. * @throws Exception
  63. */
  64. public function setCourse($id)
  65. {
  66. if (!$id) {
  67. $this->course = null;
  68. return;
  69. }
  70. $em = Database::getManager();
  71. /** @var Course $course */
  72. $course = $em->find('ChamiloCoreBundle:Course', $id);
  73. if (!$course) {
  74. throw new Exception(get_lang('NoCourse'));
  75. }
  76. $this->course = $course;
  77. }
  78. /** Set the current session
  79. * @param int $id
  80. * @throws Exception
  81. */
  82. public function setSession($id)
  83. {
  84. if (!$id) {
  85. $this->session = null;
  86. return;
  87. }
  88. $em = Database::getManager();
  89. /** @var Session $session */
  90. $session = $em->find('ChamiloCoreBundle:Session', $id);
  91. if (!$session) {
  92. throw new Exception(get_lang('NoSession'));
  93. }
  94. $this->session = $session;
  95. }
  96. /**
  97. * @param string $username
  98. * @param string $apiKeyToValidate
  99. * @return Rest
  100. * @throws Exception
  101. */
  102. public static function validate($username, $apiKeyToValidate)
  103. {
  104. $apiKey = self::findUserApiKey($username, self::SERVIVE_NAME);
  105. if ($apiKey != $apiKeyToValidate) {
  106. throw new Exception(get_lang('InvalidApiKey'));
  107. }
  108. return new self($username, $apiKey);
  109. }
  110. /**
  111. * Create the gcm_registration_id extra field for users
  112. */
  113. public static function init()
  114. {
  115. $extraField = new ExtraField('user');
  116. $fieldInfo = $extraField->get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION);
  117. if (empty($fieldInfo)) {
  118. $extraField->save([
  119. 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
  120. 'field_type' => ExtraField::FIELD_TYPE_TEXT,
  121. 'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION
  122. ]);
  123. }
  124. }
  125. /**
  126. * @param string $registrationId
  127. * @return bool
  128. */
  129. public function setGcmId($registrationId)
  130. {
  131. $registrationId = Security::remove_XSS($registrationId);
  132. $extraFieldValue = new ExtraFieldValue('user');
  133. return $extraFieldValue->save([
  134. 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
  135. 'value' => $registrationId,
  136. 'item_id' => $this->user->getId()
  137. ]);
  138. }
  139. /**
  140. * @param int $lastMessageId
  141. * @return array
  142. */
  143. public function getUserMessages($lastMessageId = 0)
  144. {
  145. $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId);
  146. $messages = [];
  147. foreach ($lastMessages as $message) {
  148. $hasAttachments = MessageManager::hasAttachments($message['id']);
  149. $messages[] = array(
  150. 'id' => $message['id'],
  151. 'title' => $message['title'],
  152. 'sender' => array(
  153. 'id' => $message['user_id'],
  154. 'lastname' => $message['lastname'],
  155. 'firstname' => $message['firstname'],
  156. 'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
  157. ),
  158. 'sendDate' => $message['send_date'],
  159. 'content' => $message['content'],
  160. 'hasAttachments' => $hasAttachments,
  161. 'url' => ''
  162. );
  163. }
  164. return $messages;
  165. }
  166. /**
  167. * Get the user courses
  168. * @return array
  169. */
  170. public function getUserCourses()
  171. {
  172. $courses = CourseManager::get_courses_list_by_user_id($this->user->getId());
  173. $data = [];
  174. foreach ($courses as $courseId) {
  175. /** @var Course $course */
  176. $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId['real_id']);
  177. $teachers = CourseManager::get_teacher_list_from_course_code_to_string($course->getCode());
  178. $data[] = [
  179. 'id' => $course->getId(),
  180. 'title' => $course->getTitle(),
  181. 'code' => $course->getCode(),
  182. 'directory' => $course->getDirectory(),
  183. 'urlPicture' => $course->getPicturePath(true),
  184. 'teachers' => $teachers
  185. ];
  186. }
  187. return $data;
  188. }
  189. /**
  190. * @return array
  191. * @throws Exception
  192. */
  193. public function getCourseInfo()
  194. {
  195. $teachers = CourseManager::get_teacher_list_from_course_code_to_string($this->course->getCode());
  196. $tools = CourseHome::get_tools_category(
  197. TOOL_STUDENT_VIEW,
  198. $this->course->getId(),
  199. $this->session ? $this->session->getId() : 0
  200. );
  201. return [
  202. 'id' => $this->course->getId(),
  203. 'title' => $this->course->getTitle(),
  204. 'code' => $this->course->getCode(),
  205. 'directory' => $this->course->getDirectory(),
  206. 'urlPicture' => $this->course->getPicturePath(true),
  207. 'teachers' => $teachers,
  208. 'tools' => array_map(
  209. function($tool) {
  210. return ['type' => $tool['name']];
  211. },
  212. $tools
  213. )
  214. ];
  215. }
  216. /**
  217. * Get the course descriptions
  218. * @return array
  219. * @throws Exception
  220. */
  221. public function getCourseDescriptions()
  222. {
  223. $descriptions = CourseDescription::get_descriptions($this->course->getId());
  224. $results = [];
  225. /** @var CourseDescription $description */
  226. foreach ($descriptions as $description) {
  227. $results[] = [
  228. 'id' => $description->get_description_type(),
  229. 'title' => $description->get_title(),
  230. 'content' => str_replace('src="/', 'src="'.api_get_path(WEB_PATH), $description->get_content())
  231. ];
  232. }
  233. return $results;
  234. }
  235. /**
  236. * @param int $directoryId
  237. * @return array
  238. * @throws Exception
  239. */
  240. public function getCourseDocuments($directoryId = 0)
  241. {
  242. /** @var string $path */
  243. $path = '/';
  244. $sessionId = $this->session ? $this->session->getId() : 0;
  245. if ($directoryId) {
  246. $directory = DocumentManager::get_document_data_by_id(
  247. $directoryId,
  248. $this->course->getCode(),
  249. false,
  250. $sessionId
  251. );
  252. if (!$directory) {
  253. throw new Exception('NoDataAvailable');
  254. }
  255. $path = $directory['path'];
  256. }
  257. require_once api_get_path(LIBRARY_PATH).'fileDisplay.lib.php';
  258. $courseInfo = api_get_course_info_by_id($this->course->getId());
  259. $documents = DocumentManager::get_all_document_data(
  260. $courseInfo,
  261. $path,
  262. 0,
  263. null,
  264. false,
  265. false,
  266. $sessionId
  267. );
  268. $results = [];
  269. if (is_array($documents)) {
  270. $webPath = api_get_path(WEB_CODE_PATH).'document/document.php?';
  271. /** @var array $document */
  272. foreach ($documents as $document) {
  273. if ($document['visibility'] != '1') {
  274. continue;
  275. }
  276. $icon = $document['filetype'] == 'file'
  277. ? choose_image($document['path'])
  278. : chooseFolderIcon($document['path']);
  279. $results[] = [
  280. 'id' => $document['id'],
  281. 'type' => $document['filetype'],
  282. 'title' => $document['title'],
  283. 'path' => $document['path'],
  284. 'url' => $webPath.http_build_query([
  285. 'username' => $this->user->getUsername(),
  286. 'api_key' => $this->apiKey,
  287. 'cidReq' => $this->course->getCode(),
  288. 'id_session' => $sessionId,
  289. 'gidReq' => 0,
  290. 'gradebook' => 0,
  291. 'origin' => '',
  292. 'action' => 'download',
  293. 'id' => $document['id']
  294. ]),
  295. 'icon' => $icon,
  296. 'size' => format_file_size($document['size'])
  297. ];
  298. }
  299. }
  300. return $results;
  301. }
  302. /**
  303. * @param int $courseId
  304. * @return array
  305. * @throws Exception
  306. */
  307. public function getCourseAnnouncements()
  308. {
  309. $sessionId = $this->session ? $this->session->getId() : 0;
  310. $announcements = AnnouncementManager::getAnnouncements(
  311. null,
  312. null,
  313. false,
  314. null,
  315. null,
  316. null,
  317. null,
  318. null,
  319. 0,
  320. $this->user->getId(),
  321. $this->course->getId(),
  322. $sessionId
  323. );
  324. $announcements = array_map(function($announcement) {
  325. return [
  326. 'id' => intval($announcement['id']),
  327. 'title' => strip_tags($announcement['title']),
  328. 'creatorName' => strip_tags($announcement['username']),
  329. 'date' => strip_tags($announcement['insert_date'])
  330. ];
  331. }, $announcements);
  332. return $announcements;
  333. }
  334. /**
  335. * @param int $announcementId
  336. * @return array
  337. * @throws Exception
  338. */
  339. public function getCourseAnnouncement($announcementId)
  340. {
  341. $sessionId = $this->session ? $this->session->getId() : 0;
  342. $announcement = AnnouncementManager::getAnnouncementInfoById(
  343. $announcementId,
  344. $this->course->getId(),
  345. $this->user->getId()
  346. );
  347. if (!$announcement) {
  348. throw new Exception(get_lang('NoAnnouncement'));
  349. }
  350. return [
  351. 'id' => intval($announcement['announcement']->getIid()),
  352. 'title' => $announcement['announcement']->getTitle(),
  353. 'creatorName' => $announcement['item_property']->getInsertUser()->getCompleteName(),
  354. 'date' => api_convert_and_format_date($announcement['item_property']->getInsertDate(), DATE_TIME_FORMAT_LONG_24H),
  355. 'content' => AnnouncementManager::parse_content(
  356. $this->user->getId(),
  357. $announcement['announcement']->getContent(),
  358. $this->course->getCode(),
  359. $sessionId
  360. )
  361. ];
  362. }
  363. /**
  364. * @return array
  365. * @throws Exception
  366. */
  367. public function getCourseAgenda()
  368. {
  369. $sessionId = $this->session ? $this->session->getId() : 0;
  370. $agenda = new Agenda(
  371. 'course',
  372. $this->user->getId(),
  373. $this->course->getId(),
  374. $sessionId
  375. );
  376. $result = $agenda->parseAgendaFilter(null);
  377. $start = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
  378. $start->modify('first day of this month');
  379. $start->setTime(0, 0, 0);
  380. $end = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
  381. $end->modify('last day of this month');
  382. $end->setTime(23, 59, 59);
  383. $groupId = current($result['groups']);
  384. $userId = current($result['users']);
  385. $events = $agenda->getEvents(
  386. $start->getTimestamp(),
  387. $end->getTimestamp(),
  388. $this->course->getId(),
  389. $groupId,
  390. $userId,
  391. 'array'
  392. );
  393. if (!is_array($events)) {
  394. return [];
  395. }
  396. $webPath = api_get_path(WEB_PATH);
  397. return array_map(
  398. function($event) use ($webPath) {
  399. return [
  400. 'id' => intval($event['unique_id']),
  401. 'title' => $event['title'],
  402. 'content' => str_replace('src="/', 'src="'.$webPath, $event['description']),
  403. 'startDate' => $event['start_date_localtime'],
  404. 'endDate' => $event['end_date_localtime'],
  405. 'isAllDay' => $event['allDay'] ? true : false
  406. ];
  407. },
  408. $events
  409. );
  410. }
  411. /**
  412. * @return array
  413. * @throws Exception
  414. */
  415. public function getCourseNotebooks()
  416. {
  417. $em = Database::getManager();
  418. /** @var CNotebookRepository $notebooksRepo */
  419. $notebooksRepo = $em->getRepository('ChamiloCourseBundle:CNotebook');
  420. $notebooks = $notebooksRepo->findByUser($this->user, $this->course, $this->session);
  421. return array_map(
  422. function (CNotebook $notebook) {
  423. return [
  424. 'id' => $notebook->getIid(),
  425. 'title' => $notebook->getTitle(),
  426. 'description' => $notebook->getDescription(),
  427. 'creationDate' => api_format_date(
  428. $notebook->getCreationDate()->getTimestamp()
  429. ),
  430. 'updateDate' => api_format_date(
  431. $notebook->getUpdateDate()->getTimestamp()
  432. )
  433. ];
  434. },
  435. $notebooks
  436. );
  437. }
  438. /**
  439. * @return array
  440. * @throws Exception
  441. */
  442. public function getCourseForumCategories()
  443. {
  444. $sessionId = $this->session ? $this->session->getId() : 0;
  445. $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
  446. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  447. $categoriesFullData = get_forum_categories('', $this->course->getId(), $sessionId);
  448. $categories = [];
  449. $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true';
  450. $forumsFullData = get_forums('', $this->course->getCode(), $includeGroupsForums, $sessionId);
  451. $forums = [];
  452. foreach ($forumsFullData as $forumId => $forumInfo) {
  453. $forum = [
  454. 'id' => intval($forumInfo['iid']),
  455. 'catId' => intval($forumInfo['forum_category']),
  456. 'title' => $forumInfo['forum_title'],
  457. 'description' => $forumInfo['forum_comment'],
  458. 'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
  459. 'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval($forumInfo['number_of_threads']) : 0,
  460. 'lastPost' => null
  461. ];
  462. $lastPostInfo = get_last_post_information($forumId, false, $this->course->getId(), $sessionId);
  463. if ($lastPostInfo) {
  464. $forum['lastPost'] = [
  465. 'date' => api_convert_and_format_date($lastPostInfo['last_post_date']),
  466. 'user' => api_get_person_name(
  467. $lastPostInfo['last_poster_firstname'],
  468. $lastPostInfo['last_poster_lastname']
  469. )
  470. ];
  471. }
  472. $forums[] = $forum;
  473. }
  474. foreach ($categoriesFullData as $category) {
  475. $categoryForums = array_filter(
  476. $forums,
  477. function(array $forum) use ($category) {
  478. if ($forum['catId'] != $category['cat_id']) {
  479. return false;
  480. }
  481. return true;
  482. }
  483. );
  484. $categories[] = [
  485. 'id' => intval($category['iid']),
  486. 'title' => $category['cat_title'],
  487. 'catId' => intval($category['cat_id']),
  488. 'description' => $category['cat_comment'],
  489. 'forums' => $categoryForums,
  490. 'courseId' => $this->course->getId()
  491. ];
  492. }
  493. return $categories;
  494. }
  495. /**
  496. * @param int $forumId
  497. * @return array
  498. * @throws Exception
  499. */
  500. public function getCourseForum($forumId)
  501. {
  502. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  503. $sessionId = $this->session ? $this->session->getId() : 0;
  504. $forumInfo = get_forums($forumId, $this->course->getCode(), true, $sessionId);
  505. if (!isset($forumInfo['iid'])) {
  506. throw new Exception(get_lang('NoForum'));
  507. }
  508. $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
  509. $forum = [
  510. 'id' => $forumInfo['iid'],
  511. 'title' => $forumInfo['forum_title'],
  512. 'description' => $forumInfo['forum_comment'],
  513. 'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
  514. 'threads' => []
  515. ];
  516. $threads = get_threads($forumInfo['iid'], $this->course->getId(), $sessionId);
  517. foreach ($threads as $thread) {
  518. $forum['threads'][] = [
  519. 'id' => $thread['iid'],
  520. 'title' => $thread['thread_title'],
  521. 'lastEditDate' => api_convert_and_format_date($thread['lastedit_date'], DATE_TIME_FORMAT_LONG_24H),
  522. 'numberOfReplies' => $thread['thread_replies'],
  523. 'numberOfViews' => $thread['thread_views'],
  524. 'author' => api_get_person_name($thread['firstname'], $thread['lastname'])
  525. ];
  526. }
  527. return $forum;
  528. }
  529. /**
  530. * @param int $forumId
  531. * @param int $threadId
  532. * @return array
  533. */
  534. public function getCourseForumThread($forumId, $threadId)
  535. {
  536. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  537. $sessionId = $this->session ? $this->session->getId() : 0;
  538. $threadInfo = get_thread_information($forumId, $threadId, $sessionId);
  539. $thread = [
  540. 'id' => intval($threadInfo['iid']),
  541. 'cId' => intval($threadInfo['c_id']),
  542. 'title' => $threadInfo['thread_title'],
  543. 'forumId' => intval($threadInfo['forum_id']),
  544. 'posts' => []
  545. ];
  546. $forumInfo = get_forums($threadInfo['forum_id'], $this->course->getCode(), true, $sessionId);
  547. $postsInfo = getPosts($forumInfo, $threadInfo['iid'], 'ASC');
  548. foreach ($postsInfo as $postInfo) {
  549. $thread['posts'][] = [
  550. 'id' => $postInfo['iid'],
  551. 'title' => $postInfo['post_title'],
  552. 'text' => $postInfo['post_text'],
  553. 'author' => api_get_person_name($postInfo['firstname'], $postInfo['lastname']),
  554. 'date' => api_convert_and_format_date($postInfo['post_date'], DATE_TIME_FORMAT_LONG_24H),
  555. 'parentId' => $postInfo['post_parent_id']
  556. ];
  557. }
  558. return $thread;
  559. }
  560. /**
  561. * @return array
  562. */
  563. public function getUserProfile()
  564. {
  565. $pictureInfo = UserManager::get_user_picture_path_by_id($this->user->getId(), 'web');
  566. $result = [
  567. 'pictureUri' => $pictureInfo['dir'].$pictureInfo['file'],
  568. 'fullName' => $this->user->getCompleteName(),
  569. 'username' => $this->user->getUsername(),
  570. 'officialCode' => $this->user->getOfficialCode(),
  571. 'phone' => $this->user->getPhone(),
  572. 'extra' => []
  573. ];
  574. $fieldValue = new ExtraFieldValue('user');
  575. $extraInfo = $fieldValue->getAllValuesForAnItem($this->user->getId(), true);
  576. foreach ($extraInfo as $extra) {
  577. /** @var ExtraFieldValues $extraValue */
  578. $extraValue = $extra['value'];
  579. $result['extra'][] = [
  580. 'title' => $extraValue->getField()->getDisplayText(true),
  581. 'value' => $extraValue->getValue()
  582. ];
  583. }
  584. return $result;
  585. }
  586. /**
  587. * @return array
  588. * @throws Exception
  589. */
  590. public function getCourseLearnPaths()
  591. {
  592. $sessionId = $this->session ? $this->session->getId() : 0;
  593. $categoriesTempList = learnpath::getCategories($this->course->getId());
  594. $categoryNone = new CLpCategory();
  595. $categoryNone->setId(0);
  596. $categoryNone->setName(get_lang('WithOutCategory'));
  597. $categoryNone->setPosition(0);
  598. $categories = array_merge([$categoryNone], $categoriesTempList);
  599. $categoryData = array();
  600. /** @var CLpCategory $category */
  601. foreach ($categories as $category) {
  602. $learnPathList = new LearnpathList(
  603. $this->user->getId(),
  604. $this->course->getCode(),
  605. $sessionId,
  606. null,
  607. false,
  608. $category->getId()
  609. );
  610. $flatLpList = $learnPathList->get_flat_list();
  611. if (empty($flatLpList)) {
  612. continue;
  613. }
  614. $listData = array();
  615. foreach ($flatLpList as $lpId => $lpDetails) {
  616. if ($lpDetails['lp_visibility'] == 0) {
  617. continue;
  618. }
  619. if (!learnpath::is_lp_visible_for_student(
  620. $lpId,
  621. $this->user->getId(),
  622. $this->course->getCode(),
  623. $sessionId
  624. )) {
  625. continue;
  626. }
  627. $timeLimits = false;
  628. //This is an old LP (from a migration 1.8.7) so we do nothing
  629. if (empty($lpDetails['created_on']) && empty($lpDetails['modified_on'])) {
  630. $timeLimits = false;
  631. }
  632. //Checking if expired_on is ON
  633. if (!empty($lpDetails['expired_on'])) {
  634. $timeLimits = true;
  635. }
  636. if ($timeLimits) {
  637. if (!empty($lpDetails['publicated_on']) && !empty($lpDetails['expired_on'])) {
  638. $startTime = api_strtotime($lpDetails['publicated_on'], 'UTC');
  639. $endTime = api_strtotime($lpDetails['expired_on'], 'UTC');
  640. $now = time();
  641. $isActivedTime = false;
  642. if ($now > $startTime && $endTime > $now) {
  643. $isActivedTime = true;
  644. }
  645. if (!$isActivedTime) {
  646. continue;
  647. }
  648. }
  649. }
  650. $progress = learnpath::getProgress($lpId, $this->user->getId(), $this->course->getId(), $sessionId);
  651. $listData[] = array(
  652. 'id' => $lpId,
  653. 'title' => Security::remove_XSS($lpDetails['lp_name']),
  654. 'progress' => intval($progress),
  655. 'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query([
  656. 'hash' => $this->encodeParams([
  657. 'action' => 'course_learnpath',
  658. 'lp_id' => $lpId,
  659. 'course' => $this->course->getId(),
  660. 'session' => $sessionId
  661. ])
  662. ])
  663. );
  664. }
  665. if (empty($listData)) {
  666. continue;
  667. }
  668. $categoryData[] = array(
  669. 'id' => $category->getId(),
  670. 'name' => $category->getName(),
  671. 'learnpaths' => $listData
  672. );
  673. }
  674. return $categoryData;
  675. }
  676. /**
  677. * @param array $additionalParams Optional
  678. * @return string
  679. */
  680. private function encodeParams(array $additionalParams = [])
  681. {
  682. $params = array_merge($additionalParams, [
  683. 'api_key' => $this->apiKey,
  684. 'username' => $this->user->getUsername(),
  685. ]);
  686. $strParams = serialize($params);
  687. $b64Encoded = base64_encode($strParams);
  688. return str_replace(['+', '/', '='], ['-', '_', '.'], $b64Encoded);
  689. }
  690. /**
  691. * @param string $encoded
  692. * @return array
  693. */
  694. public static function decodeParams($encoded) {
  695. $decoded = str_replace(['-', '_', '.'], ['+', '/', '='], $encoded);
  696. $mod4 = strlen($decoded) % 4;
  697. if ($mod4) {
  698. $decoded .= substr('====', $mod4);
  699. }
  700. $b64Decoded = base64_decode($decoded);
  701. return unserialize($b64Decoded);
  702. }
  703. /**
  704. * Start login for a user. Then make a redirect to show the learnpath
  705. * @param int $lpId
  706. */
  707. public function showLearningPath($lpId)
  708. {
  709. $loggedUser['user_id'] = $this->user->getId();
  710. $loggedUser['status'] = $this->user->getStatus();
  711. $loggedUser['uidReset'] = true;
  712. $sessionId = $this->session ? $this->session->getId() : 0;
  713. ChamiloSession::write('_user', $loggedUser);
  714. Login::init_user($this->user->getId(), true);
  715. $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query([
  716. 'cidReq' => $this->course->getCode(),
  717. 'id_session' => $sessionId,
  718. 'gidReq' => 0,
  719. 'gradebook' => 0,
  720. 'origin' => '',
  721. 'action' => 'view',
  722. 'lp_id' => intval($lpId),
  723. 'isStudentView' => 'true'
  724. ]);
  725. header("Location: $url");
  726. exit;
  727. }
  728. /**
  729. * @param array $postValues
  730. * @param int $forumId
  731. * @return array
  732. */
  733. public function saveForumPost(array $postValues, $forumId)
  734. {
  735. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  736. $forum = get_forums($forumId, $this->course->getCode());
  737. store_reply($forum, $postValues, $this->course->getId(), $this->user->getId());
  738. return [
  739. 'registered' => true
  740. ];
  741. }
  742. /**
  743. * Get the list of sessions for current user
  744. * @return array the sessions list
  745. */
  746. public function getUserSessions()
  747. {
  748. $data = [];
  749. $sessionsByCategory = UserManager::get_sessions_by_category($this->user->getId(), false);
  750. foreach ($sessionsByCategory as $category) {
  751. $categorySessions = [];
  752. foreach ($category['sessions'] as $sessions) {
  753. $sessionCourses = [];
  754. foreach ($sessions['courses'] as $course) {
  755. $courseInfo = api_get_course_info_by_id($course['real_id']);
  756. $teachers = SessionManager::getCoachesByCourseSessionToString(
  757. $sessions['session_id'],
  758. $course['real_id']
  759. );
  760. $sessionCourses[] = [
  761. 'id' => $courseInfo['real_id'],
  762. 'title' => $courseInfo['title'],
  763. 'code' => $courseInfo['code'],
  764. 'directory' => $courseInfo['directory'],
  765. 'pictureUrl' => $courseInfo['course_image_large'],
  766. 'teachers' => $teachers
  767. ];
  768. }
  769. $sessionBox = Display::get_session_title_box($sessions['session_id']);
  770. $categorySessions[] = [
  771. 'name' => $sessionBox['title'],
  772. 'id' => $sessions['session_id'],
  773. 'date' => $sessionBox['dates'],
  774. 'duration' => isset($sessionBox['duration']) ? $sessionBox['duration'] : null,
  775. 'courses' => $sessionCourses
  776. ];
  777. }
  778. $data[] = [
  779. 'id' => $category['session_category']['id'],
  780. 'name' => $category['session_category']['name'],
  781. 'sessions' => $categorySessions
  782. ];
  783. }
  784. return $data;
  785. }
  786. /**
  787. * @param string $subject
  788. * @param string $text
  789. * @param array $receivers
  790. * @return array
  791. */
  792. public function saveUserMessage($subject, $text, array $receivers)
  793. {
  794. foreach ($receivers as $userId) {
  795. MessageManager::send_message($userId, $subject, $text);
  796. }
  797. return [
  798. 'sent' => true
  799. ];
  800. }
  801. /**
  802. * @param string $search
  803. * @return array
  804. */
  805. public function getMessageUsers($search)
  806. {
  807. /** @var UserRepository $repo */
  808. $repo = Database::getManager()
  809. ->getRepository('ChamiloUserBundle:User');
  810. $users = $repo->findUsersToSendMessage($this->user->getId(), $search);
  811. $showEmail = api_get_setting('show_email_addresses') === 'true';
  812. $data = [];
  813. /** @var User $user */
  814. foreach ($users as $user) {
  815. $userName = $user->getCompleteName();
  816. if ($showEmail) {
  817. $userName .= " ({$user->getEmail()})";
  818. }
  819. $data[] = [
  820. 'id' => $user->getId(),
  821. 'name' => $userName,
  822. ];
  823. }
  824. return $data;
  825. }
  826. /**
  827. * @param string $title
  828. * @param string $text
  829. * @return bool
  830. */
  831. public function saveCourseNotebook($title, $text)
  832. {
  833. $values = ['note_title' => $title, 'note_comment' => $text];
  834. $sessionId = $this->session ? $this->session->getId() : 0;
  835. $noteBookId = NotebookManager::save_note(
  836. $values,
  837. $this->user->getId(),
  838. $this->course->getId(),
  839. $sessionId
  840. );
  841. return [
  842. 'registered' => $noteBookId
  843. ];
  844. }
  845. /**
  846. * @param array $values
  847. * @param int $forumId
  848. * @return array
  849. */
  850. public function saveForumThread(array $values, $forumId)
  851. {
  852. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  853. $sessionId = $this->session ? $this->session->getId() : 0;
  854. $forum = get_forums($forumId, $this->course->getCode(), true, $sessionId);
  855. $courseInfo = api_get_course_info($this->course->getCode());
  856. $id = store_thread($forum, $values, $courseInfo, false, $this->user->getId(), $sessionId);
  857. return [
  858. 'registered' => $id
  859. ];
  860. }
  861. }