'.$title.'
'; $message[1] .= $userInfo['complete_name_with_username']; if (in_array('reply', $actions)) { $message[3] = Display::url( Display::returnFontAwesomeIcon('reply', 2), $newMessageLink.'?re_id='.$messageId, ['title' => get_lang('Reply to this message')] ); } } else { $message[1] = ''.$title.'
'; $message[1] .= get_lang('Unknown user'); if (in_array('reply', $actions)) { $message[3] = Display::url( Display::returnFontAwesomeIcon('reply', 2), '#', ['title' => get_lang('Reply to this message')] ); } } $message[0] = $messageId; $message[2] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG); // Actions if (in_array('edit', $actions)) { $message[3] .= '  '. Display::url( Display::returnFontAwesomeIcon('pencil', 2), $newMessageLink.'?action=edit&id='.$messageId, ['title' => get_lang('Forward message')] ); } // Actions if (in_array('forward', $actions)) { $message[3] .= '  '. Display::url( Display::returnFontAwesomeIcon('share', 2), $newMessageLink.'?forward_id='.$messageId, ['title' => get_lang('Forward message')] ); } if (in_array('delete', $actions)) { $message[3] .= '  '. Display::returnFontAwesomeIcon('trash', 2).''; } foreach ($message as $key => $value) { $message[$key] = api_xml_http_response_encode($value); } $messageList[] = $message; } return $messageList; } /** * @param array $aboutUserInfo * @param array $fromUserInfo * @param string $subject * @param string $content * * @return bool */ public static function sendMessageAboutUser( $aboutUserInfo, $fromUserInfo, $subject, $content ) { if (empty($aboutUserInfo) || empty($fromUserInfo)) { return false; } if (empty($fromUserInfo['id']) || empty($aboutUserInfo['id'])) { return false; } $table = Database::get_main_table(TABLE_MESSAGE); $now = api_get_utc_datetime(); $params = [ 'user_sender_id' => $fromUserInfo['id'], 'user_receiver_id' => $aboutUserInfo['id'], 'msg_status' => MESSAGE_STATUS_CONVERSATION, 'send_date' => $now, 'title' => $subject, 'content' => $content, 'group_id' => 0, 'parent_id' => 0, 'update_date' => $now, ]; $id = Database::insert($table, $params); if ($id) { return true; } return false; } public static function getMessagesAboutUser(User $user): array { if (!empty($user)) { $table = Database::get_main_table(TABLE_MESSAGE); $sql = 'SELECT id FROM '.$table.' WHERE user_receiver_id = '.$user->getId().' AND msg_status = '.MESSAGE_STATUS_CONVERSATION.' '; $result = Database::query($sql); $messages = []; $repo = Database::getManager()->getRepository(Message::class); while ($row = Database::fetch_array($result)) { $message = $repo->find($row['id']); $messages[] = $message; } return $messages; } return []; } public static function getMessagesAboutUserToString(User $user): string { $messages = self::getMessagesAboutUser($user); $html = ''; if (!empty($messages)) { /** @var Message $message */ foreach ($messages as $message) { $tag = 'message_'.$message->getId(); $tagAccordion = 'accordion_'.$message->getId(); $tagCollapse = 'collapse_'.$message->getId(); $date = Display::dateToStringAgoAndLongDate( $message->getSendDate() ); $localTime = api_get_local_time( $message->getSendDate(), null, null, false, false ); $senderId = $message->getUserSender()->getId(); $senderInfo = api_get_user_info($senderId); $html .= Display::panelCollapse( $localTime.' '.$senderInfo['complete_name'].' '.$message->getTitle(), $message->getContent().'
'.$date.'
'.get_lang( 'Author' ).': '.$senderInfo['complete_name_with_message_link'], $tag, null, $tagAccordion, $tagCollapse, false ); } } return $html; } /** * @param int $senderId * @param int $receiverId * @param string $subject * @param string $message * * @return bool */ public static function messageWasAlreadySent($senderId, $receiverId, $subject, $message) { $table = Database::get_main_table(TABLE_MESSAGE); $senderId = (int) $senderId; $receiverId = (int) $receiverId; $subject = Database::escape_string($subject); $message = Database::escape_string($message); $sql = "SELECT * FROM $table WHERE user_sender_id = $senderId AND user_receiver_id = $receiverId AND title = '$subject' AND content = '$message' AND (msg_status = ".MESSAGE_STATUS_UNREAD." OR msg_status = ".MESSAGE_STATUS_NEW.") "; $result = Database::query($sql); return Database::num_rows($result) > 0; } /** * Sends a message to a user/group. * * @param int $receiverUserId * @param string $subject * @param string $content * @param array $attachments files array($_FILES) (optional) * @param array $fileCommentList about attachment files (optional) * @param int $group_id (optional) * @param int $parent_id (optional) * @param int $editMessageId id for updating the message (optional) * @param int $topic_id (optional) the default value is the current user_id * @param int $sender_id * @param bool $directMessage * @param int $forwardId * @param array $smsParameters * @param bool $checkCurrentAudioId * @param bool $forceTitleWhenSendingEmail force the use of $title as subject instead of "You have a new message" * @param int $status Message status * * @return bool */ public static function send_message( $receiverUserId, $subject, $content, array $attachments = [], array $fileCommentList = [], $group_id = 0, $parent_id = 0, $editMessageId = 0, $topic_id = 0, $sender_id = 0, $directMessage = false, $forwardId = 0, $smsParameters = [], $checkCurrentAudioId = false, $forceTitleWhenSendingEmail = false, $status = 0 ) { $group_id = (int) $group_id; $receiverUserId = (int) $receiverUserId; $parent_id = (int) $parent_id; $editMessageId = (int) $editMessageId; $topic_id = (int) $topic_id; $status = empty($status) ? MESSAGE_STATUS_UNREAD : (int) $status; $user_sender_id = empty($sender_id) ? api_get_user_id() : (int) $sender_id; if (empty($user_sender_id) || empty($receiverUserId)) { return false; } $userSender = api_get_user_entity($user_sender_id); if (null === $userSender) { Display::addFlash(Display::return_message(get_lang('This user doesn\'t exist'), 'warning')); return false; } $userRecipient = api_get_user_entity($receiverUserId); if (null === $userRecipient) { return false; } // Disabling messages for inactive users. if (0 == $userRecipient->getActive()) { return false; } $sendEmail = true; // Disabling messages depending the pausetraining plugin. $allowPauseFormation = 'true' === api_get_plugin_setting('pausetraining', 'tool_enable') && 'true' === api_get_plugin_setting('pausetraining', 'allow_users_to_edit_pause_formation'); if ($allowPauseFormation) { $extraFieldValue = new ExtraFieldValue('user'); $disableEmails = $extraFieldValue->get_values_by_handler_and_field_variable( $receiverUserId, 'disable_emails' ); // User doesn't want email notifications but chamilo inbox still available. if (!empty($disableEmails) && isset($disableEmails['value']) && 1 === (int) $disableEmails['value'] ) { $sendEmail = false; } if ($sendEmail) { // Check if user pause his formation. $pause = $extraFieldValue->get_values_by_handler_and_field_variable( $receiverUserId, 'pause_formation' ); if (!empty($pause) && isset($pause['value']) && 1 === (int) $pause['value']) { $startDate = $extraFieldValue->get_values_by_handler_and_field_variable( $receiverUserId, 'start_pause_date' ); $endDate = $extraFieldValue->get_values_by_handler_and_field_variable( $receiverUserId, 'end_pause_date' ); if ( !empty($startDate) && isset($startDate['value']) && !empty($startDate['value']) && !empty($endDate) && isset($endDate['value']) && !empty($endDate['value']) ) { $now = time(); $start = api_strtotime($startDate['value']); $end = api_strtotime($endDate['value']); if ($now > $start && $now < $end) { $sendEmail = false; } } } } } $totalFileSize = 0; $attachmentList = []; if (is_array($attachments)) { $counter = 0; foreach ($attachments as $attachment) { $attachment['comment'] = isset($fileCommentList[$counter]) ? $fileCommentList[$counter] : ''; $fileSize = isset($attachment['size']) ? $attachment['size'] : 0; if (is_array($fileSize)) { foreach ($fileSize as $size) { $totalFileSize += $size; } } else { $totalFileSize += $fileSize; } $attachmentList[] = $attachment; $counter++; } } if ($checkCurrentAudioId) { // Add the audio file as an attachment $audioId = Session::read('current_audio_id'); if (!empty($audioId)) { $file = api_get_uploaded_file('audio_message', api_get_user_id(), $audioId); if (!empty($file)) { $audioAttachment = [ 'name' => basename($file), 'comment' => 'audio_message', 'size' => filesize($file), 'tmp_name' => $file, 'error' => 0, 'type' => DocumentManager::file_get_mime_type(basename($file)), ]; // create attachment from audio message $attachmentList[] = $audioAttachment; } } } // Validating fields if (empty($subject) && empty($group_id)) { Display::addFlash( Display::return_message( get_lang('You should write a subject'), 'warning' ) ); return false; } elseif ($totalFileSize > (int) api_get_setting('message_max_upload_filesize')) { $warning = sprintf( get_lang('Files size exceeds'), format_file_size(api_get_setting('message_max_upload_filesize')) ); Display::addFlash(Display::return_message($warning, 'warning')); return false; } $now = api_get_utc_datetime(); $table = Database::get_main_table(TABLE_MESSAGE); $em = Database::getManager(); $message = null; // Just in case we replace the and \n and \n\r while saving in the DB if (!empty($receiverUserId) || !empty($group_id)) { // message for user friend //@todo it's possible to edit a message? yes, only for groups if (!empty($editMessageId)) { $query = " UPDATE $table SET update_date = '".$now."', content = '".Database::escape_string($content)."' WHERE id = '$editMessageId' "; Database::query($query); $messageId = $editMessageId; } else { $repo = $em->getRepository(Message::class); $parent = $repo->find($parent_id); $message = new Message(); $message ->setUserSender($userSender) ->setUserReceiver($userRecipient) ->setMsgStatus($status) ->setTitle($subject) ->setContent($content) ->setGroupId($group_id) ->setParent($parent) ; $em->persist($message); $em->flush(); $messageId = $message->getId(); } // Forward also message attachments. $forwardAttachments = []; if (!empty($forwardId)) { $forwardMessage = $repo->find($forwardId); if (null !== $forwardMessage) { $forwardAttachments = $forwardMessage->getAttachments(); foreach ($forwardAttachments as $forwardAttachment) { $message->addAttachment($forwardAttachment); } $em->persist($message); $em->flush(); } } // Save attachment file for inbox messages if (is_array($attachmentList)) { foreach ($attachmentList as $attachment) { if (0 == $attachment['error']) { $comment = $attachment['comment']; self::saveMessageAttachmentFile( $attachment, $comment, $message, null, $receiverUserId, $group_id ); } } } // Save message in the outbox for user friend or group. if (empty($group_id) && MESSAGE_STATUS_UNREAD === $status) { $params = [ 'user_sender_id' => $user_sender_id, 'user_receiver_id' => $receiverUserId, 'msg_status' => MESSAGE_STATUS_OUTBOX, 'send_date' => $now, 'title' => $subject, 'content' => $content, 'group_id' => $group_id, 'parent_id' => $parent_id, 'update_date' => $now, ]; Database::insert($table, $params); // save attachment file for outbox messages /*if (is_array($attachmentList)) { foreach ($attachmentList as $attachment) { if (0 == $attachment['error']) { $comment = $attachment['comment']; self::saveMessageAttachmentFile( $attachment, $comment, $outbox_last_id, $user_sender_id ); } } }*/ } if ($sendEmail) { $notification = new Notification(); $sender_info = api_get_user_info($user_sender_id); // add file attachment additional attributes $attachmentAddedByMail = []; foreach ($attachmentList as $attachment) { $attachmentAddedByMail[] = [ 'path' => $attachment['tmp_name'], 'filename' => $attachment['name'], ]; } if (empty($group_id)) { $type = Notification::NOTIFICATION_TYPE_MESSAGE; if ($directMessage) { $type = Notification::NOTIFICATION_TYPE_DIRECT_MESSAGE; } $notification->saveNotification( $messageId, $type, [$receiverUserId], $subject, $content, $sender_info, $attachmentAddedByMail, $smsParameters, $forceTitleWhenSendingEmail ); } else { $usergroup = new UserGroup(); $group_info = $usergroup->get($group_id); $group_info['topic_id'] = $topic_id; $group_info['msg_id'] = $messageId; $user_list = $usergroup->get_users_by_group( $group_id, false, [], 0, 1000 ); // Adding more sense to the message group $subject = sprintf(get_lang('There is a new message in group %s'), $group_info['name']); $new_user_list = []; foreach ($user_list as $user_data) { $new_user_list[] = $user_data['id']; } $group_info = [ 'group_info' => $group_info, 'user_info' => $sender_info, ]; $notification->saveNotification( $messageId, Notification::NOTIFICATION_TYPE_GROUP, $new_user_list, $subject, $content, $group_info, $attachmentAddedByMail, $smsParameters ); } } return $messageId; } return false; } /** * @param int $receiverUserId * @param int $subject * @param string $message * @param int $sender_id * @param bool $sendCopyToDrhUsers send copy to related DRH users * @param bool $directMessage * @param array $smsParameters * @param bool $uploadFiles Do not upload files using the MessageManager class * @param array $attachmentList * * @return bool */ public static function send_message_simple( $receiverUserId, $subject, $message, $sender_id = 0, $sendCopyToDrhUsers = false, $directMessage = false, $smsParameters = [], $uploadFiles = true, $attachmentList = [] ) { $files = $_FILES ? $_FILES : []; if (false === $uploadFiles) { $files = []; } // $attachmentList must have: tmp_name, name, size keys if (!empty($attachmentList)) { $files = $attachmentList; } $result = self::send_message( $receiverUserId, $subject, $message, $files, [], null, null, null, null, $sender_id, $directMessage, 0, $smsParameters ); if ($sendCopyToDrhUsers) { $userInfo = api_get_user_info($receiverUserId); $drhList = UserManager::getDrhListFromUser($receiverUserId); if (!empty($drhList)) { foreach ($drhList as $drhInfo) { $message = sprintf( get_lang('Copy of message sent to %s'), $userInfo['complete_name'] ).'
'.$message; self::send_message_simple( $drhInfo['id'], $subject, $message, $sender_id, false, $directMessage ); } } } return $result; } /** * @param int $user_receiver_id * @param int $id * * @return bool */ public static function delete_message_by_user_receiver($user_receiver_id, $id) { $id = (int) $id; $user_receiver_id = (int) $user_receiver_id; if (empty($id) || empty($user_receiver_id)) { return false; } $em = Database::getManager(); $repo = $em->getRepository(Message::class); $criteria = ['id' => $id, 'userReceiver' => $user_receiver_id]; $message = $repo->findOneBy($criteria); if (null === $message || ($message && MESSAGE_STATUS_OUTBOX === $message->getMsgStatus())) { return false; } $message->setMsgStatus(MESSAGE_STATUS_DELETED); $attachments = $message->getAttachments(); if (!empty($attachments)) { $repo = Container::getMessageAttachmentRepository(); foreach ($attachments as $file) { $repo->softDelete($file); } } $em->persist($message); $em->flush(); /* // Delete attachment file. self::delete_message_attachment_file($id, $user_receiver_id); // Soft delete message. $query = "UPDATE $table SET msg_status = ".MESSAGE_STATUS_DELETED." WHERE id = $id AND user_receiver_id = $user_receiver_id "; Database::query($query);*/ return true; } /** * Set status deleted. * * @author Isaac FLores Paz * * @param int * @param int * * @return bool */ public static function delete_message_by_user_sender($user_sender_id, $id) { $user_sender_id = (int) $user_sender_id; $id = (int) $id; if (empty($id) || empty($user_sender_id)) { return false; } $em = Database::getManager(); $repo = $em->getRepository(Message::class); $criteria = ['id' => $id, 'userSender' => $user_sender_id]; $message = $repo->findOneBy($criteria); /*$table = Database::get_main_table(TABLE_MESSAGE); $sql = "SELECT * FROM $table WHERE id = $id AND user_sender_id= $user_sender_id"; $rs = Database::query($sql);*/ if (null !== $message) { // delete attachment file //self::delete_message_attachment_file($id, $user_sender_id); $message->setMsgStatus(MESSAGE_STATUS_DELETED); self::softDeleteAttachments($message); $em->persist($message); $em->flush(); return true; } return false; } public static function softDeleteAttachments(Message $message): void { $attachments = $message->getAttachments(); if (!empty($attachments)) { $repo = Container::getMessageAttachmentRepository(); foreach ($attachments as $file) { $repo->softDelete($file); } } } /** * Saves a message attachment files. * * @param array $file $_FILES['name'] * @param string $comment a comment about the uploaded file */ public static function saveMessageAttachmentFile($file, $comment, Message $message) { // Try to add an extension to the file if it hasn't one $type = $file['type'] ?? ''; if (empty($type)) { $type = DocumentManager::file_get_mime_type($file['name']); } $new_file_name = add_ext_on_mime(stripslashes($file['name']), $type); // user's file name $file_name = $file['name']; if (!filter_extension($new_file_name)) { Display::addFlash( Display::return_message( get_lang('File upload failed: this file extension or file type is prohibited'), 'error' ) ); } else { $em = Database::getManager(); $attachmentRepo = Container::getMessageAttachmentRepository(); $attachment = new MessageAttachment(); $attachment ->setSize($file['size']) ->setPath($file_name) ->setFilename($file_name) ->setComment($comment) ->setParent($message->getUserSender()) ->setMessage($message) ; $request = Container::getRequest(); $fileToUpload = null; /** @var UploadedFile $fileRequest */ foreach ($request->files->all() as $fileRequest) { if ($fileRequest->getClientOriginalName() === $file['name']) { $fileToUpload = $fileRequest; break; } } $em->persist($attachment); if (null !== $fileToUpload) { $attachmentRepo->addFile($attachment, $fileToUpload); $attachment->addUserLink($message->getUserSender()); $attachment->addUserLink($message->getUserReceiver()); } $em->flush(); } return false; } /** * @param int $user_id * @param int $message_id * @param int $type * * @return bool */ public static function update_message_status($user_id, $message_id, $type) { $user_id = (int) $user_id; $message_id = (int) $message_id; $type = (int) $type; if (empty($user_id) || empty($message_id)) { return false; } $table_message = Database::get_main_table(TABLE_MESSAGE); $sql = "UPDATE $table_message SET msg_status = '$type' WHERE user_receiver_id = ".$user_id." AND id = '".$message_id."'"; $result = Database::query($sql); return Database::affected_rows($result) > 0; } /** * get messages by group id. * * @param int $group_id group id * * @return array */ public static function get_messages_by_group($group_id) { $group_id = (int) $group_id; if (empty($group_id)) { return false; } $table = Database::get_main_table(TABLE_MESSAGE); $sql = "SELECT * FROM $table WHERE group_id= $group_id AND msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."') ORDER BY id"; $rs = Database::query($sql); $data = []; if (Database::num_rows($rs) > 0) { while ($row = Database::fetch_array($rs, 'ASSOC')) { $data[] = $row; } } return $data; } /** * get messages by group id. * * @param int $group_id * @param int $message_id * * @return array */ public static function get_messages_by_group_by_message($group_id, $message_id) { $group_id = (int) $group_id; if (empty($group_id)) { return false; } $table = Database::get_main_table(TABLE_MESSAGE); $sql = "SELECT * FROM $table WHERE group_id = $group_id AND msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."') ORDER BY id "; $rs = Database::query($sql); $data = []; $parents = []; if (Database::num_rows($rs) > 0) { while ($row = Database::fetch_array($rs, 'ASSOC')) { if ($message_id == $row['parent_id'] || in_array($row['parent_id'], $parents)) { $parents[] = $row['id']; $data[] = $row; } } } return $data; } /** * Get messages by parent id optionally with limit. * * @param int parent id * @param int group id (optional) * @param int offset (optional) * @param int limit (optional) * * @return array */ public static function getMessagesByParent($parentId, $groupId = 0, $offset = 0, $limit = 0) { $table = Database::get_main_table(TABLE_MESSAGE); $parentId = (int) $parentId; if (empty($parentId)) { return []; } $condition_group_id = ''; if (!empty($groupId)) { $groupId = (int) $groupId; $condition_group_id = " AND group_id = '$groupId' "; } $condition_limit = ''; if ($offset && $limit) { $offset = (int) $offset; $limit = (int) $limit; $offset = ($offset - 1) * $limit; $condition_limit = " LIMIT $offset,$limit "; } $sql = "SELECT * FROM $table WHERE parent_id='$parentId' AND msg_status NOT IN (".MESSAGE_STATUS_OUTBOX.", ".MESSAGE_STATUS_WALL_DELETE.") $condition_group_id ORDER BY send_date DESC $condition_limit "; $rs = Database::query($sql); $data = []; if (Database::num_rows($rs) > 0) { while ($row = Database::fetch_array($rs)) { $data[$row['id']] = $row; } } return $data; } /** * Gets information about messages sent. * * @param int * @param int * @param string * @param string * * @return array */ public static function get_message_data_sent( $from, $numberOfItems, $column, $direction, $extraParams = [] ) { $from = (int) $from; $numberOfItems = (int) $numberOfItems; if (!isset($direction)) { $column = 2; $direction = 'DESC'; } else { $column = (int) $column; if (!in_array($direction, ['ASC', 'DESC'])) { $direction = 'ASC'; } } if (!in_array($column, [0, 1, 2])) { $column = 2; } $table = Database::get_main_table(TABLE_MESSAGE); $request = api_is_xml_http_request(); $keyword = isset($extraParams['keyword']) && !empty($extraParams['keyword']) ? $extraParams['keyword'] : ''; $keywordCondition = ''; if (!empty($keyword)) { $keyword = Database::escape_string($keyword); $keywordCondition = " AND (title like '%$keyword%' OR content LIKE '%$keyword%') "; } $sql = "SELECT id as col0, title as col1, send_date as col2, user_receiver_id, msg_status, user_sender_id FROM $table WHERE user_sender_id = ".api_get_user_id()." AND msg_status = ".MESSAGE_STATUS_OUTBOX." $keywordCondition ORDER BY col$column $direction LIMIT $from, $numberOfItems"; $result = Database::query($sql); $message_list = []; while ($row = Database::fetch_array($result, 'ASSOC')) { $messageId = $row['col0']; $title = $row['col1']; $sendDate = $row['col2']; $senderId = $row['user_sender_id']; if (true === $request) { $message[0] = ''; } else { $message[0] = $messageId; } $class = 'class = "read"'; $title = Security::remove_XSS($title); $userInfo = api_get_user_info($senderId); if (true === $request) { $message[1] = ''. $userInfo['complete_name_with_username'].''; $message[2] = ''.str_replace( "\\", "", $title ).''; //date stays the same $message[3] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG); $message[4] = '  '. Display::returnFontAwesomeIcon('trash', 2).''; } else { $message[1] = ''.$title.'
'.$userInfo['complete_name_with_username']; $message[2] = api_convert_and_format_date($sendDate, DATE_TIME_FORMAT_LONG); $message[3] = ''. Display::returnFontAwesomeIcon('trash', 2).''; } $message_list[] = $message; } return $message_list; } /** * display message box in the inbox. * * @param int $messageId * @param int $type * * @todo replace numbers with letters in the $row array pff... * * @return string html with the message content */ public static function showMessageBox($messageId, $type) { $messageId = (int) $messageId; if (empty($messageId) || empty($type)) { return ''; } $currentUserId = api_get_user_id(); $criteria = []; $status = null; switch ($type) { case self::MESSAGE_TYPE_OUTBOX: $userCondition = " user_sender_id = $currentUserId AND "; $criteria['userSender'] = $currentUserId; $criteria['msgStatus'] = MESSAGE_STATUS_OUTBOX; break; case self::MESSAGE_TYPE_INBOX: $userCondition = " user_receiver_id = $currentUserId AND "; $criteria['userReceiver'] = $currentUserId; /*$query = "UPDATE $table SET msg_status = '".MESSAGE_STATUS_NEW."' WHERE id = $messageId "; Database::query($query);*/ break; case self::MESSAGE_TYPE_PROMOTED: $userCondition = " user_receiver_id = $currentUserId AND "; $criteria['userReceiver'] = $currentUserId; $criteria['msgStatus'] = MESSAGE_STATUS_PROMOTED; break; } $criteria['id'] = $messageId; $em = Database::getManager(); $repo = $em->getRepository(Message::class); $message = $repo->findOneBy($criteria); if (null === $message) { return ''; } /*if (self::MESSAGE_TYPE_INBOX === $type) { $message->setMsgStatus(MESSAGE_STATUS_NEW); $em->persist($message); $em->flush(); }*/ $table = Database::get_main_table(TABLE_MESSAGE); /* Get previous message */ $query = "SELECT id FROM $table WHERE $userCondition id < $messageId ORDER BY id DESC LIMIT 1 "; $result = Database::query($query); $rowPrevMessage = Database::fetch_array($result, 'ASSOC'); $idPrevMessage = (int) isset($rowPrevMessage['id']) ? $rowPrevMessage['id'] : 0; /* Get next message */ $query = "SELECT id FROM $table WHERE $userCondition id > $messageId ORDER BY id ASC LIMIT 1 "; $result = Database::query($query); $rowNextMessage = Database::fetch_array($result, 'ASSOC'); $idNextMessage = (int) isset($rowNextMessage['id']) ? $rowNextMessage['id'] : 0; // get file attachments by message id $filesAttachments = self::getAttachmentLinkList($message, $type); $title = Security::remove_XSS($message->getTitle(), STUDENT, true); $content = str_replace('
', '
', $message->getContent()); $content = Security::remove_XSS($content, STUDENT, true); $name = get_lang('Unknown user'); $userImage = ''; if (null !== $message->getUserSender()) { $name = UserManager::formatUserFullName($message->getUserSender()); /*$userImage = Display::img( $fromUser['avatar_small'], $name, ['title' => $name, 'class' => 'img-responsive img-circle', 'style' => 'max-width:35px'], false );*/ } $messageContent = Display::page_subheader(str_replace("\\", '', $title)); $messageContent .= ''; if ('true' === api_get_setting('allow_social_tool')) { $messageContent .= '
'; $messageContent .= '
'; $messageContent .= '
    '; if (null !== $message->getUserSender()) { $messageContent .= '
  • '.$userImage.'
  • '; $messageContent .= '
  • '; $messageContent .= Display::url( $name, api_get_path(WEB_PATH).'main/social/profile.php?u='.$message->getUserSender()->getId() ); } else { $messageContent .= '
  • '.$name; } switch ($type) { case self::MESSAGE_TYPE_INBOX: $messageContent .= ' '.get_lang('To').' '.get_lang('Me'); break; case self::MESSAGE_TYPE_OUTBOX: if (null !== $message->getUserReceiver()) { $messageContent .= ' '.get_lang('To') .' '.UserManager::formatUserFullName($message->getUserReceiver()).'
  • '; } break; case self::MESSAGE_TYPE_PROMOTED: break; } $messageContent .= ' 
  • '.Display::dateToStringAgoAndLongDate($message->getSendDate()).'
  • '; $messageContent .= '
