Passed
Push — master ( ec308f...430c19 )
by Julito
08:35 queued 11s
created

MessageManager::get_messages_by_group()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 3
nop 1
dl 0
loc 23
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Course;
6
use Chamilo\CoreBundle\Entity\Message;
7
use Chamilo\CoreBundle\Entity\MessageAttachment;
8
use Chamilo\CoreBundle\Entity\MessageFeedback;
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Framework\Container;
11
use ChamiloSession as Session;
12
use Doctrine\Common\Collections\Criteria;
13
use Symfony\Component\HttpFoundation\File\UploadedFile;
14
15
class MessageManager
16
{
17
    public static function getMessagesAboutUserToString(User $user): string
18
    {
19
        $messages = Container::getMessageRepository()->getMessageByUser($user, Message::MESSAGE_TYPE_CONVERSATION);
20
        $html = '';
21
        if (!empty($messages)) {
22
            foreach ($messages as $message) {
23
                $tag = 'message_'.$message->getId();
24
                $tagAccordion = 'accordion_'.$message->getId();
25
                $tagCollapse = 'collapse_'.$message->getId();
26
                $date = Display::dateToStringAgoAndLongDate(
27
                    $message->getSendDate()
28
                );
29
                $localTime = api_get_local_time(
30
                    $message->getSendDate(),
31
                    null,
32
                    null,
33
                    false,
34
                    false
35
                );
36
                $sender = $message->getSender();
37
                $html .= Display::panelCollapse(
38
                    $localTime.' '.UserManager::formatUserFullName($sender).' '.$message->getTitle(),
39
                    $message->getContent().'<br />'.$date.'<br />'.get_lang(
40
                        'Author'
41
                    ).': '.$sender->getUsername(),
42
                    $tag,
43
                    null,
44
                    $tagAccordion,
45
                    $tagCollapse,
46
                    false
47
                );
48
            }
49
        }
50
51
        return $html;
52
    }
53
54
    /**
55
     * @param int    $senderId
56
     * @param int    $receiverId
57
     * @param string $subject
58
     * @param string $message
59
     *
60
     * @return bool
61
     */
62
    public static function messageWasAlreadySent($senderId, $receiverId, $subject, $message)
63
    {
64
        $tblMessage = Database::get_main_table(TABLE_MESSAGE);
65
        $senderId = (int) $senderId;
66
        $receiverId = (int) $receiverId;
67
        $subject = Database::escape_string($subject);
68
        $message = Database::escape_string($message);
69
70
        $sql = "SELECT m.id FROM $tblMessage m
71
                INNER JOIN message_rel_user mru on m.id = mru.message_id
72
                WHERE
73
                    m.user_sender_id = $senderId AND
74
                    mru.user_id = $receiverId AND
75
                    m.title = '$subject' AND
76
                    m.content = '$message' AND
77
                    m.msg_type = ".Message::MESSAGE_TYPE_INBOX."
78
                ";
79
        $result = Database::query($sql);
80
81
        return Database::num_rows($result) > 0;
82
    }
83
84
    /**
85
     * Sends a message to a user/group.
86
     *
87
     * @param int    $receiverUserId
88
     * @param string $subject
89
     * @param string $content
90
     * @param array  $attachments                files array($_FILES) (optional)
91
     * @param array  $fileCommentList            about attachment files (optional)
92
     * @param int    $group_id                   (optional)
93
     * @param int    $parent_id                  (optional)
94
     * @param int    $editMessageId              id for updating the message (optional)
95
     * @param int    $topic_id                   (optional) the default value is the current user_id
96
     * @param int    $sender_id
97
     * @param bool   $directMessage
98
     * @param int    $forwardId
99
     * @param bool   $checkCurrentAudioId
100
     * @param bool   $forceTitleWhenSendingEmail force the use of $title as subject instead of "You have a new message"
101
     *
102
     * @return bool
103
     */
104
    public static function send_message(
105
        $receiverUserId,
106
        $subject,
107
        $content,
108
        array $attachments = [],
109
        array $fileCommentList = [],
110
        $group_id = 0,
111
        $parent_id = 0,
112
        $editMessageId = 0,
113
        $topic_id = 0,
114
        $sender_id = 0,
115
        $directMessage = false,
116
        $forwardId = 0,
117
        $checkCurrentAudioId = false,
118
        $forceTitleWhenSendingEmail = false,
119
    ) {
120
        $group_id = (int) $group_id;
121
        $receiverUserId = (int) $receiverUserId;
122
        $parent_id = (int) $parent_id;
123
        $editMessageId = (int) $editMessageId;
124
        $topic_id = (int) $topic_id;
125
        $user_sender_id = empty($sender_id) ? api_get_user_id() : (int) $sender_id;
126
127
        if (empty($user_sender_id) || empty($receiverUserId)) {
128
            return false;
129
        }
130
131
        $userSender = api_get_user_entity($user_sender_id);
132
        if (null === $userSender) {
133
            Display::addFlash(Display::return_message(get_lang('This user doesn\'t exist'), 'warning'));
134
135
            return false;
136
        }
137
138
        $userRecipient = api_get_user_entity($receiverUserId);
139
140
        if (null === $userRecipient) {
141
            return false;
142
        }
143
144
        // Disabling messages for inactive users.
145
        if (!$userRecipient->getActive()) {
146
            return false;
147
        }
148
149
        $sendEmail = true;
150
        // Disabling messages depending the pausetraining plugin.
151
        $allowPauseFormation =
152
            'true' === api_get_plugin_setting('pausetraining', 'tool_enable') &&
153
            'true' === api_get_plugin_setting('pausetraining', 'allow_users_to_edit_pause_formation');
154
155
        if ($allowPauseFormation) {
156
            $extraFieldValue = new ExtraFieldValue('user');
157
            $disableEmails = $extraFieldValue->get_values_by_handler_and_field_variable(
158
                $receiverUserId,
159
                'disable_emails'
160
            );
161
162
            // User doesn't want email notifications but chamilo inbox still available.
163
            if (!empty($disableEmails) &&
164
                isset($disableEmails['value']) && 1 === (int) $disableEmails['value']
165
            ) {
166
                $sendEmail = false;
167
            }
168
169
            if ($sendEmail) {
170
                // Check if user pause his formation.
171
                $pause = $extraFieldValue->get_values_by_handler_and_field_variable(
172
                    $receiverUserId,
173
                    'pause_formation'
174
                );
175
                if (!empty($pause) && isset($pause['value']) && 1 === (int) $pause['value']) {
176
                    $startDate = $extraFieldValue->get_values_by_handler_and_field_variable(
177
                        $receiverUserId,
178
                        'start_pause_date'
179
                    );
180
                    $endDate = $extraFieldValue->get_values_by_handler_and_field_variable(
181
                        $receiverUserId,
182
                        'end_pause_date'
183
                    );
184
185
                    if (!empty($startDate) && isset($startDate['value']) && !empty($startDate['value']) &&
186
                        !empty($endDate) && isset($endDate['value']) && !empty($endDate['value'])
187
                    ) {
188
                        $now = time();
189
                        $start = api_strtotime($startDate['value']);
190
                        $end = api_strtotime($endDate['value']);
191
192
                        if ($now > $start && $now < $end) {
193
                            $sendEmail = false;
194
                        }
195
                    }
196
                }
197
            }
198
        }
199
200
        $totalFileSize = 0;
201
        $attachmentList = [];
202
        if (is_array($attachments)) {
203
            $counter = 0;
204
            foreach ($attachments as $attachment) {
205
                $attachment['comment'] = $fileCommentList[$counter] ?? '';
206
                $fileSize = $attachment['size'] ?? 0;
207
                if (is_array($fileSize)) {
208
                    foreach ($fileSize as $size) {
209
                        $totalFileSize += $size;
210
                    }
211
                } else {
212
                    $totalFileSize += $fileSize;
213
                }
214
                $attachmentList[] = $attachment;
215
                $counter++;
216
            }
217
        }
218
219
        if ($checkCurrentAudioId) {
220
            // Add the audio file as an attachment
221
            $audio = Session::read('current_audio');
222
            if (!empty($audio) && isset($audio['name']) && !empty($audio['name'])) {
223
                $audio['comment'] = 'audio_message';
224
                // create attachment from audio message
225
                $attachmentList[] = $audio;
226
            }
227
        }
228
229
        // Validating fields
230
        if (empty($subject) && empty($group_id)) {
231
            Display::addFlash(
232
                Display::return_message(
233
                    get_lang('You should write a subject'),
234
                    'warning'
235
                )
236
            );
237
238
            return false;
239
        } elseif ($totalFileSize > (int) api_get_setting('message_max_upload_filesize')) {
240
            $warning = sprintf(
241
                get_lang('Files size exceeds'),
242
                format_file_size(api_get_setting('message_max_upload_filesize'))
243
            );
244
245
            Display::addFlash(Display::return_message($warning, 'warning'));
246
247
            return false;
248
        }
249
250
        $em = Database::getManager();
251
        $repo = $em->getRepository(Message::class);
252
        $parent = null;
253
        if (!empty($parent_id)) {
254
            $parent = $repo->find($parent_id);
255
        }
256
257
        // Just in case we replace the and \n and \n\r while saving in the DB
258
        if (!empty($receiverUserId) || !empty($group_id)) {
259
            // message for user friend
260
            //@todo it's possible to edit a message? yes, only for groups
261
            if (!empty($editMessageId)) {
262
                $message = $repo->find($editMessageId);
263
                if (null !== $message) {
264
                    $message->setContent($content);
265
                    $em->persist($message);
266
                    $em->flush();
267
                }
268
                $messageId = $editMessageId;
269
            } else {
270
                $message = (new Message())
271
                    ->setSender($userSender)
272
                    ->addReceiver($userRecipient)
273
                    ->setTitle($subject)
274
                    ->setContent($content)
275
                    ->setGroup(api_get_group_entity($group_id))
276
                    ->setParent($parent)
277
                ;
278
                $em->persist($message);
279
                $em->flush();
280
                $messageId = $message->getId();
281
            }
282
283
            // Forward also message attachments.
284
            if (!empty($forwardId)) {
285
                $forwardMessage = $repo->find($forwardId);
286
                if (null !== $forwardMessage) {
287
                    $forwardAttachments = $forwardMessage->getAttachments();
288
                    foreach ($forwardAttachments as $forwardAttachment) {
289
                        $message->addAttachment($forwardAttachment);
290
                    }
291
                    $em->persist($message);
292
                    $em->flush();
293
                }
294
            }
295
296
            // Save attachment file for inbox messages
297
            if (is_array($attachmentList)) {
298
                foreach ($attachmentList as $attachment) {
299
                    if (0 === $attachment['error']) {
300
                        self::saveMessageAttachmentFile(
301
                            $attachment,
302
                            $attachment['comment'] ?? '',
303
                            $message,
304
                        );
305
                    }
306
                }
307
            }
308
309
            if ($sendEmail) {
310
                $notification = new Notification();
311
                $sender_info = api_get_user_info($user_sender_id);
312
313
                // add file attachment additional attributes
314
                $attachmentAddedByMail = [];
315
                foreach ($attachmentList as $attachment) {
316
                    $attachmentAddedByMail[] = [
317
                        'path' => $attachment['tmp_name'],
318
                        'filename' => $attachment['name'],
319
                    ];
320
                }
321
322
                if (empty($group_id)) {
323
                    $type = Notification::NOTIFICATION_TYPE_MESSAGE;
324
                    if ($directMessage) {
325
                        $type = Notification::NOTIFICATION_TYPE_DIRECT_MESSAGE;
326
                    }
327
                    $notification->saveNotification(
328
                        $messageId,
329
                        $type,
330
                        [$receiverUserId],
331
                        $subject,
332
                        $content,
333
                        $sender_info,
334
                        $attachmentAddedByMail,
335
                        $forceTitleWhenSendingEmail
336
                    );
337
                } else {
338
                    $usergroup = new UserGroupModel();
339
                    $group_info = $usergroup->get($group_id);
340
                    $group_info['topic_id'] = $topic_id;
341
                    $group_info['msg_id'] = $messageId;
342
343
                    $user_list = $usergroup->get_users_by_group(
344
                        $group_id,
345
                        false,
346
                        [],
347
                        0,
348
                        1000
349
                    );
350
351
                    // Adding more sense to the message group
352
                    $subject = sprintf(get_lang('There is a new message in group %s'), $group_info['name']);
353
                    $new_user_list = [];
354
                    foreach ($user_list as $user_data) {
355
                        $new_user_list[] = $user_data['id'];
356
                    }
357
                    $group_info = [
358
                        'group_info' => $group_info,
359
                        'user_info' => $sender_info,
360
                    ];
361
                    $notification->saveNotification(
362
                        $messageId,
363
                        Notification::NOTIFICATION_TYPE_GROUP,
364
                        $new_user_list,
365
                        $subject,
366
                        $content,
367
                        $group_info,
368
                        $attachmentAddedByMail
369
                    );
370
                }
371
            }
372
373
            return $messageId;
374
        }
375
376
        return false;
377
    }
378
379
    /**
380
     * @param int    $receiverUserId
381
     * @param string $subject
382
     * @param string $message
383
     * @param int    $sender_id
384
     * @param bool   $sendCopyToDrhUsers send copy to related DRH users
385
     * @param bool   $directMessage
386
     * @param bool   $uploadFiles        Do not upload files using the MessageManager class
387
     * @param array  $attachmentList
388
     *
389
     * @return bool
390
     */
391
    public static function send_message_simple(
392
        $receiverUserId,
393
        $subject,
394
        $message,
395
        $sender_id = 0,
396
        $sendCopyToDrhUsers = false,
397
        $directMessage = false,
398
        $uploadFiles = true,
399
        $attachmentList = []
400
    ) {
401
        $files = $_FILES ? $_FILES : [];
402
        if (false === $uploadFiles) {
403
            $files = [];
404
        }
405
        // $attachmentList must have: tmp_name, name, size keys
406
        if (!empty($attachmentList)) {
407
            $files = $attachmentList;
408
        }
409
        $result = self::send_message(
410
            $receiverUserId,
411
            $subject,
412
            $message,
413
            $files,
414
            [],
415
            null,
416
            null,
417
            null,
418
            null,
419
            $sender_id,
420
            $directMessage
421
        );
422
423
        if ($sendCopyToDrhUsers) {
424
            $userInfo = api_get_user_info($receiverUserId);
425
            $drhList = UserManager::getDrhListFromUser($receiverUserId);
426
            if (!empty($drhList)) {
427
                foreach ($drhList as $drhInfo) {
428
                    $message = sprintf(
429
                        get_lang('Copy of message sent to %s'),
430
                        $userInfo['complete_name']
431
                    ).' <br />'.$message;
432
433
                    self::send_message_simple(
434
                        $drhInfo['id'],
435
                        $subject,
436
                        $message,
437
                        $sender_id,
438
                        false,
439
                        $directMessage
440
                    );
441
                }
442
            }
443
        }
444
445
        return $result;
446
    }
447
448
    public static function softDeleteAttachments(Message $message): void
449
    {
450
        $attachments = $message->getAttachments();
451
        if (!empty($attachments)) {
452
            $repo = Container::getMessageAttachmentRepository();
453
            foreach ($attachments as $file) {
454
                $repo->softDelete($file);
455
            }
456
        }
457
    }
458
459
    /**
460
     * Saves a message attachment files.
461
     *
462
     * @param array  $file    $_FILES['name']
463
     * @param string $comment a comment about the uploaded file
464
     */
465
    public static function saveMessageAttachmentFile($file, $comment, Message $message)
466
    {
467
        // Try to add an extension to the file if it hasn't one
468
        $type = $file['type'] ?? '';
469
        if (empty($type)) {
470
            $type = DocumentManager::file_get_mime_type($file['name']);
471
        }
472
        $new_file_name = add_ext_on_mime(stripslashes($file['name']), $type);
473
474
        // user's file name
475
        $fileName = $file['name'];
476
        if (!filter_extension($new_file_name)) {
477
            Display::addFlash(
478
                Display::return_message(
479
                    get_lang('File upload failed: this file extension or file type is prohibited'),
480
                    'error'
481
                )
482
            );
483
484
            return false;
485
        }
486
487
        $em = Database::getManager();
488
        $attachmentRepo = Container::getMessageAttachmentRepository();
489
490
        $attachment = (new MessageAttachment())
491
            ->setSize($file['size'])
492
            ->setPath($fileName)
493
            ->setFilename($fileName)
494
            ->setComment($comment)
495
            ->setParent($message->getSender())
496
            ->setMessage($message)
497
        ;
498
499
        $request = Container::getRequest();
500
        $fileToUpload = null;
501
502
        // Search for files inside the $_FILES, when uploading several files from the form.
503
        if ($request->files->count()) {
504
            /** @var UploadedFile|null $fileRequest */
505
            foreach ($request->files->all() as $fileRequest) {
506
                if (null === $fileRequest) {
507
                    continue;
508
                }
509
                if ($fileRequest->getClientOriginalName() === $file['name']) {
510
                    $fileToUpload = $fileRequest;
511
                    break;
512
                }
513
            }
514
        }
515
516
        // If no found file, try with $file['content'].
517
        if (null === $fileToUpload && isset($file['content'])) {
518
            $handle = tmpfile();
519
            fwrite($handle, $file['content']);
520
            $meta = stream_get_meta_data($handle);
521
            $fileToUpload = new UploadedFile($meta['uri'], $fileName, $file['type'], null, true);
522
        }
523
524
        if (null !== $fileToUpload) {
525
            $em->persist($attachment);
526
            $attachmentRepo->addFile($attachment, $fileToUpload);
527
            $attachment->addUserLink($message->getSender());
528
            $receivers = $message->getReceivers();
529
            foreach ($receivers as $receiver) {
530
                $attachment->addUserLink($receiver);
531
            }
532
            $em->flush();
533
534
            return true;
535
        }
536
537
        return false;
538
    }
539
540
    /**
541
     * get messages by group id.
542
     *
543
     * @param int $group_id group id
544
     *
545
     * @return array
546
     */
547
    public static function get_messages_by_group($group_id)
548
    {
549
        $group_id = (int) $group_id;
550
551
        if (empty($group_id)) {
552
            return false;
553
        }
554
555
        $table = Database::get_main_table(TABLE_MESSAGE);
556
        $sql = "SELECT * FROM $table
557
                WHERE
558
                    group_id= $group_id AND
559
                    msg_type = ".Message::MESSAGE_TYPE_GROUP."
560
                ORDER BY id";
561
        $rs = Database::query($sql);
562
        $data = [];
563
        if (Database::num_rows($rs) > 0) {
564
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
565
                $data[] = $row;
566
            }
567
        }
568
569
        return $data;
570
    }
