GOOD SHELL MAS BOY
Server: Apache/2.4.52 (Ubuntu)
System: Linux vmi1836763.contaboserver.net 5.15.0-130-generic #140-Ubuntu SMP Wed Dec 18 17:59:53 UTC 2024 x86_64
User: www-data (33)
PHP: 8.4.10
Disabled: NONE
Upload Files
File: /var/www/console.fixgini.com/app/Http/Controllers/MessageController.php
<?php

namespace App\Http\Controllers;


use App\Models\User;
use App\Models\Message;
use App\Mail\SupportEmail;
use App\Events\MessageSent;
use App\Models\SupportMail;
use App\Models\Conversation;
use Illuminate\Http\Request;
use Google\Client as GoogleClient;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use App\Models\BlockedUser;
use Illuminate\Support\Facades\DB;


class MessageController extends Controller
{

    public function getConversationId($userOneId, $userTwoId)
    {
        // Check if conversation already exists
        $conversation = Conversation::where(function ($query) use ($userOneId, $userTwoId) {
            $query->where('user_one_id', $userOneId)
                ->where('user_two_id', $userTwoId);
        })->orWhere(function ($query) use ($userOneId, $userTwoId) {
            $query->where('user_one_id', $userTwoId)
                ->where('user_two_id', $userOneId);
        })->first();

        // If conversation exists, return the ID
        if ($conversation) {
            return $conversation->id;
        }

        // If conversation doesn't exist, create a new one
        $conversation = Conversation::create([
            'user_one_id' => $userOneId,
            'user_two_id' => $userTwoId,
        ]);

        return $conversation->id;
    }

    public function sendMessage(Request $request)
    {
        try {
            // Validate the request
            $validated = $request->validate([
                'sender_id' => 'required|exists:users,id',
                'recipient_id' => 'required|exists:users,id',
                'content' => 'required|string',
                'file_url' => 'sometimes|string',
                'file_public_id' => 'sometimes|string',
            ]);

            // Retrieve sender, recipient, and message content from validated data
            $senderId = $validated['sender_id'];
            $recipientId = $validated['recipient_id'];
            $messageText = $validated['content'];
            $file_url = $validated['file_url'];
            $file_public_id = $validated['file_public_id'];

            // Get or create a conversation ID
            $conversationId = $this->getConversationId($senderId, $recipientId);


            // Prevent sending message to someone who blocked you
$isBlocked = BlockedUser::where('user_id', $recipientId)
    ->where('blocked_user_id', $senderId)
    ->exists();

if ($isBlocked) {
    return response()->json(['status' => 'error', 'message' => 'You are blocked by this user.'], 403);
}

// Prevent sending message to someone you’ve blocked
$youBlocked = BlockedUser::where('user_id', $senderId)
    ->where('blocked_user_id', $recipientId)
    ->exists();

if ($youBlocked) {
    return response()->json(['status' => 'error', 'message' => 'You have blocked this user.'], 403);
}


            // Create and save the message
            $message = Message::create([
                'conversation_id' => $conversationId,
                'sender_id' => $senderId,
                'recipient_id' => $recipientId,
                'message' => $messageText,
                'file_url' => $file_url,
                'file_public_id' => $file_public_id,
            ]);

            event(new MessageSent($message));

            // Return the created message in the response
            return response()->json(['status' => 'success', 'message' => $message], 200);
        } catch (\Throwable $th) {
            return response()->json(['status' => 'error', 'message' => $th->getMessage()], 500);
        }
    }

    public function fetchMessages(Request $request)
    {
        try {
            $validated = $request->validate([
                'conversation_id' => 'required|exists:conversations,id',
            ]);

            // Retrieve all messages for the specified conversation
            $messages = Message::where('conversation_id', $validated['conversation_id'])->get();

            // Return the messages in the response
            return response()->json(['status' => 'success', 'data' => $messages], 200);
        } catch (\Throwable $th) {
            return response()->json(['status' => 'error', 'message' => $th->getMessage()], 404);
        }
    }