'; $messageContent .= '
'; $messageContent .= '
'; } else { switch ($type) { case self::MESSAGE_TYPE_INBOX: $messageContent .= get_lang('From').': '.$name.' '.get_lang('To').' '. get_lang('Me').''; break; case self::MESSAGE_TYPE_OUTBOX: $messageContent .= get_lang('From').': '.$name.' '.get_lang('To').' '. UserManager::formatUserFullName($message->getUserReceiver()).''; break; } } $messageContent .= '
'. str_replace("\\", "", $content).'
'.(!empty($filesAttachments) ? implode('
', $filesAttachments) : '').'
'; $social_link = ''; if (isset($_GET['f']) && 'social' === $_GET['f']) { $social_link = 'f=social'; } switch ($type) { case self::MESSAGE_TYPE_OUTBOX: $messageContent .= ''. Display::return_icon('back.png', get_lang('Return to outbox')).'  '; $messageContent .= ''. Display::return_icon('delete.png', get_lang('Delete message')).' '; break; case self::MESSAGE_TYPE_INBOX: $messageContent .= ''. Display::return_icon('back.png', get_lang('Return to inbox')).'  '; $messageContent .= ''. Display::return_icon('message_reply.png', get_lang('Reply to this message')).'  '; $messageContent .= ''. Display::return_icon('delete.png', get_lang('DeleteMessage')).' '; if (0 != $idPrevMessage) { $messageContent .= ''. Display::return_icon('icons/22/back.png', get_lang('ScormPrevious')).'  '; } if (0 != $idNextMessage) { $messageContent .= ''. Display::return_icon('icons/22/move.png', get_lang('ScormNext')).'  '; } break; } $messageContent .= '
'; return $messageContent; } /** * get user id by user email. * * @param string $user_email * * @return int user id */ public static function get_user_id_by_email($user_email) { $table = Database::get_main_table(TABLE_MAIN_USER); $sql = 'SELECT user_id FROM '.$table.' WHERE email="'.Database::escape_string($user_email).'";'; $rs = Database::query($sql); $row = Database::fetch_array($rs, 'ASSOC'); if (isset($row['user_id'])) { return $row['user_id']; } return null; } /** * Displays messages of a group with nested view. * * @param int $groupId * * @return string */ public static function display_messages_for_group($groupId) { global $my_group_role; $rows = self::get_messages_by_group($groupId); $topics_per_page = 10; $html_messages = ''; $query_vars = ['id' => $groupId, 'topics_page_nr' => 0]; if (is_array($rows) && count($rows) > 0) { // prepare array for topics with its items $topics = []; $x = 0; foreach ($rows as $index => $value) { if (empty($value['parent_id'])) { $topics[$value['id']] = $value; } } $new_topics = []; foreach ($topics as $id => $value) { $rows = null; $rows = self::get_messages_by_group_by_message($groupId, $value['id']); if (!empty($rows)) { $count = count(self::calculate_children($rows, $value['id'])); } else { $count = 0; } $value['count'] = $count; $new_topics[$id] = $value; } $array_html = []; foreach ($new_topics as $index => $topic) { $html = ''; // topics $user_sender_info = api_get_user_info($topic['user_sender_id']); $name = $user_sender_info['complete_name']; $html .= '
'; $html .= '
'; $items = $topic['count']; $reply_label = (1 == $items) ? get_lang('Reply') : get_lang('Replies'); $label = ' '.$items.' '.$reply_label; $topic['title'] = trim($topic['title']); if (empty($topic['title'])) { $topic['title'] = get_lang('Untitled'); } $html .= '
'; $html .= Display::tag( 'h4', Display::url( Security::remove_XSS($topic['title'], STUDENT, true), api_get_path(WEB_CODE_PATH).'social/group_topics.php?id='.$groupId.'&topic_id='.$topic['id'] ), ['class' => 'title'] ); $actions = ''; if (GROUP_USER_PERMISSION_ADMIN == $my_group_role || GROUP_USER_PERMISSION_MODERATOR == $my_group_role ) { $actions = '
'.Display::url( get_lang('Delete'), api_get_path( WEB_CODE_PATH ).'social/group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic['id'], ['class' => 'btn btn-default'] ); } $date = ''; if ($topic['send_date'] != $topic['update_date']) { if (!empty($topic['update_date'])) { $date .= ' '.get_lang( 'LastUpdate' ).' '.Display::dateToStringAgoAndLongDate($topic['update_date']); } } else { $date .= ' '.get_lang( 'Created' ).' '.Display::dateToStringAgoAndLongDate($topic['send_date']); } $html .= '
'.$label.' - '.$date.$actions.'
'; $html .= '
'; $image = $user_sender_info['avatar']; $user_info = '
'.$name.'
'; $user_info .= ''; $html .= '
'; $html .= $user_info; $html .= '
'; $html .= '
'; $html .= '
'; $array_html[] = [$html]; } // grids for items and topics with paginations $html_messages .= Display::return_sortable_grid( 'topics', [], $array_html, [ 'hide_navigation' => false, 'per_page' => $topics_per_page, ], $query_vars, false, [true, true, true, false], false ); } return $html_messages; } /** * Displays messages of a group with nested view. * * @param $groupId * @param $topic_id * * @return string */ public static function display_message_for_group($groupId, $topic_id) { global $my_group_role; $main_message = self::get_message_by_id($topic_id); if (empty($main_message)) { return false; } $webCodePath = api_get_path(WEB_CODE_PATH); $iconCalendar = Display::returnFontAwesomeIcon('calendar'); $langEdit = get_lang('Edit'); $langReply = get_lang('Reply'); $langLastUpdated = get_lang('LastUpdated'); $langCreated = get_lang('Created'); $rows = self::get_messages_by_group_by_message($groupId, $topic_id); $rows = self::calculate_children($rows, $topic_id); $current_user_id = api_get_user_id(); $items_per_page = 50; $query_vars = ['id' => $groupId, 'topic_id' => $topic_id, 'topics_page_nr' => 0]; // Main message $links = ''; $main_content = ''; $html = ''; $items_page_nr = null; $user_sender_info = api_get_user_info($main_message['user_sender_id']); $filesAttachments = self::getAttachmentLinkList($main_message['id'], 0); $name = $user_sender_info['complete_name']; $topic_page_nr = isset($_GET['topics_page_nr']) ? (int) $_GET['topics_page_nr'] : null; $links .= '
'; $links .= '
'; if ((GROUP_USER_PERMISSION_ADMIN == $my_group_role || GROUP_USER_PERMISSION_MODERATOR == $my_group_role) || $main_message['user_sender_id'] == $current_user_id ) { $urlEdit = $webCodePath.'social/message_for_group_form.inc.php?' .http_build_query( [ 'user_friend' => $current_user_id, 'group_id' => $groupId, 'message_id' => $main_message['id'], 'action' => 'edit_message_group', 'anchor_topic' => 'topic_'.$main_message['id'], 'topics_page_nr' => $topic_page_nr, 'items_page_nr' => $items_page_nr, 'topic_id' => $main_message['id'], ] ); $links .= Display::toolbarButton( $langEdit, $urlEdit, 'pencil', 'default', ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'], false ); } $links .= self::getLikesButton($main_message['id'], $current_user_id, $groupId); $urlReply = $webCodePath.'social/message_for_group_form.inc.php?' .http_build_query( [ 'user_friend' => $current_user_id, 'group_id' => $groupId, 'message_id' => $main_message['id'], 'action' => 'reply_message_group', 'anchor_topic' => 'topic_'.$main_message['id'], 'topics_page_nr' => $topic_page_nr, 'topic_id' => $main_message['id'], ] ); $links .= Display::toolbarButton( $langReply, $urlReply, 'commenting', 'default', ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'], false ); if (api_is_platform_admin()) { $links .= Display::toolbarButton( get_lang('Delete'), 'group_topics.php?action=delete&id='.$groupId.'&topic_id='.$topic_id, 'trash', 'default', [], false ); } $links .= '
'; $links .= '
'; $title = '

'.Security::remove_XSS($main_message['title'], STUDENT, true).$links.'

'; $userPicture = $user_sender_info['avatar']; $main_content .= '
'; $main_content .= '
'; $main_content .= '
'; $main_content .= Display::img( $userPicture, $name, ['width' => '60px', 'class' => 'img-responsive img-circle'], false ); $main_content .= '
'; $main_content .= '
'; $date = ''; if ($main_message['send_date'] != $main_message['update_date']) { if (!empty($main_message['update_date'])) { $date = '
' ."$iconCalendar $langLastUpdated " .Display::dateToStringAgoAndLongDate($main_message['update_date']) .'
'; } } else { $date = '
' ."$iconCalendar $langCreated " .Display::dateToStringAgoAndLongDate($main_message['send_date']) .'
'; } $attachment = '
' .(!empty($filesAttachments) ? implode('
', $filesAttachments) : '') .'
'; $main_content .= '
'; $user_link = Display::url( $name, $webCodePath.'social/profile.php?u='.$main_message['user_sender_id'] ); $main_content .= '
'; $main_content .= '
'.$user_link.'
'; $main_content .= $date; $main_content .= '
'.$main_message['content'].$attachment.'
'; $main_content .= '
'; $main_content .= '
'; $html .= Display::div( Display::div( $title.$main_content, ['class' => 'message-topic'] ), ['class' => 'sm-groups-message'] ); $topic_id = $main_message['id']; if (is_array($rows) && count($rows) > 0) { $topics = $rows; $array_html_items = []; foreach ($topics as $index => $topic) { if (empty($topic['id'])) { continue; } $items_page_nr = isset($_GET['items_'.$topic['id'].'_page_nr']) ? (int) $_GET['items_'.$topic['id'].'_page_nr'] : null; $links = ''; $links .= '
'; $html_items = ''; $user_sender_info = api_get_user_info($topic['user_sender_id']); $filesAttachments = self::getAttachmentLinkList($topic['id'], 0); $name = $user_sender_info['complete_name']; $links .= '
'; if ( (GROUP_USER_PERMISSION_ADMIN == $my_group_role || GROUP_USER_PERMISSION_MODERATOR == $my_group_role ) || $topic['user_sender_id'] == $current_user_id ) { $links .= Display::toolbarButton( $langEdit, $webCodePath.'social/message_for_group_form.inc.php?' .http_build_query( [ 'user_friend' => $current_user_id, 'group_id' => $groupId, 'message_id' => $topic['id'], 'action' => 'edit_message_group', 'anchor_topic' => 'topic_'.$topic_id, 'topics_page_nr' => $topic_page_nr, 'items_page_nr' => $items_page_nr, 'topic_id' => $topic_id, ] ), 'pencil', 'default', ['class' => 'ajax', 'data-title' => $langEdit, 'data-size' => 'lg'], false ); } $links .= self::getLikesButton($topic['id'], $current_user_id, $groupId); $links .= Display::toolbarButton( $langReply, $webCodePath.'social/message_for_group_form.inc.php?' .http_build_query( [ 'user_friend' => $current_user_id, 'group_id' => $groupId, 'message_id' => $topic['id'], 'action' => 'reply_message_group', 'anchor_topic' => 'topic_'.$topic_id, 'topics_page_nr' => $topic_page_nr, 'items_page_nr' => $items_page_nr, 'topic_id' => $topic_id, ] ), 'commenting', 'default', ['class' => 'ajax', 'data-title' => $langReply, 'data-size' => 'lg'], false ); $links .= '
'; $links .= '
'; $userPicture = $user_sender_info['avatar']; $user_link = Display::url( $name, $webCodePath.'social/profile.php?u='.$topic['user_sender_id'] ); $html_items .= '
'; $html_items .= '
'; $html_items .= '
'; $html_items .= Display::img( $userPicture, $name, ['width' => '60px', 'class' => 'img-responsive img-circle'], false ); $html_items .= '
'; $html_items .= '
'; $date = ''; if ($topic['send_date'] != $topic['update_date']) { if (!empty($topic['update_date'])) { $date = '
' ."$iconCalendar $langLastUpdated " .Display::dateToStringAgoAndLongDate($topic['update_date']) .'
'; } } else { $date = '
' ."$iconCalendar $langCreated " .Display::dateToStringAgoAndLongDate($topic['send_date']) .'
'; } $attachment = '
' .(!empty($filesAttachments) ? implode('
', $filesAttachments) : '') .'
'; $html_items .= '
' .'
' .$links .'
'.$user_link.'
' .$date .'
' .Security::remove_XSS($topic['content'], STUDENT, true) .'
'.$attachment.'
' .'
' .'
'; $base_padding = 20; if (0 == $topic['indent_cnt']) { $indent = $base_padding; } else { $indent = (int) $topic['indent_cnt'] * $base_padding + $base_padding; } $html_items = Display::div($html_items, ['class' => 'message-post', 'id' => 'msg_'.$topic['id']]); $html_items = Display::div($html_items, ['class' => '', 'style' => 'margin-left:'.$indent.'px']); $array_html_items[] = [$html_items]; } // grids for items with paginations $options = ['hide_navigation' => false, 'per_page' => $items_per_page]; $visibility = [true, true, true, false]; $style_class = [ 'item' => ['class' => 'user-post'], 'main' => ['class' => 'user-list'], ]; if (!empty($array_html_items)) { $html .= Display::return_sortable_grid( 'items_'.$topic['id'], [], $array_html_items, $options, $query_vars, null, $visibility, false, $style_class ); } } return $html; } /** * Add children to messages by id is used for nested view messages. * * @param array $rows rows of messages * * @return array $first_seed new list adding the item children */ public static function calculate_children($rows, $first_seed) { $rows_with_children = []; foreach ($rows as $row) { $rows_with_children[$row["id"]] = $row; $rows_with_children[$row["parent_id"]]["children"][] = $row["id"]; } $rows = $rows_with_children; $sorted_rows = [0 => []]; self::message_recursive_sort($rows, $sorted_rows, $first_seed); unset($sorted_rows[0]); return $sorted_rows; } /** * Sort recursively the messages, is used for for nested view messages. * * @param array original rows of messages * @param array list recursive of messages * @param int seed for calculate the indent * @param int indent for nested view */ public static function message_recursive_sort( $rows, &$messages, $seed = 0, $indent = 0 ) { if ($seed > 0 && isset($rows[$seed]["id"])) { $messages[$rows[$seed]["id"]] = $rows[$seed]; $messages[$rows[$seed]["id"]]["indent_cnt"] = $indent; $indent++; } if (isset($rows[$seed]["children"])) { foreach ($rows[$seed]["children"] as $child) { self::message_recursive_sort($rows, $messages, $child, $indent); } } } /** * Get array of links (download) for message attachment files. * * @return array */ public static function getAttachmentLinkList(Message $message) { //$files = self::getAttachmentList($message); $files = $message->getAttachments(); // get file attachments by message id $list = []; if ($files) { $attachIcon = Display::returnFontAwesomeIcon('paperclip'); $repo = Container::getMessageAttachmentRepository(); foreach ($files as $file) { $size = format_file_size($file->getSize()); $comment = Security::remove_XSS($file->getComment()); $filename = Security::remove_XSS($file->getFilename()); $url = $repo->getResourceFileUrl($file); $link = Display::url($filename, $url); $comment = !empty($comment) ? ' - '.$comment.'' : ''; $attachmentLine = $attachIcon.' '.$link.' ('.$size.')'.$comment; /*if ('audio_message' === $file['comment']) { $attachmentLine = '