Passed
Pull Request — master (#5005)
by Yannick
12:54 queued 06:05
created

MessageManager::display_message_for_group()   F

Complexity

Conditions 23
Paths 145

Size

Total Lines 312
Code Lines 232

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 232
nc 145
nop 2
dl 0
loc 312
rs 3.0333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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:

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