571
572
    /**
573
     * get messages by group id.
574
     *
575
     * @param int $group_id
576
     * @param int $message_id
577
     *
578
     * @return array
579
     */
580
    public static function get_messages_by_group_by_message($group_id, $message_id)
581
    {
582
        $group_id = (int) $group_id;
583
584
        if (empty($group_id)) {
585
            return false;
586
        }
587
588
        $table = Database::get_main_table(TABLE_MESSAGE);
589
        $sql = "SELECT * FROM $table
590
                WHERE
591
                    group_id = $group_id AND
592
                    msg_type = '".Message::MESSAGE_TYPE_GROUP."'
593
                ORDER BY id ";
594
595
        $rs = Database::query($sql);
596
        $data = [];
597
        $parents = [];
598
        if (Database::num_rows($rs) > 0) {
599
            while ($row = Database::fetch_array($rs, 'ASSOC')) {
600
                if ($message_id == $row['parent_id'] || in_array($row['parent_id'], $parents)) {
601
                    $parents[] = $row['id'];
602
                    $data[] = $row;
603
                }
604
            }
605
        }
606
607
        return $data;
608
    }
609
610
    /**
611
     * Get messages by parent id optionally with limit.
612
     *
613
     * @param  int        parent id
614
     * @param  int        group id (optional)
615
     * @param  int        offset (optional)
616
     * @param  int        limit (optional)
617
     *
618
     * @return array
619
     */
