Passed
Push — master ( 954b89...f7e68c )
by Julito
07:20
created

MessageManager::send_message_simple()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 58
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 34
nc 24
nop 9
dl 0
loc 58
rs 8.4426
c 0
b 0
f 0

How to fix   Long Method    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
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Course;
6
use Chamilo\CoreBundle\Entity\Message;
7
use Chamilo\CoreBundle\Entity\MessageAttachment;
8
use Chamilo\CoreBundle\Entity\MessageFeedback;
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Framework\Container;
11
use ChamiloSession as Session;
12
use Doctrine\Common\Collections\Criteria;
13
use Symfony\Component\HttpFoundation\File\UploadedFile;
14
15
/**
16
 * This class provides methods for messages management.
17
 * Include/require it in your code to use its features.
18
 */
19
class MessageManager
20
{
21
    /**
22
     * @param array  $aboutUserInfo
23
     * @param array  $fromUserInfo
24
     * @param string $subject
25
     * @param string $content
26
     *
27
     * @return bool
28
     */
29
    public static function sendMessageAboutUser(
30
        $aboutUserInfo,
31
        $fromUserInfo,
32
        $subject,
33
        $content
34
    ) {
35
        if (empty($aboutUserInfo) || empty($fromUserInfo)) {
36
            return false;
37
        }
38
39
        if (empty($fromUserInfo['id']) || empty($aboutUserInfo['id'])) {
40
            return false;
41
        }
42
43
        $table = Database::get_main_table(TABLE_MESSAGE);
44
        $now = api_get_utc_datetime();
45
        $params = [
46
            'user_sender_id' => $fromUserInfo['id'],
47
            'user_receiver_id' => $aboutUserInfo['id'],
48
            'msg_status' => MESSAGE_STATUS_CONVERSATION,
49
            'send_date' => $now,
50
            'title' => $subject,
51
            'content' => $content,
52
            'group_id' => 0,
53
            'parent_id' => 0,
54
            'update_date' => $now,
55
        ];
56
        $id = Database::insert($table, $params);
57
58
        if ($id) {
59
            return true;
60
        }
61
62
        return false;
63
    }
64
65
    public static function getMessagesAboutUser(User $user): array
66
    {
67
        if (!empty($user)) {
68
            $table = Database::get_main_table(TABLE_MESSAGE);
69
            $sql = 'SELECT id FROM '.$table.'
70
                    WHERE
71
                      user_receiver_id = '.$user->getId().' AND
72
                      msg_status = '.MESSAGE_STATUS_CONVERSATION.'
73
                    ';
74
            $result = Database::query($sql);
75
            $messages = [];
76
            $repo = Database::getManager()->getRepository(Message::class);
77
            while ($row = Database::fetch_array($result)) {
78
                $message = $repo->find($row['id']);
79
                $messages[] = $message;
80
            }
81
82
            return $messages;
83
        }
84
85
        return [];
86
    }
87
88
    public static function getMessagesAboutUserToString(User $user): string
89
    {
90
        $messages = self::getMessagesAboutUser($user);
91
        $html = '';
92
        if (!empty($messages)) {
93
            /** @var Message $message */
94
            foreach ($messages as $message) {
95
                $tag = 'message_'.$message->getId();
96
                $tagAccordion = 'accordion_'.$message->getId();
97
                $tagCollapse = 'collapse_'.$message->getId();
98
                $date = Display::dateToStringAgoAndLongDate(
99
                    $message->getSendDate()
100
                );
101
                $localTime = api_get_local_time(
102
                    $message->getSendDate(),
103
                    null,
104
                    null,
105
                    false,
106
                    false
107
                );
108
                $senderId = $message->getUserSender()->getId();
109
                $senderInfo = api_get_user_info($senderId);
110
                $html .= Display::panelCollapse(
111
                    $localTime.' '.$senderInfo['complete_name'].' '.$message->getTitle(),
112
                    $message->getContent().'<br />'.$date.'<br />'.get_lang(
113
                        'Author'
114
                    ).': '.$senderInfo['complete_name_with_message_link'],
115
                    $tag,
116
                    null,
117
                    $tagAccordion,
118
                    $tagCollapse,
119
                    false
120
                );
121
            }
122
        }
123
124
        return $html;
125
    }
126
127
    /**
128
     * @param int    $senderId
129
     * @param int    $receiverId
130
     * @param string $subject
131
     * @param string $message
132
     *
133
     * @return bool
134
     */
135
    public static function messageWasAlreadySent($senderId, $receiverId, $subject, $message)
136
    {
137
        $table = Database::get_main_table(TABLE_MESSAGE);
138
        $senderId = (int) $senderId;
139
        $receiverId = (int) $receiverId;
140
        $subject = Database::escape_string($subject);
141
        $message = Database::escape_string($message);
142
143
        $sql = "SELECT * FROM $table
144
                WHERE
145
                    user_sender_id = $senderId AND
146
                    user_receiver_id = $receiverId AND
147
                    title = '$subject' AND
148
                    content = '$message' AND
149
                    msg_type = ".Message::MESSAGE_TYPE_INBOX."
150
                ";
151
        $result = Database::query($sql);
152
153
        return Database::num_rows($result) > 0;
154
    }
155
156
    /**
157
     * Sends a message to a user/group.
158
     *
159
     * @param int    $receiverUserId
160
     * @param string $subject
161
     * @param string $content
162
     * @param array  $attachments                files array($_FILES) (optional)
163
     * @param array  $fileCommentList            about attachment files (optional)
164
     * @param int    $group_id                   (optional)
165
     * @param int    $parent_id                  (optional)
166
     * @param int    $editMessageId              id for updating the message (optional)
167
     * @param int    $topic_id                   (optional) the default value is the current user_id
168
     * @param int    $sender_id
169
     * @param bool   $directMessage
170
     * @param int    $forwardId
171
     * @param array  $smsParameters
172
     * @param bool   $checkCurrentAudioId
173
     * @param bool   $forceTitleWhenSendingEmail force the use of $title as subject instead of "You have a new message"
174
     * @param int    $status                     Message status
175
     *
176
     * @return bool
177
     */
178
    public static function send_message(
179
        $receiverUserId,
180
        $subject,
181
        $content,
182
        array $attachments = [],
183
        array $fileCommentList = [],
184
        $group_id = 0,
185
        $parent_id = 0,
186
        $editMessageId = 0,
187
        $topic_id = 0,
188
        $sender_id = 0,
189
        $directMessage = false,
190
        $forwardId = 0,
191
        $smsParameters = [],
192
        $checkCurrentAudioId = false,
193
        $forceTitleWhenSendingEmail = false,
194
        $status = 0
195
    ) {
196
        $group_id = (int) $group_id;
197
        $receiverUserId = (int) $receiverUserId;
198
        $parent_id = (int) $parent_id;
199
        $editMessageId = (int) $editMessageId;
200
        $topic_id = (int) $topic_id;
201
        $status = empty($status) ? MESSAGE_STATUS_UNREAD : (int) $status;
202
        $user_sender_id = empty($sender_id) ? api_get_user_id() : (int) $sender_id;
203
204
        if (empty($user_sender_id) || empty($receiverUserId)) {
205
            return false;
206
        }
207
208
        $userSender = api_get_user_entity($user_sender_id);
209
        if (null === $userSender) {
210
            Display::addFlash(Display::return_message(get_lang('This user doesn\'t exist'), 'warning'));
211
212
            return false;
213
        }
214
215
        $userRecipient = api_get_user_entity($receiverUserId);
216
217
        if (null === $userRecipient) {
218
            return false;
219
        }
220
221
        // Disabling messages for inactive users.
222
        if (!$userRecipient->getActive()) {
223
            return false;
224
        }
225
226
        $sendEmail = true;
227
        // Disabling messages depending the pausetraining plugin.
228
        $allowPauseFormation =
229
            'true' === api_get_plugin_setting('pausetraining', 'tool_enable') &&
230
            'true' === api_get_plugin_setting('pausetraining', 'allow_users_to_edit_pause_formation');
231
232
        if ($allowPauseFormation) {
233
            $extraFieldValue = new ExtraFieldValue('user');
234
            $disableEmails = $extraFieldValue->get_values_by_handler_and_field_variable(
235
                $receiverUserId,
236
                'disable_emails'
237
            );
238
239
            // User doesn't want email notifications but chamilo inbox still available.
240
            if (!empty($disableEmails) &&
241
                isset($disableEmails['value']) && 1 === (int) $disableEmails['value']
242
            ) {
243
                $sendEmail = false;
244
            }
245
246
            if ($sendEmail) {
247
                // Check if user pause his formation.
248
                $pause = $extraFieldValue->get_values_by_handler_and_field_variable(
249
                    $receiverUserId,
250
                    'pause_formation'
251
                );
252
                if (!empty($pause) && isset($pause['value']) && 1 === (int) $pause['value']) {
253
                    $startDate = $extraFieldValue->get_values_by_handler_and_field_variable(
254
                        $receiverUserId,
255
                        'start_pause_date'
256
                    );
257
                    $endDate = $extraFieldValue->get_values_by_handler_and_field_variable(
258
                        $receiverUserId,
259
                        'end_pause_date'
260
                    );
261
262
                    if (!empty($startDate) && isset($startDate['value']) && !empty($startDate['value']) &&
263
                        !empty($endDate) && isset($endDate['value']) && !empty($endDate['value'])
264
                    ) {
265
                        $now = time();
266
                        $start = api_strtotime($startDate['value']);
267
                        $end = api_strtotime($endDate['value']);
268
269
                        if ($now > $start && $now < $end) {
270
                            $sendEmail = false;
271
                        }
272
                    }
273
                }
274
            }
275
        }
276
277
        $totalFileSize = 0;
278
        $attachmentList = [];
279
        if (is_array($attachments)) {
280
            $counter = 0;
281
            foreach ($attachments as $attachment) {
282
                $attachment['comment'] = $fileCommentList[$counter] ?? '';
283
                $fileSize = $attachment['size'] ?? 0;
284
                if (is_array($fileSize)) {
285
                    foreach ($fileSize as $size) {
286
                        $totalFileSize += $size;
287
                    }
288
                } else {
289
                    $totalFileSize += $fileSize;
290
                }
291
                $attachmentList[] = $attachment;
292
                $counter++;
293
            }
294
        }
295
296
        if ($checkCurrentAudioId) {
297
            // Add the audio file as an attachment
298
            $audio = Session::read('current_audio');
299
            if (!empty($audio) && isset($audio['name']) && !empty($audio['name'])) {
300
                $audio['comment'] = 'audio_message';
301
                // create attachment from audio message
302
                $attachmentList[] = $audio;
303
            }
304
        }
305
306
        // Validating fields
307
        if (empty($subject) && empty($group_id)) {
308
            Display::addFlash(
309
                Display::return_message(
310
                    get_lang('You should write a subject'),
311
                    'warning'
312
                )
313
            );
314
315
            return false;
316
        } elseif ($totalFileSize > (int) api_get_setting('message_max_upload_filesize')) {
317
            $warning = sprintf(
318
                get_lang('Files size exceeds'),
319
                format_file_size(api_get_setting('message_max_upload_filesize'))
320
            );
321
322
            Display::addFlash(Display::return_message($warning, 'warning'));
323
324
            return false;
325
        }
326
327
        $em = Database::getManager();
328
        $repo = $em->getRepository(Message::class);
329
        $parent = null;
330
        if (!empty($parent_id)) {
331
            $parent = $repo->find($parent_id);
332
        }
333
334
        // Just in case we replace the and \n and \n\r while saving in the DB
335
        if (!empty($receiverUserId) || !empty($group_id)) {
336
            // message for user friend
337
            //@todo it's possible to edit a message? yes, only for groups
338
            if (!empty($editMessageId)) {
339
                $message = $repo->find($editMessageId);
340
                if (null !== $message) {
341
                    $message->setContent($content);
342
                    $em->persist($message);
343
                    $em->flush();
344
                }
345
                $messageId = $editMessageId;
346
            } else {
347
                $message = new Message();
348
                $message
349
                    ->setUserSender($userSender)
350
                    ->setUserReceiver($userRecipient)
351
                    ->setMsgType($status)
352
                    ->setTitle($subject)
353
                    ->setContent($content)
354
                    ->setGroup(api_get_group_entity($group_id))
355
                    ->setParent($parent)
356
                ;
357
                $em->persist($message);
358
                $em->flush();
359
                $messageId = $message->getId();
360
            }
361
362
            // Forward also message attachments.
363
            if (!empty($forwardId)) {
364
                $forwardMessage = $repo->find($forwardId);
365
                if (null !== $forwardMessage) {
366
                    $forwardAttachments = $forwardMessage->getAttachments();
367
                    foreach ($forwardAttachments as $forwardAttachment) {
368
                        $message->addAttachment($forwardAttachment);
369
                    }
370
                    $em->persist($message);
371
                    $em->flush();
372
                }
373
            }
374
375
            // Save attachment file for inbox messages
376
            if (is_array($attachmentList)) {
377
                foreach ($attachmentList as $attachment) {
378
                    if (0 === $attachment['error']) {
379
                        self::saveMessageAttachmentFile(
380
                            $attachment,
381
                            $attachment['comment'] ?? '',
382
                            $message,
383
                        );
384
                    }
385
                }
386
            }
387
388
            if ($sendEmail) {
389
                $notification = new Notification();
390
                $sender_info = api_get_user_info($user_sender_id);
391
392
                // add file attachment additional attributes
393
                $attachmentAddedByMail = [];
394
                foreach ($attachmentList as $attachment) {
395
                    $attachmentAddedByMail[] = [
396
                        'path' => $attachment['tmp_name'],
397
                        'filename' => $attachment['name'],
398
                    ];
399
                }
400
401
                if (empty($group_id)) {
402
                    $type = Notification::NOTIFICATION_TYPE_MESSAGE;
403
                    if ($directMessage) {
404
                        $type = Notification::NOTIFICATION_TYPE_DIRECT_MESSAGE;
405
                    }
406
                    $notification->saveNotification(
407
                        $messageId,
408
                        $type,
409
                        [$receiverUserId],
410
                        $subject,
411
                        $content,
412
                        $sender_info,
413
                        $attachmentAddedByMail,
414
                        $smsParameters,
415
                        $forceTitleWhenSendingEmail
416
                    );
417
                } else {
418
                    $usergroup = new UserGroupModel();
419
                    $group_info = $usergroup->get($group_id);
420
                    $group_info['topic_id'] = $topic_id;
421
                    $group_info['msg_id'] = $messageId;
422
423
                    $user_list = $usergroup->get_users_by_group(
424
                        $group_id,
425
                        false,
426
                        [],
427
                        0,
428
                        1000
429
                    );
430
431
                    // Adding more sense to the message group
432
                    $subject = sprintf(get_lang('There is a new message in group %s'), $group_info['name']);
433
                    $new_user_list = [];
434
                    foreach ($user_list as $user_data) {
435
                        $new_user_list[] = $user_data['id'];
436
                    }
437
                    $group_info = [
438
                        'group_info' => $group_info,
439
                        'user_info' => $sender_info,
440
                    ];
441
                    $notification->saveNotification(
442
                        $messageId,
443
                        Notification::NOTIFICATION_TYPE_GROUP,
444
                        $new_user_list,
445
                        $subject,
446
                        $content,
447
                        $group_info,
448
                        $attachmentAddedByMail,
449
                        $smsParameters
450
                    );
451
                }
452
            }
453
454
            return $messageId;
455
        }
456
457
        return false;
458
    }
459
460
    /**
461
     * @param int    $receiverUserId
462
     * @param string $subject
463
     * @param string $message
464
     * @param int    $sender_id
465
     * @param bool   $sendCopyToDrhUsers send copy to related DRH users
466
     * @param bool   $directMessage
467
     * @param array  $smsParameters
468
     * @param bool   $uploadFiles        Do not upload files using the MessageManager class
469
     * @param array  $attachmentList
470
     *
471
     * @return bool
472
     */
473
    public static function send_message_simple(
474
        $receiverUserId,
475
        $subject,
476
        $message,
477
        $sender_id = 0,
478
        $sendCopyToDrhUsers = false,
479
        $directMessage = false,
480
        $smsParameters = [],
481
        $uploadFiles = true,
482
        $attachmentList = []
483
    ) {
484
        $files = $_FILES ? $_FILES : [];
485
        if (false === $uploadFiles) {
486
            $files = [];
487
        }
488
        // $attachmentList must have: tmp_name, name, size keys
489
        if (!empty($attachmentList)) {
490
            $files = $attachmentList;
491
        }
492
        $result = self::send_message(
493
            $receiverUserId,
494
            $subject,
495
            $message,
496
            $files,
497
            [],
498
            null,
499
            null,
500
            null,
501
            null,
502
            $sender_id,
503
            $directMessage,
504
            0,
505
            $smsParameters
506
        );
507
508
        if ($sendCopyToDrhUsers) {
509
            $userInfo = api_get_user_info($receiverUserId);
510
            $drhList = UserManager::getDrhListFromUser($receiverUserId);
511
            if (!empty($drhList)) {
512
                foreach ($drhList as $drhInfo) {
513
                    $message = sprintf(
514
                        get_lang('Copy of message sent to %s'),
515
                        $userInfo['complete_name']
516
                    ).' <br />'.$message;
517
518
                    self::send_message_simple(
519
                        $drhInfo['id'],
520
                        $subject,
521
                        $message,
522
                        $sender_id,
523
                        false,
524
                        $directMessage
525
                    );
526
                }
527
            }
528
        }
529
530
        return $result;
531
    }
532
533
    public static function softDeleteAttachments(Message $message): void
534
    {
535
        $attachments = $message->getAttachments();
536
        if (!empty($attachments)) {
537
            $repo = Container::getMessageAttachmentRepository();
538
            foreach ($attachments as $file) {
539
                $repo->softDelete($file);
540
            }
541
        }
542
    }
543
544
    /**
545
     * Saves a message attachment files.
546
     *
547
     * @param array  $file    $_FILES['name']
548
     * @param string $comment a comment about the uploaded file
549
     */
550
    public static function saveMessageAttachmentFile($file, $comment, Message $message)
551
    {
552
        // Try to add an extension to the file if it hasn't one
553
        $type = $file['type'] ?? '';
554
        if (empty($type)) {
555
            $type = DocumentManager::file_get_mime_type($file['name']);
556
        }
557
        $new_file_name = add_ext_on_mime(stripslashes($file['name']), $type);
558
559
        // user's file name
560
        $fileName = $file['name'];
561
        if (!filter_extension($new_file_name)) {
562
            Display::addFlash(
563
                Display::return_message(
564
                    get_lang('File upload failed: this file extension or file type is prohibited'),
565
                    'error'
566
                )
567
            );
568
569
            return false;
570
        }
571
572
        $em = Database::getManager();
573
        $attachmentRepo = Container::getMessageAttachmentRepository();
574
575
        $attachment = new MessageAttachment();
576
        $attachment
577
            ->setSize($file['size'])
578
            ->setPath($fileName)
579
            ->setFilename($fileName)
580
            ->setComment($comment)
581
            ->setParent($message->getUserSender())
582
            ->setMessage($message)
583
        ;
584
585
        $request = Container::getRequest();
586
        $fileToUpload = null;
587
588
        // Search for files inside the $_FILES, when uploading several files from the form.
589
        if ($request->files->count()) {
590
            /** @var UploadedFile|null $fileRequest */
591
            foreach ($request->files->all() as $fileRequest) {
592
                if (null === $fileRequest) {
593
                    continue;
594
                }
595
                if ($fileRequest->getClientOriginalName() === $file['name']) {
596
                    $fileToUpload = $fileRequest;
597
                    break;
598
                }
599
            }
600
        }
601
602
        // If no found file, try with $file['content'].
603
        if (null === $fileToUpload && isset($file['content'])) {
604
            $handle = tmpfile();
605
            fwrite($handle, $file['content']);
606
            $meta = stream_get_meta_data($handle);
607
            $fileToUpload = new UploadedFile($meta['uri'], $fileName, $file['type'], null, true);
608
        }
609
610
        if (null !== $fileToUpload) {
611
            $em->persist($attachment);
612
            $attachmentRepo->addFile($attachment, $fileToUpload);
613
            $attachment->addUserLink($message->getUserSender());
614
            $attachment->addUserLink($message->getUserReceiver());
615
            $em->flush();
616
617
            return true;
618
        }
619
620
        return false;
621
    }
622
623
    /**
624
     * get messages by group id.
625
     *
626
     * @param int $group_id group id
627
     *
628
     * @return array
629
     */
630
    public static function get_messages_by_group($group_id)
631
    {
632
        $group_id = (int) $group_id;
633
634
        if (empty($group_id)) {
635
            return false;
636
        }
637
638
        $table = Database::get_main_table(TABLE_MESSAGE);
639
        $sql = "SELECT * FROM $table
640
                WHERE
641
                    group_id= $group_id AND
642
                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
643
                ORDER BY id";
644
        $rs = Database::query($sql);
645
        $data = [];
646
        if (Database::num_rows($rs) > 0) {
647
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
648
                $data[] = $row;
649
            }
650
        }
651
652
        return $data;
653
    }
