db = $db; $this->user = $user; $this->config = $config; //Set the codes and labels array $this->requestStatusLabels = [self::REQUEST_STATUS_PENDING=>_('Sending'), self::REQUEST_STATUS_DRAFT=>_('Draft'), self::REQUEST_STATUS_OPENED=>_('Opened'), self::REQUEST_STATUS_PART_REPORTED=>_('Partially answered'), self::REQUEST_STATUS_REPORTED=>_('Answered'), self::REQUEST_STATUS_REOPENED=>_('Reopened')]; $this->statusNumbers = ['pending'=>-1, 'draft'=>5, 'opened'=>1, '! referted'=>2, 'reopened'=>3, 'referted'=>4]; $this->activityCodes = [ 'USR_LOGGED_IN' => _('User %s logged in (regular login).'), 'USR_AUTO_LOGGED_IN' => _('User %s logged in (auto-login).'), 'USR_LOGIN_FAILED' => _('User %s login failed (regular login).'), 'USR_AUTO_LOGIN_FAILED' => _('User %s login failed (auto-login).'), 'REQ_LISTED' => _('Requests listed by the user %s.'), 'REQ_NEW' => _('Opened new Request for writing by the user %s.'), 'REQ_EDITED' => _('Opened draft Request #%s for editing by the user %s.'), 'REQ_VIEW' => _('Opened Request #%s for reading by the user %s.'), 'REQ_SAVED_DRAFT' => _('Saved Request #%s as draft by the user %s.'), 'REQ_SENT' => _('Sent new Request #%s by the user %s.'), 'REQ_FILE_ADDED' => _('File %s attached to the Request #%s by the user %s.'), 'REQ_DELETED' => _('Request #%s deleted by the user %s.'), 'REQ_FWD' => _('Added new specialties to the Request #%s by the user %s.'), 'REQ_MSG' => _('New message added to the Request #%s by the user %s.'), 'REQ_STATUS_CNG_MODERATOR' => _('Status of the Request #%s changed to %s by the Moderator.') ]; } public function isUserTheAuthor($requestID=0, $userID=0) { $result = $this->db ->where('r.id', $requestID) ->where('r.user_id', $userID) ->get('requests r'); return is_array($result) && !empty($result) ? true : false; } public function isUserModerator($requestCenterID=0, $clinicalCenters=[], $userID=0) { return isset($clinicalCenters[$requestCenterID]) ? true : false; } public function isUserReferrer($requestID=0, $userID=0) { $result = $this->db ->where('rr.request_id', $requestID) ->where('rr.user_id', $userID) ->get('requests_recipients rr'); return is_array($result) && !empty($result) ? true : false; } //Check whether the provided user is a referral in the provided request public function isReferralInRequest($requestID=0, $userID=0) { $recipients = $this->db ->where('rr.request_id', $requestID) ->where('rr.user_id', $userID) ->get('requests_recipients rr'); return count($recipients) > 0 ? true : false; } public function isApplicantInRequest($requestID=0, $userID=0) { $request = $this->db ->where('id', $requestID) ->getOne('requests r', 'r.user_id'); return isset($request['user_id']) && (int)$request['user_id'] == (int)$userID ? true : false; } public function getSpecialtyByClinicalCenterId($ccId=0, $groupId=0) { $specialties = []; /*if ($ccId > 0) { $results = $this->db ->where('ccmst.center_id', $ccId) ->join('users_medical_specialties ums', 'ums.id=ccmst.specialty_id', 'INNER') ->orderBy('ums.description', 'asc') ->get('clinical_center_medical_specialties_to ccmst', null, ['ums.id', 'ums.description']); } else { $results = $this->db ->orderBy('ums.description', 'asc') ->get('users_medical_specialties ums', null, ['ums.id', 'ums.description']); }*/ //All Medical Specialties if ($ccId > 0) { $results = $this->db ->where('ccmst.center_id', $ccId) ->where('urt.role_id', REFERRER_ROLE_ID) ->where('u.group_id', $groupId) ->where('u.status', 1) ->join('users_medical_specialties ums', 'ums.id=ccmst.specialty_id', 'INNER') ->join('users_medical_specialties_to umst', 'umst.specialty_id=ums.id', 'INNER') ->join('users u', 'u.id=umst.user_id', 'INNER') ->join('users_roles_to urt', 'urt.user_id=u.id', 'INNER') ->groupBy('ums.id') ->orderBy('ums.description', 'asc') ->get('clinical_center_medical_specialties_to ccmst', null, ['ums.id', 'ums.description']); } else { $results = $this->db ->where('urt.role_id', REFERRER_ROLE_ID) ->where('u.group_id', $groupId) ->where('u.status', 1) ->join('users_medical_specialties_to umst', 'umst.specialty_id=ums.id', 'INNER') ->join('users u', 'u.id=umst.user_id', 'INNER') ->join('users_roles_to urt', 'urt.user_id=u.id', 'INNER') ->groupBy('ums.id') ->orderBy('ums.description', 'asc') ->get('users_medical_specialties ums', null, ['ums.id', 'ums.description']); } if (is_array($results)) { foreach($results as $item) { $specialties[$item['id']]['id'] = $item['id']; $specialties[$item['id']]['description'] = _($item['description']); } } return $specialties; } public function getRecipientsByRequestId($requestId=0) { $recipients = $this->db ->where('rr.request_id', $requestId) ->join('users u', 'u.id=rr.user_id', 'INNER') ->orderBy('u.surname', 'ASC') ->get('requests_recipients rr', null, ['u.name', 'u.surname', "(SELECT GROUP_CONCAT(ms.description SEPARATOR '|') FROM users_medical_specialties_to umst JOIN users_medical_specialties ms ON ms.id=umst.specialty_id WHERE umst.user_id=u.id ORDER BY ms.description) AS ms_list"]); if(is_array($recipients)) { foreach($recipients as $index => $recipient) { $ms = $recipient['ms_list']; if (strpos($ms, '|') !== false) { $temp = explode('|', $ms); $tempArr = []; foreach($temp as $item) { $tempArr[] = _($item); } $recipients[$index]['ms_list'] = implode(', ', $tempArr); } else { $recipients[$index]['ms_list'] = _($ms); } } } return $recipients; } public function getRecipients($params=[]) { $referralMs = isset($params['ms']) ? $params['ms'] : []; //Medical Specialty $referralCc = isset($params['cc']) ? $params['cc'] : []; //Clinical Center $referralLangs = isset($params['langs']) ? $params['langs'] : []; $recipientList = isset($params['recipientList']) ? $params['recipientList'] : []; $groupId = isset($params['groupId']) ? $params['groupId'] : 0; $arrayLangs = []; foreach($referralLangs as $lang) { $arrayLangs[] = $lang; } if (is_array($recipientList) && !empty($recipientList)) { return $this->db ->where('ucct.role_id', REFERRER_ROLE_ID) ->where('u.id IN('.implode(',', $recipientList).')') ->where('u.group_id', $groupId) ->where('u.status', 1) ->join('users u', 'u.id=ucct.user_id', 'INNER') ->orderBy('u.surname', 'asc') ->get('users_clinical_centers_to ucct', null, [ 'u.id user_id', 'u.surname', 'u.name', 'ucct.user_id', "(SELECT GROUP_CONCAT(ms.description SEPARATOR ', ') FROM users_medical_specialties_to umst JOIN users_medical_specialties ms ON ms.id=umst.specialty_id WHERE umst.user_id=u.id ORDER BY ms.description) AS ms_list", "(SELECT GROUP_CONCAT(cc.description SEPARATOR ', ') FROM users_clinical_centers_to ucct JOIN clinical_centers cc ON cc.id=ucct.center_id WHERE ucct.user_id=u.id AND ucct.role_id=".REFERRER_ROLE_ID." ORDER BY cc.description) AS cc_list" ]); } else { if (!empty($referralCc)) { $this->db->where("ucct.center_id IN(".implode(',', $referralCc).")"); } if (!empty($referralMs) && !empty($referralLangs)) { $results = $this->db ->where('ucct.role_id', REFERRER_ROLE_ID) //->where("u.language_default IN($langList)") ->where('u.status', 1) ->where('u.group_id', $groupId) ->join('users u', 'u.id=ucct.user_id', 'INNER') ->having('ms_total', 0, '>') ->orderBy('u.surname', 'asc') ->get('users_clinical_centers_to ucct', null, [ 'u.id user_id', 'u.surname', 'u.name', 'u.language_default', 'ucct.user_id', "(SELECT COUNT(*) FROM users_medical_specialties_to umst WHERE umst.specialty_id IN(".implode(',', $referralMs).") AND umst.user_id=ucct.user_id) ms_total", "(SELECT GROUP_CONCAT(ms.description SEPARATOR ', ') FROM users_medical_specialties_to umst JOIN users_medical_specialties ms ON ms.id=umst.specialty_id WHERE umst.user_id=u.id ORDER BY ms.description) AS ms_list", "(SELECT GROUP_CONCAT(cc.description SEPARATOR ', ') FROM users_clinical_centers_to ucct JOIN clinical_centers cc ON cc.id=ucct.center_id WHERE ucct.user_id=u.id AND ucct.role_id=".REFERRER_ROLE_ID." ORDER BY cc.description) AS cc_list", "(SELECT GROUP_CONCAT(ult.language_id) FROM users_languages_to ult WHERE ult.user_id=u.id) AS user_alt_langs" ]); //Check the languages $recipients = []; if (is_array($results)) { /*foreach($results as $result) { $checkLangsList = !empty($result['user_alt_langs']) ? $result['user_alt_langs'].','.$result['language_default'] : $result['language_default']; $checkLangs = explode(',', $checkLangsList); foreach($arrayLangs as $lng) { if (in_array($lng, $checkLangs)) { $recipients[] = $result; } } } return $recipients; */ return $results; } } } return false; } //public function forwardRequest($requestID=0, $formSpecialtyList=[], $groupId=0, $senderId=0, $centerId=0) { public function forwardRequest($requestID=0, $newSpecialties=[], $groupId=0, $senderId=0, $centerId=0) { //if (empty($formSpecialtyList)) return false; if (!is_array($newSpecialties)) return false; if (count($newSpecialties) < 1) return false; $isForward = false; /*$requestSpecialties = $this->db ->where('rmst.request_id', $requestID) ->getOne('requests_medical_specialties_to rmst', "GROUP_CONCAT(rmst.specialty_id) specialty_comma_list"); $specialtyList = explode(',', $requestSpecialties['specialty_comma_list']); //Moderator or Referral has added a specialty $newSpecialties = []; $referrals = []; if(count($formSpecialtyList) > count($specialtyList)) { foreach($formSpecialtyList as $formSpecialty) { if (!in_array($formSpecialty, $specialtyList)) { $newSpecialties[$formSpecialty] = $formSpecialty; } } */ //if (!empty($newSpecialties)) { $referrals = $this->db ->where("umst.specialty_id IN(".implode(',', $newSpecialties).")") ->where('u.group_id', $groupId) ->where('u.status', 1) ->having('centers', 0, '>') ->join('users u', 'u.id=umst.user_id', 'INNER') ->get('users_medical_specialties_to umst', null, ['umst.user_id', "(SELECT COUNT(*) FROM users_clinical_centers_to ucct WHERE ucct.user_id=u.id AND ucct.role_id=".REFERRER_ROLE_ID." AND ucct.center_id=$centerId) centers"]); //Add these user to the recipient list if (is_array($referrals) && !empty($referrals)) { $isForward = true; //Add the new specialty foreach($newSpecialties as $newSpecialty) { $this->db->insert('requests_medical_specialties_to', ['request_id'=>$requestID, 'specialty_id'=>$newSpecialty]); } foreach($referrals as $referral) { $this->db->insert('requests_recipients', ['request_id'=>$requestID, 'user_id'=>$referral['user_id']]); $this->queueMessage($requestID, $referral['user_id'], $senderId, 'NEW_FWD_REQUEST'); } $this->setActivityLog($this->user->getUserId(), 'REQ_FWD', ['userId'=>$this->user->getUserId(), 'requestId'=>$requestID]); } //} //} return $isForward; //return $this->db->getLastQuery(); } public function setRequestProgress($requestID=0, $userID=0) { $request = $this->db->where('id', $requestID)->getOne('requests'); } public function incrementReferralCounter($requestID=0, $userID=0) { if ($this->isReferralInRequest($requestID, $userID)) { $specialtyList = []; $specialties = $this->db ->where('umst.user_id', $userID) ->get('users_medical_specialties_to umst', null, ['umst.specialty_id']); if (is_array($specialties) && !empty($specialties)) { foreach($specialties as $specialty) { $specialtyList[] = $specialty['specialty_id']; } //Sort the array to always get the same comma separated list sort($specialtyList); } return $this->db->insert('request_reports_counter', ['request_id'=>$requestID, 'referral_id'=>$userID, 'referral_specialties'=>implode(',', $specialtyList)]); } return false; } public function cleanReferralCounter($requestID=0) { return $this->db->where('request_id', $requestID)->delete('request_reports_counter'); } public function isRequestFullyReported($requestID=0) { //Request spcialties $specialties = $this->db ->where('rmst.request_id', $requestID) ->get('requests_medical_specialties_to rmst', null, ['rmst.specialty_id']); $specialtyList = []; if (is_array($specialties) && !empty($specialties)) { //Flat the specialties in a one dimensional array foreach($specialties as $specialty) { $specialtyList[] = $specialty['specialty_id']; } $specialtyList = array_unique($specialtyList); sort($specialtyList); //Get all answers $comments = $this->db ->where('rc.request_id', $requestID) ->get('requests_comments rc'); //Array of specialties for each responders $msPerResponders = []; //Get all medical specialties for each responders if (is_array($comments) && !empty($comments)) { foreach($comments as $comment) { $ms = $this->db ->where('umst.user_id', $comment['user_id']) ->get('users_medical_specialties_to umst'); if (is_array($ms)) { //Flat the medical specialties in a one dimensional array with no duplicates foreach($ms as $item) { if (in_array($item['specialty_id'], $specialtyList)) { $msPerResponders[$item['specialty_id']] = $item['specialty_id']; } } $msPerResponders = array_unique($msPerResponders); sort($msPerResponders); } } $diff = array_diff($specialtyList, $msPerResponders); return empty($diff) ? true : -2; } return 0; } else { return -1; } } public function setLog($logName='', $output=null) { file_put_contents(BASE_ROOT.'log/'.$logName.'.log', $output."\n", FILE_APPEND); } public function setActivityLog($userId=0, $activityCode='', $params=[]) { return; $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $requestId = $params['requestId'] ?? 0; $this->db->insert('log_activities', ['user_id'=>$userId, 'request_id'=>$requestId, 'user_agent'=>$userAgent, 'activity_code'=>$activityCode, 'activity_params'=>json_encode($params), 'created_at'=>date('Y-m-d H:i:s')]); } public function setRequestStatus($requestID=0, $statusCode='', $userId=0) { $statusNumber = isset($this->statusNumbers[$statusCode]) ? $this->statusNumbers[$statusCode] : -1; if ($this->db->where('id', $requestID)->update('requests', ['request_status'=>$statusCode, 'request_status_number'=>$statusNumber])) { return $this->setStatusHistory($requestID, $statusCode, $userId); } return false; } public function filterActivityLog($activityCode='', $params=[]) { $userData = isset($params['userId']) ? $this->user->getUserDB($params['userId']) : null; $userString = !empty($userData) && is_array($userData) ? $userData['surname'].' '.$userData['name'] : 'n/d'; $requestId = $params['requestId'] ?? 'n/d'; $fileTitle = $params['fileTitle'] ?? 'n/d'; $newStatus = $params['newStatus'] ?? 'n/d'; switch($activityCode) { case 'USR_LOGGED_IN': case 'USR_AUTO_LOGGED_IN': case 'USR_LOGIN_FAILED': case 'USR_AUTO_LOGIN_FAILED': case 'REQ_LISTED': case 'REQ_NEW': return vsprintf($this->activityCodes[$activityCode], [$userString]); break; case 'REQ_EDITED': case 'REQ_VIEW': case 'REQ_SAVED_DRAFT': case 'REQ_SENT': case 'REQ_DELETED': case 'REQ_FWD': case 'REQ_MSG': return vsprintf($this->activityCodes[$activityCode], [$requestId, $userString]); break; case 'REQ_FILE_ADDED': return vsprintf($this->activityCodes[$activityCode], [$fileTitle, $requestId, $userString]); break; case 'REQ_STATUS_CNG_MODERATOR': return vsprintf($this->activityCodes[$activityCode], [$requestId, $newStatus]); break; } } public function getActivityLogList($params=[]) { return; $userId = (int)$params['userId'] ?? 0; $requestId = (int)$params['requestId'] ?? 0; $dateFrom = $params['dateFrom'] ?? null; $dateTo = $params['dateTo'] ?? null; $logList = []; if ($userId > 0) { $this->db->where('user_id', $userId); } if ($requestId > 0) { $this->db->where('request_id', $requestId); } if (!is_null($dateFrom)) { $this->db->where("created_at >= '$dateFrom'"); } if (!is_null($dateTo)) { $this->db->where("created_at <= '$dateTo'"); } $results = $this->db->get('log_activities'); if (is_array($results) && !empty($results)) { foreach($results as $result) { $logRow = $this->filterActivityLog($result['activity_code'], json_decode($result['activity_params'], true)); if ($logRow != '') $logList[] = $result['created_at'].' > '.$logRow; } } return $logList; } public function setStatusHistory($requestID=0, $statusCode='', $userId=0) { $this->updateDate($requestID); return $this->db->insert('requests_statuses_history', ['request_id'=>$requestID, 'user_id'=>$userId, 'status_code'=>$statusCode, 'created_at'=>date('Y-m-d H:i:s')]); } public function getCommentList($requestID=0, $ccID=0, $checkCC=true) { $groupedComments = []; $positions = []; //$userIsAuthor = $this->isUserTheAuthor($requestID, $this->user->getUserId()); $comments = $this->db ->where('rc.request_id', $requestID) ->where('rc.is_visible', 1) ->join('users u', 'u.id=rc.user_id', 'INNER') ->orderBy('rc.created_at', 'asc') ->get('requests_comments rc', null, ['rc.*', 'u.name user_name', 'u.surname user_surname', 'u.remarks_public', 'u.updated_at user_updated_at', "(SELECT GROUP_CONCAT(ums.description SEPARATOR '|') FROM users_medical_specialties_to umst INNER JOIN users_medical_specialties ums ON ums.id=umst.specialty_id WHERE umst.user_id=rc.user_id ORDER BY ums.description ASC) medspec_list", "(SELECT GROUP_CONCAT(cc.description SEPARATOR ', ') FROM users_clinical_centers_to ucct JOIN clinical_centers cc ON cc.id=ucct.center_id WHERE ucct.role_id=".REFERRER_ROLE_ID." AND ucct.user_id=rc.user_id ORDER BY cc.description ASC) cc_list", "(SELECT GROUP_CONCAT(ucct.center_id SEPARATOR '|') FROM users_clinical_centers_to ucct WHERE ucct.role_id=".MODERATOR_ROLE_ID." AND ucct.user_id=rc.user_id) cc_list_moderator", "(SELECT GROUP_CONCAT(sub_urt.role_id SEPARATOR '|') FROM users_roles_to sub_urt WHERE sub_urt.user_id=rc.user_id) user_roles"] ); if (is_array($comments)) { $prvUserId = 0; $prvPosition = 'left'; foreach($comments as $index => $comment) { $comments[$index]['show_meta'] = false; $comments[$index]['show_specialties'] = false; //Default value $comments[$index]['is_responder'] = false; $comments[$index]['is_the_author'] = false; //Translate a stringify the Medical Specialties list $medSpecialties = strpos($comments[$index]['medspec_list'], '|') !== false ? explode('|', $comments[$index]['medspec_list']) : [$comments[$index]['medspec_list']]; if (is_array($medSpecialties) && !empty($medSpecialties)) { foreach($medSpecialties as $i => $ms) { $medSpecialties[$i] = _($ms); } $comments[$index]['medspec_list'] = implode(', ', $medSpecialties); } else { $comments[$index]['medspec_list'] = !is_null($medSpecialties) ? _($medSpecialties) : ''; } //Set the (chat) balloon position if ($prvUserId > 0 && $prvUserId !== $comment['user_id']) { if ($prvPosition == 'left') { $comments[$index]['position'] = 'right'; $prvPosition = 'right'; } else { $comments[$index]['position'] = 'left'; $prvPosition = 'left'; } $comments[$index]['show_meta'] = true; } else { $comments[$index]['position'] = $prvPosition; //Default if ($prvUserId == 0) $comments[$index]['show_meta'] = true; //Default } $prvUserId = $comment['user_id']; //Check whether this user is a moderator in the current clinical center or just check whether the user is a moderator or isn't if ($checkCC) { //Clinical centers in whitch the user is a moderator $ccModerator = explode('|', $comment['cc_list_moderator']); //Compare the current Clinical Center ID against the previouses ($ccModerator) if (in_array($ccID, $ccModerator)) { $comments[$index]['is_moderator'] = true; } else { $comments[$index]['is_moderator'] = false; } } else { $comments[$index]['is_moderator'] = false; } //Is Referral (show the Medical Specialties) if (in_array(REFERRER_ROLE_ID, explode('|', $comment['user_roles']))) { $comments[$index]['show_specialties'] = true; $comments[$index]['is_responder'] = true; } //If Moderator, overwrite the possible previouse value if ($comments[$index]['is_moderator']) { $comments[$index]['show_specialties'] = false; } $userIsAuthor = $this->isUserTheAuthor($requestID, $comments[$index]['user_id']); //If Author, overwrite the possible previouse values if ($userIsAuthor) { $comments[$index]['show_specialties'] = false; $comments[$index]['is_moderator'] = false; //Overwrite the previouse value $comments[$index]['is_the_author'] = $userIsAuthor; } $comments[$index]['request_cc'] = $ccID; $comments[$index]['attachments'] = $this->getAttachmentsByRequestId($requestID, $comment['id']); $tUserId = $comment['user_id']; } } return $comments; } public function getAttachmentsByRequestId($requestID=0, $commentID=0) { $this->db->where('ra.request_id', $requestID); if ($commentID > 0) { $this->db->where('ra.comment_id', $commentID); } $attachments = $this->db->join('users u', 'u.id=ra.user_id', 'left') ->orderBy('ra.created_at', 'desc') ->get('requests_attachments ra', null, ['ra.*', 'u.name', 'u.surname']); return $attachments; } public function updateDate($requestID=0) { return $this->db->where('id', $requestID)->update('requests', ['updated_at'=>date('Y-m-d H:i:s')]); } public function deleteRequest($requestId=0) { $request = $this->db->where('id', $requestId)->delete('requests'); $attachments = $this->db->where('request_id', $requestId)->delete('requests_attachments'); $comments = $this->db->where('request_id', $requestId)->delete('requests_comments'); $languages = $this->db->where('request_id', $requestId)->delete('requests_languages_to'); $specialties = $this->db->where('request_id', $requestId)->delete('requests_medical_specialties_to'); $notifications = $this->db->where('request_id', $requestId)->where('sent_status', 0)->delete('requests_messages_queue'); $recipients = $this->db->where('request_id', $requestId)->delete('requests_recipients'); $registry = $this->db->where('request_id', $requestId)->delete('requests_registry'); $statusHistory = $this->db->where('request_id', $requestId)->delete('requests_statuses_history'); $symptoms = $this->db->where('request_id', $requestId)->delete('requests_symptoms_to'); $wizards = $this->db->where('request_id', $requestId)->delete('requests_wizards_to'); $wizardDermaPositions = $this->db->where('request_id', $requestId)->delete('requests_wizard_derma_position_to'); $reportCounter = $this->db->where('request_id', $requestId)->delete('request_reports_counter'); $centers = $this->db->where('request_id', $requestId)->delete('request_clinical_centers_to'); //TODO: delete attachment files return $request; } public function updateUserToken($userId=0, $uniqueId=null) { $expireDays = $this->config['settings']['autologin-expire-days']; $expireDate = date('Y-m-d 00:00:00', strtotime("+$expireDays days", time())); $returnUniqueId = null; $check = $this->db->where('id', $userId)->getOne('users', 'autologin_token, autologin_expires_at'); $this->db->where('id', $userId); if (!empty($check['autologin_expires_at'])) { $this->db->where("DATEDIFF(NOW(), autologin_expires_at) > $expireDays"); } $this->db->update('users', ['autologin_token'=>$uniqueId, 'autologin_expires_at'=>$expireDate]); if ($this->db->count > 0) { $returnUniqueId = $uniqueId; } else { $returnUniqueId = $check['autologin_token']; } return $returnUniqueId; } public function getStatistics($field='triage_color', $roleId=0, $controller=null) { $returnData = []; $count = 0; $labels = []; $values = []; $perc = []; $colors = []; $borders = []; $colorList = ['white'=>'rgba(255, 255, 255, 1)', 'green'=>'rgba(36, 167, 83, 1)', 'yellow'=>'rgba(255, 192, 67, 1)', 'red'=>'rgba(221, 51, 72, 1)', '! referted'=>'rgba(255, 192, 67, 1)', 'referted'=>'rgba(36, 167, 83, 1)', 'pending'=>'rgba(227, 227, 227, 1)', 'opened'=>'rgba(108, 117, 124, 1)', 'reopened'=>'rgba(221, 51, 72, 1)', 'draft'=>'rgba(165, 165, 165, 1)']; $borderList = ['white'=>'rgba(0, 0, 0, 0.2)', 'green'=>'rgba(36, 167, 83, 1)', 'yellow'=>'rgba(255, 192, 67, 1)', 'red'=>'rgba(221, 51, 72, 1)']; switch ($roleId) { case ADMIN_ROLE_ID: $this->db->where('r.group_id', $controller->userGroupId); break; case MODERATOR_ROLE_ID: case REFERRER_ROLE_ID: case GUEST_ROLE_ID: $clinicalCenters = $controller->getUserClinicalCenters($this->user->getUserId(), $roleId); //In mainController $ccIds = array_keys($clinicalCenters); $this->db->where('r.center_id', $ccIds, 'IN'); if ($field != 'triage_color') { $this->db->where('r.request_status', ['opened', 'reopened', '! referted', 'referted'], 'IN'); } break; //Applicant default: $this->db->where('r.user_id', $this->user->getUserId()); } $this->db->where('r.request_visibility', 'all'); if ($field == 'triage_color') { $this->db->where('r.request_status', ['opened', 'reopened', '! referted'], 'IN'); $this->db->groupBy('r.triage_color'); $results = $this->db->get('requests r', null, ['COUNT(*) total', 'r.triage_color']); } if ($field == 'request_status') { $this->db->groupBy('r.request_status'); $results = $this->db->get('requests r', null, ['COUNT(*) total', 'r.request_status']); } if (is_array($results)) { foreach($results as $index => $item) { $count = $count+$item['total']; $labels[$index] = _(ucfirst($item[$field])) ?? null; $labelsValues[$index] = _(ucfirst($item[$field])).' ('.$item['total'].')' ?? null; $values[$index] = $item['total']; $colors[$index] = $colorList[$item[$field]]; $borders[$index] = $borderList[$item[$field]] ?? null; } foreach($results as $index => $item) { //$results[$index]['perc'] = round($item['total']*100/$count); $perc[$index] = number_format($item['total']*100/$count, 1); $labelsPerc[$index] = _(ucfirst($item[$field])).' ('.$perc[$index].'%)' ?? null; } } $returnData['labels'] = $labels; $returnData['labelsValues'] = $labelsValues; $returnData['labelsPerc'] = $labelsPerc; $returnData['colors'] = $colors; $returnData['borders'] = $borders; $returnData['values'] = $values; $returnData['perc'] = $perc; $returnData['query'] = $this->db->getLastQuery(); return $returnData; } public function getDataForMessageQueue($requestID=0, $recipientID=0, $senderID=0, $msgCode='') { $currentLocale = setlocale(LC_ALL, 0); $supportedLocales = $this->config['settings']['supported-locales']; $request = $this->db ->where('r.id', $requestID) ->join('clinical_centers cc', 'cc.id=r.center_id', 'INNER') ->join('continents cnt', 'cnt.code=cc.continent_code', 'INNER') ->join('countries cntr', 'cntr.country_iso2_code=cc.country_code', 'INNER') ->getOne('requests r', "r.id request_id, r.triage_color, (SELECT GROUP_CONCAT(rlt.language_code) FROM requests_languages_to rlt WHERE rlt.request_id=r.id) request_lang_list, (SELECT GROUP_CONCAT(ums.description SEPARATOR ', ') FROM requests_medical_specialties_to rmst JOIN users_medical_specialties ums ON ums.id=rmst.specialty_id WHERE rmst.request_id=r.id) specialties, cc.description cc_name, cntr.country_name, cnt.name continent_name"); $sender = $this->db ->where('u.id', $senderID) ->getOne('users u'); $recipient = $this->db ->where('u.id', $recipientID) ->getOne('users u'); $recipientLang = isset($recipient['language_default']) ? $recipient['language_default'] : 'en'; $recipientLocale = isset($supportedLocales[$recipientLang]) ? $supportedLocales[$recipientLang] : 'en_US'; setlocale(LC_ALL, $recipientLocale); $langList = $this->stringifyLangCodes($request['request_lang_list']); $specialtyList = $this->translateSpecialties($request['specialties']); $newUniqueId = uniqid(); $uniqueId = $this->updateUserToken($recipient['id'], $newUniqueId); $siteLink = $this->config['settings']['http-protocol'].$this->config['settings']['site-domain'].'/#/auto-login/'.$uniqueId.'/'.$request['request_id']; $msgData = $this->getLocalisedMsgData($msgCode, $recipient['language_default']); $subject = $msgData['msg_object']; $body = $this->replaceMsgPlaceholders($msgData['msg_body'], $msgCode, [ 'specialtyList' => $specialtyList, 'code' => _(ucfirst($request['triage_color'])), 'langList' => $langList, 'requestId' => $request['request_id'], 'center' => $request['cc_name'].' ('.$request['country_name'].', '.$request['continent_name'].')', 'siteLink' => $siteLink ] ); $mailID = uniqid(); $mailHTML = $this->getMessageTemplate('Email/template', ['mailID'=>$mailID, 'body'=>nl2br($body), 'showTemplate'=>true]); $queueEmailData = [ 'senderId' => $senderID, 'recipientId' => $recipient['id'], 'requestId' => $requestID, 'mailId' => $mailID, 'subject' => $subject, 'content' => $mailHTML, 'type' => 'email', 'recipient' => $recipient['email'], 'senderStatus' => $sender['status'] ]; if ($recipient['language_default'] == 'it') { $sms_body = 'Controlla la richiesta #'.$request['request_id'].', clicca '.$siteLink; } else { $sms_body = 'Check request #'.$request['request_id'].', click '.$siteLink; } $queueSMSData = [ 'senderId' => $senderID, 'recipientId' => $recipient['id'], 'requestId' => $requestID, 'mailId' => '', 'subject' => '', 'content' => $sms_body, 'type' => 'sms', 'recipient' => $recipient['mobile_number'], 'senderStatus' => $sender['status'] ]; setlocale(LC_ALL, $currentLocale); return ['email'=>$queueEmailData, 'sms'=>$queueSMSData]; } public function notifyAllReferrals($requestID=0, $msgCode='', $sendSMS=true) { $request = $this->db ->where('r.id', $requestID) ->getOne('requests r', "r.id request_id, r.user_id applicant_id, (SELECT GROUP_CONCAT(rr.user_id) FROM requests_recipients rr WHERE rr.request_id=r.id) recipients_comma_list"); $recipientIds = []; if (isset($request['recipients_comma_list'])) { $recipientIds = explode(',', $request['recipients_comma_list']); } $returns = []; if (is_array($recipientIds) && !empty($recipientIds)) { foreach($recipientIds as $recipientId) { $returns[] = $this->queueMessage($requestID, $recipientId, $request['applicant_id'], $msgCode, $sendSMS); } } return $returns; } public function queueMessage($requestID=0, $recipientID=0, $senderID=0, $msgCode='', $sendSMS=true) { $msgStructure = $this->getDataForMessageQueue($requestID, $recipientID, $senderID, $msgCode); $this->insertMsgInQueue($msgStructure['email']); if ($sendSMS) $this->insertMsgInQueue($msgStructure['sms']); return $msgStructure; } public function getMessageTemplate($path, $params=[]) { if (!empty($params)) extract($params); ob_start(); include VIEWS_DIR.'Elements/Message/'.$path.'.part.php'; $content = ob_get_clean(); return $content; } public function getOpenedRequestsToNofify() { $groupedById = []; $recipients = $this->db ->where('r.request_status', self::REQUEST_STATUS_OPENED) ->where('r.opened_sent', 0) ->join('requests r', 'r.id=rr.request_id', 'INNER') ->join('users u', 'u.id=rr.user_id', 'INNER') ->join('clinical_centers cc', 'cc.id=r.center_id', 'INNER') ->join('continents cnt', 'cnt.code=cc.continent_code', 'INNER') ->join('countries cntr', 'cntr.country_iso2_code=cc.country_code', 'INNER') ->get('requests_recipients rr', null, [ 'r.id request_id', 'r.user_id applicant_id', 'rr.user_id recipient_id', 'r.triage_color', 'u.id recipient_id', 'u.name', 'u.surname', 'u.language_default', 'u.email', 'u.mobile_number', 'u.mobile_number_chat', 'u.allow_phone_text', 'u.allow_phone_chat', 'u.allow_email_msgs', 'cc.description cc_name', 'cntr.country_name', 'cnt.name continent_name', "(SELECT applicant_tb.status FROM users applicant_tb WHERE applicant_tb.id=r.user_id) applicant_status", "(SELECT applicant_ltb.language_default FROM users applicant_ltb WHERE applicant_ltb.id=r.user_id) applicant_lang", "(SELECT applicant_emtb.email FROM users applicant_emtb WHERE applicant_emtb.id=r.user_id) applicant_email", "(SELECT applicant_phtb.mobile_number FROM users applicant_phtb WHERE applicant_phtb.id=r.user_id) applicant_phone", "(SELECT GROUP_CONCAT(ums.description SEPARATOR ', ') FROM requests_medical_specialties_to rmst JOIN users_medical_specialties ums ON ums.id=rmst.specialty_id WHERE rmst.request_id=rr.request_id) specialties", "(SELECT GROUP_CONCAT(rlt.language_code) FROM requests_languages_to rlt WHERE rlt.request_id=rr.request_id) request_lang_list" ]); //Group by request id if (is_array($recipients)) { foreach($recipients as $recipient) { $groupedById[$recipient['request_id']][] = $recipient; } } return $groupedById; } public function getLocalisedMsgData($msg_code='', $lang='', $msg_type='') { $searchLang = $lang != 'en' ? ['en', $lang] : ['en']; $this->db->where('rmt.msg_code', $msg_code); $this->db->where('rmt.lang_code', $searchLang, 'IN'); if ($msg_type != '') { $this->db->where('rmt.msg_type', $msg_type); } $results = $this->db->get('requests_messages_text rmt'); $msg = []; if (is_array($results)) { foreach($results as $result) { if ($result['lang_code'] == $lang) { $msg = $result; break; } } if (empty($msg)) { foreach($results as $result) { if ($result['lang_code'] == 'en') { $msg = $result; break; } } } } return $msg; } public function isRequestPreviouslyReopened($requestID=0) { $history = $this->db ->where('rsh.request_id', $requestID) ->where('rsh.status_code', 'reopened') ->getOne('requests_statuses_history rsh', "COUNT(*) AS counter"); return isset($history['counter']) && (int)$history['counter'] > 0 ? true : false; } public function translateSpecialties($commaList='') { $list = explode(',', $commaList); $specialties = []; $stringSpecialties = ''; if (is_array($list)) { foreach($list as $item) { $specialties[] = _($item); } $stringSpecialties = implode(', ', $specialties); } return $stringSpecialties; } public function setOpenedRequestNotified($requestID=0) { return $this->db->where('id', $requestID)->update('requests', ['opened_sent'=>1, 'opened_sent_at'=>date('Y-m-d H:i:s')]); } /*public function insertMsgInQueue($msgInfo=[]) { return $this->db->insert('requests_messages_queue', [ 'sender_id' => $msgInfo['senderId'], 'recipient_id' => $msgInfo['recipientId'], 'request_id' => $msgInfo['requestId'], 'mail_id' => $msgInfo['mailId'], 'msg_subject' => $msgInfo['subject'], 'msg_content' => $msgInfo['content'], 'msg_type' => $msgInfo['type'], 'msg_recipient' => $msgInfo['recipient'], 'sender_status' => $msgInfo['senderStatus'], 'created_at' => date('Y-m-d H:i:s'), ]); }*/ public function insertMsgInQueue($msgInfo=[]) { return $this->db->insert('requests_messages_queue', [ 'sender_id' => $msgInfo['senderId'], 'recipient_id' => $msgInfo['recipientId'], 'request_id' => $msgInfo['requestId'], 'mail_id' => $msgInfo['mailId'], 'msg_subject' => $msgInfo['subject'], 'msg_content' => $msgInfo['content'], 'msg_type' => $msgInfo['type'], 'msg_recipient' => $msgInfo['recipient'], 'sender_status' => $msgInfo['senderStatus'], 'attachments' => isset($msgInfo['attachments']) ? $msgInfo['attachments'] : null, 'delay_at' => isset($msgInfo['delay']) ? $msgInfo['delay'] : null, 'created_at' => date('Y-m-d H:i:s'), ]); } public function replaceMsgPlaceholders($text='', $msgCode='', $data=[]) { switch($msgCode) { case 'APPLICANT_CONFIRM': return vsprintf($text, [$data['specialtyList'], $data['code'], $data['langList'], $data['siteLink']]); break; case 'NEW_FWD_REQUEST': return vsprintf($text, [$data['specialtyList'], $data['code'], $data['langList'], $data['requestId'], $data['center'], $data['siteLink']]); break; case 'PARTIALLY_REPORTED': return vsprintf($text, [$data['specialtyList'], $data['code'], $data['langList'], $data['requestId'], $data['siteLink']]); break; case 'REQUEST_UPDATE': return vsprintf($text, [$data['code'], $data['langList'], $data['requestId'], $data['center'], $data['siteLink']]); break; case 'REQUEST_UPDATE_APPLICANT': return vsprintf($text, [$data['code'], $data['langList'], $data['requestId'], $data['center'], $data['siteLink']]); break; case 'CLOSED_BY_MODERATOR': return vsprintf($text, [$data['specialtyList'], $data['code'], $data['langList'], $data['requestId'], $data['siteLink']]); break; default: return ''; } } public function stringifyLangCodes($langCodeList='') { $codes = explode(',', $langCodeList); $langs = []; $langString = ''; $labels = ['en'=>_('english'), 'it'=>_('italian'), 'fr'=>_('french'), 'es'=>_('spanish'), 'pt'=>_('portoguese')]; if (is_array($codes)) { foreach($codes as $code) { $langs[] = ucfirst(_($labels[$code])); } $langString = implode(', ', $langs); } return $langString; } public function getICD10Categories($lang='en') { $categories = []; $resultLangs = $this->db->getOne('icd10_languages'); $supportedLangs = explode('|', $resultLangs['supported_langs']); $lang = in_array($lang, $supportedLangs) ? $lang : 'en'; $this->db->rawQuery("SET SESSION group_concat_max_len = 1000000"); $results = $this->db ->where("c.parent_id = ''") ->where('cl.lang_code', $lang) ->join('icd10_categories_labels cl', 'cl.category_id=c.id', 'INNER') ->orderBy('c.position', 'asc') ->get('icd10_categories c', null, [ 'c.id', 'cl.description', "(SELECT GROUP_CONCAT('\"', csub.id, '\"', ':', '\"', clsub.description, '\"' SEPARATOR ',') FROM icd10_categories csub JOIN icd10_categories_labels clsub ON clsub.category_id=csub.id WHERE clsub.lang_code = '$lang' AND csub.parent_id=c.id) subcategories" ]); if (is_array($results)) { foreach($results as $index => $item) { $categories[$index]['id'] = $item['id']; $categories[$index]['label'] = $item['description']; //$categories[$index]['subcategories-raw'] = $item['subcategories']; $categories[$index]['subcategories'] = json_decode('{'.$item['subcategories'].'}', true); } } return $categories; } public function getDeseasesByICD10Category($category='', $lang='en', $selectedDeseases=[]) { $deseases = []; $resultLangs = $this->db->getOne('icd10_languages'); $supportedLangs = explode('|', $resultLangs['supported_langs']); $lang = in_array($lang, $supportedLangs) ? $lang : 'en'; $this->db->rawQuery("SET SESSION group_concat_max_len = 1000000"); $results = $this->db ->where('category_id', $category) ->where('parent_id', '') ->where('idl.lang_code', $lang) ->join('icd10_desease_labels idl', 'idl.desease_id=d.id', 'INNER') ->get('icd10_deseases d', null, [ 'd.id', 'd.category_id', 'd.description', "(SELECT GROUP_CONCAT('\"', dsub.id, '\"', ':', '\"', iclsub.description, '\"' SEPARATOR ',') FROM icd10_deseases dsub JOIN icd10_desease_labels iclsub ON iclsub.desease_id=dsub.id WHERE iclsub.lang_code = '$lang' AND dsub.parent_id=d.id) subdeseases" ]); if (is_array($results)) { foreach($results as $index => $item) { $deseases[$index]['id'] = $item['id']; $deseases[$index]['label'] = $item['description']; $deseases[$index]['disabled'] = in_array($item['id'], $selectedDeseases) ? 'disabled' : ''; $subdeseases = json_decode('{'.$item['subdeseases'].'}', true); if (is_array($subdeseases)) { foreach($subdeseases as $subId => $subLabel) { unset($subdeseases[$subId]); $subdeseases[$subId]['label'] = $subLabel; if (in_array($subId, $selectedDeseases)) { $subdeseases[$subId]['disabled'] = 'disabled'; } else { $subdeseases[$subId]['disabled'] = ''; } } $deseases[$index]['subdeseases'] = $subdeseases; } else { $deseases[$index]['subdeseases'] = []; } } } return $deseases; } public function getECD10ListByRequestId($requestId=0, $lang_code='en') { $resultLangs = $this->db->getOne('icd10_languages'); $supportedLangs = explode('|', $resultLangs['supported_langs']); $lang_code = in_array($lang_code, $supportedLangs) ? $lang_code : 'en'; $icd10 = $this->db ->where('rst.request_id', $requestId) ->where('idl.lang_code', $lang_code) ->join('icd10_deseases icdd', 'icdd.id=rst.symptom_id', 'INNER') ->join('icd10_desease_labels idl', 'idl.desease_id=rst.symptom_id', 'INNER') ->get('requests_symptoms_to rst', null, [ 'icdd.id', 'idl.description label', "(SELECT idlsub.description FROM icd10_desease_labels idlsub WHERE idlsub.desease_id = icdd.parent_id AND idlsub.lang_code = '$lang_code') parent_label" ]); return $icd10; } public function getDeseaseByKeyword($keyword='', $langCode='en', $selectedDeseases=[]) { $deseases = []; $results = $this->db ->where("idl.description LIKE '%$keyword%'") ->where('idl.lang_code', $langCode) ->where("d.parent_id <> ''") ->join('icd10_desease_labels idl', 'idl.desease_id=d.id', 'INNER') ->get('icd10_deseases d', 10, [ 'idl.description', 'idl.desease_id', 'd.parent_id', "(SELECT idlsub.description FROM icd10_desease_labels idlsub WHERE idlsub.desease_id = d.parent_id AND idlsub.lang_code = '$langCode') parent_label" ]); if (is_array($results) && !empty($results)) { foreach($results as $index => $item) { $deseases[$item['parent_id']]['id'] = $item['parent_id']; $deseases[$item['parent_id']]['label'] = $item['parent_label']; $deseases[$item['parent_id']]['disabled'] = in_array($item['parent_id'], $selectedDeseases) ? 'disabled' : ''; $deseases[$item['parent_id']]['subdeseases'][$item['desease_id']]['id'] = $item['desease_id']; $deseases[$item['parent_id']]['subdeseases'][$item['desease_id']]['label'] = $item['description']; $deseases[$item['parent_id']]['subdeseases'][$item['desease_id']]['disabled'] = in_array($item['desease_id'], $selectedDeseases) ? 'disabled' : '';; } } /*foreach($results as $index => $item) { $deseases[$index]['id'] = $item['parent_id']; $deseases[$index]['label'] = $item['parent_label']; $deseases[$index]['disabled'] = in_array($item['parent_id'], $selectedDeseases) ? 'disabled' : ''; $deseases[$index]['subdeseases'][$item['desease_id']]['id'] = $item['desease_id']; $deseases[$index]['subdeseases'][$item['desease_id']]['label'] = $item['description']; $deseases[$index]['subdeseases'][$item['desease_id']]['disabled'] = in_array($item['desease_id'], $selectedDeseases) ? 'disabled' : '';; }*/ return $deseases; } public function getExams($checkedExams=[]) { $axams = []; $this->db->rawQuery("SET SESSION group_concat_max_len = 1000000"); $results = $this->db ->get('requests_exams re', null, [ 're.id', 're.standard_description', 're.exam_type', "(SELECT GROUP_CONCAT('\"', resub.id, '\"', ':', '\"', resub.standard_description, '\"') FROM requests_exams resub WHERE resub.parent_id=re.id) children" ]); if (is_array($results)) { foreach($results as $index => $item) { $axams[$item['standard_description']][$item['id']]['id'] = $item['id']; $axams[$item['standard_description']][$item['id']]['description'] = _($item['standard_description']); $axams[$item['standard_description']][$item['id']]['type'] = $item['exam_type']; $axams[$item['standard_description']][$item['id']]['checked'] = false; //Default if (isset($checkedExams[$item['exam_type']])) { foreach($checkedExams[$item['exam_type']] as $checkeds) { if ($checkeds['id'] == $item['id']) { $axams[$item['standard_description']][$item['id']]['checked'] = true; break; } } } $childrenData = json_decode('{'.stripslashes($item['children']).'}', true); $children = []; if (is_array($childrenData) && !empty($childrenData)) { foreach($childrenData as $childId => $childStandardLabel) { $children[$childId]['description'] = _($childStandardLabel); $children[$childId]['checked'] = false; if (isset($checkedExams[$item['exam_type']])) { foreach($checkedExams[$item['exam_type']] as $checkeds) { if ($checkeds['id'] == $childId) { $children[$childId]['checked'] = true; break; } } } } } $axams[$item['standard_description']][$item['id']]['children'] = $children; } } return $axams; } public function getWizardsByRequestId($requestId=0) { $wizards = []; $results = $this->db ->where('request_id', $requestId) ->join('requests_exams re', 're.id=rwt.exam_id', 'INNER') ->get('requests_wizards_to rwt', null, [ 're.id', 're.standard_description', 'rwt.exam_type', "(SELECT re_parent.standard_description FROM requests_exams re_parent WHERE re_parent.id=re.parent_id) parent_name" ]); if (is_array($results)) { foreach($results as $index => $item) { $wizards[$item['exam_type']][$index]['id'] = $item['id']; $description = $item['parent_name'] != '' ? _($item['parent_name']).' / '._($item['standard_description']) : _($item['standard_description']); $wizards[$item['exam_type']][$index]['description'] = $description; } } return $wizards; } public function getWizardsDermaPositions($requestId=0) { $positions = []; $results = $this->db ->where('request_id', $requestId) ->get('requests_wizard_derma_position_to'); if (is_array($results) && !empty($results)) { foreach($results as $item) { $positions[$item['position_type']] = $item; } } return $positions; } public function getWizardsEarDeseases($requestId=0) { $deseases = []; $results = $this->db ->where('request_id', $requestId) ->get('requests_wizard_ear_deseases_to'); if (is_array($results) && !empty($results)) { foreach($results as $item) { $deseases[$item['desease_type']] = $item; } } return $deseases; } public function checkPartialUploads() { $path = MEDIA_TMP_DIR; $infoFiles = glob($path.'*.info'); return $infoFiles; } public function cron() { shell_exec('cd '.$this->config['job']['path'].'; /usr/local/bin/php cron.php > /dev/null 2>/dev/null &'); } }