Passed
Push — master ( 568d8b...72684c )
by Julito
09:38
created

MessageManager::send_message()   F

Complexity

Conditions 37
Paths 14026

Size

Total Lines 269
Code Lines 167

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 37
eloc 167
nc 14026
nop 16
dl 0
loc 269
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\Message;
5
use Chamilo\UserBundle\Entity\User;
6
use ChamiloSession as Session;
7
8
/**
9
 * Class MessageManager.
10
 *
11
 * This class provides methods for messages management.
12
 * Include/require it in your code to use its features.
13
 *
14
 * @package chamilo.library
15
 */
16
class MessageManager
17
{
18
    const MESSAGE_TYPE_INBOX = 1;
19
    const MESSAGE_TYPE_OUTBOX = 2;
20
    const MESSAGE_TYPE_PROMOTED = 3;
21
22
    /**
23
     * Get count new messages for the current user from the database.
24
     *
25
     * @return int
26
     */
27
    public static function getCountNewMessages()
28
    {
29
        $userId = api_get_user_id();
30
        if (empty($userId)) {
31
            return false;
32
        }
33
34
        static $count;
35
        if (!isset($count)) {
36
            $cacheAvailable = api_get_configuration_value('apc');
37
            if ($cacheAvailable === true) {
38
                $var = api_get_configuration_value('apc_prefix').'social_messages_unread_u_'.$userId;
39
                if (apcu_exists($var)) {
40
                    $count = apcu_fetch($var);
41
                } else {
42
                    $count = self::getCountNewMessagesFromDB($userId);
43
                    apcu_store($var, $count, 60);
44
                }
45
            } else {
46
                $count = self::getCountNewMessagesFromDB($userId);
47
            }
48
        }
49
50
        return $count;
51
    }
52
53
    /**
54
     * Gets the total number of messages, used for the inbox sortable table.
55
     *
56
     * @param array $params
57
     *
58
     * @return int
59
     */
60
    public static function getNumberOfMessages($params)
61
    {
62
        $table = Database::get_main_table(TABLE_MESSAGE);
63
        $conditions = self::getWhereConditions($params);
64
65
        $sql = "SELECT COUNT(id) as number_messages
66
                FROM $table
67
                WHERE 
68
                    $conditions
69
                ";
70
        $result = Database::query($sql);
71
        $result = Database::fetch_array($result);
72
73
        if ($result) {
74
            return (int) $result['number_messages'];
75
        }
76
77
        return 0;
78
    }
79
80
    /**
81
     * @param array $extraParams
82
     *
83
     * @return string
84
     */
85
    public static function getWhereConditions($extraParams)
86
    {
87
        $userId = api_get_user_id();
88
89
        $keyword = isset($extraParams['keyword']) && !empty($extraParams['keyword']) ? $extraParams['keyword'] : '';
90
        $type = isset($extraParams['type']) && !empty($extraParams['type']) ? $extraParams['type'] : '';
91
92
        if (empty($type)) {
93
            return '';
94
        }
95
96
        switch ($type) {
97
            case self::MESSAGE_TYPE_INBOX:
98
                $statusList = [MESSAGE_STATUS_NEW, MESSAGE_STATUS_UNREAD];
99
                $userCondition = " user_receiver_id = $userId AND";
100
                break;
101
            case self::MESSAGE_TYPE_OUTBOX:
102
                $statusList = [MESSAGE_STATUS_OUTBOX];
103
                $userCondition = " user_sender_id = $userId AND";
104
                break;
105
            case self::MESSAGE_TYPE_PROMOTED:
106
                $statusList = [MESSAGE_STATUS_PROMOTED];
107
                $userCondition = " user_receiver_id = $userId AND";
108
                break;
109
        }
110
111
        if (empty($statusList)) {
112
            return '';
113
        }
114
115
        $keywordCondition = '';
116
        if (!empty($keyword)) {
117
            $keyword = Database::escape_string($keyword);
118
            $keywordCondition = " AND (title like '%$keyword%' OR content LIKE '%$keyword%') ";
119
        }
120
        $messageStatusCondition = implode("','", $statusList);
121
122
        return " $userCondition
123
                 msg_status IN ('$messageStatusCondition')
124
                 $keywordCondition";
125
    }
126
127
    /**
128
     * Gets information about some messages, used for the inbox sortable table.
129
     *
130
     * @param int    $from
131
     * @param int    $numberOfItems
132
     * @param string $column
133
     * @param string $direction
134
     * @param array  $extraParams
135
     *
136
     * @return array
137
     */
138
    public static function getMessageData(
139
        $from,
140
        $numberOfItems,
141
        $column,
142
        $direction,
143
        $extraParams = []
144
    ) {
145
        $from = (int) $from;
146
        $numberOfItems = (int) $numberOfItems;
147
        // Forcing this order.
148
        if (!isset($direction)) {
149
            $column = 2;
150
            $direction = 'DESC';
151
        } else {
152
            $column = (int) $column;
153
            if (!in_array($direction, ['ASC', 'DESC'])) {
154
                $direction = 'ASC';
155
            }
156
        }
157
158
        if (!in_array($column, [0, 1, 2])) {
159
            $column = 2;
160
        }
161
162
        $type = isset($extraParams['type']) && !empty($extraParams['type']) ? $extraParams['type'] : '';
163
164
        if (empty($type)) {
165
            return [];
166
        }
167
168
        $viewUrl = '';
169
        switch ($type) {
170
            case self::MESSAGE_TYPE_OUTBOX:
171
            case self::MESSAGE_TYPE_INBOX:
172
                $viewUrl = api_get_path(WEB_CODE_PATH).'messages/view_message.php';
173
                break;
174
            case self::MESSAGE_TYPE_PROMOTED:
175
                $viewUrl = api_get_path(WEB_CODE_PATH).'social/view_promoted_message.php';
176
                break;
177
        }
178
        $viewUrl .= '?type='.$type;
179
180
        $whereConditions = self::getWhereConditions($extraParams);
181
182
        if (empty($whereConditions)) {
183
            return [];
184
        }
185
186
        $table = Database::get_main_table(TABLE_MESSAGE);
187
        $sql = "SELECT 
188
                    id as col0, 
189
                    title as col1, 
190
                    send_date as col2, 
191
                    msg_status as col3,
192
                    user_sender_id
193
                FROM $table
194
                WHERE
195
                    $whereConditions
196
                ORDER BY col$column $direction
197
                LIMIT $from, $numberOfItems";
198
199
        $result = Database::query($sql);
200
        $messageList = [];
201
        $newMessageLink = api_get_path(WEB_CODE_PATH).'messages/new_message.php';
202
203
        $actions = $extraParams['actions'];
204
        $url = api_get_self();
205
        while ($row = Database::fetch_array($result, 'ASSOC')) {
206
            $messageId = $row['col0'];
207
            $title = $row['col1'];
208
            $sendDate = $row['col2'];
209
            $status = $row['col3'];
210
            $senderId = $row['user_sender_id'];
211
212
            $title = Security::remove_XSS($title, STUDENT, true);
213
            $title = cut($title, 80, true);
214
215
            $class = 'class = "read"';
216
            if ($status == 1) {
217
                $class = 'class = "unread"';
218
            }
219
220
            $userInfo = api_get_user_info($senderId);
221
            $message[3] = '';
222
            if (!empty($senderId) && !empty($userInfo)) {
223
                $message[1] = '<a '.$class.' href="'.$viewUrl.'&id='.$messageId.'">'.$title.'</a><br />';
224
                $message[1] .= $userInfo['complete_name_with_username'];
225
                if (in_array('reply', $actions)) {
226
                    $message[3] =
227
                        Display::url(
228
                            Display::returnFontAwesomeIcon('reply', 2),
229
                            $newMessageLink.'?re_id='.$messageId,
230
                            ['title' => get_lang('ReplyToMessage')]
231
                        );
232
                }
233
            } else {
234
                $message[1] = '<a '.$class.' href="'.$viewUrl.'&id='.$messageId.'">'.$title.'</a><br />';
235
                $message[1] .= get_lang('UnknownUser');
236
                if (in_array('reply', $actions)) {
237
                    $message[3] =
238
                        Display::url(
239
                            Display::returnFontAwesomeIcon('reply', 2),
240
                            '#',
241
                            ['title' => get_lang('ReplyToMessage')]
242
                        );
243
                }
244
            }
245
246
            $message[0] = $messageId;
247
            $message[2] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG);
248
249
            // Actions
250
            if (in_array('edit', $actions)) {
251
                $message[3] .=
252
                    '&nbsp;&nbsp;'.
253
                    Display::url(
254
                        Display::returnFontAwesomeIcon('pencil', 2),
255
                        $newMessageLink.'?action=edit&id='.$messageId,
256
                        ['title' => get_lang('ForwardMessage')]
257
                    );
258
            }
259
260
            // Actions
261
            if (in_array('forward', $actions)) {
262
                $message[3] .=
263
                    '&nbsp;&nbsp;'.
264
                    Display::url(
265
                        Display::returnFontAwesomeIcon('share', 2),
266
                        $newMessageLink.'?forward_id='.$messageId,
267
                        ['title' => get_lang('ForwardMessage')]
268
                    );
269
            }
270
271
            if (in_array('delete', $actions)) {
272
                $message[3] .= '&nbsp;&nbsp;<a title="'.addslashes(
273
                    get_lang('DeleteMessage')
274
                ).'" onclick="javascript:if(!confirm('."'".addslashes(
275
                    api_htmlentities(get_lang('ConfirmDeleteMessage'))
276
                )."'".')) return false;" href="'.$url.'?action=deleteone&id='.$messageId.'">'.
277
                Display::returnFontAwesomeIcon('trash', 2).'</a>';
278
            }
279
280
            foreach ($message as $key => $value) {
281
                $message[$key] = api_xml_http_response_encode($value);
282
            }
283
            $messageList[] = $message;
284
        }
285
286
        return $messageList;
287
    }
288
289
    /**
290
     * @param array  $aboutUserInfo
291
     * @param array  $fromUserInfo
292
     * @param string $subject
293
     * @param string $content
294
     *
295
     * @return bool
296
     */
297
    public static function sendMessageAboutUser(
298
        $aboutUserInfo,
299
        $fromUserInfo,
300
        $subject,
301
        $content
302
    ) {
303
        if (empty($aboutUserInfo) || empty($fromUserInfo)) {
304
            return false;
305
        }
306
307
        if (empty($fromUserInfo['id']) || empty($aboutUserInfo['id'])) {
308
            return false;
309
        }
310
311
        $table = Database::get_main_table(TABLE_MESSAGE);
312
        $now = api_get_utc_datetime();
313
        $params = [
314
            'user_sender_id' => $fromUserInfo['id'],
315
            'user_receiver_id' => $aboutUserInfo['id'],
316
            'msg_status' => MESSAGE_STATUS_CONVERSATION,
317
            'send_date' => $now,
318
            'title' => $subject,
319
            'content' => $content,
320
            'group_id' => 0,
321
            'parent_id' => 0,
322
            'update_date' => $now,
323
        ];
324
        $id = Database::insert($table, $params);
325
326
        if ($id) {
327
            return true;
328
        }
329
330
        return false;
331
    }
332
333
    /**
334
     * @param array $aboutUserInfo
335
     *
336
     * @return array
337
     */
338
    public static function getMessagesAboutUser($aboutUserInfo)
339
    {
340
        if (!empty($aboutUserInfo)) {
341
            $table = Database::get_main_table(TABLE_MESSAGE);
342
            $sql = 'SELECT id FROM '.$table.'
343
                    WHERE 
344
                      user_receiver_id = '.$aboutUserInfo['id'].' AND 
345
                      msg_status = '.MESSAGE_STATUS_CONVERSATION.'                    
346
                    ';
347
            $result = Database::query($sql);
348
            $messages = [];
349
            $repo = Database::getManager()->getRepository('ChamiloCoreBundle:Message');
350
            while ($row = Database::fetch_array($result)) {
351
                $message = $repo->find($row['id']);
352
                $messages[] = $message;
353
            }
354
355
            return $messages;
356
        }
357
358
        return [];
359
    }
360
361
    /**
362
     * @param array $userInfo
363
     *
364
     * @return string
365
     */
366
    public static function getMessagesAboutUserToString($userInfo)
