Passed
Push — master ( 8f8ee7...6565b2 )
by Julito
11:41
created

AnnouncementEmail   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 307
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 157
dl 0
loc 307
rs 9.44
c 0
b 0
f 0
wmc 37

9 Methods

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