620
    public static function getMessagesByParent($parentId, $groupId = 0, $offset = 0, $limit = 0)
621
    {
622
        $table = Database::get_main_table(TABLE_MESSAGE);
623
        $parentId = (int) $parentId;
624
625
        if (empty($parentId)) {
626
            return [];
627
        }
628
629
        $condition_group_id = '';
630
        if (!empty($groupId)) {
631
            $groupId = (int) $groupId;
632
            $condition_group_id = " AND group_id = '$groupId' ";
633
        }
634
635
        $condition_limit = '';
636
        if ($offset && $limit) {
637
            $offset = (int) $offset;
638
            $limit = (int) $limit;
639
            $offset = ($offset - 1) * $limit;
640
            $condition_limit = " LIMIT $offset,$limit ";
641
        }
642
643
        $sql = "SELECT * FROM $table
644
                WHERE
645
                    parent_id='$parentId' AND
646
                    msg_type = '".Message::MESSAGE_TYPE_GROUP."'
647
                    $condition_group_id
648
                ORDER BY send_date DESC $condition_limit ";
649
        $rs = Database::query($sql);
650
        $data = [];
651
        if (Database::num_rows($rs) > 0) {
652
            while ($row = Database::fetch_array($rs)) {
653
                $data[$row['id']] = $row;
654
            }
655
        }
656
657
        return $data;
658
    }
659
660
    /**
661
     * Displays messages of a group with nested view.
662
     *
663
     * @param int $groupId
664
     *
665
     * @return string
666
     */
667
    public static function display_messages_for_group($groupId)
