LearningCalendarPlugin.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. <?php
  2. /* For license terms, see /license.txt */
  3. /**
  4. * Class LearningCalendarPlugin.
  5. */
  6. class LearningCalendarPlugin extends Plugin
  7. {
  8. const EVENT_TYPE_TAKEN = 1;
  9. const EVENT_TYPE_EXAM = 2;
  10. const EVENT_TYPE_FREE = 3;
  11. /**
  12. * Class constructor.
  13. */
  14. protected function __construct()
  15. {
  16. $version = '0.1';
  17. $author = 'Julio Montoya';
  18. parent::__construct($version, $author, ['enabled' => 'boolean']);
  19. $this->setHasPersonalEvents(true);
  20. }
  21. /**
  22. * Event definition.
  23. *
  24. * @return array
  25. */
  26. public function getEventTypeList()
  27. {
  28. return [
  29. self::EVENT_TYPE_TAKEN => ['color' => 'red', 'name' => self::get_lang('EventTypeTaken')],
  30. self::EVENT_TYPE_EXAM => ['color' => 'yellow', 'name' => self::get_lang('EventTypeExam')],
  31. self::EVENT_TYPE_FREE => ['color' => 'green', 'name' => self::get_lang('EventTypeFree')],
  32. ];
  33. }
  34. /**
  35. * @return array
  36. */
  37. public function getEventTypeColorList()
  38. {
  39. $list = $this->getEventTypeList();
  40. $newList = [];
  41. foreach ($list as $eventId => $event) {
  42. $newList[$eventId] = $event['color'];
  43. }
  44. return $newList;
  45. }
  46. /**
  47. * Get the class instance.
  48. *
  49. * @return $this
  50. */
  51. public static function create()
  52. {
  53. static $result = null;
  54. return $result ?: $result = new self();
  55. }
  56. /**
  57. * Get the plugin directory name.
  58. */
  59. public function get_name()
  60. {
  61. return 'learning_calendar';
  62. }
  63. /**
  64. * Install the plugin. Setup the database.
  65. */
  66. public function install()
  67. {
  68. $sql = "
  69. CREATE TABLE IF NOT EXISTS learning_calendar(
  70. id int not null AUTO_INCREMENT primary key,
  71. title varchar(255) not null default '',
  72. description longtext default null,
  73. total_hours int not null default 0,
  74. minutes_per_day int not null default 0,
  75. disabled int default 0,
  76. author_id int(11) not null
  77. )
  78. ";
  79. Database::query($sql);
  80. $sql = "
  81. CREATE TABLE IF NOT EXISTS learning_calendar_events(
  82. id int not null AUTO_INCREMENT primary key,
  83. name varchar(255) default '',
  84. calendar_id int not null,
  85. start_date date not null,
  86. end_date date not null,
  87. type int not null
  88. )
  89. ";
  90. Database::query($sql);
  91. $sql = "
  92. CREATE TABLE IF NOT EXISTS learning_calendar_user(
  93. id int not null AUTO_INCREMENT primary key,
  94. user_id int(11) not null,
  95. calendar_id int not null
  96. )
  97. ";
  98. Database::query($sql);
  99. $extraField = new ExtraField('lp_item');
  100. $params = [
  101. 'variable' => 'calendar',
  102. 'visible_to_self' => 1,
  103. 'changeable' => 1,
  104. 'visible_to_others' => 1,
  105. 'field_type' => ExtraField::FIELD_TYPE_CHECKBOX,
  106. ];
  107. $extraField->save($params);
  108. $extraField = new ExtraField('course');
  109. $params = [
  110. 'display_text' => $this->get_lang('CourseHoursDuration'),
  111. 'variable' => 'course_hours_duration',
  112. 'visible_to_self' => 1,
  113. 'changeable' => 1,
  114. 'visible_to_others' => 1,
  115. 'field_type' => ExtraField::FIELD_TYPE_TEXT,
  116. ];
  117. $extraField->save($params);
  118. return true;
  119. }
  120. /**
  121. * Uninstall the plugin.
  122. */
  123. public function uninstall()
  124. {
  125. $tables = [
  126. 'learning_calendar',
  127. 'learning_calendar_events',
  128. 'learning_calendar_user',
  129. ];
  130. foreach ($tables as $table) {
  131. $sql = "DROP TABLE IF EXISTS $table";
  132. Database::query($sql);
  133. }
  134. $extraField = new ExtraField('lp_item');
  135. $fieldInfo = $extraField->get_handler_field_info_by_field_variable('calendar');
  136. if ($fieldInfo) {
  137. $extraField->delete($fieldInfo['id']);
  138. }
  139. $extraField = new ExtraField('course');
  140. $fieldInfo = $extraField->get_handler_field_info_by_field_variable('course_hours_duration');
  141. if ($fieldInfo) {
  142. $extraField->delete($fieldInfo['id']);
  143. }
  144. return true;
  145. }
  146. /**
  147. * @param int $from
  148. * @param int $numberOfItems
  149. * @param int $column
  150. * @param string $direction
  151. *
  152. * @return array
  153. */
  154. public function getCalendars(
  155. $from,
  156. $numberOfItems,
  157. $column,
  158. $direction = 'DESC'
  159. ) {
  160. $column = (int) $column;
  161. $from = (int) $from;
  162. $numberOfItems = (int) $numberOfItems;
  163. $direction = strtoupper($direction);
  164. if (!in_array($direction, ['ASC', 'DESC'])) {
  165. $direction = 'DESC';
  166. }
  167. if (api_is_platform_admin()) {
  168. $sql = 'SELECT * FROM learning_calendar';
  169. } else {
  170. $userId = api_get_user_id();
  171. $sql = "SELECT * FROM learning_calendar WHERE author_id = $userId";
  172. }
  173. $sql .= " LIMIT $from, $numberOfItems ";
  174. $result = Database::query($sql);
  175. $list = [];
  176. $link = api_get_path(WEB_PLUGIN_PATH).'learning_calendar/start.php';
  177. while ($row = Database::fetch_array($result)) {
  178. $id = $row['id'];
  179. $row['title'] = Display::url(
  180. $row['title'],
  181. api_get_path(WEB_PLUGIN_PATH).'learning_calendar/calendar.php?id='.$id
  182. );
  183. $actions = Display::url(
  184. Display::return_icon('edit.png', get_lang('Edit')),
  185. $link.'?action=edit&id='.$id
  186. );
  187. $actions .= Display::url(
  188. Display::return_icon('copy.png', get_lang('Copy')),
  189. $link.'?action=copy&id='.$id
  190. );
  191. $actions .= Display::url(
  192. Display::return_icon('delete.png', get_lang('Delete')),
  193. $link.'?action=delete&id='.$id
  194. );
  195. $row['actions'] = $actions;
  196. $list[] = $row;
  197. }
  198. return $list;
  199. }
  200. /**
  201. * @param array $calendarInfo
  202. * @param int $start
  203. * @param int $end
  204. * @param int $type
  205. * @param bool $getCount
  206. *
  207. * @return array
  208. */
  209. public function getCalendarsEventsByDate($calendarInfo, $start, $end, $type = 0, $getCount = false)
  210. {
  211. if (empty($calendarInfo)) {
  212. return [];
  213. }
  214. $calendarId = (int) $calendarInfo['id'];
  215. $start = (int) $start;
  216. $end = (int) $end;
  217. $startCondition = '';
  218. $endCondition = '';
  219. $typeCondition = '';
  220. if ($start !== 0) {
  221. $start = api_get_utc_datetime($start);
  222. $startCondition = "AND start_date >= '".$start."'";
  223. }
  224. if ($end !== 0) {
  225. $end = api_get_utc_datetime($end);
  226. $endCondition = "AND (end_date <= '".$end."' OR end_date IS NULL)";
  227. }
  228. if (!empty($type)) {
  229. $type = (int) $type;
  230. $typeCondition = " AND type = $type ";
  231. }
  232. $select = '*';
  233. if ($getCount) {
  234. $select = 'count(id) count ';
  235. }
  236. $sql = "SELECT $select FROM learning_calendar_events
  237. WHERE calendar_id = $calendarId $startCondition $endCondition $typeCondition";
  238. $result = Database::query($sql);
  239. if ($getCount) {
  240. $row = Database::fetch_array($result, 'ASSOC');
  241. return $row['count'];
  242. }
  243. $list = [];
  244. while ($row = Database::fetch_array($result, 'ASSOC')) {
  245. $list[] = $row;
  246. }
  247. return ['calendar' => $calendarInfo, 'events' => $list];
  248. }
  249. /**
  250. * @param array $calendarInfo
  251. *
  252. * @return array
  253. */
  254. public function getFirstCalendarDate($calendarInfo)
  255. {
  256. if (empty($calendarInfo)) {
  257. return [];
  258. }
  259. $calendarId = (int) $calendarInfo['id'];
  260. /*if (!empty($type)) {
  261. $type = (int) $type;
  262. $typeCondition = " AND type = $type ";
  263. }*/
  264. $sql = "SELECT start_date FROM learning_calendar_events
  265. WHERE calendar_id = $calendarId ORDER BY start_date LIMIT 1";
  266. $result = Database::query($sql);
  267. $row = Database::fetch_array($result, 'ASSOC');
  268. return $row['start_date'];
  269. }
  270. /**
  271. * @return int
  272. */
  273. public function getCalendarCount()
  274. {
  275. if (api_is_platform_admin()) {
  276. $sql = 'select count(*) as count FROM learning_calendar';
  277. } else {
  278. $userId = api_get_user_id();
  279. $sql = "select count(*) as count FROM learning_calendar WHERE author_id = $userId";
  280. }
  281. $result = Database::query($sql);
  282. $result = Database::fetch_array($result);
  283. return (int) $result['count'];
  284. }
  285. /**
  286. * @param int $calendarId
  287. *
  288. * @return array
  289. */
  290. public function getUsersPerCalendar($calendarId)
  291. {
  292. $calendarId = (int) $calendarId;
  293. $sql = "SELECT * FROM learning_calendar_user
  294. WHERE calendar_id = $calendarId";
  295. $result = Database::query($sql);
  296. $list = [];
  297. while ($row = Database::fetch_array($result, 'ASSOC')) {
  298. $userInfo = api_get_user_info($row['user_id']);
  299. $userInfo['exam'] = 'exam';
  300. $list[] = $userInfo;
  301. }
  302. return $list;
  303. }
  304. /**
  305. * @param int $calendarId
  306. *
  307. * @return int
  308. */
  309. public function getUsersPerCalendarCount($calendarId)
  310. {
  311. $calendarId = (int) $calendarId;
  312. $sql = "SELECT count(id) as count FROM learning_calendar_user
  313. WHERE calendar_id = $calendarId";
  314. $result = Database::query($sql);
  315. $row = Database::fetch_array($result, 'ASSOC');
  316. return (int) $row['count'];
  317. }
  318. /**
  319. * @param int $id
  320. */
  321. public function toggleVisibility($id)
  322. {
  323. $extraField = new ExtraField('lp_item');
  324. $fieldInfo = $extraField->get_handler_field_info_by_field_variable('calendar');
  325. if ($fieldInfo) {
  326. $itemInfo = $this->getItemVisibility($id);
  327. if (empty($itemInfo)) {
  328. $extraField = new ExtraFieldValue('lp_item');
  329. $value = 1;
  330. $params = [
  331. 'field_id' => $fieldInfo['id'],
  332. 'value' => $value,
  333. 'item_id' => $id,
  334. ];
  335. $extraField->save($params);
  336. } else {
  337. $newValue = (int) $itemInfo['value'] === 1 ? 0 : 1;
  338. $extraField = new ExtraFieldValue('lp_item');
  339. $params = [
  340. 'id' => $itemInfo['id'],
  341. 'value' => $newValue,
  342. ];
  343. $extraField->update($params);
  344. }
  345. }
  346. }
  347. /**
  348. * @param int $id
  349. *
  350. * @return array
  351. */
  352. public function getItemVisibility($id)
  353. {
  354. $extraField = new ExtraFieldValue('lp_item');
  355. $values = $extraField->get_values_by_handler_and_field_variable($id, 'calendar');
  356. if (empty($values)) {
  357. return [];
  358. }
  359. return $values;
  360. }
  361. /**
  362. * @param int $calendarId
  363. *
  364. * @return array|mixed
  365. */
  366. public function getCalendar($calendarId)
  367. {
  368. $calendarId = (int) $calendarId;
  369. $sql = "SELECT * FROM learning_calendar WHERE id = $calendarId";
  370. $result = Database::query($sql);
  371. $item = Database::fetch_array($result, 'ASSOC');
  372. return $item;
  373. }
  374. /**
  375. * @param int $userId
  376. *
  377. * @return array|mixed
  378. */
  379. public function getUserCalendar($userId)
  380. {
  381. $userId = (int) $userId;
  382. $sql = "SELECT * FROM learning_calendar_user WHERE user_id = $userId";
  383. $result = Database::query($sql);
  384. $item = Database::fetch_array($result, 'ASSOC');
  385. return $item;
  386. }
  387. /**
  388. * @param int $userId
  389. * @param int $start
  390. * @param int $end
  391. * @param int $type
  392. * @param bool $getCount
  393. *
  394. * @return array|int
  395. */
  396. public function getUserEvents($userId, $start, $end, $type = 0, $getCount = false)
  397. {
  398. $calendarRelUser = $this->getUserCalendar($userId);
  399. if (!empty($calendarRelUser)) {
  400. $calendar = $this->getCalendar($calendarRelUser['calendar_id']);
  401. return $this->getCalendarsEventsByDate($calendar, $start, $end, $type, $getCount);
  402. }
  403. if ($getCount) {
  404. return 0;
  405. }
  406. return [];
  407. }
  408. /**
  409. * @param int $userId
  410. *
  411. * @return mixed|string
  412. */
  413. public function getUserCalendarToString($userId)
  414. {
  415. $calendar = $this->getUserCalendar($userId);
  416. if ($calendar) {
  417. $calendarInfo = $this->getCalendar($calendar['calendar_id']);
  418. return $calendarInfo['title'];
  419. }
  420. return '';
  421. }
  422. /**
  423. * @param int $calendarId
  424. * @param int $userId
  425. *
  426. * @return bool
  427. */
  428. public function addUserToCalendar($calendarId, $userId)
  429. {
  430. $calendar = $this->getUserCalendar($userId);
  431. if (empty($calendar)) {
  432. $params = [
  433. 'calendar_id' => $calendarId,
  434. 'user_id' => $userId,
  435. ];
  436. Database::insert('learning_calendar_user', $params);
  437. }
  438. return true;
  439. }
  440. /**
  441. * @param int $calendarId
  442. * @param int $userId
  443. *
  444. * @return bool
  445. */
  446. public function updateUserToCalendar($calendarId, $userId)
  447. {
  448. $calendar = $this->getUserCalendar($userId);
  449. if (!empty($calendar)) {
  450. $params = [
  451. 'calendar_id' => $calendarId,
  452. 'user_id' => $userId,
  453. ];
  454. Database::update('learning_calendar_user', $params, ['id = ?' => $calendar['id']]);
  455. }
  456. return true;
  457. }
  458. /**
  459. * @param int $calendarId
  460. * @param int $userId
  461. *
  462. * @return bool
  463. */
  464. public function deleteAllCalendarFromUser($calendarId, $userId)
  465. {
  466. $calendarId = (int) $calendarId;
  467. $userId = (int) $userId;
  468. $sql = "DELETE FROM learning_calendar_user
  469. WHERE user_id = $userId AND calendar_id = $calendarId";
  470. Database::query($sql);
  471. return true;
  472. }
  473. /*public static function getUserCalendar($calendarId, $userId)
  474. {
  475. $params = [
  476. 'calendar_id' => $calendarId,
  477. 'user_id' => $calendarId,
  478. ];
  479. Database::insert('learning_calendar_user', $params);
  480. return true;
  481. }*/
  482. /**
  483. * @param FormValidator $form
  484. */
  485. public function getForm(FormValidator &$form)
  486. {
  487. $form->addText('title', get_lang('Title'));
  488. $form->addText('total_hours', get_lang('TotalHours'));
  489. $form->addText('minutes_per_day', get_lang('MinutesPerDay'));
  490. $form->addHtmlEditor('description', get_lang('Description'), false);
  491. }
  492. /**
  493. * @param Agenda $agenda
  494. * @param int $start
  495. * @param int $end
  496. *
  497. * @return array
  498. */
  499. public function getPersonalEvents($agenda, $start, $end)
  500. {
  501. $userId = api_get_user_id();
  502. $events = $this->getUserEvents($userId, $start, $end);
  503. if (empty($events)) {
  504. return [];
  505. }
  506. $calendarInfo = $events['calendar'];
  507. $events = $events['events'];
  508. $list = [];
  509. $typeList = $this->getEventTypeColorList();
  510. foreach ($events as $row) {
  511. $event = [];
  512. $event['id'] = 'personal_'.$row['id'];
  513. $event['title'] = $calendarInfo['title'];
  514. $event['className'] = 'personal';
  515. $color = isset($typeList[$row['type']]) ? $typeList[$row['type']] : $typeList[self::EVENT_TYPE_FREE];
  516. $event['borderColor'] = $color;
  517. $event['backgroundColor'] = $color;
  518. $event['editable'] = false;
  519. $event['sent_to'] = get_lang('Me');
  520. $event['type'] = 'personal';
  521. if (!empty($row['start_date'])) {
  522. $event['start'] = $agenda->formatEventDate($row['start_date']);
  523. $event['start_date_localtime'] = api_get_local_time($row['start_date']);
  524. }
  525. if (!empty($row['end_date'])) {
  526. $event['end'] = $agenda->formatEventDate($row['end_date']);
  527. $event['end_date_localtime'] = api_get_local_time($row['end_date']);
  528. }
  529. $event['description'] = 'plugin';
  530. $event['allDay'] = 1;
  531. $event['parent_event_id'] = 0;
  532. $event['has_children'] = 0;
  533. $list[] = $event;
  534. }
  535. return $list;
  536. }
  537. /**
  538. * @param int $userId
  539. * @param array $coursesAndSessions
  540. *
  541. * @return string
  542. */
  543. public function getGradebookEvaluationListToString($userId, $coursesAndSessions)
  544. {
  545. $list = $this->getGradebookEvaluationList($userId, $coursesAndSessions);
  546. $html = '';
  547. if (!empty($list)) {
  548. $html = implode('<br />', array_column($list, 'name'));
  549. }
  550. return $html;
  551. }
  552. /**
  553. * @param int $userId
  554. * @param array $coursesAndSessions
  555. *
  556. * @return array
  557. */
  558. public function getGradebookEvaluationList($userId, $coursesAndSessions)
  559. {
  560. $userId = (int) $userId;
  561. if (empty($coursesAndSessions)) {
  562. return 0;
  563. }
  564. $courseSessionConditionToString = '';
  565. foreach ($coursesAndSessions as $sessionId => $courseList) {
  566. if (isset($courseList['course_list'])) {
  567. $courseList = array_keys($courseList['course_list']);
  568. }
  569. if (empty($courseList)) {
  570. continue;
  571. }
  572. //$courseListToString = implode("','", $courseList);
  573. /*if (empty($sessionId)) {
  574. $courseAndSessionCondition[] =
  575. " c.id IN ('$courseListToString') ";
  576. } else {
  577. $courseAndSessionCondition[] = "
  578. (
  579. c.id IN ('$courseListToString')
  580. )";
  581. }*/
  582. $courseSessionConditionToString = " AND c.id IN ('".implode("','", $courseList)."') ";
  583. }
  584. if (empty($courseSessionConditionToString)) {
  585. return 0;
  586. }
  587. $tableEvaluation = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
  588. $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
  589. $tableResult = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
  590. $sql = "SELECT DISTINCT e.name, e.id
  591. FROM $tableEvaluation e
  592. INNER JOIN $tableCourse c
  593. ON (course_code = c.code)
  594. INNER JOIN $tableResult r
  595. ON (r.evaluation_id = e.id)
  596. WHERE
  597. e.type = 'evaluation' AND
  598. r.score > 0 AND
  599. r.user_id = $userId
  600. $courseSessionConditionToString
  601. ";
  602. $result = Database::query($sql);
  603. $list = [];
  604. if (Database::num_rows($result)) {
  605. while ($row = Database::fetch_array($result, 'ASSOC')) {
  606. $list[$row['id']] = $row;
  607. }
  608. }
  609. return $list;
  610. }
  611. /**
  612. * @param int $userId
  613. * @param array $coursesAndSessions
  614. *
  615. * @return int
  616. */
  617. public function getItemCountChecked($userId, $coursesAndSessions)
  618. {
  619. $userId = (int) $userId;
  620. if (empty($coursesAndSessions)) {
  621. return 0;
  622. }
  623. $tableItem = Database::get_course_table(TABLE_LP_ITEM);
  624. $tableLp = Database::get_course_table(TABLE_LP_MAIN);
  625. $tableLpItemView = Database::get_course_table(TABLE_LP_ITEM_VIEW);
  626. $tableLpView = Database::get_course_table(TABLE_LP_VIEW);
  627. $extraField = new ExtraField('lp_item');
  628. $fieldInfo = $extraField->get_handler_field_info_by_field_variable('calendar');
  629. if (empty($fieldInfo)) {
  630. return 0;
  631. }
  632. $courseAndSessionCondition = [];
  633. foreach ($coursesAndSessions as $sessionId => $courseList) {
  634. if (isset($courseList['course_list'])) {
  635. $courseList = array_keys($courseList['course_list']);
  636. }
  637. if (empty($courseList)) {
  638. continue;
  639. }
  640. $courseListToString = implode("','", $courseList);
  641. if (empty($sessionId)) {
  642. $courseAndSessionCondition[] =
  643. " ((l.session_id = 0 OR l.session_id is NULL) AND i.c_id IN ('$courseListToString'))";
  644. } else {
  645. $courseAndSessionCondition[] = "
  646. (
  647. ((l.session_id = 0 OR l.session_id is NULL) OR l.session_id = $sessionId) AND
  648. i.c_id IN ('$courseListToString')
  649. )";
  650. }
  651. }
  652. if (empty($courseAndSessionCondition)) {
  653. return 0;
  654. }
  655. $courseSessionConditionToString = 'AND ('.implode(' OR ', $courseAndSessionCondition).') ';
  656. $sql = "SELECT count(*) as count
  657. FROM $tableItem i INNER JOIN $tableLp l
  658. ON (i.c_id = l.c_id AND i.lp_id = l.iid)
  659. INNER JOIN $tableLpItemView iv
  660. ON (iv.c_id = l.c_id AND i.iid = iv.lp_item_id)
  661. INNER JOIN $tableLpView v
  662. ON (v.c_id = l.c_id AND v.lp_id = l.iid AND iv.lp_view_id = v.iid)
  663. INNER JOIN extra_field_values e
  664. ON (e.item_id = i.iid AND value = 1 AND field_id = ".$fieldInfo['id'].")
  665. WHERE v.user_id = $userId AND status = 'completed' $courseSessionConditionToString";
  666. $result = Database::query($sql);
  667. if (Database::num_rows($result)) {
  668. $row = Database::fetch_array($result, 'ASSOC');
  669. return $row['count'];
  670. }
  671. return 0;
  672. }
  673. /**
  674. * @param int $userId
  675. * @param array $courseAndSessionList
  676. *
  677. * @return string
  678. */
  679. public function getUserStatsPanel($userId, $courseAndSessionList)
  680. {
  681. // @todo use translation
  682. // get events from this year to today
  683. $stats = $this->getUserStats($userId, $courseAndSessionList);
  684. $html = $this->get_lang('NumberDaysAccumulatedInCalendar').$stats['user_event_count'];
  685. if (!empty($courseAndSessionList)) {
  686. $html .= '<br />';
  687. $html .= $this->get_lang('NumberDaysAccumulatedInLp').$stats['completed'];
  688. $html .= '<br />';
  689. $html .= $this->get_lang('NumberDaysInRetard').' '.$stats['diff'];
  690. }
  691. $html = Display::panel($html, $this->get_lang('LearningCalendar'));
  692. return $html;
  693. }
  694. /**
  695. * @param int $userId
  696. * @param array $courseAndSessionList
  697. *
  698. * @return array
  699. */
  700. public function getUserStats($userId, $courseAndSessionList)
  701. {
  702. // Get events from this year to today
  703. $takenCount = $this->getUserEvents(
  704. $userId,
  705. strtotime(date('Y-01-01')),
  706. time(),
  707. self::EVENT_TYPE_TAKEN,
  708. true
  709. );
  710. $completed = 0;
  711. $diff = 0;
  712. if (!empty($courseAndSessionList)) {
  713. $completed = $this->getItemCountChecked($userId, $courseAndSessionList);
  714. $diff = $takenCount - $completed;
  715. }
  716. return [
  717. 'user_event_count' => $takenCount,
  718. 'completed' => $completed,
  719. 'diff' => $diff,
  720. ];
  721. }
  722. /**
  723. * @param int $calendarId
  724. *
  725. * @return bool
  726. */
  727. public function copyCalendar($calendarId)
  728. {
  729. $item = $this->getCalendar($calendarId);
  730. $this->protectCalendar($item);
  731. $item['author_id'] = api_get_user_id();
  732. if (empty($item)) {
  733. return false;
  734. }
  735. $calendarId = (int) $calendarId;
  736. unset($item['id']);
  737. //$item['title'] = $item['title'];
  738. $newCalendarId = Database::insert('learning_calendar', $item);
  739. if (!empty($newCalendarId)) {
  740. $sql = "SELECT * FROM learning_calendar_events WHERE calendar_id = $calendarId";
  741. $result = Database::query($sql);
  742. while ($row = Database::fetch_array($result, 'ASSOC')) {
  743. unset($row['id']);
  744. $row['calendar_id'] = $newCalendarId;
  745. Database::insert('learning_calendar_events', $row);
  746. }
  747. return true;
  748. }
  749. return false;
  750. }
  751. /**
  752. * @param int $calendarId
  753. *
  754. * @return bool
  755. */
  756. public function deleteCalendar($calendarId)
  757. {
  758. $item = $this->getCalendar($calendarId);
  759. $this->protectCalendar($item);
  760. if (empty($item)) {
  761. return false;
  762. }
  763. $calendarId = (int) $calendarId;
  764. $sql = "DELETE FROM learning_calendar WHERE id = $calendarId";
  765. Database::query($sql);
  766. // Delete events
  767. $sql = "DELETE FROM learning_calendar_events WHERE calendar_id = $calendarId";
  768. Database::query($sql);
  769. return true;
  770. }
  771. /**
  772. * @param int $calendarId
  773. * @param string $startDate
  774. */
  775. public function toogleDayType($calendarId, $startDate)
  776. {
  777. $startDate = Database::escape_string($startDate);
  778. $calendarId = (int) $calendarId;
  779. $eventTypeList = $this->getEventTypeColorList();
  780. // Remove the free type to loop correctly when toogle days.
  781. unset($eventTypeList[self::EVENT_TYPE_FREE]);
  782. $sql = "SELECT * FROM learning_calendar_events
  783. WHERE start_date = '$startDate' AND calendar_id = $calendarId ";
  784. $result = Database::query($sql);
  785. if (Database::num_rows($result)) {
  786. $row = Database::fetch_array($result, 'ASSOC');
  787. $currentType = $row['type'];
  788. $currentType++;
  789. if ($currentType > count($eventTypeList)) {
  790. Database::delete(
  791. 'learning_calendar_events',
  792. [' calendar_id = ? AND start_date = ?' => [$calendarId, $startDate]]
  793. );
  794. } else {
  795. $params = [
  796. 'type' => $currentType,
  797. ];
  798. Database::update(
  799. 'learning_calendar_events',
  800. $params,
  801. [' calendar_id = ? AND start_date = ?' => [$calendarId, $startDate]]
  802. );
  803. }
  804. } else {
  805. $params = [
  806. 'name' => '',
  807. 'calendar_id' => $calendarId,
  808. 'start_date' => $startDate,
  809. 'end_date' => $startDate,
  810. 'type' => self::EVENT_TYPE_TAKEN,
  811. ];
  812. Database::insert('learning_calendar_events', $params);
  813. }
  814. }
  815. /**
  816. * @param int $calendarId
  817. *
  818. * @return array
  819. */
  820. public function getEvents($calendarId)
  821. {
  822. $calendarId = (int) $calendarId;
  823. $eventTypeList = $this->getEventTypeColorList();
  824. $sql = "SELECT * FROM learning_calendar_events
  825. WHERE calendar_id = $calendarId ";
  826. $result = Database::query($sql);
  827. $list = [];
  828. while ($row = Database::fetch_array($result, 'ASSOC')) {
  829. $list[] = [
  830. 'start_date' => $row['start_date'],
  831. 'end_date' => $row['start_date'],
  832. 'color' => $eventTypeList[$row['type']],
  833. ];
  834. }
  835. return $list;
  836. }
  837. /**
  838. * @param array $calendarInfo
  839. */
  840. public function protectCalendar($calendarInfo = [])
  841. {
  842. $allow = api_is_platform_admin() || api_is_teacher();
  843. if (!$allow) {
  844. api_not_allowed(true);
  845. }
  846. if (!empty($calendarInfo)) {
  847. if (!api_is_platform_admin() && api_is_teacher()) {
  848. if ($calendarInfo['author_id'] != api_get_user_id()) {
  849. api_not_allowed(true);
  850. }
  851. }
  852. }
  853. }
  854. }