367
    {
368
        $messages = self::getMessagesAboutUser($userInfo);
369
        $html = '';
370
        if (!empty($messages)) {
371
            /** @var Message $message */
372
            foreach ($messages as $message) {
373
                $tag = 'message_'.$message->getId();
374
                $tagAccordion = 'accordion_'.$message->getId();
375
                $tagCollapse = 'collapse_'.$message->getId();
376
                $date = Display::dateToStringAgoAndLongDate(
377
                    $message->getSendDate()
378
                );
379
                $localTime = api_get_local_time(
380
                    $message->getSendDate(),
381
                    null,
382
                    null,
383
                    false,
384
                    false
385
                );
386
                $senderId = $message->getUserSenderId();
387
                $senderInfo = api_get_user_info($senderId);
388
                $html .= Display::panelCollapse(
389
                    $localTime.' '.$senderInfo['complete_name'].' '.$message->getTitle(),
390
                    $message->getContent().'<br />'.$date.'<br />'.get_lang(
391
                        'Author'
392
                    ).': '.$senderInfo['complete_name_with_message_link'],
393
                    $tag,
394
                    null,
395
                    $tagAccordion,
396
                    $tagCollapse,
397
                    false
398
                );
399
            }
400
        }
401
402
        return $html;
403
    }
404
405
    /**
406
     * @param int    $senderId
407
     * @param int    $receiverId
408
     * @param string $subject
409
     * @param string $message
410
     *
411
     * @return bool
412
     */
413
    public static function messageWasAlreadySent($senderId, $receiverId, $subject, $message)
414
    {
415
        $table = Database::get_main_table(TABLE_MESSAGE);
416
        $senderId = (int) $senderId;
417
        $receiverId = (int) $receiverId;
418
        $subject = Database::escape_string($subject);
419
        $message = Database::escape_string($message);
420
421
        $sql = "SELECT * FROM $table
422
                WHERE 
423
                    user_sender_id = $senderId AND
424
                    user_receiver_id = $receiverId AND 
425
                    title = '$subject' AND 
426
                    content = '$message' AND
427
                    (msg_status = ".MESSAGE_STATUS_UNREAD." OR msg_status = ".MESSAGE_STATUS_NEW.")                    
428
                ";
429
        $result = Database::query($sql);
430
431
        return Database::num_rows($result) > 0;
432
    }
433
434
    /**
435
     * Sends a message to a user/group.
436
     *
437
     * @param int    $receiver_user_id
438
     * @param string $subject
439
     * @param string $content
440
     * @param array  $attachments                files array($_FILES) (optional)
441
     * @param array  $fileCommentList            about attachment files (optional)
442
     * @param int    $group_id                   (optional)
443
     * @param int    $parent_id                  (optional)
444
     * @param int    $editMessageId              id for updating the message (optional)
445
     * @param int    $topic_id                   (optional) the default value is the current user_id
446
     * @param int    $sender_id
447
     * @param bool   $directMessage
448
     * @param int    $forwardId
449
     * @param array  $smsParameters
450
     * @param bool   $checkCurrentAudioId
451
     * @param bool   $forceTitleWhenSendingEmail force the use of $title as subject instead of "You have a new message"
452
     *
453
     * @return bool
454
     */
455
    public static function send_message(
456
        $receiver_user_id,
457
        $subject,
458
        $content,
459
        array $attachments = [],
460
        array $fileCommentList = [],
461
        $group_id = 0,
462
        $parent_id = 0,
463
        $editMessageId = 0,
464
        $topic_id = 0,
465
        $sender_id = 0,
466
        $directMessage = false,
467
        $forwardId = 0,
468
        $smsParameters = [],
469
        $checkCurrentAudioId = false,
470
        $forceTitleWhenSendingEmail = false,
471
        $status = 0
472
    ) {
473
        $table = Database::get_main_table(TABLE_MESSAGE);
474
        $group_id = (int) $group_id;
475
        $receiver_user_id = (int) $receiver_user_id;
476
        $parent_id = (int) $parent_id;
477
        $editMessageId = (int) $editMessageId;
478
        $topic_id = (int) $topic_id;
479
480
        $status = empty($status) ? MESSAGE_STATUS_UNREAD : (int) $status;
481
482
        if (!empty($receiver_user_id)) {
483
            $receiverUserInfo = api_get_user_info($receiver_user_id);
484
485
            // Disabling messages for inactive users.
486
            if ($receiverUserInfo['active'] == 0) {
487
                return false;
488
            }
489
        }
490
491
        $user_sender_id = empty($sender_id) ? api_get_user_id() : (int) $sender_id;
492
        if (empty($user_sender_id)) {
493
            Display::addFlash(Display::return_message(get_lang('UserDoesNotExist'), 'warning'));
494
495
            return false;
496
        }
497
498
        $totalFileSize = 0;
499
        $attachmentList = [];
500
        if (is_array($attachments)) {
501
            $counter = 0;
502
            foreach ($attachments as $attachment) {
503
                $attachment['comment'] = isset($fileCommentList[$counter]) ? $fileCommentList[$counter] : '';
504
                $fileSize = isset($attachment['size']) ? $attachment['size'] : 0;
505
                if (is_array($fileSize)) {
506
                    foreach ($fileSize as $size) {
507
                        $totalFileSize += $size;
508
                    }
509
                } else {
510
                    $totalFileSize += $fileSize;
511
                }
512
                $attachmentList[] = $attachment;
513
                $counter++;
514
            }
515
        }
516
517
        if ($checkCurrentAudioId) {
518
            // Add the audio file as an attachment
519
            $audioId = Session::read('current_audio_id');
520
            if (!empty($audioId)) {
521
                $file = api_get_uploaded_file('audio_message', api_get_user_id(), $audioId);
522
                if (!empty($file)) {
523
                    $audioAttachment = [
524
                        'name' => basename($file),
525
                        'comment' => 'audio_message',
526
                        'size' => filesize($file),
527
                        'tmp_name' => $file,
528
                        'error' => 0,
529
                        'type' => DocumentManager::file_get_mime_type(basename($file)),
530
                    ];
531
                    // create attachment from audio message
532
                    $attachmentList[] = $audioAttachment;
533
                }
534
            }
535
        }
536
537
        // Validating fields
538
        if (empty($subject) && empty($group_id)) {
539
            Display::addFlash(
540
                Display::return_message(
541
                    get_lang('YouShouldWriteASubject'),
542
                    'warning'
543
                )
544
            );
545
546
            return false;
547
        } elseif ($totalFileSize > intval(api_get_setting('message_max_upload_filesize'))) {
548
            $warning = sprintf(
549
                get_lang('FilesSizeExceedsX'),
550
                format_file_size(api_get_setting('message_max_upload_filesize'))
551
            );
552
553
            Display::addFlash(Display::return_message($warning, 'warning'));
554
555
            return false;
556
        }
557
558
        // Just in case we replace the and \n and \n\r while saving in the DB
559
        // $content = str_replace(array("\n", "\n\r"), '<br />', $content);
560
        $now = api_get_utc_datetime();
561
        if (!empty($receiver_user_id) || !empty($group_id)) {
562
            // message for user friend
563
            //@todo it's possible to edit a message? yes, only for groups
564
            if (!empty($editMessageId)) {
565
                $query = " UPDATE $table SET
566
                              update_date = '".$now."',
567
                              content = '".Database::escape_string($content)."'
568
                           WHERE id = '$editMessageId' ";
569
                Database::query($query);
570
                $messageId = $editMessageId;
571
            } else {
572
                $params = [
573
                    'user_sender_id' => $user_sender_id,
574
                    'msg_status' => $status,
575
                    'send_date' => $now,
576
                    'title' => $subject,
577
                    'content' => $content,
578
                    'group_id' => $group_id,
579
                    'parent_id' => $parent_id,
580
                    'update_date' => $now,
581
                ];
582
                if (!empty($receiver_user_id)) {
583
                    $params['user_receiver_id'] = $receiver_user_id;
584
                }
585
                $messageId = Database::insert($table, $params);
586
            }
587
588
            // Forward also message attachments
589
            if (!empty($forwardId)) {
590
                $attachments = self::getAttachmentList($forwardId);
591
                foreach ($attachments as $attachment) {
592
                    if (!empty($attachment['file_source'])) {
593
                        $file = [
594
                            'name' => $attachment['filename'],
595
                            'tmp_name' => $attachment['file_source'],
596
                            'size' => $attachment['size'],
597
                            'error' => 0,
598
                            'comment' => $attachment['comment'],
599
                        ];
600
601
                        // Inject this array so files can be added when sending and email with the mailer
602
                        $attachmentList[] = $file;
603
                    }
604
                }
605
            }
606
607
            // Save attachment file for inbox messages
608
            if (is_array($attachmentList)) {
609
                foreach ($attachmentList as $attachment) {
610
                    if ($attachment['error'] == 0) {
611
                        $comment = $attachment['comment'];
612
                        self::saveMessageAttachmentFile(
613
                            $attachment,
614
                            $comment,
615
                            $messageId,
616
                            null,
617
                            $receiver_user_id,
618
                            $group_id
619
                        );
620
                    }
621
                }
622
            }
623
624
            // Save message in the outbox for user friend or group.
625
            if (empty($group_id) && $status == MESSAGE_STATUS_UNREAD) {
626
                $params = [
627
                    'user_sender_id' => $user_sender_id,
628
                    'user_receiver_id' => $receiver_user_id,
629
                    'msg_status' => MESSAGE_STATUS_OUTBOX,
630
                    'send_date' => $now,
631
                    'title' => $subject,
632
                    'content' => $content,
633
                    'group_id' => $group_id,
634
                    'parent_id' => $parent_id,
635
                    'update_date' => $now,
636
                ];
637
                $outbox_last_id = Database::insert($table, $params);
638
639
                // save attachment file for outbox messages
640
                if (is_array($attachmentList)) {
641
                    foreach ($attachmentList as $attachment) {
642
                        if ($attachment['error'] == 0) {
643
                            $comment = $attachment['comment'];
644
                            self::saveMessageAttachmentFile(
645
                                $attachment,
646
                                $comment,
647
                                $outbox_last_id,
648
                                $user_sender_id
649
                            );
650
                        }
651
                    }
652
                }
653
            }
654
655
            // Load user settings.
656
            $notification = new Notification();
657
            $sender_info = api_get_user_info($user_sender_id);
658
659
            // add file attachment additional attributes
660
            $attachmentAddedByMail = [];
661
            foreach ($attachmentList as $attachment) {
662
                $attachmentAddedByMail[] = [
663
                    'path' => $attachment['tmp_name'],
664
                    'filename' => $attachment['name'],
665
                ];
666
            }
667
668
            if (empty($group_id)) {
669
                $type = Notification::NOTIFICATION_TYPE_MESSAGE;
670
                if ($directMessage) {
671
                    $type = Notification::NOTIFICATION_TYPE_DIRECT_MESSAGE;
672
                }
673
                $notification->saveNotification(
674
                    $messageId,
675
                    $type,
676
                    [$receiver_user_id],
677
                    $subject,
678
                    $content,
679
                    $sender_info,
680
                    $attachmentAddedByMail,
681
                    $smsParameters,
682
                    $forceTitleWhenSendingEmail
683
                );
684
            } else {
685
                $usergroup = new UserGroup();
686
                $group_info = $usergroup->get($group_id);
687
                $group_info['topic_id'] = $topic_id;
688
                $group_info['msg_id'] = $messageId;
689
690
                $user_list = $usergroup->get_users_by_group(
691
                    $group_id,
692
                    false,
693
                    [],
694
                    0,
695
                    1000
696
                );
697
698
                // Adding more sense to the message group
699
                $subject = sprintf(get_lang('ThereIsANewMessageInTheGroupX'), $group_info['name']);
700
                $new_user_list = [];
701
                foreach ($user_list as $user_data) {
702
                    $new_user_list[] = $user_data['id'];
703
                }
704
                $group_info = [
705
                    'group_info' => $group_info,
706
                    'user_info' => $sender_info,
707
                ];
708
                $notification->saveNotification(
709
                    $messageId,
710
                    Notification::NOTIFICATION_TYPE_GROUP,
711
                    $new_user_list,
712
                    $subject,
713
                    $content,
714
                    $group_info,
715
                    $attachmentAddedByMail,
716
                    $smsParameters
717
                );
718
            }
719
720
            return $messageId;
721
        }
722
723
        return false;
724
    }
725
726
    /**
727
     * @param int    $receiver_user_id
728
     * @param int    $subject
729
     * @param string $message
730
     * @param int    $sender_id
731
     * @param bool   $sendCopyToDrhUsers send copy to related DRH users
732
     * @param bool   $directMessage
733
     * @param array  $smsParameters
734
     * @param bool   $uploadFiles        Do not upload files using the MessageManager class
735
     * @param array  $attachmentList
736
     *
737
     * @return bool
738
     */