668
    {
669
        global $my_group_role;
670
671
        $rows = self::get_messages_by_group($groupId);
672
        $topics_per_page = 10;
673
        $html_messages = '';
674
        $query_vars = ['id' => $groupId, 'topics_page_nr' => 0];
675
676
        if (is_array($rows) && count($rows) > 0) {
677
            // prepare array for topics with its items
678
            $topics = [];
679
            $x = 0;
680
            foreach ($rows as $index => $value) {
681
                if (empty($value['parent_id'])) {
682
                    $topics[$value['id']] = $value;
683
                }
684
            }
685
686
            $new_topics = [];
687
688
            foreach ($topics as $id => $value) {
689
                $rows = self::get_messages_by_group_by_message($groupId, $value['id']);
690
                if (!empty($rows)) {
691
                    $count = count(self::calculate_children($rows, $value['id']));
692
                } else {
693
                    $count = 0;
694
                }
695
                $value['count'] = $count;
696
                $new_topics[$id] = $value;
697
            }
698
699
            $array_html = [];
700
            foreach ($new_topics as $index => $topic) {
701
                $html = '';
702
                // topics
703
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
704
                $name = $user_sender_info['complete_name'];
705
                $html .= '<div class="groups-messages">';
706
                $html .= '<div class="row">';
707
708
                $items = $topic['count'];
709
                $reply_label = (1 == $items) ? get_lang('Reply') : get_lang('Replies');
710
                $label = '<i class="fa fa-envelope"></i> '.$items.' '.$reply_label;
711
                $topic['title'] = trim($topic['title']);
712
713
                if (empty($topic['title'])) {
714
                    $topic['title'] = get_lang('Untitled');
715
                }
716
717
                $html .= '<div class="col-xs-8 col-md-10">';
718
                $html .= Display::tag(
719
                    'h4',
720
                    Display::url(
721
                        Security::remove_XSS($topic['title'], STUDENT, true),
722
                        api_get_path(WEB_CODE_PATH).'social/group_topics.php?id='.$groupId.'&topic_id='.$topic['id']
723
                    ),
724
                    ['class' => 'title']
725
                );
726
                $actions = '';
727
                if (GROUP_USER_PERMISSION_ADMIN == $my_group_role ||
728
                    GROUP_USER_PERMISSION_MODERATOR == $my_group_role
729
                ) {
730
                    $actions = '<br />'.Display::url(
731
                            get_lang('Delete'),
732
                            api_get_path(
733
                                WEB_CODE_PATH
734
                            ).'social/group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic['id'],
735
                            ['class' => 'btn btn-default']
736
                        );
737
                }
738
739
                $date = '';
740
                if ($topic['send_date'] != $topic['update_date']) {
741
                    if (!empty($topic['update_date'])) {
742
                        $date .= '<i class="fa fa-calendar"></i> '.get_lang(
743
                                'LastUpdate'
744
                            ).' '.Display::dateToStringAgoAndLongDate($topic['update_date']);
745
                    }
746
                } else {
747
                    $date .= '<i class="fa fa-calendar"></i> '.get_lang(
748
                            'Created'
749
                        ).' '.Display::dateToStringAgoAndLongDate($topic['send_date']);
750
                }
751
                $html .= '<div class="date">'.$label.' - '.$date.$actions.'</div>';
752
                $html .= '</div>';
753
754
                $image = $user_sender_info['avatar'];
755
756
                $user_info = '<div class="author"><img class="img-responsive img-circle" src="'.$image.'" alt="'.$name.'"  width="64" height="64" title="'.$name.'" /></div>';
757
                $user_info .= '<div class="name"><a href="'.api_get_path(
758
                        WEB_PATH
759
                    ).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp;</a></div>';
760
761
                $html .= '<div class="col-xs-4 col-md-2">';
762
                $html .= $user_info;
763
                $html .= '</div>';
764
                $html .= '</div>';
765
                $html .= '</div>';
766
767
                $array_html[] = [$html];
768
            }
769
770
            // grids for items and topics  with paginations
771
            $html_messages .= Display::return_sortable_grid(
772
                'topics',
773
                [],
774
                $array_html,
775
                [
776
                    'hide_navigation' => false,
777
                    'per_page' => $topics_per_page,
778
                ],
779
                $query_vars,
780
                false,
781
                [true, true, true, false],
782
                false
783
            );
784
        }
785
786
        return $html_messages;
787
    }
788
789
    /**
790
     * Displays messages of a group with nested view.
791
     *
792
     * @param $groupId
793
     * @param $topic_id
794
     *
795
     * @return string
796
     */
797
    public static function display_message_for_group($groupId, $topic_id)