    //Support Mail
    public function supportMail(Request $request)
    {
        // Validation
        try {
            $validated = $request->validate([
                'subject' => 'required|string|max:255',
                'message' => 'required|string|max:500',
                'sender_id' => 'required',
                'receiver_id' => 'nullable',
                'attachment' => 'nullable',
            ]);

            $ticket_no = 'FG' . rand(10000, 99999);

            SupportMail::create([
                'subject' => $validated['subject'],
                'message' => $validated['message'],
                'user_id' => $validated['sender_id'],
                'receiver_id' => $validated['receiver_id'] ?? NULL,
                'ticket_no' => $ticket_no,
                'attachment' => $validated['attachment'],
            ]);

            $user = User::where('id', $validated['sender_id'])->first();
            Mail::to('fixginiservices@gmail.com')->send(new SupportEmail($user, $validated['subject']));

            return response()->json(['status' => 'success', 'message' => 'Thank you! Admin will get intouch with you shortly'], 200);
        } catch (\Throwable $th) {
            return response()->json(['status' => 'success', 'message' => $th->getMessage()], 500);
        }
    }

    public function storeToken(Request $request)
    {
        $request->validate([
            'token' => 'required|string',
        ]);
        $user = Auth::user();
        $updateUser = User::where('id', $user->id)->first();
        if ($updateUser) {
            $updateUser->update([
                'fcm_token' => $request->token, // Assuming your users table has an `fcm_token` column
            ]);
            return response()->json(['message' => 'Token saved successfully.', 'status' => 'success']);
        }
        return response()->json(['message' => 'User not authenticated.', 'status' => 'error'], 401);
    }

    public function sendFcmNotification(Request $request)
    {
        try {
            // Validate request
           $data = $request->validate([
                'message' => 'required',
                'receiver_id' => 'required',
            ]);
            $receiver = User::where('id', $data['receiver_id'])->first();

            $fcmToken = $receiver->fcm_token;
            info('FCM' . $fcmToken);
            info('receiver data ' . $receiver);
            
            if (empty($fcmToken)) {
                return response()->json(['message' => 'No FCM token available for this user'], 400);
            }

            // Path to Firebase service account credentials
            $credentialsFilePath = public_path("fixgini-168886924712.json");
            $projectId = 'fixgini';

            // Retrieve access token for FCM using Google Client
            $client = new GoogleClient();
            $client->setAuthConfig($credentialsFilePath);
            $client->useApplicationDefaultCredentials();
            $client->addScope('https://www.googleapis.com/auth/firebase.messaging');
            $client->fetchAccessTokenWithAssertion();
            $token = $client->getAccessToken();
            $accessToken = $token['access_token'];

            // Set up headers for FCM API
            $headers = [
                "Authorization: Bearer $accessToken",
                'Content-Type: application/json',
            ];

            $data = [
                "title" => "Dear {$user->name}",
                "message" => $request->message,
                "type" => "single_chat",
            ];
            $notification = [
                "title" => "Dear {$user->name}",
                "body" => $request->message,
            ];
            $webpush = [
                "fcm_options" => [
                    "link" => "https://fixgini.com/chat"
                ],
            ];

            // FCM API payload for the single user
            $data = [
                "message" => [
                    // "token" => 'eK40dI1WTMOmZLJzCfB0fp:APA91bE7g5Z0_H12gzLIilPNSpTYo1jhvZsK6gjLJqsOCpUngtlZ7N2765iE_YSXody6wzbrDKA6bfwd3-wGMghLi1I3NaWSMzGVGH265Q7TbdXDVC-yfsQ',
                    "token" => $fcmToken,
                    "data" => $data,
                    "notification" => $notification,
                    "webpush" => $webpush,
                ],

            ];
            $payload = json_encode($data);

            // Send the notification via cURL
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send");
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            $response = curl_exec($ch);
            $err = curl_error($ch);
            curl_close($ch);

            // Check for errors
            if ($err) {
                Log::error('Curl Error: ', ['error' => $err]); // Use array structure for logging
                return response()->json([
                    'message' => 'Curl Error: ' . $err,
                ], 500);
            } else {
                // Decode response for logging
                $decodedResponse = json_decode($response, true);
                Log::info('Notification sent successfully with response : ', $decodedResponse); // Log array response properly

                return response()->json([
                    'message' => 'Notification sent successfully',
                    'response' => $decodedResponse, // Return decoded response as JSON
                ], 200);
            }
        } catch (\Throwable $th) {
            Log::error($th->getMessage());
            // Catch and handle errors
            return response()->json([
                'message' => $th->getMessage(),
            ], 500);
        }
    }

