Passed
Push — master ( dc373e...baaca7 )
by Julito
11:31
created

MessageManager::send_message()   F

Complexity

Conditions 29
Paths 605

Size

Total Lines 215
Code Lines 136

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 29
eloc 136
nc 605
nop 13
dl 0
loc 215
rs 2.1641
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 ChamiloSession as Session;
5
use Chamilo\UserBundle\Entity\User;
6
7
/**
8
 * Class MessageManager
9
 *
10
 * This class provides methods for messages management.
11
 * Include/require it in your code to use its features.
12
 *
13
 * @package chamilo.library
14
 */
15
class MessageManager
16
{
17
    /**
18
     * Get count new messages for the current user from the database.
19
     * @return int
20
     */
21
    public static function getCountNewMessages()
22
    {
23
        $userId = api_get_user_id();
24
        if (empty($userId)) {
25
            return false;
26
        }
27
28
        static $count;
29
        if (!isset($count)) {
30
            $cacheAvailable = api_get_configuration_value('apc');
31
            if ($cacheAvailable === true) {
32
                $var = api_get_configuration_value('apc_prefix').'social_messages_unread_u_'.$userId;
33
                if (apcu_exists($var)) {
34
                    $count = apcu_fetch($var);
35
                } else {
36
                    $count = self::getCountNewMessagesFromDB($userId);
37
                    apcu_store($var, $count, 60);
38
                }
39
            } else {
40
                $count = self::getCountNewMessagesFromDB($userId);
41
            }
42
        }
43
44
        return $count;
45
    }
46
    /**
47
     * Execute the SQL necessary to know the number of messages in the database
48
     * @param   int $userId The user for which we need the unread messages count
49
     * @return  int The number of unread messages in the database for the given user
50
     */
51
    private static function getCountNewMessagesFromDB($userId)
52
    {
53
        if (empty($userId)) {
54
            return 0;
55
        }
56
        $table = Database::get_main_table(TABLE_MESSAGE);
57
        $sql = "SELECT COUNT(id) as count 
58
                FROM $table
59
                WHERE
60
                    user_receiver_id=".api_get_user_id()." AND
61
                    msg_status = ".MESSAGE_STATUS_UNREAD;
62
        $result = Database::query($sql);
63
        $row = Database::fetch_assoc($result);
64
65
        return $row['count'];
66
    }
67
68
    /**
69
     * Gets the total number of messages, used for the inbox sortable table
70
     * @param bool $unread
71
     * @return int
72
     */
73
    public static function getNumberOfMessages($unread = false)
74
    {
75
        $table = Database::get_main_table(TABLE_MESSAGE);
76
        if ($unread) {
77
            $condition_msg_status = ' msg_status = '.MESSAGE_STATUS_UNREAD.' ';
78
        } else {
79
            $condition_msg_status = ' msg_status IN('.MESSAGE_STATUS_NEW.','.MESSAGE_STATUS_UNREAD.') ';
80
        }
81
82
        $keyword = Session::read('message_search_keyword');
83
        $keywordCondition = '';
84
        if (!empty($keyword)) {
85
            $keyword = Database::escape_string($keyword);
86
            $keywordCondition = " AND (title like '%$keyword%' OR content LIKE '%$keyword%') ";
87
        }
88
89
        $sql = "SELECT COUNT(id) as number_messages
90
                FROM $table
91
                WHERE $condition_msg_status AND
92
                    user_receiver_id=".api_get_user_id()."
93
                    $keywordCondition
94
                ";
95
        $result = Database::query($sql);
96
        $result = Database::fetch_array($result);
97
98
        return $result['number_messages'];
99
    }
100
101
    /**
102
     * Gets information about some messages, used for the inbox sortable table
103
     * @param int $from
104
     * @param int $number_of_items
105
     * @param string $column
106
     * @param string $direction
107
     * @return array
108
     */
109
    public static function get_message_data(
110
        $from,
111
        $number_of_items,
112
        $column,
113
        $direction
114
    ) {
115
        $from = (int) $from;
116
        $number_of_items = (int) $number_of_items;
117
118
        //forcing this order
119
        if (!isset($direction)) {
120
            $column = 2;
121
            $direction = 'DESC';
122
        } else {
123
            $column = intval($column);
124
            if (!in_array($direction, ['ASC', 'DESC'])) {
125
                $direction = 'ASC';
126
            }
127
        }
128
129
        if (!in_array($column, [0, 1, 2])) {
130
            $column = 2;
131
        }
132
133
        $keyword = Session::read('message_search_keyword');
134
        $keywordCondition = '';
135
        if (!empty($keyword)) {
136
            $keyword = Database::escape_string($keyword);
137
            $keywordCondition = " AND (title like '%$keyword%' OR content LIKE '%$keyword%') ";
138
        }
139
140
        $table = Database::get_main_table(TABLE_MESSAGE);
141
        $sql = "SELECT 
142
                    id as col0, 
143
                    title as col1, 
144
                    send_date as col2, 
145
                    msg_status as col3,
146
                    user_sender_id
147
                FROM $table
148
                WHERE
149
                    user_receiver_id=".api_get_user_id()." AND
150
                    msg_status IN (".MESSAGE_STATUS_NEW.", ".MESSAGE_STATUS_UNREAD.")
151
                    $keywordCondition
152
                ORDER BY col$column $direction
153
                LIMIT $from, $number_of_items";
154
155
        $result = Database::query($sql);
156
        $message_list = [];
157
        $newMessageLink = api_get_path(WEB_CODE_PATH).'messages/new_message.php';
158
        while ($row = Database::fetch_array($result, 'ASSOC')) {
159
            $messageId = $row['col0'];
160
            $title = $row['col1'];
161
            $sendDate = $row['col2'];
162
            $status = $row['col3'];
163
            $senderId = $row['user_sender_id'];
164
165
            $title = Security::remove_XSS($title, STUDENT, true);
166
            $title = cut($title, 80, true);
167
168
            if ($status == 1) {
169
                $class = 'class = "unread"';
170
            } else {
171
                $class = 'class = "read"';
172
            }
173
174
            $userInfo = api_get_user_info($senderId);
175
            if (!empty($senderId) && !empty($userInfo)) {
176
                $message[1] = '<a '.$class.' href="view_message.php?id='.$messageId.'">'.$title.'</a><br />';
177
                $message[1] .= $userInfo['complete_name_with_username'];
178
                $message[3] =
179
                    Display::url(
180
                        Display::returnFontAwesomeIcon('reply', 2),
181
                        $newMessageLink.'?re_id='.$messageId,
182
                        ['title' => get_lang('ReplyToMessage') ]
183
                    );
184
            } else {
185
                $message[1] = '<a '.$class.' href="view_message.php?id='.$messageId.'">'.$title.'</a><br />';
186
                $message[1] .= get_lang('UnknownUser');
187
                $message[3] =
188
                    Display::url(
189
                        Display::returnFontAwesomeIcon('reply', 2),
190
                        '#',
191
                        ['title' => get_lang('ReplyToMessage')]
192
                    );
193
            }
194
195
            $message[0] = $messageId;
196
            $message[2] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG);
197
            $message[3] .=
198
                '&nbsp;&nbsp;'.
199
                Display::url(
200
                    Display::returnFontAwesomeIcon('share', 2),
201
                    $newMessageLink.'?forward_id='.$messageId,
202
                    ['title' => get_lang('ForwardMessage') ]
203
                ).
204
                '&nbsp;&nbsp;<a title="'.addslashes(get_lang('DeleteMessage')).'" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmDeleteMessage')))."'".')) return false;" href="inbox.php?action=deleteone&id='.$messageId.'">'.
205
                Display::returnFontAwesomeIcon('trash', 2).'</a>';
206
            foreach ($message as $key => $value) {
207
                $message[$key] = api_xml_http_response_encode($value);
208
            }
209
            $message_list[] = $message;
210
        }
211
212
        return $message_list;
213
    }
214
215
    /**
216
     * @param array $aboutUserInfo
217
     * @param array $fromUserInfo
218
     * @param string $subject
219
     * @param string $content
220
     * @return bool
221
     */
222
    public static function sendMessageAboutUser(
223
        $aboutUserInfo,
224
        $fromUserInfo,
225
        $subject,
226
        $content
227
    ) {
228
        if (empty($aboutUserInfo) || empty($fromUserInfo)) {
229
            return false;
230
        }
231
232
        if (empty($fromUserInfo['id']) || empty($aboutUserInfo['id'])) {
233
            return false;
234
        }
235
236
        $table = Database::get_main_table(TABLE_MESSAGE);
237
        $now = api_get_utc_datetime();
238
        $params = [
239
            'user_sender_id' => $fromUserInfo['id'],
240
            'user_receiver_id' => $aboutUserInfo['id'],
241
            'msg_status' => MESSAGE_STATUS_CONVERSATION,
242
            'send_date' => $now,
243
            'title' => $subject,
244
            'content' => $content,
245
            'group_id' => 0,
246
            'parent_id' => 0,
247
            'update_date' => $now
248
        ];
249
        $id = Database::insert($table, $params);
250
        if ($id) {
251
            return true;
252
        }
253
254
        return false;
255
    }
256
257
    /**
258
     * @param array $aboutUserInfo
259
     * @return array
260
     */
261
    public static function getMessagesAboutUser($aboutUserInfo)
262
    {
263
        if (!empty($aboutUserInfo)) {
264
            $criteria = [
265
              'userReceiverId' => $aboutUserInfo['id'],
266
              'msgStatus' => MESSAGE_STATUS_CONVERSATION
267
            ];
268
            $repo = Database::getManager()->getRepository('ChamiloCoreBundle:Message');
269
            $messages = $repo->findBy($criteria, ['sendDate' => 'DESC']);
270
271
            return $messages;
272
        }
273
274
        return [];
275
    }
276
277
    /**
278
     * Sends a message to a user/group
279
     *
280
     * @param int $receiver_user_id
281
     * @param string $subject
282
     * @param string $content
283
     * @param array $file_attachments files array($_FILES) (optional)
284
     * @param array $file_comments about attachment files (optional)
285
     * @param int $group_id (optional)
286
     * @param int $parent_id (optional)
287
     * @param int $editMessageId id for updating the message (optional)
288
     * @param int $topic_id (optional) the default value is the current user_id
289
     * @param int $sender_id
290
     * @param bool $directMessage
291
     * @param int $forwardId
292
     * @param array $smsParameters
293
     *
294
     * @return bool
295
     */
