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