654
655
    /**
656
     * get messages by group id.
657
     *
658
     * @param int $group_id
659
     * @param int $message_id
660
     *
661
     * @return array
662
     */
663
    public static function get_messages_by_group_by_message($group_id, $message_id)
664
    {
665
        $group_id = (int) $group_id;
666
667
        if (empty($group_id)) {
668
            return false;
669
        }
670
671
        $table = Database::get_main_table(TABLE_MESSAGE);
672
        $sql = "SELECT * FROM $table
673
                WHERE
674
                    group_id = $group_id AND
675
                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
676
                ORDER BY id ";
677
678
        $rs = Database::query($sql);
679
        $data = [];
680
        $parents = [];
681
        if (Database::num_rows($rs) > 0) {
682
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
683
                if ($message_id == $row['parent_id'] || in_array($row['parent_id'], $parents)) {
684
                    $parents[] = $row['id'];
685
                    $data[] = $row;
686
                }
687
            }
688
        }
689
690
        return $data;
691
    }
692
693
    /**
694
     * Get messages by parent id optionally with limit.
695
     *
696
     * @param  int        parent id
697
     * @param  int        group id (optional)
698
     * @param  int        offset (optional)
699
     * @param  int        limit (optional)
700
     *
701
     * @return array
702
     */
703
    public static function getMessagesByParent($parentId, $groupId = 0, $offset = 0, $limit = 0)