296
    public static function send_message(
297
        $receiver_user_id,
298
        $subject,
299
        $content,
300
        array $file_attachments = [],
301
        array $file_comments = [],
302
        $group_id = 0,
303
        $parent_id = 0,
304
        $editMessageId = 0,
305
        $topic_id = 0,
306
        $sender_id = 0,
307
        $directMessage = false,
308
        $forwardId = 0,
309
        $smsParameters = []
310
    ) {
311
        $table = Database::get_main_table(TABLE_MESSAGE);
312
        $group_id = (int) $group_id;
313
        $receiver_user_id = (int) $receiver_user_id;
314
        $parent_id = (int) $parent_id;
315
        $editMessageId = (int) $editMessageId;
316
        $topic_id = (int) $topic_id;
317
318
        if (!empty($receiver_user_id)) {
319
            $receiverUserInfo = api_get_user_info($receiver_user_id);
320
321
            // Disabling messages for inactive users.
322
            if ($receiverUserInfo['active'] == 0) {
323
                return false;
324
            }
325
        }
326
327
        $user_sender_id = empty($sender_id) ? api_get_user_id() : (int) $sender_id;
328
        if (empty($user_sender_id)) {
329
            Display::addFlash(Display::return_message(get_lang('UserDoesNotExist'), 'warning'));
330
            return false;
331
        }
332
333
        $totalFileSize = 0;
334
        if (is_array($file_attachments)) {
335
            foreach ($file_attachments as $file_attach) {
336
                $fileSize = isset($file_attach['size']) ? $file_attach['size'] : 0;
337
                if (is_array($fileSize)) {
338
                    foreach ($fileSize as $size) {
339
                        $totalFileSize += $size;
340
                    }
341
                } else {
342
                    $totalFileSize += $fileSize;
343
                }
344
            }
345
        }
346
347
        // Validating fields
348
        if (empty($subject) && empty($group_id)) {
349
            Display::addFlash(
350
                Display::return_message(
351
                    get_lang('YouShouldWriteASubject'),
352
                    'warning'
353
                )
354
            );
355
            return false;
356
        } elseif ($totalFileSize > intval(api_get_setting('message_max_upload_filesize'))) {
357
            $warning = sprintf(
358
                get_lang("FilesSizeExceedsX"),
359
                format_file_size(api_get_setting('message_max_upload_filesize'))
360
            );
361
362
            Display::addFlash(Display::return_message($warning, 'warning'));
363
364
            return false;
365
        }
366
367
        // Just in case we replace the and \n and \n\r while saving in the DB
368
        // $content = str_replace(array("\n", "\n\r"), '<br />', $content);
369
        $now = api_get_utc_datetime();
370
        if (!empty($receiver_user_id) || !empty($group_id)) {
371
            // message for user friend
372
            //@todo it's possible to edit a message? yes, only for groups
373
            if (!empty($editMessageId)) {
374
                $query = " UPDATE $table SET
375
                                update_date = '".$now."',
376
                                content = '".Database::escape_string($content)."'
377
                           WHERE id = '$editMessageId' ";
378
                Database::query($query);
379
                $messageId = $editMessageId;
380
            } else {
381
                $params = [
382
                    'user_sender_id' => $user_sender_id,
383
                    'user_receiver_id' => $receiver_user_id,
384
                    'msg_status' => MESSAGE_STATUS_UNREAD,
385
                    'send_date' => $now,
386
                    'title' => $subject,
387
                    'content' => $content,
388
                    'group_id' => $group_id,
389
                    'parent_id' => $parent_id,
390
                    'update_date' => $now
391
                ];
392
                $messageId = Database::insert($table, $params);
393
            }
394
395
            // Save attachment file for inbox messages
396
            if (is_array($file_attachments)) {
397
                $i = 0;
398
                foreach ($file_attachments as $file_attach) {
399
                    if ($file_attach['error'] == 0) {
400
                        self::saveMessageAttachmentFile(
401
                            $file_attach,
402
                            isset($file_comments[$i]) ? $file_comments[$i] : null,
403
                            $messageId,
404
                            null,
405
                            $receiver_user_id,
406
                            $group_id
407
                        );
408
                    }
409
                    $i++;
410
                }
411
            }
412
413
            if (empty($group_id)) {
414
                // message in outbox for user friend or group
415
                $params = [
416
                    'user_sender_id' => $user_sender_id,
417
                    'user_receiver_id' => $receiver_user_id,
418
                    'msg_status' => MESSAGE_STATUS_OUTBOX,
419
                    'send_date' => $now,
420
                    'title' => $subject,
421
                    'content' => $content,
422
                    'group_id' => $group_id,
423
                    'parent_id' => $parent_id,
424
                    'update_date' => $now
425
                ];
426
                $outbox_last_id = Database::insert($table, $params);
427
428
                // save attachment file for outbox messages
429
                if (is_array($file_attachments)) {
430
                    $o = 0;
431
                    foreach ($file_attachments as $file_attach) {
432
                        if ($file_attach['error'] == 0) {
433
                            $comment = isset($file_comments[$o]) ? $file_comments[$o] : '';
434
                            self::saveMessageAttachmentFile(
435
                                $file_attach,
436
                                $comment,
437
                                $outbox_last_id,
438
                                $user_sender_id
439
                            );
440
                        }
441
                        $o++;
442
                    }
443
                }
444
            }
445
446
            // Load user settings.
447
            $notification = new Notification();
448
            $sender_info = api_get_user_info($user_sender_id);
449
450
            // add file attachment additional attributes
451
            foreach ($file_attachments as $index => $file_attach) {
452
                $file_attachments[$index]['path'] = $file_attach['tmp_name'];
453
                $file_attachments[$index]['filename'] = $file_attach['name'];
454
            }
455
456
            if (empty($group_id)) {
457
                $type = Notification::NOTIFICATION_TYPE_MESSAGE;
458
                if ($directMessage) {
459
                    $type = Notification::NOTIFICATION_TYPE_DIRECT_MESSAGE;
460
                }
461
                $notification->saveNotification(
462
                    $messageId,
463
                    $type,
464
                    [$receiver_user_id],
465
                    $subject,
466
                    $content,
467
                    $sender_info,
468
                    $file_attachments,
469
                    $smsParameters
470
                );
471
            } else {
472
                $usergroup = new UserGroup();
473
                $group_info = $usergroup->get($group_id);
474
                $group_info['topic_id'] = $topic_id;
475
                $group_info['msg_id'] = $messageId;
476
477
                $user_list = $usergroup->get_users_by_group(
478
                    $group_id,
479
                    false,
480
                    [],
481
                    0,
482
                    1000
483
                );
484
485
                // Adding more sense to the message group
486
                $subject = sprintf(get_lang('ThereIsANewMessageInTheGroupX'), $group_info['name']);
487
                $new_user_list = [];
488
                foreach ($user_list as $user_data) {
489
                    $new_user_list[] = $user_data['id'];
490
                }
491
                $group_info = [
492
                    'group_info' => $group_info,
493
                    'user_info' => $sender_info,
494
                ];
495
                $notification->saveNotification(
496
                    $messageId,
497
                    Notification::NOTIFICATION_TYPE_GROUP,
498
                    $new_user_list,
499
                    $subject,
500
                    $content,
501
                    $group_info,
502
                    $file_attachments,
503
                    $smsParameters
504
                );
505
            }
506
507
            return $messageId;
508
        }
509
510
        return false;
511
    }
512
513
    /**
514
     * @param int $receiver_user_id
515
     * @param int $subject
516
     * @param string $message
517
     * @param int $sender_id
518
     * @param bool $sendCopyToDrhUsers send copy to related DRH users
519
     * @param bool $directMessage
520
     * @param array $smsParameters
521
     * @param bool $uploadFiles Do not upload files using the MessageManager class
522
     * @param bool $attachmentList
523
     *
524
     * @return bool
525
     */
526
    public static function send_message_simple(
527
        $receiver_user_id,
528
        $subject,
529
        $message,
530
        $sender_id = 0,
531
        $sendCopyToDrhUsers = false,
532
        $directMessage = false,
533
        $smsParameters = [],
534
        $uploadFiles = true,
535
        $attachmentList = []
536
    ) {
537
        $files = $_FILES ? $_FILES : [];
538
        if ($uploadFiles === false) {
539
            $files = [];
540
        }
541
        // $attachmentList must have: tmp_name, name, size keys
542
        if (!empty($attachmentList)) {
543
            $files = $attachmentList;
544
        }
545
        $result = self::send_message(
546
            $receiver_user_id,
547
            $subject,
548
            $message,
549
            $files,
550
            [],
551
            null,
552
            null,
553
            null,
554
            null,
555
            $sender_id,
556
            $directMessage,
557
            0,
558
            $smsParameters
559
        );
560
561
        if ($sendCopyToDrhUsers) {
562
            $userInfo = api_get_user_info($receiver_user_id);
563
            $drhList = UserManager::getDrhListFromUser($receiver_user_id);
564
            if (!empty($drhList)) {
565
                foreach ($drhList as $drhInfo) {
566
                    $message = sprintf(
567
                        get_lang('CopyOfMessageSentToXUser'),
568
                        $userInfo['complete_name']
569
                    ).' <br />'.$message;
570
571
                    self::send_message_simple(
572
                        $drhInfo['user_id'],
573
                        $subject,
574
                        $message,
575
                        $sender_id,
576
                        false,
577
                        $directMessage
578
                    );
579
                }
580
            }
581
        }
582
583
        return $result;
584
    }
585
586
    /**
587
     * Update parent ids for other receiver user from current message in groups
588
     * @author Christian Fasanando Flores
589
     * @param  int $parent_id
590
     * @param  int $receiver_user_id
591
     * @param  int $messageId
592
     * @return void
593
     */