739
    public static function send_message_simple(
740
        $receiver_user_id,
741
        $subject,
742
        $message,
743
        $sender_id = 0,
744
        $sendCopyToDrhUsers = false,
745
        $directMessage = false,
746
        $smsParameters = [],
747
        $uploadFiles = true,
748
        $attachmentList = []
749
    ) {
750
        $files = $_FILES ? $_FILES : [];
751
        if ($uploadFiles === false) {
752
            $files = [];
753
        }
754
        // $attachmentList must have: tmp_name, name, size keys
755
        if (!empty($attachmentList)) {
756
            $files = $attachmentList;
757
        }
758
        $result = self::send_message(
759
            $receiver_user_id,
760
            $subject,
761
            $message,
762
            $files,
763
            [],
764
            null,
765
            null,
766
            null,
767
            null,
768
            $sender_id,
769
            $directMessage,
770
            0,
771
            $smsParameters
772
        );
773
774
        if ($sendCopyToDrhUsers) {
775
            $userInfo = api_get_user_info($receiver_user_id);
776
            $drhList = UserManager::getDrhListFromUser($receiver_user_id);
777
            if (!empty($drhList)) {
778
                foreach ($drhList as $drhInfo) {
779
                    $message = sprintf(
780
                        get_lang('CopyOfMessageSentToXUser'),
781
                        $userInfo['complete_name']
782
                    ).' <br />'.$message;
783
784
                    self::send_message_simple(
785
                        $drhInfo['user_id'],
786
                        $subject,
787
                        $message,
788
                        $sender_id,
789
                        false,
790
                        $directMessage
791
                    );
792
                }
793
            }
794
        }
795
796
        return $result;
797
    }
798
799
    /**
800
     * Update parent ids for other receiver user from current message in groups.
801
     *
802
     * @author Christian Fasanando Flores
803
     *
804
     * @param int $parent_id
805
     * @param int $receiver_user_id
806
     * @param int $messageId
807
     */
808
    public static function update_parent_ids_from_reply(
809
        $parent_id,
810
        $receiver_user_id,
811
        $messageId
812
    ) {
813
        $table = Database::get_main_table(TABLE_MESSAGE);
814
        $parent_id = intval($parent_id);
815
        $receiver_user_id = intval($receiver_user_id);
816
        $messageId = intval($messageId);
817
818
        // first get data from message id (parent)
819
        $sql = "SELECT * FROM $table WHERE id = '$parent_id'";
820
        $rs_message = Database::query($sql);
821
        $row_message = Database::fetch_array($rs_message);
822
823
        // get message id from data found early for other receiver user
824
        $sql = "SELECT id FROM $table
825
                WHERE
826
                    user_sender_id ='{$row_message['user_sender_id']}' AND
827
                    title='{$row_message['title']}' AND
828
                    content='{$row_message['content']}' AND
829
                    group_id='{$row_message['group_id']}' AND
830
                    user_receiver_id='$receiver_user_id'";
831
        $result = Database::query($sql);
832
        $row = Database::fetch_array($result);
833
834
        // update parent_id for other user receiver
835
        $sql = "UPDATE $table SET parent_id = ".$row['id']."
836
                WHERE id = $messageId";
837
        Database::query($sql);
838
    }
839
840
    /**
841
     * @param int $user_receiver_id
842
     * @param int $id
843
     *
844
     * @return bool
845
     */
846
    public static function delete_message_by_user_receiver($user_receiver_id, $id)
847
    {
848
        $table = Database::get_main_table(TABLE_MESSAGE);
849
        $id = (int) $id;
850
        $user_receiver_id = (int) $user_receiver_id;
851
852
        if (empty($id) || empty($user_receiver_id)) {
853
            return false;
854
        }
855
856
        $sql = "SELECT * FROM $table
857
                WHERE 
858
                    id = $id AND 
859
                    user_receiver_id = $user_receiver_id AND
860
                    msg_status <> ".MESSAGE_STATUS_OUTBOX;
861
        $rs = Database::query($sql);
862
863
        if (Database::num_rows($rs) > 0) {
864
            // Delete attachment file.
865
            self::delete_message_attachment_file($id, $user_receiver_id);
866
            // Soft delete message.
867
            $query = "UPDATE $table 
868
                      SET msg_status = ".MESSAGE_STATUS_DELETED."
869
                      WHERE
870
                        id = $id AND 
871
                        user_receiver_id = $user_receiver_id ";
872
            Database::query($query);
873
874
            return true;
875
        }
876
877
        return false;
878
    }
879
880
    /**
881
     * Set status deleted.
882
     *
883
     * @author Isaac FLores Paz <[email protected]>
884
     *
885
     * @param  int
886
     * @param  int
887
     *
888
     * @return bool
889
     */
890
    public static function delete_message_by_user_sender($user_sender_id, $id)
891
    {
892
        $user_sender_id = (int) $user_sender_id;
893
        $id = (int) $id;
894
895
        if (empty($id) || empty($user_sender_id)) {
896
            return false;
897
        }
898
899
        $table = Database::get_main_table(TABLE_MESSAGE);
900
901
        $sql = "SELECT * FROM $table WHERE id = $id AND user_sender_id= $user_sender_id";
902
        $rs = Database::query($sql);
903
904
        if (Database::num_rows($rs) > 0) {
905
            // delete attachment file
906
            self::delete_message_attachment_file($id, $user_sender_id);
907
            // delete message
908
            $sql = "UPDATE $table
909
                    SET msg_status = '".MESSAGE_STATUS_DELETED."'
910
                    WHERE user_sender_id= $user_sender_id AND id= $id";
911
            Database::query($sql);
912
913
            return true;
914
        }
915
916
        return false;
917
    }
918
919
    /**
920
     * Saves a message attachment files.
921
     *
922
     * @param array $file_attach $_FILES['name']
923
     * @param  string    a comment about the uploaded file
924
     * @param  int        message id
925
     * @param  int        receiver user id (optional)
926
     * @param  int        sender user id (optional)
927
     * @param  int        group id (optional)
928
     */
929
    public static function saveMessageAttachmentFile(
930
        $file_attach,
931
        $file_comment,
932
        $message_id,
933
        $receiver_user_id = 0,
934
        $sender_user_id = 0,
935
        $group_id = 0
936
    ) {
937
        $table = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
938
939
        // Try to add an extension to the file if it hasn't one
940
        $type = isset($file_attach['type']) ? $file_attach['type'] : '';
941
        if (empty($type)) {
942
            $type = DocumentManager::file_get_mime_type($file_attach['name']);
943
        }
944
        $new_file_name = add_ext_on_mime(stripslashes($file_attach['name']), $type);
945
946
        // user's file name
947
        $file_name = $file_attach['name'];
948
        if (!filter_extension($new_file_name)) {
949
            Display::addFlash(Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'error'));
950
        } else {
951
            $new_file_name = uniqid('');
952
            if (!empty($receiver_user_id)) {
953
                $message_user_id = $receiver_user_id;
954
            } else {
955
                $message_user_id = $sender_user_id;
956
            }
957
958
            // User-reserved directory where photos have to be placed.*
959
            $userGroup = new UserGroup();
960
            if (!empty($group_id)) {
961
                $path_user_info = $userGroup->get_group_picture_path_by_id(
962
                    $group_id,
963
                    'system',
964
                    true
965
                );
966
            } else {
967
                $path_user_info['dir'] = UserManager::getUserPathById($message_user_id, 'system');
968
            }
969
970
            $path_message_attach = $path_user_info['dir'].'message_attachments/';
971
            // If this directory does not exist - we create it.
972
            if (!file_exists($path_message_attach)) {
973
                @mkdir($path_message_attach, api_get_permissions_for_new_directories(), true);
974
            }
975
976
            $new_path = $path_message_attach.$new_file_name;
977
            $fileCopied = false;
978
            if (isset($file_attach['tmp_name']) && !empty($file_attach['tmp_name'])) {
979
                if (is_uploaded_file($file_attach['tmp_name'])) {
980
                    @copy($file_attach['tmp_name'], $new_path);
981
                    $fileCopied = true;
982
                } else {
983
                    // 'tmp_name' can be set by the ticket or when forwarding a message
984
                    if (file_exists($file_attach['tmp_name'])) {
985
                        @copy($file_attach['tmp_name'], $new_path);
986
                        $fileCopied = true;
987
                    }
988
                }
989
            }
990
991
            if ($fileCopied) {
992
                // Storing the attachments if any
993
                $params = [
994
                    'filename' => $file_name,
995
                    'comment' => $file_comment,
996
                    'path' => $new_file_name,
997
                    'message_id' => $message_id,
998
                    'size' => $file_attach['size'],
999
                ];
1000
1001
                return Database::insert($table, $params);
1002
            }
1003
        }
1004
1005
        return false;
1006
    }
1007
1008
    /**
1009
     * Delete message attachment files (logically updating the row with a suffix _DELETE_id).
1010
     *
1011
     * @param  int    message id
1012
     * @param  int    message user id (receiver user id or sender user id)
1013
     * @param  int    group id (optional)
1014
     */
1015
    public static function delete_message_attachment_file(
1016
        $message_id,
1017
        $message_uid,
1018
        $group_id = 0
1019
    ) {
1020
        $message_id = (int) $message_id;
1021
        $message_uid = (int) $message_uid;
1022
        $table_message_attach = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
1023
1024
        $sql = "SELECT * FROM $table_message_attach
1025
                WHERE message_id = '$message_id'";
1026
        $rs = Database::query($sql);
1027
        while ($row = Database::fetch_array($rs)) {
1028
            $path = $row['path'];
1029
            $attach_id = (int) $row['id'];
1030
            $new_path = $path.'_DELETED_'.$attach_id;
1031
1032
            if (!empty($group_id)) {
1033
                $userGroup = new UserGroup();
1034
                $path_user_info = $userGroup->get_group_picture_path_by_id(
1035
                    $group_id,
1036
                    'system',
1037
                    true
1038
                );
1039
            } else {
1040
                $path_user_info['dir'] = UserManager::getUserPathById(
1041
                    $message_uid,
1042
                    'system'
1043
                );
1044
            }
1045
1046
            $path_message_attach = $path_user_info['dir'].'message_attachments/';
1047
            if (is_file($path_message_attach.$path)) {
1048
                if (rename($path_message_attach.$path, $path_message_attach.$new_path)) {
1049
                    $sql = "UPDATE $table_message_attach 
1050
                            SET path = '$new_path'
1051
                            WHERE id = $attach_id ";
1052
                    Database::query($sql);
1053
                }
1054
            }
1055
        }
1056
    }
1057
1058
    /**
1059
     * @param int $user_id
1060
     * @param int $message_id
1061
     * @param int $type
1062
     *
1063
     * @return bool
1064
     */
1065
    public static function update_message_status($user_id, $message_id, $type)
1066
    {
1067
        $user_id = (int) $user_id;
1068
        $message_id = (int) $message_id;
1069
        $type = (int) $type;
1070
1071
        if (empty($user_id) || empty($message_id)) {
1072
            return false;
1073
        }
1074
1075
        $table_message = Database::get_main_table(TABLE_MESSAGE);
1076
        $sql = "UPDATE $table_message SET
1077
                    msg_status = '$type'
1078
                WHERE
1079
                    user_receiver_id = ".$user_id." AND
1080
                    id = '".$message_id."'";
1081
        Database::query($sql);
1082
    }
1083
1084
    /**
1085
     * get messages by group id.
1086
     *
1087
     * @param int $group_id group id
1088
     *
1089
     * @return array
1090
     */
1091
    public static function get_messages_by_group($group_id)
1092
    {
1093
        $group_id = (int) $group_id;
1094
1095
        if (empty($group_id)) {
1096
            return false;
1097
        }
1098
1099
        $table = Database::get_main_table(TABLE_MESSAGE);
1100
        $sql = "SELECT * FROM $table
1101
                WHERE
1102
                    group_id= $group_id AND
1103
                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
1104
                ORDER BY id";
1105
        $rs = Database::query($sql);
1106
        $data = [];
1107
        if (Database::num_rows($rs) > 0) {
1108
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
1109
                $data[] = $row;
1110
            }
1111
        }
1112
1113
        return $data;
1114
    }
1115
1116
    /**
1117
     * get messages by group id.
1118
     *
1119
     * @param int $group_id
1120
     * @param int $message_id
1121
     *
1122
     * @return array
1123
     */
1124
    public static function get_messages_by_group_by_message($group_id, $message_id)
1125
    {
1126
        $group_id = (int) $group_id;
1127
1128
        if (empty($group_id)) {
1129
            return false;
1130
        }
1131
1132
        $table = Database::get_main_table(TABLE_MESSAGE);
1133
        $sql = "SELECT * FROM $table
1134
                WHERE
1135
                    group_id = $group_id AND
1136
                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
1137
                ORDER BY id ";
1138
1139
        $rs = Database::query($sql);
1140
        $data = [];
1141
        $parents = [];
1142
        if (Database::num_rows($rs) > 0) {
1143
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
1144
                if ($message_id == $row['parent_id'] || in_array($row['parent_id'], $parents)) {
1145
                    $parents[] = $row['id'];
1146
                    $data[] = $row;
1147
                }
1148
            }
1149
        }
