Rest.php 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  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 SAVE_COURSE = 'save_course';
  42. const SAVE_USER = 'save_user';
  43. const SUBSCRIBE_USER_TO_COURSE = 'subscribe_user_to_course';
  44. const EXTRAFIELD_GCM_ID = 'gcm_registration_id';
  45. /**
  46. * @var Session
  47. */
  48. private $session;
  49. /**
  50. * @var Course
  51. */
  52. private $course;
  53. /**
  54. * Rest constructor.
  55. * @param string $username
  56. * @param string $apiKey
  57. */
  58. public function __construct($username, $apiKey)
  59. {
  60. parent::__construct($username, $apiKey);
  61. }
  62. /**
  63. * Set the current course
  64. * @param int $id
  65. * @throws Exception
  66. */
  67. public function setCourse($id)
  68. {
  69. if (!$id) {
  70. $this->course = null;
  71. return;
  72. }
  73. $em = Database::getManager();
  74. /** @var Course $course */
  75. $course = $em->find('ChamiloCoreBundle:Course', $id);
  76. if (!$course) {
  77. throw new Exception(get_lang('NoCourse'));
  78. }
  79. $this->course = $course;
  80. }
  81. /** Set the current session
  82. * @param int $id
  83. * @throws Exception
  84. */
  85. public function setSession($id)
  86. {
  87. if (!$id) {
  88. $this->session = null;
  89. return;
  90. }
  91. $em = Database::getManager();
  92. /** @var Session $session */
  93. $session = $em->find('ChamiloCoreBundle:Session', $id);
  94. if (!$session) {
  95. throw new Exception(get_lang('NoSession'));
  96. }
  97. $this->session = $session;
  98. }
  99. /**
  100. * @param string $username
  101. * @param string $apiKeyToValidate
  102. * @return Rest
  103. * @throws Exception
  104. */
  105. public static function validate($username, $apiKeyToValidate)
  106. {
  107. $apiKey = self::findUserApiKey($username, self::SERVIVE_NAME);
  108. if ($apiKey != $apiKeyToValidate) {
  109. throw new Exception(get_lang('InvalidApiKey'));
  110. }
  111. return new self($username, $apiKey);
  112. }
  113. /**
  114. * Create the gcm_registration_id extra field for users
  115. */
  116. public static function init()
  117. {
  118. $extraField = new ExtraField('user');
  119. $fieldInfo = $extraField->get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION);
  120. if (empty($fieldInfo)) {
  121. $extraField->save([
  122. 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
  123. 'field_type' => ExtraField::FIELD_TYPE_TEXT,
  124. 'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION
  125. ]);
  126. }
  127. }
  128. /**
  129. * @param string $registrationId
  130. * @return bool
  131. */
  132. public function setGcmId($registrationId)
  133. {
  134. $registrationId = Security::remove_XSS($registrationId);
  135. $extraFieldValue = new ExtraFieldValue('user');
  136. return $extraFieldValue->save([
  137. 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
  138. 'value' => $registrationId,
  139. 'item_id' => $this->user->getId()
  140. ]);
  141. }
  142. /**
  143. * @param int $lastMessageId
  144. * @return array
  145. */
  146. public function getUserMessages($lastMessageId = 0)
  147. {
  148. $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId);
  149. $messages = [];
  150. foreach ($lastMessages as $message) {
  151. $hasAttachments = MessageManager::hasAttachments($message['id']);
  152. $messages[] = array(
  153. 'id' => $message['id'],
  154. 'title' => $message['title'],
  155. 'sender' => array(
  156. 'id' => $message['user_id'],
  157. 'lastname' => $message['lastname'],
  158. 'firstname' => $message['firstname'],
  159. 'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
  160. ),
  161. 'sendDate' => $message['send_date'],
  162. 'content' => $message['content'],
  163. 'hasAttachments' => $hasAttachments,
  164. 'url' => ''
  165. );
  166. }
  167. return $messages;
  168. }
  169. /**
  170. * Get the user courses
  171. * @return array
  172. */
  173. public function getUserCourses()
  174. {
  175. $courses = CourseManager::get_courses_list_by_user_id($this->user->getId());
  176. $data = [];
  177. foreach ($courses as $courseId) {
  178. /** @var Course $course */
  179. $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId['real_id']);
  180. $teachers = CourseManager::getTeacherListFromCourseCodeToString($course->getCode());
  181. $data[] = [
  182. 'id' => $course->getId(),
  183. 'title' => $course->getTitle(),
  184. 'code' => $course->getCode(),
  185. 'directory' => $course->getDirectory(),
  186. 'urlPicture' => $course->getPicturePath(true),
  187. 'teachers' => $teachers
  188. ];
  189. }
  190. return $data;
  191. }
  192. /**
  193. * @return array
  194. * @throws Exception
  195. */
  196. public function getCourseInfo()
  197. {
  198. $teachers = CourseManager::getTeacherListFromCourseCodeToString($this->course->getCode());
  199. $tools = CourseHome::get_tools_category(
  200. TOOL_STUDENT_VIEW,
  201. $this->course->getId(),
  202. $this->session ? $this->session->getId() : 0
  203. );
  204. return [
  205. 'id' => $this->course->getId(),
  206. 'title' => $this->course->getTitle(),
  207. 'code' => $this->course->getCode(),
  208. 'directory' => $this->course->getDirectory(),
  209. 'urlPicture' => $this->course->getPicturePath(true),
  210. 'teachers' => $teachers,
  211. 'tools' => array_map(
  212. function ($tool) {
  213. return ['type' => $tool['name']];
  214. },
  215. $tools
  216. )
  217. ];
  218. }
  219. /**
  220. * Get the course descriptions
  221. * @return array
  222. * @throws Exception
  223. */
  224. public function getCourseDescriptions()
  225. {
  226. $descriptions = CourseDescription::get_descriptions($this->course->getId());
  227. $results = [];
  228. /** @var CourseDescription $description */
  229. foreach ($descriptions as $description) {
  230. $results[] = [
  231. 'id' => $description->get_description_type(),
  232. 'title' => $description->get_title(),
  233. 'content' => str_replace('src="/', 'src="'.api_get_path(WEB_PATH), $description->get_content())
  234. ];
  235. }
  236. return $results;
  237. }
  238. /**
  239. * @param int $directoryId
  240. * @return array
  241. * @throws Exception
  242. */
  243. public function getCourseDocuments($directoryId = 0)
  244. {
  245. /** @var string $path */
  246. $path = '/';
  247. $sessionId = $this->session ? $this->session->getId() : 0;
  248. if ($directoryId) {
  249. $directory = DocumentManager::get_document_data_by_id(
  250. $directoryId,
  251. $this->course->getCode(),
  252. false,
  253. $sessionId
  254. );
  255. if (!$directory) {
  256. throw new Exception('NoDataAvailable');
  257. }
  258. $path = $directory['path'];
  259. }
  260. $courseInfo = api_get_course_info_by_id($this->course->getId());
  261. $documents = DocumentManager::get_all_document_data(
  262. $courseInfo,
  263. $path,
  264. 0,
  265. null,
  266. false,
  267. false,
  268. $sessionId
  269. );
  270. $results = [];
  271. if (is_array($documents)) {
  272. $webPath = api_get_path(WEB_CODE_PATH).'document/document.php?';
  273. /** @var array $document */
  274. foreach ($documents as $document) {
  275. if ($document['visibility'] != '1') {
  276. continue;
  277. }
  278. $icon = $document['filetype'] == 'file'
  279. ? choose_image($document['path'])
  280. : chooseFolderIcon($document['path']);
  281. $results[] = [
  282. 'id' => $document['id'],
  283. 'type' => $document['filetype'],
  284. 'title' => $document['title'],
  285. 'path' => $document['path'],
  286. 'url' => $webPath.http_build_query([
  287. 'username' => $this->user->getUsername(),
  288. 'api_key' => $this->apiKey,
  289. 'cidReq' => $this->course->getCode(),
  290. 'id_session' => $sessionId,
  291. 'gidReq' => 0,
  292. 'gradebook' => 0,
  293. 'origin' => '',
  294. 'action' => 'download',
  295. 'id' => $document['id']
  296. ]),
  297. 'icon' => $icon,
  298. 'size' => format_file_size($document['size'])
  299. ];
  300. }
  301. }
  302. return $results;
  303. }
  304. /**
  305. * @return array
  306. * @throws Exception
  307. */
  308. public function getCourseAnnouncements()
  309. {
  310. $sessionId = $this->session ? $this->session->getId() : 0;
  311. $announcements = AnnouncementManager::getAnnouncements(
  312. null,
  313. null,
  314. false,
  315. null,
  316. null,
  317. null,
  318. null,
  319. null,
  320. 0,
  321. $this->user->getId(),
  322. $this->course->getId(),
  323. $sessionId
  324. );
  325. $announcements = array_map(
  326. function ($announcement) {
  327. return [
  328. 'id' => intval($announcement['id']),
  329. 'title' => strip_tags($announcement['title']),
  330. 'creatorName' => strip_tags($announcement['username']),
  331. 'date' => strip_tags($announcement['insert_date']),
  332. ];
  333. },
  334. $announcements
  335. );
  336. return $announcements;
  337. }
  338. /**
  339. * @param int $announcementId
  340. * @return array
  341. * @throws Exception
  342. */
  343. public function getCourseAnnouncement($announcementId)
  344. {
  345. $sessionId = $this->session ? $this->session->getId() : 0;
  346. $announcement = AnnouncementManager::getAnnouncementInfoById(
  347. $announcementId,
  348. $this->course->getId(),
  349. $this->user->getId()
  350. );
  351. if (!$announcement) {
  352. throw new Exception(get_lang('NoAnnouncement'));
  353. }
  354. return [
  355. 'id' => intval($announcement['announcement']->getIid()),
  356. 'title' => $announcement['announcement']->getTitle(),
  357. 'creatorName' => $announcement['item_property']->getInsertUser()->getCompleteName(),
  358. 'date' => api_convert_and_format_date(
  359. $announcement['item_property']->getInsertDate(),
  360. DATE_TIME_FORMAT_LONG_24H
  361. ),
  362. 'content' => AnnouncementManager::parse_content(
  363. $this->user->getId(),
  364. $announcement['announcement']->getContent(),
  365. $this->course->getCode(),
  366. $sessionId
  367. )
  368. ];
  369. }
  370. /**
  371. * @return array
  372. * @throws Exception
  373. */
  374. public function getCourseAgenda()
  375. {
  376. $sessionId = $this->session ? $this->session->getId() : 0;
  377. $agenda = new Agenda(
  378. 'course',
  379. $this->user->getId(),
  380. $this->course->getId(),
  381. $sessionId
  382. );
  383. $result = $agenda->parseAgendaFilter(null);
  384. $start = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
  385. $start->modify('first day of this month');
  386. $start->setTime(0, 0, 0);
  387. $end = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
  388. $end->modify('last day of this month');
  389. $end->setTime(23, 59, 59);
  390. $groupId = current($result['groups']);
  391. $userId = current($result['users']);
  392. $events = $agenda->getEvents(
  393. $start->getTimestamp(),
  394. $end->getTimestamp(),
  395. $this->course->getId(),
  396. $groupId,
  397. $userId,
  398. 'array'
  399. );
  400. if (!is_array($events)) {
  401. return [];
  402. }
  403. $webPath = api_get_path(WEB_PATH);
  404. return array_map(
  405. function ($event) use ($webPath) {
  406. return [
  407. 'id' => intval($event['unique_id']),
  408. 'title' => $event['title'],
  409. 'content' => str_replace('src="/', 'src="'.$webPath, $event['description']),
  410. 'startDate' => $event['start_date_localtime'],
  411. 'endDate' => $event['end_date_localtime'],
  412. 'isAllDay' => $event['allDay'] ? true : false
  413. ];
  414. },
  415. $events
  416. );
  417. }
  418. /**
  419. * @return array
  420. * @throws Exception
  421. */
  422. public function getCourseNotebooks()
  423. {
  424. $em = Database::getManager();
  425. /** @var CNotebookRepository $notebooksRepo */
  426. $notebooksRepo = $em->getRepository('ChamiloCourseBundle:CNotebook');
  427. $notebooks = $notebooksRepo->findByUser($this->user, $this->course, $this->session);
  428. return array_map(
  429. function (CNotebook $notebook) {
  430. return [
  431. 'id' => $notebook->getIid(),
  432. 'title' => $notebook->getTitle(),
  433. 'description' => $notebook->getDescription(),
  434. 'creationDate' => api_format_date(
  435. $notebook->getCreationDate()->getTimestamp()
  436. ),
  437. 'updateDate' => api_format_date(
  438. $notebook->getUpdateDate()->getTimestamp()
  439. )
  440. ];
  441. },
  442. $notebooks
  443. );
  444. }
  445. /**
  446. * @return array
  447. * @throws Exception
  448. */
  449. public function getCourseForumCategories()
  450. {
  451. $sessionId = $this->session ? $this->session->getId() : 0;
  452. $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
  453. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  454. $categoriesFullData = get_forum_categories('', $this->course->getId(), $sessionId);
  455. $categories = [];
  456. $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true';
  457. $forumsFullData = get_forums('', $this->course->getCode(), $includeGroupsForums, $sessionId);
  458. $forums = [];
  459. foreach ($forumsFullData as $forumId => $forumInfo) {
  460. $forum = [
  461. 'id' => intval($forumInfo['iid']),
  462. 'catId' => intval($forumInfo['forum_category']),
  463. 'title' => $forumInfo['forum_title'],
  464. 'description' => $forumInfo['forum_comment'],
  465. 'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
  466. 'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval($forumInfo['number_of_threads']) : 0,
  467. 'lastPost' => null
  468. ];
  469. $lastPostInfo = get_last_post_information($forumId, false, $this->course->getId(), $sessionId);
  470. if ($lastPostInfo) {
  471. $forum['lastPost'] = [
  472. 'date' => api_convert_and_format_date($lastPostInfo['last_post_date']),
  473. 'user' => api_get_person_name(
  474. $lastPostInfo['last_poster_firstname'],
  475. $lastPostInfo['last_poster_lastname']
  476. )
  477. ];
  478. }
  479. $forums[] = $forum;
  480. }
  481. foreach ($categoriesFullData as $category) {
  482. $categoryForums = array_filter(
  483. $forums,
  484. function (array $forum) use ($category) {
  485. if ($forum['catId'] != $category['cat_id']) {
  486. return false;
  487. }
  488. return true;
  489. }
  490. );
  491. $categories[] = [
  492. 'id' => intval($category['iid']),
  493. 'title' => $category['cat_title'],
  494. 'catId' => intval($category['cat_id']),
  495. 'description' => $category['cat_comment'],
  496. 'forums' => $categoryForums,
  497. 'courseId' => $this->course->getId()
  498. ];
  499. }
  500. return $categories;
  501. }
  502. /**
  503. * @param int $forumId
  504. * @return array
  505. * @throws Exception
  506. */
  507. public function getCourseForum($forumId)
  508. {
  509. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  510. $sessionId = $this->session ? $this->session->getId() : 0;
  511. $forumInfo = get_forums($forumId, $this->course->getCode(), true, $sessionId);
  512. if (!isset($forumInfo['iid'])) {
  513. throw new Exception(get_lang('NoForum'));
  514. }
  515. $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
  516. $forum = [
  517. 'id' => $forumInfo['iid'],
  518. 'title' => $forumInfo['forum_title'],
  519. 'description' => $forumInfo['forum_comment'],
  520. 'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
  521. 'threads' => []
  522. ];
  523. $threads = get_threads($forumInfo['iid'], $this->course->getId(), $sessionId);
  524. foreach ($threads as $thread) {
  525. $forum['threads'][] = [
  526. 'id' => $thread['iid'],
  527. 'title' => $thread['thread_title'],
  528. 'lastEditDate' => api_convert_and_format_date($thread['lastedit_date'], DATE_TIME_FORMAT_LONG_24H),
  529. 'numberOfReplies' => $thread['thread_replies'],
  530. 'numberOfViews' => $thread['thread_views'],
  531. 'author' => api_get_person_name($thread['firstname'], $thread['lastname'])
  532. ];
  533. }
  534. return $forum;
  535. }
  536. /**
  537. * @param int $forumId
  538. * @param int $threadId
  539. * @return array
  540. */
  541. public function getCourseForumThread($forumId, $threadId)
  542. {
  543. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  544. $sessionId = $this->session ? $this->session->getId() : 0;
  545. $threadInfo = get_thread_information($forumId, $threadId, $sessionId);
  546. $thread = [
  547. 'id' => intval($threadInfo['iid']),
  548. 'cId' => intval($threadInfo['c_id']),
  549. 'title' => $threadInfo['thread_title'],
  550. 'forumId' => intval($threadInfo['forum_id']),
  551. 'posts' => []
  552. ];
  553. $forumInfo = get_forums($threadInfo['forum_id'], $this->course->getCode(), true, $sessionId);
  554. $postsInfo = getPosts($forumInfo, $threadInfo['iid'], 'ASC');
  555. foreach ($postsInfo as $postInfo) {
  556. $thread['posts'][] = [
  557. 'id' => $postInfo['iid'],
  558. 'title' => $postInfo['post_title'],
  559. 'text' => $postInfo['post_text'],
  560. 'author' => api_get_person_name($postInfo['firstname'], $postInfo['lastname']),
  561. 'date' => api_convert_and_format_date($postInfo['post_date'], DATE_TIME_FORMAT_LONG_24H),
  562. 'parentId' => $postInfo['post_parent_id']
  563. ];
  564. }
  565. return $thread;
  566. }
  567. /**
  568. * @return array
  569. */
  570. public function getUserProfile()
  571. {
  572. $pictureInfo = UserManager::get_user_picture_path_by_id($this->user->getId(), 'web');
  573. $result = [
  574. 'pictureUri' => $pictureInfo['dir'].$pictureInfo['file'],
  575. 'fullName' => $this->user->getCompleteName(),
  576. 'username' => $this->user->getUsername(),
  577. 'officialCode' => $this->user->getOfficialCode(),
  578. 'phone' => $this->user->getPhone(),
  579. 'extra' => []
  580. ];
  581. $fieldValue = new ExtraFieldValue('user');
  582. $extraInfo = $fieldValue->getAllValuesForAnItem($this->user->getId(), true);
  583. foreach ($extraInfo as $extra) {
  584. /** @var ExtraFieldValues $extraValue */
  585. $extraValue = $extra['value'];
  586. $result['extra'][] = [
  587. 'title' => $extraValue->getField()->getDisplayText(true),
  588. 'value' => $extraValue->getValue()
  589. ];
  590. }
  591. return $result;
  592. }
  593. /**
  594. * @return array
  595. * @throws Exception
  596. */
  597. public function getCourseLearnPaths()
  598. {
  599. $sessionId = $this->session ? $this->session->getId() : 0;
  600. $categoriesTempList = learnpath::getCategories($this->course->getId());
  601. $categoryNone = new CLpCategory();
  602. $categoryNone->setId(0);
  603. $categoryNone->setName(get_lang('WithOutCategory'));
  604. $categoryNone->setPosition(0);
  605. $categories = array_merge([$categoryNone], $categoriesTempList);
  606. $categoryData = array();
  607. /** @var CLpCategory $category */
  608. foreach ($categories as $category) {
  609. $learnPathList = new LearnpathList(
  610. $this->user->getId(),
  611. $this->course->getCode(),
  612. $sessionId,
  613. null,
  614. false,
  615. $category->getId()
  616. );
  617. $flatLpList = $learnPathList->get_flat_list();
  618. if (empty($flatLpList)) {
  619. continue;
  620. }
  621. $listData = array();
  622. foreach ($flatLpList as $lpId => $lpDetails) {
  623. if ($lpDetails['lp_visibility'] == 0) {
  624. continue;
  625. }
  626. if (!learnpath::is_lp_visible_for_student(
  627. $lpId,
  628. $this->user->getId(),
  629. $this->course->getCode(),
  630. $sessionId
  631. )) {
  632. continue;
  633. }
  634. $timeLimits = false;
  635. // This is an old LP (from a migration 1.8.7) so we do nothing
  636. if (empty($lpDetails['created_on']) && empty($lpDetails['modified_on'])) {
  637. $timeLimits = false;
  638. }
  639. // Checking if expired_on is ON
  640. if (!empty($lpDetails['expired_on'])) {
  641. $timeLimits = true;
  642. }
  643. if ($timeLimits) {
  644. if (!empty($lpDetails['publicated_on']) && !empty($lpDetails['expired_on'])) {
  645. $startTime = api_strtotime($lpDetails['publicated_on'], 'UTC');
  646. $endTime = api_strtotime($lpDetails['expired_on'], 'UTC');
  647. $now = time();
  648. $isActivedTime = false;
  649. if ($now > $startTime && $endTime > $now) {
  650. $isActivedTime = true;
  651. }
  652. if (!$isActivedTime) {
  653. continue;
  654. }
  655. }
  656. }
  657. $progress = learnpath::getProgress($lpId, $this->user->getId(), $this->course->getId(), $sessionId);
  658. $listData[] = array(
  659. 'id' => $lpId,
  660. 'title' => Security::remove_XSS($lpDetails['lp_name']),
  661. 'progress' => intval($progress),
  662. 'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query([
  663. 'hash' => $this->encodeParams([
  664. 'action' => 'course_learnpath',
  665. 'lp_id' => $lpId,
  666. 'course' => $this->course->getId(),
  667. 'session' => $sessionId
  668. ])
  669. ])
  670. );
  671. }
  672. if (empty($listData)) {
  673. continue;
  674. }
  675. $categoryData[] = array(
  676. 'id' => $category->getId(),
  677. 'name' => $category->getName(),
  678. 'learnpaths' => $listData
  679. );
  680. }
  681. return $categoryData;
  682. }
  683. /**
  684. * @param array $additionalParams Optional
  685. * @return string
  686. */
  687. private function encodeParams(array $additionalParams = [])
  688. {
  689. $params = array_merge($additionalParams, [
  690. 'api_key' => $this->apiKey,
  691. 'username' => $this->user->getUsername(),
  692. ]);
  693. $strParams = serialize($params);
  694. $b64Encoded = base64_encode($strParams);
  695. return str_replace(['+', '/', '='], ['-', '_', '.'], $b64Encoded);
  696. }
  697. /**
  698. * @param string $encoded
  699. * @return array
  700. */
  701. public static function decodeParams($encoded)
  702. {
  703. $decoded = str_replace(['-', '_', '.'], ['+', '/', '='], $encoded);
  704. $mod4 = strlen($decoded) % 4;
  705. if ($mod4) {
  706. $decoded .= substr('====', $mod4);
  707. }
  708. $b64Decoded = base64_decode($decoded);
  709. return unserialize($b64Decoded);
  710. }
  711. /**
  712. * Start login for a user. Then make a redirect to show the learnpath
  713. * @param int $lpId
  714. */
  715. public function showLearningPath($lpId)
  716. {
  717. $loggedUser['user_id'] = $this->user->getId();
  718. $loggedUser['status'] = $this->user->getStatus();
  719. $loggedUser['uidReset'] = true;
  720. $sessionId = $this->session ? $this->session->getId() : 0;
  721. ChamiloSession::write('_user', $loggedUser);
  722. Login::init_user($this->user->getId(), true);
  723. $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query([
  724. 'cidReq' => $this->course->getCode(),
  725. 'id_session' => $sessionId,
  726. 'gidReq' => 0,
  727. 'gradebook' => 0,
  728. 'origin' => '',
  729. 'action' => 'view',
  730. 'lp_id' => intval($lpId),
  731. 'isStudentView' => 'true'
  732. ]);
  733. header("Location: $url");
  734. exit;
  735. }
  736. /**
  737. * @param array $postValues
  738. * @param int $forumId
  739. * @return array
  740. */
  741. public function saveForumPost(array $postValues, $forumId)
  742. {
  743. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  744. $forum = get_forums($forumId, $this->course->getCode());
  745. store_reply($forum, $postValues, $this->course->getId(), $this->user->getId());
  746. return [
  747. 'registered' => true
  748. ];
  749. }
  750. /**
  751. * Get the list of sessions for current user
  752. * @return array the sessions list
  753. */
  754. public function getUserSessions()
  755. {
  756. $data = [];
  757. $sessionsByCategory = UserManager::get_sessions_by_category($this->user->getId(), false);
  758. foreach ($sessionsByCategory as $category) {
  759. $categorySessions = [];
  760. foreach ($category['sessions'] as $sessions) {
  761. $sessionCourses = [];
  762. foreach ($sessions['courses'] as $course) {
  763. $courseInfo = api_get_course_info_by_id($course['real_id']);
  764. $teachers = SessionManager::getCoachesByCourseSessionToString(
  765. $sessions['session_id'],
  766. $course['real_id']
  767. );
  768. $sessionCourses[] = [
  769. 'id' => $courseInfo['real_id'],
  770. 'title' => $courseInfo['title'],
  771. 'code' => $courseInfo['code'],
  772. 'directory' => $courseInfo['directory'],
  773. 'pictureUrl' => $courseInfo['course_image_large'],
  774. 'teachers' => $teachers
  775. ];
  776. }
  777. $sessionBox = Display::get_session_title_box($sessions['session_id']);
  778. $categorySessions[] = [
  779. 'name' => $sessionBox['title'],
  780. 'id' => $sessions['session_id'],
  781. 'date' => $sessionBox['dates'],
  782. 'duration' => isset($sessionBox['duration']) ? $sessionBox['duration'] : null,
  783. 'courses' => $sessionCourses
  784. ];
  785. }
  786. $data[] = [
  787. 'id' => $category['session_category']['id'],
  788. 'name' => $category['session_category']['name'],
  789. 'sessions' => $categorySessions
  790. ];
  791. }
  792. return $data;
  793. }
  794. /**
  795. * @param string $subject
  796. * @param string $text
  797. * @param array $receivers
  798. * @return array
  799. */
  800. public function saveUserMessage($subject, $text, array $receivers)
  801. {
  802. foreach ($receivers as $userId) {
  803. MessageManager::send_message($userId, $subject, $text);
  804. }
  805. return [
  806. 'sent' => true
  807. ];
  808. }
  809. /**
  810. * @param string $search
  811. * @return array
  812. */
  813. public function getMessageUsers($search)
  814. {
  815. /** @var UserRepository $repo */
  816. $repo = Database::getManager()->getRepository('ChamiloUserBundle:User');
  817. $users = $repo->findUsersToSendMessage($this->user->getId(), $search);
  818. $showEmail = api_get_setting('show_email_addresses') === 'true';
  819. $data = [];
  820. /** @var User $user */
  821. foreach ($users as $user) {
  822. $userName = $user->getCompleteName();
  823. if ($showEmail) {
  824. $userName .= " ({$user->getEmail()})";
  825. }
  826. $data[] = [
  827. 'id' => $user->getId(),
  828. 'name' => $userName,
  829. ];
  830. }
  831. return $data;
  832. }
  833. /**
  834. * @param string $title
  835. * @param string $text
  836. * @return array
  837. */
  838. public function saveCourseNotebook($title, $text)
  839. {
  840. $values = ['note_title' => $title, 'note_comment' => $text];
  841. $sessionId = $this->session ? $this->session->getId() : 0;
  842. $noteBookId = NotebookManager::save_note(
  843. $values,
  844. $this->user->getId(),
  845. $this->course->getId(),
  846. $sessionId
  847. );
  848. return [
  849. 'registered' => $noteBookId
  850. ];
  851. }
  852. /**
  853. * @param array $values
  854. * @param int $forumId
  855. * @return array
  856. */
  857. public function saveForumThread(array $values, $forumId)
  858. {
  859. require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
  860. $sessionId = $this->session ? $this->session->getId() : 0;
  861. $forum = get_forums($forumId, $this->course->getCode(), true, $sessionId);
  862. $courseInfo = api_get_course_info($this->course->getCode());
  863. $id = store_thread($forum, $values, $courseInfo, false, $this->user->getId(), $sessionId);
  864. return [
  865. 'registered' => $id
  866. ];
  867. }
  868. /**
  869. * @param array $course_param
  870. * @return array
  871. */
  872. public function addCourse($course_param)
  873. {
  874. $table_course = Database::get_main_table(TABLE_MAIN_COURSE);
  875. $extra_list= array();
  876. $title = isset($course_param['title']) ? $course_param['title'] : '';
  877. $category_code = isset($course_param['category_code']) ? $course_param['category_code'] : '';
  878. $wanted_code = isset($course_param['wanted_code']) ? intval($course_param['wanted_code']) : 0;
  879. $tutor_name = isset($course_param['tutor_name']) ? $course_param['tutor_name'] : '';
  880. $admin_id = isset($course_param['admin_id']) ? $course_param['admin_id'] : null;
  881. $language = isset($course_param['language']) ? $course_param['language'] : null;
  882. $original_course_id = isset($course_param['original_course_id']) ? $course_param['original_course_id'] : null;
  883. $diskQuota = isset($course_param['disk_quota']) ? $course_param['disk_quota'] : '100';
  884. $visibility = isset($course_param['visibility']) ? (int) $course_param['visibility'] : null;
  885. if (isset($course_param['visibility'])) {
  886. if ($course_param['visibility'] &&
  887. $course_param['visibility'] >= 0 &&
  888. $course_param['visibility'] <= 3
  889. ) {
  890. $visibility = (int) $course_param['visibility'];
  891. }
  892. }
  893. // Check whether exits $x_course_code into user_field_values table.
  894. $courseInfo = CourseManager::getCourseInfoFromOriginalId(
  895. 'id',
  896. $course_param['original_course_id_name']
  897. );
  898. if (!empty($courseInfo)) {
  899. if ($courseInfo['visibility'] != 0) {
  900. $sql = "UPDATE $table_course SET
  901. course_language = '".Database::escape_string($course_language)."',
  902. title = '".Database::escape_string($title)."',
  903. category_code = '".Database::escape_string($category_code)."',
  904. tutor_name = '".Database::escape_string($tutor_name)."',
  905. visual_code = '".Database::escape_string($wanted_code)."'";
  906. if ($visibility !== null) {
  907. $sql .= ", visibility = $visibility ";
  908. }
  909. $sql .= " WHERE id = ".$courseInfo['real_id'];
  910. Database::query($sql);
  911. if (is_array($extra_list) && count($extra_list) > 0) {
  912. foreach ($extra_list as $extra) {
  913. $extra_field_name = $extra['field_name'];
  914. $extra_field_value = $extra['field_value'];
  915. // Save the external system's id into course_field_value table.
  916. CourseManager::update_course_extra_field_value(
  917. $courseInfo['code'],
  918. $extra_field_name,
  919. $extra_field_value
  920. );
  921. }
  922. }
  923. $results[] = $courseInfo['code'];
  924. } else {
  925. $results[] = 0;
  926. }
  927. }
  928. if (!empty($course_param['course_language'])) {
  929. $course_language = $course_param['course_language'];
  930. }
  931. $params = array();
  932. $params['title'] = $title;
  933. $params['wanted_code'] = $wanted_code;
  934. $params['category_code'] = $category_code;
  935. $params['course_category'] = $category_code;
  936. $params['tutor_name'] = $tutor_name;
  937. $params['course_language'] = $course_language;
  938. $params['user_id'] = $this->user->getId();
  939. $params['visibility'] = $visibility;
  940. $params['disk_quota'] = $diskQuota;
  941. if (isset($subscribe) && $subscribe != '') { // Valid values: 0, 1
  942. $params['subscribe'] = $subscribe;
  943. }
  944. if (isset($unsubscribe) && $subscribe != '') { // Valid values: 0, 1
  945. $params['unsubscribe'] = $unsubscribe;
  946. }
  947. $course_info = CourseManager::create_course($params, $params['user_id']);
  948. if (!empty($course_info)) {
  949. $course_code = $course_info['code'];
  950. // Save new field label into course_field table
  951. CourseManager::create_course_extra_field(
  952. $original_course_id_name,
  953. 1,
  954. $original_course_id_name,
  955. ''
  956. );
  957. // Save the external system's id into user_field_value table.
  958. CourseManager::update_course_extra_field_value(
  959. $course_code,
  960. $original_course_id_name,
  961. $original_course_id_value
  962. );
  963. if (is_array($extra_list) && count($extra_list) > 0) {
  964. foreach ($extra_list as $extra) {
  965. $extra_field_name = $extra['field_name'];
  966. $extra_field_value = $extra['field_value'];
  967. // Save new fieldlabel into course_field table.
  968. CourseManager::create_course_extra_field(
  969. $extra_field_name,
  970. 1,
  971. $extra_field_name,
  972. ''
  973. );
  974. // Save the external system's id into course_field_value table.
  975. CourseManager::update_course_extra_field_value(
  976. $course_code,
  977. $extra_field_name,
  978. $extra_field_value
  979. );
  980. }
  981. }
  982. $results[] = $course_code;
  983. } else {
  984. $results[] = 0;
  985. }
  986. return $results;
  987. }
  988. /**
  989. * @param $user_param
  990. * @return array
  991. */
  992. public function addUser($user_param)
  993. {
  994. $results = array();
  995. $orig_user_id_value = array();
  996. $userManager = UserManager::getManager();
  997. $userRepository = UserManager::getRepository();
  998. $firstName = $user_param['firstname'];
  999. $lastName = $user_param['lastname'];
  1000. $status = $user_param['status'];
  1001. $email = $user_param['email'];
  1002. $loginName = $user_param['loginname'];
  1003. $password = $user_param['password'];
  1004. $official_code = '';
  1005. $language = '';
  1006. $phone = '';
  1007. $picture_uri = '';
  1008. $auth_source = PLATFORM_AUTH_SOURCE;
  1009. $expiration_date = '';
  1010. $active = 1;
  1011. $hr_dept_id = 0;
  1012. $extra = null;
  1013. $original_user_id_name = $user_param['original_user_id_name'];
  1014. $original_user_id_value = $user_param['original_user_id_value'];
  1015. $orig_user_id_value[] = $user_param['original_user_id_value'];
  1016. $extra_list = $user_param['extra'];
  1017. if (!empty($user_param['language'])) {
  1018. $language = $user_param['language'];
  1019. }
  1020. if (!empty($user_param['phone'])) {
  1021. $phone = $user_param['phone'];
  1022. }
  1023. if (!empty($user_param['expiration_date'])) {
  1024. $expiration_date = $user_param['expiration_date'];
  1025. }
  1026. // Default language.
  1027. if (empty($language)) {
  1028. $language = api_get_setting('platformLanguage');
  1029. }
  1030. // First check wether the login already exists.
  1031. if (!UserManager::is_username_available($loginName)) {
  1032. $results[] = 0;
  1033. }
  1034. $userId = UserManager::create_user(
  1035. $firstName,
  1036. $lastName,
  1037. $status,
  1038. $email,
  1039. $loginName,
  1040. $password,
  1041. $official_code,
  1042. $language,
  1043. $phone,
  1044. $picture_uri,
  1045. $auth_source,
  1046. $expiration_date,
  1047. $active,
  1048. $hr_dept_id
  1049. );
  1050. if ($userId) {
  1051. if (api_is_multiple_url_enabled()) {
  1052. if (api_get_current_access_url_id() != -1) {
  1053. UrlManager::add_user_to_url(
  1054. $userId,
  1055. api_get_current_access_url_id()
  1056. );
  1057. } else {
  1058. UrlManager::add_user_to_url($userId, 1);
  1059. }
  1060. } else {
  1061. // We add by default the access_url_user table with access_url_id = 1
  1062. UrlManager::add_user_to_url($userId, 1);
  1063. }
  1064. // Save new field label into user_field table.
  1065. UserManager::create_extra_field(
  1066. $original_user_id_name,
  1067. 1,
  1068. $original_user_id_name,
  1069. ''
  1070. );
  1071. // Save the external system's id into user_field_value table.
  1072. UserManager::update_extra_field_value(
  1073. $userId,
  1074. $original_user_id_name,
  1075. $original_user_id_value
  1076. );
  1077. if (is_array($extra_list) && count($extra_list) > 0) {
  1078. foreach ($extra_list as $extra) {
  1079. $extra_field_name = $extra['field_name'];
  1080. $extra_field_value = $extra['field_value'];
  1081. // Save new field label into user_field table.
  1082. UserManager::create_extra_field(
  1083. $extra_field_name,
  1084. 1,
  1085. $extra_field_name,
  1086. ''
  1087. );
  1088. // Save the external system's id into user_field_value table.
  1089. UserManager::update_extra_field_value(
  1090. $userId,
  1091. $extra_field_name,
  1092. $extra_field_value
  1093. );
  1094. }
  1095. }
  1096. $results[] = $userId;
  1097. } else {
  1098. $results[] = 0;
  1099. }
  1100. return $results;
  1101. }
  1102. /**
  1103. * Subscribe User to Course
  1104. * @param array $params
  1105. * @return array
  1106. */
  1107. public function subscribeUserToCourse($params)
  1108. {
  1109. $course_id = $params['course_id'];
  1110. $course_code = $params['course_code'];
  1111. $user_id = $params['user_id'];
  1112. if (!$course_id && !$course_code) {
  1113. return [false];
  1114. }
  1115. if (!$course_code) {
  1116. $course_code = CourseManager::get_course_code_from_course_id($course_id);
  1117. }
  1118. if (CourseManager::subscribe_user($user_id, $course_code)) {
  1119. return [true];
  1120. } else {
  1121. return [false];
  1122. }
  1123. return [true];
  1124. }
  1125. }