ldc-legaulois/app/Http/Controllers/Club/MessageController.php
Alexis Gousseau 9d452b5659 chore: ⬆️ bump crm to V4
2024-09-13 15:41:25 +02:00

179 lines
6.9 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\Http\JsonResponse;
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|\Illuminate\Contracts\View\Factory
*/
public function index()
{
return view('club.pages.messages.index');
}
/**
* Fetch conversations and block list
*
* @return \Illuminate\Http\JsonResponse
*/
public function conversations(): 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 user
*
* @param \App\Http\Requests\Club\Messages\SendMessageRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function send(SendMessageRequest $request): 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(['toCustomer' => function (Builder $q) {
$q->select(['id', 'username', 'created_at']);
}, 'fromCustomer' => function (Builder $q) {
$q->select(['id', 'username', 'created_at']);
}]));
}
/**
* Destroy a message
*
* @param \App\Http\Requests\Club\Messages\DeleteMessagesRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function delete(DeleteMessagesRequest $request): 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): 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): 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([]);
}
}