704
    {
705
        $table = Database::get_main_table(TABLE_MESSAGE);
706
        $parentId = (int) $parentId;
707
708
        if (empty($parentId)) {
709
            return [];
710
        }
711
712
        $condition_group_id = '';
713
        if (!empty($groupId)) {
714
            $groupId = (int) $groupId;
715
            $condition_group_id = " AND group_id = '$groupId' ";
716
        }
717
718
        $condition_limit = '';
719
        if ($offset && $limit) {
720
            $offset = (int) $offset;
721
            $limit = (int) $limit;
722
            $offset = ($offset - 1) * $limit;
723
            $condition_limit = " LIMIT $offset,$limit ";
724
        }
725
726
        $sql = "SELECT * FROM $table
727
                WHERE
728
                    parent_id='$parentId' AND
729
                    msg_status NOT IN (".MESSAGE_STATUS_OUTBOX.", ".MESSAGE_STATUS_WALL_DELETE.")
730
                    $condition_group_id
731
                ORDER BY send_date DESC $condition_limit ";
732
        $rs = Database::query($sql);
733
        $data = [];
734
        if (Database::num_rows($rs) > 0) {
735
            while ($row = Database::fetch_array($rs)) {
736
                $data[$row['id']] = $row;
737
            }
738
        }
739
740
        return $data;
741
    }