798
    {
799
        return '';
800
801
        /*global $my_group_role;
802
        $message = Container::getMessageRepository()->find($topic_id);
803
        if (null === $message) {
804
            return false;
805
        }
806
807
        $webCodePath = api_get_path(WEB_CODE_PATH);
808
        $iconCalendar = Display::returnFontAwesomeIcon('calendar');
809
810
        $langEdit = get_lang('Edit');
811
        $langReply = get_lang('Reply');
812
        $langLastUpdated = get_lang('LastUpdated');
813
        $langCreated = get_lang('Created');
814
815
        $rows = self::get_messages_by_group_by_message($groupId, $topic_id);
816
        $rows = self::calculate_children($rows, $topic_id);
817
        $current_user_id = api_get_user_id();
818
819
        $items_per_page = 50;
820
        $query_vars = ['id' => $groupId, 'topic_id' => $topic_id, 'topics_page_nr' => 0];
821
822
        // Main message
823
        $links = '';
824
        $main_content = '';
825
        $html = '';
826
        $items_page_nr = null;
827
828
        $filesAttachments = self::getAttachmentLinkList($message);
829
        $name = UserManager::formatUserFullName($message->getSender());
830
831
        $topic_page_nr = isset($_GET['topics_page_nr']) ? (int) $_GET['topics_page_nr'] : null;
832
833
        $links .= '<div class="pull-right">';
834
        $links .= '<div class="btn-group btn-group-sm">';
835
836
        if ((GROUP_USER_PERMISSION_ADMIN == $my_group_role || GROUP_USER_PERMISSION_MODERATOR == $my_group_role) ||
837
            $message->getSender()->getId() == $current_user_id
838
        ) {
839
            $urlEdit = $webCodePath.'social/message_for_group_form.inc.php?'
840
                .http_build_query(
841
                    [
842
                        'user_friend' => $current_user_id,
843
                        'group_id' => $groupId,
844
                        'message_id' => $message->getId(),
845
                        'action' => 'edit_message_group',
846
                        'anchor_topic' => 'topic_'.$message->getId(),
847
                        'topics_page_nr' => $topic_page_nr,
848
                        'items_page_nr' => $items_page_nr,
849
                        'topic_id' => $message->getId(),
850
                    ]
851
                );
852
853
            $links .= Display::toolbarButton(
854
                $langEdit,
855
                $urlEdit,
856
                'pencil',
857
                'default',
858
                ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'],
859
                false
860
            );
861
        }
862
863
        $links .= self::getLikesButton($message->getId(), $current_user_id, $groupId);
864
865
        $urlReply = $webCodePath.'social/message_for_group_form.inc.php?'
866
            .http_build_query(
867
                [
868
                    'user_friend' => $current_user_id,
869
                    'group_id' => $groupId,
870
                    'message_id' => $message->getId(),
871
                    'action' => 'reply_message_group',
872
                    'anchor_topic' => 'topic_'.$message->getId(),
873
                    'topics_page_nr' => $topic_page_nr,
874
                    'topic_id' => $message->getId(),
875
                ]
876
            );
877
878
        $links .= Display::toolbarButton(
879
            $langReply,
880
            $urlReply,
881
            'commenting',
882
            'default',
883
            ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'],
884
            false
885
        );
886
887
        if (api_is_platform_admin()) {
888
            $links .= Display::toolbarButton(
889
                get_lang('Delete'),
890
                'group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic_id,
891
                'trash',
892
                'default',
893
                [],
894
                false
895
            );
896
        }
897
898
        $links .= '</div>';
899
        $links .= '</div>';
900
901
        $title = '<h4>'.Security::remove_XSS($message->getTitle(), STUDENT, true).$links.'</h4>';
902
903
        $main_content .= '<div class="row">';
904
        $main_content .= '<div class="col-md-2">';
905
        $main_content .= '<div class="avatar-author">';
906
        $main_content .= Display::img(
907
            $userPicture,
908
            $name,
909
            ['width' => '60px', 'class' => 'img-responsive img-circle'],
910
            false
911
        );
912
        $main_content .= '</div>';
913
        $main_content .= '</div>';
914
915
        $date = '';
916
        if ($main_message['send_date'] != $main_message['update_date']) {
917
            if (!empty($main_message['update_date'])) {
918
                $date = '<div class="date"> '
919
                    ."$iconCalendar $langLastUpdated "
920
                    .Display::dateToStringAgoAndLongDate($main_message['update_date'])
921
                    .'</div>';
922
            }
923
        } else {
924
            $date = '<div class="date"> '
925
                ."$iconCalendar $langCreated "
926
                .Display::dateToStringAgoAndLongDate($main_message['send_date'])
927
                .'</div>';
928
        }
929
        $attachment = '<div class="message-attach">'
930
            .(!empty($filesAttachments) ? implode('<br />', $filesAttachments) : '')
931
            .'</div>';
932
        $main_content .= '<div class="col-md-10">';
933
        $user_link = Display::url(
934
            $name,
935
            $webCodePath.'social/profile.php?u='.$main_message['user_sender_id']
936
        );
937
        $main_content .= '<div class="message-content"> ';
938
        $main_content .= '<div class="username">'.$user_link.'</div>';
939
        $main_content .= $date;
940
        $main_content .= '<div class="message">'.$main_message['content'].$attachment.'</div></div>';
941
        $main_content .= '</div>';
942
        $main_content .= '</div>';
943
944
        $html .= Display::div(
945
            Display::div(
946
                $title.$main_content,
947
                ['class' => 'message-topic']
948
            ),
949
            ['class' => 'sm-groups-message']
950
        );
951
952
        $topic_id = $main_message['id'];
953
954
        if (is_array($rows) && count($rows) > 0) {
955
            $topics = $rows;
956
            $array_html_items = [];
957
958
            foreach ($topics as $index => $topic) {
959
                if (empty($topic['id'])) {
960
                    continue;
961
                }
962
                $items_page_nr = isset($_GET['items_'.$topic['id'].'_page_nr'])
963
                    ? (int) $_GET['items_'.$topic['id'].'_page_nr']
964
                    : null;
965
                $links = '';
966
                $links .= '<div class="pull-right">';
967
                $html_items = '';
968
                $user_sender_info = api_get_user_info($topic['user_sender_id']);
969
                $filesAttachments = self::getAttachmentLinkList($topic['id'], 0);
970
                $name = $user_sender_info['complete_name'];
971
972
                $links .= '<div class="btn-group btn-group-sm">';
973
                if (
974
                    (GROUP_USER_PERMISSION_ADMIN == $my_group_role ||
975
                        GROUP_USER_PERMISSION_MODERATOR == $my_group_role
976
                    ) ||
977
                    $topic['user_sender_id'] == $current_user_id
978
                ) {
979
                    $links .= Display::toolbarButton(
980
                        $langEdit,
981
                        $webCodePath.'social/message_for_group_form.inc.php?'
982
                            .http_build_query(
983
                                [
984
                                    'user_friend' => $current_user_id,
985
                                    'group_id' => $groupId,
986
                                    'message_id' => $topic['id'],
987
                                    'action' => 'edit_message_group',
988
                                    'anchor_topic' => 'topic_'.$topic_id,
989
                                    'topics_page_nr' => $topic_page_nr,
990
                                    'items_page_nr' => $items_page_nr,
991
                                    'topic_id' => $topic_id,
992
                                ]
993
                            ),
994
                        'pencil',
995
                        'default',
996
                        ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'],
997
                        false
998
                    );
999
                }
1000
1001
                $links .= self::getLikesButton($topic['id'], $current_user_id, $groupId);
1002
1003
                $links .= Display::toolbarButton(
1004
                    $langReply,
1005
                    $webCodePath.'social/message_for_group_form.inc.php?'
1006
                        .http_build_query(
1007
                            [
1008
                                'user_friend' => $current_user_id,
1009
                                'group_id' => $groupId,
1010
                                'message_id' => $topic['id'],
1011
                                'action' => 'reply_message_group',
1012
                                'anchor_topic' => 'topic_'.$topic_id,
1013
                                'topics_page_nr' => $topic_page_nr,
1014
                                'items_page_nr' => $items_page_nr,
1015
                                'topic_id' => $topic_id,
1016
                            ]
1017
                        ),
1018
                    'commenting',
1019
                    'default',
1020
                    ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'],
1021
                    false
1022
                );
1023
                $links .= '</div>';
1024
                $links .= '</div>';
1025
1026
                $userPicture = $user_sender_info['avatar'];
1027
                $user_link = Display::url(
1028
                    $name,
1029
                    $webCodePath.'social/profile.php?u='.$topic['user_sender_id']
1030
                );
1031
                $html_items .= '<div class="row">';
1032
                $html_items .= '<div class="col-md-2">';
1033
                $html_items .= '<div class="avatar-author">';
1034
                $html_items .= Display::img(
1035
                    $userPicture,
1036
                    $name,
1037
                    ['width' => '60px', 'class' => 'img-responsive img-circle'],
1038
                    false
1039
                );
1040
                $html_items .= '</div>';
1041
                $html_items .= '</div>';
1042
1043
                $date = '';
1044
                if ($topic['send_date'] != $topic['update_date']) {
1045
                    if (!empty($topic['update_date'])) {
1046
                        $date = '<div class="date"> '
1047
                            ."$iconCalendar $langLastUpdated "
1048
                            .Display::dateToStringAgoAndLongDate($topic['update_date'])
1049
                            .'</div>';
1050
                    }
1051
                } else {
1052
                    $date = '<div class="date"> '
1053
                        ."$iconCalendar $langCreated "
1054
                        .Display::dateToStringAgoAndLongDate($topic['send_date'])
1055
                        .'</div>';
1056
                }
1057
                $attachment = '<div class="message-attach">'
1058
                    .(!empty($filesAttachments) ? implode('<br />', $filesAttachments) : '')
1059
                    .'</div>';
1060
                $html_items .= '<div class="col-md-10">'
1061
                    .'<div class="message-content">'
1062
                    .$links
1063
                    .'<div class="username">'.$user_link.'</div>'
1064
                    .$date
1065
                    .'<div class="message">'
1066
                    .Security::remove_XSS($topic['content'], STUDENT, true)
1067
                    .'</div>'.$attachment.'</div>'
1068
                    .'</div>'
1069
                    .'</div>';
1070
1071
                $base_padding = 20;
1072
1073
                if (0 == $topic['indent_cnt']) {
1074
                    $indent = $base_padding;
1075
                } else {
1076
                    $indent = (int) $topic['indent_cnt'] * $base_padding + $base_padding;
1077
                }
1078
1079
                $html_items = Display::div($html_items, ['class' => 'message-post', 'id' => 'msg_'.$topic['id']]);
1080
                $html_items = Display::div($html_items, ['class' => '', 'style' => 'margin-left:'.$indent.'px']);
1081
                $array_html_items[] = [$html_items];
1082
            }
1083
1084
            // grids for items with paginations
1085
            $options = ['hide_navigation' => false, 'per_page' => $items_per_page];
1086
            $visibility = [true, true, true, false];
1087
1088
            $style_class = [
1089
                'item' => ['class' => 'user-post'],
1090
                'main' => ['class' => 'user-list'],
1091
            ];
1092
            if (!empty($array_html_items)) {
1093
                $html .= Display::return_sortable_grid(
1094
                    'items_'.$topic['id'],
1095
                    [],
1096
                    $array_html_items,
1097
                    $options,
1098
                    $query_vars,
1099
                    null,
1100
                    $visibility,
1101
                    false,
1102
                    $style_class
1103
                );
1104
            }
1105
        }*/
1106
1107
        return $html;
0 ignored issues
show
Unused Code introduced by
return $html is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1108
    }