594
    public static function update_parent_ids_from_reply(
595
        $parent_id,
596
        $receiver_user_id,
597
        $messageId
598
    ) {
599
        $table = Database::get_main_table(TABLE_MESSAGE);
600
        $parent_id = intval($parent_id);
601
        $receiver_user_id = intval($receiver_user_id);
602
        $messageId = intval($messageId);
603
604
        // first get data from message id (parent)
605
        $sql = "SELECT * FROM $table WHERE id = '$parent_id'";
606
        $rs_message = Database::query($sql);
607
        $row_message = Database::fetch_array($rs_message);
608
609
        // get message id from data found early for other receiver user
610
        $sql = "SELECT id FROM $table
611
                WHERE
612
                    user_sender_id ='{$row_message['user_sender_id']}' AND
613
                    title='{$row_message['title']}' AND
614
                    content='{$row_message['content']}' AND
615
                    group_id='{$row_message['group_id']}' AND
616
                    user_receiver_id='$receiver_user_id'";
617
        $result = Database::query($sql);
618
        $row = Database::fetch_array($result);
619
620
        // update parent_id for other user receiver
621
        $sql = "UPDATE $table SET parent_id = ".$row['id']."
622
                WHERE id = $messageId";
623
        Database::query($sql);
624
    }
625
626
    /**
627
     * @param int $user_receiver_id
628
     * @param int $id
629
     * @return bool
630
     */
631
    public static function delete_message_by_user_receiver($user_receiver_id, $id)
632
    {
633
        $table = Database::get_main_table(TABLE_MESSAGE);
634
        if ($id != strval(intval($id))) {
635
            return false;
636
        }
637
        $user_receiver_id = intval($user_receiver_id);
638
        $id = intval($id);
639
        $sql = "SELECT * FROM $table
640
                WHERE id = ".$id." AND msg_status <>".MESSAGE_STATUS_OUTBOX;
641
        $rs = Database::query($sql);
642
643
        if (Database::num_rows($rs) > 0) {
644
            // delete attachment file
645
            self::delete_message_attachment_file($id, $user_receiver_id);
646
            // delete message
647
            $query = "UPDATE $table 
648
                      SET msg_status = ".MESSAGE_STATUS_DELETED."
649
                      WHERE 
650
                        user_receiver_id=".$user_receiver_id." AND 
651
                        id = " . $id;
652
            Database::query($query);
653
654
            return true;
655
        } else {
656
            return false;
657
        }
658
    }
659
660
    /**
661
     * Set status deleted
662
     * @author Isaac FLores Paz <[email protected]>
663
     * @param  int
664
     * @param  int
665
     * @return bool
666
     */
667
    public static function delete_message_by_user_sender($user_sender_id, $id)
668
    {
669
        if ($id != strval(intval($id))) {
670
            return false;
671
        }
672
673
        $table = Database::get_main_table(TABLE_MESSAGE);
674
675
        $id = intval($id);
676
        $user_sender_id = intval($user_sender_id);
677
678
        $sql = "SELECT * FROM $table WHERE id='$id'";
679
        $rs = Database::query($sql);
680
681
        if (Database::num_rows($rs) > 0) {
682
            // delete attachment file
683
            self::delete_message_attachment_file($id, $user_sender_id);
684
            // delete message
685
            $sql = "UPDATE $table 
686
                    SET msg_status = ".MESSAGE_STATUS_DELETED."
687
                    WHERE user_sender_id='$user_sender_id' AND id='$id'";
688
            Database::query($sql);
689
690
            return true;
691
        }
692
693
        return false;
694
    }
695
696
    /**
697
     * Saves a message attachment files
698
     * @param  array $file_attach $_FILES['name']
699
     * @param  string    a comment about the uploaded file
700
     * @param  int        message id
701
     * @param  int        receiver user id (optional)
702
     * @param  int        sender user id (optional)
703
     * @param  int        group id (optional)
704
     */
705
    public static function saveMessageAttachmentFile(
706
        $file_attach,
707
        $file_comment,
708
        $message_id,
709
        $receiver_user_id = 0,
710
        $sender_user_id = 0,
711
        $group_id = 0
712
    ) {
713
        $tbl_message_attach = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
714
715
        // Try to add an extension to the file if it hasn't one
716
        $type = isset($file_attach['type']) ? $file_attach['type'] : '';
717
        if (empty($type)) {
718
            $type = DocumentManager::file_get_mime_type($file_attach['name']);
719
        }
720
        $new_file_name = add_ext_on_mime(stripslashes($file_attach['name']), $type);
721
722
        // user's file name
723
        $file_name = $file_attach['name'];
724
        if (!filter_extension($new_file_name)) {
725
            Display::addFlash(Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'error'));
726
        } else {
727
            $new_file_name = uniqid('');
728
            if (!empty($receiver_user_id)) {
729
                $message_user_id = $receiver_user_id;
730
            } else {
731
                $message_user_id = $sender_user_id;
732
            }
733
734
            // User-reserved directory where photos have to be placed.*
735
            $userGroup = new UserGroup();
736
            if (!empty($group_id)) {
737
                $path_user_info = $userGroup->get_group_picture_path_by_id(
738
                    $group_id,
739
                    'system',
740
                    true
741
                );
742
            } else {
743
                $path_user_info['dir'] = UserManager::getUserPathById($message_user_id, 'system');
744
            }
745
746
            $path_message_attach = $path_user_info['dir'].'message_attachments/';
747
            // If this directory does not exist - we create it.
748
            if (!file_exists($path_message_attach)) {
749
                @mkdir($path_message_attach, api_get_permissions_for_new_directories(), true);
750
            }
751
752
            $new_path = $path_message_attach.$new_file_name;
753
754
            if (is_uploaded_file($file_attach['tmp_name'])) {
755
                @copy($file_attach['tmp_name'], $new_path);
756
            } else {
757
                // 'tmp_name' can be set by the ticket
758
                if (file_exists($file_attach['tmp_name'])) {
759
                    @copy($file_attach['tmp_name'], $new_path);
760
                }
761
            }
762
763
            // Storing the attachments if any
764
            $params = [
765
                'filename' => $file_name,
766
                'comment' => $file_comment,
767
                'path' => $new_file_name,
768
                'message_id' => $message_id,
769
                'size' => $file_attach['size']
770
            ];
771
            Database::insert($tbl_message_attach, $params);
772
        }
773
    }
774
775
    /**
776
     * Delete message attachment files (logically updating the row with a suffix _DELETE_id)
777
     * @param  int    message id
778
     * @param  int    message user id (receiver user id or sender user id)
779
     * @param  int    group id (optional)
780
     */
781
    public static function delete_message_attachment_file(
782
        $message_id,
783
        $message_uid,
784
        $group_id = 0
785
    ) {
786
        $message_id = intval($message_id);
787
        $message_uid = intval($message_uid);
788
        $table_message_attach = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
789
790
        $sql = "SELECT * FROM $table_message_attach 
791
                WHERE message_id = '$message_id'";
792
        $rs = Database::query($sql);
793
        while ($row = Database::fetch_array($rs)) {
794
            $path = $row['path'];
795
            $attach_id = $row['id'];
796
            $new_path = $path.'_DELETED_'.$attach_id;
797
798
            if (!empty($group_id)) {
799
                $userGroup = new UserGroup();
800
                $path_user_info = $userGroup->get_group_picture_path_by_id(
801
                    $group_id,
802
                    'system',
803
                    true
804
                );
805
            } else {
806
                $path_user_info['dir'] = UserManager::getUserPathById(
807
                    $message_uid,
808
                    'system'
809
                );
810
            }
811
812
            $path_message_attach = $path_user_info['dir'].'message_attachments/';
813
            if (is_file($path_message_attach.$path)) {
814
                if (rename($path_message_attach.$path, $path_message_attach.$new_path)) {
815
                    $sql = "UPDATE $table_message_attach set path='$new_path'
816
                            WHERE id ='$attach_id'";
817
                    Database::query($sql);
818
                }
819
            }
820
        }
821
    }
822
823
    /**
824
     * update messages by user id and message id
825
     * @param  int $user_id
826
     * @param  int $message_id
827
     * @return bool
828
     */
829
    public static function update_message($user_id, $message_id)
830
    {
831
        if ($message_id != strval(intval($message_id)) || $user_id != strval(intval($user_id))) {
832
            return false;
833
        }
834
835
        $table = Database::get_main_table(TABLE_MESSAGE);
836
        $sql = "UPDATE $table SET 
837
                    msg_status = '".MESSAGE_STATUS_NEW."'
838
                WHERE
839
                    msg_status <> ".MESSAGE_STATUS_OUTBOX." AND
840
                    user_receiver_id = ".intval($user_id)." AND
841
                    id = '".intval($message_id)."'";
842
        Database::query($sql);
843
        return true;
844
    }
845
846
    /**
847
     * @param int $user_id
848
     * @param int $message_id
849
     * @param string $type
850
     * @return bool
851
     */
852
    public static function update_message_status($user_id, $message_id, $type)
853
    {
854
        $type = intval($type);
855
        if ($message_id != strval(intval($message_id)) || $user_id != strval(intval($user_id))) {
856
            return false;
857
        }
858
        $table_message = Database::get_main_table(TABLE_MESSAGE);
859
        $sql = "UPDATE $table_message SET
860
                    msg_status = '$type'
861
                WHERE
862
                    user_receiver_id = ".intval($user_id)." AND
863
                    id = '".intval($message_id)."'";
864
        Database::query($sql);
865
    }
866
867
    /**
868
     * get messages by user id and message id
869
     * @param  int $user_id
870
     * @param  int $message_id
871
     * @return array
872
     */
873
    public static function get_message_by_user($user_id, $message_id)
874
    {
875
        if ($message_id != strval(intval($message_id)) || $user_id != strval(intval($user_id))) {
876
            return false;
877
        }
878
        $table = Database::get_main_table(TABLE_MESSAGE);
879
        $query = "SELECT * FROM $table
880
                  WHERE user_receiver_id=".intval($user_id)." AND id='".intval($message_id)."'";
881
        $result = Database::query($query);
882
883
        return $row = Database::fetch_array($result);
884
    }
885
886
    /**
887
     * get messages by group id
888
     * @param  int $group_id group id
889
     * @return array
890
     */
891
    public static function get_messages_by_group($group_id)