742
743
    /**
744
     * Displays messages of a group with nested view.
745
     *
746
     * @param int $groupId
747
     *
748
     * @return string
749
     */
750
    public static function display_messages_for_group($groupId)
751
    {
752
        global $my_group_role;
753
754
        $rows = self::get_messages_by_group($groupId);
755
        $topics_per_page = 10;
756
        $html_messages = '';
757
        $query_vars = ['id' => $groupId, 'topics_page_nr' => 0];
758
759
        if (is_array($rows) && count($rows) > 0) {
760
            // prepare array for topics with its items
761
            $topics = [];
762
            $x = 0;
763
            foreach ($rows as $index => $value) {
764
                if (empty($value['parent_id'])) {
765
                    $topics[$value['id']] = $value;
766
                }
767
            }
768
769
            $new_topics = [];
770
771
            foreach ($topics as $id => $value) {
772
                $rows = null;
773
                $rows = self::get_messages_by_group_by_message($groupId, $value['id']);
774
                if (!empty($rows)) {
775
                    $count = count(self::calculate_children($rows, $value['id']));
776
                } else {
777
                    $count = 0;
778
                }
779
                $value['count'] = $count;
780
                $new_topics[$id] = $value;
781
            }
782
783
            $array_html = [];
784
            foreach ($new_topics as $index => $topic) {
785
                $html = '';
786
                // topics
787
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
788
                $name = $user_sender_info['complete_name'];
789
                $html .= '<div class="groups-messages">';
790
                $html .= '<div class="row">';
791
792
                $items = $topic['count'];
793
                $reply_label = (1 == $items) ? get_lang('Reply') : get_lang('Replies');
794
                $label = '<i class="fa fa-envelope"></i> '.$items.' '.$reply_label;
795
                $topic['title'] = trim($topic['title']);
796
797
                if (empty($topic['title'])) {
798
                    $topic['title'] = get_lang('Untitled');
799
                }
800
801
                $html .= '<div class="col-xs-8 col-md-10">';
802
                $html .= Display::tag(
803
                    'h4',
804
                    Display::url(
805
                        Security::remove_XSS($topic['title'], STUDENT, true),
806
                        api_get_path(WEB_CODE_PATH).'social/group_topics.php?id='.$groupId.'&topic_id='.$topic['id']
807
                    ),
808
                    ['class' => 'title']
809
                );
810
                $actions = '';
811
                if (GROUP_USER_PERMISSION_ADMIN == $my_group_role ||
812
                    GROUP_USER_PERMISSION_MODERATOR == $my_group_role
813
                ) {
814
                    $actions = '<br />'.Display::url(
815
                            get_lang('Delete'),
816
                            api_get_path(
817
                                WEB_CODE_PATH
818
                            ).'social/group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic['id'],
819
                            ['class' => 'btn btn-default']
820
                        );
821
                }
822
823
                $date = '';
824
                if ($topic['send_date'] != $topic['update_date']) {
825
                    if (!empty($topic['update_date'])) {
826
                        $date .= '<i class="fa fa-calendar"></i> '.get_lang(
827
                                'LastUpdate'
828
                            ).' '.Display::dateToStringAgoAndLongDate($topic['update_date']);
829
                    }
830
                } else {
831
                    $date .= '<i class="fa fa-calendar"></i> '.get_lang(
832
                            'Created'
833
                        ).' '.Display::dateToStringAgoAndLongDate($topic['send_date']);
834
                }
835
                $html .= '<div class="date">'.$label.' - '.$date.$actions.'</div>';
836
                $html .= '</div>';
837
838
                $image = $user_sender_info['avatar'];
839
840
                $user_info = '<div class="author"><img class="img-responsive img-circle" src="'.$image.'" alt="'.$name.'"  width="64" height="64" title="'.$name.'" /></div>';
841
                $user_info .= '<div class="name"><a href="'.api_get_path(
842
                        WEB_PATH
843
                    ).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp;</a></div>';
844
845
                $html .= '<div class="col-xs-4 col-md-2">';
846
                $html .= $user_info;
847
                $html .= '</div>';
848
                $html .= '</div>';
849
                $html .= '</div>';
850
851
                $array_html[] = [$html];
852
            }
853
854
            // grids for items and topics  with paginations
855
            $html_messages .= Display::return_sortable_grid(
856
                'topics',
857
                [],
858
                $array_html,
859
                [
860
                    'hide_navigation' => false,
861
                    'per_page' => $topics_per_page,
862
                ],
863
                $query_vars,
864
                false,
865
                [true, true, true, false],
866
                false
867
            );
868
        }
869
870
        return $html_messages;
871
    }
872
873
    /**
874
     * Displays messages of a group with nested view.
875
     *
876
     * @param $groupId
877
     * @param $topic_id
878
     *
879
     * @return string
880
     */
881
    public static function display_message_for_group($groupId, $topic_id)