1109
1110
    /**
1111
     * Add children to messages by id is used for nested view messages.
1112
     *
1113
     * @param array $rows rows of messages
1114
     *
1115
     * @return array $first_seed new list adding the item children
1116
     */
1117
    public static function calculate_children($rows, $first_seed)
1118
    {
1119
        $rows_with_children = [];
1120
        foreach ($rows as $row) {
1121
            $rows_with_children[$row["id"]] = $row;
1122
            $rows_with_children[$row["parent_id"]]["children"][] = $row["id"];
1123
        }
1124
        $rows = $rows_with_children;
1125
        $sorted_rows = [0 => []];
1126
        self::message_recursive_sort($rows, $sorted_rows, $first_seed);
1127
        unset($sorted_rows[0]);
1128
1129
        return $sorted_rows;
1130
    }
1131
1132
    /**
1133
     * Sort recursively the messages, is used for for nested view messages.
1134
     *
1135
     * @param array  original rows of messages
1136
     * @param array  list recursive of messages
1137
     * @param int   seed for calculate the indent
1138
     * @param int   indent for nested view
1139
     */
1140
    public static function message_recursive_sort(
1141
        $rows,
1142
        &$messages,
1143
        $seed = 0,
1144
        $indent = 0
1145
    ) {
1146
        if ($seed > 0 && isset($rows[$seed]["id"])) {
1147
            $messages[$rows[$seed]["id"]] = $rows[$seed];
1148
            $messages[$rows[$seed]["id"]]["indent_cnt"] = $indent;
1149
            $indent++;
1150
        }
1151
1152
        if (isset($rows[$seed]["children"])) {
1153
            foreach ($rows[$seed]["children"] as $child) {
1154
                self::message_recursive_sort($rows, $messages, $child, $indent);
1155
            }
1156
        }
1157
    }
1158
1159
    /**
1160
     * Get array of links (download) for message attachment files.
1161
     *
1162
     * @return array
1163
     */
1164
    public static function getAttachmentLinkList(Message $message)
1165
    {
1166
        $files = $message->getAttachments();
1167
        // get file attachments by message id
1168
        $list = [];
1169
        if ($files) {
0 ignored issues
show
introduced by
$files is of type Doctrine\Common\Collections\Collection, thus it always evaluated to true.
Loading history...
1170
            $attachIcon = Display::returnFontAwesomeIcon('paperclip');
1171
            $repo = Container::getMessageAttachmentRepository();
1172
            foreach ($files as $file) {
1173
                $size = format_file_size($file->getSize());
1174
                $comment = Security::remove_XSS($file->getComment());
1175
                $filename = Security::remove_XSS($file->getFilename());
1176
                $url = $repo->getResourceFileUrl($file);
1177
                $link = Display::url($filename, $url);
1178
                $comment = !empty($comment) ? '&nbsp;-&nbsp;<i>'.$comment.'</i>' : '';
1179
1180
                $attachmentLine = $attachIcon.'&nbsp;'.$link.'&nbsp;('.$size.')'.$comment;
1181
                /*if ('audio_message' === $file['comment']) {
1182
                    $attachmentLine = '<audio src="'.$archiveURL.$archiveFile.'"/>';
1183
                }*/
1184
                $list[] = $attachmentLine;
1185
            }
1186
        }
1187
1188
        return $list;
1189
    }
1190
1191
    /**
1192
     * @return string
1193
     */
1194
    public static function generate_message_form()
1195
    {
1196
        $form = new FormValidator('send_message');
1197
        $form->addText(
1198
            'subject',
1199
            get_lang('Subject'),
1200
            false,
1201
            ['id' => 'subject_id']
1202
        );
1203
        $form->addTextarea(
1204
            'content',
1205
            get_lang('Message'),
1206
            ['id' => 'content_id', 'rows' => '5']
1207
        );
1208
1209
        return $form->returnForm();
1210
    }
1211
1212
    /**
1213
     * @return string
1214
     */
1215
    public static function generate_invitation_form()
1216
    {
1217
        $form = new FormValidator('send_invitation');
1218
        $form->addTextarea(
1219
            'content',
1220
            get_lang('Add a personal message'),
1221
            ['id' => 'content_invitation_id', 'rows' => 5]
1222
        );
1223
1224
        return $form->returnForm();
1225
    }
1226
1227
    /**
1228
     * @param string $type
1229
     * @param string $keyword
1230
     * @param array  $actions
1231
     *
1232
     * @return string
1233
     */
1234
    public static function getMessageGrid($type, $keyword, $actions = [])
1235
    {
1236
        $html = '';
1237
        // display sortable table with messages of the current user
1238
        $table = new SortableTable(
1239
            'message_inbox',
1240
            ['MessageManager', 'getNumberOfMessages'],
1241
            ['MessageManager', 'getMessageData'],
1242
            2,
1243
            20,
1244
            'DESC'
1245
        );
1246
        $table->setDataFunctionParams(
1247
            ['keyword' => $keyword, 'type' => $type, 'actions' => $actions]
1248
        );
1249
        $table->set_header(0, '', false, ['style' => 'width:15px;']);
1250
        $table->set_header(1, get_lang('Messages'), false);
1251
        $table->set_header(2, get_lang('Date'), true, ['style' => 'width:180px;']);
1252
        $table->set_header(3, get_lang('Edit'), false, ['style' => 'width:120px;']);
1253
1254
        if (isset($_REQUEST['f']) && 'social' === $_REQUEST['f']) {
1255
            $parameters['f'] = 'social';
1256
            $table->set_additional_parameters($parameters);
1257
        }
1258
1259
        $defaultActions = [
1260
            'delete' => get_lang('Delete selected messages'),
1261
            'mark_as_unread' => get_lang('Mark as unread'),
1262
            'mark_as_read' => get_lang('Mark as read'),
1263
        ];
1264
1265
        if (!in_array('delete', $actions)) {
1266
            unset($defaultActions['delete']);
1267
        }
1268
        if (!in_array('mark_as_unread', $actions)) {
1269
            unset($defaultActions['mark_as_unread']);
1270
        }
1271
        if (!in_array('mark_as_read', $actions)) {
1272
            unset($defaultActions['mark_as_read']);
1273
        }
1274
1275
        $table->set_form_actions($defaultActions);
1276
1277
        $html .= $table->return_table();
1278
1279
        return $html;
1280
    }
