332 lines
12 KiB
PHP
332 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Domain\Messenger\Models\ChatRoom;
|
|
use App\Domain\Messenger\Models\Message;
|
|
use App\Models\User;
|
|
use Inertia\Inertia;
|
|
use Illuminate\Support\Facades\Request;
|
|
use Illuminate\Http\Request as HttpRequest;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
|
|
class MessengerController extends Controller
|
|
{
|
|
|
|
protected function getSearchByMessage($currentUser, $search)
|
|
{
|
|
return $currentUser
|
|
->chat_rooms()
|
|
->orderBy('updated_at', 'desc')
|
|
->with(['messsages' => function ($query) use($search) {
|
|
$query->where('message', 'ilike', "{$search}%");
|
|
}, 'users:id,first_name,last_name,username,photo_path,banner_path,color,user_char'])
|
|
->whereHas('messsages', function (Builder $query) use($search) {
|
|
$query->where('message', 'ilike', "{$search}%");
|
|
})
|
|
->get();
|
|
}
|
|
|
|
protected function getSearchByUser($currentUser, $search)
|
|
{
|
|
return $currentUser
|
|
->chat_rooms()
|
|
->orderBy('updated_at', 'desc')
|
|
->with(['users:id,first_name,last_name,username,photo_path,banner_path,color,user_char', 'messsages'])
|
|
->whereHas('users', function (Builder $query) use($search) {
|
|
$query->where('first_name', 'ilike', '%'.$search.'%')
|
|
->orWhere('last_name', 'ilike', '%'.$search.'%');
|
|
})
|
|
->get();
|
|
}
|
|
|
|
public function index()
|
|
{
|
|
// Если пользователь выбирается по гет параметру
|
|
$chatSelectUser = null;
|
|
$chatSelectUserID = 0;
|
|
if($getUsername = request()->get('user')){
|
|
$chatSelectUser = User::where('username', $getUsername)->firstOrFail();
|
|
$chatSelectUser->name = $chatSelectUser->name;
|
|
$chatSelectUserID = $chatSelectUser->id;
|
|
}
|
|
|
|
$search = request()->get('search');
|
|
$type = request()->get('type');
|
|
$currentUser = auth()->user();
|
|
|
|
if($search){
|
|
if($type == 1){
|
|
$chat_rooms = $this->getSearchByMessage($currentUser, $search);
|
|
}else{
|
|
$chat_rooms = $this->getSearchByUser($currentUser, $search);
|
|
}
|
|
|
|
$chat_rooms->transform(function ($room) {
|
|
$message = $room->messsages->first();
|
|
$room->latestMessage = $message;
|
|
return $room;
|
|
});
|
|
}else{
|
|
$chat_rooms = $currentUser
|
|
->chat_rooms()
|
|
->orderBy('updated_at', 'desc')
|
|
->with('latestMessage', 'users:id,first_name,last_name,username,photo_path,banner_path,color,user_char')
|
|
->get();
|
|
}
|
|
|
|
$rooms = $chat_rooms->map(function ($room) use ($currentUser, $chatSelectUserID) {
|
|
$is_my_message = false;
|
|
$classActive = false;
|
|
if($room->latestMessage->user_id === $currentUser->id){
|
|
$is_my_message = true;
|
|
}
|
|
$message = $room->latestMessage->message;
|
|
$updated_at_human = $room->latestMessage->created_at->diffForHumans();
|
|
$updated_at = $room->latestMessage->created_at->format('U');
|
|
|
|
$correspond = $room->users->where('id', '<>', $currentUser->id)->first();
|
|
unset($correspond->pivot);
|
|
$correspond->name = $correspond->name;
|
|
if($chatSelectUserID === $correspond->id){ // делаем активным
|
|
$classActive = true;
|
|
}
|
|
return [
|
|
'id' => $room->id,
|
|
'is_freeze' => $room->is_freeze,
|
|
'classActive' => $classActive,
|
|
'is_my_message' => $is_my_message,
|
|
'message' => $message,
|
|
'is_reading' => $room->latestMessage->is_reading,
|
|
'updated_at' => $updated_at,
|
|
'updated_at_human' => $updated_at_human,
|
|
'correspond' => $correspond->toArray(),
|
|
];
|
|
});
|
|
|
|
if($chatSelectUserID){
|
|
$checkActiveRoom = $rooms->contains(function ($item) {
|
|
return $item['classActive'] === true;
|
|
});
|
|
if(!$checkActiveRoom){
|
|
$globalRoomUser = $this->isRoomCreate($chatSelectUserID);
|
|
if($globalRoomUser){
|
|
$globalRoomUser->load('latestMessage');
|
|
$is_my_message = false;
|
|
if($globalRoomUser->latestMessage->user_id === auth()->user()->id){
|
|
$is_my_message = true;
|
|
}
|
|
$new_room = [
|
|
'id' => $globalRoomUser->id,
|
|
'is_freeze' => $globalRoomUser->is_freeze,
|
|
'classActive' => true,
|
|
'is_my_message' => $is_my_message,
|
|
'message' => $globalRoomUser->latestMessage->message,
|
|
'is_reading' => $globalRoomUser->latestMessage->is_reading,
|
|
'updated_at' => $globalRoomUser->updated_at->format('U'),
|
|
'updated_at_human' => $globalRoomUser->updated_at->diffForHumans(),
|
|
'correspond' => $chatSelectUser->only(['id','name','first_name','last_name','photo_path','banner_path','color','user_char', 'username']),
|
|
];
|
|
$rooms[] = $new_room;
|
|
}
|
|
}
|
|
$rooms = $rooms->sortByDesc('classActive')->values();
|
|
}
|
|
|
|
return Inertia::render('Messenger/Index', [
|
|
'rooms' => $rooms,
|
|
'roomSearch' => $search,
|
|
]);
|
|
}
|
|
|
|
|
|
public function show($id)
|
|
{
|
|
$room = ChatRoom::findOrFail($id);
|
|
$search = request()->get('search');
|
|
|
|
$messages = $room->messsages()->with('user:id,first_name,photo_path,color,user_char')->orderBy('id');
|
|
if($search){
|
|
$messages = $messages->where('message', 'ilike', "{$search}%");
|
|
}
|
|
$messages = $messages->cursorPaginate(50);
|
|
$nextCursor = get_cursor_hash($messages);
|
|
|
|
|
|
|
|
$messages->each(function ($message) {
|
|
if($message->is_reading === false && $message->user_id != auth()->user()->id){
|
|
$message->is_reading = true;
|
|
$message->save();
|
|
}
|
|
$message->group = $message->created_at->format('d.m.Y');
|
|
$message->created = $message->created_at->format('H:i');
|
|
return $message;
|
|
});
|
|
$messages = $messages->groupBy(function ($val) {
|
|
return \Carbon\Carbon::parse($val->created_at)->format('d.m.Y');
|
|
});
|
|
|
|
return ['records' => $messages, 'cursor' => $nextCursor];
|
|
|
|
|
|
}
|
|
|
|
public function store(HttpRequest $request)
|
|
{
|
|
$message = $request->input('params.message');
|
|
$chat_room_id = $request->input('params.room');
|
|
$status = $this->createMessage($message, $chat_room_id);
|
|
if($status === false){
|
|
return null;
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
public function storeFromProfile(HttpRequest $request)
|
|
{
|
|
$message = $request->input('message');
|
|
$chat_room_id = $request->input('chat_room');
|
|
|
|
$status = $this->createMessage($message, $chat_room_id);
|
|
if($status === false){
|
|
return redirect()->back()->with('error', 'Вы не можете отправить сообщение данному пользователю');
|
|
}
|
|
|
|
return redirect()->back()->with('success', 'Сообщение успешно отправлено!');
|
|
}
|
|
|
|
protected function createMessage($text, $chat_room_id)
|
|
{
|
|
$user = auth()->user();
|
|
$chatRoom = ChatRoom::find($chat_room_id);
|
|
if($chatRoom->is_freeze){
|
|
return false;
|
|
}
|
|
$message = new Message;
|
|
$message->message = $text;
|
|
$message->user_id = $user->id;
|
|
$message->chat_room_id = $chat_room_id;
|
|
$message->save();
|
|
|
|
$chatRoom->touch();
|
|
|
|
$message->created = $message->created_at->format('H:i');
|
|
$message->updated_at_room_human = $message->created_at->diffForHumans();
|
|
$message->updated_at_room = $message->created_at->format('U');
|
|
$message->group = $message->created_at->format('d.m.Y');
|
|
$message->keyGroupDate = $message->created_at->format('d.m.Y');
|
|
$message->user = $user->only(['id','first_name','photo_path','color','user_char']);
|
|
|
|
return $message;
|
|
}
|
|
|
|
public function checkRoom(HttpRequest $request)
|
|
{
|
|
$userId = $request->input('params.user');
|
|
$room = $this->isRoomCreate($userId);
|
|
return $room ? $room->id : 0;
|
|
}
|
|
|
|
protected function isRoomCreate($userId)
|
|
{
|
|
return auth()->user()->chat_rooms()->whereHas('users', function (Builder $query) use($userId) {
|
|
$query->where('id', $userId);
|
|
})->first();
|
|
}
|
|
|
|
public function createRoom(HttpRequest $request)
|
|
{
|
|
$message = $request->input('message');
|
|
$user_id = $request->input('user_id');
|
|
|
|
$existBannedUsers = $this->getBannedUser($user_id);
|
|
if($existBannedUsers){
|
|
return redirect()->back()->with('error', 'Вы не можете отправить сообщение данному пользователю');
|
|
}
|
|
|
|
$room = new ChatRoom;
|
|
$room->save();
|
|
$room->users()->attach([$user_id, auth()->user()->id]);
|
|
|
|
$this->createMessage($message, $room->id);
|
|
|
|
return redirect()->back()->with('success', 'Сообщение успешно отправлено!');
|
|
}
|
|
|
|
public function freezeRoom(HttpRequest $request)
|
|
{
|
|
$room_id = $request->input('room');
|
|
$room = ChatRoom::find($room_id);
|
|
$roomUsers = $room->users;
|
|
$isAuthUserExist = $roomUsers->contains(fn($user) => $user->id === auth()->user()->id);
|
|
$correspond = $roomUsers->where('id', '<>', auth()->user()->id)->first();
|
|
if(!$isAuthUserExist){
|
|
return redirect()->back()->with('error', 'Доступ запрещен');
|
|
}
|
|
|
|
// добавляем пользователя
|
|
$status = auth()->user()->bannedUsers()->toggle([$correspond->id]);
|
|
|
|
// проверяем есть ли пользователя из чата в черном списке, если есть замораживаем чат
|
|
$existBannedUsers = $this->getBannedUser($correspond->id);
|
|
|
|
if($existBannedUsers){ //disable touch update_at column
|
|
\DB::table('chat_rooms')->where('id', $room->id)->update(['is_freeze' => true]);
|
|
}else{
|
|
\DB::table('chat_rooms')->where('id', $room->id)->update(['is_freeze' => false]);
|
|
}
|
|
|
|
$msg = 'Пользователь успешно удален из чернго списка';
|
|
if(count($status['attached'])){
|
|
$msg = 'Пользователь успешно добавлен в черный список';
|
|
}
|
|
|
|
return redirect()->back()->with('success', $msg);
|
|
}
|
|
|
|
public function checkBannedUser(HttpRequest $request)
|
|
{
|
|
$correspond_id = $request->input('params.user');
|
|
$partnerIsBanned = \DB::table('user_banned')
|
|
->where('user_id', auth()->user()->id)
|
|
->where('banned_user_id', $correspond_id)->count();
|
|
if($partnerIsBanned){
|
|
return ['banned' => true];
|
|
}
|
|
|
|
return ['banned' => false];
|
|
}
|
|
|
|
public function leaveRoom(HttpRequest $request)
|
|
{
|
|
$room_id = $request->input('room');
|
|
|
|
$room = ChatRoom::find($room_id);
|
|
$room->users()->detach(auth()->user()->id);
|
|
|
|
return redirect()->back()->with('success', 'Успешно покинули беседу');
|
|
}
|
|
|
|
|
|
public function removeMessage($id)
|
|
{
|
|
$message = Message::findOrFail($id);
|
|
$message->delete();
|
|
|
|
return ['success' => true];
|
|
}
|
|
|
|
protected function getBannedUser($correspondId)
|
|
{
|
|
return \DB::table('user_banned')
|
|
->where('user_id', auth()->user()->id)
|
|
->where('banned_user_id', $correspondId)
|
|
->orWhere(function($query) use($correspondId) {
|
|
$query->where('user_id', $correspondId)
|
|
->where('banned_user_id', auth()->user()->id);
|
|
})->count();
|
|
}
|
|
}
|