src/Controller/MessageController.php line 426

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