1150
1151
        return $data;
1152
    }
1153
1154
    /**
1155
     * Get messages by parent id optionally with limit.
1156
     *
1157
     * @param  int        parent id
1158
     * @param  int        group id (optional)
1159
     * @param  int        offset (optional)
1160
     * @param  int        limit (optional)
1161
     *
1162
     * @return array
1163
     */
1164
    public static function getMessagesByParent($parentId, $groupId = 0, $offset = 0, $limit = 0)
1165
    {
1166
        $table = Database::get_main_table(TABLE_MESSAGE);
1167
        $parentId = (int) $parentId;
1168
1169
        if (empty($parentId)) {
1170
            return [];
1171
        }
1172
1173
        $condition_group_id = '';
1174
        if (!empty($groupId)) {
1175
            $groupId = (int) $groupId;
1176
            $condition_group_id = " AND group_id = '$groupId' ";
1177
        }
1178
1179
        $condition_limit = '';
1180
        if ($offset && $limit) {
1181
            $offset = (int) $offset;
1182
            $limit = (int) $limit;
1183
            $offset = ($offset - 1) * $limit;
1184
            $condition_limit = " LIMIT $offset,$limit ";
1185
        }
1186
1187
        $sql = "SELECT * FROM $table
1188
                WHERE
1189
                    parent_id='$parentId' AND
1190
                    msg_status NOT IN (".MESSAGE_STATUS_OUTBOX.", ".MESSAGE_STATUS_WALL_DELETE.")
1191
                    $condition_group_id
1192
                ORDER BY send_date DESC $condition_limit ";
1193
        $rs = Database::query($sql);
1194
        $data = [];
1195
        if (Database::num_rows($rs) > 0) {
1196
            while ($row = Database::fetch_array($rs)) {
1197
                $data[$row['id']] = $row;
1198
            }
1199
        }
1200
1201
        return $data;
1202
    }
1203
1204
    /**
1205
     * Gets information about messages sent.
1206
     *
1207
     * @param int
1208
     * @param int
1209
     * @param string
1210
     * @param string
1211
     *
1212
     * @return array
1213
     */
1214
    public static function get_message_data_sent(
1215
        $from,
1216
        $numberOfItems,
1217
        $column,
1218
        $direction,
1219
        $extraParams = []
1220
    ) {
1221
        $from = (int) $from;
1222
        $numberOfItems = (int) $numberOfItems;
1223
        if (!isset($direction)) {
1224
            $column = 2;
1225
            $direction = 'DESC';
1226
        } else {
1227
            $column = (int) $column;
1228
            if (!in_array($direction, ['ASC', 'DESC'])) {
1229
                $direction = 'ASC';
1230
            }
1231
        }
1232
1233
        if (!in_array($column, [0, 1, 2])) {
1234
            $column = 2;
1235
        }
1236
        $table = Database::get_main_table(TABLE_MESSAGE);
1237
        $request = api_is_xml_http_request();
1238
        $keyword = isset($extraParams['keyword']) && !empty($extraParams['keyword']) ? $extraParams['keyword'] : '';
1239
        $keywordCondition = '';
1240
        if (!empty($keyword)) {
1241
            $keyword = Database::escape_string($keyword);
1242
            $keywordCondition = " AND (title like '%$keyword%' OR content LIKE '%$keyword%') ";
1243
        }
1244
1245
        $sql = "SELECT
1246
                    id as col0,
1247
                    title as col1,
1248
                    send_date as col2,
1249
                    user_receiver_id,
1250
                    msg_status,
1251
                    user_sender_id
1252
                FROM $table
1253
                WHERE
1254
                    user_sender_id = ".api_get_user_id()." AND
1255
                    msg_status = ".MESSAGE_STATUS_OUTBOX."
1256
                    $keywordCondition
1257
                ORDER BY col$column $direction
1258
                LIMIT $from, $numberOfItems";
1259
        $result = Database::query($sql);
1260
1261
        $message_list = [];
1262
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1263
            $messageId = $row['col0'];
1264
            $title = $row['col1'];
1265
            $sendDate = $row['col2'];
1266
            $senderId = $row['user_sender_id'];
1267
1268
            if ($request === true) {
1269
                $message[0] = '<input type="checkbox" value='.$messageId.' name="out[]">';
1270
            } else {
1271
                $message[0] = $messageId;
1272
            }
1273
1274
            $class = 'class = "read"';
1275
            $title = Security::remove_XSS($title);
1276
            $userInfo = api_get_user_info($senderId);
1277
            if ($request === true) {
1278
                $message[1] = '<a onclick="show_sent_message('.$messageId.')" href="javascript:void(0)">'.
1279
                    $userInfo['complete_name_with_username'].'</a>';
1280
                $message[2] = '<a onclick="show_sent_message('.$messageId.')" href="javascript:void(0)">'.str_replace(
1281
                        "\\",
1282
                        "",
1283
                        $title
1284
                    ).'</a>';
1285
                //date stays the same
1286
                $message[3] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG);
1287
                $message[4] = '&nbsp;&nbsp;<a title="'.addslashes(
1288
                        get_lang('DeleteMessage')
1289
                    ).'" onclick="delete_one_message_outbox('.$messageId.')" href="javascript:void(0)"  >'.
1290
                    Display::returnFontAwesomeIcon('trash', 2).'</a>';
1291
            } else {
1292
                $message[1] = '<a '.$class.' onclick="show_sent_message('.$messageId.')" href="../messages/view_message.php?id_send='.$messageId.'">'.$title.'</a><br />'.$userInfo['complete_name_with_username'];
1293
                $message[2] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG);
1294
                $message[3] = '<a title="'.addslashes(
1295
                        get_lang('DeleteMessage')
1296
                    ).'" href="outbox.php?action=deleteone&id='.$messageId.'"  onclick="javascript:if(!confirm('."'".addslashes(
1297
                        api_htmlentities(get_lang('ConfirmDeleteMessage'))
1298
                    )."'".')) return false;" >'.
1299
                    Display::returnFontAwesomeIcon('trash', 2).'</a>';
1300
            }
1301
1302
            $message_list[] = $message;
1303
        }
1304
1305
        return $message_list;
1306
    }
1307
1308
    /**
1309
     * display message box in the inbox.
1310
     *
1311
     * @param int $messageId
1312
     * @param int $type
1313
     *
1314
     * @todo replace numbers with letters in the $row array pff...
1315
     *
1316
     * @return string html with the message content
1317
     */
1318
    public static function showMessageBox($messageId, $type)
1319
    {
1320
        $messageId = (int) $messageId;
1321
1322
        if (empty($messageId) || empty($type)) {
1323
            return '';
1324
        }
1325
        $currentUserId = api_get_user_id();
1326
1327
        $table = Database::get_main_table(TABLE_MESSAGE);
1328
1329
        if (empty($type)) {
1330
            return '';
1331
        }
1332
1333
        switch ($type) {
1334
            case self::MESSAGE_TYPE_OUTBOX:
1335
                $status = MESSAGE_STATUS_OUTBOX;
1336
                $userCondition = " user_sender_id = $currentUserId AND ";
1337
                break;
1338
            case self::MESSAGE_TYPE_INBOX:
1339
                $status = MESSAGE_STATUS_NEW;
1340
                $userCondition = " user_receiver_id = $currentUserId AND ";
1341
1342
                $query = "UPDATE $table SET
1343
                          msg_status = '".MESSAGE_STATUS_NEW."'
1344
                          WHERE id = $messageId ";
1345
                Database::query($query);
1346
                break;
1347
            case self::MESSAGE_TYPE_PROMOTED:
1348
                $status = MESSAGE_STATUS_PROMOTED;
1349
                $userCondition = " user_receiver_id = $currentUserId AND ";
1350
                break;
1351
        }
1352
1353
        if (empty($userCondition)) {
1354
            return '';
1355
        }
1356
1357
        $query = "SELECT * FROM $table
1358
                  WHERE                            
1359
                    id = $messageId AND 
1360
                    $userCondition
1361
                    msg_status = $status";
1362
        $result = Database::query($query);
1363
        $row = Database::fetch_array($result, 'ASSOC');
1364
1365
        if (empty($row)) {
1366
            return '';
1367
        }
1368
1369
        $user_sender_id = $row['user_sender_id'];
1370
1371
        // get file attachments by message id
1372
        $files_attachments = self::getAttachmentLinkList($messageId, $type);
1373
1374
        $row['content'] = str_replace('</br>', '<br />', $row['content']);
1375
        $title = Security::remove_XSS($row['title'], STUDENT, true);
1376
        $content = Security::remove_XSS($row['content'], STUDENT, true);
1377
1378
        $name = get_lang('UnknownUser');
1379
        $fromUser = api_get_user_info($user_sender_id);
1380
        $userImage = '';
1381
        if (!empty($user_sender_id) && !empty($fromUser)) {
1382
            $name = $fromUser['complete_name_with_username'];
1383
            $userImage = Display::img(
1384
                $fromUser['avatar_small'],
1385
                $name,
1386
                ['title' => $name, 'class' => 'img-responsive img-circle', 'style' => 'max-width:35px'],
1387
                false
1388
            );
1389
        }
1390
1391
        $message_content = Display::page_subheader(str_replace("\\", '', $title));
1392
1393
        $receiverUserInfo = [];
1394
        if (!empty($row['user_receiver_id'])) {
1395
            $receiverUserInfo = api_get_user_info($row['user_receiver_id']);
1396
        }
1397
1398
        $message_content .= '<tr>';
1399
        if (api_get_setting('allow_social_tool') === 'true') {
1400
            $message_content .= '<div class="row">';
1401
            $message_content .= '<div class="col-md-12">';
1402
            $message_content .= '<ul class="list-message">';
1403
1404
            if (!empty($user_sender_id)) {
1405
                $message_content .= '<li>'.$userImage.'</li>';
1406
                $message_content .= '<li>';
1407
                $message_content .= Display::url(
1408
                    $name,
1409
                    api_get_path(WEB_PATH).'main/social/profile.php?u='.$user_sender_id
1410
                );
1411
            } else {
1412
                $message_content .= '<li>'.$name;
1413
            }
1414
1415
            switch ($type) {
1416
                case self::MESSAGE_TYPE_INBOX:
1417
                    //$message_content .= api_strtolower(get_lang('To')).'&nbsp;<b>-</b></li>';
1418
                    $message_content .= '&nbsp;'.api_strtolower(get_lang('To')).'&nbsp;'.get_lang('Me');
1419
                    break;
1420
                case self::MESSAGE_TYPE_OUTBOX:
1421
                    if (!empty($receiverUserInfo)) {
1422
                        $message_content .= '&nbsp;'.api_strtolower(
1423
                                get_lang('To')
1424
                            ).'&nbsp;<b>'.$receiverUserInfo['complete_name_with_username'].'</b></li>';
1425
                    }
1426
                    break;
1427
                case self::MESSAGE_TYPE_PROMOTED:
1428
                    break;
1429
            }
1430
1431
            $message_content .= '&nbsp;<li>'.Display::dateToStringAgoAndLongDate($row['send_date']).'</li>';
1432
            $message_content .= '</ul>';
1433
            $message_content .= '</div>';
1434
            $message_content .= '</div>';
1435
        } else {
1436
            switch ($type) {
1437
                case self::MESSAGE_TYPE_INBOX:
1438
                    $message_content .= get_lang('From').':&nbsp;'.$name.'</b> '.api_strtolower(get_lang('To')).' <b>'.
1439
                        get_lang('Me').'</b>';
1440
                    break;
1441
                case self::MESSAGE_TYPE_OUTBOX:
1442
1443
                    $message_content .= get_lang('From').':&nbsp;'.$name.'</b> '.api_strtolower(get_lang('To')).' <b>'.
1444
                        $receiverUserInfo['complete_name_with_username'].'</b>';
1445
                    break;
1446
            }
1447
        }
1448
1449
        $message_content .= '
1450
		        <hr style="color:#ddd" />
1451
		        <table width="100%">
1452
		            <tr>
1453
		              <td valign=top class="view-message-content">'.str_replace("\\", "", $content).'</td>
1454
		            </tr>
1455
		        </table>
1456
		        <div id="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>
1457
		        <div style="padding: 15px 0px 5px 0px">';
1458
        $social_link = '';
1459
        if (isset($_GET['f']) && $_GET['f'] == 'social') {
1460
            $social_link = 'f=social';
1461
        }
1462
1463
        switch ($type) {
1464
            case self::MESSAGE_TYPE_OUTBOX:
1465
                $message_content .= '<a href="outbox.php?'.$social_link.'">'.
1466
                    Display::return_icon('back.png', get_lang('ReturnToOutbox')).'</a> &nbsp';
1467
                $message_content .= '<a href="outbox.php?action=deleteone&id='.$messageId.'&'.$social_link.'" >'.
1468
                    Display::return_icon('delete.png', get_lang('DeleteMessage')).'</a>&nbsp';
1469
                break;
1470
            case self::MESSAGE_TYPE_INBOX:
1471
                $message_content .= '<a href="inbox.php?'.$social_link.'">'.
1472
                    Display::return_icon('back.png', get_lang('ReturnToInbox')).'</a> &nbsp';
1473
                $message_content .= '<a href="new_message.php?re_id='.$messageId.'&'.$social_link.'">'.
1474
                    Display::return_icon('message_reply.png', get_lang('ReplyToMessage')).'</a> &nbsp';
1475
                $message_content .= '<a href="inbox.php?action=deleteone&id='.$messageId.'&'.$social_link.'" >'.
1476
                    Display::return_icon('delete.png', get_lang('DeleteMessage')).'</a>&nbsp';
1477
                break;
1478
        }
1479
1480
        $message_content .= '</div></td>
1481
		      <td width=10></td>
1482
		    </tr>
1483
		</table>';
1484
1485
        return $message_content;
1486
    }