892
    {
893
        if ($group_id != strval(intval($group_id))) {
894
            return false;
895
        }
896
897
        $table = Database::get_main_table(TABLE_MESSAGE);
898
        $group_id = intval($group_id);
899
        $sql = "SELECT * FROM $table
900
                WHERE
901
                    group_id= $group_id AND
902
                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
903
                ORDER BY id";
904
        $rs = Database::query($sql);
905
        $data = [];
906
        if (Database::num_rows($rs) > 0) {
907
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
908
                $data[] = $row;
909
            }
910
        }
911
        return $data;
912
    }
913
914
    /**
915
     * get messages by group id
916
     * @param  int $group_id
917
     * @param int $message_id
918
     * @return array
919
     */
920
    public static function get_messages_by_group_by_message($group_id, $message_id)
921
    {
922
        if ($group_id != strval(intval($group_id))) {
923
            return false;
924
        }
925
        $table = Database::get_main_table(TABLE_MESSAGE);
926
        $group_id = intval($group_id);
927
        $sql = "SELECT * FROM $table
928
                WHERE
929
                    group_id = $group_id AND
930
                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
931
                ORDER BY id ";
932
933
        $rs = Database::query($sql);
934
        $data = [];
935
        $parents = [];
936
        if (Database::num_rows($rs) > 0) {
937
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
938
                if ($message_id == $row['parent_id'] || in_array($row['parent_id'], $parents)) {
939
                    $parents[] = $row['id'];
940
                    $data[] = $row;
941
                }
942
            }
943
        }
944
945
        return $data;
946
    }
947
948
    /**
949
     * Get messages by parent id optionally with limit
950
     * @param  int        parent id
951
     * @param  int        group id (optional)
952
     * @param  int        offset (optional)
953
     * @param  int        limit (optional)
954
     * @return array
955
     */
956
    public static function get_messages_by_parent($parent_id, $group_id = 0, $offset = 0, $limit = 0)
957
    {
958
        if ($parent_id != strval(intval($parent_id))) {
959
            return false;
960
        }
961
        $table = Database::get_main_table(TABLE_MESSAGE);
962
        $parent_id = intval($parent_id);
963
        $condition_group_id = '';
964
        if (!empty($group_id)) {
965
            $group_id = intval($group_id);
966
            $condition_group_id = " AND group_id = '$group_id' ";
967
        }
968
969
        $condition_limit = '';
970
        if ($offset && $limit) {
971
            $offset = ($offset - 1) * $limit;
972
            $condition_limit = " LIMIT $offset,$limit ";
973
        }
974
975
        $sql = "SELECT * FROM $table
976
                WHERE
977
                    parent_id='$parent_id' AND
978
                    msg_status <> ".MESSAGE_STATUS_OUTBOX."
979
                    $condition_group_id
980
                ORDER BY send_date DESC $condition_limit ";
981
        $rs = Database::query($sql);
982
        $data = [];
983
        if (Database::num_rows($rs) > 0) {
984
            while ($row = Database::fetch_array($rs)) {
985
                $data[$row['id']] = $row;
986
            }
987
        }
988
989
        return $data;
990
    }
991
992
    /**
993
     * Gets information about messages sent
994
     * @param  integer
995
     * @param  integer
996
     * @param  string
997
     * @return array
998
     */
999
    public static function get_message_data_sent(
1000
        $from,
1001
        $number_of_items,
1002
        $column,
1003
        $direction
1004
    ) {
1005
        $from = intval($from);
1006
        $number_of_items = intval($number_of_items);
1007
        if (!isset($direction)) {
1008
            $column = 2;
1009
            $direction = 'DESC';
1010
        } else {
1011
            $column = intval($column);
1012
            if (!in_array($direction, ['ASC', 'DESC'])) {
1013
                $direction = 'ASC';
1014
            }
1015
        }
1016
1017
        if (!in_array($column, [0, 1, 2])) {
1018
            $column = 2;
1019
        }
1020
        $table = Database::get_main_table(TABLE_MESSAGE);
1021
        $request = api_is_xml_http_request();
1022
        $keyword = Session::read('message_sent_search_keyword');
1023
        $keywordCondition = '';
1024
        if (!empty($keyword)) {
1025
            $keyword = Database::escape_string($keyword);
1026
            $keywordCondition = " AND (title like '%$keyword%' OR content LIKE '%$keyword%') ";
1027
        }
1028
1029
        $sql = "SELECT
1030
                    id as col0, 
1031
                    title as col1, 
1032
                    send_date as col2, 
1033
                    user_receiver_id, 
1034
                    msg_status,
1035
                    user_sender_id
1036
                FROM $table
1037
                WHERE
1038
                    user_sender_id = ".api_get_user_id()." AND
1039
                    msg_status = ".MESSAGE_STATUS_OUTBOX."
1040
                    $keywordCondition
1041
                ORDER BY col$column $direction
1042
                LIMIT $from, $number_of_items";
1043
        $result = Database::query($sql);
1044
        $i = 0;
1045
        $message_list = [];
1046
        while ($row = Database::fetch_array($result, 'ASSOC')) {
1047
            $messageId = $row['col0'];
1048
            $title = $row['col1'];
1049
            $sendDate = $row['col2'];
1050
            $status = $row['msg_status'];
1051
            $senderId = $row['user_sender_id'];
1052
1053
            if ($request === true) {
1054
                $message[0] = '<input type="checkbox" value='.$messageId.' name="out[]">';
1055
            } else {
1056
                $message[0] = $messageId;
1057
            }
1058
1059
            $class = 'class = "read"';
1060
            $title = Security::remove_XSS($title);
1061
            $userInfo = api_get_user_info($senderId);
1062
            if ($request === true) {
1063
                $message[1] = '<a onclick="show_sent_message('.$messageId.')" href="javascript:void(0)">'.$userInfo['complete_name_with_username'].'</a>';
1064
                $message[2] = '<a onclick="show_sent_message('.$messageId.')" href="javascript:void(0)">'.str_replace("\\", "", $title).'</a>';
1065
                //date stays the same
1066
                $message[3] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG);
1067
                $message[4] = '&nbsp;&nbsp;<a title="'.addslashes(get_lang('DeleteMessage')).'" onclick="delete_one_message_outbox('.$messageId.')" href="javascript:void(0)"  >'.
1068
                    Display::returnFontAwesomeIcon('trash', 2).'</a>';
1069
            } else {
1070
                $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'];
1071
                $message[2] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG);
1072
                $message[3] = '<a title="'.addslashes(get_lang('DeleteMessage')).'" href="outbox.php?action=deleteone&id='.$messageId.'"  onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmDeleteMessage')))."'".')) return false;" >'.
1073
                    Display::returnFontAwesomeIcon('trash', 2).'</a>';
1074
            }
1075
1076
            $message_list[] = $message;
1077
            $i++;
1078
        }
1079
1080
        return $message_list;
1081
    }
1082
1083
    /**
1084
     * Gets information about number messages sent
1085
     * @author Isaac FLores Paz <[email protected]>
1086
     * @param void
1087
     * @return integer
1088
     */
1089
    public static function getNumberOfMessagesSent()
1090
    {
1091
        $table = Database::get_main_table(TABLE_MESSAGE);
1092
        $keyword = Session::read('message_sent_search_keyword');
1093
        $keywordCondition = '';
1094
        if (!empty($keyword)) {
1095
            $keyword = Database::escape_string($keyword);
1096
            $keywordCondition = " AND (title like '%$keyword%' OR content LIKE '%$keyword%') ";
1097
        }
1098
1099
        $sql = "SELECT COUNT(id) as number_messages 
1100
                FROM $table
1101
                WHERE
1102
                  msg_status = ".MESSAGE_STATUS_OUTBOX." AND
1103
                  user_sender_id = ".api_get_user_id()."
1104
                  $keywordCondition
1105
                ";
1106
        $result = Database::query($sql);
1107
        $result = Database::fetch_array($result);
1108
1109
        return $result['number_messages'];
1110
    }
1111
1112
    /**
1113
     * display message box in the inbox
1114
     * @param int the message id
1115
     * @param string inbox or outbox strings are available
1116
     * @todo replace numbers with letters in the $row array pff...
1117
     * @return string html with the message content
1118
     */
1119
    public static function showMessageBox($messageId, $source = 'inbox')
