175 lines
6.8 KiB
PHP
175 lines
6.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Club;
|
|
|
|
use App\Enums\NotificationType;
|
|
use App\Events\NewNotification;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Club\Messages\BlockCustomerRequest;
|
|
use App\Http\Requests\Club\Messages\DeleteMessagesRequest;
|
|
use App\Http\Requests\Club\Messages\MarkAsReadRequest;
|
|
use App\Http\Requests\Club\Messages\SendMessageRequest;
|
|
use App\Lib\Helpers\ToolboxHelper;
|
|
use App\Models\BlockList;
|
|
use App\Models\Customer;
|
|
use App\Models\Message;
|
|
use App\Models\Notification;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Lottery;
|
|
|
|
class MessageController extends Controller
|
|
{
|
|
/**
|
|
* Show messagerie.
|
|
*
|
|
* @return \Illuminate\Contracts\View\View
|
|
*/
|
|
public function index(): \Illuminate\Contracts\View\View
|
|
{
|
|
return view('club.pages.messages.index');
|
|
}
|
|
|
|
/**
|
|
* Fetch conversations and block list.
|
|
*
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function conversations(): \Illuminate\Http\JsonResponse
|
|
{
|
|
/** How many message to keey in a conversation */
|
|
$messagesToKeepInConversations = 25;
|
|
/** @var \App\Models\Customer */
|
|
$customer = Auth::guard('club')->user();
|
|
$conversations = $customer->conversations();
|
|
$ids = collect($conversations)->pluck('to_id');
|
|
$block_list = BlockList::query()
|
|
->whereHas('customer', fn (Builder $q) => $q->where('id', $customer->id))
|
|
->orWhereHas('blocked', fn (Builder $q) => $q->where('id', $customer->id))
|
|
->get();
|
|
|
|
// * Sort In reverse order messages
|
|
$conversations = collect($conversations)
|
|
->map(function (array $conversation) use ($messagesToKeepInConversations) {
|
|
$sortFn = fn (Message $a, Message $b) => $a->created_at->timestamp < $b->created_at->timestamp;
|
|
// * Limit messages per conversations
|
|
Lottery::odds(1, 20)
|
|
->winner(fn() => collect($conversation['messages'])
|
|
// @phpstan-ignore-next-line
|
|
->sort($sortFn)
|
|
->splice($messagesToKeepInConversations)
|
|
->each(fn(Message $message) => $message->delete()))
|
|
->choose();
|
|
return $conversation;
|
|
})->all();
|
|
// * Notifications
|
|
$notifications = Notification::query()
|
|
->whereHas('customer', fn (Builder $q) => $q->where('id', $customer->id))
|
|
->where('notifiable_type', Message::class)
|
|
->pluck('notifiable_id', 'id');
|
|
return response()->json(compact('conversations', 'block_list', 'notifications'));
|
|
}
|
|
|
|
/**
|
|
* Send a message to a club customer.
|
|
*
|
|
* @param \App\Http\Requests\Club\Messages\SendMessageRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function send(SendMessageRequest $request): \Illuminate\Http\JsonResponse
|
|
{
|
|
/** @var \App\Models\Customer */
|
|
$customer = Auth::guard('club')->user();
|
|
/** @var \App\Models\Customer */
|
|
$toCustomer = Customer::query()->where('username', $request->input('to'))->firstOrFail();
|
|
$message = new Message($request->only('message'));
|
|
$message->fromCustomer()->associate($customer);
|
|
$message->toCustomer()->associate($toCustomer);
|
|
$message->message = ToolboxHelper::censorString($message->message);
|
|
$message->saveOrFail();
|
|
event(new NewNotification(
|
|
NotificationType::message,
|
|
route('club.messages.index', ['m' => $message->id]),
|
|
$message,
|
|
$toCustomer
|
|
));
|
|
return response()->json($message->load(['fromCustomer', 'toCustomer']));
|
|
}
|
|
|
|
/**
|
|
* Destroy a club customer's message.
|
|
*
|
|
* @param \App\Http\Requests\Club\Messages\DeleteMessagesRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function delete(DeleteMessagesRequest $request): \Illuminate\Http\JsonResponse
|
|
{
|
|
return DB::transaction(function () use ($request) {
|
|
/** @var \App\Models\Customer */
|
|
$customer = Auth::guard('club')->user();
|
|
$message = Message::findOrFail($request->input('message'));
|
|
$conversations = $customer->conversations();
|
|
foreach ($conversations as $conversation) {
|
|
$conversation = (object)$conversation;
|
|
if ($conversation->id != $message->id) {
|
|
continue;
|
|
}
|
|
/** @var \App\Models\Message $message */
|
|
foreach ($conversation->messages as $message) {
|
|
if ($message->from == $customer->id) {
|
|
$message->hide_from = true;
|
|
}
|
|
if ($message->to == $customer->id) {
|
|
$message->hide_to = true;
|
|
}
|
|
if ($message->hide_to && $message->hide_from) {
|
|
$message->delete();
|
|
} else {
|
|
$message->saveOrFail();
|
|
}
|
|
}
|
|
}
|
|
return response()->json();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Block a customer to prevent him sending messages.
|
|
*
|
|
* @param \App\Http\Requests\Club\Messages\BlockCustomerRequest $request
|
|
* @param boolean $status
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function toggleBlock(BlockCustomerRequest $request, bool $status): \Illuminate\Http\JsonResponse
|
|
{
|
|
/** @var \App\Models\Customer */
|
|
$customer = Auth::guard('club')->user();
|
|
/** @var \App\Models\Customer */
|
|
$customerToBlock = Customer::query()->where('username', $request->input('username'))->firstOrFail();
|
|
$blockCustomer = BlockList::firstOrNew([
|
|
'customer_id' => $customer->id,
|
|
'blocked_id' => $customerToBlock->id,
|
|
]);
|
|
($status) ? $blockCustomer->saveOrFail() : $blockCustomer->deleteOrFail();
|
|
return response()->json($blockCustomer);
|
|
}
|
|
|
|
/**
|
|
* Mark notificaiton as read.
|
|
*
|
|
* @param \App\Http\Requests\Club\Messages\MarkAsReadRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function notificationsRead(MarkAsReadRequest $request): \Illuminate\Http\JsonResponse
|
|
{
|
|
/** @var \App\Models\Customer */
|
|
$customer = Auth::guard('club')->user();
|
|
Notification::query()
|
|
->where('notifiable_type', Message::class)
|
|
->whereIn('id', $request->input('messageList'))
|
|
->whereHas('customer', fn (Builder $q) => $q->where('id', $customer->id))
|
|
->delete();
|
|
return response()->json([]);
|
|
}
|
|
}
|