882
    {
883
        global $my_group_role;
884
        $main_message = self::get_message_by_id($topic_id);
885
        if (empty($main_message)) {
886
            return false;
887
        }
888
889
        $webCodePath = api_get_path(WEB_CODE_PATH);
890
        $iconCalendar = Display::returnFontAwesomeIcon('calendar');
891
892
        $langEdit = get_lang('Edit');
893
        $langReply = get_lang('Reply');
894
        $langLastUpdated = get_lang('LastUpdated');
895
        $langCreated = get_lang('Created');
896
897
        $rows = self::get_messages_by_group_by_message($groupId, $topic_id);
898
        $rows = self::calculate_children($rows, $topic_id);
899
        $current_user_id = api_get_user_id();
900
901
        $items_per_page = 50;
902
        $query_vars = ['id' => $groupId, 'topic_id' => $topic_id, 'topics_page_nr' => 0];
903
904
        // Main message
905
        $links = '';
906
        $main_content = '';
907
        $html = '';
908
        $items_page_nr = null;
909
910
        $user_sender_info = api_get_user_info($main_message['user_sender_id']);
911
        $filesAttachments = self::getAttachmentLinkList($main_message['id'], 0);
912
        $name = $user_sender_info['complete_name'];
913
914
        $topic_page_nr = isset($_GET['topics_page_nr']) ? (int) $_GET['topics_page_nr'] : null;
915
916
        $links .= '<div class="pull-right">';
917
        $links .= '<div class="btn-group btn-group-sm">';
918
919
        if ((GROUP_USER_PERMISSION_ADMIN == $my_group_role || GROUP_USER_PERMISSION_MODERATOR == $my_group_role) ||
920
            $main_message['user_sender_id'] == $current_user_id
921
        ) {
922
            $urlEdit = $webCodePath.'social/message_for_group_form.inc.php?'
923
                .http_build_query(
924
                    [
925
                        'user_friend' => $current_user_id,
926
                        'group_id' => $groupId,
927
                        'message_id' => $main_message['id'],
928
                        'action' => 'edit_message_group',
929
                        'anchor_topic' => 'topic_'.$main_message['id'],
930
                        'topics_page_nr' => $topic_page_nr,
931
                        'items_page_nr' => $items_page_nr,
932
                        'topic_id' => $main_message['id'],
933
                    ]
934
                );
935
936
            $links .= Display::toolbarButton(
937
                $langEdit,
938
                $urlEdit,
939
                'pencil',
940
                'default',
941
                ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'],
942
                false
943
            );
944
        }
945
946
        $links .= self::getLikesButton($main_message['id'], $current_user_id, $groupId);
947
948
        $urlReply = $webCodePath.'social/message_for_group_form.inc.php?'
949
            .http_build_query(
950
                [
951
                    'user_friend' => $current_user_id,
952
                    'group_id' => $groupId,
953
                    'message_id' => $main_message['id'],
954
                    'action' => 'reply_message_group',
955
                    'anchor_topic' => 'topic_'.$main_message['id'],
956
                    'topics_page_nr' => $topic_page_nr,
957
                    'topic_id' => $main_message['id'],
958
                ]
959
            );
960
961
        $links .= Display::toolbarButton(
962
            $langReply,
963
            $urlReply,
964
            'commenting',
965
            'default',
966
            ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'],
967
            false
968
        );
969
970
        if (api_is_platform_admin()) {
971
            $links .= Display::toolbarButton(
972
                get_lang('Delete'),
973
                'group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic_id,
974
                'trash',
975
                'default',
976
                [],
977
                false
978
            );
979
        }
980
981
        $links .= '</div>';
982
        $links .= '</div>';
983
984
        $title = '<h4>'.Security::remove_XSS($main_message['title'], STUDENT, true).$links.'</h4>';
985
986
        $userPicture = $user_sender_info['avatar'];
987
        $main_content .= '<div class="row">';
988
        $main_content .= '<div class="col-md-2">';
989
        $main_content .= '<div class="avatar-author">';
990
        $main_content .= Display::img(
991
            $userPicture,
992
            $name,
993
            ['width' => '60px', 'class' => 'img-responsive img-circle'],
994
            false
995
        );
996
        $main_content .= '</div>';
997
        $main_content .= '</div>';
998
999
        $date = '';
1000
        if ($main_message['send_date'] != $main_message['update_date']) {
1001
            if (!empty($main_message['update_date'])) {
1002
                $date = '<div class="date"> '
1003
                    ."$iconCalendar $langLastUpdated "
1004
                    .Display::dateToStringAgoAndLongDate($main_message['update_date'])
1005
                    .'</div>';
1006
            }
1007
        } else {
1008
            $date = '<div class="date"> '
1009
                ."$iconCalendar $langCreated "
1010
                .Display::dateToStringAgoAndLongDate($main_message['send_date'])
1011
                .'</div>';
1012
        }
1013
        $attachment = '<div class="message-attach">'
1014
            .(!empty($filesAttachments) ? implode('<br />', $filesAttachments) : '')
1015
            .'</div>';
1016
        $main_content .= '<div class="col-md-10">';
1017
        $user_link = Display::url(
1018
            $name,
1019
            $webCodePath.'social/profile.php?u='.$main_message['user_sender_id']
1020
        );
1021
        $main_content .= '<div class="message-content"> ';
1022
        $main_content .= '<div class="username">'.$user_link.'</div>';
1023
        $main_content .= $date;
1024
        $main_content .= '<div class="message">'.$main_message['content'].$attachment.'</div></div>';
1025
        $main_content .= '</div>';
1026
        $main_content .= '</div>';
1027
1028
        $html .= Display::div(
1029
            Display::div(
1030
                $title.$main_content,
1031
                ['class' => 'message-topic']
1032
            ),
1033
            ['class' => 'sm-groups-message']
1034
        );
1035
1036
        $topic_id = $main_message['id'];
1037
1038
        if (is_array($rows) && count($rows) > 0) {
1039
            $topics = $rows;
1040
            $array_html_items = [];
1041
1042
            foreach ($topics as $index => $topic) {
1043
                if (empty($topic['id'])) {
1044
                    continue;
1045
                }
1046
                $items_page_nr = isset($_GET['items_'.$topic['id'].'_page_nr'])
1047
                    ? (int) $_GET['items_'.$topic['id'].'_page_nr']
1048
                    : null;
1049
                $links = '';
1050
                $links .= '<div class="pull-right">';
1051
                $html_items = '';
1052
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
1053
                $filesAttachments = self::getAttachmentLinkList($topic['id'], 0);
1054
                $name = $user_sender_info['complete_name'];
1055
1056
                $links .= '<div class="btn-group btn-group-sm">';
1057
                if (
1058
                    (GROUP_USER_PERMISSION_ADMIN == $my_group_role ||
1059
                        GROUP_USER_PERMISSION_MODERATOR == $my_group_role
1060
                    ) ||
1061
                    $topic['user_sender_id'] == $current_user_id
1062
                ) {
1063
                    $links .= Display::toolbarButton(
1064
                        $langEdit,
1065
                        $webCodePath.'social/message_for_group_form.inc.php?'
1066
                            .http_build_query(
1067
                                [
1068
                                    'user_friend' => $current_user_id,
1069
                                    'group_id' => $groupId,
1070
                                    'message_id' => $topic['id'],
1071
                                    'action' => 'edit_message_group',
1072
                                    'anchor_topic' => 'topic_'.$topic_id,
1073
                                    'topics_page_nr' => $topic_page_nr,
1074
                                    'items_page_nr' => $items_page_nr,
1075
                                    'topic_id' => $topic_id,
1076
                                ]
1077
                            ),
1078
                        'pencil',
1079
                        'default',
1080
                        ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'],
1081
                        false
1082
                    );
1083
                }
1084
1085
                $links .= self::getLikesButton($topic['id'], $current_user_id, $groupId);
1086
1087
                $links .= Display::toolbarButton(
1088
                    $langReply,
1089
                    $webCodePath.'social/message_for_group_form.inc.php?'
1090
                        .http_build_query(
1091
                            [
1092
                                'user_friend' => $current_user_id,
1093
                                'group_id' => $groupId,
1094
                                'message_id' => $topic['id'],
1095
                                'action' => 'reply_message_group',
1096
                                'anchor_topic' => 'topic_'.$topic_id,
1097
                                'topics_page_nr' => $topic_page_nr,
1098
                                'items_page_nr' => $items_page_nr,
1099
                                'topic_id' => $topic_id,
1100
                            ]
1101
                        ),
1102
                    'commenting',
1103
                    'default',
1104
                    ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'],
1105
                    false
1106
                );
1107
                $links .= '</div>';
1108
                $links .= '</div>';
1109
1110
                $userPicture = $user_sender_info['avatar'];
1111
                $user_link = Display::url(
1112
                    $name,
1113
                    $webCodePath.'social/profile.php?u='.$topic['user_sender_id']
1114
                );
1115
                $html_items .= '<div class="row">';
1116
                $html_items .= '<div class="col-md-2">';
1117
                $html_items .= '<div class="avatar-author">';
1118
                $html_items .= Display::img(
1119
                    $userPicture,
1120
                    $name,
1121
                    ['width' => '60px', 'class' => 'img-responsive img-circle'],
1122
                    false
1123
                );
1124
                $html_items .= '</div>';
1125
                $html_items .= '</div>';
1126
1127
                $date = '';
1128
                if ($topic['send_date'] != $topic['update_date']) {
1129
                    if (!empty($topic['update_date'])) {
1130
                        $date = '<div class="date"> '
1131
                            ."$iconCalendar $langLastUpdated "
1132
                            .Display::dateToStringAgoAndLongDate($topic['update_date'])
1133
                            .'</div>';
1134
                    }
1135
                } else {
1136
                    $date = '<div class="date"> '
1137
                        ."$iconCalendar $langCreated "
1138
                        .Display::dateToStringAgoAndLongDate($topic['send_date'])
1139
                        .'</div>';
1140
                }
1141
                $attachment = '<div class="message-attach">'
1142
                    .(!empty($filesAttachments) ? implode('<br />', $filesAttachments) : '')
1143
                    .'</div>';
1144
                $html_items .= '<div class="col-md-10">'
1145
                    .'<div class="message-content">'
1146
                    .$links
1147
                    .'<div class="username">'.$user_link.'</div>'
1148
                    .$date
1149
                    .'<div class="message">'
1150
                    .Security::remove_XSS($topic['content'], STUDENT, true)
1151
                    .'</div>'.$attachment.'</div>'
1152
                    .'</div>'
1153
                    .'</div>';
1154
1155
                $base_padding = 20;
1156
1157
                if (0 == $topic['indent_cnt']) {
1158
                    $indent = $base_padding;
1159
                } else {
1160
                    $indent = (int) $topic['indent_cnt'] * $base_padding + $base_padding;
1161
                }
1162
1163
                $html_items = Display::div($html_items, ['class' => 'message-post', 'id' => 'msg_'.$topic['id']]);
1164
                $html_items = Display::div($html_items, ['class' => '', 'style' => 'margin-left:'.$indent.'px']);
1165
                $array_html_items[] = [$html_items];
1166
            }
1167
1168
            // grids for items with paginations
1169
            $options = ['hide_navigation' => false, 'per_page' => $items_per_page];
1170
            $visibility = [true, true, true, false];
1171
1172
            $style_class = [
1173
                'item' => ['class' => 'user-post'],
1174
                'main' => ['class' => 'user-list'],
1175
            ];
1176
            if (!empty($array_html_items)) {
1177
                $html .= Display::return_sortable_grid(
1178
                    'items_'.$topic['id'],
1179
                    [],
1180
                    $array_html_items,
1181
                    $options,
1182
                    $query_vars,
1183
                    null,
1184
                    $visibility,
1185
                    false,
1186
                    $style_class
1187
                );
1188
            }
1189
        }
1190
1191
        return $html;
1192
    }