1120
    {
1121
        $table = Database::get_main_table(TABLE_MESSAGE);
1122
        $messageId = intval($messageId);
1123
1124
        if ($source == 'outbox') {
1125
            if (isset($messageId) && is_numeric($messageId)) {
1126
                $query = "SELECT * FROM $table
1127
                          WHERE
1128
                            user_sender_id = ".api_get_user_id()." AND
1129
                            id = ".$messageId." AND
1130
                            msg_status = ".MESSAGE_STATUS_OUTBOX;
1131
                $result = Database::query($query);
1132
            }
1133
        } else {
1134
            if (is_numeric($messageId) && !empty($messageId)) {
1135
                $query = "UPDATE $table SET
1136
                          msg_status = '".MESSAGE_STATUS_NEW."'
1137
                          WHERE
1138
                            user_receiver_id=" . api_get_user_id()." AND
1139
                            id='" . $messageId."'";
1140
                Database::query($query);
1141
1142
                $query = "SELECT * FROM $table
1143
                          WHERE
1144
                            msg_status<> ".MESSAGE_STATUS_OUTBOX." AND
1145
                            user_receiver_id=".api_get_user_id()." AND
1146
                            id='" . $messageId."'";
1147
                $result = Database::query($query);
1148
            }
1149
        }
1150
        $row = Database::fetch_array($result, 'ASSOC');
1151
        $user_sender_id = $row['user_sender_id'];
1152
1153
        // get file attachments by message id
1154
        $files_attachments = self::get_links_message_attachment_files(
1155
            $messageId,
1156
            $source
1157
        );
1158
1159
        $title = Security::remove_XSS($row['title'], STUDENT, true);
1160
        $content = Security::remove_XSS($row['content'], STUDENT, true);
1161
1162
        $name = get_lang('UnknownUser');
1163
        $fromUser = api_get_user_info($user_sender_id);
1164
        $userImage = '';
1165
        if (!empty($user_sender_id) && !empty($fromUser)) {
1166
            $name = $fromUser['complete_name_with_username'];
1167
            $userImage = Display::img(
1168
                $fromUser['avatar_small'],
1169
                $name,
1170
                ['title' => $name, 'class' => 'img-responsive img-circle', 'style' => 'max-width:35px'],
1171
                false
1172
            );
1173
        }
1174
1175
        $message_content = Display::page_subheader(str_replace("\\", "", $title));
1176
1177
        $receiverUserInfo = [];
1178
        if (!empty($row['user_receiver_id'])) {
1179
            $receiverUserInfo = api_get_user_info($row['user_receiver_id']);
1180
        }
1181
1182
        $message_content .= '<tr>';
1183
        if (api_get_setting('allow_social_tool') == 'true') {
1184
            $message_content .= '<div class="row">';
1185
            if ($source == 'outbox') {
1186
                $message_content .= '<div class="col-md-12">';
1187
                $message_content .= '<ul class="list-message">';
1188
                $message_content .= '<li>'.$userImage.'</li>';
1189
                $message_content .= '<li>'.$name.'&nbsp;';
1190
                if (!empty($receiverUserInfo)) {
1191
                    $message_content .= api_strtolower(get_lang('To')).'&nbsp;<b>'.$receiverUserInfo['complete_name_with_username'].'</b></li>';
1192
                } else {
1193
                    $message_content .= api_strtolower(get_lang('To')).'&nbsp;<b>-</b></li>';
1194
                }
1195
1196
                $message_content .= '<li>'.Display::dateToStringAgoAndLongDate($row['send_date']).'</li>';
1197
                $message_content .= '</ul>';
1198
                $message_content .= '</div>';
1199
            } else {
1200
                $message_content .= '<div class="col-md-12">';
1201
                $message_content .= '<ul class="list-message">';
1202
                if (!empty($user_sender_id)) {
1203
                    $message_content .= '<li>'.$userImage.'</li>';
1204
                    $message_content .= '<li><a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$user_sender_id.'">'.$name.'</a>';
1205
                } else {
1206
                    $message_content .= '<li>'.$name;
1207
                }
1208
1209
                $message_content .= '&nbsp;'.api_strtolower(get_lang('To')).'&nbsp;'.get_lang('Me');
1210
                $message_content .= '<li>'.Display::dateToStringAgoAndLongDate($row['send_date']).'</li>';
1211
                $message_content .= '</ul>';
1212
                $message_content .= '</div>';
1213
            }
1214
            $message_content .= '</div>';
1215
        } else {
1216
            if ($source == 'outbox') {
1217
                $message_content .= get_lang('From').':&nbsp;'.$name.'</b> '.api_strtolower(get_lang('To')).' <b>'.
1218
                    $receiverUserInfo['complete_name_with_username'].'</b>';
1219
            } else {
1220
                $message_content .= get_lang('From').':&nbsp;'.$name.'</b> '.api_strtolower(get_lang('To')).' <b>'.
1221
                    get_lang('Me').'</b>';
1222
            }
1223
        }
1224
1225
        $message_content .= '		        
1226
		        <hr style="color:#ddd" />
1227
		        <table width="100%">
1228
		            <tr>
1229
		              <td valign=top class="view-message-content">' . str_replace("\\", "", $content).'</td>
1230
		            </tr>
1231
		        </table>
1232
		        <div id="message-attach">' . (!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>
1233
		        <div style="padding: 15px 0px 5px 0px">';
1234
        $social_link = '';
1235
        if (isset($_GET['f']) && $_GET['f'] == 'social') {
1236
            $social_link = 'f=social';
1237
        }
1238
        if ($source == 'outbox') {
1239
            $message_content .= '<a href="outbox.php?'.$social_link.'">'.
1240
                Display::return_icon('back.png', get_lang('ReturnToOutbox')).'</a> &nbsp';
1241
        } else {
1242
            $message_content .= '<a href="inbox.php?'.$social_link.'">'.
1243
                Display::return_icon('back.png', get_lang('ReturnToInbox')).'</a> &nbsp';
1244
            $message_content .= '<a href="new_message.php?re_id='.$messageId.'&'.$social_link.'">'.
1245
                Display::return_icon('message_reply.png', get_lang('ReplyToMessage')).'</a> &nbsp';
1246
        }
1247
        $message_content .= '<a href="inbox.php?action=deleteone&id='.$messageId.'&'.$social_link.'" >'.
1248
            Display::return_icon('delete.png', get_lang('DeleteMessage')).'</a>&nbsp';
1249
1250
        $message_content .= '</div></td>
1251
		      <td width=10></td>
1252
		    </tr>
1253
		</table>';
1254
1255
        return $message_content;
1256
    }
1257
1258
    /**
1259
     * get user id by user email
1260
     * @param string $user_email
1261
     * @return int user id
1262
     */
1263
    public static function get_user_id_by_email($user_email)
1264
    {
1265
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
1266
        $sql = 'SELECT user_id FROM '.$tbl_user.'
1267
                WHERE email="' . Database::escape_string($user_email).'";';
1268
        $rs = Database::query($sql);
1269
        $row = Database::fetch_array($rs, 'ASSOC');
1270
        if (isset($row['user_id'])) {
1271
            return $row['user_id'];
1272
        } else {
1273
            return null;
1274
        }
1275
    }
1276
1277
    /**
1278
     * Displays messages of a group with nested view
1279
     *
1280
     * @param int $group_id
1281
     * @return string
1282
     */
1283
    public static function display_messages_for_group($group_id)
1284
    {
1285
        global $my_group_role;
1286
1287
        $rows = self::get_messages_by_group($group_id);
1288
        $topics_per_page = 10;
1289
        $html_messages = '';
1290
        $query_vars = ['id' => $group_id, 'topics_page_nr' => 0];
1291
1292
        if (is_array($rows) && count($rows) > 0) {
1293
            // prepare array for topics with its items
1294
            $topics = [];
1295
            $x = 0;
1296
            foreach ($rows as $index => $value) {
1297
                if (empty($value['parent_id'])) {
1298
                    $topics[$value['id']] = $value;
1299
                }
1300
            }
1301
1302
            $new_topics = [];
1303
1304
            foreach ($topics as $id => $value) {
1305
                $rows = null;
1306
                $rows = self::get_messages_by_group_by_message($group_id, $value['id']);
1307
                if (!empty($rows)) {
1308
                    $count = count(self::calculate_children($rows, $value['id']));
1309
                } else {
1310
                    $count = 0;
1311
                }
1312
                $value['count'] = $count;
1313
                $new_topics[$id] = $value;
1314
            }
1315
1316
            $array_html = [];
1317
            foreach ($new_topics as $index => $topic) {
1318
                $html = '';
1319
                // topics
1320
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
1321
                $name = $user_sender_info['complete_name'];
1322
                $html .= '<div class="groups-messages">';
1323
                $html .= '<div class="row">';
1324
1325
                $items = $topic['count'];
1326
                $reply_label = ($items == 1) ? get_lang('GroupReply') : get_lang('GroupReplies');
1327
                $label = '<i class="fa fa-envelope"></i> '.$items.' '.$reply_label;
1328
                $topic['title'] = trim($topic['title']);
1329
1330
                if (empty($topic['title'])) {
1331
                    $topic['title'] = get_lang('Untitled');
1332
                }
1333
1334
                $html .= '<div class="col-xs-8 col-md-10">';
1335
                $html .= Display::tag(
1336
                    'h4',
1337
                    Display::url(
1338
                        Security::remove_XSS($topic['title'], STUDENT, true),
1339
                        api_get_path(WEB_CODE_PATH).'social/group_topics.php?id='.$group_id.'&topic_id='.$topic['id']
1340
                    ),
1341
                    ['class' => 'title']
1342
                );
1343
                $actions = '';
1344
                if ($my_group_role == GROUP_USER_PERMISSION_ADMIN ||
1345
                    $my_group_role == GROUP_USER_PERMISSION_MODERATOR
1346
                ) {
1347
                    $actions = '<br />'.Display::url(
1348
                        get_lang('Delete'),
1349
                        api_get_path(WEB_CODE_PATH).'social/group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic['id'],
1350
                        ['class' => 'btn btn-default']
1351
                    );
1352
                }
1353
1354
                $date = '';
1355
                if ($topic['send_date'] != $topic['update_date']) {
1356
                    if (!empty($topic['update_date'])) {
1357
                        $date .= '<i class="fa fa-calendar"></i> '.get_lang('LastUpdate').' '.Display::dateToStringAgoAndLongDate($topic['update_date']);
1358
                    }
1359
                } else {
1360
                    $date .= '<i class="fa fa-calendar"></i> '.get_lang('Created').' '.Display::dateToStringAgoAndLongDate($topic['send_date']);
1361
                }
1362
                $html .= '<div class="date">'.$label.' - '.$date.$actions.'</div>';
1363
                $html .= '</div>';
1364
1365
                $image = $user_sender_info['avatar'];
1366
1367
                $user_info = '<div class="author"><img class="img-responsive img-circle" src="'.$image.'" alt="'.$name.'"  width="64" height="64" title="'.$name.'" /></div>';
1368
                $user_info .= '<div class="name"><a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp;</a></div>';
1369
1370
                $html .= '<div class="col-xs-4 col-md-2">';
1371
                $html .= $user_info;
1372
                $html .= '</div>';
1373
                $html .= '</div>';
1374
                $html .= '</div>';
1375
1376
                $array_html[] = [$html];
1377
            }
1378
1379
            // grids for items and topics  with paginations
1380
            $html_messages .= Display::return_sortable_grid(
1381
                'topics',
1382
                [],
1383
                $array_html,
1384
                [
1385
                    'hide_navigation' => false,
1386
                    'per_page' => $topics_per_page
1387
                ],
1388
                $query_vars,
1389
                false,
1390
                [true, true, true, false],
1391
                false
1392
            );
1393
        }
1394
1395
        return $html_messages;
1396
    }
1397
1398
    /**
1399
     * Displays messages of a group with nested view
1400
     * @param $group_id
1401
     * @param $topic_id
1402
     * @param $is_member
1403
     * @param $messageId
1404
     * @return string
1405
     */
1406
    public static function display_message_for_group($group_id, $topic_id, $is_member, $messageId)