1487
1488
    /**
1489
     * get user id by user email.
1490
     *
1491
     * @param string $user_email
1492
     *
1493
     * @return int user id
1494
     */
1495
    public static function get_user_id_by_email($user_email)
1496
    {
1497
        $table = Database::get_main_table(TABLE_MAIN_USER);
1498
        $sql = 'SELECT user_id
1499
                FROM '.$table.'
1500
                WHERE email="'.Database::escape_string($user_email).'";';
1501
        $rs = Database::query($sql);
1502
        $row = Database::fetch_array($rs, 'ASSOC');
1503
        if (isset($row['user_id'])) {
1504
            return $row['user_id'];
1505
        }
1506
1507
        return null;
1508
    }
1509
1510
    /**
1511
     * Displays messages of a group with nested view.
1512
     *
1513
     * @param int $groupId
1514
     *
1515
     * @return string
1516
     */
1517
    public static function display_messages_for_group($groupId)
1518
    {
1519
        global $my_group_role;
1520
1521
        $rows = self::get_messages_by_group($groupId);
1522
        $topics_per_page = 10;
1523
        $html_messages = '';
1524
        $query_vars = ['id' => $groupId, 'topics_page_nr' => 0];
1525
1526
        if (is_array($rows) && count($rows) > 0) {
1527
            // prepare array for topics with its items
1528
            $topics = [];
1529
            $x = 0;
1530
            foreach ($rows as $index => $value) {
1531
                if (empty($value['parent_id'])) {
1532
                    $topics[$value['id']] = $value;
1533
                }
1534
            }
1535
1536
            $new_topics = [];
1537
1538
            foreach ($topics as $id => $value) {
1539
                $rows = null;
1540
                $rows = self::get_messages_by_group_by_message($groupId, $value['id']);
1541
                if (!empty($rows)) {
1542
                    $count = count(self::calculate_children($rows, $value['id']));
1543
                } else {
1544
                    $count = 0;
1545
                }
1546
                $value['count'] = $count;
1547
                $new_topics[$id] = $value;
1548
            }
1549
1550
            $array_html = [];
1551
            foreach ($new_topics as $index => $topic) {
1552
                $html = '';
1553
                // topics
1554
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
1555
                $name = $user_sender_info['complete_name'];
1556
                $html .= '<div class="groups-messages">';
1557
                $html .= '<div class="row">';
1558
1559
                $items = $topic['count'];
1560
                $reply_label = ($items == 1) ? get_lang('GroupReply') : get_lang('GroupReplies');
1561
                $label = '<i class="fa fa-envelope"></i> '.$items.' '.$reply_label;
1562
                $topic['title'] = trim($topic['title']);
1563
1564
                if (empty($topic['title'])) {
1565
                    $topic['title'] = get_lang('Untitled');
1566
                }
1567
1568
                $html .= '<div class="col-xs-8 col-md-10">';
1569
                $html .= Display::tag(
1570
                    'h4',
1571
                    Display::url(
1572
                        Security::remove_XSS($topic['title'], STUDENT, true),
1573
                        api_get_path(WEB_CODE_PATH).'social/group_topics.php?id='.$groupId.'&topic_id='.$topic['id']
1574
                    ),
1575
                    ['class' => 'title']
1576
                );
1577
                $actions = '';
1578
                if ($my_group_role == GROUP_USER_PERMISSION_ADMIN ||
1579
                    $my_group_role == GROUP_USER_PERMISSION_MODERATOR
1580
                ) {
1581
                    $actions = '<br />'.Display::url(
1582
                            get_lang('Delete'),
1583
                            api_get_path(
1584
                                WEB_CODE_PATH
1585
                            ).'social/group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic['id'],
1586
                            ['class' => 'btn btn-default']
1587
                        );
1588
                }
1589
1590
                $date = '';
1591
                if ($topic['send_date'] != $topic['update_date']) {
1592
                    if (!empty($topic['update_date'])) {
1593
                        $date .= '<i class="fa fa-calendar"></i> '.get_lang(
1594
                                'LastUpdate'
1595
                            ).' '.Display::dateToStringAgoAndLongDate($topic['update_date']);
1596
                    }
1597
                } else {
1598
                    $date .= '<i class="fa fa-calendar"></i> '.get_lang(
1599
                            'Created'
1600
                        ).' '.Display::dateToStringAgoAndLongDate($topic['send_date']);
1601
                }
1602
                $html .= '<div class="date">'.$label.' - '.$date.$actions.'</div>';
1603
                $html .= '</div>';
1604
1605
                $image = $user_sender_info['avatar'];
1606
1607
                $user_info = '<div class="author"><img class="img-responsive img-circle" src="'.$image.'" alt="'.$name.'"  width="64" height="64" title="'.$name.'" /></div>';
1608
                $user_info .= '<div class="name"><a href="'.api_get_path(
1609
                        WEB_PATH
1610
                    ).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp;</a></div>';
1611
1612
                $html .= '<div class="col-xs-4 col-md-2">';
1613
                $html .= $user_info;
1614
                $html .= '</div>';
1615
                $html .= '</div>';
1616
                $html .= '</div>';
1617
1618
                $array_html[] = [$html];
1619
            }
1620
1621
            // grids for items and topics  with paginations
1622
            $html_messages .= Display::return_sortable_grid(
1623
                'topics',
1624
                [],
1625
                $array_html,
1626
                [
1627
                    'hide_navigation' => false,
1628
                    'per_page' => $topics_per_page,
1629
                ],
1630
                $query_vars,
1631
                false,
1632
                [true, true, true, false],
1633
                false
1634
            );
1635
        }
1636
1637
        return $html_messages;
1638
    }
1639
1640
    /**
1641
     * Displays messages of a group with nested view.
1642
     *
1643
     * @param $groupId
1644
     * @param $topic_id
1645
     *
1646
     * @return string
1647
     */
1648
    public static function display_message_for_group($groupId, $topic_id, $is_member, $messageId)