1193
1194
    /**
1195
     * Add children to messages by id is used for nested view messages.
1196
     *
1197
     * @param array $rows rows of messages
1198
     *
1199
     * @return array $first_seed new list adding the item children
1200
     */
1201
    public static function calculate_children($rows, $first_seed)
1202
    {
1203
        $rows_with_children = [];
1204
        foreach ($rows as $row) {
1205
            $rows_with_children[$row["id"]] = $row;
1206
            $rows_with_children[$row["parent_id"]]["children"][] = $row["id"];
1207
        }
1208
        $rows = $rows_with_children;
1209
        $sorted_rows = [0 => []];
1210
        self::message_recursive_sort($rows, $sorted_rows, $first_seed);
1211
        unset($sorted_rows[0]);
1212
1213
        return $sorted_rows;
1214
    }
1215
1216
    /**
1217
     * Sort recursively the messages, is used for for nested view messages.
1218
     *
1219
     * @param array  original rows of messages
1220
     * @param array  list recursive of messages
1221
     * @param int   seed for calculate the indent
1222
     * @param int   indent for nested view
1223
     */
1224
    public static function message_recursive_sort(
1225
        $rows,
1226
        &$messages,
1227
        $seed = 0,
1228
        $indent = 0
1229
    ) {
1230
        if ($seed > 0 && isset($rows[$seed]["id"])) {
1231
            $messages[$rows[$seed]["id"]] = $rows[$seed];
1232
            $messages[$rows[$seed]["id"]]["indent_cnt"] = $indent;
1233
            $indent++;
1234
        }
1235
1236
        if (isset($rows[$seed]["children"])) {
1237
            foreach ($rows[$seed]["children"] as $child) {
1238
                self::message_recursive_sort($rows, $messages, $child, $indent);
1239
            }
1240
        }
1241
    }
1242
1243
    /**
1244
     * Get array of links (download) for message attachment files.
1245
     *
1246
     * @return array
1247
     */
1248
    public static function getAttachmentLinkList(Message $message)
1249
    {
1250
        $files = $message->getAttachments();
1251
        // get file attachments by message id
1252
        $list = [];
1253
        if ($files) {
0 ignored issues
show
introduced by
$files is of type Doctrine\Common\Collections\Collection, thus it always evaluated to true.
Loading history...
1254
            $attachIcon = Display::returnFontAwesomeIcon('paperclip');
1255
            $repo = Container::getMessageAttachmentRepository();
1256
            foreach ($files as $file) {
1257
                $size = format_file_size($file->getSize());
1258
                $comment = Security::remove_XSS($file->getComment());
1259
                $filename = Security::remove_XSS($file->getFilename());
1260
                $url = $repo->getResourceFileUrl($file);
1261
                $link = Display::url($filename, $url);
1262
                $comment = !empty($comment) ? '&nbsp;-&nbsp;<i>'.$comment.'</i>' : '';
1263
1264
                $attachmentLine = $attachIcon.'&nbsp;'.$link.'&nbsp;('.$size.')'.$comment;
1265
                /*if ('audio_message' === $file['comment']) {
1266
                    $attachmentLine = '<audio src="'.$archiveURL.$archiveFile.'"/>';
1267
                }*/
1268
                $list[] = $attachmentLine;
1269
            }
1270
        }
1271
1272
        return $list;
1273
    }
1274
1275
    /**
1276
     * Get message list by id.
1277
     *
1278
     * @param int $messageId
1279
     *
1280
     * @return array
1281
     */
1282
    public static function get_message_by_id($messageId)
1283
    {
1284
        $table = Database::get_main_table(TABLE_MESSAGE);
1285
        $messageId = (int) $messageId;
1286
        $sql = "SELECT * FROM $table
1287
                WHERE
1288
                    id = '$messageId' AND
1289
                    msg_status <> '".MESSAGE_STATUS_DELETED."' ";
1290
        $res = Database::query($sql);
1291
        $item = [];
1292
        if (Database::num_rows($res) > 0) {
1293
            $item = Database::fetch_array($res, 'ASSOC');
1294
        }
1295
1296
        return $item;
1297
    }
1298
1299
    /**
1300
     * @return string
1301
     */
1302
    public static function generate_message_form()
1303
    {
1304
        $form = new FormValidator('send_message');
1305
        $form->addText(
1306
            'subject',
1307
            get_lang('Subject'),
1308
            false,
1309
            ['id' => 'subject_id']
1310
        );
1311
        $form->addTextarea(
1312
            'content',
1313
            get_lang('Message'),
1314
            ['id' => 'content_id', 'rows' => '5']
1315
        );
1316
1317
        return $form->returnForm();
1318
    }
1319
1320
    /**
1321
     * @return string
1322
     */
1323
    public static function generate_invitation_form()
1324
    {
1325
        $form = new FormValidator('send_invitation');
1326
        $form->addTextarea(
1327
            'content',
1328
            get_lang('Add a personal message'),
1329
            ['id' => 'content_invitation_id', 'rows' => 5]
1330
        );
1331
1332
        return $form->returnForm();
1333
    }
1334
1335
    /**
1336
     * @param string $type
1337
     * @param string $keyword
1338
     * @param array  $actions
1339
     *
1340
     * @return string
1341
     */
1342
    public static function getMessageGrid($type, $keyword, $actions = [])
1343
    {
1344
        $html = '';
1345
        // display sortable table with messages of the current user
1346
        $table = new SortableTable(
1347
            'message_inbox',
1348
            ['MessageManager', 'getNumberOfMessages'],
1349
            ['MessageManager', 'getMessageData'],
1350
            2,
1351
            20,
1352
            'DESC'
1353
        );
1354
        $table->setDataFunctionParams(
1355
            ['keyword' => $keyword, 'type' => $type, 'actions' => $actions]
1356
        );
1357
        $table->set_header(0, '', false, ['style' => 'width:15px;']);
1358
        $table->set_header(1, get_lang('Messages'), false);
1359
        $table->set_header(2, get_lang('Date'), true, ['style' => 'width:180px;']);
1360
        $table->set_header(3, get_lang('Edit'), false, ['style' => 'width:120px;']);
1361
1362
        if (isset($_REQUEST['f']) && 'social' === $_REQUEST['f']) {
1363
            $parameters['f'] = 'social';
1364
            $table->set_additional_parameters($parameters);
1365
        }
1366
1367
        $defaultActions = [
1368
            'delete' => get_lang('Delete selected messages'),
1369
            'mark_as_unread' => get_lang('Mark as unread'),
1370
            'mark_as_read' => get_lang('Mark as read'),
1371
        ];
1372
1373
        if (!in_array('delete', $actions)) {
1374
            unset($defaultActions['delete']);
1375
        }
1376
        if (!in_array('mark_as_unread', $actions)) {
1377
            unset($defaultActions['mark_as_unread']);
1378
        }
1379
        if (!in_array('mark_as_read', $actions)) {
1380
            unset($defaultActions['mark_as_read']);
1381
        }
1382
1383
        $table->set_form_actions($defaultActions);
1384
1385
        $html .= $table->return_table();
1386
1387
        return $html;
1388
    }
