Passed
Push — master ( db53d7...84ebef )
by Julito
09:47
created

AnnouncementEmail   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 316
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 162
dl 0
loc 316
rs 9.1199
c 0
b 0
f 0
wmc 41

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 3
A all_users() 0 23 4
C send() 0 82 14
B sent_to() 0 36 9
A logMailSent() 0 10 1
A sendAnnouncementEmailToMySelf() 0 12 1
A subject() 0 12 2
A attachment() 0 16 3
A message() 0 42 4

How to fix   Complexity   

Complex Class

Complex classes like AnnouncementEmail often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AnnouncementEmail, and based on these observations, apply Extract Interface, too.

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