1407
    {
1408
        global $my_group_role;
1409
        $main_message = self::get_message_by_id($topic_id);
1410
        if (empty($main_message)) {
1411
            return false;
1412
        }
1413
        $rows = self::get_messages_by_group_by_message($group_id, $topic_id);
1414
        $rows = self::calculate_children($rows, $topic_id);
1415
        $current_user_id = api_get_user_id();
1416
1417
        $items_per_page = 50;
1418
        $query_vars = ['id' => $group_id, 'topic_id' => $topic_id, 'topics_page_nr' => 0];
1419
1420
        // Main message
1421
        $links = '';
1422
        $main_content = '';
1423
        $html = '';
1424
        $items_page_nr = null;
1425
1426
        $user_sender_info = api_get_user_info($main_message['user_sender_id']);
1427
        $files_attachments = self::get_links_message_attachment_files($main_message['id']);
1428
        $name = $user_sender_info['complete_name'];
1429
1430
        $topic_page_nr = isset($_GET['topics_page_nr']) ? intval($_GET['topics_page_nr']) : null;
1431
1432
        $links .= '<div class="pull-right">';
1433
        $links .= '<div class="btn-group btn-group-sm">';
1434
1435
        if (($my_group_role == GROUP_USER_PERMISSION_ADMIN ||
1436
                $my_group_role == GROUP_USER_PERMISSION_MODERATOR) ||
1437
            $main_message['user_sender_id'] == $current_user_id
1438
        ) {
1439
            $urlEdit = api_get_path(WEB_CODE_PATH);
1440
            $urlEdit .= 'social/message_for_group_form.inc.php?';
1441
            $urlEdit .= http_build_query([
1442
                'user_friend' => $current_user_id,
1443
                'group_id' => $group_id,
1444
                'message_id' => $main_message['id'],
1445
                'action' => 'edit_message_group',
1446
                'anchor_topic' => 'topic_'.$main_message['id'],
1447
                'topics_page_nr' => $topic_page_nr,
1448
                'items_page_nr' => $items_page_nr,
1449
                'topic_id' => $main_message['id']
1450
            ]);
1451
1452
            $links .= Display::url(
1453
                Display::returnFontAwesomeIcon('pencil'),
1454
                $urlEdit,
1455
                [
1456
                    'class' => 'btn btn-default ajax',
1457
                    'title' => get_lang('Edit'),
1458
                    'data-title' => get_lang('Edit'),
1459
                    'data-size' => 'lg'
1460
                ]
1461
            );
1462
        }
1463
1464
        $urlReply = api_get_path(WEB_CODE_PATH);
1465
        $urlReply .= 'social/message_for_group_form.inc.php?';
1466
        $urlReply .= http_build_query([
1467
            'user_friend' => api_get_user_id(),
1468
            'group_id' => $group_id,
1469
            'message_id' => $main_message['id'],
1470
            'action' => 'reply_message_group',
1471
            'anchor_topic' => 'topic_'.$main_message['id'],
1472
            'topics_page_nr' => $topic_page_nr,
1473
            'topic_id' => $main_message['id']
1474
        ]);
1475
1476
        $links .= Display::url(
1477
            Display::returnFontAwesomeIcon('commenting'),
1478
            $urlReply,
1479
            [
1480
                'class' => 'btn btn-default ajax',
1481
                'title' => get_lang('Reply'),
1482
                'data-title' => get_lang('Reply'),
1483
                'data-size' => 'lg'
1484
            ]
1485
        );
1486
1487
        if (api_is_platform_admin()) {
1488
            $links .= Display::url(
1489
                Display::returnFontAwesomeIcon('trash'),
1490
                'group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic_id,
1491
                [
1492
                    'class' => 'btn btn-default'
1493
                ]
1494
            );
1495
        }
1496
1497
        $links .= '</div>';
1498
        $links .= '</div>';
1499
1500
        $title = '<h4>'.Security::remove_XSS($main_message['title'], STUDENT, true).$links.'</h4>';
1501
1502
        $userPicture = $user_sender_info['avatar'];
1503
        $main_content .= '<div class="row">';
1504
        $main_content .= '<div class="col-md-2">';
1505
        $main_content .= '<div class="avatar-author">';
1506
        $main_content .= '<img width="60px" src="'.$userPicture.'" alt="'.$name.'" class="img-responsive img-circle" title="'.$name.'" />';
1507
        $main_content .= '</div>';
1508
        $main_content .= '</div>';
1509
1510
        $date = '';
1511
        if ($main_message['send_date'] != $main_message['update_date']) {
1512
            if (!empty($main_message['update_date'])) {
1513
                $date = '<div class="date"> '.
1514
                    Display::returnFontAwesomeIcon('calendar').' '.get_lang('LastUpdate').' '.
1515
                    Display::dateToStringAgoAndLongDate($main_message['update_date']).
1516
                    '</div>';
1517
            }
1518
        } else {
1519
            $date = '<div class="date"> '.
1520
                Display::returnFontAwesomeIcon('calendar').' '.get_lang('Created').' '.
1521
                Display::dateToStringAgoAndLongDate($main_message['send_date']).
1522
                '</div>';
1523
        }
1524
        $attachment = '<div class="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>';
1525
        $main_content .= '<div class="col-md-10">';
1526
        $user_link = '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$main_message['user_sender_id'].'">'.$name.'</a>';
1527
        $main_content .= '<div class="message-content"> ';
1528
        $main_content .= '<div class="username">'.$user_link.'</div>';
1529
        $main_content .= $date;
1530
        $main_content .= '<div class="message">'.$main_message['content'].$attachment.'</div></div>';
1531
        $main_content .= '</div>';
1532
        $main_content .= '</div>';
1533
1534
        $html .= Display::div(
1535
            Display::div(
1536
                $title.$main_content,
1537
                ['class' => 'message-topic']
1538
            ),
1539
            ['class' => 'sm-groups-message']
1540
        );
1541
1542
        $topic_id = $main_message['id'];
1543
1544
        if (is_array($rows) && count($rows) > 0) {
1545
            $topics = $rows;
1546
            $array_html_items = [];
1547
            foreach ($topics as $index => $topic) {
1548
                if (empty($topic['id'])) {
1549
                    continue;
1550
                }
1551
                $items_page_nr = isset($_GET['items_'.$topic['id'].'_page_nr']) ? intval($_GET['items_'.$topic['id'].'_page_nr']) : null;
1552
                $links = '';
1553
                $links .= '<div class="pull-right">';
1554
                $html_items = '';
1555
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
1556
                $files_attachments = self::get_links_message_attachment_files($topic['id']);
1557
                $name = $user_sender_info['complete_name'];
1558
1559
                $links .= '<div class="btn-group btn-group-sm">';
1560
                if (($my_group_role == GROUP_USER_PERMISSION_ADMIN || $my_group_role == GROUP_USER_PERMISSION_MODERATOR) ||
1561
                    $topic['user_sender_id'] == $current_user_id
1562
                ) {
1563
                    $links .= '<a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?height=400&width=800&&user_friend='.$current_user_id.'&group_id='.$group_id.'&message_id='.$topic['id'].'&action=edit_message_group&anchor_topic=topic_'.$topic_id.'&topics_page_nr='.$topic_page_nr.'&items_page_nr='.$items_page_nr.'&topic_id='.$topic_id.'" class="ajax btn btn-default" data-size="lg" data-title="'.get_lang('Edit').'" title="'.get_lang('Edit').'">'.
1564
                        Display::returnFontAwesomeIcon('pencil').'</a>';
1565
                }
1566
                $links .= '<a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?height=400&width=800&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&message_id='.$topic['id'].'&action=reply_message_group&anchor_topic=topic_'.$topic_id.'&topics_page_nr='.$topic_page_nr.'&items_page_nr='.$items_page_nr.'&topic_id='.$topic_id.'" class="ajax btn btn-default" data-size="lg" data-title="'.get_lang('Reply').'" title="'.get_lang('Reply').'">';
1567
                $links .= Display::returnFontAwesomeIcon('commenting').'</a>';
1568
                $links .= '</div>';
1569
                $links .= '</div>';
1570
1571
                $userPicture = $user_sender_info['avatar'];
1572
                $user_link = '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp</a>';
1573
                $html_items .= '<div class="row">';
1574
                $html_items .= '<div class="col-md-2">';
1575
                $html_items .= '<div class="avatar-author">';
1576
                $html_items .= '<img width="60px" src="'.$userPicture.'" alt="'.$name.'" class="img-responsive img-circle" title="'.$name.'" /></div>';
1577
                $html_items .= '</div>';
1578
1579
                $date = '';
1580
                if ($topic['send_date'] != $topic['update_date']) {
1581
                    if (!empty($topic['update_date'])) {
1582
                        $date = '<div class="date"> '.
1583
                            Display::returnFontAwesomeIcon('calendar').' '.
1584
                            get_lang('LastUpdate').' '.Display::dateToStringAgoAndLongDate($topic['update_date']).
1585
                        '</div>';
1586
                    }
1587
                } else {
1588
                    $date = '<div class="date"> '.
1589
                        Display::returnFontAwesomeIcon('calendar').
1590
                        get_lang('Created').' '.Display::dateToStringAgoAndLongDate($topic['send_date']).
1591
                    '</div>';
1592
                }
1593
                $attachment = '<div class="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>';
1594
                $html_items .= '<div class="col-md-10">';
1595
                $html_items .= '<div class="message-content">';
1596
                $html_items .= $links;
1597
                $html_items .= '<div class="username">'.$user_link.'</div>';
1598
                $html_items .= $date;
1599
                $html_items .= '<div class="message">'.
1600
                    Security::remove_XSS($topic['content'], STUDENT, true).
1601
                    '</div>'.$attachment.'</div>';
1602
                $html_items .= '</div>';
1603
                $html_items .= '</div>';
1604
1605
                $base_padding = 20;
1606
1607
                if ($topic['indent_cnt'] == 0) {
1608
                    $indent = $base_padding;
1609
                } else {
1610
                    $indent = intval($topic['indent_cnt']) * $base_padding + $base_padding;
1611
                }
1612
1613
                $html_items = Display::div($html_items, ['class' => 'message-post', 'id' => 'msg_'.$topic['id']]);
1614
                $html_items = Display::div($html_items, ['class' => '', 'style' => 'margin-left:'.$indent.'px']);
1615
                $array_html_items[] = [$html_items];
1616
            }
1617
1618
            // grids for items with paginations
1619
            $options = ['hide_navigation' => false, 'per_page' => $items_per_page];
1620
            $visibility = [true, true, true, false];
1621
1622
            $style_class = [
1623
                'item' => ['class' => 'user-post'],
1624
                'main' => ['class' => 'user-list'],
1625
            ];
1626
            if (!empty($array_html_items)) {
1627
                $html .= Display::return_sortable_grid(
1628
                    'items_'.$topic['id'],
1629
                    [],
1630
                    $array_html_items,
1631
                    $options,
1632
                    $query_vars,
1633
                    null,
1634
                    $visibility,
1635
                    false,
1636
                    $style_class
1637
                );
1638
            }
1639
        }
1640
1641
        return $html;
1642
    }
