mirror of
https://github.com/Bigherollc/wticreatorstudio.git
synced 2026-07-14 18:02:01 -04:00
754 lines
28 KiB
PHP
754 lines
28 KiB
PHP
<?php
|
|
|
|
namespace Modules\Chat\Repositories;
|
|
|
|
use App\Events\GroupEvent;
|
|
use App\Events\UserEvent;
|
|
use App\Exceptions\ApiOperationFailedException;
|
|
use App\Jobs\SendOneSignalPushJob;
|
|
use Modules\Chat\Entities\ArchivedUser;
|
|
use Modules\Chat\Entities\ChatRequestModel;
|
|
use Modules\Chat\Entities\Conversation;
|
|
use Modules\Chat\Entities\Group;
|
|
use Modules\Chat\Entities\GroupMessageRecipient;
|
|
use Modules\Chat\Entities\MessageAction;
|
|
use Modules\Chat\Entities\User;
|
|
use App\Traits\ImageTrait;
|
|
use Auth;
|
|
use Carbon\Carbon;
|
|
use DB;
|
|
use Embed\Embed;
|
|
use Exception;
|
|
use Illuminate\Container\Container as Application;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Query\JoinClause;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
|
|
|
/**
|
|
* Class ChatRepository
|
|
*/
|
|
class ChatRepository extends BaseRepository
|
|
{
|
|
private $groupRepo;
|
|
|
|
public function __construct(Application $app, GroupRepository $groupRepository)
|
|
{
|
|
parent::__construct($app);
|
|
$this->groupRepo = $groupRepository;
|
|
}
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $fieldSearchable = [
|
|
'from_id', 'to_id', 'message', 'status', 'file_name',
|
|
];
|
|
|
|
/**
|
|
* Return searchable fields.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getFieldsSearchable()
|
|
{
|
|
return $this->fieldSearchable;
|
|
}
|
|
|
|
/**
|
|
* Configure the Model.
|
|
**/
|
|
public function model()
|
|
{
|
|
return Conversation::class;
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getLatestConversations($input = [])
|
|
{
|
|
$offset = isset($input['offset']) ? $input['offset'] : 0;
|
|
$isArchived = isset($input['isArchived']) ? 1 : 0;
|
|
$authId = getLoggedInUserId();
|
|
$isGroupChatEnabled = isGroupChatEnabled();
|
|
|
|
$subQuery = Conversation::leftJoin('users as u', 'u.id', '=', DB::raw("if(from_id = $authId, to_id, from_id)"))
|
|
->leftJoin('message_action as ma', function (JoinClause $join) use ($authId) {
|
|
$join->on('ma.deleted_by', '=', DB::raw("$authId"));
|
|
$join->on('ma.conversation_id', '=', 'conversations.id');
|
|
})
|
|
->whereNull('u.deleted_at')
|
|
->where(function (Builder $q) use ($authId) {
|
|
$q->where('from_id', '=', $authId)->orWhere('to_id', '=', $authId);
|
|
})
|
|
->where(function (Builder $q) {
|
|
$q->whereColumn('ma.conversation_id', '!=', 'conversations.id')
|
|
->orWhereNull('ma.conversation_id');
|
|
})
|
|
->where('conversations.to_type', '=', Conversation::class)
|
|
->selectRaw(
|
|
"max(conversations.id) as latest_id , u.id as user_id, 0 as group_id,
|
|
sum(if(conversations.status = 0 and from_id != $authId, 1, 0)) as unread_count"
|
|
)
|
|
->groupBy(DB::raw("if(from_id = $authId, to_id, from_id)"));
|
|
|
|
if ($isGroupChatEnabled) {
|
|
$groupSubQuery = Conversation::leftJoin('message_action as ma', function (JoinClause $join) use ($authId) {
|
|
$join->on('ma.deleted_by', '=', DB::raw("$authId"));
|
|
$join->on('ma.conversation_id', '=', 'conversations.id');
|
|
});
|
|
if (! $isArchived) {
|
|
$groupSubQuery->has('archiveConversation', '=', 0);
|
|
}
|
|
$groupSubQuery->leftJoin('group_message_recipients as gmr', function (JoinClause $join) use ($authId) {
|
|
$join->on('gmr.user_id', '=', DB::raw("$authId"));
|
|
$join->on('gmr.conversation_id', '=', 'conversations.id');
|
|
})
|
|
->leftJoin('users as u', 'u.id', '=', 'conversations.from_id')
|
|
->whereNull('u.deleted_at')
|
|
->whereRaw('to_id IN (select group_id from group_users where user_id = ?)', [$authId])
|
|
->where('conversations.to_type', '=', Group::class)
|
|
->where(function (Builder $q) {
|
|
$q->whereColumn('ma.conversation_id', '!=', 'conversations.id')
|
|
->orWhereNull('ma.conversation_id');
|
|
})
|
|
->selectRaw(
|
|
"max(conversations.id) as latest_id , 0 as user_id, to_id as group_id,
|
|
SUM(CASE WHEN gmr.read_at IS NULL and user_id = $authId THEN 1 END) as unread_count"
|
|
|
|
)->whereHas('group.usersWithTrashed', function (Builder $q) use ($authId) {
|
|
$q->where('user_id', $authId); // To get conversations in which user is
|
|
})
|
|
->groupBy('conversations.to_id');
|
|
|
|
$bindings = array_merge($subQuery->getBindings(), $groupSubQuery->getBindings());
|
|
$groupSubQueryStr = $groupSubQuery->toSql();
|
|
$relations = ['group.lastConversations.conversation', 'user.userStatus', 'group.usersWithTrashed'];
|
|
} else {
|
|
$bindings = $subQuery->getBindings();
|
|
$relations = ['user.userStatus'];
|
|
}
|
|
$subQueryStr = $subQuery->toSql();
|
|
|
|
$archiveUsers = ArchivedUser::toBase()
|
|
->select('owner_id')
|
|
->whereArchivedBy(getLoggedInUserId())
|
|
->whereOwnerType(User::class)
|
|
->pluck('owner_id')->toArray();
|
|
|
|
$chatList = Conversation::with($relations)->newQuery();
|
|
$chatList = $chatList->select('temp.*', 'cc.*');
|
|
if ($isGroupChatEnabled) {
|
|
$chatList->from(DB::raw("($subQueryStr union $groupSubQueryStr) as temp"));
|
|
} else {
|
|
$chatList->from(DB::raw("($subQueryStr) as temp"));
|
|
}
|
|
$chatList->setBindings($bindings)
|
|
->leftJoin('conversations as cc', 'cc.id', '=', 'temp.latest_id');
|
|
if (! $isArchived) {
|
|
$chatList = $chatList->whereNotIn('temp.user_id', $archiveUsers);
|
|
} else {
|
|
$archiveGroups = [];
|
|
if ($isGroupChatEnabled) {
|
|
$archiveGroups = ArchivedUser::whereArchivedBy(getLoggedInUserId())->whereOwnerType(Group::class)->get()->pluck('owner_id')->toArray();
|
|
}
|
|
$chatList = $chatList->where(function ($query) use ($archiveUsers, $archiveGroups, $isGroupChatEnabled) {
|
|
$query->whereIn('temp.user_id', $archiveUsers);
|
|
if ($isGroupChatEnabled) {
|
|
$query->orWhereIn('temp.group_id', $archiveGroups);
|
|
}
|
|
});
|
|
}
|
|
$chatList = $chatList->orderBy('cc.created_at', 'desc')->offset($offset)->limit(10)
|
|
->get()->keyBy('id');
|
|
|
|
// TODO : refactor this later
|
|
// To replace user's last conversation when he/she leave the group
|
|
$groupsConversation = [];
|
|
if ($isGroupChatEnabled) {
|
|
$groupsConversation = $chatList->where('is_group')->all();
|
|
}
|
|
|
|
$chatList = $chatList->toArray();
|
|
if (! $isGroupChatEnabled) {
|
|
return array_values($chatList);
|
|
}
|
|
|
|
foreach ($groupsConversation as $conversation) {
|
|
if ($conversation->group->lastConversations->isEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
$lastConversations = $conversation->group->lastConversations->keyBy('user_id');
|
|
if (! isset($lastConversations[getLoggedInUserId()])) {
|
|
continue;
|
|
}
|
|
$newConversation = $lastConversations[getLoggedInUserId()]->conversation;
|
|
$chatList[$conversation->id]['id'] = $newConversation->id;
|
|
$chatList[$conversation->id]['message'] = $newConversation->message;
|
|
$chatList[$conversation->id]['from_id'] = $newConversation->from_id;
|
|
$chatList[$conversation->id]['to_id'] = $newConversation->to_id;
|
|
$chatList[$conversation->id]['unread_message'] = 0;
|
|
$chatList[$conversation->id]['group_details'] = $lastConversations[getLoggedInUserId()]->group_details;
|
|
}
|
|
|
|
return array_values($chatList);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
*
|
|
* @throws Exception
|
|
*
|
|
* @return Conversation
|
|
*/
|
|
public function sendMessage($input)
|
|
{
|
|
if (isset($input['is_archive_chat']) && $input['is_archive_chat'] == 1) {
|
|
$archivedUser = ArchivedUser::whereOwnerId($input['to_id'])->whereArchivedBy(getLoggedInUserId())->first();
|
|
if (! empty($archivedUser)) {
|
|
$archivedUser->delete();
|
|
}
|
|
}
|
|
|
|
$input['to_type'] = Conversation::class;
|
|
$input['from_id'] = getLoggedInUserId();
|
|
if (isValidURL($input['message'])) {
|
|
$input['message_type'] = detectURL($input['message']);
|
|
}
|
|
|
|
$pattern = '~[a-z]+://\S+~';
|
|
$message = $input['message'];
|
|
|
|
if ($num_found = preg_match_all($pattern, $message, $out)) {
|
|
$link = $out[0];
|
|
try {
|
|
$info = Embed::create($link[0]);
|
|
|
|
$input['url_details'] = [
|
|
'title' => $info->title,
|
|
'image' => $info->image,
|
|
'description' => $info->description,
|
|
'url' => $info->url,
|
|
];
|
|
} catch (Exception $e) {
|
|
}
|
|
}
|
|
|
|
if (isset($input['is_group']) && $input['is_group']) {
|
|
return $this->sendGroupMessage($input);
|
|
}
|
|
|
|
/** @var $conversation Conversation */
|
|
$conversation = $this->create($input)->fresh();
|
|
$conversation->sender;
|
|
|
|
$broadcastData = $conversation->toArray();
|
|
if (! empty($conversation->reply_to)) {
|
|
$broadcastData['reply_message']['id'] = $conversation->replyMessage->id;
|
|
$broadcastData['reply_message']['message'] = $conversation->replyMessage->message;
|
|
$broadcastData['reply_message']['sender']['id'] = $conversation->replyMessage->sender->id;
|
|
$broadcastData['reply_message']['sender']['name'] = $conversation->replyMessage->sender->name;
|
|
}
|
|
$broadcastData['type'] = User::NEW_PRIVATE_CONVERSATION;
|
|
broadcast(new UserEvent($broadcastData, $conversation->to_id))->toOthers();
|
|
|
|
/** @var User $receiver */
|
|
$receiver = $conversation->receiver;
|
|
if ($receiver->is_subscribed && ! $receiver->devices->isEmpty()) {
|
|
// Send OneSignal Push of user is subscribed
|
|
$headings = $receiver->name.' | '.getAppName();
|
|
|
|
foreach ($receiver->devices as $device) {
|
|
$options = [];
|
|
if ($conversation->message_type == 1) {
|
|
$options['image'] = $conversation->message;
|
|
}
|
|
dispatch(new SendOneSignalPushJob([$device->player_id], $headings, $input['message'], $options));
|
|
}
|
|
}
|
|
|
|
$notificationInput = [
|
|
'owner_id' => $conversation['from_id'],
|
|
'owner_type' => User::class,
|
|
'notification' => $conversation['message'],
|
|
'to_id' => $conversation['to_id'],
|
|
'message_type' => $conversation['message_type'],
|
|
'file_name' => $conversation['file_name'],
|
|
];
|
|
/** @var NotificationRepository $notificationRepo */
|
|
$notificationRepo = app(NotificationRepository::class);
|
|
$notificationRepo->sendNotification($notificationInput, $conversation['to_id']);
|
|
|
|
return $conversation;
|
|
}
|
|
|
|
/**
|
|
* @param array $groupUsers
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function groupMessageValidations($groupUsers)
|
|
{
|
|
// If user is removed/leave from group, then her can not able to send message in group
|
|
if (! in_array(getLoggedInUserId(), $groupUsers)) {
|
|
throw new UnprocessableEntityHttpException('Only active member of this group can send message.');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
*
|
|
* @return Conversation
|
|
*/
|
|
public function sendGroupMessage($input)
|
|
{
|
|
$input['to_type'] = Group::class;
|
|
|
|
/** @var Group $group */
|
|
$group = Group::with('users')->findOrFail($input['to_id']);
|
|
$groupUsers = $group->users->pluck('id', 'id')->toArray();
|
|
$this->groupMessageValidations($groupUsers);
|
|
|
|
/** @var $conversation Conversation */
|
|
$conversation = $this->create($input)->fresh();
|
|
$conversation->sender;
|
|
$broadcastData = $this->prepareGroupChatBroadCastData($conversation->toArray(), $group->toArray());
|
|
if (! empty($conversation->reply_to)) {
|
|
$broadcastData['reply_message']['id'] = $conversation->replyMessage->id;
|
|
$broadcastData['reply_message']['message'] = $conversation->replyMessage->message;
|
|
$broadcastData['reply_message']['sender']['id'] = $conversation->replyMessage->sender->id;
|
|
$broadcastData['reply_message']['sender']['name'] = $conversation->replyMessage->sender->name;
|
|
}
|
|
broadcast(new GroupEvent($broadcastData))->toOthers();
|
|
$this->groupRepo->addRecordsToGroupMessageRecipients($groupUsers, $conversation->id, $group->id);
|
|
|
|
// Send PushNotifications to group users who's push are enabled
|
|
$headings = $group->name.' | '.getAppName();
|
|
$playerIds = [];
|
|
$group->users->filter(function (User $user) use (&$playerIds) {
|
|
if ($user->id == getLoggedInUserId()) {
|
|
return;
|
|
}
|
|
|
|
if ($user->is_subscribed) {
|
|
foreach ($user->devices as $device) {
|
|
$playerIds[] = $device->player_id;
|
|
}
|
|
}
|
|
});
|
|
|
|
if (count($playerIds)) {
|
|
$options = [];
|
|
if ($conversation->message_type == 1) {
|
|
$options['image'] = $conversation->message;
|
|
}
|
|
dispatch(new SendOneSignalPushJob($playerIds, $headings, $input['message'], $options));
|
|
}
|
|
$conversation->readBy;
|
|
|
|
$this->sendGroupMessageNotification($conversation, $group->users);
|
|
|
|
return $conversation;
|
|
}
|
|
|
|
/**
|
|
* @param Conversation $conversation
|
|
* @param array $groupMembers
|
|
*/
|
|
public function sendGroupMessageNotification($conversation, $groupMembers)
|
|
{
|
|
/** @var User $groupMember */
|
|
foreach ($groupMembers as $groupMember) {
|
|
if ($groupMember->id == getLoggedInUserId()) {
|
|
continue;
|
|
}
|
|
$notificationInput = [
|
|
'owner_id' => $conversation->to_id,
|
|
'owner_type' => Group::class,
|
|
'notification' => $conversation->message,
|
|
'to_id' => $groupMember->id,
|
|
'message_type' => $conversation->message_type,
|
|
'file_name' => $conversation->file_name,
|
|
];
|
|
|
|
/** @var NotificationRepository $notificationRepo */
|
|
$notificationRepo = app(NotificationRepository::class);
|
|
$notificationRepo->sendNotification($notificationInput, $groupMember->id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $conversation
|
|
* @param array $group
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function prepareGroupChatBroadCastData($conversation, $group)
|
|
{
|
|
$groupInfo = $group;
|
|
$senderInfo = Auth::user();
|
|
|
|
// Remove Unused Information
|
|
unset($conversation['sender']);
|
|
unset($conversation['group']);
|
|
unset($conversation['receiver']);
|
|
|
|
$conversation['group']['id'] = $groupInfo['id'];
|
|
$conversation['group']['name'] = $groupInfo['name'];
|
|
$conversation['group']['photo'] = $groupInfo['photo'];
|
|
$conversation['sender']['id'] = $senderInfo['id'];
|
|
$conversation['sender']['photo'] = $senderInfo['photo'];
|
|
$conversation['sender']['name'] = $senderInfo['name'];
|
|
$conversation['sender']['role_name'] = $senderInfo['role_name'];
|
|
$conversation['type'] = Group::NEW_GROUP_MESSAGE_ARRIVED;
|
|
|
|
return $conversation;
|
|
}
|
|
|
|
/**
|
|
* @param UploadedFile $file
|
|
*
|
|
* @throws ApiOperationFailedException
|
|
*
|
|
* @return string|void
|
|
*/
|
|
public function addAttachment($file)
|
|
{
|
|
$extension = strtolower($file->getClientOriginalExtension());
|
|
if (! in_array($extension,
|
|
[
|
|
'xls', 'pdf', 'doc', 'docx', 'xlsx', 'jpg', 'gif', 'jpeg', 'png', 'mp4', 'mkv', 'avi', 'txt', 'mp3',
|
|
'ogg', 'wav', 'aac', 'alac',
|
|
'zip', 'rar',
|
|
])) {
|
|
throw new ApiOperationFailedException('You can not upload this file.', Response::HTTP_BAD_REQUEST);
|
|
}
|
|
|
|
if (in_array($extension, ['jpg', 'gif', 'png', 'jpeg'])) {
|
|
$fileName = ImageTrait::makeImage($file, Conversation::PATH, []);
|
|
|
|
return $fileName;
|
|
}
|
|
|
|
if (in_array($extension, ['xls', 'pdf', 'doc', 'docx', 'xlsx', 'txt'])) {
|
|
$fileName = ImageTrait::makeAttachment($file, Conversation::PATH);
|
|
|
|
return $fileName;
|
|
}
|
|
|
|
if (in_array($extension, ['mp4', 'mkv', 'avi'])) {
|
|
$fileName = ImageTrait::uploadVideo($file, Conversation::PATH);
|
|
|
|
return $fileName;
|
|
}
|
|
|
|
if (in_array($extension, ['mp3', 'ogg', 'wav', 'aac', 'alac', 'zip', 'rar'])) {
|
|
$fileName = ImageTrait::uploadFile($file, Conversation::PATH);
|
|
|
|
return $fileName;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $extension
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getMessageTypeByExtension($extension)
|
|
{
|
|
$extension = strtolower($extension);
|
|
if (in_array($extension, ['jpg', 'gif', 'png', 'jpeg'])) {
|
|
return Conversation::MEDIA_IMAGE;
|
|
} elseif (in_array($extension, ['doc', 'docx'])) {
|
|
return Conversation::MEDIA_DOC;
|
|
} elseif ($extension == 'pdf') {
|
|
return Conversation::MEDIA_PDF;
|
|
} elseif (in_array($extension, ['mp3', 'ogg', 'wav', 'aac', 'alac'])) {
|
|
return Conversation::MEDIA_VOICE;
|
|
} elseif (in_array($extension, ['mp4', 'mkv', 'avi'])) {
|
|
return Conversation::MEDIA_VIDEO;
|
|
} elseif (in_array($extension, ['txt'])) {
|
|
return Conversation::MEDIA_TXT;
|
|
} elseif (in_array($extension, ['xls', 'xlsx'])) {
|
|
return Conversation::MEDIA_XLS;
|
|
} elseif (in_array($extension, ['zip', 'rar'])) {
|
|
return Conversation::MEDIA_ZIP;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
*
|
|
* @return array
|
|
*/
|
|
public function markMessagesAsRead($input)
|
|
{
|
|
$senderId = Auth::id();
|
|
$isGroup = (isset($input['is_group']) && $input['is_group'] == '1') ? true : false;
|
|
$remainingUnread = 0;
|
|
|
|
if ($isGroup && ! empty($input['ids'])) {
|
|
$this->readGroupMessages($input['ids']);
|
|
$remainingUnread = $this->getUnreadMessageCount($input['group_id'], true);
|
|
} elseif (! $isGroup && ! empty($input['ids'])) {
|
|
$unreadIds = $input['ids'];
|
|
$unreadIds = (is_array($unreadIds)) ? $unreadIds : [$unreadIds];
|
|
$firstUnreadConversationId = $unreadIds[0];
|
|
Conversation::whereIn('id', $unreadIds)->update(['status' => 1]);
|
|
|
|
$conversation = Conversation::find($firstUnreadConversationId);
|
|
$senderId = ($conversation->from_id == getLoggedInUserId()) ? $conversation->to_id : $conversation->from_id;
|
|
$receiverId = ($conversation->from_id == getLoggedInUserId()) ? $conversation->from_id : $conversation->to_id;
|
|
$remainingUnread = $this->getUnreadMessageCount($senderId);
|
|
|
|
broadcast(new UserEvent(
|
|
[
|
|
'user_id' => $receiverId,
|
|
'ids' => $unreadIds,
|
|
'type' => User::PRIVATE_MESSAGE_READ,
|
|
], $conversation->from_id))->toOthers();
|
|
}
|
|
|
|
return ['senderId' => $senderId, 'remainingUnread' => $remainingUnread];
|
|
}
|
|
|
|
/**
|
|
* @param array $ids
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function readGroupMessages($ids)
|
|
{
|
|
// First Read Given Messages
|
|
$query = GroupMessageRecipient::with('conversation')->whereIn('conversation_id', $ids)
|
|
->where('user_id', getLoggedInUserId());
|
|
$query->update(['read_at' => Carbon::now()]);
|
|
|
|
// Group by given conversations record
|
|
$records = GroupMessageRecipient::with('conversation')->whereIn('conversation_id', $ids)->get([
|
|
'read_at', 'conversation_id',
|
|
])->groupBy('conversation_id');
|
|
|
|
$conversationIds = $query->pluck('conversation_id');
|
|
$readMessages = $query->first();
|
|
if (! empty($readMessages)) {
|
|
broadcast(new GroupEvent(
|
|
[
|
|
'group' => ['id' => $readMessages->conversation->to_id],
|
|
'type' => Group::GROUP_MESSAGE_READ_BY_MEMBER,
|
|
'conversation_ids' => $conversationIds,
|
|
'read_by_user_id' => Auth::id(),
|
|
'read_at' => Carbon::now()->format('Y-m-d H:i:s'),
|
|
]))->toOthers();
|
|
}
|
|
// If given conversation id read by all members than fire read all msg event
|
|
foreach ($ids as $id) {
|
|
$readByAll = collect($records[$id])->map(function ($record) {
|
|
if (empty($record->read_at)) {
|
|
return $record;
|
|
}
|
|
})->toArray();
|
|
|
|
if (empty(array_filter($readByAll))) {
|
|
broadcast(new GroupEvent(
|
|
[
|
|
'group' => ['id' => $records[$id][0]->conversation->to_id],
|
|
'type' => Group::GROUP_MESSAGE_READ_BY_ALL_MEMBERS,
|
|
'conversation_id' => $id,
|
|
'group_id' => $records[$id][0]->conversation->to_id,
|
|
]))->toOthers();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param int $senderId
|
|
* @param bool $isGroup
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getUnreadMessageCount($senderId, $isGroup = false)
|
|
{
|
|
if ($isGroup) {
|
|
return GroupMessageRecipient::whereUserId(Auth::id())->where('group_id', $senderId)
|
|
->whereNull('read_at')->count();
|
|
}
|
|
|
|
return Conversation::where(function (Builder $q) use ($senderId) {
|
|
$q->where('from_id', '=', $senderId)->where('to_id', '=', getLoggedInUserId());
|
|
})->where('status', '=', 0)->message()->count();
|
|
}
|
|
|
|
/**
|
|
* @param $userId
|
|
*/
|
|
public function deleteConversation($userId)
|
|
{
|
|
$chatIds = Conversation::leftJoin('message_action as ma', function (JoinClause $join) {
|
|
$authUserId = getLoggedInUserId();
|
|
$join->on('ma.deleted_by', '=', DB::raw("$authUserId"));
|
|
$join->on('ma.conversation_id', '=', 'conversations.id');
|
|
})
|
|
->where(function (Builder $q) use ($userId) {
|
|
$q->where(function (Builder $q) use ($userId) {
|
|
$q->where('from_id', '=', $userId)
|
|
->where('to_id', '=', getLoggedInUserId());
|
|
})->orWhere(function (Builder $q) use ($userId) {
|
|
$q->where('from_id', '=', getLoggedInUserId())
|
|
->where('to_id', '=', $userId);
|
|
});
|
|
})
|
|
->where(function (Builder $q) {
|
|
$q->whereColumn('ma.conversation_id', '!=', 'conversations.id')
|
|
->orWhereNull('ma.conversation_id');
|
|
})
|
|
->get(['conversations.*'])
|
|
->pluck('id')
|
|
->toArray();
|
|
|
|
$input = [];
|
|
foreach ($chatIds as $chatId) {
|
|
$input[] = [
|
|
'conversation_id' => $chatId,
|
|
'deleted_by' => getLoggedInUserId(),
|
|
];
|
|
}
|
|
|
|
MessageAction::insert($input);
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function deleteGroupConversation($groupId)
|
|
{
|
|
$conversationIds = Conversation::whereToId($groupId)->pluck('id')->toArray();
|
|
|
|
$input = [];
|
|
foreach ($conversationIds as $chatId) {
|
|
$input[] = [
|
|
'conversation_id' => $chatId,
|
|
'deleted_by' => getLoggedInUserId(),
|
|
];
|
|
}
|
|
|
|
MessageAction::insert($input);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param $id
|
|
*/
|
|
public function deleteMessage($id)
|
|
{
|
|
MessageAction::create([
|
|
'conversation_id' => $id,
|
|
'deleted_by' => getLoggedInUserId(),
|
|
'is_hard_delete' => 1,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
*
|
|
* @throws Exception
|
|
*
|
|
* @return Conversation|bool|Model
|
|
*/
|
|
public function sendChatRequest($input)
|
|
{
|
|
$toId = $input['to_id'];
|
|
$message = $input['message'];
|
|
$chatRequest = ChatRequestModel::whereFromId(getLoggedInUserId())
|
|
->whereOwnerId($toId)
|
|
->where('status', '!=', ChatRequestModel::STATUS_DECLINE)
|
|
->first();
|
|
|
|
//chat request already send
|
|
if (! empty($chatRequest)) {
|
|
return false;
|
|
}
|
|
|
|
//check for user has public/private account
|
|
$user = User::find($toId);
|
|
if ($user->privacy > 0) {
|
|
return false;
|
|
}
|
|
|
|
// Delete Old declined request
|
|
ChatRequestModel::whereFromId(getLoggedInUserId())
|
|
->whereOwnerId($toId)
|
|
->where('owner_type', '=', User::class)
|
|
->delete();
|
|
|
|
// Create new request
|
|
ChatRequestModel::create([
|
|
'from_id' => getLoggedInUserId(),
|
|
'owner_id' => $toId,
|
|
'owner_type' => User::class,
|
|
]);
|
|
|
|
$conversation = Conversation::create([
|
|
'from_id' => getLoggedInUserId(),
|
|
'to_id' => $toId,
|
|
'to_type' => Conversation::class,
|
|
'message' => $message,
|
|
'status' => 0,
|
|
'message_type' => 0,
|
|
]);
|
|
$conversation->sender;
|
|
$broadcastData = $conversation->toArray();
|
|
$broadcastData['type'] = User::CHAT_REQUEST;
|
|
$broadcastData['owner_type'] = User::class;
|
|
broadcast(new UserEvent($broadcastData, $toId))->toOthers();
|
|
|
|
$notificationInput = [
|
|
'owner_id' => $conversation['from_id'],
|
|
'owner_type' => User::class,
|
|
'notification' => $conversation['message'],
|
|
'to_id' => $conversation['to_id'],
|
|
'message_type' => $conversation['message_type'],
|
|
'file_name' => $conversation['file_name'],
|
|
];
|
|
/** @var NotificationRepository $notificationRepo */
|
|
$notificationRepo = app(NotificationRepository::class);
|
|
$notificationRepo->sendNotification($notificationInput, $conversation['to_id']);
|
|
|
|
return $conversation;
|
|
}
|
|
|
|
/**
|
|
* @param array $chatRequest
|
|
* @param int $userEventType
|
|
*/
|
|
public function sendAcceptDeclineChatRequestNotification($chatRequest, $userEventType = 0)
|
|
{
|
|
$notificationInput = [
|
|
'owner_id' => $chatRequest['owner_id'],
|
|
'owner_type' => $chatRequest['owner_type'],
|
|
'notification' => $chatRequest['message'],
|
|
'to_id' => $chatRequest['from_id'],
|
|
'message_type' => 0,
|
|
];
|
|
|
|
/** @var NotificationRepository $notificationRepo */
|
|
$notificationRepo = app(NotificationRepository::class);
|
|
$notificationRepo->sendNotification($notificationInput, $chatRequest['from_id'], $userEventType);
|
|
}
|
|
}
|