Files
site/app/Http/Controllers/MessengerController.php

332 lines
12 KiB
PHP
Executable File

<?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();
}
}