1643
1644
    /**
1645
     * Add children to messages by id is used for nested view messages
1646
     * @param array $rows rows of messages
1647
     * @return array $first_seed new list adding the item children
1648
     */
1649
    public static function calculate_children($rows, $first_seed)
1650
    {
1651
        $rows_with_children = [];
1652
        foreach ($rows as $row) {
1653
            $rows_with_children[$row["id"]] = $row;
1654
            $rows_with_children[$row["parent_id"]]["children"][] = $row["id"];
1655
        }
1656
        $rows = $rows_with_children;
1657
        $sorted_rows = [0 => []];
1658
        self::message_recursive_sort($rows, $sorted_rows, $first_seed);
1659
        unset($sorted_rows[0]);
1660
1661
        return $sorted_rows;
1662
    }
1663
1664
    /**
1665
     * Sort recursively the messages, is used for for nested view messages
1666
     * @param array  original rows of messages
1667
     * @param array  list recursive of messages
1668
     * @param int   seed for calculate the indent
1669
     * @param int   indent for nested view
1670
     * @return void
1671
     */
1672
    public static function message_recursive_sort(
1673
        $rows,
1674
        &$messages,
1675
        $seed = 0,
1676
        $indent = 0
1677
    ) {
1678
        if ($seed > 0 && isset($rows[$seed]["id"])) {
1679
            $messages[$rows[$seed]["id"]] = $rows[$seed];
1680
            $messages[$rows[$seed]["id"]]["indent_cnt"] = $indent;
1681
            $indent++;
1682
        }
1683
1684
        if (isset($rows[$seed]["children"])) {
1685
            foreach ($rows[$seed]["children"] as $child) {
1686
                self::message_recursive_sort($rows, $messages, $child, $indent);
1687
            }
1688
        }
1689
    }
1690
1691
    /**
1692
     * Sort date by desc from a multi-dimensional array
1693
     * @param array $array1 first array to compare
1694
     * @param array $array2 second array to compare
1695
     * @return bool
1696
     */
1697
    public function order_desc_date($array1, $array2)
1698
    {
1699
        return strcmp($array2['send_date'], $array1['send_date']);
1700
    }
1701
1702
    /**
1703
     * Get array of links (download) for message attachment files
1704
     * @param int $messageId
1705
     * @param string $type message list (inbox/outbox)
1706
     * @return array
1707
     */
1708
    public static function get_links_message_attachment_files($messageId, $type = '')
1709
    {
1710
        $table = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
1711
        $messageId = intval($messageId);
1712
1713
        // get file attachments by message id
1714
        $links_attach_file = [];
1715
        if (!empty($messageId)) {
1716
            $sql = "SELECT * FROM $table
1717
                    WHERE message_id = '$messageId'";
1718
1719
            $rs_file = Database::query($sql);
1720
            if (Database::num_rows($rs_file) > 0) {
1721
                $attach_icon = Display::return_icon('attachment.gif', '');
1722
                $archiveURL = api_get_path(WEB_CODE_PATH).'messages/download.php?type='.$type.'&file=';
1723
                while ($row_file = Database::fetch_array($rs_file)) {
1724
                    $archiveFile = $row_file['path'];
1725
                    $filename = $row_file['filename'];
1726
                    $filesize = format_file_size($row_file['size']);
1727
                    $filecomment = Security::remove_XSS($row_file['comment']);
1728
                    $filename = Security::remove_XSS($filename);
1729
                    $links_attach_file[] = $attach_icon.'&nbsp;<a href="'.$archiveURL.$archiveFile.'">'.$filename.'</a>
1730
                        &nbsp;('.$filesize.')'.(!empty($filecomment) ? '&nbsp;-&nbsp;<i>'.$filecomment.'</i>' : '');
1731
                }
1732
            }
1733
        }
1734
        return $links_attach_file;
1735
    }
1736
1737
    /**
1738
     * Get message list by id
1739
     * @param int $messageId
1740
     * @return array
1741
     */
1742
    public static function get_message_by_id($messageId)
1743
    {
1744
        $table = Database::get_main_table(TABLE_MESSAGE);
1745
        $messageId = intval($messageId);
1746
        $sql = "SELECT * FROM $table
1747
                WHERE 
1748
                    id = '$messageId' AND 
1749
                    msg_status <> '".MESSAGE_STATUS_DELETED."' ";
1750
        $res = Database::query($sql);
1751
        $item = [];
1752
        if (Database::num_rows($res) > 0) {
1753
            $item = Database::fetch_array($res, 'ASSOC');
1754
        }
1755
        return $item;
1756
    }
1757
1758
    /**
1759
     *
1760
     * @return string
1761
     */
1762
    public static function generate_message_form()
1763
    {
1764
        $form = new FormValidator('send_message');
1765
        $form->addText(
1766
            'subject',
1767
            get_lang('Subject'),
1768
            false,
1769
            ['id' => 'subject_id']
1770
        );
1771
        $form->addTextarea(
1772
            'content',
1773
            get_lang('Message'),
1774
            ['id' => 'content_id', 'rows' => '5']
1775
        );
1776
1777
        return $form->returnForm();
1778
    }
1779
1780
    /**
1781
     * @param $id
1782
     * @param array $params
1783
     * @return string
1784
     */
1785
    public static function generate_invitation_form($id, $params = [])
1786
    {
1787
        $form = new FormValidator('send_invitation');
1788
        $form->addTextarea(
1789
            'content',
1790
            get_lang('AddPersonalMessage'),
1791
            ['id' => 'content_invitation_id', 'rows' => 5]
1792
        );
1793
        return $form->returnForm();
1794
    }
1795
1796
    //@todo this functions should be in the message class
1797
    /**
1798
     * @param string $keyword
1799
     * @return string
1800
     */
1801
    public static function inbox_display($keyword = '')
1802
    {
1803
        $success = get_lang('SelectedMessagesDeleted');
1804
        $success_read = get_lang('SelectedMessagesRead');
1805
        $success_unread = get_lang('SelectedMessagesUnRead');
1806
        $html = '';
1807
1808
        Session::write('message_search_keyword', $keyword);
1809
1810
        if (isset($_REQUEST['action'])) {
1811
            switch ($_REQUEST['action']) {
1812
                case 'mark_as_unread':
1813
                    if (is_array($_POST['id'])) {
1814
                        foreach ($_POST['id'] as $index => $message_id) {
1815
                            self::update_message_status(
1816
                                api_get_user_id(),
1817
                                $message_id,
1818
                                MESSAGE_STATUS_UNREAD
1819
                            );
1820
                        }
1821
                    }
1822
                    $html .= Display::return_message(
1823
                        api_xml_http_response_encode($success_unread),
1824
                        'normal',
1825
                        false
1826
                    );
1827
                    break;
1828
                case 'mark_as_read':
1829
                    if (is_array($_POST['id'])) {
1830
                        foreach ($_POST['id'] as $index => $message_id) {
1831
                            self::update_message_status(
1832
                                api_get_user_id(),
1833
                                $message_id,
1834
                                MESSAGE_STATUS_NEW
1835
                            );
1836
                        }
1837
                    }
1838
                    $html .= Display::return_message(
1839
                        api_xml_http_response_encode($success_read),
1840
                        'normal',
1841
                        false
1842
                    );
1843
                    break;
1844
                case 'delete':
1845
                    foreach ($_POST['id'] as $index => $message_id) {
1846
                        self::delete_message_by_user_receiver(api_get_user_id(), $message_id);
1847
                    }
1848
                    $html .= Display::return_message(
1849
                        api_xml_http_response_encode($success),
1850
                        'normal',
1851
                        false
1852
                    );
1853
                    break;
1854
                case 'deleteone':
1855
                    self::delete_message_by_user_receiver(api_get_user_id(), $_GET['id']);
1856
                    $html .= Display::return_message(
1857
                        api_xml_http_response_encode($success),
1858
                        'confirmation',
1859
                        false
1860
                    );
1861
                    break;
1862
            }
1863
        }
1864
1865
        // display sortable table with messages of the current user
1866
        $table = new SortableTable(
1867
            'message_inbox',
1868
            ['MessageManager', 'getNumberOfMessages'],
1869
            ['MessageManager', 'get_message_data'],
1870
            2,
1871
            20,
1872
            'DESC'
1873
        );
1874
        $table->set_header(0, '', false, ['style' => 'width:15px;']);
1875
        $table->set_header(1, get_lang('Messages'), false);
1876
        $table->set_header(2, get_lang('Date'), true, ['style' => 'width:180px;']);
1877
        $table->set_header(3, get_lang('Modify'), false, ['style' => 'width:120px;']);
1878
1879
        if (isset($_REQUEST['f']) && $_REQUEST['f'] == 'social') {
1880
            $parameters['f'] = 'social';
1881
            $table->set_additional_parameters($parameters);
1882
        }
1883
        $table->set_form_actions(
1884
            [
1885
                'delete' => get_lang('DeleteSelectedMessages'),
1886
                'mark_as_unread' => get_lang('MailMarkSelectedAsUnread'),
1887
                'mark_as_read' => get_lang('MailMarkSelectedAsRead'),
1888
            ]
1889
        );
1890
        $html .= $table->return_table();
1891
1892
        Session::erase('message_search_keyword');
1893
1894
        return $html;
1895
    }
