ScheduledAnnouncement.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Class ScheduledAnnouncement
  5. * Requires DB change:.
  6. *
  7. * CREATE TABLE scheduled_announcements (id INT AUTO_INCREMENT NOT NULL, subject VARCHAR(255) NOT NULL, message LONGTEXT NOT NULL, date DATETIME DEFAULT NULL, sent TINYINT(1) NOT NULL, session_id INT NOT NULL, c_id INT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
  8. *
  9. * Config setting:
  10. * $_configuration['allow_scheduled_announcements'] = true;
  11. *
  12. * Setup linux cron file:
  13. * main/cron/scheduled_announcement.php
  14. *
  15. * Requires:
  16. * composer update
  17. *
  18. * @package chamilo.library
  19. */
  20. class ScheduledAnnouncement extends Model
  21. {
  22. public $table;
  23. public $columns = ['id', 'subject', 'message', 'date', 'sent', 'session_id'];
  24. /**
  25. * Constructor.
  26. */
  27. public function __construct()
  28. {
  29. parent::__construct();
  30. $this->table = 'scheduled_announcements';
  31. }
  32. /**
  33. * @param array $where_conditions
  34. *
  35. * @return array
  36. */
  37. public function get_all($where_conditions = [])
  38. {
  39. return Database::select(
  40. '*',
  41. $this->table,
  42. ['where' => $where_conditions, 'order' => 'subject ASC']
  43. );
  44. }
  45. /**
  46. * @return mixed
  47. */
  48. public function get_count()
  49. {
  50. $row = Database::select(
  51. 'count(*) as count',
  52. $this->table,
  53. [],
  54. 'first'
  55. );
  56. return $row['count'];
  57. }
  58. /**
  59. * Displays the title + grid.
  60. *
  61. * @param int $sessionId
  62. *
  63. * @return string
  64. */
  65. public function getGrid($sessionId)
  66. {
  67. // action links
  68. $action = '<div class="actions" style="margin-bottom:20px">';
  69. $action .= Display::url(
  70. Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM),
  71. api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$sessionId
  72. );
  73. $action .= '<a href="'.api_get_self().'?action=add&session_id='.$sessionId.'">'.
  74. Display::return_icon('add.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
  75. $action .= '<a href="scheduled_announcement.php?action=run&session_id='.$sessionId.'">'.
  76. Display::return_icon('tuning.png', get_lang('SendManuallyPendingAnnouncements'), '', ICON_SIZE_MEDIUM).
  77. '</a>';
  78. $action .= '</div>';
  79. $html = $action;
  80. $html .= '<div id="session-table" class="table-responsive">';
  81. $html .= Display::grid_html('programmed');
  82. $html .= '</div>';
  83. return $html;
  84. }
  85. /**
  86. * Returns a Form validator Obj.
  87. *
  88. * @param int $id
  89. * @param string $url
  90. * @param string $action add, edit
  91. * @param array $sessionInfo
  92. *
  93. * @return FormValidator form validator obj
  94. */
  95. public function returnSimpleForm($id, $url, $action, $sessionInfo = [])
  96. {
  97. $form = new FormValidator(
  98. 'announcement',
  99. 'post',
  100. $url
  101. );
  102. $form->addHidden('session_id', $sessionInfo['id']);
  103. $form->addDateTimePicker('date', get_lang('Date'));
  104. $form->addText('subject', get_lang('Subject'));
  105. $form->addHtmlEditor('message', get_lang('Message'));
  106. $extraField = new ExtraField('scheduled_announcement');
  107. $extra = $extraField->addElements($form, $id);
  108. $js = $extra['jquery_ready_content'];
  109. $form->addHtml("<script> $(function() { $js }); </script> ");
  110. $this->setTagsInForm($form);
  111. $form->addCheckBox('sent', null, get_lang('MessageSent'));
  112. if ($action == 'edit') {
  113. $form->addButtonUpdate(get_lang('Modify'));
  114. }
  115. return $form;
  116. }
  117. /**
  118. * Returns a Form validator Obj.
  119. *
  120. * @todo the form should be auto generated
  121. *
  122. * @param string $url
  123. * @param string $action add, edit
  124. * @param array
  125. *
  126. * @return FormValidator form validator obj
  127. */
  128. public function returnForm($url, $action, $sessionInfo = [])
  129. {
  130. // Setting the form elements
  131. $header = get_lang('Add');
  132. if ($action == 'edit') {
  133. $header = get_lang('Modify');
  134. }
  135. $form = new FormValidator(
  136. 'announcement',
  137. 'post',
  138. $url
  139. );
  140. $form->addHeader($header);
  141. if ($action == 'add') {
  142. $form->addHtml(
  143. Display::return_message(
  144. nl2br(get_lang('ScheduleAnnouncementDescription')),
  145. 'normal',
  146. false
  147. )
  148. );
  149. }
  150. $form->addHidden('session_id', $sessionInfo['id']);
  151. $useBaseDate = false;
  152. $startDate = $sessionInfo['access_start_date'];
  153. $endDate = $sessionInfo['access_end_date'];
  154. if (!empty($startDate) || !empty($endDate)) {
  155. $useBaseDate = true;
  156. }
  157. $typeOptions = [
  158. 'specific_date' => get_lang('SpecificDate'),
  159. ];
  160. if ($useBaseDate) {
  161. $typeOptions['base_date'] = get_lang('BaseDate');
  162. }
  163. $form->addSelect(
  164. 'type',
  165. get_lang('Type'),
  166. $typeOptions,
  167. [
  168. 'onchange' => "javascript:
  169. if (this.options[this.selectedIndex].value == 'base_date') {
  170. document.getElementById('options').style.display = 'block';
  171. document.getElementById('specific_date').style.display = 'none';
  172. } else {
  173. document.getElementById('options').style.display = 'none';
  174. document.getElementById('specific_date').style.display = 'block';
  175. }
  176. ", ]
  177. );
  178. $form->addHtml('<div id="specific_date">');
  179. $form->addDateTimePicker('date', get_lang('Date'));
  180. $form->addHtml('</div>');
  181. $form->addHtml('<div id="options" style="display:none">');
  182. $startDate = $sessionInfo['access_start_date'];
  183. $endDate = $sessionInfo['access_end_date'];
  184. $form->addText(
  185. 'days',
  186. get_lang('Days'),
  187. false
  188. );
  189. $form->addSelect(
  190. 'moment_type',
  191. get_lang('AfterOrBefore'),
  192. [
  193. 'after' => get_lang('After'),
  194. 'before' => get_lang('Before'),
  195. ]
  196. );
  197. if (!empty($startDate)) {
  198. $options['start_date'] = get_lang('StartDate').' - '.$startDate;
  199. }
  200. if (!empty($endDate)) {
  201. $options['end_date'] = get_lang('EndDate').' - '.$endDate;
  202. }
  203. if (!empty($options)) {
  204. $form->addSelect('base_date', get_lang('BaseDate'), $options);
  205. }
  206. $form->addHtml('</div>');
  207. $form->addText('subject', get_lang('Subject'));
  208. $form->addHtmlEditor('message', get_lang('Message'));
  209. $extraField = new ExtraField('scheduled_announcement');
  210. $extra = $extraField->addElements($form);
  211. $js = $extra['jquery_ready_content'];
  212. $form->addHtml("<script> $(function() { $js }); </script> ");
  213. $this->setTagsInForm($form);
  214. if ($action == 'edit') {
  215. $form->addButtonUpdate(get_lang('Modify'));
  216. } else {
  217. $form->addButtonCreate(get_lang('Add'));
  218. }
  219. return $form;
  220. }
  221. /**
  222. * @param int $id
  223. *
  224. * @return string
  225. */
  226. public function getAttachmentToString($id)
  227. {
  228. $file = $this->getAttachment($id);
  229. if (!empty($file) && !empty($file['value'])) {
  230. $url = api_get_path(WEB_UPLOAD_PATH).$file['value'];
  231. return get_lang('Attachment').': '.Display::url(basename($file['value']), $url, ['target' => '_blank']);
  232. }
  233. return '';
  234. }
  235. /**
  236. * @param int $id
  237. *
  238. * @return array
  239. */
  240. public function getAttachment($id)
  241. {
  242. $extraFieldValue = new ExtraFieldValue('scheduled_announcement');
  243. $attachment = $extraFieldValue->get_values_by_handler_and_field_variable($id, 'attachment');
  244. return $attachment;
  245. }
  246. /**
  247. * @param int $urlId
  248. *
  249. * @return int
  250. */
  251. public function sendPendingMessages($urlId = 0)
  252. {
  253. if (!$this->allowed()) {
  254. return 0;
  255. }
  256. $messagesSent = 0;
  257. $now = api_get_utc_datetime();
  258. $result = $this->get_all();
  259. foreach ($result as $result) {
  260. if (empty($result['sent'])) {
  261. if (!empty($result['date']) && $result['date'] < $now) {
  262. $sessionId = $result['session_id'];
  263. $sessionInfo = api_get_session_info($sessionId);
  264. if (empty($sessionInfo)) {
  265. continue;
  266. }
  267. $users = SessionManager::get_users_by_session(
  268. $sessionId,
  269. 0,
  270. false,
  271. $urlId
  272. );
  273. $coachId = $sessionInfo['id_coach'];
  274. if (empty($users) || empty($coachId)) {
  275. continue;
  276. }
  277. if ($users) {
  278. $this->update(['id' => $result['id'], 'sent' => 1]);
  279. $attachments = $this->getAttachmentToString($result['id']);
  280. $subject = $result['subject'];
  281. foreach ($users as $user) {
  282. // Take original message
  283. $message = $result['message'];
  284. $userInfo = api_get_user_info($user['user_id']);
  285. $courseList = SessionManager::getCoursesInSession($sessionId);
  286. $courseInfo = [];
  287. if (!empty($courseList)) {
  288. $courseId = current($courseList);
  289. $courseInfo = api_get_course_info_by_id($courseId);
  290. }
  291. $progress = '';
  292. if (!empty($sessionInfo) && !empty($courseInfo)) {
  293. $progress = Tracking::get_avg_student_progress(
  294. $user['user_id'],
  295. $courseInfo['code'],
  296. [],
  297. $sessionId
  298. );
  299. }
  300. if (is_numeric($progress)) {
  301. $progress = $progress.'%';
  302. } else {
  303. $progress = '0%';
  304. }
  305. $startTime = api_get_local_time(
  306. $sessionInfo['access_start_date'],
  307. null,
  308. null,
  309. true
  310. );
  311. $endTime = api_get_local_time(
  312. $sessionInfo['access_end_date'],
  313. null,
  314. null,
  315. true
  316. );
  317. $generalCoach = '';
  318. $generalCoachEmail = '';
  319. if (!empty($sessionInfo['id_coach'])) {
  320. $coachInfo = api_get_user_info($sessionInfo['id_coach']);
  321. if (!empty($coachInfo)) {
  322. $generalCoach = $coachInfo['complete_name'];
  323. $generalCoachEmail = $coachInfo['email'];
  324. }
  325. }
  326. $tags = [
  327. '((session_name))' => $sessionInfo['name'],
  328. '((session_start_date))' => $startTime,
  329. '((general_coach))' => $generalCoach,
  330. '((general_coach_email))' => $generalCoachEmail,
  331. '((session_end_date))' => $endTime,
  332. '((user_complete_name))' => $userInfo['complete_name'],
  333. '((user_first_name))' => $userInfo['firstname'],
  334. '((user_last_name))' => $userInfo['lastname'],
  335. '((lp_progress))' => $progress,
  336. ];
  337. $message = str_replace(array_keys($tags), $tags, $message);
  338. $message .= $attachments;
  339. MessageManager::send_message_simple(
  340. $userInfo['user_id'],
  341. $subject,
  342. $message,
  343. $coachId
  344. );
  345. }
  346. }
  347. $messagesSent++;
  348. }
  349. }
  350. }
  351. return $messagesSent;
  352. }
  353. /**
  354. * @return array
  355. */
  356. public function getTags()
  357. {
  358. $tags = [
  359. '((session_name))',
  360. '((session_start_date))',
  361. '((session_end_date))',
  362. '((general_coach))',
  363. '((general_coach_email))',
  364. '((user_complete_name))',
  365. '((user_first_name))',
  366. '((user_last_name))',
  367. '((lp_progress))',
  368. ];
  369. return $tags;
  370. }
  371. /**
  372. * @return bool
  373. */
  374. public function allowed()
  375. {
  376. return api_get_configuration_value('allow_scheduled_announcements');
  377. }
  378. /**
  379. * @param FormValidator $form
  380. */
  381. private function setTagsInForm(&$form)
  382. {
  383. $form->addLabel(
  384. get_lang('Tags'),
  385. Display::return_message(
  386. implode('<br />', $this->getTags()),
  387. 'normal',
  388. false
  389. )
  390. );
  391. }
  392. }