1281
1282
    /**
1283
     * @param string $url
1284
     *
1285
     * @return FormValidator
1286
     */
1287
    public static function getSearchForm($url)
1288
    {
1289
        $form = new FormValidator(
1290
            'search',
1291
            'post',
1292
            $url,
1293
            null,
1294
            [],
1295
            FormValidator::LAYOUT_INLINE
1296
        );
1297
1298
        $form->addElement(
1299
            'text',
1300
            'keyword',
1301
            false,
1302
            [
1303
                'aria-label' => get_lang('Search'),
1304
            ]
1305
        );
1306
        $form->addButtonSearch(get_lang('Search'));
1307
1308
        return $form;
1309
    }
1310
1311
    /**
1312
     * Send a notification to all admins when a new user is registered.
1313
     */
1314
    public static function sendNotificationOfNewRegisteredUser(User $user)
1315
    {
1316
        $tplMailBody = new Template(
1317
            null,
1318
            false,
1319
            false,
1320
            false,
1321
            false,
1322
            false,
1323
            false
1324
        );
1325
        $tplMailBody->assign('user', $user);
1326
        $tplMailBody->assign('is_western_name_order', api_is_western_name_order());
1327
        $tplMailBody->assign(
1328
            'manageUrl',
1329
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$user->getId()
1330
        );
1331
1332
        $layoutContent = $tplMailBody->get_template('mail/new_user_mail_to_admin.tpl');
1333
1334
        $emailsubject = '['.get_lang('The user has been registered').'] '.$user->getUsername();
1335
        $emailbody = $tplMailBody->fetch($layoutContent);
1336
1337
        $admins = UserManager::get_all_administrators();
1338
1339
        foreach ($admins as $admin_info) {
1340
            self::send_message(
1341
                $admin_info['user_id'],
1342
                $emailsubject,
1343
                $emailbody,
1344
                [],
1345
                [],
1346
                null,
1347
                null,
1348
                null,
1349
                null,
1350
                $user->getId()
1351
            );
1352
        }
1353
    }
1354
1355
    /**
1356
     * Send a notification to all admins when a new user is registered
1357
     * while the approval method is used for users registration.
1358
     */
1359
    public static function sendNotificationOfNewRegisteredUserApproval(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
        $userId = $user->getId();
1373
        $url_edit = Display::url(
1374
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$userId,
1375
            api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$userId
1376
        );
1377
        $tplMailBody->assign(
1378
            'manageUrl',
1379
            $url_edit
1380
        );
1381
        // Get extra field values for this user and reformat the array
1382
        $extraFieldValues = new ExtraFieldValue('user');
1383
        $userExtraFields = $extraFieldValues->getAllValuesByItem($userId);
1384
        $values = [];
1385
        foreach ($userExtraFields as $field => $value) {
1386
            $values[$value['variable']] = $value['value'];
1387
        }
1388
        $tplMailBody->assign(
1389
            'extra',
1390
            $values
1391
        );
1392
        $layoutContent = '';
1393
        $emailbody = '';
1394
        if (true == api_get_configuration_value('mail_template_system')) {
1395
            $mailTemplateManager = new MailTemplateManager();
1396
            $templateText = $mailTemplateManager->getTemplateByType('new_user_mail_to_admin_approval.tpl');
1397
            if (empty($templateText)) {
1398
            } else {
1399
                // custom procedure to load a template as a string (doesn't use cache so may slow down)
1400
                $template = $tplMailBody->twig->createTemplate($templateText);
1401
                $emailbody = $template->render($tplMailBody->params);
1402
            }
1403
        }
1404
        if (empty($emailbody)) {
1405
            $layoutContent = $tplMailBody->get_template('mail/new_user_mail_to_admin_approval.tpl');
1406
            $emailbody = $tplMailBody->fetch($layoutContent);
1407
        }
1408
1409
        $emailsubject = '['.get_lang('ApprovalForNewAccount').'] '.$user->getUsername();
1410
1411
        if (api_get_configuration_value('send_inscription_notification_to_general_admin_only')) {
1412
            $email = api_get_setting('emailAdministrator');
1413
            $firstname = api_get_setting('administratorSurname');
1414
            $lastname = api_get_setting('administratorName');
1415
            api_mail_html("$firstname $lastname", $email, $emailsubject, $emailbody);
1416
        } else {
1417
            $admins = UserManager::get_all_administrators();
1418
            foreach ($admins as $admin_info) {
1419
                self::send_message(
1420
                    $admin_info['user_id'],
1421
                    $emailsubject,
1422
                    $emailbody,
1423
                    [],
1424
                    [],
1425
                    null,
1426
                    null,
1427
                    null,
1428
                    null,
1429
                    $userId
1430
                );
1431
            }
1432
        }
1433
    }
1434
1435
    /**
1436
     * Get the error log from failed mailing
1437
     * This assumes a complex setup where you have a cron script regularly copying the mail queue log
1438
     * into app/cache/mail/mailq.
1439
     * This can be done with a cron command like (check the location of your mail log file first):.
1440
     *
1441
     * @example 0,30 * * * * root cp /var/log/exim4/mainlog /var/www/chamilo/app/cache/mail/mailq
1442
     *
1443
     * @return array|bool
1444
     */
1445
    public static function failedSentMailErrors()
1446
    {
1447
        $base = api_get_path(SYS_ARCHIVE_PATH).'mail/';
1448
        $mailq = $base.'mailq';
1449
1450
        if (!file_exists($mailq) || !is_readable($mailq)) {
1451
            return false;
1452
        }
1453
1454
        $file = fopen($mailq, 'r');
1455
        $i = 1;
1456
        while (!feof($file)) {
1457
            $line = fgets($file);
1458
1459
            if ('' == trim($line)) {
1460
                continue;
1461
            }
1462
1463
            // Get the mail code, something like 1WBumL-0002xg-FF
1464
            if (preg_match('/(.*)\s((.*)-(.*)-(.*))\s<(.*)$/', $line, $codeMatches)) {
1465
                $mail_queue[$i]['code'] = $codeMatches[2];
1466
            }
1467
1468
            $fullMail = $base.$mail_queue[$i]['code'];
1469
            $mailFile = fopen($fullMail, 'r');
1470
1471
            // Get the reason of mail fail
1472
            $iX = 1;
1473
            while (!feof($mailFile)) {
1474
                $mailLine = fgets($mailFile);
1475
                //if ($iX == 4 && preg_match('/(.*):\s(.*)$/', $mailLine, $matches)) {
1476
                if (2 == $iX &&
1477
                    preg_match('/(.*)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s(.*)/', $mailLine, $detailsMatches)
1478
                ) {
1479
                    $mail_queue[$i]['reason'] = $detailsMatches[3];
1480
                }
1481
                $iX++;
1482
            }
1483
1484
            fclose($mailFile);
1485
1486
            // Get the time of mail fail
1487
            if (preg_match('/^\s?(\d+)(\D+)\s+(.*)$/', $line, $timeMatches)) {
1488
                $mail_queue[$i]['time'] = $timeMatches[1].$timeMatches[2];
1489
            } elseif (preg_match('/^(\s+)((.*)@(.*))\s+(.*)$/', $line, $emailMatches)) {
1490
                $mail_queue[$i]['mail'] = $emailMatches[2];
1491
                $i++;
1492
            }
1493
        }
1494
1495
        fclose($file);
1496
1497
        return array_reverse($mail_queue);
1498
    }