1896
1897
    /**
1898
     * @param string $keyword
1899
     * @return string
1900
     */
1901
    public static function outbox_display($keyword = '')
1902
    {
1903
        Session::write('message_sent_search_keyword', $keyword);
1904
        $success = get_lang('SelectedMessagesDeleted').'&nbsp</b><br />
1905
                    <a href="outbox.php">'.get_lang('BackToOutbox').'</a>';
1906
1907
        $html = '';
1908
        if (isset($_REQUEST['action'])) {
1909
            switch ($_REQUEST['action']) {
1910
                case 'delete':
1911
                    $number_of_selected_messages = count($_POST['id']);
1912
                    if ($number_of_selected_messages != 0) {
1913
                        foreach ($_POST['id'] as $index => $message_id) {
1914
                            self::delete_message_by_user_receiver(
1915
                                api_get_user_id(),
1916
                                $message_id
1917
                            );
1918
                        }
1919
                    }
1920
                    $html .= Display::return_message(api_xml_http_response_encode($success), 'normal', false);
1921
                    break;
1922
                case 'deleteone':
1923
                    self::delete_message_by_user_receiver(api_get_user_id(), $_GET['id']);
1924
                    $html .= Display::return_message(api_xml_http_response_encode($success), 'normal', false);
1925
                    $html .= '<br/>';
1926
                    break;
1927
            }
1928
        }
1929
1930
        // display sortable table with messages of the current user
1931
        $table = new SortableTable(
1932
            'message_outbox',
1933
            ['MessageManager', 'getNumberOfMessagesSent'],
1934
            ['MessageManager', 'get_message_data_sent'],
1935
            2,
1936
            20,
1937
            'DESC'
1938
        );
1939
1940
        $table->set_header(0, '', false, ['style' => 'width:15px;']);
1941
        $table->set_header(1, get_lang('Messages'), false);
1942
        $table->set_header(2, get_lang('Date'), true, ['style' => 'width:180px;']);
1943
        $table->set_header(3, get_lang('Modify'), false, ['style' => 'width:70px;']);
1944
1945
        $table->set_form_actions(['delete' => get_lang('DeleteSelectedMessages')]);
1946
        $html .= $table->return_table();
1947
1948
        Session::erase('message_sent_search_keyword');
1949
1950
        return $html;
1951
    }
1952
1953
    /**
1954
     * Get the count of the last received messages for a user
1955
     * @param int $userId The user id
1956
     * @param int $lastId The id of the last received message
1957
     * @return int The count of new messages
1958
     */
1959
    public static function countMessagesFromLastReceivedMessage($userId, $lastId = 0)
1960
    {
1961
        $userId = intval($userId);
1962
        $lastId = intval($lastId);
1963
1964
        if (empty($userId)) {
1965
            return 0;
1966
        }
1967
1968
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
1969
1970
        $conditions = [
1971
            'where' => [
1972
                'user_receiver_id = ?' => $userId,
1973
                'AND msg_status = ?' => MESSAGE_STATUS_UNREAD,
1974
                'AND id > ?' => $lastId
1975
            ]
1976
        ];
1977
1978
        $result = Database::select('COUNT(1) AS qty', $messagesTable, $conditions);
1979
1980
        if (!empty($result)) {
1981
            $row = current($result);
1982
1983
            return $row['qty'];
1984
        }
1985
1986
        return 0;
1987
    }
1988
1989
    /**
1990
     * Get the data of the last received messages for a user
1991
     * @param int $userId The user id
1992
     * @param int $lastId The id of the last received message
1993
     * @return array
1994
     */
1995
    public static function getMessagesFromLastReceivedMessage($userId, $lastId = 0)
1996
    {
1997
        $userId = intval($userId);
1998
        $lastId = intval($lastId);
1999
2000
        if (empty($userId)) {
2001
            return [];
2002
        }
2003
2004
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
2005
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
2006
2007
        $sql = "SELECT m.*, u.user_id, u.lastname, u.firstname
2008
                FROM $messagesTable as m
2009
                INNER JOIN $userTable as u
2010
                ON m.user_sender_id = u.user_id
2011
                WHERE
2012
                    m.user_receiver_id = $userId AND
2013
                    m.msg_status = ".MESSAGE_STATUS_UNREAD."
2014
                    AND m.id > $lastId
2015
                ORDER BY m.send_date DESC";
2016
2017
        $result = Database::query($sql);
2018
2019
        $messages = [];
2020
        if ($result !== false) {
2021
            while ($row = Database::fetch_assoc($result)) {
2022
                $messages[] = $row;
2023
            }
2024
        }
2025
2026
        return $messages;
2027
    }
2028
2029
    /**
2030
     * Check whether a message has attachments
2031
     * @param int $messageId The message id
2032
     * @return boolean Whether the message has attachments return true. Otherwise return false
2033
     */
2034
    public static function hasAttachments($messageId)
2035
    {
2036
        $messageId = intval($messageId);
2037
2038
        if (empty($messageId)) {
2039
            return false;
2040
        }
2041
2042
        $messageAttachmentTable = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
2043
2044
        $conditions = [
2045
            'where' => [
2046
                'message_id = ?' => $messageId
2047
            ]
2048
        ];
2049
2050
        $result = Database::select(
2051
            'COUNT(1) AS qty',
2052
            $messageAttachmentTable,
2053
            $conditions,
2054
            'first'
2055
        );
2056
2057
        if (!empty($result)) {
2058
            if ($result['qty'] > 0) {
2059
                return true;
2060
            }
2061
        }
2062
2063
        return false;
2064
    }
2065
2066
    /**
2067
     * @param string $url
2068
     *
2069
     * @return FormValidator
2070
     */
2071
    public static function getSearchForm($url)
2072
    {
2073
        $form = new FormValidator(
2074
            'search',
2075
            'post',
2076
            $url,
2077
            null,
2078
            [],
2079
            FormValidator::LAYOUT_INLINE
2080
        );
2081
2082
        $form->addElement(
2083
            'text',
2084
            'keyword',
2085
            false,
2086
            [
2087
                'aria-label' => get_lang('Search'),
2088
            ]
2089
        );
2090
        $form->addButtonSearch(get_lang('Search'));
2091
2092
        return $form;
2093
    }
2094
2095
    /**
2096
     * Send a notification to all admins when a new user is registered
2097
     * @param User $user
2098
     */
2099
    public static function sendNotificationByRegisteredUser(User $user)
2100
    {
2101
        $tplMailBody = new Template(
2102
            null,
2103
            false,
2104
            false,
2105
            false,
2106
            false,
2107
            false,
2108
            false
2109
        );
2110
        $tplMailBody->assign('user', $user);
2111
        $tplMailBody->assign('is_western_name_order', api_is_western_name_order());
2112
        $tplMailBody->assign(
2113
            'manageUrl',
2114
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$user->getId()
2115
        );
2116
2117
        $layoutContent = $tplMailBody->get_template('mail/new_user_mail_to_admin.tpl');
2118
2119
        $emailsubject = '['.get_lang('UserRegistered').'] '.$user->getUsername();
2120
        $emailbody = $tplMailBody->fetch($layoutContent);
2121
2122
        $admins = UserManager::get_all_administrators();
2123
2124
        foreach ($admins as $admin_info) {
2125
            self::send_message(
2126
                $admin_info['user_id'],
2127
                $emailsubject,
2128
                $emailbody,
2129
                [],
2130
                [],
2131
                null,
2132
                null,
2133
                null,
2134
                null,
2135
                $user->getId()
2136
            );
2137
        }
2138
    }
2139
2140
    /**
2141
     * Get the error log from failed mailing
2142
     * This assumes a complex setup where you have a cron script regularly copying the mail queue log
2143
     * into app/cache/mail/mailq.
2144
     * This can be done with a cron command like (check the location of your mail log file first):
2145
     * @example 0,30 * * * * root cp /var/log/exim4/mainlog /var/www/chamilo/app/cache/mail/mailq
2146
     * @return array|bool
2147
     */
2148
    public static function failedSentMailErrors()
2149
    {
2150
        $base = api_get_path(SYS_ARCHIVE_PATH).'mail/';
2151
        $mailq = $base.'mailq';
2152
2153
        if (!file_exists($mailq) || !is_readable($mailq)) {
2154
            return false;
2155
        }
2156
2157
        $file = fopen($mailq, 'r');
2158
        $i = 1;
2159
        while (!feof($file)) {
2160
            $line = fgets($file);
2161
            //$line = trim($line);
2162
2163
            if (trim($line) == '') {
2164
                continue;
2165
            }
2166
2167
            //Get the mail code, something like 1WBumL-0002xg-FF
2168
            if (preg_match('/(.*)\s((.*)-(.*)-(.*))\s<(.*)$/', $line, $codeMatches)) {
2169
                $mail_queue[$i]['code'] = $codeMatches[2];
2170
            }
2171
2172
            $fullMail = $base.$mail_queue[$i]['code'];
2173
            $mailFile = fopen($fullMail, 'r');
2174
2175
            //Get the reason of mail fail
2176
            $iX = 1;
2177
2178
            while (!feof($mailFile)) {
2179
                $mailLine = fgets($mailFile);
2180
                #if ($iX == 4 && preg_match('/(.*):\s(.*)$/', $mailLine, $matches)) {
2181
                if (
2182
                    $iX == 2 &&
2183
                    preg_match('/(.*)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s(.*)/', $mailLine, $detailsMatches)
2184
                ) {
2185
                    $mail_queue[$i]['reason'] = $detailsMatches[3];
2186
                }
2187
2188
                $iX++;
2189
            }
2190
2191
            fclose($mailFile);
2192
2193
            //Get the time of mail fail
2194
            if (preg_match('/^\s?(\d+)(\D+)\s+(.*)$/', $line, $timeMatches)) {
2195
                $mail_queue[$i]['time'] = $timeMatches[1].$timeMatches[2];
2196
            } elseif (preg_match('/^(\s+)((.*)@(.*))\s+(.*)$/', $line, $emailMatches)) {
2197
                $mail_queue[$i]['mail'] = $emailMatches[2];
2198
                $i++;
2199
            }
2200
        }
2201
2202
        fclose($file);
2203
2204
        return array_reverse($mail_queue);
2205
    }
2206
}
2207