Passed
Push — master ( e03d1a...85547e )
by
unknown
08:55 queued 13s
created

MessageManager::send_message_simple()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 55
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 33
c 0
b 0
f 0
nc 24
nop 8
dl 0
loc 55
rs 8.4586

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