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

MessageManager::send_message_simple()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 55
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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