AnnouncementEmail.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Announcement Email.
  5. *
  6. * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
  7. * @author Julio Montoya <gugli100@gmail.com> Adding session support
  8. */
  9. class AnnouncementEmail
  10. {
  11. public $session_id = null;
  12. public $logger;
  13. protected $course = null;
  14. protected $announcement = null;
  15. /**
  16. * @param array $courseInfo
  17. * @param int $sessionId
  18. * @param int $announcementId
  19. * @param \Monolog\Logger $logger
  20. */
  21. public function __construct($courseInfo, $sessionId, $announcementId, $logger = null)
  22. {
  23. if (empty($courseInfo)) {
  24. $courseInfo = api_get_course_info();
  25. }
  26. $this->course = $courseInfo;
  27. $this->session_id = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
  28. if (is_numeric($announcementId)) {
  29. $this->announcement = AnnouncementManager::get_by_id($courseInfo['real_id'], $announcementId);
  30. }
  31. $this->logger = $logger;
  32. }
  33. /**
  34. * Course info.
  35. *
  36. * @param string $key
  37. *
  38. * @return string|null
  39. */
  40. public function course($key = '')
  41. {
  42. $result = $key ? $this->course[$key] : $this->course;
  43. $result = $key == 'id' ? intval($result) : $result;
  44. return $result;
  45. }
  46. /**
  47. * Announcement info.
  48. *
  49. * @param string $key
  50. *
  51. * @return array
  52. */
  53. public function announcement($key = '')
  54. {
  55. $result = $key ? $this->announcement[$key] : $this->announcement;
  56. $result = $key == 'id' ? intval($result) : $result;
  57. return $result;
  58. }
  59. /**
  60. * Returns either all course users or all session users depending on whether
  61. * session is turned on or not.
  62. *
  63. * @return array
  64. */
  65. public function all_users()
  66. {
  67. $courseCode = $this->course('code');
  68. if (empty($this->session_id)) {
  69. $group_id = api_get_group_id();
  70. if (empty($group_id)) {
  71. $userList = CourseManager::get_user_list_from_course_code($courseCode);
  72. } else {
  73. $userList = GroupManager::get_users($group_id);
  74. $new_user_list = [];
  75. foreach ($userList as $user) {
  76. $new_user_list[] = ['user_id' => $user];
  77. }
  78. $userList = $new_user_list;
  79. }
  80. } else {
  81. $userList = CourseManager::get_user_list_from_course_code(
  82. $courseCode,
  83. $this->session_id
  84. );
  85. }
  86. return $userList;
  87. }
  88. /**
  89. * Returns users and groups an announcement item has been sent to.
  90. *
  91. * @return array Array of users and groups to whom the element has been sent
  92. */
  93. public function sent_to_info()
  94. {
  95. $result = [];
  96. $result['groups'] = [];
  97. $result['users'] = [];
  98. $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
  99. $tool = TOOL_ANNOUNCEMENT;
  100. $id = $this->announcement('id');
  101. $course_id = $this->course('real_id');
  102. $sessionCondition = api_get_session_condition($this->session_id);
  103. $sql = "SELECT to_group_id, to_user_id
  104. FROM $table
  105. WHERE
  106. c_id = $course_id AND
  107. tool = '$tool' AND
  108. ref = $id
  109. $sessionCondition";
  110. $rs = Database::query($sql);
  111. while ($row = Database::fetch_array($rs, 'ASSOC')) {
  112. // if to_user_id <> 0 then it is sent to a specific user
  113. $user_id = $row['to_user_id'];
  114. if (!empty($user_id)) {
  115. $result['users'][] = (int) $user_id;
  116. // If user is set then skip the group
  117. continue;
  118. }
  119. // if to_group_id is null then it is sent to a specific user
  120. // if to_group_id = 0 then it is sent to everybody
  121. $group_id = $row['to_group_id'];
  122. if (!empty($group_id)) {
  123. $result['groups'][] = (int) $group_id;
  124. }
  125. }
  126. return $result;
  127. }
  128. /**
  129. * Returns the list of user info to which an announcement was sent.
  130. * This function returns a list of actual users even when recipient
  131. * are groups.
  132. *
  133. * @return array
  134. */
  135. public function sent_to()
  136. {
  137. $sent_to = $this->sent_to_info();
  138. $users = $sent_to['users'];
  139. $users = $users ? $users : [];
  140. $groups = $sent_to['groups'];
  141. if ($users) {
  142. $users = UserManager::get_user_list_by_ids($users, true);
  143. }
  144. if (!empty($groups)) {
  145. $groupUsers = GroupManager::get_groups_users($groups);
  146. $groupUsers = UserManager::get_user_list_by_ids($groupUsers, true);
  147. if (!empty($groupUsers)) {
  148. $users = array_merge($users, $groupUsers);
  149. }
  150. }
  151. if (empty($users)) {
  152. if (!empty($this->logger)) {
  153. $this->logger->addInfo('User list is empty. No users found. Trying all_users()');
  154. }
  155. $users = self::all_users();
  156. }
  157. // Clean users just in case
  158. $newListUsers = [];
  159. if (!empty($users)) {
  160. foreach ($users as $user) {
  161. $newListUsers[$user['user_id']] = ['user_id' => $user['user_id']];
  162. }
  163. }
  164. return $newListUsers;
  165. }
  166. /**
  167. * Email subject.
  168. *
  169. * @param bool $directMessage
  170. *
  171. * @return string
  172. */
  173. public function subject($directMessage = false)
  174. {
  175. if ($directMessage) {
  176. $result = $this->announcement('title');
  177. } else {
  178. $result = $this->course('title').' - '.$this->announcement('title');
  179. }
  180. $result = stripslashes($result);
  181. return $result;
  182. }
  183. /**
  184. * Email message.
  185. *
  186. * @param int $receiverUserId
  187. *
  188. * @return string
  189. */
  190. public function message($receiverUserId)
  191. {
  192. $content = $this->announcement('content');
  193. $session_id = $this->session_id;
  194. $courseCode = $this->course('code');
  195. $content = AnnouncementManager::parseContent(
  196. $receiverUserId,
  197. $content,
  198. $courseCode,
  199. $session_id
  200. );
  201. // Build the link by hand because api_get_cidreq() doesn't accept course params
  202. $course_param = 'cidReq='.$courseCode.'&id_session='.$session_id.'&gidReq='.api_get_group_id();
  203. $course_name = $this->course('title');
  204. $result = "<div>$content</div>";
  205. // Adding attachment
  206. $attachment = $this->attachment();
  207. if (!empty($attachment)) {
  208. $result .= '<br />';
  209. $result .= Display::url(
  210. $attachment['filename'],
  211. api_get_path(WEB_CODE_PATH).'announcements/download.php?file='.basename($attachment['path']).'&'.$course_param
  212. );
  213. $result .= '<br />';
  214. }
  215. $result .= '<hr />';
  216. $userInfo = api_get_user_info();
  217. if (!empty($userInfo)) {
  218. $result .= '<a href="mailto:'.$userInfo['mail'].'">'.$userInfo['complete_name'].'</a><br/>';
  219. }
  220. $result .= '<a href="'.api_get_path(WEB_CODE_PATH).'announcements/announcements.php?'.$course_param.'">'.$course_name.'</a><br/>';
  221. return $result;
  222. }
  223. /**
  224. * Returns the one file that can be attached to an announcement.
  225. *
  226. * @return array
  227. */
  228. public function attachment()
  229. {
  230. $result = [];
  231. $table = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
  232. $id = $this->announcement('id');
  233. $course_id = $this->course('real_id');
  234. $sql = "SELECT * FROM $table
  235. WHERE c_id = $course_id AND announcement_id = $id ";
  236. $rs = Database::query($sql);
  237. $course_path = $this->course('directory');
  238. while ($row = Database::fetch_array($rs)) {
  239. $path = api_get_path(SYS_COURSE_PATH).$course_path.'/upload/announcements/'.$row['path'];
  240. $filename = $row['filename'];
  241. $result[] = ['path' => $path, 'filename' => $filename];
  242. }
  243. $result = $result ? reset($result) : [];
  244. return $result;
  245. }
  246. /**
  247. * Send announcement by email to myself.
  248. */
  249. public function sendAnnouncementEmailToMySelf()
  250. {
  251. $userId = api_get_user_id();
  252. $subject = $this->subject();
  253. $message = $this->message($userId);
  254. MessageManager::send_message_simple(
  255. $userId,
  256. $subject,
  257. $message,
  258. api_get_user_id(),
  259. false,
  260. true
  261. );
  262. }
  263. /**
  264. * Send emails to users.
  265. *
  266. * @param bool $sendToUsersInSession
  267. * @param bool $sendToDrhUsers send a copy of the message to the DRH users
  268. * @param int $senderId related to the main user
  269. * @param bool $directMessage
  270. *
  271. * @return array
  272. */
  273. public function send($sendToUsersInSession = false, $sendToDrhUsers = false, $senderId = 0, $directMessage = false)
  274. {
  275. $senderId = empty($senderId) ? api_get_user_id() : (int) $senderId;
  276. $subject = $this->subject($directMessage);
  277. // Send email one by one to avoid antispam
  278. $users = $this->sent_to();
  279. $batchSize = 20;
  280. $counter = 1;
  281. $em = Database::getManager();
  282. if (empty($users) && !empty($this->logger)) {
  283. $this->logger->addInfo('User list is empty. No emails will be sent.');
  284. }
  285. $messageSentTo = [];
  286. foreach ($users as $user) {
  287. $message = $this->message($user['user_id']);
  288. $wasSent = MessageManager::messageWasAlreadySent($senderId, $user['user_id'], $subject, $message);
  289. if ($wasSent === false) {
  290. if (!empty($this->logger)) {
  291. $this->logger->addInfo(
  292. 'Announcement: #'.$this->announcement('id').'. Send email to user: #'.$user['user_id']
  293. );
  294. }
  295. $messageSentTo[] = $user['user_id'];
  296. MessageManager::send_message_simple(
  297. $user['user_id'],
  298. $subject,
  299. $message,
  300. $senderId,
  301. $sendToDrhUsers,
  302. true
  303. );
  304. } else {
  305. if (!empty($this->logger)) {
  306. $this->logger->addInfo(
  307. 'Message "'.$subject.'" was already sent. Announcement: #'.$this->announcement('id').'.
  308. User: #'.$user['user_id']
  309. );
  310. }
  311. }
  312. if (($counter % $batchSize) === 0) {
  313. $em->flush();
  314. $em->clear();
  315. }
  316. $counter++;
  317. }
  318. if ($sendToUsersInSession) {
  319. $sessionList = SessionManager::get_session_by_course($this->course['real_id']);
  320. if (!empty($sessionList)) {
  321. foreach ($sessionList as $sessionInfo) {
  322. $sessionId = $sessionInfo['id'];
  323. $message = $this->message(null);
  324. $userList = CourseManager::get_user_list_from_course_code(
  325. $this->course['code'],
  326. $sessionId
  327. );
  328. if (!empty($userList)) {
  329. foreach ($userList as $user) {
  330. $messageSentTo[] = $user['user_id'];
  331. MessageManager::send_message_simple(
  332. $user['user_id'],
  333. $subject,
  334. $message,
  335. $senderId,
  336. false,
  337. true
  338. );
  339. }
  340. }
  341. }
  342. }
  343. }
  344. $this->logMailSent();
  345. $messageSentTo = array_unique($messageSentTo);
  346. return $messageSentTo;
  347. }
  348. /**
  349. * Store that emails where sent.
  350. */
  351. public function logMailSent()
  352. {
  353. $id = $this->announcement('id');
  354. $courseId = $this->course('real_id');
  355. $table = Database::get_course_table(TABLE_ANNOUNCEMENT);
  356. $sql = "UPDATE $table SET
  357. email_sent = 1
  358. WHERE
  359. c_id = $courseId AND
  360. id = $id AND
  361. session_id = {$this->session_id}
  362. ";
  363. Database::query($sql);
  364. }
  365. }