Passed
Push — master ( eb5904...054905 )
by Angel Fernando Quiroz
08:23
created

MessageManager::getAttachmentLinkList()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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