    // new codes  block user, get blocked user, unblock user

    // block user

    public function blockUser(Request $request)
{
    $request->validate([
        'blocked_user_id' => 'required|exists:users,id',
        'report_reason' => 'nullable|string|max:255',
        'report_description' => 'nullable|string|max:1000',
    ]);

    $userId = Auth::id();
    $blockedUserId = $request->blocked_user_id;

    // Prevent self-blocking
    if ($userId == $blockedUserId) {
        return response()->json([
            'status' => 'error',
            'message' => 'You cannot block yourself.'
        ], 400);
    }

    // Check if already blocked
    $existing = BlockedUser::where('user_id', $userId)
        ->where('blocked_user_id', $blockedUserId)
        ->first();

    if ($existing) {
        return response()->json([
            'status' => 'error',
            'message' => 'User already blocked.'
        ], 400);
    }

    // Create block with optional report
    $block = BlockedUser::create([
        'user_id' => $userId,
        'blocked_user_id' => $blockedUserId,
        'report_reason' => $request->report_reason,
        'report_description' => $request->report_description,
    ]);

    // Optional: notify admin or log report
    if ($request->filled('report_reason')) {
        // You can log this or email admins
        \Log::info('User reported another user', [
            'reported_by' => $userId,
            'reported_user' => $blockedUserId,
            'reason' => $request->report_reason,
        ]);
    }

    return response()->json([
        'status' => 'success',
        'message' => 'User blocked successfully.',
        'data' => $block,
    ]);
}


    //block user

    //unblock user

    public function unblockUser(Request $request)
    {
        $request->validate([
            'blocked_user_id' => 'required|exists:users,id',
        ]);

        $userId = Auth::id();

        $deleted = BlockedUser::where('user_id', $userId)
            ->where('blocked_user_id', $request->blocked_user_id)
            ->delete();

        if (!$deleted) {
            return response()->json(['status' => 'error', 'message' => 'User not found in block list.'], 404);
        }

        return response()->json(['status' => 'success', 'message' => 'User unblocked successfully.']);
    }
    //unblock user


    // Get list of blocked users
    public function getBlockedUsers()
    {
        $userId = Auth::id();
        $blocked = BlockedUser::where('user_id', $userId)
            ->with('blockedUser:id,name,email') // eager load details
            ->get();

        return response()->json(['status' => 'success', 'data' => $blocked]);
    }

    // send message modified


    public function sendMessage1111(Request $request)
{
    $request->validate([
        'recipient_id' => 'required|exists:users,id',
        'message' => 'required|string|max:5000',
    ]);

    $senderId = Auth::id();
    $recipientId = $request->recipient_id;

    // ✅ 1. Prevent sending message to yourself
    if ($senderId == $recipientId) {
        return response()->json([
            'status' => 'error',
            'message' => 'You cannot send a message to yourself.'
        ], 400);
    }

    // ✅ 2. Check if recipient has blocked sender
    $isBlocked = BlockedUser::where('user_id', $recipientId)
        ->where('blocked_user_id', $senderId)
        ->exists();

    if ($isBlocked) {
        return response()->json([
            'status' => 'error',
            'message' => 'You are blocked by this user.'
        ], 403);
    }

    // ✅ 3. Check if sender has blocked recipient
    $youBlocked = BlockedUser::where('user_id', $senderId)
        ->where('blocked_user_id', $recipientId)
        ->exists();

    if ($youBlocked) {
        return response()->json([
            'status' => 'error',
            'message' => 'You have blocked this user. Unblock them to send a message.'
        ], 403);
    }

    // ✅ 4. Create the message
    $message = Message::create([
        'sender_id' => $senderId,
        'recipient_id' => $recipientId,
        'content' => $request->message,
    ]);

    // ✅ 5. (Optional) broadcast or notify recipient here if using events
    // broadcast(new MessageSent($message))->toOthers();

    return response()->json([
        'status' => 'success',
        'message' => 'Message sent successfully.',
        'data' => $message,
    ]);
}


    //send message modified

    // new codes
}