ScheduledAnnouncement.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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 = array('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 = array())
  38. {
  39. return Database::select(
  40. '*',
  41. $this->table,
  42. array('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. array(),
  54. 'first'
  55. );
  56. return $row['count'];
  57. }
  58. /**
  59. * Displays the title + grid
  60. */
  61. public function getGrid($sessionId)
  62. {
  63. // action links
  64. $action = '<div class="actions" style="margin-bottom:20px">';
  65. $action .= Display::url(
  66. Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM),
  67. api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$sessionId
  68. );
  69. $action .= '<a href="'.api_get_self().'?action=add&session_id='.$sessionId.'">'.
  70. Display::return_icon('add.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
  71. $action .= '<a href="scheduled_announcement.php?action=run&session_id='.$sessionId.'">'.
  72. Display::return_icon('mail_send.png', get_lang('Send'), '', ICON_SIZE_MEDIUM).
  73. '</a>';
  74. $action .= '</div>';
  75. $html = $action;
  76. $html .= '<div id="session-table" class="table-responsive">';
  77. $html .= Display::grid_html('programmed');
  78. $html .= '</div>';
  79. return $html;
  80. }
  81. /**
  82. * Returns a Form validator Obj
  83. * @param string $url
  84. * @param string $action add, edit
  85. *
  86. * @return FormValidator form validator obj
  87. */
  88. public function returnSimpleForm($url, $action, $sessionInfo = [])
  89. {
  90. $form = new FormValidator(
  91. 'announcement',
  92. 'post',
  93. $url
  94. );
  95. $form->addHidden('session_id', $sessionInfo['id']);
  96. $form->addDateTimePicker('date', get_lang('Date'));
  97. $form->addText('subject', get_lang('Subject'));
  98. $form->addHtmlEditor('message', get_lang('Message'));
  99. $this->setTagsInForm($form);
  100. $form->addCheckBox('sent', null, get_lang('MessageSent'));
  101. if ($action == 'edit') {
  102. $form->addButtonUpdate(get_lang('Modify'));
  103. }
  104. return $form;
  105. }
  106. /**
  107. * @param FormValidator $form
  108. */
  109. private function setTagsInForm(& $form)
  110. {
  111. $form->addLabel(
  112. get_lang('Tags'),
  113. Display::return_message(
  114. implode('<br />', $this->getTags()),
  115. 'normal',
  116. false
  117. )
  118. );
  119. }
  120. /**
  121. * Returns a Form validator Obj
  122. * @todo the form should be auto generated
  123. * @param string $url
  124. * @param string $action add, edit
  125. * @param array
  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->addElement('html', '<div id="specific_date">');
  179. $form->addDateTimePicker('date', get_lang('Date'));
  180. $form->addElement('html', '</div>');
  181. $form->addElement('html', '<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->addElement('html', '</div>');
  207. $form->addText('subject', get_lang('Subject'));
  208. $form->addHtmlEditor('message', get_lang('Message'));
  209. $this->setTagsInForm($form);
  210. if ($action == 'edit') {
  211. $form->addButtonUpdate(get_lang('Modify'));
  212. } else {
  213. $form->addButtonCreate(get_lang('Add'));
  214. }
  215. return $form;
  216. }
  217. /**
  218. * @param int $urlId
  219. *
  220. * @return int
  221. */
  222. public function sendPendingMessages($urlId = 0)
  223. {
  224. if (!$this->allowed()) {
  225. return 0;
  226. }
  227. $messagesSent = 0;
  228. $now = api_get_utc_datetime();
  229. $result = $this->get_all();
  230. foreach ($result as $result) {
  231. if (empty($result['sent'])) {
  232. if (!empty($result['date']) && $result['date'] < $now) {
  233. $sessionId = $result['session_id'];
  234. $sessionInfo = api_get_session_info($sessionId);
  235. if (empty($sessionInfo)) {
  236. continue;
  237. }
  238. $users = SessionManager::get_users_by_session(
  239. $sessionId,
  240. '0',
  241. false,
  242. $urlId
  243. );
  244. if (empty($users)) {
  245. continue;
  246. }
  247. self::update(['id' => $result['id'], 'sent' => 1]);
  248. $subject = $result['subject'];
  249. if ($users) {
  250. foreach ($users as $user) {
  251. // Take original message
  252. $message = $result['message'];
  253. $userInfo = api_get_user_info($user['user_id']);
  254. $courseList = SessionManager::getCoursesInSession($sessionId);
  255. $courseInfo = [];
  256. if (!empty($courseList)) {
  257. $courseId = current($courseList);
  258. $courseInfo = api_get_course_info_by_id($courseId);
  259. }
  260. $progress = '';
  261. if (!empty($sessionInfo) && !empty($courseInfo)) {
  262. $progress = Tracking::get_avg_student_progress(
  263. $user['user_id'],
  264. $courseInfo['code'],
  265. null,
  266. $sessionId
  267. );
  268. }
  269. if (is_numeric($progress)) {
  270. $progress = $progress.'%';
  271. } else {
  272. $progress = '0%';
  273. }
  274. $startTime = api_get_local_time(
  275. $sessionInfo['access_start_date'],
  276. null,
  277. null,
  278. true
  279. );
  280. $endTime = api_get_local_time(
  281. $sessionInfo['access_end_date'],
  282. null,
  283. null,
  284. true
  285. );
  286. $generalCoach = '';
  287. $generalCoachEmail = '';
  288. if (!empty($sessionInfo['coach_id'])) {
  289. $coachInfo = api_get_user_info($sessionInfo['coach_id']);
  290. if (!empty($coachInfo)) {
  291. $generalCoach = $coachInfo['complete_name'];
  292. $generalCoachEmail = $coachInfo['email'];
  293. }
  294. }
  295. $tags = [
  296. '((session_name))' => $sessionInfo['name'],
  297. '((session_start_date))' => $startTime,
  298. '((general_coach))' => $generalCoach,
  299. '((general_coach_email))' => $generalCoachEmail,
  300. '((session_end_date))' => $endTime,
  301. '((user_complete_name))' => $userInfo['complete_name'],
  302. '((user_first_name))' => $userInfo['firstname'],
  303. '((user_last_name))' => $userInfo['lastname'],
  304. '((lp_progress))' => $progress,
  305. ];
  306. $message = str_replace(array_keys($tags), $tags, $message);
  307. MessageManager::send_message(
  308. $userInfo['user_id'],
  309. $subject,
  310. $message
  311. );
  312. }
  313. }
  314. $messagesSent++;
  315. }
  316. }
  317. }
  318. return $messagesSent;
  319. }
  320. /**
  321. * @return array
  322. */
  323. public function getTags()
  324. {
  325. $tags = [
  326. '((session_name))',
  327. '((session_start_date))',
  328. '((session_end_date))',
  329. '((general_coach))',
  330. '((general_coach_email))',
  331. '((user_complete_name))',
  332. '((user_first_name))',
  333. '((user_last_name))',
  334. '((lp_progress))'
  335. ];
  336. return $tags;
  337. }
  338. /**
  339. * @return bool
  340. */
  341. public function allowed()
  342. {
  343. return api_get_configuration_value('allow_scheduled_announcements');
  344. }
  345. }