ScheduledAnnouncement.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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. * @param int $sessionId
  61. * @return string
  62. */
  63. public function getGrid($sessionId)
  64. {
  65. // action links
  66. $action = '<div class="actions" style="margin-bottom:20px">';
  67. $action .= Display::url(
  68. Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM),
  69. api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$sessionId
  70. );
  71. $action .= '<a href="'.api_get_self().'?action=add&session_id='.$sessionId.'">'.
  72. Display::return_icon('add.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
  73. $action .= '<a href="scheduled_announcement.php?action=run&session_id='.$sessionId.'">'.
  74. Display::return_icon('tuning.png', get_lang('SendManuallyPendingAnnouncements'), '', ICON_SIZE_MEDIUM).
  75. '</a>';
  76. $action .= '</div>';
  77. $html = $action;
  78. $html .= '<div id="session-table" class="table-responsive">';
  79. $html .= Display::grid_html('programmed');
  80. $html .= '</div>';
  81. return $html;
  82. }
  83. /**
  84. * Returns a Form validator Obj
  85. * @param string $url
  86. * @param string $action add, edit
  87. * @param array $sessionInfo
  88. *
  89. * @return FormValidator form validator obj
  90. */
  91. public function returnSimpleForm($url, $action, $sessionInfo = [])
  92. {
  93. $form = new FormValidator(
  94. 'announcement',
  95. 'post',
  96. $url
  97. );
  98. $form->addHidden('session_id', $sessionInfo['id']);
  99. $form->addDateTimePicker('date', get_lang('Date'));
  100. $form->addText('subject', get_lang('Subject'));
  101. $form->addHtmlEditor('message', get_lang('Message'));
  102. $this->setTagsInForm($form);
  103. $form->addCheckBox('sent', null, get_lang('MessageSent'));
  104. if ($action == 'edit') {
  105. $form->addButtonUpdate(get_lang('Modify'));
  106. }
  107. return $form;
  108. }
  109. /**
  110. * @param FormValidator $form
  111. */
  112. private function setTagsInForm(& $form)
  113. {
  114. $form->addLabel(
  115. get_lang('Tags'),
  116. Display::return_message(
  117. implode('<br />', $this->getTags()),
  118. 'normal',
  119. false
  120. )
  121. );
  122. }
  123. /**
  124. * Returns a Form validator Obj
  125. * @todo the form should be auto generated
  126. * @param string $url
  127. * @param string $action add, edit
  128. * @param array
  129. * @return FormValidator form validator obj
  130. */
  131. public function returnForm($url, $action, $sessionInfo = [])
  132. {
  133. // Setting the form elements
  134. $header = get_lang('Add');
  135. if ($action == 'edit') {
  136. $header = get_lang('Modify');
  137. }
  138. $form = new FormValidator(
  139. 'announcement',
  140. 'post',
  141. $url
  142. );
  143. $form->addHeader($header);
  144. if ($action == 'add') {
  145. $form->addHtml(
  146. Display::return_message(
  147. nl2br(get_lang('ScheduleAnnouncementDescription')),
  148. 'normal',
  149. false
  150. )
  151. );
  152. }
  153. $form->addHidden('session_id', $sessionInfo['id']);
  154. $useBaseDate = false;
  155. $startDate = $sessionInfo['access_start_date'];
  156. $endDate = $sessionInfo['access_end_date'];
  157. if (!empty($startDate) || !empty($endDate)) {
  158. $useBaseDate = true;
  159. }
  160. $typeOptions = [
  161. 'specific_date' => get_lang('SpecificDate')
  162. ];
  163. if ($useBaseDate) {
  164. $typeOptions['base_date'] = get_lang('BaseDate');
  165. }
  166. $form->addSelect(
  167. 'type',
  168. get_lang('Type'),
  169. $typeOptions,
  170. [
  171. 'onchange' => "javascript:
  172. if (this.options[this.selectedIndex].value == 'base_date') {
  173. document.getElementById('options').style.display = 'block';
  174. document.getElementById('specific_date').style.display = 'none';
  175. } else {
  176. document.getElementById('options').style.display = 'none';
  177. document.getElementById('specific_date').style.display = 'block';
  178. }
  179. "]
  180. );
  181. $form->addHtml('<div id="specific_date">');
  182. $form->addDateTimePicker('date', get_lang('Date'));
  183. $form->addHtml('</div>');
  184. $form->addHtml('<div id="options" style="display:none">');
  185. $startDate = $sessionInfo['access_start_date'];
  186. $endDate = $sessionInfo['access_end_date'];
  187. $form->addText(
  188. 'days',
  189. get_lang('Days'),
  190. false
  191. );
  192. $form->addSelect(
  193. 'moment_type',
  194. get_lang('AfterOrBefore'),
  195. [
  196. 'after' => get_lang('After'),
  197. 'before' => get_lang('Before'),
  198. ]
  199. );
  200. if (!empty($startDate)) {
  201. $options['start_date'] = get_lang('StartDate').' - '.$startDate;
  202. }
  203. if (!empty($endDate)) {
  204. $options['end_date'] = get_lang('EndDate').' - '.$endDate;
  205. }
  206. if (!empty($options)) {
  207. $form->addSelect('base_date', get_lang('BaseDate'), $options);
  208. }
  209. $form->addHtml('</div>');
  210. $form->addText('subject', get_lang('Subject'));
  211. $form->addHtmlEditor('message', get_lang('Message'));
  212. $this->setTagsInForm($form);
  213. if ($action == 'edit') {
  214. $form->addButtonUpdate(get_lang('Modify'));
  215. } else {
  216. $form->addButtonCreate(get_lang('Add'));
  217. }
  218. return $form;
  219. }
  220. /**
  221. * @param int $urlId
  222. *
  223. * @return int
  224. */
  225. public function sendPendingMessages($urlId = 0)
  226. {
  227. if (!$this->allowed()) {
  228. return 0;
  229. }
  230. $messagesSent = 0;
  231. $now = api_get_utc_datetime();
  232. $result = $this->get_all();
  233. foreach ($result as $result) {
  234. if (empty($result['sent'])) {
  235. if (!empty($result['date']) && $result['date'] < $now) {
  236. $sessionId = $result['session_id'];
  237. $sessionInfo = api_get_session_info($sessionId);
  238. if (empty($sessionInfo)) {
  239. continue;
  240. }
  241. $users = SessionManager::get_users_by_session(
  242. $sessionId,
  243. '0',
  244. false,
  245. $urlId
  246. );
  247. if (empty($users)) {
  248. continue;
  249. }
  250. self::update(['id' => $result['id'], 'sent' => 1]);
  251. $subject = $result['subject'];
  252. if ($users) {
  253. foreach ($users as $user) {
  254. // Take original message
  255. $message = $result['message'];
  256. $userInfo = api_get_user_info($user['user_id']);
  257. $courseList = SessionManager::getCoursesInSession($sessionId);
  258. $courseInfo = [];
  259. if (!empty($courseList)) {
  260. $courseId = current($courseList);
  261. $courseInfo = api_get_course_info_by_id($courseId);
  262. }
  263. $progress = '';
  264. if (!empty($sessionInfo) && !empty($courseInfo)) {
  265. $progress = Tracking::get_avg_student_progress(
  266. $user['user_id'],
  267. $courseInfo['code'],
  268. null,
  269. $sessionId
  270. );
  271. }
  272. if (is_numeric($progress)) {
  273. $progress = $progress.'%';
  274. } else {
  275. $progress = '0%';
  276. }
  277. $startTime = api_get_local_time(
  278. $sessionInfo['access_start_date'],
  279. null,
  280. null,
  281. true
  282. );
  283. $endTime = api_get_local_time(
  284. $sessionInfo['access_end_date'],
  285. null,
  286. null,
  287. true
  288. );
  289. $generalCoach = '';
  290. $generalCoachEmail = '';
  291. if (!empty($sessionInfo['coach_id'])) {
  292. $coachInfo = api_get_user_info($sessionInfo['coach_id']);
  293. if (!empty($coachInfo)) {
  294. $generalCoach = $coachInfo['complete_name'];
  295. $generalCoachEmail = $coachInfo['email'];
  296. }
  297. }
  298. $tags = [
  299. '((session_name))' => $sessionInfo['name'],
  300. '((session_start_date))' => $startTime,
  301. '((general_coach))' => $generalCoach,
  302. '((general_coach_email))' => $generalCoachEmail,
  303. '((session_end_date))' => $endTime,
  304. '((user_complete_name))' => $userInfo['complete_name'],
  305. '((user_first_name))' => $userInfo['firstname'],
  306. '((user_last_name))' => $userInfo['lastname'],
  307. '((lp_progress))' => $progress,
  308. ];
  309. $message = str_replace(array_keys($tags), $tags, $message);
  310. MessageManager::send_message(
  311. $userInfo['user_id'],
  312. $subject,
  313. $message
  314. );
  315. }
  316. }
  317. $messagesSent++;
  318. }
  319. }
  320. }
  321. return $messagesSent;
  322. }
  323. /**
  324. * @return array
  325. */
  326. public function getTags()
  327. {
  328. $tags = [
  329. '((session_name))',
  330. '((session_start_date))',
  331. '((session_end_date))',
  332. '((general_coach))',
  333. '((general_coach_email))',
  334. '((user_complete_name))',
  335. '((user_first_name))',
  336. '((user_last_name))',
  337. '((lp_progress))'
  338. ];
  339. return $tags;
  340. }
  341. /**
  342. * @return bool
  343. */
  344. public function allowed()
  345. {
  346. return api_get_configuration_value('allow_scheduled_announcements');
  347. }
  348. }