HEX
Server: LiteSpeed
System: Linux my-kul-web2054.main-hosting.eu 5.14.0-611.13.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 11 04:57:59 EST 2025 x86_64
User: u665686179 (665686179)
PHP: 8.2.30
Disabled: system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
Upload Files
File: /home/u665686179/domains/dealkr.com/public_html/app/Http/Controllers/Web/ChattingController.php
<?php

namespace App\Http\Controllers\Web;

use App\Contracts\Repositories\ChattingRepositoryInterface;
use App\Contracts\Repositories\CustomerRepositoryInterface;
use App\Contracts\Repositories\DeliveryManRepositoryInterface;
use App\Contracts\Repositories\ShopRepositoryInterface;
use App\Contracts\Repositories\VendorRepositoryInterface;
use App\Enums\ViewPaths\Web\Chatting;
use App\Events\ChattingEvent;
use App\Http\Controllers\BaseController;
use App\Http\Requests\Web\ChattingRequest;
use App\Services\ChattingService;
use App\Traits\PushNotificationTrait;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class ChattingController extends BaseController
{
    use PushNotificationTrait;

    /**
     * @param ChattingRepositoryInterface $chattingRepo
     * @param ShopRepositoryInterface $shopRepo
     * @param ChattingService $chattingService
     * @param DeliveryManRepositoryInterface $deliveryManRepo
     * @param CustomerRepositoryInterface $customerRepo
     * @param VendorRepositoryInterface $vendorRepo
     */
    public function __construct(
        private readonly ChattingRepositoryInterface    $chattingRepo,
        private readonly ShopRepositoryInterface        $shopRepo,
        private readonly ChattingService                $chattingService,
        private readonly DeliveryManRepositoryInterface $deliveryManRepo,
        private readonly CustomerRepositoryInterface    $customerRepo,
        private readonly VendorRepositoryInterface      $vendorRepo,
    )
    {
    }

    /**
     * @param Request|null $request
     * @param string|array|null $type
     * @return View|Collection|LengthAwarePaginator|callable|RedirectResponse|null
     */
    public function index(?Request $request, string|array $type = null): View|Collection|LengthAwarePaginator|null|callable|RedirectResponse
    {
        return match ($type) {
            'delivery-man' => $this->getChatList(relation: ['deliveryMan'], columnName: 'delivery_man_id', type: $type),
            'vendor' => $this->getChatList(relation: ['seller'], columnName: 'seller_id', type: $type),
        };
    }

    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function getMessageByUser(Request $request): JsonResponse
    {
        if ($request->has(key: 'delivery_man_id')) {
            $getUser = $this->deliveryManRepo->getFirstWhere(params: ['id' => $request['delivery_man_id']]);
            $requestColumn = 'delivery_man_id';
            $requestId = $request['delivery_man_id'];
            $whereNotNull = ['user_id', 'delivery_man_id'];
            $relation = ['deliveryMan'];
            $type = 'delivery-man';
        } elseif ($request->has(key: 'vendor_id') && $request['vendor_id'] == 0) {
            $getUser = 'admin';
            $requestColumn = 'admin_id';
            $requestId = 0;
            $whereNotNull = ['user_id', 'admin_id'];
            $relation = ['admin'];
            $type = 'admin';
        } else {
            $vendorData = $this->vendorRepo->getFirstWhere(params: ['id' => $request['vendor_id']], relations: ['shop']);
            $getUser = $vendorData->shop;
            $requestColumn = 'seller_id';
            $requestId = $request['vendor_id'];
            $whereNotNull = ['user_id', 'seller_id', 'shop_id'];
            $relation = ['seller'];
            $type = 'vendor';
        }
        $this->updateAllUnseenMessageStatus(requestColumn: $requestColumn, requestId: $requestId);
        $chattingMessages = $this->getMessage(requestColumn: $requestColumn, requestId: $requestId, whereNotNull: $whereNotNull, relation: $relation);
        $data = self::getRenderMessagesView(user: $getUser, message: $chattingMessages, type: $type);
        return response()->json($data);
    }

    /**
     * @param ChattingRequest $request
     * @return JsonResponse
     */
    public function addMessage(ChattingRequest $request): JsonResponse
    {
        $customerId = auth('customer')->id();
        $customer = $this->customerRepo->getFirstWhere(params: ['id' => $customerId]);
        if ($request->has(key: 'delivery_man_id')) {
            $this->chattingRepo->add(
                data: $this->chattingService->addChattingDataForWeb(
                    request: $request,
                    userId: $customerId,
                    type: 'deliveryman',
                    deliveryManId: $request['delivery_man_id']
                )
            );
            $getUser = $this->deliveryManRepo->getFirstWhere(params: ['id' => $request['delivery_man_id']]);
            $requestColumn = 'delivery_man_id';
            $requestId = $request['delivery_man_id'];
            $whereNotNull = ['user_id', 'delivery_man_id'];
            $relation = ['deliveryMan'];
            $type = 'delivery-man';
            event(new ChattingEvent(key: 'message_from_customer', type: 'delivery_man', userData: $getUser, messageForm: $customer));
        } elseif ($request->has(key: 'vendor_id') && $request['vendor_id'] == 0) {
            $this->chattingRepo->add(
                data: $this->chattingService->addChattingDataForWeb(
                    request: $request,
                    userId: $customerId,
                    type: 'admin',
                    adminId: $request['vendor_id']
                )
            );
            $getUser = 'admin';
            $requestColumn = 'admin_id';
            $requestId = 0;
            $whereNotNull = ['user_id', 'admin_id'];
            $relation = ['admin'];
            $type = 'admin';
        } else {
            $vendorData = $this->vendorRepo->getFirstWhere(params: ['id' => $request['vendor_id']], relations: ['shop']);

            $this->chattingRepo->add(
                data: $this->chattingService->addChattingDataForWeb(
                    request: $request,
                    userId: $customerId,
                    type: 'seller',
                    shopId: $vendorData?->shop?->id,
                    vendorId: $vendorData['id'])
            );

            event(new ChattingEvent(key: 'message_from_customer', type: 'seller', userData: $vendorData, messageForm: $customer));
            $getUser = $vendorData->shop;
            $requestColumn = 'seller_id';
            $requestId = $vendorData['id'];
            $whereNotNull = ['user_id', 'seller_id', 'shop_id'];
            $relation = ['seller'];
            $type = 'vendor';
        }
        $chattingMessages = $this->getMessage(requestColumn: $requestColumn, requestId: $requestId, whereNotNull: $whereNotNull, relation: $relation);
        $data = self::getRenderMessagesView(user: $getUser, message: $chattingMessages, type: $type);
        return response()->json($data);
    }

    /**
     * @param array $relation
     * @param string $columnName
     * @param string $type
     * @return View
     */
    private function getChatList(array $relation, string $columnName, string $type): View
    {
        $customerId = auth('customer')->id();
        $allChattingUsers = $this->chattingRepo->getListWhereNotNull(
            orderBy: ['id' => 'DESC'],
            filters: ['user_id' => $customerId],
            whereNotNull: [$columnName],
            relations: $relation,
            dataLimit: 'all'
        )->unique($columnName);

        if ($type == 'vendor') {
            $inHouseInfo = $this->chattingRepo->getListWhereNotNull(
                orderBy: ['id' => 'DESC'],
                filters: ['user_id' => $customerId],
                whereNotNull: ['admin_id'],
                relations: ['admin'],
                dataLimit: 'all'
            )->unique('admin_id');
            $allChattingUsers = $inHouseInfo->count() > 0 ? ($allChattingUsers->merge($inHouseInfo))->sortByDesc('id')->values() : $allChattingUsers;
        }
        $allChattingUsers?->map(function ($chatting, $index) use ($allChattingUsers, $customerId) {
            $filterColumn = !is_null($chatting?->admin_id) ? 'admin_id' : (!is_null($chatting?->seller_id) ? 'seller_id' : 'delivery_man_id');
            $filterId = $chatting?->admin_id ?? ($chatting?->seller_id ? $chatting->shop->id : $chatting->deliveryMan->id);
            $filter = [
                'user_id' => $customerId,
                $filterColumn => $filterId,
                'sent_by_customer' => 0,
                'seen_by_customer' => 0,
            ];
            $unseenMessageCount = $this->chattingRepo->getListWhere(
                filters: $filter, dataLimit: 'all'
            )->count();
            if ($index === 0) {
                $chatting['unseen_message_count'] = 0;
            } else {
                $chatting['unseen_message_count'] = $unseenMessageCount;
            }
        });
        $lastChatUser = null;
        foreach ($allChattingUsers as $key => $value) {
            $lastChatUser = (!is_null($value->admin_id) ? ['id' => 0] : (!is_null($value->seller_id) ? $value->shop : $value->deliveryMan));
            if (!is_null($value->admin_id)) {
                $columnName = 'admin_id';
                $type = 'admin';
                $relation = ['admin'];
            }
            break;
        }
        if ($lastChatUser) {
            $this->updateAllUnseenMessageStatus(requestColumn: $columnName, requestId: $lastChatUser['id']);
            $chattingMessages = $this->getMessage(requestColumn: $columnName, requestId: $lastChatUser['id'], whereNotNull: ['user_id', $columnName], relation: $relation);
        } else {
            $chattingMessages = [];
        }
        return view(VIEW_FILE_NAMES['user_inbox'], [
            'userType' => $type,
            'userData' => $lastChatUser ? $this->getUserData(type: $type, user: ($lastChatUser['id'] == 0 ? 'admin' : $lastChatUser)) : '',
            'allChattingUsers' => $allChattingUsers,
            'lastChatUser' => $lastChatUser,
            'chattingMessages' => $chattingMessages,
        ]);
    }

    /**
     * @param object|string $user
     * @param object $message
     * @param string $type
     * @return array
     */
    protected function getRenderMessagesView(object|string $user, object $message, string $type): array
    {
        return [
            'userData' => $this->getUserData(type: $type, user: $user),
            'chattingMessages' => view(VIEW_FILE_NAMES['user_inbox_message'], [
                'lastChatUser' => $user,
                'userType' => $type,
                'chattingMessages' => $message
            ])->render(),
        ];
    }

    private function getUserData($type, $user): array
    {
        if ($type == 'vendor') {
            $userData = ['name' => $user['name'], 'phone' => $user['contact']];
            $userData['image'] = getStorageImages(path: $user->image_full_url, type: 'shop');
            $userData['temporary-close-status'] = (int)checkVendorAbility(type: 'vendor', status: 'temporary_close', vendor: $user);
        } elseif ($type == 'delivery-man') {
            $userData = ['name' => $user['f_name'] . ' ' . $user['l_name'], 'phone' => $user['country_code'] . $user['phone']];
            $userData['image'] = getStorageImages(path: $user->image_full_url, type: 'avatar');
            $userData['temporary-close-status'] = '';
        } else {
            $userData = ['name' => getInHouseShopConfig(key: 'name'), 'phone' => ''];
            $userData['image'] = getStorageImages(path: getInHouseShopConfig(key: 'image_full_url'), type: 'shop');
            $userData['temporary-close-status'] = (int)checkVendorAbility(type: 'inhouse', status: 'temporary_close');
        }
        return $userData;
    }

    private function getMessage($requestColumn, $requestId, $whereNotNull, $relation): Collection
    {
        $customerId = auth('customer')->id();
        $orderBy = theme_root_path() == 'default' ? ['id' => 'DESC'] : ['id' => 'ASC'];
        return $this->chattingRepo->getListWhereNotNull(
            orderBy: $orderBy,
            filters: ['user_id' => $customerId, $requestColumn => $requestId],
            whereNotNull: $whereNotNull,
            relations: $relation,
            dataLimit: 'all'
        );
    }

    private function updateAllUnseenMessageStatus($requestColumn, $requestId): void
    {
        $customerId = auth('customer')->id();
        $this->chattingRepo->updateAllWhere(
            params: ['user_id' => $customerId, $requestColumn => $requestId],
            data: ['seen_by_customer' => 1]
        );
    }
}