1649
    {
1650
        global $my_group_role;
1651
        $main_message = self::get_message_by_id($topic_id);
1652
        if (empty($main_message)) {
1653
            return false;
1654
        }
1655
1656
        $webCodePath = api_get_path(WEB_CODE_PATH);
1657
        $iconCalendar = Display::returnFontAwesomeIcon('calendar');
1658
1659
        $langEdit = get_lang('Edit');
1660
        $langReply = get_lang('Reply');
1661
        $langLastUpdated = get_lang('LastUpdated');
1662
        $langCreated = get_lang('Created');
1663
1664
        $rows = self::get_messages_by_group_by_message($groupId, $topic_id);
1665
        $rows = self::calculate_children($rows, $topic_id);
1666
        $current_user_id = api_get_user_id();
1667
1668
        $items_per_page = 50;
1669
        $query_vars = ['id' => $groupId, 'topic_id' => $topic_id, 'topics_page_nr' => 0];
1670
1671
        // Main message
1672
        $links = '';
1673
        $main_content = '';
1674
        $html = '';
1675
        $items_page_nr = null;
1676
1677
        $user_sender_info = api_get_user_info($main_message['user_sender_id']);
1678
        $files_attachments = self::getAttachmentLinkList($main_message['id'], 0);
1679
        $name = $user_sender_info['complete_name'];
1680
1681
        $topic_page_nr = isset($_GET['topics_page_nr']) ? (int) $_GET['topics_page_nr'] : null;
1682
1683
        $links .= '<div class="pull-right">';
1684
        $links .= '<div class="btn-group btn-group-sm">';
1685
1686
        if (($my_group_role == GROUP_USER_PERMISSION_ADMIN || $my_group_role == GROUP_USER_PERMISSION_MODERATOR) ||
1687
            $main_message['user_sender_id'] == $current_user_id
1688
        ) {
1689
            $urlEdit = $webCodePath.'social/message_for_group_form.inc.php?'
1690
                .http_build_query(
1691
                    [
1692
                        'user_friend' => $current_user_id,
1693
                        'group_id' => $groupId,
1694
                        'message_id' => $main_message['id'],
1695
                        'action' => 'edit_message_group',
1696
                        'anchor_topic' => 'topic_'.$main_message['id'],
1697
                        'topics_page_nr' => $topic_page_nr,
1698
                        'items_page_nr' => $items_page_nr,
1699
                        'topic_id' => $main_message['id'],
1700
                    ]
1701
                );
1702
1703
            $links .= Display::toolbarButton(
1704
                $langEdit,
1705
                $urlEdit,
1706
                'pencil',
1707
                'default',
1708
                ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'],
1709
                false
1710
            );
1711
        }
1712
1713
        $links .= self::getLikesButton($main_message['id'], $current_user_id, $groupId);
1714
1715
        $urlReply = $webCodePath.'social/message_for_group_form.inc.php?'
1716
            .http_build_query(
1717
                [
1718
                    'user_friend' => $current_user_id,
1719
                    'group_id' => $groupId,
1720
                    'message_id' => $main_message['id'],
1721
                    'action' => 'reply_message_group',
1722
                    'anchor_topic' => 'topic_'.$main_message['id'],
1723
                    'topics_page_nr' => $topic_page_nr,
1724
                    'topic_id' => $main_message['id'],
1725
                ]
1726
            );
1727
1728
        $links .= Display::toolbarButton(
1729
            $langReply,
1730
            $urlReply,
1731
            'commenting',
1732
            'default',
1733
            ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'],
1734
            false
1735
        );
1736
1737
        if (api_is_platform_admin()) {
1738
            $links .= Display::toolbarButton(
1739
                get_lang('Delete'),
1740
                'group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic_id,
1741
                'trash',
1742
                'default',
1743
                [],
1744
                false
1745
            );
1746
        }
1747
1748
        $links .= '</div>';
1749
        $links .= '</div>';
1750
1751
        $title = '<h4>'.Security::remove_XSS($main_message['title'], STUDENT, true).$links.'</h4>';
1752
1753
        $userPicture = $user_sender_info['avatar'];
1754
        $main_content .= '<div class="row">';
1755
        $main_content .= '<div class="col-md-2">';
1756
        $main_content .= '<div class="avatar-author">';
1757
        $main_content .= Display::img(
1758
            $userPicture,
1759
            $name,
1760
            ['width' => '60px', 'class' => 'img-responsive img-circle'],
1761
            false
1762
        );
1763
        $main_content .= '</div>';
1764
        $main_content .= '</div>';
1765
1766
        $date = '';
1767
        if ($main_message['send_date'] != $main_message['update_date']) {
1768
            if (!empty($main_message['update_date'])) {
1769
                $date = '<div class="date"> '
1770
                    ."$iconCalendar $langLastUpdated "
1771
                    .Display::dateToStringAgoAndLongDate($main_message['update_date'])
1772
                    .'</div>';
1773
            }
1774
        } else {
1775
            $date = '<div class="date"> '
1776
                ."$iconCalendar $langCreated "
1777
                .Display::dateToStringAgoAndLongDate($main_message['send_date'])
1778
                .'</div>';
1779
        }
1780
        $attachment = '<div class="message-attach">'
1781
            .(!empty($files_attachments) ? implode('<br />', $files_attachments) : '')
1782
            .'</div>';
1783
        $main_content .= '<div class="col-md-10">';
1784
        $user_link = Display::url(
1785
            $name,
1786
            $webCodePath.'social/profile.php?u='.$main_message['user_sender_id']
1787
        );
1788
        $main_content .= '<div class="message-content"> ';
1789
        $main_content .= '<div class="username">'.$user_link.'</div>';
1790
        $main_content .= $date;
1791
        $main_content .= '<div class="message">'.$main_message['content'].$attachment.'</div></div>';
1792
        $main_content .= '</div>';
1793
        $main_content .= '</div>';
1794
1795
        $html .= Display::div(
1796
            Display::div(
1797
                $title.$main_content,
1798
                ['class' => 'message-topic']
1799
            ),
1800
            ['class' => 'sm-groups-message']
1801
        );
1802
1803
        $topic_id = $main_message['id'];
1804
1805
        if (is_array($rows) && count($rows) > 0) {
1806
            $topics = $rows;
1807
            $array_html_items = [];
1808
1809
            foreach ($topics as $index => $topic) {
1810
                if (empty($topic['id'])) {
1811
                    continue;
1812
                }
1813
                $items_page_nr = isset($_GET['items_'.$topic['id'].'_page_nr'])
1814
                    ? (int) $_GET['items_'.$topic['id'].'_page_nr']
1815
                    : null;
1816
                $links = '';
1817
                $links .= '<div class="pull-right">';
1818
                $html_items = '';
1819
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
1820
                $files_attachments = self::getAttachmentLinkList($topic['id'], 0);
1821
                $name = $user_sender_info['complete_name'];
1822
1823
                $links .= '<div class="btn-group btn-group-sm">';
1824
                if (
1825
                    ($my_group_role == GROUP_USER_PERMISSION_ADMIN ||
1826
                        $my_group_role == GROUP_USER_PERMISSION_MODERATOR
1827
                    ) ||
1828
                    $topic['user_sender_id'] == $current_user_id
1829
                ) {
1830
                    $links .= Display::toolbarButton(
1831
                        $langEdit,
1832
                        $webCodePath.'social/message_for_group_form.inc.php?'
1833
                            .http_build_query(
1834
                                [
1835
                                    'user_friend' => $current_user_id,
1836
                                    'group_id' => $groupId,
1837
                                    'message_id' => $topic['id'],
1838
                                    'action' => 'edit_message_group',
1839
                                    'anchor_topic' => 'topic_'.$topic_id,
1840
                                    'topics_page_nr' => $topic_page_nr,
1841
                                    'items_page_nr' => $items_page_nr,
1842
                                    'topic_id' => $topic_id,
1843
                                ]
1844
                            ),
1845
                        'pencil',
1846
                        'default',
1847
                        ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'],
1848
                        false
1849
                    );
1850
                }
1851
1852
                $links .= self::getLikesButton($topic['id'], $current_user_id, $groupId);
1853
1854
                $links .= Display::toolbarButton(
1855
                    $langReply,
1856
                    $webCodePath.'social/message_for_group_form.inc.php?'
1857
                        .http_build_query(
1858
                            [
1859
                                'user_friend' => $current_user_id,
1860
                                'group_id' => $groupId,
1861
                                'message_id' => $topic['id'],
1862
                                'action' => 'reply_message_group',
1863
                                'anchor_topic' => 'topic_'.$topic_id,
1864
                                'topics_page_nr' => $topic_page_nr,
1865
                                'items_page_nr' => $items_page_nr,
1866
                                'topic_id' => $topic_id,
1867
                            ]
1868
                        ),
1869
                    'commenting',
1870
                    'default',
1871
                    ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'],
1872
                    false
1873
                );
1874
                $links .= '</div>';
1875
                $links .= '</div>';
1876
1877
                $userPicture = $user_sender_info['avatar'];
1878
                $user_link = Display::url(
1879
                    $name,
1880
                    $webCodePath.'social/profile.php?u='.$topic['user_sender_id']
1881
                );
1882
                $html_items .= '<div class="row">';
1883
                $html_items .= '<div class="col-md-2">';
1884
                $html_items .= '<div class="avatar-author">';
1885
                $html_items .= Display::img(
1886
                    $userPicture,
1887
                    $name,
1888
                    ['width' => '60px', 'class' => 'img-responsive img-circle'],
1889
                    false
1890
                );
1891
                $html_items .= '</div>';
1892
                $html_items .= '</div>';
1893
1894
                $date = '';
1895
                if ($topic['send_date'] != $topic['update_date']) {
1896
                    if (!empty($topic['update_date'])) {
1897
                        $date = '<div class="date"> '
1898
                            ."$iconCalendar $langLastUpdated "
1899
                            .Display::dateToStringAgoAndLongDate($topic['update_date'])
1900
                            .'</div>';
1901
                    }
1902
                } else {
1903
                    $date = '<div class="date"> '
1904
                        ."$iconCalendar $langCreated "
1905
                        .Display::dateToStringAgoAndLongDate($topic['send_date'])
1906
                        .'</div>';
1907
                }
1908
                $attachment = '<div class="message-attach">'
1909
                    .(!empty($files_attachments) ? implode('<br />', $files_attachments) : '')
1910
                    .'</div>';
1911
                $html_items .= '<div class="col-md-10">'
1912
                    .'<div class="message-content">'
1913
                    .$links
1914
                    .'<div class="username">'.$user_link.'</div>'
1915
                    .$date
1916
                    .'<div class="message">'
1917
                    .Security::remove_XSS($topic['content'], STUDENT, true)
1918
                    .'</div>'.$attachment.'</div>'
1919
                    .'</div>'
1920
                    .'</div>';
1921
1922
                $base_padding = 20;
1923
1924
                if ($topic['indent_cnt'] == 0) {
1925
                    $indent = $base_padding;
1926
                } else {
1927
                    $indent = (int) $topic['indent_cnt'] * $base_padding + $base_padding;
1928
                }
1929
1930
                $html_items = Display::div($html_items, ['class' => 'message-post', 'id' => 'msg_'.$topic['id']]);
1931
                $html_items = Display::div($html_items, ['class' => '', 'style' => 'margin-left:'.$indent.'px']);
1932
                $array_html_items[] = [$html_items];
1933
            }
1934
1935
            // grids for items with paginations
1936
            $options = ['hide_navigation' => false, 'per_page' => $items_per_page];
1937
            $visibility = [true, true, true, false];
1938
1939
            $style_class = [
1940
                'item' => ['class' => 'user-post'],
1941
                'main' => ['class' => 'user-list'],
1942
            ];
1943
            if (!empty($array_html_items)) {
1944
                $html .= Display::return_sortable_grid(
1945
                    'items_'.$topic['id'],
1946
                    [],
1947
                    $array_html_items,
1948
                    $options,
1949
                    $query_vars,
1950
                    null,
1951
                    $visibility,
1952
                    false,
1953
                    $style_class
1954
                );
1955
            }
1956
        }
1957
1958
        return $html;
1959
    }
1960
1961
    /**
1962
     * Add children to messages by id is used for nested view messages.
1963
     *
1964
     * @param array $rows rows of messages
1965
     *
1966
     * @return array $first_seed new list adding the item children
1967
     */
1968
    public static function calculate_children($rows, $first_seed)
1969
    {
1970
        $rows_with_children = [];
1971
        foreach ($rows as $row) {
1972
            $rows_with_children[$row["id"]] = $row;
1973
            $rows_with_children[$row["parent_id"]]["children"][] = $row["id"];
1974
        }
1975
        $rows = $rows_with_children;
1976
        $sorted_rows = [0 => []];
1977
        self::message_recursive_sort($rows, $sorted_rows, $first_seed);
1978
        unset($sorted_rows[0]);
1979
1980
        return $sorted_rows;
1981
    }
1982
1983
    /**
1984
     * Sort recursively the messages, is used for for nested view messages.
1985
     *
1986
     * @param array  original rows of messages
1987
     * @param array  list recursive of messages
1988
     * @param int   seed for calculate the indent
1989
     * @param int   indent for nested view
1990
     */
1991
    public static function message_recursive_sort(
1992
        $rows,
1993
        &$messages,
1994
        $seed = 0,
1995
        $indent = 0
1996
    ) {
1997
        if ($seed > 0 && isset($rows[$seed]["id"])) {
1998
            $messages[$rows[$seed]["id"]] = $rows[$seed];
1999
            $messages[$rows[$seed]["id"]]["indent_cnt"] = $indent;
2000
            $indent++;
2001
        }
2002
2003
        if (isset($rows[$seed]["children"])) {
2004
            foreach ($rows[$seed]["children"] as $child) {
2005
                self::message_recursive_sort($rows, $messages, $child, $indent);
2006
            }
2007
        }
2008
    }
2009
2010
    /**
2011
     * @param int $messageId
2012
     *
2013
     * @return array
2014
     */
2015
    public static function getAttachmentList($messageId)
2016
    {
2017
        $table = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
2018
        $messageId = (int) $messageId;
2019
2020
        if (empty($messageId)) {
2021
            return [];
2022
        }
2023
2024
        $messageInfo = self::get_message_by_id($messageId);
2025
2026
        if (empty($messageInfo)) {
2027
            return [];
2028
        }
2029
2030
        $attachmentDir = UserManager::getUserPathById($messageInfo['user_receiver_id'], 'system');
2031
        $attachmentDir .= 'message_attachments/';
2032
2033
        $sql = "SELECT * FROM $table
2034
                WHERE message_id = '$messageId'";
2035
        $result = Database::query($sql);
2036
        $files = [];
2037
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2038
            $row['file_source'] = '';
2039
            if (file_exists($attachmentDir.$row['path'])) {
2040
                $row['file_source'] = $attachmentDir.$row['path'];
2041
            }
2042
            $files[] = $row;
2043
        }
2044
2045
        return $files;
2046
    }
2047
2048
    /**
2049
     * Get array of links (download) for message attachment files.
2050
     *
2051
     * @param int $messageId
2052
     * @param int $type
2053
     *
2054
     * @return array
2055
     */
2056
    public static function getAttachmentLinkList($messageId, $type)
2057
    {
2058
        $files = self::getAttachmentList($messageId);
2059
        // get file attachments by message id
2060
        $list = [];
2061
        if ($files) {
2062
            $attachIcon = Display::return_icon('attachment.gif', '');
2063
            $archiveURL = api_get_path(WEB_CODE_PATH).'messages/download.php?type='.$type.'&file=';
2064
            foreach ($files as $row_file) {
2065
                $archiveFile = $row_file['path'];
2066
                $filename = $row_file['filename'];
2067
                $size = format_file_size($row_file['size']);
2068
                $comment = Security::remove_XSS($row_file['comment']);
2069
                $filename = Security::remove_XSS($filename);
2070
                $link = Display::url($filename, $archiveURL.$archiveFile);
2071
                $comment = !empty($comment) ? '&nbsp;-&nbsp;<i>'.$comment.'</i>' : '';
2072
2073
                $attachmentLine = $attachIcon.'&nbsp;'.$link.'&nbsp;('.$size.')'.$comment;
2074
                if ($row_file['comment'] === 'audio_message') {
2075
                    $attachmentLine = '<audio src="'.$archiveURL.$archiveFile.'"/>';
2076
                }
2077
                $list[] = $attachmentLine;
2078
            }
2079
        }
2080
2081
        return $list;
2082
    }
2083
2084
    /**
2085
     * Get message list by id.
2086
     *
2087
     * @param int $messageId
2088
     *
2089
     * @return array
2090
     */
2091
    public static function get_message_by_id($messageId)
2092
    {
2093
        $table = Database::get_main_table(TABLE_MESSAGE);
2094
        $messageId = (int) $messageId;
2095
        $sql = "SELECT * FROM $table
2096
                WHERE 
2097
                    id = '$messageId' AND 
2098
                    msg_status <> '".MESSAGE_STATUS_DELETED."' ";
2099
        $res = Database::query($sql);
2100
        $item = [];
2101
        if (Database::num_rows($res) > 0) {
2102
            $item = Database::fetch_array($res, 'ASSOC');
2103
        }
2104
2105
        return $item;
2106
    }
2107
2108
    /**
2109
     * @return string
2110
     */
2111
    public static function generate_message_form()
2112
    {
2113
        $form = new FormValidator('send_message');
2114
        $form->addText(
2115
            'subject',
2116
            get_lang('Subject'),
2117
            false,
2118
            ['id' => 'subject_id']
2119
        );
2120
        $form->addTextarea(
2121
            'content',
2122
            get_lang('Message'),
2123
            ['id' => 'content_id', 'rows' => '5']
2124
        );
2125
2126
        return $form->returnForm();
2127
    }
2128
2129
    /**
2130
     * @return string
2131
     */
2132
    public static function generate_invitation_form()
2133
    {
2134
        $form = new FormValidator('send_invitation');
2135
        $form->addTextarea(
2136
            'content',
2137
            get_lang('AddPersonalMessage'),
2138
            ['id' => 'content_invitation_id', 'rows' => 5]
2139
        );
2140
2141
        return $form->returnForm();
2142
    }
2143
2144
    /**
2145
     * @param string $type
2146
     * @param string $keyword
2147
     * @param array  $actions
2148
     *
2149
     * @return string
2150
     */
2151
    public static function getMessageGrid($type, $keyword, $actions = [])