1499
1500
    /**
1501
     * @param int $userId
1502
     *
1503
     * @return array
1504
     */
1505
    public static function getUsersThatHadConversationWithUser($userId)
1506
    {
1507
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
1508
        $userId = (int) $userId;
1509
1510
        $sql = "SELECT DISTINCT
1511
                    user_sender_id
1512
                FROM $messagesTable
1513
                WHERE
1514
                    user_receiver_id = ".$userId;
1515
        $result = Database::query($sql);
1516
        $users = Database::store_result($result);
1517
        $userList = [];
1518
        foreach ($users as $userData) {
1519
            $userId = $userData['user_sender_id'];
1520
            if (empty($userId)) {
1521
                continue;
1522
            }
1523
            $userInfo = api_get_user_info($userId);
1524
            if ($userInfo) {
1525
                $userList[$userId] = $userInfo;
1526
            }
1527
        }
1528
1529
        return $userList;
1530
    }
1531
1532
    /**
1533
     * @param int $userId
1534
     * @param int $otherUserId
1535
     *
1536
     * @return array
1537
     */
1538
    public static function getAllMessagesBetweenStudents($userId, $otherUserId)
1539
    {
1540
        $messagesTable = Database::get_main_table(TABLE_MESSAGE);
1541
        $userId = (int) $userId;
1542
        $otherUserId = (int) $otherUserId;
1543
1544
        if (empty($otherUserId) || empty($userId)) {
1545
            return [];
1546
        }
1547
1548
        $sql = "SELECT DISTINCT *
1549
                FROM $messagesTable
1550
                WHERE
1551
                    (user_receiver_id = $userId AND user_sender_id = $otherUserId) OR
1552
                    (user_receiver_id = $otherUserId AND user_sender_id = $userId)
1553
                ORDER BY send_date DESC
1554
            ";
1555
        $result = Database::query($sql);
1556
        $messages = Database::store_result($result);
1557
        $list = [];
1558
        foreach ($messages as $message) {
1559
            $list[] = $message;
1560
        }
1561
1562
        return $list;
1563
    }
1564
1565
    /**
1566
     * @param string $subject
1567
     * @param string $message
1568
     * @param Course $course
1569
     * @param int    $sessionId
1570
     *
1571
     * @return bool
1572
     */
1573
    public static function sendMessageToAllUsersInCourse($subject, $message, Course $course, $sessionId = 0)
1574
    {
1575
        $senderId = api_get_user_id();
1576
        if (empty($senderId)) {
1577
            return false;
1578
        }
1579
        if (empty($sessionId)) {
1580
            // Course students and teachers
1581
            $users = CourseManager::get_user_list_from_course_code($course->getCode());
1582
        } else {
1583
            // Course-session students and course session coaches
1584
            $users = CourseManager::get_user_list_from_course_code($course->getCode(), $sessionId);
1585
        }
1586
1587
        if (empty($users)) {
1588
            return false;
1589
        }
1590
1591
        foreach ($users as $userInfo) {
1592
            self::send_message_simple(
1593
                $userInfo['user_id'],
1594
                $subject,
1595
                $message,
1596
                $senderId,
1597
                false,
1598
                false,
1599
                false
1600
            );
1601
        }
1602
    }
1603
1604
    /**
1605
     * Clean audio messages already added in the message tool.
1606
     */
1607
    public static function cleanAudioMessage()
1608
    {
1609
        Session::erase('current_audio');
1610
    }
1611
1612
    /**
1613
     * @param int    $senderId
1614
     * @param string $subject
1615
     * @param string $message
1616
     */
1617
    public static function sendMessageToAllAdminUsers(
1618
        $senderId,
1619
        $subject,
1620
        $message
1621
    ) {
1622
        $admins = UserManager::get_all_administrators();
1623
        foreach ($admins as $admin) {
1624
            self::send_message_simple($admin['user_id'], $subject, $message, $senderId);
1625
        }
1626
    }
1627
1628
    /**
1629
     * @param int $messageId
1630
     * @param int $userId
1631
     *
1632
     * @return array
1633
     */
1634
    public static function countLikesAndDislikes($messageId, $userId)
1635
    {
1636
        if (!api_get_configuration_value('social_enable_messages_feedback')) {
1637
            return [];
1638
        }
1639
1640
        $messageId = (int) $messageId;
1641
        $userId = (int) $userId;
1642
1643
        $em = Database::getManager();
1644
        $query = $em
1645
            ->createQuery('
1646
                SELECT SUM(l.liked) AS likes, SUM(l.disliked) AS dislikes FROM ChamiloCoreBundle:MessageFeedback l
1647
                WHERE l.message = :message
1648
            ')
1649
            ->setParameters(['message' => $messageId]);
1650
1651
        try {
1652
            $counts = $query->getSingleResult();
1653
        } catch (Exception $e) {
1654
            $counts = ['likes' => 0, 'dislikes' => 0];
1655
        }
1656
1657
        $userLike = $em
1658
            ->getRepository(MessageFeedback::class)
1659
            ->findOneBy(['message' => $messageId, 'user' => $userId]);
1660
1661
        return [
1662
            'likes' => (int) $counts['likes'],
1663
            'dislikes' => (int) $counts['dislikes'],
1664
            'user_liked' => $userLike ? $userLike->isLiked() : false,
1665
            'user_disliked' => $userLike ? $userLike->isDisliked() : false,
1666
        ];
1667
    }
1668
1669
    /**
1670
     * @param int $messageId
1671
     * @param int $userId
1672
     * @param int $groupId   Optional.
1673
     *
1674
     * @return string
1675
     */
1676
    public static function getLikesButton($messageId, $userId, $groupId = 0)
1677
    {
1678
        if (!api_get_configuration_value('social_enable_messages_feedback')) {
1679
            return '';
1680
        }
1681
1682
        $countLikes = self::countLikesAndDislikes($messageId, $userId);
1683
1684
        $class = $countLikes['user_liked'] ? 'btn-primary' : 'btn-default';
1685
1686
        $btnLike = Display::button(
1687
            'like',
1688
            Display::returnFontAwesomeIcon('thumbs-up', '', true)
1689
                .PHP_EOL.'<span>'.$countLikes['likes'].'</span>',
1690
            [
1691
                'title' => get_lang('Like'),
1692
                'class' => 'btn  social-like '.$class,
1693
                'data-status' => 'like',
1694
                'data-message' => $messageId,
1695
                'data-group' => $groupId,
1696
            ]
1697
        );
1698
1699
        $btnDislike = '';
1700
        if (false === api_get_configuration_value('disable_dislike_option')) {
1701
            $disabled = $countLikes['user_disliked'] ? 'btn-danger' : 'btn-default';
1702
1703
            $btnDislike = Display::button(
1704
                'like',
1705
                Display::returnFontAwesomeIcon('thumbs-down', '', true)
1706
                .PHP_EOL.'<span>'.$countLikes['dislikes'].'</span>',
1707
                [
1708
                    'title' => get_lang('Dislike'),
1709
                    'class' => 'btn social-like '.$disabled,
1710
                    'data-status' => 'dislike',
1711
                    'data-message' => $messageId,
1712
                    'data-group' => $groupId,
1713
                ]
1714
            );
1715
        }
1716
1717
        return $btnLike.PHP_EOL.$btnDislike;
1718
    }
1719
}
1720