Passed
Push — master ( f10e67...52beba )
by Julito
07:56
created

MessageManager::getSearchForm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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