2152
    {
2153
        $html = '';
2154
        // display sortable table with messages of the current user
2155
        $table = new SortableTable(
2156
            'message_inbox',
2157
            ['MessageManager', 'getNumberOfMessages'],
2158
            ['MessageManager', 'getMessageData'],
2159
            2,
2160
            20,
2161
            'DESC'
2162
        );
2163
2164
        $table->setDataFunctionParams(
2165
            ['keyword' => $keyword, 'type' => $type, 'actions' => $actions]
2166
        );
2167
        $table->set_header(0, '', false, ['style' => 'width:15px;']);
2168
        $table->set_header(1, get_lang('Messages'), false);
2169
        $table->set_header(2, get_lang('Date'), true, ['style' => 'width:180px;']);
2170
        $table->set_header(3, get_lang('Modify'), false, ['style' => 'width:120px;']);
2171
2172
        if (isset($_REQUEST['f']) && $_REQUEST['f'] === 'social') {
2173
            $parameters['f'] = 'social';
2174
            $table->set_additional_parameters($parameters);
2175
        }
2176
2177
        $defaultActions = [
2178
            'delete' => get_lang('DeleteSelectedMessages'),
2179
            'mark_as_unread' => get_lang('MailMarkSelectedAsUnread'),
2180
            'mark_as_read' => get_lang('MailMarkSelectedAsRead'),
2181
        ];
2182
2183
        if (!in_array('delete', $actions)) {
2184
            unset($defaultActions['delete']);
2185
        }
2186
        if (!in_array('mark_as_unread', $actions)) {
2187
            unset($defaultActions['mark_as_unread']);
2188
        }
2189
        if (!in_array('mark_as_read', $actions)) {
2190
            unset($defaultActions['mark_as_read']);
2191
        }
2192
2193
        $table->set_form_actions($defaultActions);
2194
2195
        $html .= $table->return_table();
2196
2197
        return $html;
2198
    }
2199
2200
    /**
2201
     * @param string $keyword
2202
     *
2203
     * @return string
2204
     */
2205
    public static function inboxDisplay($keyword = '')
2206
    {
2207
        $success = get_lang('SelectedMessagesDeleted');
2208
        $success_read = get_lang('SelectedMessagesRead');
2209
        $success_unread = get_lang('SelectedMessagesUnRead');
2210
        $currentUserId = api_get_user_id();
2211
2212
        if (isset($_REQUEST['action'])) {
2213
            switch ($_REQUEST['action']) {
2214
                case 'mark_as_unread':
2215
                    if (is_array($_POST['id'])) {
2216
                        foreach ($_POST['id'] as $index => $messageId) {
2217
                            self::update_message_status(
2218
                                $currentUserId,
2219
                                $messageId,
2220
                                MESSAGE_STATUS_UNREAD
2221
                            );
2222
                        }
2223
                    }
2224
                    Display::addFlash(Display::return_message(
2225
                        $success_unread,
2226
                        'normal',
2227
                        false
2228
                    ));
2229
                    break;
2230
                case 'mark_as_read':
2231
                    if (is_array($_POST['id'])) {
2232
                        foreach ($_POST['id'] as $index => $messageId) {
2233
                            self::update_message_status(
2234
                                $currentUserId,
2235
                                $messageId,
2236
                                MESSAGE_STATUS_NEW
2237
                            );
2238
                        }
2239
                    }
2240
                    Display::addFlash(Display::return_message(
2241
                        $success_read,
2242
                        'normal',
2243
                        false
2244
                    ));
2245
                    break;
2246
                case 'delete':
2247
                    foreach ($_POST['id'] as $index => $messageId) {
2248
                        self::delete_message_by_user_receiver($currentUserId, $messageId);
2249
                    }
2250
                    Display::addFlash(Display::return_message(
2251
                        $success,
2252
                        'normal',
2253
                        false
2254
                    ));
2255
                    break;
2256
                case 'deleteone':
2257
                    $result = self::delete_message_by_user_receiver($currentUserId, $_GET['id']);
2258
                    if ($result) {
2259
                        Display::addFlash(
2260
                            Display::return_message(
2261
                                $success,
2262
                                'confirmation',
2263
                                false
2264
                            )
2265
                        );
2266
                    }
2267
                    break;
2268
            }
2269
            header('Location: '.api_get_self());
2270
            exit;
2271
        }
2272
2273
        $actions = ['reply', 'mark_as_unread', 'mark_as_read', 'forward', 'delete'];
2274
        $html = self::getMessageGrid(self::MESSAGE_TYPE_INBOX, $keyword, $actions);
2275
2276
        return $html;
2277
    }
2278
2279
    /**
2280
     * @param string $keyword
2281
     *
2282
     * @return string
2283
     */
2284
    public static function getPromotedMessagesGrid($keyword)
2285
    {
2286
        $actions = ['delete'];
2287
        $currentUserId = api_get_user_id();
2288
2289
        $success = get_lang('SelectedMessagesDeleted');
2290
        if (isset($_REQUEST['action'])) {
2291
            switch ($_REQUEST['action']) {
2292
                case 'delete':
2293
                    foreach ($_POST['id'] as $index => $messageId) {
2294
                        self::delete_message_by_user_receiver($currentUserId, $messageId);
2295
                    }
2296
                    Display::addFlash(Display::return_message(
2297
                        $success,
2298
                        'normal',
2299
                        false
2300
                    ));
2301
                    break;
2302
                case 'deleteone':
2303
                    self::delete_message_by_user_receiver($currentUserId, $_GET['id']);
2304
                    Display::addFlash(Display::return_message(
2305
                        $success,
2306
                        'confirmation',
2307
                        false
2308
                    ));
2309
                    break;
2310
            }
2311
2312
            header('Location: '.api_get_self());
2313
            exit;
2314
        }
2315
2316
        $html = self::getMessageGrid(self::MESSAGE_TYPE_PROMOTED, $keyword, $actions);
2317
2318
        return $html;
2319
    }
2320
2321
    /**
2322
     * @param string $keyword
2323
     *
2324
     * @return string
2325
     */
2326
    public static function outBoxDisplay($keyword)
2327
    {
2328
        $actions = ['delete'];
2329
2330
        $success = get_lang('SelectedMessagesDeleted');
2331
        $currentUserId = api_get_user_id();
2332
        if (isset($_REQUEST['action'])) {
2333
            switch ($_REQUEST['action']) {
2334
                case 'delete':
2335
                    foreach ($_POST['id'] as $index => $messageId) {
2336
                        self::delete_message_by_user_sender($currentUserId, $messageId);
2337
                    }
2338
                    Display::addFlash(Display::return_message(
2339
                        $success,
2340
                        'normal',
2341
                        false
2342
                    ));
2343
2344
                    break;
2345
                case 'deleteone':
2346
                    self::delete_message_by_user_sender($currentUserId, $_GET['id']);
2347
                    Display::addFlash(Display::return_message(
2348
                        $success,
2349
                        'confirmation',
2350
                        false
2351
                    ));
2352
                    break;
2353
            }
2354
2355
            header('Location: '.api_get_self());
2356
            exit;
2357
        }
2358
2359
        $html = self::getMessageGrid(self::MESSAGE_TYPE_OUTBOX, $keyword, $actions);
2360
2361
        return $html;
2362
    }
2363
2364
    /**
2365
     * @param string $keyword
2366
     *
2367
     * @return string
2368
     */
2369
    public static function outbox_display($keyword = '')
2370
    {
2371
        Session::write('message_sent_search_keyword', $keyword);
2372
        $success = get_lang('SelectedMessagesDeleted').'&nbsp</b><br />
2373
                    <a href="outbox.php">'.get_lang('BackToOutbox').'</a>';
2374
2375
        $html = '';
2376
        if (isset($_REQUEST['action'])) {
2377
            switch ($_REQUEST['action']) {
2378
                case 'delete':
2379
                    $count = count($_POST['id']);
2380
                    if ($count != 0) {
2381
                        foreach ($_POST['id'] as $index => $messageId) {
2382
                            self::delete_message_by_user_receiver(
2383
                                api_get_user_id(),
2384
                                $messageId
2385
                            );
2386
                        }
2387
                    }
2388
                    $html .= Display::return_message(api_xml_http_response_encode($success), 'normal', false);
2389
                    break;
2390
                case 'deleteone':
2391
                    self::delete_message_by_user_receiver(api_get_user_id(), $_GET['id']);
2392
                    $html .= Display::return_message(api_xml_http_response_encode($success), 'normal', false);
2393
                    $html .= '<br/>';
2394
                    break;
2395
            }
2396
        }
2397
2398
        // display sortable table with messages of the current user
2399
        $table = new SortableTable(
2400
            'message_outbox',
2401
            ['MessageManager', 'getNumberOfMessages'],
2402
            ['MessageManager', 'getMessageData'],
2403
            2,
2404
            20,
2405
            'DESC'
2406
        );
2407
        $table->setDataFunctionParams(
2408
            ['keyword' => $keyword, 'type' => self::MESSAGE_TYPE_OUTBOX]
2409
        );
2410
2411
        $table->set_header(0, '', false, ['style' => 'width:15px;']);
2412
        $table->set_header(1, get_lang('Messages'), false);
2413
        $table->set_header(2, get_lang('Date'), true, ['style' => 'width:180px;']);
2414
        $table->set_header(3, get_lang('Modify'), false, ['style' => 'width:70px;']);
2415
2416
        $table->set_form_actions(['delete' => get_lang('DeleteSelectedMessages')]);
2417
        $html .= $table->return_table();
2418
2419
        return $html;
2420
    }
2421
2422
    /**
2423
     * Get the data of the last received messages for a user.
2424
     *
2425
     * @param int $userId The user id
2426
     * @param int $lastId The id of the last received message
2427
     *
2428
     * @return array
2429
     */
2430
    public static function getMessagesFromLastReceivedMessage($userId, $lastId = 0)
2431
    {
2432
        $userId = (int) $userId;
2433
        $lastId = (int) $lastId;
2434
2435
        if (empty($userId)) {
2436
            return [];
2437
        }
2438
2439
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
2440
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
2441
2442
        $sql = "SELECT m.*, u.user_id, u.lastname, u.firstname
2443
                FROM $messagesTable as m
2444
                INNER JOIN $userTable as u
2445
                ON m.user_sender_id = u.user_id
2446
                WHERE
2447
                    m.user_receiver_id = $userId AND
2448
                    m.msg_status = ".MESSAGE_STATUS_UNREAD."
2449
                    AND m.id > $lastId
2450
                ORDER BY m.send_date DESC";
2451
2452
        $result = Database::query($sql);
2453
2454
        $messages = [];
2455
        if ($result !== false) {
2456
            while ($row = Database::fetch_assoc($result)) {
2457
                $messages[] = $row;
2458
            }
2459
        }
2460
2461
        return $messages;
2462
    }
2463
2464
    /**
2465
     * Check whether a message has attachments.
2466
     *
2467
     * @param int $messageId The message id
2468
     *
2469
     * @return bool Whether the message has attachments return true. Otherwise return false
2470
     */
2471
    public static function hasAttachments($messageId)
2472
    {
2473
        $messageId = (int) $messageId;
2474
2475
        if (empty($messageId)) {
2476
            return false;
2477
        }
2478
2479
        $messageAttachmentTable = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
2480
2481
        $conditions = [
2482
            'where' => [
2483
                'message_id = ?' => $messageId,
2484
            ],
2485
        ];
2486
2487
        $result = Database::select(
2488
            'COUNT(1) AS qty',
2489
            $messageAttachmentTable,
2490
            $conditions,
2491
            'first'
2492
        );
2493
2494
        if (!empty($result)) {
2495
            if ($result['qty'] > 0) {
2496
                return true;
2497
            }
2498
        }
2499
2500
        return false;
2501
    }
2502
2503
    /**
2504
     * @param int $messageId
2505
     *
2506
     * @return array|bool
2507
     */
2508
    public static function getAttachment($messageId)
2509
    {
2510
        $messageId = (int) $messageId;
2511
2512
        if (empty($messageId)) {
2513
            return false;
2514
        }
2515
2516
        $table = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
2517
2518
        $conditions = [
2519
            'where' => [
2520
                'id = ?' => $messageId,
2521
            ],
2522
        ];
2523
2524
        $result = Database::select(
2525
            '*',
2526
            $table,
2527
            $conditions,
2528
            'first'
2529
        );
2530
2531
        if (!empty($result)) {
2532
            return $result;
2533
        }
2534
2535
        return false;
2536
    }
2537
2538
    /**
2539
     * @param string $url
2540
     *
2541
     * @return FormValidator
2542
     */
2543
    public static function getSearchForm($url)
