src/Controller/MessageController.php line 75

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Clinic\Clinic;
  4. use App\Entity\Clinic\Person\ClinicUser;
  5. use App\Entity\Domain;
  6. use App\Entity\Website;
  7. use App\Entity\Person\Setting;
  8. use App\Entity\Media\Media;
  9. use App\Services\MediaManager;
  10. use App\Aws\SESManager;
  11. use App\Aws\S3Manager;
  12. use App\Entity\Meeting;
  13. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Psr\Log\LoggerInterface;
  21. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  22. use App\Entity\Person\SuperClinicAdmin;
  23. use App\Entity\Person\User;
  24. use Symfony\Component\Serializer\SerializerInterface;
  25. use Symfony\Component\Filesystem\Filesystem;
  26. use Symfony\Component\HttpFoundation\File\UploadedFile;
  27. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  28. /**
  29.  * Class MessageController.
  30.  */
  31. class MessageController extends AbstractController
  32. {
  33.        /**
  34.      * @var SerializerInterface
  35.      */
  36.     private $serializer;
  37.     /**
  38.      * @var LoggerInterface
  39.      */
  40.     private $logger;
  41.     /**
  42.      * @var SESManager
  43.      */
  44.      
  45.     private $SESManager;
  46.     /**
  47.      * @var MediaManager
  48.      */
  49.     private $mediaManager;
  50.     /**
  51.      * @var Filesystem
  52.      */
  53.     private $filesystem;
  54.     /**
  55.      * @var string
  56.      */
  57.     /**
  58.      * @var S3Manager
  59.      */
  60.     private $s3Manager;
  61.     public function __construct(LoggerInterface $logger,SerializerInterface $serializerSESManager $SESManagerMediaManager $mediaManagerS3Manager $s3ManagerFilesystem $filesystem)
  62.     {
  63.         $this->logger $logger;
  64.         $this->SESManager $SESManager;
  65.         $this->mediaManager $mediaManager;
  66.         $this->filesystem $filesystem;
  67.         $this->s3Manager $s3Manager;
  68.         $this->serializer $serializer;
  69.         @date_default_timezone_set(@$_COOKIE['tz']);
  70.     }
  71.     /**
  72.      * @Route("/admin/message/index", name="index")
  73.      */
  74.     public function index(Request $request): Response
  75.     {
  76.         // dd($_COOKIE);
  77.         $data = [];
  78.         $data['convId'] = (@$_GET['conv_id'] > 0) ? $_GET['conv_id'] : 0;
  79.         $data['user'] = $this->getUser();
  80.         $data['needLicense'] = false;
  81.         
  82.         if ($data['user']->getRole() != 'ROLE_CONSENTZ_ADMIN') {
  83.             
  84.             if ($data['user']->getClinic() != null) {
  85.                 $data['clinic'] = $this->getDoctrine()->getRepository(Clinic::class)
  86.                     ->find($data['user']->getClinic());
  87.             } else if ($data['user']->getOrganisation() && $data['user']->getOrganisation()->getClinics()->count() > && $data['user']->getRole() == 'ROLE_SUPER_CLINIC_ADMIN') {
  88.                 $data['clinic'] = $data['user']->getOrganisation()->getClinics()->first();
  89.             }
  90.             if ($data['clinic']) {
  91.                 return new RedirectResponse($this->generateUrl('clinic_message_index', ['clinicId' => $data['clinic']->getId()]));
  92.             }
  93.             return $this->render('message/index.html.twig'$data);
  94.         }else{
  95.             if($request->get('clinic') > 0){
  96.    
  97.             $clinic $this->getDoctrine()->getRepository(Clinic::class)
  98.                     ->find$request->get('clinic'));
  99.                 $user =  $this->getDoctrine()->getRepository(ClinicUser::class)->findOneBy([
  100.                     'clinic' =>$clinic,
  101.                     'deleted' => false,
  102.                     'locked' => false,
  103.                     'role' => User::ROLE_SUPER_CLINIC_ADMIN
  104.                 ]);
  105.                 if (!$user && $clinic->getOrganisation()) {
  106.                     $user $clinic->getOrganisation()->getAdmins()->first();
  107.                 }
  108.                 return new RedirectResponse($this->generateUrl('messagestart') . '?user_id=' $user->getId());
  109.             } 
  110.             return $this->render('message/admin_index.html.twig'$data);
  111.         }
  112.     }
  113.     /**
  114.      * @Route("/admin/message/index/{clinicId}", name="clinic_message_index")
  115.      */
  116.     public function clinic_message_index(Request $request$clinicId): Response
  117.     {
  118.         $data = [];
  119.         $data['convId'] = (@$_GET['conv_id'] > 0) ? $_GET['conv_id'] : 0;
  120.         $data['user'] = $this->getUser();
  121.         $data['needLicense'] = false;
  122.         if ($data['user']->getRole() != 'ROLE_CONSENTZ_ADMIN') {
  123.             $myClinic false;
  124.             if ($data['user']->getOrganisation() && $data['user']->getOrganisation()->getClinics()->count() > && $data['user']->getRole() == 'ROLE_SUPER_CLINIC_ADMIN') {
  125.                 foreach ($data['user']->getOrganisation()->getClinics() as $cl) {
  126.                     if ($cl->getId() == $clinicId) {
  127.                         $myClinic true;
  128.                         break;
  129.                     }
  130.                 }
  131.             } else if ($data['user']->getClinic() != null) {
  132.                 if ($data['user']->getClinic()->getId() == $clinicId) {
  133.                     $myClinic true;
  134.                 }
  135.             }
  136.             if (!$myClinic) {
  137.                 return new JsonResponse(['status' => 'error''message' => 'Clinic Not Exist']);
  138.             }
  139.             $data['clinic'] =  $this->getDoctrine()->getRepository(Clinic::class)
  140.                 ->find($clinicId);
  141.             if (!$data['clinic']) {
  142.                 return new RedirectResponse($this->generateUrl('message_index'));
  143.             }
  144.         }
  145.         
  146.         $clinic $data['clinic'];
  147.         if($clinic->getOrganisation()) {
  148.           if($clinic->getOrganisation()->isEnableFeatureLicensingMessage()) {
  149.             if(!$clinic->hasLicense(Clinic::FEATURE_MESSAGE)) {
  150.               $data['needLicense'] = true;
  151.               //return $this->redirectToRoute('need_feature_license', ['clinic' => $clinic->getId(), 'featureCode' => Clinic::FEATURE_MESSAGE]);
  152.             }
  153.           }
  154.         }
  155.         
  156.         return $this->render('message/index.html.twig'$data);
  157.     }
  158.     /**
  159.      * @Route("/admin/message/start", name="messagestart")
  160.      */
  161.     public function messagestart(Request $request): Response
  162.     {
  163.         $opponantId = @$_GET['user_id'];
  164.         $data $this->startNewConversation($opponantId);
  165.         if ($request->isXmlHttpRequest()) {
  166.             return new JsonResponse($data);
  167.         } else {
  168.             if ($data['status'] == 1) {
  169.                 return new RedirectResponse($this->generateUrl('message_index') . '?conv_id=' $data['convId']);
  170.             } else {
  171.                 return new RedirectResponse($this->generateUrl('message_index'));
  172.             }
  173.         }
  174.     }
  175.     /**
  176.      * @Route("/admin/message/conversation_list", name="conversation_list")
  177.      */
  178.     public function conversation_list(Request $request): Response
  179.     {
  180.         $user $this->getUser();
  181.         $userId $user->getId();
  182.         $filter =  $request->get('filter');
  183.         $section = ($request->get('section') > 0) ? $request->get('section') : 0;
  184.         $offset = ($request->get('offset') > 0) ? $request->get('offset') : 0;
  185.         $em $this->getDoctrine()->getManager();
  186.         $adminConversation = [];
  187.         if($user->getRole() != 'ROLE_CONSENTZ_ADMIN'){
  188.             $sql "select id from user where deleted=? and role =?";
  189.             $ap $em->getConnection()->prepare($sql);
  190.             $ap->execute([0,'ROLE_CONSENTZ_ADMIN']);
  191.             $admins =   $ap->fetchAll();
  192.             $adminIds array_column($admins'id');
  193.             foreach($adminIds as $adminId){
  194.                 $params = [];
  195.                 $adminsSql 'select c.*,m.message,m.type as msgtype from conversation  as c left join chat_messages as m on m.id=c.last_chat_id left join user as u on IF(c.from_user_id=?,u.id=c.to_user_id,u.id=c.from_user_id) where FIND_IN_SET(?, c.user_ids) AND FIND_IN_SET(?, c.user_ids) and c.type=? ';
  196.                 $params[] = $userId;
  197.                 $params[] = $userId;
  198.                 $params[] = $adminId;
  199.                 $params[] = 0;
  200.                 if ($filter['search'] != '') {
  201.                     $adminsSql .= ' and (u.first_name like ? or u.last_name like ? or u.email like ? or u.username like ? or c.title like ?)';
  202.                     $params[] = '%' trim($filter['search']) . '%';
  203.                     $params[] = '%' trim($filter['search']) . '%';
  204.                     $params[] = '%' trim($filter['search']) . '%';
  205.                     $params[] = '%' trim($filter['search']) . '%';
  206.                     $params[] = '%' trim($filter['search']) . '%';
  207.                 }
  208.                 $ap $em->getConnection()->prepare($adminsSql);
  209.                 $ap->execute($params);
  210.                 $adminConv =   $ap->fetchAssociative();
  211.                 if($adminConv){
  212.                     $adminConversation[] = $adminConv;
  213.                 }
  214.                 break;
  215.             }
  216.             $adminConvIds array_column($adminConversation'id');
  217.         }else{
  218.             $adminConvIds = [];
  219.         }
  220.       
  221.         $userRole=$user->getRole();
  222.     
  223. //end here
  224.         $limit 50;
  225.         $query['select'] = 'c.*,m.message,m.type as msgtype';
  226.         $query['query'] = 'from conversation  as c ';
  227.         $query['query'] .= 'left join chat_messages as m on m.id=c.last_chat_id  ';
  228.         $query['params'] = [];
  229.         if ($filter['search'] != '') {
  230.             $query['query'] .= 'left join user as u1 on (c.from_user_id=? and u1.id=c.to_user_id) ';
  231.             $query['params'][] = $userId;
  232.             $query['query'] .= 'left join user as u2 on (c.from_user_id!=? and u2.id=c.from_user_id) ';
  233.             $query['params'][] = $userId;
  234.     
  235.             $query['query'] .= ' where (u1.first_name like ? or u2.first_name like ? or u1.last_name like ? or u1.email like ? or u1.username like ? or u2.last_name like ? or u2.email like ? or u2.username like ? or c.title like ?) '//
  236.             $query['params'][] = '%' trim($filter['search']) . '%';
  237.             $query['params'][] = '%' trim($filter['search']) . '%';
  238.             $query['params'][] = '%' trim($filter['search']) . '%';
  239.             $query['params'][] = '%' trim($filter['search']) . '%';
  240.             $query['params'][] = '%' trim($filter['search']) . '%';
  241.             $query['params'][] = '%' trim($filter['search']) . '%';
  242.             $query['params'][] = '%' trim($filter['search']) . '%';
  243.             $query['params'][] = '%' trim($filter['search']) . '%';
  244.             $query['params'][] = '%' trim($filter['search']) . '%';
  245.             $query['query'] .= ' and FIND_IN_SET(?,c.user_ids) ';  
  246.             $query['params'][] = $userId;          
  247.         } else {
  248.             $query['query'] .= ' where FIND_IN_SET(?,c.user_ids) '
  249.             $query['params'][] = $userId;                      
  250.         }
  251.         $query['query'] .= 'AND (c.deleted_by IS NULL OR NOT FIND_IN_SET(?,c.deleted_by)) '
  252.         $query['params'][] = $userId;                      
  253.         if(!empty($adminConversation)){
  254.             $query['query'] .= ' and c.id NOT IN (' implode(','array_fill(0count($adminConvIds), '?')) . ') order by c.updated_at desc';
  255.             $query['params'] = array_merge($query['params'],$adminConvIds);
  256.         }else{
  257.             $query['query'] .= ' order by c.updated_at desc';
  258.         }
  259.         $query['query'] .= ' limit ' $limit ' offset ' $offset ' ';
  260.         $ap $em->getConnection()->prepare('select ' $query['select'] . ' ' $query['query']);
  261.         $ap->execute($query['params']);
  262.         $conversations $ap->fetchAll();
  263.         $convList = [];
  264.         if(!empty($adminConversation) && $offset == 0){
  265.             $conversations array_merge($adminConversation,$conversations);
  266.         }
  267.         $offset count($conversations) + $offset;
  268.         $hasMore false;
  269.         if ($limit <= count($conversations)) {
  270.             $hasMore true;
  271.         }
  272.         
  273.         foreach ($conversations as $conversation) {
  274.             if ($conversation['type'] == 0) {
  275.                 if ($conversation['from_user_id'] == $userId) {
  276.                     $opponantId $conversation['to_user_id'];
  277.                 } else {
  278.                     $opponantId $conversation['from_user_id'];
  279.                 }
  280.                 $sql "select user.*,media.url from user left join media on media.id=user.media_id where user.id = ?";
  281.                 $ap $em->getConnection()->prepare($sql);
  282.                 $ap->execute([$opponantId]);
  283.                 $userData $ap->fetchAssociative();
  284.                 if (!$userData) {
  285.                     continue;
  286.                 }
  287.                 //  dd($userData);
  288.                 
  289.                 $conversation['title'] = $userData['first_name'] . ' ' $userData['last_name'];
  290.                 $conversation['slug'] = $userData['username'];
  291.                 $conversation['is_online'] = $userData['is_online'];
  292.                 $conversation['is_available'] = 1;
  293.                 $conversation['is_online_class'] = ($userData['is_online'] == 1) ? 'greendot' 'reddot';
  294.                 $conversation['group_tag'] = '';
  295.                 $conversation['thumb'] = ($userData['profile_img'] != '') ? $userData['profile_img'] : (($userData['url'] != '')?$userData['url']:'/images/Clinic/solid_gray.png');
  296.                 $conversation['group_class'] = '';
  297.                 $conversation['delete_class'] = $userData['role'] == 'ROLE_CONSENTZ_ADMIN'?'withdelete'.(in_array($conversation['id'],$adminConvIds)?' pinnedchat':''):'';
  298.             
  299.             } else {
  300.                 $conversation['title'] = $conversation['title'];
  301.                 if ($conversation['clinic_id'] > 0) {
  302.                     $conversation['group_tag'] = "<span class='badge badge-infobg'>Clinic</span>";
  303.                     $conversation['delete_class'] = 'withdelete';
  304.                 } else {
  305.                     $conversation['group_tag'] = "<span class='badge badge-blue'>Group</span>";
  306.                     $conversation['delete_class'] = ($user->getRole() == 'ROLE_CONSENTZ_ADMIN' || ($userId == $conversation['from_user_id'])) ? '' 'withdelete';
  307.                    
  308.                 }
  309.                 $conversation['slug'] = '';
  310.                 $conversation['is_online'] = 0;
  311.                 $conversation['is_available'] = 0;
  312.                 $conversation['is_online_class'] = '';
  313.                 $conversation['group_class'] = 'withbtn';
  314.             }
  315.             $opponantId $conversation['from_user_id'] == $userId $conversation['to_user_id'] : $conversation['from_user_id'];
  316.             $sql "select count(*) as unread_count from chat_messages where conversation_id =? and not FIND_IN_SET(?,read_user_ids)";
  317.             $ap $em->getConnection()->prepare($sql);
  318.             $ap->execute([$conversation['id'], $userId]);
  319.             $unreadCount $ap->fetchAssociative();
  320.             $time '';
  321.             $msg_date '';
  322.             $msg_time '';
  323.             if($conversation['updated_at']){
  324.                 $time = ($conversation['updated_at'] > (time() - 86400)) ? date('h:i A'$conversation['updated_at']) : date('Y-m-d h:i A'$conversation['updated_at']);
  325.                 $msg_date = ($conversation['updated_at'] > (time() - 86400)) ? '' date('Y-m-d'$conversation['updated_at']);
  326.                 $msg_time = ($conversation['updated_at'] > (time() - 86400)) ? date('h:i A'$conversation['updated_at']) : date('h:i A'$conversation['updated_at']);
  327.             }else if ($conversation['created_at']) {
  328.                 $time = ($conversation['created_at'] > (time() - 86400)) ? date('h:i A'$conversation['created_at']) : date('Y-m-d h:i A'$conversation['created_at']);
  329.                 $msg_date = ($conversation['created_at'] > (time() - 86400)) ? '' date('Y-m-d'$conversation['created_at']);
  330.                 $msg_time = ($conversation['created_at'] > (time() - 86400)) ? date('h:i A'$conversation['created_at']) : date('h:i A'$conversation['created_at']);
  331.             }
  332.             if ($conversation['msgtype'] == 2) {
  333.                 $message =  '[Call]';
  334.             } else if ($conversation['msgtype'] == 1) {
  335.                 $message =  '[File]';
  336.             } else {
  337.                 $message $conversation['message'] ? $conversation['message']  : '';
  338.             }
  339.             if(isset($unreadCount['unread_count']) && $unreadCount['unread_count']){
  340.                 $this->receiveMessages($em,$userId,$conversation['id']);
  341.             }
  342.             $convList[] = [
  343.                 'conv_id' => $conversation['id'],
  344.                 'conv_type' => $conversation['type'],
  345.                 'conv_user_ids' => $conversation['user_ids'],
  346.                 'user_id' => ($conversation['type'] == 0) ? $opponantId '',
  347.                 'image' => ($conversation['type'] == 0) ?  $conversation['thumb'] : (($conversation['g_image'] != '') ? $conversation['g_image'] : '/images/Clinic/solid_gray.png'),
  348.                 'name' => $conversation['title'],
  349.                 'slug' => $conversation['slug'],
  350.                 'group_tag' => $conversation['group_tag'],
  351.                 'message' => $message,
  352.                 'date_msg' => $msg_date $msg_date '',
  353.                 'time_msg' => $msg_time $msg_time '',
  354.                 'created_at' => $time,
  355.                 'unread_count' => isset($unreadCount['unread_count']) && $unreadCount['unread_count'] ? $unreadCount['unread_count'] : '',
  356.                 'is_online' => ($conversation['is_online'] == 1) ? 0,
  357.                 'is_online_class' => $conversation['is_online_class'],
  358.                 'group_class' => $conversation['group_class'],
  359.                 'delete_class' => $conversation['delete_class']
  360.             ];
  361.         }
  362.         return new JsonResponse(['status' => 1'data' => $convList'hasMore' => $hasMore'offset' => $offset'role'=>$userRole]);
  363.     }
  364.     /**
  365.      * @Route("/admin/message/get_total_unread_messages", name="getTotalUnreadMessage")
  366.      */
  367.     public function getTotalUnreadMessage(Request $request)
  368.     {
  369.         $em $this->getDoctrine()->getManager();
  370.         $user $this->getUser();
  371.         $clinic $request->get('clinic');
  372.         $sql "SELECT cm.* FROM `chat_messages` as cm join conversation as c on c.id=cm.conversation_id where not FIND_IN_SET(?,cm.read_user_ids) and FIND_IN_SET(?,c.user_ids) limit 1";
  373.         $ap $em->getConnection()->prepare($sql);
  374.         $ap->execute([$user->getId(),$user->getId()]);
  375.         $chatMessages $ap->fetchAssociative();
  376.         if($clinic 0){
  377.             $sql "SELECT c.*,pc.clinic_id FROM communication as c join patient_conversation as pc on pc.id=c.conversation_id where  pc.clinic_id=? and c.read_status=0 and c.sender_type=? LIMIT 1";
  378.             $ap $em->getConnection()->prepare($sql);
  379.             $ap->execute([$clinic,1]);
  380.             $patientMessages $ap->fetchAssociative();
  381.             $sql "SELECT c.*,pc.clinic_id FROM prospect_communication as c join prospect_conversation as pc on pc.id=c.conversation_id where pc.clinic_id=? and c.read_status=0 and c.sender_type=? LIMIT 1";
  382.             $ap $em->getConnection()->prepare($sql);
  383.             $ap->execute([$clinic,1]);
  384.             $prospectMessages $ap->fetchAssociative();
  385.         }else{
  386.             $patientMessages NULL;
  387.             $prospectMessages NULL;
  388.         }
  389.         
  390.         return new JsonResponse(['chat_unread' => $chatMessages?1:0'patient_unread' => $patientMessages?1:0'prospect_unread' => $prospectMessages?1:0]);
  391.     }
  392.     /**
  393.      * @Route("/admin/message/list", name="message_list")
  394.      */
  395.     public function message_list(Request $request): Response
  396.     {
  397.         $user $this->getUser();
  398.         $userId $user->getId();
  399.         $em $this->getDoctrine()->getManager();
  400.         $convId $request->get('conv_id');
  401.         $offset =  $request->get('offset');
  402.         $sql "select * from conversation where id = ? and FIND_IN_SET(?,user_ids)";
  403.         $ap $em->getConnection()->prepare($sql);
  404.         $ap->execute([$convId,$userId]);
  405.         $conversation $ap->fetchAssociative();
  406.         if (!$conversation) {
  407.             return new JsonResponse(['status' => 0'message' => 'Conversation Not Found']);
  408.         }
  409.         $limit =  50;
  410.         $query['select'] = "m.*,concat(u.first_name,' ',u.last_name) as name ,u.profile_img as image,media.url as media_url ";
  411.         $query['query'] = 'from chat_messages as m ';
  412.         $query['query'] .= 'left join user as u on u.id=m.from_user_id ';
  413.         $query['query'] .= 'left join media on u.media_id=media.id ';
  414.         $query['params'] = [];
  415.         $query['query'] .= 'where m.conversation_id=?';  
  416.         $query['query'] .= 'AND (m.deleted_by IS NULL OR m.deleted_by NOT LIKE ?) ';      
  417.         $query['query'] .= 'order by m.created_at desc';
  418.         $query['params'] = [$convId,'%'.$userId.'%'];
  419.       
  420.         $query['query'] .= ' limit ' $limit ' offset ' $offset ' ';
  421.         $ap $em->getConnection()->prepare('select ' $query['select'] . ' ' $query['query']);
  422.         $ap->execute($query['params']);
  423.         $messageList $ap->fetchAll();
  424.         foreach ($messageList as $k => $message) {
  425.             $message['chat_id'] = $message['id'];
  426.             $message['receive_status'] = '';
  427.             if($conversation['type'] == 1){
  428.               $read_ids explode(',', @$message['read_user_ids']);
  429.               $receiver_ids explode(',', @$message['receiver_ids']);
  430.               $conversation_ids explode(',', @$conversation['user_ids']);
  431.               $hasBeenRead = empty(array_diff($conversation_ids$read_ids));
  432.               if(!$hasBeenRead){
  433.                  $hasBeenReceived =  empty(array_diff($conversation_ids$receiver_ids));
  434.                 if($hasBeenReceived){
  435.                   $message['receive_status'] = 'delivered';  
  436.                 }
  437.               }else{
  438.                 $message['receive_status'] = 'read';
  439.               } 
  440.             }else{
  441.                 if($message['from_user_id'] == $userId){
  442.                 $hasBeenRead in_array($message['to_user_id'],explode(','$message['read_user_ids']));
  443.                 if(!$hasBeenRead){
  444.                     $hasBeenReceived in_array($message['to_user_id'],explode(',', @$message['receiver_ids']));
  445.                     if($hasBeenReceived){
  446.                     $message['receive_status'] = 'delivered';  
  447.                     }
  448.                 }else{
  449.                     $message['receive_status'] = 'read';
  450.                 }
  451.                 }
  452.             } 
  453.             $messageList[$k] = $this->setData($message$userId);
  454.         }
  455.         $messageList array_reverse($messageList);
  456.         try {
  457.             $sql "UPDATE `chat_messages` SET `status` = 1 WHERE `conversation_id`=? and `to_user_id`=? ";
  458.             $appointment $em->getConnection()->prepare($sql);
  459.             $appointment->execute([$convId$userId]);
  460.         } catch (\Exception $e) {
  461.         }
  462.         try {
  463.             $sql "UPDATE `chat_messages` SET `read_user_ids` =concat(read_user_ids,',$userId')  WHERE `conversation_id`=? and not FIND_IN_SET(?,read_user_ids) ";
  464.             $appointment $em->getConnection()->prepare($sql);
  465.             $appointment->execute([$convId$userId]);
  466.         } catch (\Exception $e) {
  467.         }
  468.         return new JsonResponse(['status' => 1'conversation_id' => $convId'data' => $messageList'offset' => $offset 50]);
  469.     }
  470.     /**
  471.      * @Route("/admin/message/read", name="message_read")
  472.      */
  473.     public function message_read(Request $request): Response
  474.     {
  475.         $em $this->getDoctrine()->getManager();
  476.         $convId $request->get('conv_id');
  477.         $user $this->getUser();
  478.         $userId $user->getId();
  479.         $sql "UPDATE `conversation` SET `status` = 1 WHERE `id`=? and status=0 and to_user_id=?";
  480.         $appointment $em->getConnection()->prepare($sql);
  481.         $appointment->execute([$convId$userId]);
  482.         $sql "UPDATE `chat_messages` SET `read_user_ids` =concat(read_user_ids,',$userId')  WHERE `conversation_id`=? and not FIND_IN_SET(?,read_user_ids) ";
  483.         $appointment $em->getConnection()->prepare($sql);
  484.         $appointment->execute([$convId$userId]);
  485.         return new JsonResponse(['status' => 1'message' => 'success']);
  486.     }
  487.     /**
  488.      * @Route("/admin/message/receive", name="message_receive")
  489.      */
  490.     public function message_receive(Request $request): Response
  491.     {
  492.         $em $this->getDoctrine()->getManager();
  493.         $convId $request->get('conv_id');
  494.         $user $this->getUser();
  495.         $userId $user->getId();
  496.         $sql "UPDATE `conversation` SET `status` = 1 WHERE `id`=? and status=0 and to_user_id=?";
  497.         $appointment $em->getConnection()->prepare($sql);
  498.         $appointment->execute([$convId$userId]);
  499.         $this->receiveMessages($em,$userId,$convId);
  500.         
  501.         return new JsonResponse(['status' => 1'message' => 'success']);
  502.     }
  503.     private function receiveMessages($em,$userId,$convId){
  504.         $sql "UPDATE `chat_messages` SET `receiver_ids` =concat(receiver_ids,',$userId')  WHERE from_user_id != ? and `conversation_id`=? and not FIND_IN_SET(?,receiver_ids) and  not FIND_IN_SET(?,read_user_ids) ";
  505.         $appointment $em->getConnection()->prepare($sql);
  506.         $appointment->execute([$userId,$convId$userId$userId]);
  507.         return;
  508.     }
  509.     /**
  510.      * @Route("/admin/message/popup_read", name="message_popupread")
  511.      */
  512.     public function message_popupread(Request $request): Response
  513.     {
  514.         $em $this->getDoctrine()->getManager();
  515.         $popup_id $request->get('popup_id');
  516.         $user $this->getUser();
  517.         $userId $user->getId();
  518.         $sql "UPDATE `advertisements` SET `read_user_ids` =concat(read_user_ids,',$userId')  WHERE `id`=?  and
  519.         not FIND_IN_SET(?,read_user_ids) ";
  520.         $appointment $em->getConnection()->prepare($sql);
  521.         $appointment->execute([$popup_id,$userId]);
  522.         return new JsonResponse(['status' => 1'message' => 'success']);
  523.     }
  524.     /**
  525.      * @Route("/admin/message/popup_unread", name="message_popupunread")
  526.      */
  527.     public function message_popupunread(Request $request): Response
  528.     {
  529.         $em $this->getDoctrine()->getManager();
  530.         $popup_id $request->get('popup_id');
  531.         $user $this->getUser();
  532.         $userId $user->getId();
  533.         $sql "select * from advertisements where FIND_IN_SET(?,receiver_user_ids) and not FIND_IN_SET(?,read_user_ids)";
  534.         $appointment $em->getConnection()->prepare($sql);
  535.         $appointment->execute([$userId$userId]);
  536.         $popups $appointment->fetchAll();
  537.         return new JsonResponse(['status' => 1'data' => $popups]);
  538.     }
  539.     /**
  540.      * @Route("/admin/message/send", name="message_send")
  541.      */
  542.     public function message_send(Request $request): Response
  543.     {
  544.         $em $this->getDoctrine()->getManager();
  545.         $user $this->getUser();
  546.         $userId $user->getId();
  547.         $name='';
  548.         if($userId){
  549.             $sql "select * from user where id=?";
  550.             $ap $em->getConnection()->prepare($sql);
  551.             $ap->execute([$userId]);
  552.             $userData $ap->fetchAssociative();
  553.             if ($userData) {
  554.                 $name$userData['first_name'] . ' ' $userData['last_name'];
  555.             } 
  556.         }
  557.         $convId $request->get('conv_id');
  558.         $toUserId $request->get('to_user_id');
  559.         $toUserId = ($toUserId 0) ? $toUserId 0;
  560.         $message $request->get('message');
  561.         $type $request->get('type');
  562.         $data $request->get('data');
  563.         $data =  isset($data) && $data json_encode($data) : '';
  564.         $time time();
  565.         $sql "select * from conversation where id = ? and FIND_IN_SET(?,user_ids)";
  566.         $ap $em->getConnection()->prepare($sql);
  567.         $ap->execute([$convId,$userId]);
  568.         $conversation $ap->fetchAssociative();
  569.         if (!$conversation) {
  570.             return new JsonResponse(['status' => 0'message' => 'Conversation Not Found']);
  571.         }
  572.         if ($conversation) {
  573.             $sql "UPDATE `conversation` SET `deleted_by` = NULL WHERE `id`=?";
  574.             $ap $em->getConnection()->prepare($sql);
  575.             $ap->execute([$convId]);
  576.         }
  577.         if ($conversation['type'] == 1) {
  578.             $toUserId 0;
  579.         }
  580.         try {
  581.             $messageData = [
  582.                 'conversation_id' => $convId,
  583.                 'from_user_id' => $userId,
  584.                 'name'=>$name,
  585.                 'read_user_ids' => $userId,
  586.                 'to_user_id' => @$toUserId,
  587.                 'message' => $message,
  588.                 'image' => ($user->getProfileImg() != '') ? $user->getProfileImg() : ($user->getMedia()?@$user->getMedia()->getUrl(): '/images/Clinic/solid_gray.png'),
  589.                 'type' => $type,
  590.                 'data' => $data,
  591.                 'created_at' => $time
  592.             ];
  593.             $sql "INSERT INTO chat_messages (conversation_id, from_user_id,  read_user_ids, to_user_id, message, type, data, created_at, receiver_ids)
  594.             VALUES (?,?,?,?,?,?,?,?,?)";
  595.             $messageInsert $em->getConnection()->prepare($sql);
  596.             $messageInsert->execute([$convId$userId$userId, @$toUserId$message$type$data$time$userId]);
  597.             $lastId $em->getConnection()->lastInsertId();
  598.             $sql "UPDATE `conversation` SET `last_chat_id` = ?,`updated_at`=? WHERE `id`=?";
  599.             $appointment $em->getConnection()->prepare($sql);
  600.             $appointment->execute([$lastId$time$convId]);
  601.             $messageData['chat_id'] = $lastId;
  602.             $message_opponant $this->setData($messageData$toUserId);
  603.             $messageData['receive_status'] = '';
  604.             $message  $this->setData($messageData$userId);
  605.             return new JsonResponse(['status' => 1'data' => $message'chat_opponant' => $message_opponant'conv_user_ids' => $conversation['user_ids']]);
  606.         } catch (\Exception $e) {
  607.             return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  608.         }
  609.     }
  610.     /**
  611.      * @Route("/admin/message/upload_file", name="message_upload_file")
  612.      */
  613.     public function message_upload_file(Request $request)
  614.     {
  615.         // dd($request->files->get('file'));
  616.         $fileExtension $request->files->get('file')->getClientOriginalExtension();
  617.         $allowedExtensions = ['jpeg''png''pdf''jpg''doc''docx''xls''xlsx''zip''wav''mp4''webp''mp3''mpeg','csv','webm','txt','ppt','pptx','mkv','avi'];
  618.         if (!in_array($fileExtension$allowedExtensions)) {
  619.             return new JsonResponse(['status' => '0''message' => 'File not valid']);
  620.         }
  621.         try {
  622.             if ($request->files->has('file')) {
  623.                 $file $request->files->get('file');
  624.                 $size $file->getSize();
  625.                 if ($size 50 1024 1024) {
  626.                     return $this->json(['status' => 0'message' => 'File size is not more than 50 MB'], Response::HTTP_BAD_REQUEST);
  627.                 }
  628.                 $fileMimeType $file->getClientMimeType();
  629.                 $originalName $file->getClientOriginalName();
  630.                 $extension $file->getClientOriginalExtension();
  631.                 $uniqueFilename md5(uniqid()) . time() . '.' $extension;
  632.                 $filePath 'chat/' date('Y') . '/' date('m') . '/';
  633.                 //   dd($s);
  634.                 $entityManager $this->getDoctrine()->getManager();
  635.                 $media = new Media();
  636.                 $media->setFile($file);
  637.                 $media->setNameFile(Media::getPrefixName($media->getFile()->getClientOriginalName()));
  638.                 $media->setS3key($filePath $uniqueFilename);
  639.                 $this->s3Manager->upload($media);
  640.                 // $entityManager->persist($media);
  641.                 $entityManager->flush();
  642.                 if ($media->getUrl() != '') {
  643.                     $return = ['status' => 1'data' => ['name' => $originalName'media_url' => $media->getUrl(), 'file_name' => $uniqueFilename'extension' => $extension'size' => $size'type' => $fileMimeType]];
  644.                 } else {
  645.                     if (!is_dir($this->getParameter('kernel.project_dir') . '/public/uploads/chat')) {
  646.                         mkdir($this->getParameter('kernel.project_dir') . '/public/uploads/chat');
  647.                     }
  648.                     if (!is_dir($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' date('Y'))) {
  649.                         mkdir($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' date('Y'));
  650.                         mkdir($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' date('Y') . '/' date('m'));
  651.                     }
  652.                     if (!is_dir($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' date('Y') . '/' date('m'))) {
  653.                         mkdir($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' date('Y') . '/' date('m'));
  654.                     }
  655.                     $s =  $file->move($filePath$uniqueFilename);
  656.                     $appUrl $_ENV['APP_URl'];
  657.                     $return = ['status' => 1'data' => ['name' => $originalName'media_url' => $appUrl $filePath $uniqueFilename'file_name' => $uniqueFilename'extension' => $extension'size' => $size'type' => $fileMimeType]];
  658.                 }
  659.                 return new JsonResponse($return);
  660.             } else {
  661.                 return new JsonResponse(['status' => '0''message' => 'File not found']);
  662.             }
  663.         } catch (\Exception $e) {
  664.             return new JsonResponse(['status' => '0''message' => $e->getMessage()]);
  665.         }
  666.     }
  667.     /**
  668.      * @Route("/admin/message/message_addchats", name="message_addchats")
  669.      */
  670.     public function message_addchats(Request $request): Response
  671.     {
  672.         $em $this->getDoctrine()->getManager();
  673.         $user $this->getUser();
  674.         $userId $user->getId();
  675.         $data = [];
  676.         if ($user->getRole() == 'ROLE_CLINIC_ADMIN' || $user->getRole() == 'ROLE_SUPER_CLINIC_ADMIN' || $user->getRole() == 'ROLE_PRACTITIONER') {
  677.             $clinic $user->getClinic();
  678.             if (!$clinic) {
  679.                 $clinic $this->getDoctrine()->getRepository(Clinic::class)
  680.                     ->findOneBy(['organisation_id' => $user->getOrganisation()->getId()]);
  681.             }
  682.             if ($clinic) {
  683.                 $clinicId $clinic->getId();
  684.             $organizationId $clinic->getOrganisation()->getId();
  685.             $roles = ['ROLE_CLINIC_ADMIN''ROLE_PRACTITIONER''ROLE_SUPER_CLINIC_ADMIN'];
  686.             $rolesPlaceholder implode(','array_fill(0count($roles), '?'));
  687.             $sql "SELECT id,username,concat(first_name,' ',last_name) as name ,profile_img FROM user WHERE  id !=?  and  deleted= ?   AND ((role IN ($rolesPlaceholder) AND clinic_id = ?) OR organisation_id = ?)";
  688.             $ap $em->getConnection()->prepare($sql);
  689.             $params array_merge([$userId0], $roles);
  690.             $params[] = $clinicId;
  691.             $params[] = $organizationId;
  692.             $ap->execute($params);
  693.             $data $ap->fetchAll();
  694.             }
  695.         }
  696.         if ($user->getRole() == 'ROLE_CONSENTZ_ADMIN') {
  697.             $sql "select id,username,concat(first_name,' ',last_name) as name ,profile_img  from user where deleted=0 and role in ('ROLE_SUPER_CLINIC_ADMIN','ROLE_CLINIC_ADMIN')";
  698.             $ap $em->getConnection()->prepare($sql);
  699.             $ap->execute();
  700.             $data =   $ap->fetchAll();
  701.         }
  702.         return $this->render('message/chat_create.html.twig', [
  703.             'userList' => $data,
  704.         ]);
  705.     }
  706.     /**
  707.      * @Route("/admin/message/message_groupmodal", name="message_groupmodal")
  708.      */
  709.     public function message_groupmodal(Request $request): Response
  710.     {
  711.         $em $this->getDoctrine()->getManager();
  712.         $user $this->getUser();
  713.         $userId $user->getId();
  714.         $data = [];
  715.         $userIds = [];
  716.         $sql "select id,type,title,user_ids from conversation where FIND_IN_SET(?,user_ids)";
  717.         $ap $em->getConnection()->prepare($sql);
  718.         $ap->execute([$userId]);
  719.         $conversationUsers $ap->fetchAll();
  720.         $groups = [];
  721.         foreach ($conversationUsers as $conv) {
  722.             foreach (explode(','$conv['user_ids']) as $uid) {
  723.                 if ($uid && $uid != $userId && !in_array($uid$userIds)) {
  724.                     $userIds[] = $uid;
  725.                 }
  726.             }
  727.             if ($conv['type'] == 1) {
  728.                 $groups[] = ['chat_id' => $conv['id'], 'chat_title' => $conv['title']];
  729.             }
  730.         }
  731.         $data['userList'] = [];
  732.         if ($userIds) {
  733.             $placeholders implode(','array_fill(0count($userIds), '?'));
  734.             $sql "select id,username,concat(first_name,' ',last_name) as name ,profile_img  from user where deleted=0 and id in($placeholders)";
  735.             $ap $em->getConnection()->prepare($sql);
  736.             $ap->execute($userIds);
  737.             $data['userList'] =   $ap->fetchAll();
  738.         }
  739.         $data['userClinicAdmins'] = [];
  740.         if ($user->getRole() == 'ROLE_CONSENTZ_ADMIN') {
  741.             $sql "select id,username,concat(first_name,' ',last_name) as name ,profile_img  from user where deleted=0 and role='ROLE_SUPER_CLINIC_ADMIN'";
  742.             $ap $em->getConnection()->prepare($sql);
  743.             $ap->execute($userIds);
  744.             $data['userClinicAdmins'] =   $ap->fetchAll();
  745.         }
  746.         // print_r($data);exit;
  747.         return $this->render('message/group_create.html.twig', [
  748.             'userList' => $data['userList'],
  749.             'groups' => $groups,
  750.             'userClinicAdmins' => $data['userClinicAdmins'],
  751.             'user' => $user
  752.         ]);
  753.     }
  754.     /**
  755.      * @Route("/admin/message/message_groupcreate", name="message_groupcreate")
  756.      */
  757.     public function message_groupcreate(Request $request): Response
  758.     {
  759.         $em $this->getDoctrine()->getManager();
  760.         $user $this->getUser();
  761.         $userId $user->getId();
  762.         $title trim($request->get('title'));
  763.         $userIds $request->get('user_ids');
  764.         $superUserIds $request->get('super_user_ids');
  765.         $croppedImg $request->get('croppedImage');
  766.         $groups $request->get('groups');
  767.         $userIds = !empty($userIds) ? $userIds : [];
  768.         $superUserIds = !empty($superUserIds) ? $superUserIds : [];
  769.         if (!empty($groups)) {
  770.             $placeholders implode(','$groups);
  771.             $sql "SELECT user_ids FROM conversation WHERE id IN ($placeholders)";
  772.             $ap $em->getConnection()->prepare($sql);
  773.             $ap->execute();
  774.             $conversationUsers $ap->fetchAll();
  775.             foreach ($conversationUsers as $conv) {
  776.                 foreach (explode(','$conv['user_ids']) as $uid) {
  777.                     if ($uid && $uid != $userId && !in_array($uid$userIds)) {
  778.                         $userIds[] = $uid;
  779.                     }
  780.                 }
  781.             }
  782.         }
  783.         if (!empty($superUserIds)) {
  784.             foreach ($superUserIds as $superUserId) {
  785.                 if ($superUserId && $superUserId != $userId && !in_array($superUserId$userIds)) {
  786.                     $userIds[] = $superUserId;
  787.                 }
  788.             }
  789.         }
  790.         try {
  791.             if (!$title) {
  792.                 return new JsonResponse(['status' => 0'message' => 'Title is required']);
  793.             }
  794.             if (empty($userIds) || count($userIds) < 1) {
  795.                 return new JsonResponse(['status' => 0'message' => 'Please select multiple users']);
  796.             }
  797.             if (isset($croppedImg) && $croppedImg && $croppedImg != 'data:,') {
  798.                 $imgData base64_decode(preg_replace('#^data:image/\w+;base64,#i'''$croppedImg));
  799.                 $parts explode(';'$croppedImg);
  800.                 $mimePart explode(':'$parts[0]);
  801.                 $imageType $mimePart[1];
  802.                 $extension explode('/'$imageType)[1];
  803.                 $uniqueFilename md5(uniqid()) . time() . '.' $extension;
  804.                 $directory $this->getParameter('kernel.project_dir') . '/public/uploads/chat/';
  805.                 if (!is_dir($directory)) {
  806.                     mkdir($directory0777true);
  807.                 }
  808.                 $fileSaved file_put_contents($directory $uniqueFilename$imgData);
  809.                 $uploadPath $directory $uniqueFilename;
  810.                 $targetFile $this->changeFilePermission($uploadPath);
  811.                 $file = new UploadedFile($targetFile$uniqueFilename'image/png');
  812.                 $entityManager $this->getDoctrine()->getManager();
  813.                 $media = new Media();
  814.                 $media->setFile($file);
  815.                 $media->setNameFile(Media::getPrefixName($media->getFile()->getClientOriginalName()));
  816.                 $media->setS3key('groups/' $uniqueFilename);
  817.                 $this->s3Manager->upload($media);
  818.                 $fileUpload $media->getUrl();
  819.                 $entityManager->flush();
  820.                 if ($fileUpload == null) {
  821.                     $fileUpload $_ENV['APP_URl'] . 'uploads/chat/' $uniqueFilename;
  822.                 } else {
  823.                     if (isset($uniqueFilename) && $uniqueFilename) {
  824.                         if (file_exists($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' $uniqueFilename)) {
  825.                             unlink($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' $uniqueFilename);
  826.                         }
  827.                     }
  828.                 }
  829.             } else {
  830.                 $fileUpload  '';
  831.             }
  832.             $userIds implode(','$userIds) . ',' $userId;
  833.             $time time();
  834.             $status 1;
  835.             $sql "INSERT INTO conversation (type, from_user_id,  title, g_image, user_ids, status, created_at, updated_at)VALUES (?,?,?,?,?,?,?,?)";
  836.             $messageInsert $em->getConnection()->prepare($sql);
  837.             $messageInsert->execute([1$userId$title$fileUpload$userIds$status$time$time]);
  838.             return new JsonResponse(['status' => 1'message' => 'Group created']);
  839.         } catch (\Exception $e) {
  840.             return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  841.         }
  842.     }
  843.     /**
  844.      * @Route("/admin/message/conversation_details", name="conversation_details")
  845.      */
  846.     public function conversation_details(Request $request): Response
  847.     {
  848.         $em $this->getDoctrine()->getManager();
  849.         $user $this->getUser();
  850.         $userId $user->getId();
  851.         $convId $request->get('conv_id');
  852.         $sql "select * from conversation where id = ?";
  853.         $ap $em->getConnection()->prepare($sql);
  854.         $ap->execute([$convId]);
  855.         $conversation $ap->fetchAssociative();
  856.         if ($conversation['type'] == 0) {
  857.             if ($conversation['from_user_id'] == $userId) {
  858.                 $opponantId $conversation['to_user_id'];
  859.             } else {
  860.                 $opponantId $conversation['from_user_id'];
  861.             }
  862.             $sql "select user.*,media.url from user left join media on media.id=user.media_id where user.id = ?";
  863.             $ap $em->getConnection()->prepare($sql);
  864.             $ap->execute([$opponantId]);
  865.             $userData $ap->fetchAssociative();
  866.             if (!$userData) {
  867.                 return new JsonResponse(['status' => 0'message' => 'Opponant not found']);
  868.             }
  869.             // dd($userData);
  870.             $conversation['user_id'] = $opponantId;
  871.             $conversation['title'] = $userData['first_name'] . ' ' $userData['last_name'];
  872.             $conversation['is_online'] = $userData['is_online'];
  873.             $conversation['image'] = ($userData['profile_img'] != '') ? $userData['profile_img'] :( $userData['url'] != ''?$userData['url']:'/images/Clinic/solid_gray.png');
  874.         } else {
  875.             $conversation['title'] = $conversation['title'];
  876.             $conversation['user_id'] = 0;
  877.             $conversation['title'] = $conversation['title'];
  878.             $conversation['is_online'] = 0;
  879.             $conversation['image'] = ($conversation['g_image'] != '') ? $conversation['g_image'] : '/images/Clinic/solid_gray.png';
  880.         }
  881.         return new JsonResponse(['status' => 1'data' => $conversation]);
  882.     }
  883.     /**
  884.      * @Route("/admin/message/conversation_delete", name="conversation_delete")
  885.      */
  886.     public function conversation_delete(Request $request): Response
  887.     {
  888.         $user $this->getUser();
  889.         $userId $user->getId();
  890.         $convId $request->get('conv_id');
  891.         
  892.         $em $this->getDoctrine()->getManager();
  893.         
  894.         // Fetch all chat messages for the given conversation ID
  895.         $sql "SELECT id, deleted_by FROM conversation WHERE id = ?";
  896.         $ap $em->getConnection()->prepare($sql);
  897.         $ap->execute([$convId]);
  898.         $conversions $ap->fetchAll(); // Fetch all records in the conversation
  899.         foreach ($conversions as $conversion) {
  900.             $deletedBy $conversion['deleted_by'];
  901.             $conversionId $conversion['id'];
  902.         
  903.             // Check if `deleted_by` is empty or does not contain the `userId`
  904.             if (empty($deletedBy)) {
  905.                 // If `deleted_by` is empty, set it to `userId`
  906.                 $updatedDeletedBy $userId;
  907.             } elseif (strpos($deletedBy, (string)$userId) === false) {
  908.                 // If `userId` is not in `deleted_by`, append it
  909.                 $updatedDeletedBy $deletedBy ',' $userId;
  910.             } else {
  911.                 // If `userId` is already in `deleted_by`, no need to update
  912.                 $updatedDeletedBy $deletedBy;
  913.             }
  914.         
  915.             // Only update if the value was modified
  916.             if ($updatedDeletedBy !== $deletedBy) {
  917.                 $updateSql "UPDATE conversation SET deleted_by = ? WHERE id = ?";
  918.                 $updateStmt $em->getConnection()->prepare($updateSql);
  919.                 $updateStmt->execute([$updatedDeletedBy$conversionId]);
  920.             }
  921.         }
  922.         // Fetch all chat messages for the given conversation ID
  923.         $sql "SELECT id, deleted_by FROM chat_messages WHERE conversation_id = ?";
  924.         $ap $em->getConnection()->prepare($sql);
  925.         $ap->execute([$convId]);
  926.         $messages $ap->fetchAll(); // Fetch all records in the conversation
  927.         
  928.         // Iterate through each message and update the `deleted_by` column
  929.         foreach ($messages as $message) {
  930.             $deletedBy $message['deleted_by'];
  931.             $messageId $message['id'];
  932.         
  933.             // Check if `deleted_by` is empty or does not contain the `userId`
  934.             if (empty($deletedBy)) {
  935.                 // If `deleted_by` is empty, set it to `userId`
  936.                 $updatedDeletedBy $userId;
  937.             } elseif (strpos($deletedBy, (string)$userId) === false) {
  938.                 // If `userId` is not in `deleted_by`, append it
  939.                 $updatedDeletedBy $deletedBy ',' $userId;
  940.             } else {
  941.                 // If `userId` is already in `deleted_by`, no need to update
  942.                 $updatedDeletedBy $deletedBy;
  943.             }
  944.         
  945.             // Only update if the value was modified
  946.             if ($updatedDeletedBy !== $deletedBy) {
  947.                 $updateSql "UPDATE chat_messages SET deleted_by = ? WHERE id = ?";
  948.                 $updateStmt $em->getConnection()->prepare($updateSql);
  949.                 $updateStmt->execute([$updatedDeletedBy$messageId]);
  950.             }
  951.         }
  952.         
  953.         // Return response after updating all messages
  954.         return new JsonResponse(['status' => 1'message' => 'Chat deleted']);
  955.         
  956.     }
  957.     /**
  958.      * @Route("/admin/message/message_groupdetails", name="message_groupdetails")
  959.      */
  960.     public function message_groupdetails(Request $request): Response
  961.     {
  962.         $em $this->getDoctrine()->getManager();
  963.         $user $this->getUser();
  964.         $userId $user->getId();
  965.         $convId $request->get('conv_id');
  966.         $sql "select * from conversation where id = ?";
  967.         $ap $em->getConnection()->prepare($sql);
  968.         $ap->execute([$convId]);
  969.         $convList $ap->fetchAssociative();
  970.         if ($convList['type'] == 1) {
  971.             if ($convList['from_user_id']  == $userId && $convList['clinic_id'] > 0) {
  972.                 $this->addClinicMembersInGroup($convList);
  973.             }
  974.             $convUsers explode(','$convList['user_ids']);
  975.             $convUserData = [];
  976.             $placeholders implode(','array_fill(0count($convUsers), '?'));
  977.             $ap $em->getConnection()->prepare("SELECT user.id,user.first_name,user.last_name,user.username,user.profile_img,user.is_online,media.url FROM user left join media on media.id=user.media_id WHERE user.deleted=0 and user.id IN ($placeholders)");
  978.             $ap->execute($convUsers);
  979.             $users $ap->fetchAll();
  980.             foreach ($users as $key => $u) {
  981.                 $users[$key]['name'] = $u['first_name'] . ' ' $u['last_name'];
  982.                 $users[$key]['image'] = ($u['profile_img'] != '') ? $u['profile_img'] : ( $u['url'] != ''?$u['url']:'/images/Clinic/solid_gray.png');
  983.                 $users[$key]['role'] = ($convList['from_user_id'] == $u['id']) ? 0;
  984.                 $users[$key]['slug'] = $u['username'];
  985.                 $users[$key]['online'] = ($u['is_online'] == 1) ? true false;
  986.             }
  987.             return $this->render('message/group_chat_details.html.twig', [
  988.                 'convList' => $convList,
  989.                 'convUserData' => $users,
  990.                 'userId' => $userId,
  991.                 'user' => $user
  992.             ]);
  993.         } else {
  994.             $oppoNantId = ($convList['from_user_id']  == $userId) ? $convList['to_user_id'] : $convList['from_user_id'];
  995.             $ap $em->getConnection()->prepare("SELECT concat(u.first_name,' ',u.last_name) as fullname,c.name,u.role,u.profile_img,u.id,u.email,concat(u.country_code,'',u.phone) as phone,c.description,u.is_online as online,media.url
  996.             FROM user AS u
  997.             left join media on media.id=u.media_id
  998.             LEFT JOIN clinics AS c
  999.                 ON (u.organisation_id IS NOT NULL AND c.organisation_id = u.organisation_id)
  1000.                 OR (u.organisation_id IS NULL AND c.id = u.clinic_id)
  1001.             WHERE u.id = ?");
  1002.             $ap->execute([$oppoNantId]);
  1003.             $u $ap->fetchAssociative();
  1004.             $u['profile_img'] = ($u['profile_img'] != '') ? $u['profile_img'] : ( $u['url'] != ''?$u['url']:'/images/Clinic/solid_gray.png');
  1005.             $ap $em->getConnection()->prepare("SELECT id,title,g_image,clinic_id FROM `conversation` where FIND_IN_SET(?,user_ids) and FIND_IN_SET(?,user_ids) and type=1 order by updated_at desc;
  1006.             ");
  1007.             $ap->execute([$oppoNantId$userId]);
  1008.             $groups $ap->fetchAll();
  1009.             return $this->render('message/chat_details.html.twig', [
  1010.                 'convList' => $convList,
  1011.                 'user' => $u,
  1012.                 'groups' => $groups
  1013.             ]);
  1014.         }
  1015.     }
  1016.     /**
  1017.      * @Route("/admin/message/groupupdatemodal", name="groupupdatemodal")
  1018.      */
  1019.     public function groupupdatemodal(Request $request): Response
  1020.     {
  1021.         $em $this->getDoctrine()->getManager();
  1022.         $user $this->getUser();
  1023.         $userId $user->getId();
  1024.         $convId $request->get('conv_id');
  1025.         $sql "select * from conversation where id = ?";
  1026.         $ap $em->getConnection()->prepare($sql);
  1027.         $ap->execute([$convId]);
  1028.         $convList $ap->fetchAssociative();
  1029.         $convUsers explode(','$convList['user_ids']);
  1030.         $userIds = [];
  1031.         $sql "select user_ids from conversation where FIND_IN_SET(?,user_ids)";
  1032.         $ap $em->getConnection()->prepare($sql);
  1033.         $ap->execute([$userId]);
  1034.         $convLists $ap->fetchAll();
  1035.         foreach ($convLists as $conv) {
  1036.             foreach (explode(','$conv['user_ids']) as $uid) {
  1037.                 if ($uid && $uid != $userId && !in_array($uid$userIds)) {
  1038.                     $userIds[] = $uid;
  1039.                 }
  1040.             }
  1041.         }
  1042.         $userList = [];
  1043.         if ($userIds) {
  1044.             $placeholders implode(','array_fill(0count($userIds), '?'));
  1045.             $sql "select id,email,concat(first_name,' ',last_name) as name ,profile_img  from user where deleted=0 and id in($placeholders)";
  1046.             $ap $em->getConnection()->prepare($sql);
  1047.             $ap->execute($userIds);
  1048.             $userList $ap->fetchAll();
  1049.         }
  1050.         return $this->render('message/group_update.html.twig', [
  1051.             'convList' => $convList,
  1052.             'convLists' => $convLists,
  1053.             'userId' => $userId,
  1054.             'convUsers' => $convUsers,
  1055.             'userList' => $userList
  1056.         ]);
  1057.     }
  1058.     /**
  1059.      * @Route("/admin/message/groupupdateusers", name="groupupdateusers")
  1060.      */
  1061.     public function groupupdateusers(Request $request): Response
  1062.     {
  1063.         $em $this->getDoctrine()->getManager();
  1064.         $convId $request->get('conv_id');
  1065.         $userIds $request->get('user_ids');
  1066.         $sql "select * from conversation where id = ?";
  1067.         $ap $em->getConnection()->prepare($sql);
  1068.         $ap->execute([$convId]);
  1069.         $convList $ap->fetchAssociative();
  1070.         if (empty($convList)) {
  1071.             return new JsonResponse(['status' => 0'message' => 'Group not found']);
  1072.         }
  1073.         $updateUserIds explode(','$convList['user_ids']);
  1074.         if (empty($userIds)) {
  1075.             return new JsonResponse(['status' => 0'message' => 'Please select users']);
  1076.         }
  1077.         $updateUserIds array_merge($userIdsexplode(','$convList['user_ids']));
  1078.         $time time();
  1079.         $userIDs implode(','$updateUserIds);
  1080.         try {
  1081.             $sql "UPDATE `conversation` SET `user_ids` = ?,updated_at=? WHERE `id`=?";
  1082.             $appointment $em->getConnection()->prepare($sql);
  1083.             $appointment->execute([$userIDs$time$convId]);
  1084.         } catch (\Exception $e) {
  1085.             return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  1086.         }
  1087.         return new JsonResponse(['status' => 1'message' => 'Group updated']);
  1088.     }
  1089.     /**
  1090.      * @Route("/admin/message/deletegroupuser", name="deletegroupuser")
  1091.      */
  1092.     public function deletegroupuser(Request $request): Response
  1093.     {
  1094.         $em $this->getDoctrine()->getManager();
  1095.         $user $this->getUser();
  1096.         $userId $user->getId();
  1097.         $user_id $request->get('user_id');
  1098.         $convId $request->get('groupconvId');
  1099.         $sql "select * from conversation where id = ?";
  1100.         $ap $em->getConnection()->prepare($sql);
  1101.         $ap->execute([$convId]);
  1102.         $convList $ap->fetchAssociative();
  1103.         if (empty($convList)) {
  1104.             return new JsonResponse(['status' => 0'message' => 'Group not found']);
  1105.         }
  1106.         $updateUserIds explode(','$convList['user_ids']);
  1107.         if (($key array_search($user_id$updateUserIds)) !== false) {
  1108.             unset($updateUserIds[$key]);
  1109.         }
  1110.         $time time();
  1111.         $userIDs implode(','$updateUserIds);
  1112.         try {
  1113.             $sql "UPDATE `conversation` SET `user_ids` = ?,updated_at=? WHERE `id`=?";
  1114.             $appointment $em->getConnection()->prepare($sql);
  1115.             $appointment->execute([$userIDs$time$convId]);
  1116.         } catch (\Exception $e) {
  1117.             return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  1118.         }
  1119.         return new JsonResponse(['status' => 1'message' => 'Group user removed']);
  1120.     }
  1121.     /**
  1122.      * @Route("/admin/message/gimage_update", name="gimage_update")
  1123.      */
  1124.     public function gimage_update(Request $request): Response
  1125.     {
  1126.         $em $this->getDoctrine()->getManager();
  1127.         $user $this->getUser();
  1128.         $userId $user->getId();
  1129.         $convId $request->get('conv_id');
  1130.         $sql "select * from conversation where id = ?";
  1131.         $ap $em->getConnection()->prepare($sql);
  1132.         $ap->execute([$convId]);
  1133.         $convList $ap->fetchAssociative();
  1134.         if (empty($convList)) {
  1135.             return 'Group not found';
  1136.         }
  1137.         return $this->render('message/gimage_update.html.twig', [
  1138.             'convList' => $convList,
  1139.             'user' => $userId,
  1140.         ]);
  1141.     }
  1142.     /**
  1143.      * @Route("/admin/message/createadvertise", name="createadvertise")
  1144.      */
  1145.     public function createadvertise(Request $request): Response
  1146.     {
  1147.         $user $this->getUser();
  1148.         $userId $user->getId();
  1149.         if ($user->getRole() != 'ROLE_CONSENTZ_ADMIN') {
  1150.             return 'You do not have permission to perform this action.';
  1151.         }
  1152.         $convId $request->get('conv_id');
  1153.         $em $this->getDoctrine()->getManager();
  1154.         $sql "select a.*,concat(u.first_name,' ',u.last_name) as name,u.profile_img,u.username from advertisements as a left join user as u on u.id=a.user_id where a.chat_id = ? order by a.id desc";
  1155.         $ap $em->getConnection()->prepare($sql);
  1156.         $ap->execute([$convId]);
  1157.         $advertisements $ap->fetchAll();
  1158.         foreach ($advertisements as $key => $advertisement) {
  1159.             $advertisements[$key]['date'] = date('d M, Y h:i A'$advertisement['created_at']);
  1160.         }
  1161.         return $this->render('message/create_advertise.html.twig', [
  1162.             'convId' => $convId,
  1163.             'advertisements' => $advertisements
  1164.         ]);
  1165.     }
  1166.     /**
  1167.      * @Route("/admin/message/createadvertisepost", name="createadvertisepost")
  1168.      */
  1169.     public function createadvertisepost(Request $request): Response
  1170.     {
  1171.         $convId $request->get('conv_id');
  1172.         $em $this->getDoctrine()->getManager();
  1173.         $sql "select * from conversation where id = ?";
  1174.         $ap $em->getConnection()->prepare($sql);
  1175.         $ap->execute([$convId]);
  1176.         $convList $ap->fetchAssociative();
  1177.         if (!$convList) {
  1178.             return new JsonResponse(['status' => '0''message' => 'Conversation not found']);
  1179.         }
  1180.         $content $request->get('content');
  1181.         $title $request->get('title');
  1182.         $user $this->getUser();
  1183.         $userId $user->getId();
  1184.         try {
  1185.             $type 0;
  1186.             $mediaUrl '';
  1187.             if ($request->files->get('media')) {
  1188.                 $fileExtension $request->files->get('media')->getClientOriginalExtension();
  1189.                 $allowedExtensions = ['jpg''jpeg''png''gif''webp''mp4''mov''avi''wmv'];
  1190.                 if (!in_array($fileExtension$allowedExtensions)) {
  1191.                     return new JsonResponse(['status' => '0''message' => 'File not valid']);
  1192.                 }
  1193.                 $file $request->files->get('media');
  1194.                 $size $file->getSize();
  1195.                 if ($size 150 1024 1024) {
  1196.                     return $this->json(['status' => 0'message' => 'File size is not more than 150 MB'], Response::HTTP_BAD_REQUEST);
  1197.                 }
  1198.                 $fileMimeType $file->getClientMimeType();
  1199.                 if (strpos($fileMimeType'image/') === 0) {
  1200.                     $type 2;
  1201.                 } else if (strpos($fileMimeType'video/') === 0) {
  1202.                     $type 1;
  1203.                 }
  1204.                 $extension $file->getClientOriginalExtension();
  1205.                 $uniqueFilename md5(uniqid()) . time() . '.' $extension;
  1206.                 $filePath 'uploads/advertise/';
  1207.                 if (!is_dir($this->getParameter('kernel.project_dir') . '/public/uploads/advertise/')) {
  1208.                     mkdir($this->getParameter('kernel.project_dir') . '/public/uploads/advertise/');
  1209.                 }
  1210.                 $entityManager $this->getDoctrine()->getManager();
  1211.                 $media = new Media();
  1212.                 $media->setFile($file);
  1213.                 $media->setNameFile(Media::getPrefixName($media->getFile()->getClientOriginalName()));
  1214.                 $media->setS3key($filePath $uniqueFilename);
  1215.                 $this->s3Manager->upload($media);
  1216.                 if ($media->getUrl() != '') {
  1217.                     $mediaUrl $media->getUrl();
  1218.                     $entityManager->flush();
  1219.                 } else {
  1220.                     $s =  $file->move($filePath$uniqueFilename);
  1221.                     $baseUrl $_ENV['APP_URl'];
  1222.                     $mediaUrl $baseUrl $filePath $uniqueFilename;
  1223.                 }
  1224.             }
  1225.             $time time();
  1226.             $sql "INSERT INTO advertisements (chat_id, media, title, user_id, type, description,receiver_user_ids,read_user_ids, created_at)VALUES (?,?,?,?,?,?,?,?,?)";
  1227.             $advertise $em->getConnection()->prepare($sql);
  1228.             $advertise->execute([$convId$mediaUrl$title$userId$type$content$convList['user_ids'], $userId$time]);
  1229.             $lastId $em->getConnection()->lastInsertId();
  1230.             $return = ['status' => 1'data' => ['media' =>   $mediaUrl'type' => $type'description' => $content'title' => $title'popup_id' => $lastId]];
  1231.             return new JsonResponse($return);
  1232.         } catch (\Exception $e) {
  1233.             return new JsonResponse(['status' => '0''message' => $e->getMessage()]);
  1234.         }
  1235.     }
  1236.     /**
  1237.      * @Route("/admin/message/updategroup", name="updategroup")
  1238.      */
  1239.     public function updategroup(Request $request): Response
  1240.     {
  1241.         $em $this->getDoctrine()->getManager();
  1242.         $user $this->getUser();
  1243.         $userId $user->getId();
  1244.         $title trim($request->get('title'));
  1245.         $convId $request->get('id');
  1246.         $croppedImg $request->get('croppedImage');
  1247.         $sql "select * from conversation where id = ?";
  1248.         $ap $em->getConnection()->prepare($sql);
  1249.         $ap->execute([$convId]);
  1250.         $convList $ap->fetchAssociative();
  1251.         if (empty($convList)) {
  1252.             return new JsonResponse(['status' => 0'message' => 'Group not found']);
  1253.         }
  1254.         try {
  1255.             if (isset($croppedImg) && $croppedImg &&  $croppedImg != 'data:,') {
  1256.                 $imgData base64_decode(preg_replace('#^data:image/\w+;base64,#i'''$croppedImg));
  1257.                 $parts explode(';'$croppedImg);
  1258.                 $mimePart explode(':'$parts[0]);
  1259.                 $imageType $mimePart[1];
  1260.                 $extension explode('/'$imageType)[1];
  1261.                 $uniqueFilename md5(uniqid()) . time() . '.' $extension;
  1262.                 $directory $this->getParameter('kernel.project_dir') . '/public/uploads/chat/';
  1263.                 if (!is_dir($directory)) {
  1264.                     mkdir($directory);
  1265.                 }
  1266.                 $fileSaved file_put_contents($directory $uniqueFilename$imgData);
  1267.                 $uploadPath $directory $uniqueFilename;
  1268.                 $targetFile $this->changeFilePermission($uploadPath);
  1269.                 $file = new UploadedFile($targetFile$uniqueFilename'image/png');
  1270.                 $entityManager $this->getDoctrine()->getManager();
  1271.                 $media = new Media();
  1272.                 $media->setFile($file);
  1273.                 $media->setNameFile(Media::getPrefixName($media->getFile()->getClientOriginalName()));
  1274.                 $media->setS3key('groups/' $uniqueFilename);
  1275.                 $this->s3Manager->upload($media);
  1276.                 $fileUpload $media->getUrl();
  1277.                 $entityManager->flush();
  1278.                 if ($fileUpload == null) {
  1279.                     $fileUpload $_ENV['APP_URl'] . 'uploads/chat/' $uniqueFilename;
  1280.                 } else {
  1281.                     if (isset($uniqueFilename) && $uniqueFilename) {
  1282.                         if (file_exists($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' $uniqueFilename)) {
  1283.                             unlink($this->getParameter('kernel.project_dir') . '/public/uploads/chat/' $uniqueFilename);
  1284.                         }
  1285.                     }
  1286.                 }
  1287.             } else {
  1288.                 $fileUpload  $convList['g_image'];
  1289.             }
  1290.             if (!$title) {
  1291.                 $title $convList['title'];
  1292.             }
  1293.             $sql "UPDATE `conversation` SET `title` = ?,g_image=? WHERE `id`=?";
  1294.             $appointment $em->getConnection()->prepare($sql);
  1295.             $appointment->execute([$title$fileUpload$convId]);
  1296.             return new JsonResponse(['status' => 1'message' => 'Group Updated']);
  1297.         } catch (\Exception $e) {
  1298.             return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  1299.         }
  1300.     }
  1301.     private function changeFilePermission($file)
  1302.     {
  1303.         if (!$this->filesystem->exists($file)) {
  1304.             return false;
  1305.         }
  1306.         try {
  1307.             $this->filesystem->chmod($file0777);
  1308.         } catch (\Exception $e) {
  1309.             $this->logger->error(
  1310.                 'error change mod for file - ' $file,
  1311.                 [
  1312.                     'message' => $e->getMessage(),
  1313.                 ]
  1314.             );
  1315.             return false;
  1316.         }
  1317.         return $file;
  1318.     }
  1319.     /**
  1320.      * @Route("/admin/message/start_call", name="startCall")
  1321.      */
  1322.     public function startCall(Request $request): Response
  1323.     {
  1324.         $em $this->getDoctrine()->getManager();
  1325.         $user $this->getUser();
  1326.         $userId $user->getId();
  1327.         $convId $request->get('conv_id');
  1328.         $type $request->get('type');
  1329.         $toUserId $request->get('to_user_id');
  1330.         $sql "select * from conversation where id = ? and FIND_IN_SET(?,user_ids)";
  1331.         $ap $em->getConnection()->prepare($sql);
  1332.         $ap->execute([$convId,$userId]);
  1333.         $conversation $ap->fetchAssociative();
  1334.         if (!$conversation) {
  1335.             return new JsonResponse(['status' => 0'message' => 'Conversation Not Found']);
  1336.         }
  1337.         
  1338.         $sql "select * from user where last_call_time > ? and (id=? or id=?)";
  1339.         $ap $em->getConnection()->prepare($sql);
  1340.         $ap->execute([time()-20,$toUserId,$userId]);
  1341.         $call $ap->fetchAssociative();
  1342.         if(isset($call) && $call){
  1343.                 return new JsonResponse(['status' => 2'data' => $call,'userId'=>$userId]);
  1344.         }
  1345.         
  1346.   
  1347.         $toUserId = ($toUserId 0) ? $toUserId 0;
  1348.         $message '';
  1349.         $type $request->get('type');
  1350.         $call_id bin2hex(random_bytes(10)) . time();
  1351.         $data = [
  1352.             'call_id' => $call_id,
  1353.             'type' => ($type == 'audio') ? 1,
  1354.             'status' => 'CALL_START'
  1355.         ];
  1356.         $data =  isset($data) && $data json_encode($data) : '';
  1357.         $time time();
  1358.        
  1359.        
  1360.         try {
  1361.             $messageData = [
  1362.                 'conversation_id' => $convId,
  1363.                 'from_user_id' => $userId,
  1364.                 'read_user_ids' => $userId,
  1365.                 'to_user_id' => @$toUserId,
  1366.                 'message' => $message,
  1367.                 'image' => ($user->getProfileImg() != '') ? $user->getProfileImg() : ($user->getMedia()?$user->getMedia()->getUrl(): '/images/Clinic/solid_gray.png'),
  1368.                 'type' => 2,
  1369.                 'data' => $data,
  1370.                 'created_at' => $time
  1371.             ];
  1372.             $t 2;
  1373.             $sql "INSERT INTO chat_messages (conversation_id, from_user_id,  read_user_ids, to_user_id, message, type, data, created_at,call_id)
  1374.             VALUES (?,?,?,?,?,?,?,?,?)";
  1375.             $messageInsert $em->getConnection()->prepare($sql);
  1376.             $messageInsert->execute([$convId$userId$userId, @$toUserId$message$t$data$time$call_id]);
  1377.             $lastId $em->getConnection()->lastInsertId();
  1378.             $sql "UPDATE `conversation` SET `last_chat_id` = ?,`updated_at`=? WHERE `id`=?";
  1379.             $appointment $em->getConnection()->prepare($sql);
  1380.             $appointment->execute([$lastId$time$convId]);
  1381.             $messageData['chat_id'] = $lastId;
  1382.             $message_opponant $this->setData($messageData$toUserId);
  1383.             $messageData['receive_status'] = '';
  1384.             $message  $this->setData($messageData$userId);
  1385.             $callSocket = [
  1386.                 'type' => "CALL_START",
  1387.                 'data' => [
  1388.                     'user_id' => $userId,
  1389.                     'name' => $user->getFullName(),
  1390.                     'call_id' => $call_id,
  1391.                     'user_image' => ($user->getProfileImg() != '') ? $user->getProfileImg() : ($user->getMedia()?$user->getMedia()->getUrl(): '/images/Clinic/solid_gray.png')
  1392.                 ]
  1393.             ];
  1394.             return new JsonResponse(['status' => 1'data' => $message'call_socket' => $callSocket'chat_opponant' => $message_opponant'conv_user_ids' => $conversation['user_ids'], 'url' => $this->generateUrl('roomstart') . '?call_id=' $call_id]);
  1395.         } catch (\Exception $e) {
  1396.             return new JsonResponse(['status' => 0'message' => $e->getMessage()]);
  1397.         }
  1398.     }
  1399.     /**
  1400.      * @Route("/admin/room/start", name="roomstart")
  1401.      */
  1402.     public function roomstart(Request $request): Response
  1403.     {
  1404.         $em $this->getDoctrine()->getManager();
  1405.         $user $this->getUser();
  1406.         $userId $user->getId();
  1407.         $sql "select chat_messages.*,conversation.type as ctype,conversation.user_ids,conversation.title,conversation.g_image from chat_messages left join conversation on conversation.id=chat_messages.conversation_id where chat_messages.call_id = ? and FIND_IN_SET(?,conversation.user_ids)";
  1408.         $ap $em->getConnection()->prepare($sql);
  1409.         $ap->execute([$_GET['call_id'], $userId]);
  1410.         $message $ap->fetchAssociative();
  1411.         if (!$message) {
  1412.             return new RedirectResponse($this->generateUrl('message_index'));
  1413.         }
  1414.         $conversationIds explode(','$message['user_ids']);
  1415.         if (($key array_search($userId$conversationIds)) !== false) {
  1416.             unset($conversationIds[$key]);
  1417.         }
  1418.         if ($message['ctype'] == 1) {
  1419.             $oppo = [
  1420.                 'type' => 1,
  1421.                 'name' => $message['title'],
  1422.                 'image' => ($message['g_image'] != '') ? $message['g_image'] : '/images/Clinic/solid_gray.png',
  1423.                 'conversationIds' => implode(','$conversationIds)
  1424.             ];
  1425.         } else {
  1426.             $opponantId = ($message['from_user_id'] == $userId) ? $message['to_user_id'] : $message['from_user_id'];
  1427.             $sql "select user.*,media.url from user left join media on media.id=user.media_id where user.id = ?";
  1428.             $ap $em->getConnection()->prepare($sql);
  1429.             $ap->execute([$opponantId]);
  1430.             $oppoN $ap->fetchAssociative();
  1431.            
  1432.             $oppo = [
  1433.                 'user_id' => $oppoN['id'],
  1434.                 'type' => 0,
  1435.                 'name' => $oppoN['first_name'] . ' ' $oppoN['last_name'],
  1436.                 'image' => ($oppoN['profile_img'] != '') ? $oppoN['profile_img'] : (($oppoN['url'] != '')?$oppoN['url']:'/images/Clinic/solid_gray.png'),
  1437.                 'conversationIds' => $oppoN['id']
  1438.             ];
  1439.         }
  1440.         $userData = [
  1441.             'id' => $userId,
  1442.             'name' => $user->getFullName(),
  1443.             'image' => ($user->getProfileImg() != '') ? $user->getProfileImg() : ($user->getMedia()?$user->getMedia()->getUrl(): '/images/Clinic/solid_gray.png')
  1444.         ];
  1445.         return $this->render('room/start.html.twig', [
  1446.             'user' => $user,
  1447.             'opponant' => $oppo,
  1448.             'message' => $message,
  1449.             'userData' => $userData,
  1450.             'conversationIds' => implode(','$conversationIds)
  1451.         ]);
  1452.     }
  1453.     /**
  1454.      * @Route("/admin/room/call", name="roomcall")
  1455.      */
  1456.     public function roomcall(Request $request): Response
  1457.     {
  1458.         $em $this->getDoctrine()->getManager();
  1459.         $user $this->getUser();
  1460.         $userId $user->getId();
  1461.         $sql "select chat_messages.*,conversation.type as ctype,conversation.user_ids,conversation.title,conversation.g_image from chat_messages left join conversation on conversation.id=chat_messages.conversation_id where chat_messages.call_id = ? and FIND_IN_SET(?,conversation.user_ids)";
  1462.         $ap $em->getConnection()->prepare($sql);
  1463.         $ap->execute([$_GET['call_id'], $userId]);
  1464.         $message $ap->fetchAssociative();
  1465.         if (!$message) {
  1466.             return new RedirectResponse($this->generateUrl('message_index'));
  1467.         }
  1468.         $conversationIds explode(','$message['user_ids']);
  1469.         if (($key array_search($userId$conversationIds)) !== false) {
  1470.             unset($conversationIds[$key]);
  1471.         }
  1472.         if ($message['ctype'] == 1) {
  1473.             $oppo = [
  1474.                 'type' => 1,
  1475.                 'name' => $message['title'],
  1476.                 'image' => ($message['g_image'] != '')?$message['g_image']: '/images/Clinic/solid_gray.png' ,
  1477.                 'conversationIds' => implode(','$conversationIds),
  1478.                 'user_id' => implode(','$conversationIds)
  1479.             ];
  1480.         } else {
  1481.         $opponantId = ($message['from_user_id'] == $userId) ? $message['to_user_id'] : $message['from_user_id'];
  1482.         $sql "select user.*,media.url from user left join media on media.id=user.media_id where user.id = ?";
  1483.         $ap $em->getConnection()->prepare($sql);
  1484.         $ap->execute([$opponantId]);
  1485.         $oppoN $ap->fetchAssociative();
  1486.             $oppo = [
  1487.                 'user_id' => $oppoN['id'],
  1488.                 'type' => 0,
  1489.                 'name' => $oppoN['first_name'] . ' ' $oppoN['last_name'],
  1490.                 'image' => ($oppoN['profile_img'] != '') ? $oppoN['profile_img'] : (($oppoN['url'] != '')?$oppoN['url']:'/images/Clinic/solid_gray.png'),
  1491.                 'conversationIds' => $oppoN['id']
  1492.             ];
  1493.         }
  1494.        
  1495.         $userInfo = [
  1496.             'id' => $userId,
  1497.             'displayName' => $user->getFullName(),
  1498.             'name' => $user->getFullName(),
  1499.             'image' => ($user->getProfileImg() != '') ? $user->getProfileImg() : ($user->getMedia()?$user->getMedia()->getUrl(): '/images/Clinic/solid_gray.png')
  1500.         ];
  1501.         $event =  $em->getRepository(Meeting::class)->findOneBy(['call_id' => $_GET['call_id']]);
  1502.         if($event){
  1503.             $eventId $event->getId();
  1504.             $clinicUsers $this->getDoctrine()->getRepository(ClinicUser::class)->findBy([
  1505.                 'id' => explode(',',$event->getClinicUsers())
  1506.             ]);
  1507.             $practitionersName '';
  1508.             foreach ($clinicUsers as $key => $clinicUser){
  1509.                 $practitionersName $practitionersName.$clinicUser->getFullName().(count($clinicUsers)- == $key?'':', ');
  1510.             }
  1511.     
  1512.             $rr $this->serializer->normalize($event'json', ['find_event' => true]);
  1513.             $clinic $this->getDoctrine()->getRepository(Clinic::class)->find($event->getClinicId());
  1514.             if (!$clinic) {
  1515.                 return $this->json('Event not found'Response::HTTP_BAD_REQUEST);
  1516.             }
  1517.             $rr['clinicTimezone'] = @array_search($clinic->getTimezone(), Clinic::CLINIC_TIMEZONES) ;
  1518.             $rr['practitionerName'] = $practitionersName;
  1519.             $dateST = new \DateTime();
  1520.             $rr['date'] = $event->getStart()->format('l, jS F');
  1521.             $rr['time'] = $event->getStart()->format('h:i A').'-'.$event->getEnd()->format('h:i A');
  1522.             
  1523.     
  1524.             $rr['practitionerName'] = $practitionersName;
  1525.             $rr['meetingUrl'] = $this->generateUrl('meeting',['meeting'=>$eventId],\Symfony\Component\Routing\Generator\UrlGeneratorInterface::ABSOLUTE_URL);
  1526.             $meetingContent =  $this->renderView('meeting/meeting_call_content.html.twig', [
  1527.                 'data' => $rr
  1528.             ]);
  1529.         }
  1530.         return $this->render('room/call.html.twig', [
  1531.             'user' => $user,
  1532.             'opponant' => $oppo,
  1533.             'message' => $message,
  1534.             'userInfo' => $userInfo,
  1535.             'roomName' => 'Consentz #'.@$_GET['call_id'],
  1536.             'conversationIds' => implode(','$conversationIds),
  1537.             'meeting' => $event?['meetingContent'=>$meetingContent,'meetingUrl'=>$rr['meetingUrl']]:'',
  1538.             'meetingId' => $event?$event->getId():0,
  1539.             
  1540.         ]);
  1541.     }
  1542.     /**
  1543.      * @Route("/admin/files/temp/upload", name="uploadNewFilesTemp")
  1544.      */
  1545.     public function uploadNewFilesTemp(Request $request)
  1546.     {
  1547.         $fileExtension $request->files->get('upload')->getClientOriginalExtension();
  1548.         $allowedExtensions = ['jpg''png''svg''webp''jpeg'];
  1549.         if (!in_array($fileExtension$allowedExtensions)) {
  1550.             return $this->json(['uploaded' => false'error' => ['message' => 'File must be in jpg/png/webp']], Response::HTTP_BAD_REQUEST);
  1551.         }
  1552.         if ($request->files->has('upload')) {
  1553.             $file $request->files->get('upload');
  1554.             $size $file->getSize();
  1555.             if ($size 20 1024 1024) {
  1556.                 return $this->json(['uploaded' => false'error' => ['message' => 'File size is not more than 20 MB']], Response::HTTP_BAD_REQUEST);
  1557.             }
  1558.             $fileMimeType $file->getClientMimeType();
  1559.             $originalName $file->getClientOriginalName();
  1560.             $extension $file->getClientOriginalExtension();
  1561.             $uniqueFilename md5(uniqid()) . time() . '.' $extension;
  1562.             $media = new Media();
  1563.             $media->setFile($file);
  1564.             $media->setNameFile(Media::getPrefixName($media->getFile()->getClientOriginalName()));
  1565.             $media->setS3key('temp/' $uniqueFilename);
  1566.             $this->s3Manager->upload($media);
  1567.             if ($media->getUrl() != null) {
  1568.                 $mediaUrl $media->getUrl();
  1569.             } else {
  1570.                 $filePath 'uploads/advertise/';
  1571.                 // dd($filePath);
  1572.                 $s =  $file->move($filePath$uniqueFilename);
  1573.                 $baseUrl $_ENV['APP_URl'];
  1574.                 $mediaUrl $baseUrl $filePath $uniqueFilename;
  1575.             }
  1576.             return $this->json(['uploaded' => true'url' => $mediaUrl'fileName' => $originalName'fileSize' => $size'fileType' => $fileMimeType]);
  1577.         }
  1578.         return $this->json(['uploaded' => false'error' => ['message' => 'No file uploaded']], Response::HTTP_BAD_REQUEST);
  1579.     }
  1580.     /**
  1581.      * @Route("/chat/presence", name="chatpresence")
  1582.      */
  1583.     public function chatpresence(Request $request)
  1584.     {
  1585.         try {
  1586.             $em $this->getDoctrine()->getManager();
  1587.             $id $request->get('room');
  1588.             $type $request->get('type');
  1589.             $this->logger->error('Sockect : User' $id ' type:' $type);
  1590.             $sql "UPDATE `user` SET `is_online` = ? WHERE  `id`=?";
  1591.             $appointment $em->getConnection()->prepare($sql);
  1592.             $appointment->execute([$type$id]);
  1593.         } catch (\Exception $e) {
  1594.             $this->logger->error('Sockect :' $e->getMessage());
  1595.             echo $e->getMessage();
  1596.             exit;
  1597.         }
  1598.         echo 'OK';
  1599.         exit;
  1600.     }
  1601.     /**
  1602.      * @Route("/admin/chat/updateUserCall", name="updateUserCall")
  1603.      */
  1604.     public function updateUserCall(Request $request){
  1605.         $user $this->getUser();
  1606.         $entityManager $this->getDoctrine()->getManager();
  1607.         $user->setLastCallTime(time());
  1608.         $entityManager->persist($user);
  1609.         $entityManager->flush();
  1610.         return new JsonResponse(['status' => 1'message' => 'ok']);
  1611.     }
  1612.     /**
  1613.      * @Route("/chat/statuscron", name="statuscron")
  1614.      */
  1615.     public function statuscron(Request $request)
  1616.     {
  1617.         $curl curl_init();
  1618.         curl_setopt_array($curl, array(
  1619.             CURLOPT_URL => 'https://' $_ENV['SOCKET_URL'] . '/rooms',
  1620.             CURLOPT_RETURNTRANSFER => true,
  1621.             CURLOPT_ENCODING => '',
  1622.             CURLOPT_MAXREDIRS => 10,
  1623.             CURLOPT_TIMEOUT => 0,
  1624.             CURLOPT_FOLLOWLOCATION => true,
  1625.             CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  1626.             CURLOPT_CUSTOMREQUEST => 'POST',
  1627.             CURLOPT_POSTFIELDS => json_encode(['api_key'=>$_ENV['SOCKET_SECRET_KEY']]),
  1628.             CURLOPT_HTTPHEADER => array(
  1629.                 'Content-Type: application/json'
  1630.             ),
  1631.         ));
  1632.         $response curl_exec($curl);
  1633.         curl_close($curl);
  1634.         $users json_decode($response);
  1635.          
  1636.         $onlineUsers = [];
  1637.         foreach ($users as $u) {          
  1638.             // $u = (int)$u;
  1639.             preg_match('/\d+/'$u$matches);
  1640.             // The number will be in $matches[0]
  1641.             $u $matches[0] ?? 0;            
  1642.             if ($u 0) {
  1643.                 $onlineUsers[] = $u;
  1644.             }
  1645.         }
  1646.         
  1647.         $em $this->getDoctrine()->getManager();
  1648.         if (count($onlineUsers) > 0) {
  1649.             $placeholders implode(','array_fill(0count($onlineUsers), '?'));           
  1650.             $sql "UPDATE `user` SET `is_online` = ? WHERE `is_online`=? ";
  1651.             $appointment $em->getConnection()->prepare($sql);
  1652.             $appointment->execute([01]);
  1653.             $sql "UPDATE `user` SET `is_online` = ? WHERE `is_online`=? and `id` IN ($placeholders)";
  1654.             $appointment $em->getConnection()->prepare($sql);
  1655.             $appointment->execute(array_merge([10], $onlineUsers));
  1656.         } else {
  1657.             $sql "UPDATE `user` SET `is_online` = ? WHERE `is_online`=?";
  1658.             $appointment $em->getConnection()->prepare($sql);
  1659.             $appointment->execute([01]);
  1660.         }
  1661.         return new JsonResponse(['status' => $response'message' => 'Success']);
  1662.     }
  1663.   
  1664.     /**
  1665.      * @Route("/patient/sync-clinic", name="patientsconversation")
  1666.      */
  1667.     public function patientsconversation(Request $request)
  1668.     {
  1669.       
  1670.         $clinic $request->get('id');
  1671.         $em $this->getDoctrine()->getManager();
  1672.         if (!$clinic) {
  1673.             $clinics $this->getDoctrine()->getRepository(Clinic::class)
  1674.             ->findAll();
  1675.             foreach ($clinics as $clinic) {
  1676.                 $this->addPatientToConversations($em$clinic->getId());
  1677.             }
  1678.         }else{
  1679.             $this->addPatientToConversations($em$clinic);
  1680.         }
  1681.       
  1682.       echo 'OK';
  1683.         exit;
  1684.     }
  1685.     public function addPatientToConversations($em$clinicId)
  1686.     {
  1687.         $limit 1000;
  1688.         $offset 0;
  1689.         do {
  1690.             $sql "SELECT id FROM user 
  1691.                     WHERE clinic_id = ? AND role = ? AND deleted = ? 
  1692.                     AND id NOT IN (
  1693.                         SELECT user_id FROM patient_conversation 
  1694.                         WHERE type = 0 AND clinic_id = ?
  1695.                     )
  1696.                     LIMIT $limit OFFSET $offset";
  1697.             $stmt $em->getConnection()->prepare($sql);
  1698.             $stmt->execute([$clinicId'ROLE_PATIENT'0$clinicId]);
  1699.             $patients $stmt->fetchAllAssociative();
  1700.             $values = [];
  1701.             foreach ($patients as $pts) {
  1702.                 $userId $pts['id'];
  1703.                 $time time();
  1704.                 $values[] = "(0, $userId$userId, 1, $time$time$clinicId)";
  1705.             }
  1706.             if (!empty($values)) {
  1707.                 $sql "INSERT INTO patient_conversation 
  1708.                         (type, user_id, user_ids, status, created_at, updated_at, clinic_id) 
  1709.                         VALUES " implode(', '$values);
  1710.                 $insertStmt $em->getConnection()->prepare($sql);
  1711.                 $insertStmt->execute();
  1712.             }
  1713.             $offset += $limit;
  1714.         } while (count($patients) === $limit);
  1715.       return new Response('Okay');
  1716.     }
  1717.     private function addClinicMembersInGroup($convList)
  1718.     {
  1719.         try {
  1720.             
  1721.             $clinic $this->getDoctrine()->getRepository(Clinic::class)
  1722.                 ->find($convList['clinic_id']);
  1723.             $organizationId $clinic->getOrganisation()->getId();
  1724.             $em $this->getDoctrine()->getManager();
  1725.             $roles = ['ROLE_CLINIC_ADMIN''ROLE_PRACTITIONER''ROLE_SUPER_CLINIC_ADMIN'];
  1726.             $rolesPlaceholder implode(','array_fill(0count($roles), '?'));
  1727.             $sql "SELECT role,id,username FROM user WHERE   deleted= ?   AND ((role IN ($rolesPlaceholder) AND clinic_id = ?) OR organisation_id = ?)  order by id desc";
  1728.             $ap $em->getConnection()->prepare($sql);
  1729.             $params array_merge([0], $roles);
  1730.             $params[] = $convList['clinic_id'];
  1731.             $params[] = $organizationId;
  1732.             $ap->execute($params);
  1733.             $users $ap->fetchAll();
  1734.             $fromuserId $convList['from_user_id'];
  1735.             $clinic $this->getDoctrine()->getRepository(Clinic::class)
  1736.                 ->find($convList['clinic_id']);
  1737.             $sql "SELECT role,id FROM user WHERE  deleted= ? and organisation_id=?";
  1738.             $ap $em->getConnection()->prepare($sql);
  1739.             $ap->execute([0$clinic->getOrganisationId()]);
  1740.             $adminData $ap->fetchAll();
  1741.             if (count($adminData) > 0) {
  1742.                 $users array_merge($users$adminData);
  1743.             }
  1744.             $userIds = [];
  1745.             foreach ($users as $us) {
  1746.                 if ($us['id'] != $fromuserId) {
  1747.                     $userIds[] = $us['id'];
  1748.                 }
  1749.             }
  1750.             $sql "SELECT role,id,username FROM user WHERE  role =? and deleted= ? order by id desc";
  1751.             $ap $em->getConnection()->prepare($sql);
  1752.             $ap->execute(['ROLE_CONSENTZ_ADMIN'0]);
  1753.             $admins $ap->fetchAll();
  1754.             foreach ($admins as $admin) {
  1755.                 $userIds[] = $admin['id'];
  1756.             }
  1757.             if (count($userIds) > 0) {
  1758.                 $userIds implode(','$userIds) . ',' $fromuserId;
  1759.                 $sql "UPDATE `conversation` SET `user_ids` = ? WHERE `id`=?";
  1760.                 $appointment $em->getConnection()->prepare($sql);
  1761.                 $appointment->execute([$userIds$convList['id']]);
  1762.             }
  1763.         } catch (\Exception $e) {
  1764.             dd($e->getMessage());
  1765.         }
  1766.         return ['status' => 1];
  1767.     }
  1768.     private function setData($chat$userId)
  1769.     {
  1770.         $time = ($chat['created_at'] > (time() - 86400)) ? date('h:i A'$chat['created_at']) : date('Y-m-d h:i A'$chat['created_at']);
  1771.         $message_class $chat['from_user_id'] == $userId 'sender' 'receiver';
  1772.         if($chat['from_user_id'] == $userId){
  1773.         if(isset($chat['receive_status']) && $chat['receive_status'] =='read'){
  1774.            $messageStatus ='read';
  1775.            $messageIcon ='&#10003;&#10003;';
  1776.         }else if(isset($chat['receive_status']) && $chat['receive_status'] =='delivered'){
  1777.            $messageStatus ='delivered';
  1778.            $messageIcon ='&#10003;';
  1779.         }else{
  1780.            $messageStatus ='sent';
  1781.            $messageIcon ='&#10003;';
  1782.         }
  1783.         }else{
  1784.             $messageStatus ='';
  1785.            $messageIcon ='';
  1786.         }
  1787.         return [
  1788.             'chat_id' => $chat['chat_id'],
  1789.             'name' => isset($chat['name']) ? $chat['name'] : '',
  1790.             'image' => (isset($chat['image']) && $chat['image'] != '') ? $chat['image'] :(@$chat['media_url'] != ''?@$chat['media_url']:'/images/Clinic/solid_gray.png'),
  1791.             'conv_id' => $chat['conversation_id'],
  1792.             'from_user_id' => $chat['from_user_id'],
  1793.             'created_at' => $chat['created_at'],
  1794.             'created_time' => $time,
  1795.             'date' => date('d-m-Y'$chat['created_at']),
  1796.             'time' => date('h:i A'$chat['created_at']),
  1797.             'message' => $this->messageHtml($chat$userId),
  1798.             'message_text' => $this->messageText($chat),
  1799.             'message_class' => $message_class,
  1800.             'receive_class'=>$messageStatus,
  1801.             'receive_icon'=>$messageIcon,
  1802.             'type' => $chat['type']
  1803.         ];
  1804.     }
  1805.     private function messageHtml($chat$userId)
  1806.     {
  1807.         $msg $chat['message'] ? $chat['message'] : '';
  1808.         if($msg != ''){
  1809.        
  1810.             if (strpos($msg'https://') !== false || strpos($msg'http://') !== false) {
  1811.                 $msg '<a href="'.strip_tags($msg).'" target="_blank">'.$msg.'</a>';
  1812.             }
  1813.         }
  1814.         if ($chat['type'] == 1) {
  1815.             $msg '';
  1816.             $chatId $chat['chat_id'];
  1817.             $data json_decode($chat['data'], true);
  1818.             if ($data) {
  1819.                 if (strpos($data['type'], 'image') !== false) {
  1820.                     $msg .= '<img src="' $data['media_url'] . '">';
  1821.                 } else if (strpos($data['type'], 'audio') !== false) {
  1822.                     $msg .= '<audio controls preload="metadata" id="chataudio_' $chatId '"  src="' $data['media_url'] . '" ></audio>';
  1823.                     $msg .= '<script>
  1824.                         setTimeout(() => {
  1825.                             const audio = document.getElementById("chataudio_' $chatId '");
  1826.                             if (audio) {
  1827.                             audio.addEventListener("loadedmetadata", () => {
  1828.                                 audio.currentTime = 0.1;
  1829.                             });
  1830.                             audio.load();
  1831.                             }
  1832.                         }, 100);
  1833.                         </script>';
  1834.                 } else if (strpos($data['type'], 'video') !== false) {
  1835.                     $msg .= '<video controls width="300" height="200" src="' $data['media_url'] . '" ></video>';
  1836.                 } else {
  1837.                     $msg .= '<span style="padding:30px;"><i class="fa fa-file" style="font-size:100px;"></i></span><br>';
  1838.                 }
  1839.             }
  1840.             $msg .= '<a download href="' $data['media_url'] . '" target="_blank"><i class="fa fa-download"></i> ' $this->shortenFilename($data['name'], 15) . '</a>';
  1841.         } else if ($chat['type'] == 2) {
  1842.             $msg '';
  1843.             $data json_decode($chat['data'], true);
  1844.             $callId "'" . @$data['call_id'] . "'";
  1845.             $fromId = @$chat['from_user_id'];
  1846.             if ($data) {
  1847.                 // $msg .= '<button type="button" class="btn tbn-primary" onclick="chatApp.joinCall(' . $callId . ',
  1848.                 // ' . $fromId . ')"><img src="/images/telephone-call.png"></button>';
  1849.                 $msg .= '<button type="button" class="btn tbn-primary" style="cursor: auto;"><img src="/images/telephone-call.png"></button>';
  1850.             }
  1851.         }
  1852.         return $msg;
  1853.     }
  1854.     private function shortenFilename($filename$maxLength 15)
  1855.     {
  1856.         $ext pathinfo($filenamePATHINFO_EXTENSION);
  1857.         $basename pathinfo($filenamePATHINFO_FILENAME);
  1858.         if (strlen($basename) > $maxLength) {
  1859.             $firstPart substr($basename0ceil($maxLength 2));
  1860.             $secondPart substr($basename, -floor($maxLength 2));
  1861.             $basename $firstPart '...' $secondPart;
  1862.         }
  1863.         return $basename '.' $ext;
  1864.     }
  1865.     private function startNewConversation($opponantId)
  1866.     {
  1867.         try {
  1868.             if ($opponantId 1) {
  1869.                 return ['status' => 0'message' => 'Invalid recipient.'];
  1870.             }
  1871.             $em $this->getDoctrine()->getManager();
  1872.             $sql "select * from user where id=? and role != ? and deleted= ?";
  1873.             $ap $em->getConnection()->prepare($sql);
  1874.             $ap->execute([$opponantId'ROLE_PATIENT'0]);
  1875.             $oppo $ap->fetchAssociative();
  1876.             if (!$oppo || @$oppo['role'] == 'ROLE_PATIENT') {
  1877.                 return ['status' => 0'message' => 'Invalid recipient.'];
  1878.             }
  1879.             $user $this->getUser();
  1880.             $userId $user->getId();
  1881.             if ($opponantId == $userId) {
  1882.                 return ['status' => 0'message' => "You cannot send a message to yourself."];
  1883.             }
  1884.             $sql "select * from conversation where (from_user_id=? and to_user_id=?) or (from_user_id=? and to_user_id=?)";
  1885.             $ap $em->getConnection()->prepare($sql);
  1886.             $ap->execute([$opponantId$userId$userId$opponantId]);
  1887.             $conversation $ap->fetchAssociative();
  1888.             $type 0;
  1889.             $time time();
  1890.             $status 1;
  1891.             if (!$conversation) {
  1892.                 $sql "INSERT INTO conversation (type, from_user_id, to_user_id, user_ids,status, created_at, updated_at)
  1893.             VALUES (?,?,?,?,?,?,?)";
  1894.                 $messageInsert $em->getConnection()->prepare($sql);
  1895.                 $messageInsert->execute([$type$userId$opponantId,  $userId ',' $opponantId$status$time$time]);
  1896.                 $lastId $em->getConnection()->lastInsertId();
  1897.                 $convId $lastId;
  1898.             } else {
  1899.                 $deletedBy $conversation['deleted_by'];
  1900.                 if ($deletedBy) {
  1901.                     $deletedByArray explode(','$deletedBy);
  1902.                     $deletedByArray array_filter(array_map('trim'$deletedByArray));
  1903.                     $deletedByArray array_filter($deletedByArray, function ($id) use ($userId) {
  1904.                         return $id != $userId;
  1905.                     });
  1906.                     $updatedDeletedBy implode(','$deletedByArray);
  1907.                 } else {
  1908.                     $updatedDeletedBy '';
  1909.                 }
  1910.                 $sql "UPDATE `conversation` SET `updated_at`=?,`deleted_by`=? WHERE `id`=?";
  1911.                 $appointment $em->getConnection()->prepare($sql);
  1912.                 $appointment->execute([time(), $updatedDeletedBy$conversation['id']]);
  1913.                 $convId $conversation['id'];
  1914.             }
  1915.             return ['status' => 1'convId' => $convId];
  1916.         } catch (\Exception $e) {
  1917.             return ['status' => 0'message' => $e->getMessage()];
  1918.         }
  1919.     }
  1920.     private function messageText($chat)
  1921.     {
  1922.         $msg $chat['message'] ? $chat['message'] : '';
  1923.         if ($chat['type'] == 1) {
  1924.             $msg '[File]';
  1925.         } else if ($chat['type'] == 2) {
  1926.             $msg 'Call';
  1927.         }
  1928.         return $msg;
  1929.     }
  1930.     
  1931.     
  1932. }