Passed
Push — master ( fba8cd...2c308e )
by Julito
09:56 queued 11s
created

AnnouncementEmail::course()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 4
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
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
0 ignored issues
show
Unused Code introduced by
$sql = 'SELECT to_group_... '.$sessionCondition is not reachable.

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, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
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