1389
1390
    /**
1391
     * @param string $url
1392
     *
1393
     * @return FormValidator
1394
     */
1395
    public static function getSearchForm($url)
1396
    {
1397
        $form = new FormValidator(
1398
            'search',
1399
            'post',
1400
            $url,
1401
            null,
1402
            [],
1403
            FormValidator::LAYOUT_INLINE
1404
        );
1405
1406
        $form->addElement(
1407
            'text',
1408
            'keyword',
1409
            false,
1410
            [
1411
                'aria-label' => get_lang('Search'),
1412
            ]
1413
        );
1414
        $form->addButtonSearch(get_lang('Search'));
1415
1416
        return $form;
1417
    }
1418
1419
    /**
1420
     * Send a notification to all admins when a new user is registered.
1421
     */
1422
    public static function sendNotificationOfNewRegisteredUser(User $user)
1423
    {
1424
        $tplMailBody = new Template(
1425
            null,
1426
            false,
1427
            false,
1428
            false,
1429
            false,
1430
            false,
1431
            false
1432
        );
1433
        $tplMailBody->assign('user', $user);
1434
        $tplMailBody->assign('is_western_name_order', api_is_western_name_order());
1435
        $tplMailBody->assign(
1436
            'manageUrl',
1437
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$user->getId()
1438
        );
1439
1440
        $layoutContent = $tplMailBody->get_template('mail/new_user_mail_to_admin.tpl');
1441
1442
        $emailsubject = '['.get_lang('The user has been registered').'] '.$user->getUsername();
1443
        $emailbody = $tplMailBody->fetch($layoutContent);
1444
1445
        $admins = UserManager::get_all_administrators();
1446
1447
        foreach ($admins as $admin_info) {
1448
            self::send_message(
1449
                $admin_info['user_id'],
1450
                $emailsubject,
1451
                $emailbody,
1452
                [],
1453
                [],
1454
                null,
1455
                null,
1456
                null,
1457
                null,
1458
                $user->getId()
1459
            );
1460
        }
1461
    }
1462
1463
    /**
1464
     * Send a notification to all admins when a new user is registered
1465
     * while the approval method is used for users registration.
1466
     */
1467
    public static function sendNotificationOfNewRegisteredUserApproval(User $user)
1468
    {
1469
        $tplMailBody = new Template(
1470
            null,
1471
            false,
1472
            false,
1473
            false,
1474
            false,
1475
            false,
1476
            false
1477
        );
1478
        $tplMailBody->assign('user', $user);
1479
        $tplMailBody->assign('is_western_name_order', api_is_western_name_order());
1480
        $userId = $user->getId();
1481
        $url_edit = Display::url(
1482
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$userId,
1483
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$userId
1484
        );
1485
        $tplMailBody->assign(
1486
            'manageUrl',
1487
            $url_edit
1488
        );
1489
        // Get extra field values for this user and reformat the array
1490
        $extraFieldValues = new ExtraFieldValue('user');
1491
        $userExtraFields = $extraFieldValues->getAllValuesByItem($userId);
1492
        $values = [];
1493
        foreach ($userExtraFields as $field => $value) {
1494
            $values[$value['variable']] = $value['value'];
1495
        }
1496
        $tplMailBody->assign(
1497
            'extra',
1498
            $values
1499
        );
1500
        $layoutContent = '';
1501
        $emailbody = '';
1502
        if (true == api_get_configuration_value('mail_template_system')) {
1503
            $mailTemplateManager = new MailTemplateManager();
1504
            $templateText = $mailTemplateManager->getTemplateByType('new_user_mail_to_admin_approval.tpl');
1505
            if (empty($templateText)) {
1506
            } else {
1507
                // custom procedure to load a template as a string (doesn't use cache so may slow down)
1508
                $template = $tplMailBody->twig->createTemplate($templateText);
1509
                $emailbody = $template->render($tplMailBody->params);
1510
            }
1511
        }
1512
        if (empty($emailbody)) {
1513
            $layoutContent = $tplMailBody->get_template('mail/new_user_mail_to_admin_approval.tpl');
1514
            $emailbody = $tplMailBody->fetch($layoutContent);
1515
        }
1516
1517
        $emailsubject = '['.get_lang('ApprovalForNewAccount').'] '.$user->getUsername();
1518
1519
        if (api_get_configuration_value('send_inscription_notification_to_general_admin_only')) {
1520
            $email = api_get_setting('emailAdministrator');
1521
            $firstname = api_get_setting('administratorSurname');
1522
            $lastname = api_get_setting('administratorName');
1523
            api_mail_html("$firstname $lastname", $email, $emailsubject, $emailbody);
1524
        } else {
1525
            $admins = UserManager::get_all_administrators();
1526
            foreach ($admins as $admin_info) {
1527
                self::send_message(
1528
                    $admin_info['user_id'],
1529
                    $emailsubject,
1530
                    $emailbody,
1531
                    [],
1532
                    [],
1533
                    null,
1534
                    null,
1535
                    null,
1536
                    null,
1537
                    $userId
1538
                );
1539
            }
1540
        }
1541
    }
1542
1543
    /**
1544
     * Get the error log from failed mailing
1545
     * This assumes a complex setup where you have a cron script regularly copying the mail queue log
1546
     * into app/cache/mail/mailq.
1547
     * This can be done with a cron command like (check the location of your mail log file first):.
1548
     *
1549
     * @example 0,30 * * * * root cp /var/log/exim4/mainlog /var/www/chamilo/app/cache/mail/mailq
1550
     *
1551
     * @return array|bool
1552
     */
1553
    public static function failedSentMailErrors()
1554
    {
1555
        $base = api_get_path(SYS_ARCHIVE_PATH).'mail/';
1556
        $mailq = $base.'mailq';
1557
1558
        if (!file_exists($mailq) || !is_readable($mailq)) {
1559
            return false;
1560
        }
1561
1562
        $file = fopen($mailq, 'r');
1563
        $i = 1;
1564
        while (!feof($file)) {
1565
            $line = fgets($file);
1566
1567
            if ('' == trim($line)) {
1568
                continue;
1569
            }
1570
1571
            // Get the mail code, something like 1WBumL-0002xg-FF
1572
            if (preg_match('/(.*)\s((.*)-(.*)-(.*))\s<(.*)$/', $line, $codeMatches)) {
1573
                $mail_queue[$i]['code'] = $codeMatches[2];
1574
            }
1575
1576
            $fullMail = $base.$mail_queue[$i]['code'];
1577
            $mailFile = fopen($fullMail, 'r');
1578
1579
            // Get the reason of mail fail
1580
            $iX = 1;
1581
            while (!feof($mailFile)) {
1582
                $mailLine = fgets($mailFile);
1583
                //if ($iX == 4 && preg_match('/(.*):\s(.*)$/', $mailLine, $matches)) {
1584
                if (2 == $iX &&
1585
                    preg_match('/(.*)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s(.*)/', $mailLine, $detailsMatches)
1586
                ) {
1587
                    $mail_queue[$i]['reason'] = $detailsMatches[3];
1588
                }
1589
                $iX++;
1590
            }
1591
1592
            fclose($mailFile);
1593
1594
            // Get the time of mail fail
1595
            if (preg_match('/^\s?(\d+)(\D+)\s+(.*)$/', $line, $timeMatches)) {
1596
                $mail_queue[$i]['time'] = $timeMatches[1].$timeMatches[2];
1597
            } elseif (preg_match('/^(\s+)((.*)@(.*))\s+(.*)$/', $line, $emailMatches)) {
1598
                $mail_queue[$i]['mail'] = $emailMatches[2];
1599
                $i++;
1600
            }
1601
        }
1602
1603
        fclose($file);
1604
1605
        return array_reverse($mail_queue);
1606
    }
