Passed
Push — webservicelpcreate ( d8cb35 )
by
unknown
13:48
created

Notification::getDefaultPlatformSenderEmail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Notification class
6
 * This class provides methods for the Notification management.
7
 * Include/require it in your code to use its features.
8
 */
9
class Notification extends Model
10
{
11
    // mail_notify_message ("At once", "Daily", "No")
12
    const NOTIFY_MESSAGE_AT_ONCE = 1;
13
    const NOTIFY_MESSAGE_DAILY = 8;
14
    const NOTIFY_MESSAGE_WEEKLY = 12;
15
    const NOTIFY_MESSAGE_NO = 0;
16
17
    // mail_notify_invitation ("At once", "Daily", "No")
18
    const NOTIFY_INVITATION_AT_ONCE = 1;
19
    const NOTIFY_INVITATION_DAILY = 8;
20
    const NOTIFY_INVITATION_WEEKLY = 12;
21
    const NOTIFY_INVITATION_NO = 0;
22
23
    // mail_notify_group_message ("At once", "Daily", "No")
24
    const NOTIFY_GROUP_AT_ONCE = 1;
25
    const NOTIFY_GROUP_DAILY = 8;
26
    const NOTIFY_GROUP_WEEKLY = 12;
27
    const NOTIFY_GROUP_NO = 0;
28
29
    // Notification types
30
    const NOTIFICATION_TYPE_MESSAGE = 1;
31
    const NOTIFICATION_TYPE_INVITATION = 2;
32
    const NOTIFICATION_TYPE_GROUP = 3;
33
    const NOTIFICATION_TYPE_WALL_MESSAGE = 4;
34
    const NOTIFICATION_TYPE_DIRECT_MESSAGE = 5;
35
    public $table;
36
    public $columns = [
37
        'id',
38
        'dest_user_id',
39
        'dest_mail',
40
        'title',
41
        'content',
42
        'send_freq',
43
        'created_at',
44
        'sent_at',
45
    ];
46
47
    //Max length of the notification.content field
48
    public $max_content_length = 254;
49
    public $debug = false;
50
51
    /* message, invitation, group messages */
52
    public $type;
53
    public $adminName;
54
    public $adminEmail;
55
    public $titlePrefix;
56
57
    /**
58
     * Constructor.
59
     */
60
    public function __construct()
61
    {
62
        // Get config from mail.conf.php, as loaded by global.inc.php
63
        $platform_email = $GLOBALS['platform_email'];
64
        $this->table = Database::get_main_table(TABLE_NOTIFICATION);
65
        if (!empty($platform_email['SMTP_FROM_EMAIL'])) {
66
            $this->adminEmail = $platform_email['SMTP_FROM_EMAIL'];
67
            if (!empty($platform_email['SMTP_FROM_NAME'])) {
68
                $this->adminName = $platform_email['SMTP_FROM_NAME'];
69
            }
70
        } else {
71
            // Default no-reply email
72
            $this->adminEmail = api_get_setting('noreply_email_address');
73
            $this->adminName = api_get_setting('siteName');
74
            $this->titlePrefix = '['.api_get_setting('siteName').'] ';
75
76
            // If no-reply email doesn't exist use the admin name/email
77
            if (empty($this->adminEmail)) {
78
                $this->adminEmail = api_get_setting('emailAdministrator');
79
                $this->adminName = api_get_person_name(
80
                    api_get_setting('administratorName'),
81
                    api_get_setting('administratorSurname'),
82
                    null,
83
                    PERSON_NAME_EMAIL_ADDRESS
84
                );
85
            }
86
        }
87
    }
88
89
    /**
90
     * @return string
91
     */
92
    public function getTitlePrefix()
93
    {
94
        return $this->titlePrefix;
95
    }
96
97
    /**
98
     * @return string
99
     */
100
    public function getDefaultPlatformSenderEmail()
101
    {
102
        return $this->adminEmail;
103
    }
104
105
    /**
106
     * @return string
107
     */
108
    public function getDefaultPlatformSenderName()
109
    {
110
        return $this->adminName;
111
    }
112
113
    /**
114
     *  Send the notifications.
115
     *
116
     *  @param int $frequency notification frequency
117
     */
118
    public function send($frequency = 8)
119
    {
120
        $notifications = $this->find(
121
            'all',
122
            ['where' => ['sent_at IS NULL AND send_freq = ?' => $frequency]]
123
        );
124
125
        if (!empty($notifications)) {
126
            foreach ($notifications as $item_to_send) {
127
                // Sending email
128
                api_mail_html(
129
                    $item_to_send['dest_mail'],
130
                    $item_to_send['dest_mail'],
131
                    Security::filter_terms($item_to_send['title']),
132
                    Security::filter_terms($item_to_send['content']),
133
                    $this->adminName,
134
                    $this->adminEmail
135
                );
136
                if ($this->debug) {
137
                    error_log('Sending message to: '.$item_to_send['dest_mail']);
138
                }
139
140
                // Updating
141
                $item_to_send['sent_at'] = api_get_utc_datetime();
142
                $this->update($item_to_send);
143
                if ($this->debug) {
144
                    error_log('Updating record : '.print_r($item_to_send, 1));
0 ignored issues
show
Bug introduced by
Are you sure print_r($item_to_send, 1) of type string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

144
                    error_log('Updating record : './** @scrutinizer ignore-type */ print_r($item_to_send, 1));
Loading history...
145
                }
146
            }
147
        }
148
    }
149
150
    /**
151
     * @param string $title
152
     * @param array  $senderInfo
153
     * @param bool   $forceTitleWhenSendingEmail force the use of $title as subject instead of "You have a new message"
154
     *
155
     * @return string
156
     */
157
    public function formatTitle($title, $senderInfo, $forceTitleWhenSendingEmail = false)
158
    {
159
        $hook = HookNotificationTitle::create();
160
        if (!empty($hook)) {
161
            $hook->setEventData(['title' => $title]);
162
            $data = $hook->notifyNotificationTitle(HOOK_EVENT_TYPE_PRE);
163
            if (isset($data['title'])) {
164
                $title = $data['title'];
165
            }
166
        }
167
168
        $newTitle = $this->getTitlePrefix();
169
170
        switch ($this->type) {
171
            case self::NOTIFICATION_TYPE_MESSAGE:
172
                if (!empty($senderInfo)) {
173
                    $senderName = api_get_person_name(
174
                        $senderInfo['firstname'],
175
                        $senderInfo['lastname'],
176
                        null,
177
                        PERSON_NAME_EMAIL_ADDRESS
178
                    );
179
                    $newTitle .= sprintf(get_lang('YouHaveANewMessageFromX'), $senderName);
180
                }
181
                break;
182
            case self::NOTIFICATION_TYPE_DIRECT_MESSAGE:
183
                $newTitle = $title;
184
                break;
185
            case self::NOTIFICATION_TYPE_INVITATION:
186
                if (!empty($senderInfo)) {
187
                    $senderName = api_get_person_name(
188
                        $senderInfo['firstname'],
189
                        $senderInfo['lastname'],
190
                        null,
191
                        PERSON_NAME_EMAIL_ADDRESS
192
                    );
193
                    $newTitle .= sprintf(get_lang('YouHaveANewInvitationFromX'), $senderName);
194
                }
195
                break;
196
            case self::NOTIFICATION_TYPE_GROUP:
197
                if (!empty($senderInfo)) {
198
                    $senderName = $senderInfo['group_info']['name'];
199
                    $newTitle .= sprintf(get_lang('YouHaveReceivedANewMessageInTheGroupX'), $senderName);
200
                    $senderName = api_get_person_name(
201
                        $senderInfo['user_info']['firstname'],
202
                        $senderInfo['user_info']['lastname'],
203
                        null,
204
                        PERSON_NAME_EMAIL_ADDRESS
205
                    );
206
                    $newTitle .= $senderName;
207
                }
208
                break;
209
        }
210
211
        // The title won't be changed, it will be used as is
212
        if ($forceTitleWhenSendingEmail) {
213
            $newTitle = $title;
214
        }
215
216
        if (!empty($hook)) {
217
            $hook->setEventData(['title' => $newTitle]);
218
            $data = $hook->notifyNotificationTitle(HOOK_EVENT_TYPE_POST);
219
            if (isset($data['title'])) {
220
                $newTitle = $data['title'];
221
            }
222
        }
223
224
        return $newTitle;
225
    }
226
227
    /**
228
     * Save message notification.
229
     *
230
     * @param int    $type                       message type
231
     *                                           NOTIFICATION_TYPE_MESSAGE,
232
     *                                           NOTIFICATION_TYPE_INVITATION,
233
     *                                           NOTIFICATION_TYPE_GROUP
234
     * @param int    $messageId
235
     * @param array  $userList                   recipients: user list of ids
236
     * @param string $title
237
     * @param string $content
238
     * @param array  $senderInfo                 result of api_get_user_info() or GroupPortalManager:get_group_data()
239
     * @param array  $attachments
240
     * @param array  $smsParameters
241
     * @param bool   $forceTitleWhenSendingEmail force the use of $title as subject instead of "You have a new message"
242
     */
243
    public function saveNotification(
244
        $messageId,
245
        $type,
246
        $userList,
247
        $title,
248
        $content,
249
        $senderInfo = [],
250
        $attachments = [],
251
        $smsParameters = [],
252
        $forceTitleWhenSendingEmail = false
253
    ) {
254
        $this->type = (int) $type;
255
        $messageId = (int) $messageId;
256
        $content = $this->formatContent($messageId, $content, $senderInfo);
257
        $titleToNotification = $this->formatTitle($title, $senderInfo, $forceTitleWhenSendingEmail);
258
        $settingToCheck = '';
259
        $avoid_my_self = false;
260
261
        switch ($this->type) {
262
            case self::NOTIFICATION_TYPE_DIRECT_MESSAGE:
263
            case self::NOTIFICATION_TYPE_MESSAGE:
264
                $settingToCheck = 'mail_notify_message';
265
                $defaultStatus = self::NOTIFY_MESSAGE_AT_ONCE;
266
                break;
267
            case self::NOTIFICATION_TYPE_INVITATION:
268
                $settingToCheck = 'mail_notify_invitation';
269
                $defaultStatus = self::NOTIFY_INVITATION_AT_ONCE;
270
                break;
271
            case self::NOTIFICATION_TYPE_GROUP:
272
                $settingToCheck = 'mail_notify_group_message';
273
                $defaultStatus = self::NOTIFY_GROUP_AT_ONCE;
274
                $avoid_my_self = true;
275
                break;
276
            default:
277
                $defaultStatus = self::NOTIFY_MESSAGE_AT_ONCE;
278
                break;
279
        }
280
281
        $settingInfo = UserManager::get_extra_field_information_by_name($settingToCheck);
282
283
        if (!empty($userList)) {
284
            foreach ($userList as $user_id) {
285
                if ($avoid_my_self) {
286
                    if ($user_id == api_get_user_id()) {
287
                        continue;
288
                    }
289
                }
290
                $userInfo = api_get_user_info($user_id);
291
292
                // Extra field was deleted or removed? Use the default status.
293
                $userSetting = $defaultStatus;
294
295
                if (!empty($settingInfo)) {
296
                    $extra_data = UserManager::get_extra_user_data($user_id);
297
298
                    if (isset($extra_data[$settingToCheck])) {
299
                        $userSetting = $extra_data[$settingToCheck];
300
                    }
301
302
                    // Means that user extra was not set
303
                    // Then send email now.
304
                    if ($userSetting === '') {
305
                        $userSetting = self::NOTIFY_MESSAGE_AT_ONCE;
306
                    }
307
                }
308
309
                $sendDate = null;
310
                switch ($userSetting) {
311
                    // No notifications
312
                    case self::NOTIFY_MESSAGE_NO:
313
                    case self::NOTIFY_INVITATION_NO:
314
                    case self::NOTIFY_GROUP_NO:
315
                        break;
316
                    // Send notification right now!
317
                    case self::NOTIFY_MESSAGE_AT_ONCE:
318
                    case self::NOTIFY_INVITATION_AT_ONCE:
319
                    case self::NOTIFY_GROUP_AT_ONCE:
320
                        $extraHeaders = [];
321
                        if (isset($senderInfo['email'])) {
322
                            $extraHeaders = [
323
                                'reply_to' => [
324
                                    'name' => $senderInfo['complete_name'],
325
                                    'mail' => $senderInfo['email'],
326
                                ],
327
                            ];
328
                        }
329
330
                        if (!empty($userInfo['email'])) {
331
                            api_mail_html(
332
                                $userInfo['complete_name'],
333
                                $userInfo['mail'],
334
                                Security::filter_terms($titleToNotification),
335
                                Security::filter_terms($content),
336
                                $this->adminName,
337
                                $this->adminEmail,
338
                                $extraHeaders,
339
                                $attachments,
340
                                false,
341
                                $smsParameters
342
                            );
343
                        }
344
                        $sendDate = api_get_utc_datetime();
345
                }
346
347
                // Saving the notification to be sent some day.
348
                $content = cut($content, $this->max_content_length);
349
                $params = [
350
                    'sent_at' => $sendDate,
351
                    'dest_user_id' => $user_id,
352
                    'dest_mail' => $userInfo['email'],
353
                    'title' => $title,
354
                    'content' => $content,
355
                    'send_freq' => $userSetting,
356
                ];
357
358
                $this->save($params);
359
            }
360
361
            self::sendPushNotification($userList, $title, $content);
362
        }
363
    }
364
365
    /**
366
     * Formats the content in order to add the welcome message,
367
     * the notification preference, etc.
368
     *
369
     * @param int    $messageId
370
     * @param string $content
371
     * @param array  $senderInfo result of api_get_user_info() or
372
     *                           GroupPortalManager:get_group_data()
373
     *
374
     * @return string
375
     * */
376
    public function formatContent($messageId, $content, $senderInfo)
377
    {
378
        $hook = HookNotificationContent::create();
379
        if (!empty($hook)) {
380
            $hook->setEventData(['content' => $content]);
381
            $data = $hook->notifyNotificationContent(HOOK_EVENT_TYPE_PRE);
382
            if (isset($data['content'])) {
383
                $content = $data['content'];
384
            }
385
        }
386
387
        $newMessageText = $linkToNewMessage = '';
388
        $showEmail = api_get_configuration_value('show_user_email_in_notification');
389
        $senderInfoName = '';
390
        if (!empty($senderInfo) && isset($senderInfo['complete_name'])) {
391
            $senderInfoName = $senderInfo['complete_name'];
392
            if ($showEmail && isset($senderInfo['complete_name_with_email_forced'])) {
393
                $senderInfoName = $senderInfo['complete_name_with_email_forced'];
394
            }
395
        }
396
397
        switch ($this->type) {
398
            case self::NOTIFICATION_TYPE_DIRECT_MESSAGE:
399
                $newMessageText = '';
400
                $linkToNewMessage = Display::url(
401
                    get_lang('SeeMessage'),
402
                    api_get_path(WEB_CODE_PATH).'messages/view_message.php?id='.$messageId
403
                );
404
                break;
405
            case self::NOTIFICATION_TYPE_MESSAGE:
406
                $allow = api_get_configuration_value('messages_hide_mail_content');
407
                if ($allow) {
408
                    $content = '';
409
                }
410
                if (!empty($senderInfo)) {
411
                    $newMessageText = sprintf(
412
                        get_lang('YouHaveANewMessageFromX'),
413
                        $senderInfoName
414
                    );
415
                }
416
                $linkToNewMessage = Display::url(
417
                    get_lang('SeeMessage'),
418
                    api_get_path(WEB_CODE_PATH).'messages/view_message.php?id='.$messageId
419
                );
420
                break;
421
            case self::NOTIFICATION_TYPE_INVITATION:
422
                if (!empty($senderInfo)) {
423
                    $newMessageText = sprintf(
424
                        get_lang('YouHaveANewInvitationFromX'),
425
                        $senderInfoName
426
                    );
427
                }
428
                $linkToNewMessage = Display::url(
429
                    get_lang('SeeInvitation'),
430
                    api_get_path(WEB_CODE_PATH).'social/invitations.php'
431
                );
432
                break;
433
            case self::NOTIFICATION_TYPE_GROUP:
434
                $topicPage = isset($_REQUEST['topics_page_nr']) ? (int) $_REQUEST['topics_page_nr'] : 0;
435
                if (!empty($senderInfo)) {
436
                    $senderName = $senderInfo['group_info']['name'];
437
                    $newMessageText = sprintf(get_lang('YouHaveReceivedANewMessageInTheGroupX'), $senderName);
438
                    $senderName = Display::url(
439
                        $senderInfoName,
440
                        api_get_path(WEB_CODE_PATH).'social/profile.php?'.$senderInfo['user_info']['user_id']
441
                    );
442
                    $newMessageText .= '<br />'.get_lang('User').': '.$senderName;
443
                }
444
                $groupUrl = api_get_path(WEB_CODE_PATH).'social/group_topics.php?id='.$senderInfo['group_info']['id'].'&topic_id='.$senderInfo['group_info']['topic_id'].'&msg_id='.$senderInfo['group_info']['msg_id'].'&topics_page_nr='.$topicPage;
445
                $linkToNewMessage = Display::url(get_lang('SeeMessage'), $groupUrl);
446
                break;
447
        }
448
        $preferenceUrl = api_get_path(WEB_CODE_PATH).'auth/profile.php';
449
450
        // You have received a new message text
451
        if (!empty($newMessageText)) {
452
            $content = $newMessageText.'<br /><hr><br />'.$content;
453
        }
454
455
        // See message with link text
456
        if (!empty($linkToNewMessage) && api_get_setting('allow_message_tool') == 'true') {
457
            $content = $content.'<br /><br />'.$linkToNewMessage;
458
        }
459
460
        // You have received this message because you are subscribed text
461
        $content = $content.'<br /><hr><i>'.
462
            sprintf(
463
                get_lang('YouHaveReceivedThisNotificationBecauseYouAreSubscribedOrInvolvedInItToChangeYourNotificationPreferencesPleaseClickHereX'),
464
                Display::url($preferenceUrl, $preferenceUrl)
465
            ).'</i>';
466
467
        if (!empty($hook)) {
468
            $hook->setEventData(['content' => $content]);
469
            $data = $hook->notifyNotificationContent(HOOK_EVENT_TYPE_POST);
470
            if (isset($data['content'])) {
471
                $content = $data['content'];
472
            }
473
        }
474
475
        return $content;
476
    }
477
478
    /**
479
     * Send the push notifications to Chamilo Mobile app.
480
     *
481
     * @param array  $userIds The IDs of users who will be notified
482
     * @param string $title   The notification title
483
     * @param string $content The notification content
484
     *
485
     * @return int The number of success notifications. Otherwise returns false
486
     */
487
    public static function sendPushNotification(array $userIds, $title, $content)
488
    {
489
        if (api_get_setting('messaging_allow_send_push_notification') !== 'true') {
490
            return false;
491
        }
492
493
        $gdcApiKey = api_get_setting('messaging_gdc_api_key');
494
495
        if ($gdcApiKey === false) {
496
            return false;
497
        }
498
499
        $content = strip_tags($content);
500
        $content = explode("\n", $content);
501
        $content = array_map('trim', $content);
502
        $content = array_filter($content);
503
        $content = implode(PHP_EOL, $content);
504
505
        $gcmRegistrationIds = [];
506
        foreach ($userIds as $userId) {
507
            $extraFieldValue = new ExtraFieldValue('user');
508
            $valueInfo = $extraFieldValue->get_values_by_handler_and_field_variable(
509
                $userId,
510
                Rest::EXTRA_FIELD_GCM_REGISTRATION
511
            );
512
513
            if (empty($valueInfo)) {
514
                continue;
515
            }
516
517
            $gcmRegistrationIds[] = $valueInfo['value'];
518
        }
519
520
        if (!$gcmRegistrationIds) {
521
            return 0;
522
        }
523
524
        $headers = [
525
            'Authorization: key='.$gdcApiKey,
526
            'Content-Type: application/json',
527
        ];
528
529
        $fields = json_encode([
530
            'registration_ids' => $gcmRegistrationIds,
531
            'data' => [
532
                'title' => $title,
533
                'message' => $content,
534
                'body' => $content,
535
                'sound' => 'default',
536
            ],
537
            'notification' => [
538
                'title' => $title,
539
                'body' => $content,
540
                'sound' => 'default',
541
            ],
542
            'collapse_key' => get_lang('Messages'),
543
        ]);
544
545
        $ch = curl_init();
546
        curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
547
        curl_setopt($ch, CURLOPT_POST, true);
548
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
549
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
550
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
551
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
552
        $result = curl_exec($ch);
553
        curl_close($ch);
554
555
        /** @var array $decodedResult */
556
        $decodedResult = json_decode($result, true);
557
558
        return intval($decodedResult['success']);
559
    }
560
}
561