Rev 3121 | Rev 4131 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?phpdeclare(strict_types = 1);namespace LeadersLinked\Controller;use Laminas\Db\Adapter\AdapterInterface;use Laminas\Cache\Storage\Adapter\AbstractAdapter;use Laminas\Mvc\Controller\AbstractActionController;use Laminas\Log\LoggerInterface;use Laminas\View\Model\JsonModel;use Laminas\View\Model\ViewModel;use LeadersLinked\Library\Functions;use LeadersLinked\Mapper\UserMapper;use LeadersLinked\Mapper\ConnectionMapper;use LeadersLinked\Mapper\ChatMessageMapper;use LeadersLinked\Mapper\ChatGroupMapper;use LeadersLinked\Mapper\ChatGroupMessageMapper;use LeadersLinked\Mapper\ChatGroupUserMessageMapper;use LeadersLinked\Mapper\ChatUserMapper;use LeadersLinked\Model\ChatMessage;use LeadersLinked\Model\ChatGroupMessage;use LeadersLinked\Model\ChatGroupUserMessage;use LeadersLinked\Model\Connection;use LeadersLinked\Model\ChatGroup;use LeadersLinked\Model\ChatUser;use LeadersLinked\Form\Chat\CreateGroupForm;use LeadersLinked\Mapper\ChatGroupUserMapper;use LeadersLinked\Model\ChatGroupUser;use LeadersLinked\Mapper\UtilMapper;class ChatController extends AbstractActionController{/**** @var AdapterInterface*/private $adapter;/**** @var AbstractAdapter*/private $cache;/**** @var LoggerInterface*/private $logger;/**** @var array*/private $config;/**** @param AdapterInterface $adapter* @param AbstractAdapter $cache* @param LoggerInterface $logger* @param array $config*/public function __construct($adapter, $cache, $logger, $config){$this->adapter = $adapter;$this->cache = $cache;$this->logger = $logger;$this->config = $config;}/**** Ruta usada para mostrar el chat en pantalla completa usada en los moviles**/public function indexAction(){$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$connectionMapper = ConnectionMapper:: getInstance($this->adapter);$connectionIds = $connectionMapper->fetchAllConnectionsByUserReturnIds( $currentUser->id );$contacts = [];if($connectionIds) {$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();$userMapper = UserMapper::getInstance($this->adapter);$users = $userMapper->fetchAllByIds($connectionIds);foreach($users as $user){$username = trim($user->first_name . ' ' . $user->last_name);$status = $user->online ? 'LABEL_ONLINE' : 'LABEL_OFFLINE';$user_image = $this->url()->fromRoute('storage', ['type' => 'user', 'code' => $user->uuid, 'filename' => $user->image]);array_push($contacts, ['id' => $user->uuid, 'status'=> $status,'name'=> $username, 'image' => $user_image]);}}$groups = [];$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$results = $chatGroupUserMapper->fetchAllByUserId($currentUser->id);if(is_array($results)) {foreach ($results as $r){$chatOwner = $chatGroupUserMapper->fetchOwnerByGroupId($r->group_id);$userOwner = $userMapper->fetchOne( $chatOwner->user_id );$chatGroup = $chatGroupMapper->fetchOne($r->group_id);array_push($groups, ['id' => $chatGroup->uuid, 'name' => $chatGroup->name, 'owner_id' => $userOwner->uuid ]);}}/*$this->layout()->setTemplate('layout/layout-chat.phtml');$this->layout()->setVariables(['is_chat' => true]);*/$viewModel = new ViewModel();$viewModel->setTemplate('leaders-linked/chat/chat.phtml');$viewModel->setVariables(['contacts' => $contacts,'groups' => $groups,'user_id' => $currentUser->id,'is_chat' => true]);return $viewModel ;}/*** Recuperamos los contactos y grupos* tiene que enviarse un petición GET a la siguiente url: /chat/heart-beat* retorna un json en caso de ser positivo* [* 'success' : true,* 'data' : [* [* 'url_leave' => 'url para abandonar el grupo en caso de no ser el propietario',* 'url_delete' => 'url para borrar el grupo si es el propietario',* 'url_add_user_to_group' => 'url para agregar un usuario al grupo si es el propietario',* 'url_get_contacts_availables_for_group' => 'url para obtener los usuarios disponibles para agregarlos al grupo',* 'url_get_contact_group_list' => 'url para obtener los usuarios del grupo si es el propietario',* 'url_clear' => 'url para limpiar los mensajes del grupo',* 'url_close' => 'url para marcar como cerrado el chat',* 'url_open' => 'url para marcar como abierto el chat',* 'url_send' => 'url para enviar un mensaje',* 'url_upload' => 'url para subir un archivo, imagen o video',* 'url_get_all_messages' => 'url para para obtener los mensajes',* 'url_mark_seen' => 'url para marcar los mensajes como vistos'* 'url_mark_received' => 'url para marcar los mensajes como recibios'* 'id' => 'id del grupo encriptado',* 'name' => 'nombre del grupo',* 'type' => 'group', //fixed* 'is_open' => 'true/false',* 'unsee_messages' => 'true/false',* 'unread_messages' => 'true/false',* 'count_not_seen_messages' => 'cantidad de mensajes no vistos',* 'count_not_received_messages' => 'cantidad de mensajes no recibidos',* 'last_message' => 'tiempo desde el ultimo mensaje',* ],* [* 'url_clear' => 'url para limpiar los mensajes del grupo',* 'url_close' => 'url para marcar como cerrado el chat',* 'url_open' => 'url para marcar como abierto el chat',* 'url_send' => 'url para enviar un mensaje',* 'url_upload' => 'url para subir un archivo, imagen o video',* 'url_get_all_messages' => 'url para para obtener los mensajes',* 'url_mark_seen' => 'url para marcar los mensajes como vistos'* 'url_mark_received' => 'url para marcar los mensajes como recibios'* 'id' => 'id del usuario encriptado',* 'name' => 'nombre del usuario',* 'image' => 'imagen del usuario',* 'type' => 'user' //fixed,* 'profile' => 'url del profile',* 'online' => 'true/false',* 'is_open' => 'true/false',* 'unsee_messages' => 'true/false'* 'unread_messages' => 'true/false',* 'count_not_seen_messages' => 'cantidad de mensajes no vistos',* 'count_not_received_messages' => 'cantidad de mensajes no recibidos',* 'last_message' => 'tiempo desde el ultimo mensaje',* ]* ]* En caso de ser negativo puede haber 2 formatos* [* 'success' : false,* 'data' : mensaje de error* ]* o* [* 'success' : false,* 'data' : [* 'fieldname' : [* 'mensaje de error'* ]* ]* ]* @return \Laminas\View\Model\JsonModel*/public function heartBeatAction(){$request = $this->getRequest();if($request->isGet()) {$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$userMapper = UserMapper::getInstance($this->adapter);$userMapper->updateChatOnlineStatus($currentUser->id);$chats = [];$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);$results = $chatGroupUserMapper->fetchAllByUserId($currentUser->id);if (is_array($results)) {foreach ($results as $r){$chatGroup = $chatGroupMapper->fetchOne($r->group_id);$chatUserOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);$chatUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);$is_open = $chatUser->open == ChatGroupUser::OPEN_YES;$count_not_seen_messages = $chatGroupUserMessageMapper->countNotSeenMessages($chatGroup->id, $currentUser->id);$count_not_received_messages = $chatGroupUserMessageMapper->countNotReceivedMessages($chatGroup->id, $currentUser->id);$lastMessage = $chatGroupUserMessageMapper->fetchLastMessage($chatGroup->id, $currentUser->id);if($lastMessage) {$lastMessage = Functions::timeAgo($lastMessage->added_on, $now);} else {$lastMessage = '';}$not_seen_messages = $count_not_seen_messages > 0;$not_received_messages = $count_not_received_messages > 0;if($chatUserOwner->user_id == $currentUser->id ) {$chat = ['url_leave' => '','url_delete' => $this->url()->fromRoute('chat/delete-group', ['group_id' => $chatGroup->uuid]),'url_add_user_to_group' => $this->url()->fromRoute('chat/add-user-to-group', ['group_id' => $chatGroup->uuid]),'url_get_contact_group_list' => $this->url()->fromRoute('chat/get-contact-group-list', ['group_id' => $chatGroup->uuid]),'url_get_contacts_availables_for_group' => $this->url()->fromRoute('chat/get-contacts-availables-for-group', ['group_id' => $chatGroup->uuid]),'url_clear' => $this->url()->fromRoute('chat/clear', ['id' => $chatGroup->uuid]),'url_close' => $this->url()->fromRoute('chat/close', ['id' => $chatGroup->uuid]),'url_open' => $this->url()->fromRoute('chat/open', ['id' => $chatGroup->uuid]),'url_send' => $this->url()->fromRoute('chat/send', ['id' => $chatGroup->uuid]),'url_upload' => $this->url()->fromRoute('chat/upload', ['id' => $chatGroup->uuid]),'url_get_all_messages' => $this->url()->fromRoute('chat/get-all-messages', ['id' => $chatGroup->uuid]),'url_mark_seen' => $this->url()->fromRoute('chat/mark-seen', ['id' => $chatGroup->uuid]),'url_mark_received' => $this->url()->fromRoute('chat/mark-received', ['id' => $chatGroup->uuid]),'id' => $chatGroup->uuid,'name' => $chatGroup->name,'type' => 'group','is_open' => $is_open ? 1 : 0,'not_seen_messages' => $not_seen_messages,'not_received_messages' => $not_received_messages,'count_not_seen_messages' => $count_not_seen_messages,'count_not_received_messages' => $count_not_received_messages,'last_message' => $lastMessage];} else {$chat = ['url_delete' => '','url_add_user_to_group' => '','url_get_contact_group_list' => $this->url()->fromRoute('chat/get-contact-group-list', ['group_id' => $chatGroup->uuid]),'url_leave' => $this->url()->fromRoute('chat/leave-group', ['group_id' => $chatGroup->uuid]),'url_clear' => $this->url()->fromRoute('chat/clear', ['id' => $chatGroup->uuid]),'url_close' => $this->url()->fromRoute('chat/close', ['id' => $chatGroup->uuid]),'url_open' => $this->url()->fromRoute('chat/open', ['id' => $chatGroup->uuid]),'url_send' => $this->url()->fromRoute('chat/send', ['id' => $chatGroup->uuid]),'url_upload' => $this->url()->fromRoute('chat/upload', ['id' => $chatGroup->uuid]),'url_get_all_messages' => $this->url()->fromRoute('chat/get-all-messages', ['id' => $chatGroup->uuid]),'url_mark_seen' => $this->url()->fromRoute('chat/mark-seen', ['id' => $chatGroup->uuid]),'url_mark_received' => $this->url()->fromRoute('chat/mark-received', ['id' => $chatGroup->uuid]),'id' => $chatGroup->uuid,'name' => $chatGroup->name,'type' => 'group','is_open' => $is_open ? 1 : 0,'not_seen_messages' => $not_seen_messages,'not_received_messages' => $not_received_messages,'count_not_seen_messages' => $count_not_seen_messages,'count_not_received_messages' => $count_not_received_messages,'last_message' => $lastMessage];}array_push($chats, $chat);}}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);$connectionMapper = ConnectionMapper::getInstance($this->adapter);$connectionIds = $connectionMapper->fetchAllConnectionsByUserReturnIds($currentUser->id);if ($connectionIds) {$userMapper = UserMapper::getInstance($this->adapter);$users = $userMapper->fetchAllByIds($connectionIds);foreach ($users as $user){$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if($chatUser) {$count_not_received_messages = $chatMessageMapper->countNotReceivedMessagesByChatIdAndToId($chatUser->id, $currentUser->id);$count_not_seen_messages = $chatMessageMapper->countNotSeenMessagesByChatIdAndToId($chatUser->id, $currentUser->id);$lastMessage = $chatMessageMapper->fetchLastMessage($chatUser->id, $currentUser->id);if($lastMessage) {$lastMessage = Functions::timeAgo($lastMessage->added_on, $now);} else {$lastMessage = '';}if($currentUser->id == $chatUser->user_id1) {$is_open = $chatUser->user_open1 == ChatUser::OPEN_YES;} else {$is_open = $chatUser->user_open2 == ChatUser::OPEN_YES;}$not_received_messages = $count_not_received_messages > 0;$not_seen_messages = $count_not_seen_messages > 0;} else {$is_open = false;$count_not_received_messages = 0;$count_not_seen_messages = 0;$not_seen_messages = false;$not_received_messages = false;$lastMessage = '';}$chat = ['url_clear' => $this->url()->fromRoute('chat/clear', ['id' => $user->uuid]),'url_close' => $this->url()->fromRoute('chat/close', ['id' => $user->uuid]),'url_open' => $this->url()->fromRoute('chat/open', ['id' => $user->uuid]),'url_send' => $this->url()->fromRoute('chat/send', ['id' => $user->uuid]),'url_upload' => $this->url()->fromRoute('chat/upload', ['id' => $user->uuid]),'url_mark_seen' => $this->url()->fromRoute('chat/mark-seen', ['id' => $user->uuid]),'url_mark_received' => $this->url()->fromRoute('chat/mark-received', ['id' => $user->uuid]),'url_get_all_messages' => $this->url()->fromRoute('chat/get-all-messages', ['id' => $user->uuid]),'id' => $user->uuid,'name' => trim($user->first_name . ' ' . $user->last_name),'image' => $this->url()->fromRoute('storage', ['code' => $user->uuid, 'type' => 'user', 'filename' => $user->image]),'profile' => $this->url()->fromRoute('profile/view', ['id' =>$user->uuid]),'type' => 'user','online' => $user->online ? 1 : 0,'is_open' => $is_open ? 1 : 0,'not_seen_messages' => $not_seen_messages,'not_received_messages' => $not_received_messages,'count_not_seen_messages' => $count_not_seen_messages,'count_not_received_messages' => $count_not_received_messages,'last_message' => $lastMessage];array_push($chats, $chat);}}$userMapper->updateLastHeartBeat($currentUser->id);$response = ['success' => true,'data' => $chats];} else {$response = ['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED'];}return new JsonModel($response);}/*** Esta función crea un grupo y asigna al usuario actual como el owner del mismo,* tiene que enviarse un petición POST a la siguiente url: /chat/create-group* con el siguiente parámetro* name = un string con un máximo de 50 carácteres* retorna un json en caso de ser positivo* [* 'success' : true,* 'data' : ID del grupo encriptado* ]* En caso de ser negativo puede haber 2 formatos* [* 'success' : false,* 'data' : mensaje de error* ]* o* [* 'success' : false,* 'data' : [* 'fieldname' : [* 'mensaje de error'* ]* ]* ]* @return \Laminas\View\Model\JsonModel*/public function createGroupAction(){$request = $this->getRequest();if($request->isPost()) {$form = new CreateGroupForm();$form->setData($request->getPost()->toArray());if($form->isValid()) {$dataPost = (array) $form->getData();$name = $dataPost['name'];$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$chatGroup = new ChatGroup();$chatGroup->name = $name;$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$result = $chatGroupMapper->insert($chatGroup);if ($result) {$chatGroup = $chatGroupMapper->fetchOne($chatGroup->id);$chatGroupUser = new ChatGroupUser();$chatGroupUser->group_id = $chatGroup->id;$chatGroupUser->user_id = $currentUser->id;$chatGroupUser->owner = ChatGroupUser::OWNER_YES;$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$result = $chatGroupUserMapper->insert($chatGroupUser);if($result) {$userMapper = UserMapper::getInstance($this->adapter);$userMapper->updateLastActivity($currentUser->id);$fullpath_chat = $this->config['leaderslinked.fullpath.chat'];$dirpath = $fullpath_chat . $chatGroup->uuid;if (! file_exists($dirpath)) {mkdir($dirpath, 0777, true);chmod($dirpath, 0777);}$response = ['success' => true,'data' => $chatGroup->uuid,];} else {$response = ['success' => false,'data' => $chatGroupUserMapper->getError(),];}} else {$response = ['success' => false,'data' => $chatGroupMapper->getError(),];}} else {$messages = [];$form_messages = (array) $form->getMessages();foreach($form_messages as $fieldname => $field_messages){$messages[$fieldname] = array_values($field_messages);}return new JsonModel(['success' => false,'data' => $messages]);}} else {$response = ['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED'];}return new JsonModel($response);}/*** Esta función crea un grupo y asigna al usuario al mismo, solo el owner puede hacerlo* Es una petición POST el url que contiene el ID encriptado del chat (/chat/add-user-to-group/:group_id)* Parámetros del route* :group_id = id del grupo encriptado* Parámetro post* uid = id encriptado del usuario* retorna un json en caso de ser positivo* [* 'success' : true,* 'data' : [* [* 'url_remove_from_group' => 'url para remover el usuario del grupo',* 'id' => 'id del usuario encriptado',* 'name' => 'nombre del usuario',* 'image' => 'imagen del usuario',* 'type' => 'user' //fixed,* 'online' => $online,* ]* ]* En caso de ser negativo puede haber 2 formatos* [* 'success' : false,* 'data' : mensaje de error* ]* o* [* 'success' : false,* 'data' : [* 'fieldname' : [* 'mensaje de error'* ]* ]* ]* @return \Laminas\View\Model\JsonModel*/public function addUserToGroupAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$group_id = $this->params()->fromRoute('group_id');$user_id = $this->params()->fromPost('uid');if(empty($group_id) || empty($user_id)) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($group_id);if(!$chatGroup) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_NOT_FOUND']);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);if($chatGroupOwner->user_id != $currentUser->id) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER']);}$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($user_id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}if($chatGroupOwner->user_id == $user->id) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_I_CAN_NOT_ADD_HIMSELF']);}$connectionMapper = ConnectionMapper::getInstance($this->adapter);$connection = $connectionMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$connection) {return new JsonModel(['success' => false,'data' => 'ERROR_THIS_USER_IS_NOT_A_CONNECTION']);}$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $user->id);if($chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_THIS_USER_ALREADY_EXISTS_IN_THIS_GROUP']);}$chatGroupUser = new ChatGroupUser();$chatGroupUser->group_id = $chatGroup->id;$chatGroupUser->user_id = $user->id;$chatGroupUser->owner = ChatGroupUser::OWNER_NO;$result = $chatGroupUserMapper->insert($chatGroupUser);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupUserMapper->getError()]);}$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true,'data' => ['url_remove_from_group' => $this->url()->fromRoute('chat/remove-user-from-group', ['group_id' => $chatGroup->uuid, 'user_id' => $user->uuid]),'id' => $user->uuid,'name' => trim($user->first_name . ' ' . $user->last_name),'image' => $this->url()->fromRoute('storage', ['code' => $user->uuid, 'type' => 'user', 'filename' => $user->image]),'type' => 'user','online' => $user->online ? 1 : 0,]]);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Esta función remueve el usuario del grupo* Es una petición POST el url que contiene el ID encriptado del chat (/chat/remove-user-from-group/:group_id/:user_id)* y la cuál se recibe en la función heartBeat.* Parámetros del route* group_id= id encriptado del grupo* user_id = id encriptado del usuario* retorna un json en caso de ser positivo* [* 'success' : true,* ]* En caso de ser negativo puede haber 2 formatos* [* 'success' : false,* 'data' : mensaje de error* ]* @return \Laminas\View\Model\JsonModel*/public function removeUserFromGroupAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$user_id = $this->params()->fromRoute('user_id');$group_id = $this->params()->fromRoute('group_id');if(empty($group_id) || empty($user_id)) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($group_id);if(!$chatGroup) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_NOT_FOUND']);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);if($chatGroupOwner->user_id != $currentUser->id) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER']);}$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($user_id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}if($chatGroupOwner->user_id == $user->id) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_I_CAN_NOT_REMOVE_MYSELF']);}$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $user->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$response = $chatGroupUserMapper->deleteByGroupIdAndUserId($chatGroup->id, $user->id);if($response) {$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true]);} else {return new JsonModel(['success' => false,'data' => $chatGroupMapper->getError()]);}} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Abandonar un grupo* Es una petición POST el url que contiene el ID encriptado del chat (/chat/leave-group/:group_id) y la cuál se recibe en la función heartBeat.* Parámetros del route* :group_id = id del grupo encriptado* En caso de una respuesta positiva* [* 'success' => true,* ]* En caso de un respuesta negativa* [* 'success' => false,* 'data' => (string) 'mensaje_de_error'* ]* @return \Laminas\View\Model\JsonModel*/public function leaveGroupAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$result = false;$group_id = $this->params()->fromRoute('group_id');if(empty($group_id)) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($group_id);if(!$chatGroup) {return new JsonModel(['success' => false,'data' => 'ERROR_GROUP_NOT_FOUND']);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}if($chatGroupUser->owner == ChatGroupUser::OWNER_YES) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_ARE_OWNER']);}$result = $chatGroupUserMapper->deleteByGroupIdAndUserId($chatGroupUser->group_id, $chatGroupUser->user_id);if($result) {$userMapper = UserMapper::getInstance($this->adapter);$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true]);} else {return new JsonModel(['success' => false,'data' => $chatGroupMapper->getError()]);}} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/**** @param ChatGroup $chatGroup* @param int $page* @return array*/private function getAllMessagesForChatGroup($chatGroup, $page = 0){$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return ['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER'];}$chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);$paginator = $chatGroupMessageMapper->getPaginatorByGroupId($chatGroup->id, $page);$pages = $paginator->count();$page = $paginator->getCurrentPageNumber();$items = [];$users = [];$userMapper = UserMapper::getInstance($this->adapter);$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();foreach ($paginator as $m){if (isset($users[$m->sender_id])) {$userdata_from = $users[$m->sender_id];} else {$userdata_from = $userMapper->fetchOne($m->sender_id);$users[ $m->sender_id ] = $userdata_from;}$pic_from = $this->url()->fromRoute('storage', ['code' => $userdata_from->uuid,'type' => 'user','filename' => $userdata_from->image]);$u = $userdata_from->id == $currentUser->id ? 1 : 2;if($m->type == ChatGroupMessage::TYPE_TEXT) {$content = $this->sanitize($m->content);} else {$content = $this->url()->fromRoute('storage', ['code' => $chatGroup->uuid, 'type' => 'chat', 'filename' => $m->content]);}$msgtime = Functions::timeAgo($m->added_on, $now);array_push($items, ['user_name' => trim($userdata_from->first_name . ' ' .$userdata_from->last_name) ,'user_id' => $userdata_from->uuid,'user_image' => $pic_from,'u' => $u,'mtype' => $m->type,'m' => $content,'time' => $msgtime,'id' => $m->uuid]);}return ['success' => true,'data' => ['page' => $page,'pages' => $pages,'items' => $items]];}/**** @param ChatUser $chatUser* @param int $page* @return array*/private function getAllMessagesForChatUser($chatUser, $page = 0){$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);$paginator = $chatMessageMapper->getAllMessagesPaginatorByChatId($chatUser->id, $page);$pages = $paginator->count();$page = $paginator->getCurrentPageNumber();$items = [];$users = [];$userMapper = UserMapper::getInstance($this->adapter);$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();$messages = $paginator->getCurrentItems();foreach ($messages as $m) {$from_id = (int) $m->from_id;$to_id = (int) $m->to_id;if (isset($users[$from_id])) {$userdata_from = $users[$from_id];} else {$userdata_from = $userMapper->fetchOne($from_id);$users[$from_id] = $userdata_from;}$pic_from = $this->url()->fromRoute('storage', ['code' => $userdata_from->uuid,'type' => 'user','filename' => $userdata_from->image]);if (isset($users[$to_id])) {$userdata_to = $users[$to_id];} else {$userdata_to = $userMapper->fetchOne($to_id);$users[ $to_id ] = $userdata_to;}$u = $m->from_id == $currentUser->id ? 1 : 2;$seen = 0;if ($m->to_id == $currentUser->id) {$seen = $m->seen == ChatMessage::SEEN_NO ? 1 : 0;}if($m->type == ChatMessage::TYPE_TEXT) {$content = $this->sanitize($m->content);} else {$content = $this->url()->fromRoute('storage', ['code' => $chatUser->uuid, 'type' => 'chat', 'filename' => $m->content]);}$msgtime = Functions::timeAgo($m->added_on, $now);array_push($items, ['user_name' => ($userdata_from->first_name . ' ' . $userdata_from->last_name),'user_id' => $userdata_from->uuid,'user_image' => $pic_from,'u' => $u,'mtype' => $m->type,'m' => $content,'time' => $msgtime,'id' => $m->uuid,'seen' => $seen,]);}return ['success' => true,'data' => ['page' => $page,'pages' => $pages,'items' => $items,'online' => $currentUser->online ? 1 : 0,]];}/*** Recupera los mensajes de un chat individual o grupal* Es una petición GET el url que contiene el ID encriptado del chat (/chat/get-all-messages/:id) y la cuál se recibe en la función heartBeat.* En caso de una respuesta positiva* [* 'success' => true,* 'data' => [* 'page' => 'entero número de página actúal',* 'pages' => 'entero número total de páginaS',* 'items' => [* 'user_name' => 'nombre del usuario que envia',* 'user_id_encript' => 'id encriptado del usuario que envia',* 'user_image' => 'ruta de la imagén del usuario que envia',* 'u' => '1 = si el usuario que envia es el usuario actual , 2 si no lo es',* 'mtype' => 'text | file',* 'm' => 'texto del mensaje o url del archivo',* 'time' => 'cadena que da el tiempo del mensaje ejemplo 1seg',* ],* 'online' => 'true/false'* ]* ]* En caso de un respuesta negativa* [* 'success' => false,* 'data' => (string) 'mensaje_de_error'* ]* @return \Laminas\View\Model\JsonModel*/public function getAllMessagesAction(){$request = $this->getRequest();if($request->isGet()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = $this->params()->fromRoute('id');$page = filter_var($this->params()->fromQuery('page', 0), FILTER_SANITIZE_NUMBER_INT);if(!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}/**** Mensajes de un chat grupal ****/$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if ($chatGroup) {$response = $this->getAllMessagesForChatGroup($chatGroup, $page);return new JsonModel($response);} else {$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$connectionMapper = ConnectionMapper::getInstance($this->adapter);$connection = $connectionMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$connection || $connection->status != Connection::STATUS_ACCEPTED) {return new JsonModel(['success' => false,'data' => 'ERROR_THIS_USER_IS_NOT_A_CONNECTION']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$chatUser) {$chatUser = new ChatUser();$chatUser->user_id1 = $currentUser->id;$chatUser->user_id2 = $user->id;$response = $chatUserMapper->insert($chatUser);if(!$response) {return new JsonModel(['success' => false,'data' => $chatUserMapper->getError()]);}$chatUser = $chatUserMapper->fetchOne($chatUser->id);$fullpath_chat = $this->config['leaderslinked.fullpath.chat'];$dirpath = $fullpath_chat . $chatUser->uuid;if (! file_exists($dirpath)) {mkdir($dirpath, 0777, true);chmod($dirpath, 0777);}}$response = $this->getAllMessagesForChatUser($chatUser, $page);return new JsonModel($response);}} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Envia un mensaje a un chat individual o grupal* Es una petición POST el url que contiene el ID encriptado del chat (/chat/send/:id) y la cuál se recibe en la función heartBeat.* Parámetros del route* :id = id del chat encriptado* Como parámentro solo se espera un campo* message: string* En caso de una respuesta positiva* [* 'success' => true,* 'user_name' => 'nombre del usuario que envia',* 'user_id_encripted' => 'id encriptado del usuario que envia',* 'user_image' => 'ruta de la imagén del usuario que envia',* 'u' => '1 = si el usuario que envia es el usuario actual , 2 si no lo es',* 'mtype' => 'text | file',* 'm' => 'texto del mensaje o url del archivo',* 'time' => 'cadena que da el tiempo del mensaje ejemplo 1seg',* ]* En caso de un respuesta negativa* [* 'success' => false,* 'data' => (string) 'mensaje_de_error'* ]* @return \Laminas\View\Model\JsonModel*/public function sendAction(){$request = $this->getRequest();if($request->isPost()) {$id = $this->params()->fromRoute('id');$message = trim(filter_var($this->params()->fromPost('message', ''), FILTER_SANITIZE_STRING));if(!$id || empty($message)) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$userMapper = UserMapper::getInstance($this->adapter);$sender_result = $userMapper->fetchOne($currentUser->id);$sender_name = trim($sender_result->first_name . ' ' . $sender_result->last_name);$sender_pic = $this->url()->fromRoute('storage', ['code' => $sender_result->uuid,'type' => 'user','filename' => $sender_result->image]);$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if($chatGroup) {$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$chatGroupMessage = new ChatGroupMessage();$chatGroupMessage->sender_id = $currentUser->id;$chatGroupMessage->group_id = $chatGroup->id;$chatGroupMessage->content = $message;$chatGroupMessage->type = ChatGroupMessage::TYPE_TEXT;$chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);$result = $chatGroupMessageMapper->insert($chatGroupMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupMessageMapper->getError()]);}$chatGroupMessage = $chatGroupMessageMapper->fetchOne($chatGroupMessage->id);$chatGroupUserMessage = new ChatGroupUserMessage();$chatGroupUserMessage->group_id = $chatGroupMessage->group_id;$chatGroupUserMessage->message_id = $chatGroupMessage->id;$chatGroupUserMessage->receiver_id = $currentUser->id;$chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_YES;$chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_NO;$chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);$result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupUserMessageMapper->getError()]);}$results = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);foreach ($results as $r){if ($r->user_id != $currentUser->id) {$chatGroupUserMessage = new ChatGroupUserMessage();$chatGroupUserMessage->group_id = $chatGroupMessage->group_id;$chatGroupUserMessage->message_id = $chatGroupMessage->id;$chatGroupUserMessage->receiver_id = $r->user_id;$chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_NO;$chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_NO;$result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupUserMessageMapper->getError()]);}}}$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();$msgtime = Functions::timeAgo($now, $now);return new JsonModel(['success' => true,'data' => ['user_name' => $sender_name,'user_id_encripted' => $sender_result->uuid,'user_image' => $sender_pic,'u' => 1,'mtype' => 'text','m' => $message,'time' => $msgtime,'id' => $chatGroupMessage->uuid,]]);} else {$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$connectionMapper = ConnectionMapper::getInstance($this->adapter);$connection = $connectionMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$connection || $connection->status != Connection::STATUS_ACCEPTED) {return new JsonModel(['success' => false,'data' => 'ERROR_THIS_USER_IS_NOT_A_CONNECTION']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$chatUser) {$chatUser = new ChatUser();$chatUser->user_id1 = $currentUser->id;$chatUser->user_id2 = $user->id;$response = $chatUserMapper->insert($chatUser);if(!$response) {return new JsonModel(['success' => false,'data' => $chatUserMapper->getError()]);}$chatUser = $chatUserMapper->fetchOne($chatUser->id);$fullpath_chat = $this->config['leaderslinked.fullpath.chat'];$dirpath = $fullpath_chat . $chatUser->uuid;if (! file_exists($dirpath)) {mkdir($dirpath, 0777, true);chmod($dirpath, 0777);}}$chatMessage = new ChatMessage();$chatMessage->chat_id = $chatUser->id;$chatMessage->from_id = $currentUser->id;$chatMessage->to_id = $user->id;$chatMessage->content = $message;$chatMessage->type = ChatMessage::TYPE_TEXT;$chatMessage->recd = ChatMessage::RECD_NO;$chatMessage->seen = ChatMessage::SEEN_NO;$chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);$result = $chatMessageMapper->insert($chatMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatMessageMapper->getError()]);}$chatMessage = $chatMessageMapper->fetchOne($chatMessage->id);$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();$msgtime = Functions::timeAgo($now, $now);return new JsonModel(['success' => true,'data' => ['user_name' => $sender_name,'user_id' => $sender_result->uuid,'user_image' => $sender_pic,'u' => 1,'mtype' => ChatMessage::TYPE_TEXT,'m' => $message,'time' => $msgtime,'id' => $chatMessage->uuid,]]);}$userMapper->updateLastActivity($currentUser->id);return new JsonModel($response);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Esta función recuperar los contactos disponibles para agregarlos a un grupo* Es una petición GET el url que contiene el ID encriptado del chat (/chat/get-contacts-availables-for-group/:group_id) y la cuál se recibe en la función heartBeat.* con el siguiente parámetro* uid = id encriptado del usuario* retorna un json en caso de ser positivo* [* 'success' : true,* 'data' : [* [* 'id' => 'id del usuario encriptado',* 'name' => 'nombre del usuario',* 'image' => 'imagen del usuario',* 'type' => 'user' //fixed,* 'online' => $online,* ]* ]* En caso de ser negativo puede haber 2 formatos* [* 'success' : false,* 'data' : mensaje de error* ]* @return \Laminas\View\Model\JsonModel*/public function contactAvailableGroupListAction(){$request = $this->getRequest();if($request->isGet()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = $this->params()->fromRoute('group_id');if(!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$userMapper = UserMapper::getInstance($this->adapter);$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if(!$chatGroup) {return new JsonModel(['success' => false,'data' => 'ERROR_GROUP_NOT_FOUND']);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);if($chatGroupOwner->user_id != $currentUser->id) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER']);}$contact_ids = [];$contacts = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);foreach($contacts as $contact){array_push($contact_ids, $contact->user_id);}$connectionMapper = ConnectionMapper::getInstance($this->adapter);$connection_ids = $connectionMapper->fetchAllConnectionsByUserReturnIds($currentUser->id);$connection_ids = array_filter($connection_ids, function($var) use ( $contact_ids) {return !in_array($var, $contact_ids);});$items = [];foreach ($connection_ids as $connection_id){$user = $userMapper->fetchOne($connection_id);if (! $user) {continue;}$name = trim($user->first_name . ' ' . $user->last_name);$image = $this->url()->fromRoute('storage', ['code' => $user->uuid,'type' => 'user','filename' => $user->image]);array_push($items, ['id' => $user->uuid,'name' => $name,'image' => $image,'online' => $user->online ? 1 : 0,]);}$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true,'data' => $items,]);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Esta función recuperar los contactos de un grupo* Es una petición GET el url que contiene el ID encriptado del chat (/chat/get-contact-group-list/:group_id) y la cuál se recibe en la función heartBeat.* con el siguiente parámetro* uid = id encriptado del usuario* retorna un json en caso de ser positivo* [* 'success' : true,* 'data' : [* [* 'url_remove_from_group' => 'url para remover el usuario del grupo',* 'id' => 'id del usuario encriptado',* 'name' => 'nombre del usuario',* 'image' => 'imagen del usuario',* 'type' => 'user' //fixed,* 'online' => $online,* ]* ]* En caso de ser negativo puede haber 2 formatos* [* 'success' : false,* 'data' : mensaje de error* ]* o* [* 'success' : false,* 'data' : [* 'fieldname' : [* 'mensaje de error'* ]* ]* ]* @return \Laminas\View\Model\JsonModel*/public function contactGroupListAction(){$request = $this->getRequest();if($request->isGet()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = $this->params()->fromRoute('group_id');if(!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$userMapper = UserMapper::getInstance($this->adapter);$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if(!$chatGroup) {return new JsonModel(['success' => false,'data' => 'ERROR_GROUP_NOT_FOUND']);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_USER_NOT_FOUND']);}$items = [];$chatGroupUsers = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);foreach ($chatGroupUsers as $chatGroupUser){$user = $userMapper->fetchOne((int) $chatGroupUser->user_id);if (! $user) {continue;}$name = trim($user->first_name . ' ' . $user->last_name);$image = $this->url()->fromRoute('storage', ['code' => $user->uuid,'type' => 'user','filename' => $user->image]);if($chatGroupUser->owner == ChatGroupUser::OWNER_YES) {$url_remove_from_group = '';} else {$url_remove_from_group = $this->url()->fromRoute('chat/remove-user-from-group', ['group_id' => $chatGroup->uuid, 'user_id' => $user->uuid ]);}array_push($items, ['url_remove_from_group' => $url_remove_from_group,'id' => $user->uuid,'name' => $name,'image' => $image,'online' => $user->online ? 1 : 0,]);}$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true,'data' => $items,]);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Elimina un grupo de chat, solo el owner puede realizarla* Es una petición POST el url que contiene el ID encriptado del chat (/chat/delete-group/:group_id) y la cuál se recibe en la función heartBeat.* Parámetros del route* :group_id = id del grupo encriptado* En caso de una respuesta positiva* [* 'success' => true,* 'data'=> (int) registros_borrados* ]* En caso de un respuesta negativa* [* 'success' => false,* 'data' => (string) 'mensaje_de_error'* ]* @return \Laminas\View\Model\JsonModel*/public function deleteGroupAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = trim(filter_var($this->params()->fromRoute('group_id'), FILTER_SANITIZE_STRING));if(!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if(!$chatGroup) {return new JsonModel(['success' => false,'data' => 'ERROR_GROUP_NOT_FOUND']);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupOwner = $chatGroupUserMapper->fetchOwnerByGroupId($chatGroup->id);if($chatGroupOwner->user_id != $currentUser->id) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_ARE_NOT_OWNER']);}$chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);$result = $chatGroupUserMessageMapper->deleteAllByGroupId($chatGroup->id);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupUserMessageMapper->getError()]);}$chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);$result = $chatGroupMessageMapper->deleteAllByGroupId($chatGroup->id);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupMessageMapper->getError()]);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$result = $chatGroupUserMapper->deleteAllByGroupId($chatGroup->id);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupUserMapper->getError()]);}$chatGroupMapper->deleteByGroupId($chatGroup->id);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupMapper->getError()]);}$fullpath_chat = $this->config['leaderslinked.fullpath.chat'];$dirpath = $fullpath_chat . $chatGroup->uuid;Functions::rmDirRecursive($dirpath);$userMapper = UserMapper::getInstance($this->adapter);$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true]);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Cerrar el chat, consiste en borrar de la variable de sessión para que el mismo no se presente la siguiente vez abierto ,* al menos que tenga mensajes sin leer* Es una petición POST el url que contiene el ID encriptado del chat (/chat/close/:id) y la cuál se recibe en la función heartBeat.* Parámetros del route* :id = id del chat encriptado* En caso de una respuesta positiva* [* 'success' => true* ]* En caso de un respuesta negativa* [* 'success' => false,* 'data' => mensaje_de_error* ]* @return \Laminas\View\Model\JsonModel*/public function closeAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = filter_var($this->params()->fromRoute('id'), FILTER_SANITIZE_STRING);if (!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if ($chatGroup) {$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$chatGroupUserMapper->markIsClose($chatGroup->id, $currentUser->id);} else {$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if($chatUser) {if($currentUser->id == $chatUser->user_id1) {$chatUserMapper->markIsClose1($chatUser->id);} else {$chatUserMapper->markIsClose2($chatUser->id);}}}$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true]);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Clear como su nombre lo indica es borrar los mensajes entre el usuario actual y otro usuario con quien sostiene el chat* Es una petición POST el url que contiene el ID encriptado del chat (/chat/clear/:id) y la cuál se recibe en la función heartBeat.* Parámetros del route* :id = id del usuario encriptado* En caso de una respuesta positiva* [* 'success' => true,* 'data'=> (int) registros_borrados* ]* En caso de un respuesta negativa* [* 'success' => false,* 'data' => (string) 'mensaje_de_error'* ]* @return \Laminas\View\Model\JsonModel*/public function clearAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = filter_var($this->params()->fromRoute('id'), FILTER_SANITIZE_STRING);if (!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if ($chatGroup) {$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$chatGroupUserMapper->markIsClose($chatGroup->id, $currentUser->id);} else {$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if($chatUser) {if($currentUser->id == $chatUser->user_id1) {$chatUserMapper->markIsClose1($chatUser->id);} else {$chatUserMapper->markIsClose2($chatUser->id);}}}$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true]);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}/*** Marca como abierto el caht* Es una petición POST el url que contiene el ID encriptado del chat (/chat/open/:id) y la cuál se recibe en la función heartBeat.* Parámetros del route* :id = id del usuario encriptado* En caso de una respuesta positiva* [* 'success' => true,* 'data'=> (int) registros_borrados* ]* En caso de un respuesta negativa* [* 'success' => false,* 'data' => (string) 'mensaje_de_error'* ]* @return \Laminas\View\Model\JsonModel*/public function openAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = filter_var($this->params()->fromRoute('id'), FILTER_SANITIZE_STRING);if (!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if ($chatGroup) {$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$chatGroupUserMapper->markIsOpen($chatGroup->id, $currentUser->id);} else {$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if($chatUser) {if($currentUser->id == $chatUser->user_id1) {$chatUserMapper->markIsOpen1($chatUser->id);} else {$chatUserMapper->markIsOpen2($chatUser->id);}}}$userMapper->updateLastActivity($currentUser->id);return new JsonModel(['success' => true]);} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}public function uploadAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = filter_var($this->params()->fromRoute('id'), FILTER_SANITIZE_STRING);if (!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$files = $this->getRequest()->getFiles()->toArray();if(!isset($files['file']) || !empty($files['file']['error'])) {return new JsonModel(['success' => false,'data' => 'ERROR_FILE_NOT_UPLOAD']);}$tmp_filename = $files['file']['tmp_name'];if(!$this->validMimeType($tmp_filename)) {return new JsonModel(['success' => false,'data' => 'ERROR_FILE_UPLODED_IS_NOT_VALID']);}$extensions = explode('.', $files['file']['name']);$extension = strtolower(trim($extensions[count($extensions) - 1]));$filename = uniqid() . '.' . $extension;$mime_type = mime_content_type($tmp_filename);if($mime_type == 'image/jpg' || $mime_type == 'image/jpeg' || $mime_type == 'image/png') {$file_type = 'image';} else if($mime_type == 'video/webm' || $mime_type == 'video/mpeg' || $mime_type == 'video/mpg' || $mime_type == 'video/mp4') {$file_type = 'video';} else if($mime_type == 'application/pdf') {$file_type = 'document';}$userMapper = UserMapper::getInstance($this->adapter);$sender_result = $userMapper->fetchOne($currentUser->id);$sender_from = trim($sender_result->first_name . ' ' . $sender_result->last_name);$sender_pic = $this->url()->fromRoute('storage', ['code' => $sender_result->uuid,'type' => 'user','filename' => $sender_result->image]);$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if($chatGroup) {$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $chatGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$fullpath_chat = $this->config['leaderslinked.fullpath.chat'];$dirpath = $fullpath_chat . $chatGroup->uuid;if (! file_exists($dirpath)) {mkdir($dirpath, 0777, true);chmod($dirpath, 0777);}$full_filename = $dirpath . DIRECTORY_SEPARATOR . $filename;if(!move_uploaded_file($tmp_filename, $full_filename)) {return new JsonModel(['success' => false,'data' => 'ERROR_FILE_UPLOADED_NOT_MOVE']);}$chatGroupMessage = new ChatGroupMessage();$chatGroupMessage->sender_id = $currentUser->id;$chatGroupMessage->group_id = $chatGroup->id;$chatGroupMessage->content = $filename;$chatGroupMessage->type = $file_type;$chatGroupMessageMapper = ChatGroupMessageMapper::getInstance($this->adapter);$result = $chatGroupMessageMapper->insert($chatGroupMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupMessageMapper->getError()]);}$chatGroupMessage = $chatGroupMessageMapper->fetchOne($chatGroupMessage->id);$chatGroupUserMessage = new ChatGroupUserMessage();$chatGroupUserMessage->group_id = $chatGroupMessage->group_id;$chatGroupUserMessage->message_id = $chatGroupMessage->id;$chatGroupUserMessage->receiver_id = $currentUser->id;$chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_YES;$chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_YES;$chatGroupUserMessageMapper = ChatGroupUserMessageMapper::getInstance($this->adapter);$result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupUserMessageMapper->getError()]);}$chatGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$results = $chatGroupUserMapper->fetchAllByGroupId($chatGroup->id);foreach ($results as $r){if ($r->user_id != $currentUser->id) {$chatGroupUserMessage = new ChatGroupUserMessage();$chatGroupUserMessage->group_id = $chatGroupMessage->group_id;$chatGroupUserMessage->message_id = $chatGroupMessage->id;$chatGroupUserMessage->receiver_id= $r->user_id;$chatGroupUserMessage->recd = ChatGroupUserMessage::RECD_NO;$chatGroupUserMessage->seen = ChatGroupUserMessage::SEEN_NO;$result = $chatGroupUserMessageMapper->insert($chatGroupUserMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatGroupUserMessageMapper->getError()]);}}}$userMapper->updateLastActivity($currentUser->id);$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();$msgtime = Functions::timeAgo($now, $now);return new JsonModel(['success' => true,'data' => ['user_name' => $sender_from,'user_id' => $currentUser->uuid,'user_image' => $sender_pic,'u' => 1,'mtype' => $file_type,'m' => $this->url()->fromRoute('storage', ['code' => $chatGroup->uuid, 'type' => 'chat', 'filename' => $filename]),'time' => $msgtime,'id' => $chatGroupMessage->uuid]]);} else {$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$chatUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_NOT_FOUND']);}$fullpath_chat = $this->config['leaderslinked.fullpath.chat'];$dirpath = $fullpath_chat . $chatUser->uuid;if (! file_exists($dirpath)) {mkdir($dirpath, 0777, true);chmod($dirpath, 0777);}$full_filename = $dirpath . DIRECTORY_SEPARATOR . $filename;if(!move_uploaded_file($tmp_filename, $full_filename)) {return new JsonModel(['success' => false,'data' => 'ERROR_FILE_UPLOADED_NOT_MOVE']);}$chatMessage = new ChatMessage();$chatMessage->chat_id = $chatUser->id;$chatMessage->from_id = $currentUser->id;$chatMessage->to_id = $user->id;$chatMessage->content = $filename;$chatMessage->type = $file_type;$chatMessage->recd = ChatMessage::RECD_NO;$chatMessage->seen = ChatMessage::SEEN_NO;$chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);$result = $chatMessageMapper->insert($chatMessage);if(!$result) {return new JsonModel(['success' => false,'data' => $chatMessageMapper->getError()]);}$chatMessage = $chatMessageMapper->fetchOne($chatMessage->id);$userMapper->updateLastActivity($currentUser->id);$utilMapper = UtilMapper::getInstance($this->adapter);$now = $utilMapper->getDatebaseNow();$msgtime = Functions::timeAgo($chatMessage->added_on, $now);return new JsonModel(['success' => true,'data' => ['user_name' => $sender_from,'user_id' => $currentUser->uuid,'user_image' => $sender_pic,'u' => 1,'mtype' => $file_type,'m' => $this->url()->fromRoute('storage', ['code' => $currentUser->uuid, 'type' => 'chat', 'filename' => $filename]),'time' => $msgtime,'id' => $chatMessage->uuid]]);}} else {return new JsonModel(['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED']);}}public function markSeenAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = $this->params()->fromRoute('id');if (!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if($chatGroup) {$charGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $charGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$charGroupUserMessage = ChatGroupUserMessageMapper::getInstance($this->adapter);$result = $charGroupUserMessage->markAsSeenByGroupIdAndUserId($chatGroup->id, $currentUser->id);if($result) {return new JsonModel(['success' => true,]);} else {return new JsonModel(['success' => false,'data' => $charGroupUserMessage->getError()]);}} else {$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$chatUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_NOT_FOUND']);}$chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);$result = $chatMessageMapper->markAsSeenByChatIdAndToId($chatUser->id, $currentUser->id);if($result) {return new JsonModel(['success' => true,]);} else {return new JsonModel(['success' => false,'data' => $charGroupUserMessage->getError()]);}}} else {$response = ['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED'];}return new JsonModel($response);}public function markReceivedAction(){$request = $this->getRequest();if($request->isPost()) {$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$id = $this->params()->fromRoute('id');if (!$id) {return new JsonModel(['success' => false,'data' => 'ERROR_PARAMETERS_ARE_INVALID']);}$chatGroupMapper = ChatGroupMapper::getInstance($this->adapter);$chatGroup = $chatGroupMapper->fetchOneByUuid($id);if($chatGroup) {$charGroupUserMapper = ChatGroupUserMapper::getInstance($this->adapter);$chatGroupUser = $charGroupUserMapper->fetchOneByGroupIdAndUserId($chatGroup->id, $currentUser->id);if(!$chatGroupUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_GROUP_YOU_NOT_MEMBER']);}$charGroupUserMessage = ChatGroupUserMessageMapper::getInstance($this->adapter);$result = $charGroupUserMessage->markAsReceivedByGroupIdAndUserId($chatGroup->id, $currentUser->id);if($result) {return new JsonModel(['success' => true,]);} else {return new JsonModel(['success' => false,'data' => $charGroupUserMessage->getError()]);}} else {$userMapper = UserMapper::getInstance($this->adapter);$user = $userMapper->fetchOneByUuid($id);if(!$user) {return new JsonModel(['success' => false,'data' => 'ERROR_USER_NOT_FOUND']);}$chatUserMapper = ChatUserMapper::getInstance($this->adapter);$chatUser = $chatUserMapper->fetchOneByUserId1AndUserId2($currentUser->id, $user->id);if(!$chatUser) {return new JsonModel(['success' => false,'data' => 'ERROR_CHAT_NOT_FOUND']);}$chatMessageMapper = ChatMessageMapper::getInstance($this->adapter);$result = $chatMessageMapper->markAsReceivedByChatIdAndToId($chatUser->id, $currentUser->id);if($result) {return new JsonModel(['success' => true,]);} else {return new JsonModel(['success' => false,'data' => $charGroupUserMessage->getError()]);}}} else {$response = ['success' => false,'data' => 'ERROR_METHOD_NOT_ALLOWED'];}return new JsonModel($response);}/**** @param string $file* @return boolean*/private function validMimeType($file){/** image/jpeg jpeg jpg jpe* image/gif gif* image/png png* video/mp4* audio/mpeg mpga mp2 mp2a mp3 m2a m3a* video/x-flv flv* application/msword doc dot* application/vnd.openxmlformats-officedocument.wordprocessingml.document docx* application/vnd.ms-excel xls xlm xla xlc xlt xlw* application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx* application/vnd.ms-powerpoint ppt pps pot* application/vnd.openxmlformats-officedocument.presentationml.presentation pptx* application/pdf pdf*/$mime = mime_content_type($file);$valid = false;$types = ['image/jpeg','image/gif','image/png','video/mp4','audio/mpeg','video/x-flv','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/vnd.ms-excel','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','application/vnd.ms-powerpoint','application/vnd.openxmlformats-officedocument.presentationml.presentation','application/pdf'];foreach ($types as $t) {if (strpos($mime, $t) !== false) {$valid = true;break;}}return $valid;}/**** @param string $text* @return string*/private function sanitize($text){$text = htmlspecialchars($text, ENT_QUOTES);$text = str_replace("\n\r", "\n", $text);$text = str_replace("\r\n", "\n", $text);$text = str_replace("\n", "<br>", $text);return $text;}/**** @param string $timestamp* @param string $now* @return string*/private function timeAgo($timestamp, $now = ''){if($now) {$datetime1 = \DateTime::createFromFormat('Y-m-d H:i:s', $now);} else {$now = date('Y-m-d H:i:s');$datetime1 = date_create($now);}$datetime2 = date_create($timestamp);$diff = date_diff($datetime1, $datetime2);$timemsg = '';if ($diff->y > 0) {$timemsg = $diff->y . ' año' . ($diff->y > 1 ? "s" : '');} else if ($diff->m > 0) {$timemsg = $diff->m . ' mes' . ($diff->m > 1 ? "es" : '');} else if ($diff->d > 0) {$timemsg = $diff->d . ' dia' . ($diff->d > 1 ? "s" : '');} else if ($diff->h > 0) {$timemsg = $diff->h . ' hora' . ($diff->h > 1 ? "s" : '');} else if ($diff->i > 0) {$timemsg = $diff->i . ' minuto' . ($diff->i > 1 ? "s" : '');} else if ($diff->s > 0) {$timemsg = $diff->s . ' segundo' . ($diff->s > 1 ? "s" : '');}if (!$timemsg) {$timemsg = "Ahora";} else {$timemsg = $timemsg . '';}return $timemsg;}/**** @param string $timestamp* @param string $now* @return boolean*/private function isInactiveConnection($timestamp, $now = ''){if($now) {$datetime1 = \DateTime::createFromFormat('Y-m-d H:i:s', $now);} else {$now = date('Y-m-d H:i:s');$datetime1 = date_create($now);}if (empty($timestamp)) {return true;}$datetime2 = date_create($timestamp);$diff = date_diff($datetime1, $datetime2);if ($diff->y > 0 || $diff->m > 0 || $diff->d > 0 || $diff->h > 0 || $diff->i > 0) {return true;}return ($diff->s) > 15 ? true : false;}}