1607
1608
    /**
1609
     * @param int $userId
1610
     *
1611
     * @return array
1612
     */
1613
    public static function getUsersThatHadConversationWithUser($userId)
1614
    {
1615
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
1616
        $userId = (int) $userId;
1617
1618
        $sql = "SELECT DISTINCT
1619
                    user_sender_id
1620
                FROM $messagesTable
1621
                WHERE
1622
                    user_receiver_id = ".$userId;
1623
        $result = Database::query($sql);
1624
        $users = Database::store_result($result);
1625
        $userList = [];
1626
        foreach ($users as $userData) {
1627
            $userId = $userData['user_sender_id'];
1628
            if (empty($userId)) {
1629
                continue;
1630
            }
1631
            $userInfo = api_get_user_info($userId);
1632
            if ($userInfo) {
1633
                $userList[$userId] = $userInfo;
1634
            }
1635
        }
1636
1637
        return $userList;
1638
    }
1639
1640
    /**
1641
     * @param int $userId
1642
     * @param int $otherUserId
1643
     *
1644
     * @return array
1645
     */
1646
    public static function getAllMessagesBetweenStudents($userId, $otherUserId)
1647
    {
1648
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
1649
        $userId = (int) $userId;
1650
        $otherUserId = (int) $otherUserId;
1651
1652
        if (empty($otherUserId) || empty($userId)) {
1653
            return [];
1654
        }
1655
1656
        $sql = "SELECT DISTINCT *
1657
                FROM $messagesTable
1658
                WHERE
1659
                    (user_receiver_id = $userId AND user_sender_id = $otherUserId) OR
1660
                    (user_receiver_id = $otherUserId AND user_sender_id = $userId)
1661
                ORDER BY send_date DESC
1662
            ";
1663
        $result = Database::query($sql);
1664
        $messages = Database::store_result($result);
1665
        $list = [];
1666
        foreach ($messages as $message) {
1667
            $list[] = $message;
1668
        }
1669
1670
        return $list;
1671
    }
1672
1673
    /**
1674
     * @param string $subject
1675
     * @param string $message
1676
     * @param Course $course
1677
     * @param int    $sessionId
1678
     *
1679
     * @return bool
1680
     */
1681
    public static function sendMessageToAllUsersInCourse($subject, $message, Course $course, $sessionId = 0)
1682
    {
1683
        $senderId = api_get_user_id();
1684
        if (empty($senderId)) {
1685
            return false;
1686
        }
1687
        if (empty($sessionId)) {
1688
            // Course students and teachers
1689
            $users = CourseManager::get_user_list_from_course_code($course->getCode());
1690
        } else {
1691
            // Course-session students and course session coaches
1692
            $users = CourseManager::get_user_list_from_course_code($course->getCode(), $sessionId);
1693
        }
1694
1695
        if (empty($users)) {
1696
            return false;
1697
        }
1698
1699
        foreach ($users as $userInfo) {
1700
            self::send_message_simple(
1701
                $userInfo['user_id'],
1702
                $subject,
1703
                $message,
1704
                $senderId,
1705
                false,
1706
                false,
1707
                [],
1708
                false
1709
            );
1710
        }
1711
    }
1712
1713
    /**
1714
     * Clean audio messages already added in the message tool.
1715
     */
1716
    public static function cleanAudioMessage()
1717
    {
1718
        Session::erase('current_audio');
1719
    }
1720
1721
    /**
1722
     * @param int    $senderId
1723
     * @param string $subject
1724
     * @param string $message
1725
     */
1726
    public static function sendMessageToAllAdminUsers(
1727
        $senderId,
1728
        $subject,
1729
        $message
1730
    ) {
1731
        $admins = UserManager::get_all_administrators();
1732
        foreach ($admins as $admin) {
1733
            self::send_message_simple($admin['user_id'], $subject, $message, $senderId);
1734
        }
1735
    }
1736
1737
    /**
1738
     * @param int $messageId
1739
     * @param int $userId
1740
     *
1741
     * @return array
1742
     */
1743
    public static function countLikesAndDislikes($messageId, $userId)
1744
    {
1745
        if (!api_get_configuration_value('social_enable_messages_feedback')) {
1746
            return [];
1747
        }
1748
1749
        $messageId = (int) $messageId;
1750
        $userId = (int) $userId;
1751
1752
        $em = Database::getManager();
1753
        $query = $em
1754
            ->createQuery('
1755
                SELECT SUM(l.liked) AS likes, SUM(l.disliked) AS dislikes FROM ChamiloCoreBundle:MessageFeedback l
1756
                WHERE l.message = :message
1757
            ')
1758
            ->setParameters(['message' => $messageId]);
1759
1760
        try {
1761
            $counts = $query->getSingleResult();
1762
        } catch (Exception $e) {
1763
            $counts = ['likes' => 0, 'dislikes' => 0];
1764
        }
1765
1766
        $userLike = $em
1767
            ->getRepository(MessageFeedback::class)
1768
            ->findOneBy(['message' => $messageId, 'user' => $userId]);
1769
1770
        return [
1771
            'likes' => (int) $counts['likes'],
1772
            'dislikes' => (int) $counts['dislikes'],
1773
            'user_liked' => $userLike ? $userLike->isLiked() : false,
1774
            'user_disliked' => $userLike ? $userLike->isDisliked() : false,
1775
        ];
1776
    }
1777
1778
    /**
1779
     * @param int $messageId
1780
     * @param int $userId
1781
     * @param int $groupId   Optional.
1782
     *
1783
     * @return string
1784
     */
1785
    public static function getLikesButton($messageId, $userId, $groupId = 0)
1786
    {
1787
        if (!api_get_configuration_value('social_enable_messages_feedback')) {
1788
            return '';
1789
        }
1790
1791
        $countLikes = self::countLikesAndDislikes($messageId, $userId);
1792
1793
        $class = $countLikes['user_liked'] ? 'btn-primary' : 'btn-default';
1794
1795
        $btnLike = Display::button(
1796
            'like',
1797
            Display::returnFontAwesomeIcon('thumbs-up', '', true)
1798
                .PHP_EOL.'<span>'.$countLikes['likes'].'</span>',
1799
            [
1800
                'title' => get_lang('Like'),
1801
                'class' => 'btn  social-like '.$class,
1802
                'data-status' => 'like',
1803
                'data-message' => $messageId,
1804
                'data-group' => $groupId,
1805
            ]
1806
        );
1807
1808
        $btnDislike = '';
1809
        if (false === api_get_configuration_value('disable_dislike_option')) {
1810
            $disabled = $countLikes['user_disliked'] ? 'btn-danger' : 'btn-default';
1811
1812
            $btnDislike = Display::button(
1813
                'like',
1814
                Display::returnFontAwesomeIcon('thumbs-down', '', true)
1815
                .PHP_EOL.'<span>'.$countLikes['dislikes'].'</span>',
1816
                [
1817
                    'title' => get_lang('Dislike'),
1818
                    'class' => 'btn social-like '.$disabled,
1819
                    'data-status' => 'dislike',
1820
                    'data-message' => $messageId,
1821
                    'data-group' => $groupId,
1822
                ]
1823
            );
1824
        }
1825
1826
        return $btnLike.PHP_EOL.$btnDislike;
1827
    }
1828
}
1829