2544
    {
2545
        $form = new FormValidator(
2546
            'search',
2547
            'post',
2548
            $url,
2549
            null,
2550
            [],
2551
            FormValidator::LAYOUT_INLINE
2552
        );
2553
2554
        $form->addElement(
2555
            'text',
2556
            'keyword',
2557
            false,
2558
            [
2559
                'aria-label' => get_lang('Search'),
2560
            ]
2561
        );
2562
        $form->addButtonSearch(get_lang('Search'));
2563
2564
        return $form;
2565
    }
2566
2567
    /**
2568
     * Send a notification to all admins when a new user is registered.
2569
     *
2570
     * @param User $user
2571
     */
2572
    public static function sendNotificationByRegisteredUser(User $user)
2573
    {
2574
        $tplMailBody = new Template(
2575
            null,
2576
            false,
2577
            false,
2578
            false,
2579
            false,
2580
            false,
2581
            false
2582
        );
2583
        $tplMailBody->assign('user', $user);
2584
        $tplMailBody->assign('is_western_name_order', api_is_western_name_order());
2585
        $tplMailBody->assign(
2586
            'manageUrl',
2587
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$user->getId()
2588
        );
2589
2590
        $layoutContent = $tplMailBody->get_template('mail/new_user_mail_to_admin.tpl');
2591
2592
        $emailsubject = '['.get_lang('UserRegistered').'] '.$user->getUsername();
2593
        $emailbody = $tplMailBody->fetch($layoutContent);
2594
2595
        $admins = UserManager::get_all_administrators();
2596
2597
        foreach ($admins as $admin_info) {
2598
            self::send_message(
2599
                $admin_info['user_id'],
2600
                $emailsubject,
2601
                $emailbody,
2602
                [],
2603
                [],
2604
                null,
2605
                null,
2606
                null,
2607
                null,
2608
                $user->getId()
2609
            );
2610
        }
2611
    }
2612
2613
    /**
2614
     * Get the error log from failed mailing
2615
     * This assumes a complex setup where you have a cron script regularly copying the mail queue log
2616
     * into app/cache/mail/mailq.
2617
     * This can be done with a cron command like (check the location of your mail log file first):.
2618
     *
2619
     * @example 0,30 * * * * root cp /var/log/exim4/mainlog /var/www/chamilo/app/cache/mail/mailq
2620
     *
2621
     * @return array|bool
2622
     */
2623
    public static function failedSentMailErrors()
2624
    {
2625
        $base = api_get_path(SYS_ARCHIVE_PATH).'mail/';
2626
        $mailq = $base.'mailq';
2627
2628
        if (!file_exists($mailq) || !is_readable($mailq)) {
2629
            return false;
2630
        }
2631
2632
        $file = fopen($mailq, 'r');
2633
        $i = 1;
2634
        while (!feof($file)) {
2635
            $line = fgets($file);
2636
2637
            if (trim($line) == '') {
2638
                continue;
2639
            }
2640
2641
            // Get the mail code, something like 1WBumL-0002xg-FF
2642
            if (preg_match('/(.*)\s((.*)-(.*)-(.*))\s<(.*)$/', $line, $codeMatches)) {
2643
                $mail_queue[$i]['code'] = $codeMatches[2];
2644
            }
2645
2646
            $fullMail = $base.$mail_queue[$i]['code'];
2647
            $mailFile = fopen($fullMail, 'r');
2648
2649
            // Get the reason of mail fail
2650
            $iX = 1;
2651
            while (!feof($mailFile)) {
2652
                $mailLine = fgets($mailFile);
2653
                //if ($iX == 4 && preg_match('/(.*):\s(.*)$/', $mailLine, $matches)) {
2654
                if ($iX == 2 &&
2655
                    preg_match('/(.*)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s(.*)/', $mailLine, $detailsMatches)
2656
                ) {
2657
                    $mail_queue[$i]['reason'] = $detailsMatches[3];
2658
                }
2659
                $iX++;
2660
            }
2661
2662
            fclose($mailFile);
2663
2664
            // Get the time of mail fail
2665
            if (preg_match('/^\s?(\d+)(\D+)\s+(.*)$/', $line, $timeMatches)) {
2666
                $mail_queue[$i]['time'] = $timeMatches[1].$timeMatches[2];
2667
            } elseif (preg_match('/^(\s+)((.*)@(.*))\s+(.*)$/', $line, $emailMatches)) {
2668
                $mail_queue[$i]['mail'] = $emailMatches[2];
2669
                $i++;
2670
            }
2671
        }
2672
2673
        fclose($file);
2674
2675
        return array_reverse($mail_queue);
2676
    }
2677
2678
    /**
2679
     * @param int $userId
2680
     *
2681
     * @return array
2682
     */
2683
    public static function getUsersThatHadConversationWithUser($userId)
2684
    {
2685
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
2686
        $userId = (int) $userId;
2687
2688
        $sql = "SELECT DISTINCT
2689
                    user_sender_id
2690
                FROM $messagesTable
2691
                WHERE
2692
                    user_receiver_id = ".$userId;
2693
        $result = Database::query($sql);
2694
        $users = Database::store_result($result);
2695
        $userList = [];
2696
        foreach ($users as $userData) {
2697
            $userId = $userData['user_sender_id'];
2698
            if (empty($userId)) {
2699
                continue;
2700
            }
2701
            $userInfo = api_get_user_info($userId);
2702
            if ($userInfo) {
2703
                $userList[$userId] = $userInfo;
2704
            }
2705
        }
2706
2707
        return $userList;
2708
    }
2709
2710
    /**
2711
     * @param int $userId
2712
     * @param int $otherUserId
2713
     *
2714
     * @return array
2715
     */
2716
    public static function getAllMessagesBetweenStudents($userId, $otherUserId)
2717
    {
2718
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
2719
        $userId = (int) $userId;
2720
        $otherUserId = (int) $otherUserId;
2721
2722
        if (empty($otherUserId) || empty($userId)) {
2723
            return [];
2724
        }
2725
2726
        $sql = "SELECT DISTINCT * 
2727
                FROM $messagesTable
2728
                WHERE
2729
                    (user_receiver_id = $userId AND user_sender_id = $otherUserId) OR
2730
                    (user_receiver_id = $otherUserId AND user_sender_id = $userId)
2731
                ORDER BY send_date DESC
2732
            ";
2733
        $result = Database::query($sql);
2734
        $messages = Database::store_result($result);
2735
        $list = [];
2736
        foreach ($messages as $message) {
2737
            $list[] = $message;
2738
        }
2739
2740
        return $list;
2741
    }
2742
2743
    /**
2744
     * @param string $subject
2745
     * @param string $message
2746
     * @param array  $courseInfo
2747
     * @param int    $sessionId
2748
     *
2749
     * @return bool
2750
     */
2751
    public static function sendMessageToAllUsersInCourse($subject, $message, $courseInfo, $sessionId = 0)
2752
    {
2753
        if (empty($courseInfo)) {
2754
            return false;
2755
        }
2756
2757
        $senderId = api_get_user_id();
2758
        if (empty($senderId)) {
2759
            return false;
2760
        }
2761
        if (empty($sessionId)) {
2762
            // Course students and teachers
2763
            $users = CourseManager::get_user_list_from_course_code($courseInfo['code']);
2764
        } else {
2765
            // Course-session students and course session coaches
2766
            $users = CourseManager::get_user_list_from_course_code($courseInfo['code'], $sessionId);
2767
        }
2768
2769
        if (empty($users)) {
2770
            return false;
2771
        }
2772
2773
        foreach ($users as $userInfo) {
2774
            self::send_message_simple(
2775
                $userInfo['user_id'],
2776
                $subject,
2777
                $message,
2778
                $senderId,
2779
                false,
2780
                false,
2781
                [],
2782
                false
2783
            );
2784
        }
2785
    }
2786
2787
    /**
2788
     * Clean audio messages already added in the message tool.
2789
     */
2790
    public static function cleanAudioMessage()
2791
    {
2792
        $audioId = Session::read('current_audio_id');
2793
        if (!empty($audioId)) {
2794
            api_remove_uploaded_file_by_id('audio_message', api_get_user_id(), $audioId);
2795
            Session::erase('current_audio_id');
2796
        }
2797
    }
2798
2799
    /**
2800
     * @param int    $senderId
2801
     * @param string $subject
2802
     * @param string $message
2803
     */
2804
    public static function sendMessageToAllAdminUsers(
2805
        $senderId,
2806
        $subject,
2807
        $message
2808
    ) {
2809
        $admins = UserManager::get_all_administrators();
2810
        foreach ($admins as $admin) {
2811
            self::send_message_simple($admin['user_id'], $subject, $message, $senderId);
2812
        }
2813
    }
2814
2815
    /**
2816
     * @param int $messageId
2817
     * @param int $userId
2818
     *
2819
     * @return array
2820
     */
2821
    public static function countLikesAndDislikes($messageId, $userId)
2822
    {
2823
        if (!api_get_configuration_value('social_enable_messages_feedback')) {
2824
            return [];
2825
        }
2826
2827
        $messageId = (int) $messageId;
2828
        $userId = (int) $userId;
2829
2830
        $em = Database::getManager();
2831
        $query = $em
2832
            ->createQuery('
2833
                SELECT SUM(l.liked) AS likes, SUM(l.disliked) AS dislikes FROM ChamiloCoreBundle:MessageFeedback l
2834
                WHERE l.message = :message
2835
            ')
2836
            ->setParameters(['message' => $messageId]);
2837
2838
        try {
2839
            $counts = $query->getSingleResult();
2840
        } catch (Exception $e) {
2841
            $counts = ['likes' => 0, 'dislikes' => 0];
2842
        }
2843
2844
        $userLike = $em
2845
            ->getRepository('ChamiloCoreBundle:MessageFeedback')
2846
            ->findOneBy(['message' => $messageId, 'user' => $userId]);
2847
2848
        return [
2849
            'likes' => (int) $counts['likes'],
2850
            'dislikes' => (int) $counts['dislikes'],
2851
            'user_liked' => $userLike ? $userLike->isLiked() : false,
2852
            'user_disliked' => $userLike ? $userLike->isDisliked() : false,
2853
        ];
2854
    }
2855
2856
    /**
2857
     * @param int $messageId
2858
     * @param int $userId
2859
     * @param int $groupId   Optional.
2860
     *
2861
     * @return string
2862
     */
2863
    public static function getLikesButton($messageId, $userId, $groupId = 0)
2864
    {
2865
        if (!api_get_configuration_value('social_enable_messages_feedback')) {
2866
            return '';
2867
        }
2868
2869
        $countLikes = self::countLikesAndDislikes($messageId, $userId);
2870
2871
        $class = $countLikes['user_liked'] ? 'btn-primary' : 'btn-default';
2872
2873
        $btnLike = Display::button(
2874
            'like',
2875
            Display::returnFontAwesomeIcon('thumbs-up', '', true)
2876
                .PHP_EOL.'<span>'.$countLikes['likes'].'</span>',
2877
            [
2878
                'title' => get_lang('VoteLike'),
2879
                'class' => 'btn  social-like '.$class,
2880
                'data-status' => 'like',
2881
                'data-message' => $messageId,
2882
                'data-group' => $groupId,
2883
            ]
2884
        );
2885
2886
        $btnDislike = '';
2887
        if (api_get_configuration_value('disable_dislike_option') === false) {
2888
            $disabled = $countLikes['user_disliked'] ? 'btn-danger' : 'btn-default';
2889
2890
            $btnDislike = Display::button(
2891
                'like',
2892
                Display::returnFontAwesomeIcon('thumbs-down', '', true)
2893
                .PHP_EOL.'<span>'.$countLikes['dislikes'].'</span>',
2894
                [
2895
                    'title' => get_lang('VoteDislike'),
2896
                    'class' => 'btn social-like '.$disabled,
2897
                    'data-status' => 'dislike',
2898
                    'data-message' => $messageId,
2899
                    'data-group' => $groupId,
2900
                ]
2901
            );
2902
        }
2903
2904
        return $btnLike.PHP_EOL.$btnDislike;
2905
    }
2906
2907
    /**
2908
     * Execute the SQL necessary to know the number of messages in the database.
2909
     *
2910
     * @param int $userId The user for which we need the unread messages count
2911
     *
2912
     * @return int The number of unread messages in the database for the given user
2913
     */
2914
    public static function getCountNewMessagesFromDB($userId)
2915
    {
2916
        $userId = (int) $userId;
2917
2918
        if (empty($userId)) {
2919
            return 0;
2920
        }
2921
2922
        $table = Database::get_main_table(TABLE_MESSAGE);
2923
        $sql = "SELECT COUNT(id) as count 
2924
                FROM $table
2925
                WHERE
2926
                    user_receiver_id = $userId AND
2927
                    msg_status = ".MESSAGE_STATUS_UNREAD;
2928
        $result = Database::query($sql);
2929
        $row = Database::fetch_assoc($result);
2930
2931
        return (int) $row['count'];
2932
    }
2933
}
2934