File: /mnt/data/doccure-wp/wp-content/plugins/doccure/chat/class-chat-system.php
<?php
use Dompdf\Css\Style;
if (!class_exists('ChatSystem')) {
/**
* One to One Chat System
*
* @package doccure
*/
class ChatSystem
{
/**
* DB Variable
*
* @var [string]
*/
protected static $wpdb;
/**
* Initialize Singleton
*
* @var [void]
*/
private static $_instance = null;
/**
* Call this method to get singleton
*
* @return ChatSystem Instance
*/
public static function instance()
{
if (self::$_instance === null) {
self::$_instance = new ChatSystem();
}
return self::$_instance;
}
/**
* PRIVATE CONSTRUCTOR
*/
private function __construct()
{
global $wpdb;
self::$wpdb = $wpdb;
add_action('after_setup_theme', array(__CLASS__, 'createChatTable'));
add_action('fetch_users_threads', array(__CLASS__, 'fetchUserThreads'), 11, 1);
add_action('wp_ajax_fetchUserConversation', array(__CLASS__, 'fetchUserConversation'));
add_action('wp_ajax_nopriv_fetchUserConversation', array(__CLASS__, 'fetchUserConversation'));
add_action('wp_ajax_sendUserMessage', array(__CLASS__, 'sendUserMessage'));
add_action('wp_ajax_nopriv_sendUserMessage', array(__CLASS__, 'sendUserMessage'));
add_action('wp_ajax_getIntervalChatHistoryData', array(__CLASS__, 'getIntervalChatHistoryData'));
add_action('wp_ajax_nopriv_getIntervalChatHistoryData', array(__CLASS__, 'getIntervalChatHistoryData'));
add_filter('get_user_info', array(__CLASS__, 'getUserInfoData'), 10, 3);
add_action('fetch_single_users_threads', array(__CLASS__, 'fetchSingleUserThreads'), 11, 2);
add_action('doccure_chat_count', array(__CLASS__, 'countUnreadMessages'),11,2);
add_filter('doccure_chat_count', array(__CLASS__, 'countUnreadMessages'),11,2);
}
/**
* Create Chat Table
*
* @return void
*/
public static function createChatTable()
{
global $wpdb;
$private_chat = $wpdb->prefix . "private_chat";
if ($wpdb->get_var("SHOW TABLES LIKE '$private_chat'") != $private_chat) {
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $private_chat (
id int(11) NOT NULL AUTO_INCREMENT,
sender_id int(11) NOT NULL,
receiver_id int(11) NOT NULL,
chat_message text NOT NULL,
status int(11) NOT NULL DEFAULT 1,
timestamp int(11) NOT NULL,
time_gmt datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}
/**
* Get current user's role
*/
public static function getCurrentUserRole($userId = '') {
$user = get_userdata($userId);
if (!empty($user)) {
$roles = $user->roles;
if (in_array('doctors', $roles)) {
return 'doctor';
} elseif (in_array('doctors_staff', $roles)) {
return 'doctors_staff';
} elseif (in_array('staff', $roles)) {
return 'staff';
} elseif (in_array('regular_users', $roles)) {
return 'patient';
}
}
return 'user';
}
/**
* Check if staff can chat with a specific user
*/
public static function canStaffChatWithUser($staffId, $targetUserId) {
$staffParentId = get_user_meta($staffId, 'parent_id', true);
$targetUserParentId = get_user_meta($targetUserId, 'parent_id', true);
// Get user roles
$staffRole = self::getCurrentUserRole($staffId);
$targetUserRole = self::getCurrentUserRole($targetUserId);
// Staff can always chat with their parent doctor
if ($targetUserId == $staffParentId) {
return true;
}
// Staff can chat with doctors_staff and staff created by the same doctor
if (in_array($targetUserRole, array('doctors_staff', 'staff')) && $targetUserParentId == $staffParentId) {
return true;
}
return false;
}
/**
* Check if doctor can chat with a specific user
*/
public static function canDoctorChatWithUser($doctorId, $targetUserId) {
$targetUserRole = self::getCurrentUserRole($targetUserId);
$targetUserParentId = get_user_meta($targetUserId, 'parent_id', true);
// Doctors can chat with ALL patients (regular_users) regardless of parent_id
if ($targetUserRole === 'patient') {
return true;
}
// Doctors can chat with doctors_staff and staff they created
if (in_array($targetUserRole, array('doctors_staff', 'staff'))) {
return $targetUserParentId == $doctorId;
}
return false;
}
/**
* Check if doctors_staff can chat with a specific user
*/
public static function canDoctorsStaffChatWithUser($doctorsStaffId, $targetUserId) {
$doctorsStaffParentId = get_user_meta($doctorsStaffId, 'parent_id', true);
$targetUserParentId = get_user_meta($targetUserId, 'parent_id', true);
// Get user roles
$doctorsStaffRole = self::getCurrentUserRole($doctorsStaffId);
$targetUserRole = self::getCurrentUserRole($targetUserId);
// Doctors_staff can always chat with their parent doctor
if ($targetUserId == $doctorsStaffParentId) {
return true;
}
// Doctors_staff can chat with other doctors_staff and staff created by the same doctor
if (in_array($targetUserRole, array('doctors_staff', 'staff')) && $targetUserParentId == $doctorsStaffParentId) {
return true;
}
// NEW: Doctors_staff can chat with ALL patients
if ($targetUserRole === 'patient') {
return true;
}
return false;
}
/**
* Check if patient can chat with a specific user
*/
public static function canPatientChatWithUser($patientId, $targetUserId) {
$targetUserRole = self::getCurrentUserRole($targetUserId);
$targetUserParentId = get_user_meta($targetUserId, 'parent_id', true);
// Patients can chat with doctors and doctors_staff
if (in_array($targetUserRole, array('doctor', 'doctors_staff'))) {
return true;
}
return false;
}
/**
* Validate if users can chat before sending message
*/
public static function validateChatPermission($senderId, $receiverId) {
$senderRole = self::getCurrentUserRole($senderId);
$receiverRole = self::getCurrentUserRole($receiverId);
switch($senderRole) {
case 'doctor':
return self::canDoctorChatWithUser($senderId, $receiverId);
case 'staff':
return self::canStaffChatWithUser($senderId, $receiverId);
case 'doctors_staff':
return self::canDoctorsStaffChatWithUser($senderId, $receiverId);
case 'patient':
return self::canPatientChatWithUser($senderId, $receiverId);
default:
return false;
}
}
/**
* Get All Users for Chat by Role with restrictions based on current user role
*/
public static function getAllUsersForChat($userId = '', $role = '') {
global $wpdb;
$userTable = $wpdb->prefix . 'users';
$usermetaTable = $wpdb->prefix . 'usermeta';
$privateChat = $wpdb->prefix . 'private_chat';
// Get current user's role
$current_user_role = self::getCurrentUserRole($userId);
// Base query to get all potential users
$query = "SELECT
u.ID as user_id,
u.display_name,
u.user_email,
u.user_registered,
pc.id as last_message_id,
pc.chat_message as last_message,
pc.status as last_message_status,
pc.time_gmt as last_message_time,
pc.sender_id,
pc.receiver_id,
CASE
WHEN pc.id IS NOT NULL THEN 1
ELSE 0
END as has_chat_history
FROM $userTable u
LEFT JOIN $privateChat pc ON pc.id = (
SELECT MAX(id) FROM $privateChat
WHERE (sender_id = u.ID AND receiver_id = $userId)
OR (sender_id = $userId AND receiver_id = u.ID)
)
WHERE u.ID != $userId";
// Add role-based restrictions
switch($current_user_role) {
case 'doctor':
// Doctors can see ALL patients, and doctors_staff/staff they created
$query .= " AND (
u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'parent_id' AND meta_value = $userId
AND user_id IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND (meta_value LIKE '%\"doctors_staff\"%' OR meta_value LIKE '%\"staff\"%')
)
)
OR
u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND meta_value LIKE '%\"regular_users\"%'
)
)";
break;
case 'staff':
$parentId = get_user_meta($userId, 'parent_id', true);
if (empty($parentId)) {
// If no parent_id, staff can't chat with anyone
$query .= " AND 1=0";
} else {
// Staff can see their parent doctor, doctors_staff, and other staff from same doctor
$query .= " AND (
u.ID = $parentId
OR u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'parent_id' AND meta_value = $parentId
AND user_id IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND (meta_value LIKE '%\"doctors_staff\"%' OR meta_value LIKE '%\"staff\"%')
)
)
)";
}
break;
case 'doctors_staff':
$parentId = get_user_meta($userId, 'parent_id', true);
if (empty($parentId)) {
// If no parent_id, doctors_staff can't chat with anyone
$query .= " AND 1=0";
} else {
// UPDATED: Doctors_staff can see their parent doctor, other doctors_staff, staff from same doctor, AND ALL patients
$query .= " AND (
u.ID = $parentId
OR u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'parent_id' AND meta_value = $parentId
AND user_id IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND (meta_value LIKE '%\"doctors_staff\"%' OR meta_value LIKE '%\"staff\"%')
)
)
OR u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND meta_value LIKE '%\"regular_users\"%'
)
)";
}
break;
case 'patient':
// Patients can see doctors and doctors_staff
$query .= " AND u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND (meta_value LIKE '%\"doctors\"%' OR meta_value LIKE '%\"doctors_staff\"%')
)";
break;
}
// Add role filter if specified
if (!empty($role)) {
switch($role) {
case 'doctor':
// Doctor filter includes both doctors and doctors_staff for all users
$query .= " AND u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND (meta_value LIKE '%\"doctors\"%' OR meta_value LIKE '%\"doctors_staff\"%')
)";
break;
case 'staff':
$query .= " AND u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND meta_value LIKE '%\"staff\"%'
)";
break;
case 'patient':
$query .= " AND u.ID IN (
SELECT user_id FROM $usermetaTable
WHERE meta_key = 'wp_capabilities'
AND meta_value LIKE '%\"regular_users\"%'
)";
break;
}
}
$query .= " ORDER BY has_chat_history DESC, pc.time_gmt DESC, u.display_name ASC";
return $wpdb->get_results($query, ARRAY_A);
}
/**
* Get User Role for Display
*/
public static function getUserRole($user_id) {
$user = get_userdata($user_id);
if (!empty($user)) {
$roles = $user->roles;
if (in_array('doctors', $roles)) {
return 'doctor';
} elseif (in_array('doctors_staff', $roles)) {
return 'doctors_staff';
} elseif (in_array('staff', $roles)) {
return 'staff';
} elseif (in_array('regular_users', $roles)) {
return 'patient';
}
}
return 'user';
}
/**
* Get available filter buttons based on user role
*/
public static function getAvailableFilters($userId = '') {
$current_user_role = self::getCurrentUserRole($userId);
$available_filters = array();
switch($current_user_role) {
case 'doctor':
// Doctors can see all filters for users they created + all patients
$available_filters = array('doctor', 'staff', 'patient');
break;
case 'staff':
// Staff can see doctor (combined doctors + doctors_staff) and staff filters
$available_filters = array('doctor', 'staff');
break;
case 'doctors_staff':
// Doctors_staff can see doctor (combined), staff and patient filters
$available_filters = array('doctor', 'staff', 'patient');
break;
case 'patient':
// Patients can see only doctor (combined doctors + doctors_staff) filter
$available_filters = array('doctor');
break;
default:
$available_filters = array('doctor', 'staff', 'patient');
break;
}
return $available_filters;
}
/**
* Get Chat Users List Threads
*
* @return array
*/
public static function getUsersThreadListData(
$userId = '',
$receiverID = '',
$type = 'list',
$data = array(),
$msgID = '',
$offset = '',
$role = '' // Added role parameter
) {
$privateChat = self::$wpdb->prefix . 'private_chat';
$userTable = self::$wpdb->prefix . 'users';
$fetchResults = array();
switch ($type) {
case "list":
// Use the new method to get users by role
$fetchResults = self::getAllUsersForChat($userId, $role);
break;
case "fetch_thread":
$fetchResults = self::$wpdb->get_results(
"SELECT * FROM $privateChat
WHERE
($privateChat.sender_id = $userId
AND
$privateChat.receiver_id = $receiverID)
OR
($privateChat.sender_id = $receiverID
AND
$privateChat.receiver_id = $userId)
", ARRAY_A
);
break;
case "fetch_thread_last_items":
$total = 10;
$limit = $offset * $total;
// Improved query to properly load older messages with proper ordering
$fetchResults = self::$wpdb->get_results(
"SELECT * FROM $privateChat
WHERE
(sender_id = $userId AND receiver_id = $receiverID)
OR
(sender_id = $receiverID AND receiver_id = $userId)
ORDER BY id DESC
LIMIT $limit, $total",
ARRAY_A
);
// Reverse the array to maintain chronological order
$fetchResults = array_reverse($fetchResults);
break;
case "fetch_interval_thread":
$fetchResults = self::$wpdb->get_results(
"SELECT * FROM $privateChat
WHERE ($privateChat.sender_id = $userId
AND $privateChat.receiver_id = $receiverID)
OR ($privateChat.sender_id = $receiverID
AND $privateChat.receiver_id = $userId)
ORDER BY $privateChat.id ASC
", ARRAY_A
);
break;
case "set_thread_status":
self::$wpdb->update(
$privateChat,
array("status" => intval(0)),
array(
"sender_id" => stripslashes_deep($receiverID),
"receiver_id" => stripslashes_deep($userId),
"status" => intval(1)
)
);
break;
case "insert_msg":
self::$wpdb->insert($privateChat, $data);
return self::$wpdb->insert_id;
break;
case "fetch_recent_thread":
$fetchResults = self::$wpdb->get_row(
"SELECT * FROM
$privateChat
WHERE $privateChat.id = $msgID", ARRAY_A
);
break;
case "count_unread_msgs":
$fetchResults = self::$wpdb->get_var(
"SELECT count(*) AS unread FROM $privateChat where $privateChat.receiver_id = $userId and status = 1"
);
break;
case "count_unread_msgs_by_user":
$fetchResults = self::$wpdb->get_var(
"SELECT count(*) AS unread FROM $privateChat
WHERE $privateChat.sender_id = $receiverID
AND $privateChat.receiver_id = $userId
AND $privateChat.status = 1"
);
break;
case "delete_thread_msg":
self::$wpdb->delete($privateChat, $data);
break;
}
return $fetchResults;
}
/**
* Fetch User Threads - Modified with updated permissions
*
* @param string $userId
* @return void
*/
public static function fetchUserThreads($userId = '')
{
ob_start();
// Get available filters based on user role
$available_filters = self::getAvailableFilters($userId);
$current_user_role = self::getCurrentUserRole($userId);
// Load users based on role restrictions
$allUsers = self::getAllUsersForChat($userId, '');
$chat_active_user = isset($_GET['id']) ? $_GET['id'] : '';
// Set default filter to the first available one
$current_filter = !empty($available_filters[0]) ? $available_filters[0] : '';
?>
<ul>
<li>
<!-- Search Box - Always show for all users -->
<div class="dc-chat-filter-buttons">
<div class="dc-formtheme dc-formsearch">
<fieldset>
<div class="form-group">
<input type="text" autocomplete="off" name="fullname" class="form-control dc-filter-users" placeholder="<?php esc_html_e('Search Users', 'doccure_core'); ?>">
<a href="javascript:;" class="dc-searchgbtn"><i class="fa fa-search"></i></a>
</div>
</fieldset>
</div>
<!-- Filter Buttons - Only show if multiple filters available -->
<?php if (count($available_filters) > 1): ?>
<div class="dc-filter-buttons-group">
<?php
// Show available filter buttons
foreach($available_filters as $filter):
$active_class = $current_filter === $filter ? 'active' : '';
$display_name = '';
switch($filter) {
case 'doctor':
$display_name = esc_html__('Doctors', 'doccure_core');
break;
case 'staff':
$display_name = esc_html__('Staff', 'doccure_core');
break;
case 'patient':
$display_name = esc_html__('Patients', 'doccure_core');
break;
}
?>
<button type="button" class="dc-filter-btn <?php echo esc_attr($active_class); ?>" data-filter="<?php echo esc_attr($filter); ?>">
<i class=""></i>
<?php echo $display_name; ?>
</button>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<div class="dc-verticalscrollbar dc-dashboardscrollbar lore" id="chat-users-list">
<?php
if ( !empty( $allUsers ) ) {
foreach ( $allUsers as $user ) {
$user_id = $user['user_id'];
$unreadNotifyClass = '';
// Check for unread messages
$unread_count = self::getUsersThreadListData($userId, $user_id, 'count_unread_msgs_by_user');
if ($unread_count > 0) {
$unreadNotifyClass = 'dc-dotnotification';
}
$userAvatar = self::getUserInfoData('avatar', $user_id, array('width' => 100, 'height' => 100));
$userName = self::getUserInfoData('username', $user_id, array());
$userUrl = self::getUserInfoData('url', $user_id, array());
$userRole = self::getUserRole($user_id);
// Get last message if exists
$last_message = !empty($user['last_message']) ? $user['last_message'] : __('No messages yet', 'doccure_core');
$last_message_id = !empty($user['last_message_id']) ? $user['last_message_id'] : 0;
// For all users, group doctors and doctors_staff under 'doctor' filter
$filter_role = $userRole;
if ($userRole === 'doctors_staff') {
$filter_role = 'doctor';
}
// For staff and patients, also group doctors and doctors_staff under 'doctor' filter
if (in_array($current_user_role, array('staff', 'patient')) && $userRole === 'doctor') {
$filter_role = 'doctor';
}
?>
<div class="dc-ad dc-load-chat <?php echo esc_attr($unreadNotifyClass); ?> user-role-<?php echo esc_attr($userRole); ?> filter-role-<?php echo esc_attr($filter_role); ?>"
id="load-user-chat-<?php echo intval($user_id); ?>"
data-userid="<?php echo intval($user_id); ?>"
data-currentid="<?php echo intval($userId); ?>"
data-msgid="<?php echo intval($last_message_id); ?>"
data-img="<?php echo esc_url($userAvatar); ?>"
data-name="<?php echo esc_attr($userName); ?>"
data-url="<?php echo esc_url($userUrl); ?>"
data-role="<?php echo esc_attr($userRole); ?>">
<figure>
<img src="<?php echo esc_url($userAvatar); ?>" alt="<?php echo esc_attr($userName); ?>">
<?php echo do_action('doccure_print_user_status',$user_id);?>
</figure>
<div class="dc-adcontent">
<h3>
<?php echo esc_attr($userName); ?>
<span>
<?php
switch($userRole) {
case 'doctor': esc_html_e('(Doctor)', 'doccure_core'); break;
case 'staff': esc_html_e('(Staff)', 'doccure_core'); break;
case 'doctors_staff': esc_html_e('(Doctor Staff)', 'doccure_core'); break;
case 'patient': esc_html_e('(Patient)', 'doccure_core'); break;
default: esc_html_e('(User)', 'doccure_core'); break;
}
?>
</span>
</h3>
<span class="list-last-message">
<?php
if (!empty($user['last_message'])) {
echo wp_trim_words($user['last_message'], 10);
} else {
echo '<em>' . esc_html__('Start a conversation', 'doccure_core') . '</em>';
}
?>
</span>
</div>
<em class="dcunread-count"><?php echo intval($unread_count); ?></em>
</div>
<?php
}
} else {
$no_users_message = '';
switch($current_user_role) {
case 'doctor':
$no_users_message = esc_html__('No users available to chat with.', 'doccure_core');
break;
case 'staff':
$no_users_message = esc_html__('No users available to chat with.', 'doccure_core');
break;
case 'doctors_staff':
$no_users_message = esc_html__('No users available to chat with.', 'doccure_core');
break;
case 'patient':
$no_users_message = esc_html__('No doctors available to chat with.', 'doccure_core');
break;
default:
$no_users_message = esc_html__('No users found to chat with.', 'doccure_core');
break;
}
echo '<p class="dc-no-users">' . $no_users_message . '</p>';
}
?>
</div>
</li>
<li>
<div class="dc-chatarea load-dc-chat-message">
<div class="dc-chatarea dc-chatarea-empty">
<figure class="dc-chatemptyimg">
<img src="<?php echo esc_url(get_template_directory_uri() . '/assets/images/message-img.png'); ?>" alt="<?php esc_attr_e('No Message Selected', 'doccure_core'); ?>">
<figcaption>
<h3><?php esc_html_e('No message selected to display', 'doccure_core'); ?></h3>
</figcaption>
</figure>
</div>
</div>
</li>
</ul>
<script type="text/javascript">
jQuery(document).ready(function($) {
<?php if (count($available_filters) > 1): ?>
// Filter button click handler (only when multiple filters available)
$('.dc-filter-btn').on('click', function() {
var filter = $(this).data('filter');
// Remove active class from all buttons
$('.dc-filter-btn').removeClass('active');
// Add active class to clicked button
$(this).addClass('active');
// Hide all users first
$('.dc-load-chat').hide();
// Show only users with the selected role
$('.filter-role-' + filter).show();
// Update no users message
updateNoUsersMessage();
});
// Function to update no users message
function updateNoUsersMessage() {
var visibleUsers = $('.dc-load-chat:visible').length;
if (visibleUsers === 0) {
if ($('.dc-no-users').length === 0) {
$('#chat-users-list').append('<p class="dc-no-users"><?php echo esc_js(__('No users found for this filter.', 'doccure_core')); ?></p>');
}
} else {
$('.dc-no-users').remove();
}
}
// Initialize filter state - show only users for the active filter
$('.dc-filter-btn.active').trigger('click');
<?php else: ?>
// For users with only one filter option, show all available users
$('.dc-load-chat').show();
<?php endif; ?>
});
</script>
<?php
if(!empty($chat_active_user)){
$script = "
jQuery(window).on('load', function() {
jQuery('#load-user-chat-".esc_js($chat_active_user)."').trigger('click');
});
";
wp_add_inline_script( 'doccure-dashboard', $script, 'before' );
}
echo ob_get_clean();
}
/**
* Fetch Single User Threads
*
* @param string $userId
* @return void
*/
public static function fetchSingleUserThreads($userId = '',$recived_id = '') {
ob_start();
$usersThreadUserList = self::getUsersThreadListData( $userId, $recived_id, 'fetch_thread', array(), '');
if ( !empty( $usersThreadUserList ) ) {
foreach ( $usersThreadUserList as $userVal ) {
$unreadNotifyClass = 'dc-offerermessage';
$chat_user_id = '';
if ( $recived_id === intval($userVal['sender_id']) ) {
$unreadNotifyClass = 'dc-memessage dc-readmessage';
}
$chat_user_id = intval($userVal['sender_id']);
$message_date = !empty($userVal['time_gmt']) ? date(get_option('date_format'), strtotime($userVal['time_gmt'])) : '';
$userAvatar = self::getUserInfoData('avatar', $chat_user_id, array('width' => 100, 'height' => 100));
$userName = self::getUserInfoData('username', $chat_user_id, array());
$userUrl = self::getUserInfoData('url', $chat_user_id, array());
$count = self::getUsersThreadListData($chat_user_id,$userId,'count_unread_msgs_by_user');
$unread = !empty( $count ) ? $count : 0;
?>
<div class="<?php echo esc_attr( $unreadNotifyClass );?>">
<?php if( !empty( $userAvatar ) ){?>
<figure><img src="<?php echo esc_url( $userAvatar );?>" alt="<?php echo esc_attr( $userName );?>"></figure>
<?php } ?>
<div class="dc-description">
<p><?php echo do_shortcode($userVal['chat_message']); ?></p>
<div class="clearfix"></div>
<time datetime="<?php echo esc_attr( $userVal['time_gmt'] );?>"><?php echo esc_html( $message_date );?></time>
</div>
</div>
<?php }
}
echo ob_get_clean();
}
/**
* Fetch User Conversation
*
* @return void
*/
public static function fetchUserConversation()
{
$json = array();
if( function_exists('doccure_validate_user') ) {
doccure_validate_user();
};
//security check
$do_check = check_ajax_referer('ajax_nonce', 'security', false);
if ( $do_check == false ) {
$json['type'] = 'error';
$json['message'] = esc_html__('No Kiddies Please', 'doccure_core');
wp_send_json( $json );
}
$senderID = !empty( $_POST['current_id'] ) ? intval( $_POST['current_id'] ) : '';
$receiverID = !empty( $_POST['user_id'] ) ? intval( $_POST['user_id'] ) : '';
$thread_page = !empty( $_POST['thread_page'] ) ? intval( $_POST['thread_page'] ) : 0;
$current_oldest_id = !empty( $_POST['current_oldest_id'] ) ? intval( $_POST['current_oldest_id'] ) : 0;
if (!empty($_POST) && $receiverID != $senderID ) {
$usersThreadData = self::getUsersThreadListData($senderID, $receiverID, 'fetch_thread_last_items', array(), '', $thread_page);
//Prepare Chat Nodes
$chat_nodes = array();
$new_oldest_id = 0;
if (!empty($usersThreadData)) {
//Update Chat Status in DB only if there are messages
self::getUsersThreadListData($senderID, $receiverID, 'set_thread_status', array(), '');
// Get the oldest message ID from the current batch
$new_oldest_id = $usersThreadData[0]['id'];
foreach ($usersThreadData as $key => $val) {
// Clear identification of sender
$chat_nodes[$key]['chat_is_sender'] = 'no';
if (intval($val['sender_id']) === intval($senderID)) {
$chat_nodes[$key]['chat_is_sender'] = 'yes';
}
$date = !empty($val['time_gmt']) ? date_i18n(get_option('date_format'), strtotime($val['time_gmt'])) : '';
$chat_nodes[$key]['chat_avatar'] = self::getUserInfoData('avatar', $val['sender_id'], array('width' => 100, 'height' => 100));
$chat_nodes[$key]['chat_username'] = self::getUserInfoData('username', $val['sender_id'], array());
$chat_nodes[$key]['chat_message'] = html_entity_decode(stripslashes($val['chat_message']), ENT_QUOTES);
$chat_nodes[$key]['chat_date'] = $date;
$chat_nodes[$key]['chat_id'] = intval($val['id']);
$chat_nodes[$key]['chat_current_user_id'] = intval($senderID);
}
}
//Create Chat Sidebar Data
$chat_sidebar = array();
$chat_sidebar['avatar'] = self::getUserInfoData('avatar', $receiverID, array('width' => 100, 'height' => 100));
$chat_sidebar['username'] = self::getUserInfoData('username', $receiverID, array());
$chat_sidebar['user_register'] = self::getUserInfoData('user_register', $receiverID, array());
$json['type'] = 'success';
$json['chat_nodes'] = $chat_nodes;
$json['chat_receiver_id'] = intval($receiverID);
$json['chat_sender_id'] = intval($senderID);
$json['chat_sidebar'] = $chat_sidebar;
$json['current_oldest_id'] = $new_oldest_id;
$json['message'] = !empty($chat_nodes) ? esc_html__('Chat Messages Found!', 'doccure_core') : esc_html__('Start a new conversation', 'doccure_core');
$json['thread_page'] = $thread_page + 1;
wp_send_json($json);
} else {
$json['type'] = 'error';
$json['message'] = esc_html__('Security check failed!', 'doccure_core');
wp_send_json($json);
}
}
/**
* Send user message function with permission validation
*
* @return void
*/
public static function sendUserMessage()
{
global $current_user,$doccure_options;
$json = array();
if( function_exists('doccure_is_demo_site') ) {
doccure_is_demo_site() ;
}; //if demo site then prevent
if( function_exists('doccure_validate_user') ) {
doccure_validate_user();
}; //if user is logged in
//security check
$do_check = check_ajax_referer('ajax_nonce', 'security', false);
if ( $do_check == false ) {
$json['type'] = 'error';
$json['message'] = esc_html__('Security check failed, this could be because of your browser cache. Please clear the cache and check it againe', 'doccure_core');
wp_send_json( $json );
}
$senderId = $current_user->ID;
$receiver_id = !empty( $_POST['receiver_id'] ) ? intval($_POST['receiver_id']) : '';
$status = !empty( $_POST['status'] ) && esc_attr( $_POST['status'] ) === 'read' ? 0 : 1;
$msg_type = !empty( $_POST['msg_type'] ) && esc_attr( $_POST['msg_type'] ) === 'modal' ? 'modal' : 'normals';
$message = !empty( $_POST['message'] ) ? esc_textarea($_POST['message']) : '';
if (empty($receiver_id)) {
$json['type'] = 'error';
$json['message'] = esc_html__('Security check failed!', 'doccure_core');
wp_send_json($json);
}
// Validate chat permissions before sending
if (!self::validateChatPermission($senderId, $receiver_id)) {
$json['type'] = 'error';
$json['message'] = esc_html__('You are not allowed to chat with this user.', 'doccure_core');
wp_send_json($json);
}
if ( intval( $receiver_id ) === intval( $current_user->ID ) ) {
$json['type'] = 'error';
$json['message'] = esc_html__('Something went wrong.', 'doccure_core');
wp_send_json($json);
}
if (empty($message)) {
$json['type'] = 'error';
$json['message'] = esc_html__('Message field is required.', 'doccure_core');
wp_send_json($json);
}
$receiverId = intval($receiver_id);
//Prepare Insert Message Data Array
$current_time = current_time('mysql');
$gmt_time = get_gmt_from_date($current_time);
$insert_data = array(
'sender_id' => $senderId,
'receiver_id' => $receiverId,
'chat_message' => $message,
'status' => $status,
'timestamp' => time(),
'time_gmt' => $gmt_time,
);
$msg_id = self::getUsersThreadListData($senderId, $receiverId, 'insert_msg', $insert_data, '');
$receiver_chat_notify = !empty($doccure_options['chat_notify_enable']) ? $doccure_options['chat_notify_enable'] : 'no';
if (class_exists('doccure_Email_helper') && $receiver_chat_notify === 'yes') {
if (class_exists('doccureRecChatNotification')) {
$email_helper = new doccureRecChatNotification();
$emailData = array();
$sender_id = doccure_get_linked_profile_id($senderId);
$receiver_id = doccure_get_linked_profile_id($receiverId);
$emailData['username'] = get_the_title($receiver_id);
$emailData['sender_name'] = get_the_title($sender_id);
$emailData['message'] = !empty($message) ? $message : '';
$emailData['email_to'] = get_userdata($receiverId)->user_email;
$email_helper->send_chat_notification($emailData);
}
}
if (!empty($msg_id)) {
$fetchRecentThread = self::getUsersThreadListData('', '', 'fetch_recent_thread', array(), $msg_id);
$message = !empty( $fetchRecentThread['chat_message'] ) ? $fetchRecentThread['chat_message'] : '';
$date = !empty($fetchRecentThread['time_gmt']) ? date_i18n(get_option('date_format'), strtotime($fetchRecentThread['time_gmt'])) : '';
$chat_nodes[0]['chat_avatar'] = self::getUserInfoData('avatar', $fetchRecentThread['sender_id'], array('width' => 100, 'height' => 100));
$chat_nodes[0]['chat_username'] = self::getUserInfoData('username', $fetchRecentThread['sender_id'], array());
$chat_nodes[0]['chat_message'] = html_entity_decode( stripslashes($message),ENT_QUOTES );
$chat_nodes[0]['chat_date'] = $date;
$chat_nodes[0]['chat_id'] = intval($fetchRecentThread['id']);
$chat_nodes[0]['chat_current_user_id'] = intval($senderId);
$chat_nodes[0]['chat_is_sender'] = 'yes';
//excerpt
if (strlen($message) > 40) {
$message = substr($message, 0, 40);
}
$json['type'] = 'success';
$json['msg_type'] = $msg_type;
$json['chat_nodes'] = $chat_nodes;
$chat_nodes[0]['chat_is_sender'] = 'no';
$json['chat_nodes_receiver'] = $chat_nodes;
$json['chat_receiver_id'] = intval($receiverId);
$json['chat_sender_id'] = intval($senderId);
$json['last_id'] = intval($msg_id);
$json['replace_recent_msg_user'] = self::getUserInfoData('username', $fetchRecentThread['receiver_id']);
$json['replace_recent_msg'] = $message;
$json['message'] = esc_html__('Message send!', 'doccure_core');
wp_send_json($json);
}
}
/**
* Get Interval Chat History
*
* @return void
*/
public static function getIntervalChatHistoryData()
{
$json = array();
if( function_exists('doccure_validate_user') ) {
doccure_validate_user();
}; //if user is logged in
//security check
$do_check = check_ajax_referer('ajax_nonce', 'security', false);
if ( $do_check == false ) {
$json['type'] = 'error';
$json['message'] = esc_html__('No Kiddies Please', 'doccure_core');
wp_send_json( $json );
}
$senderID = !empty( $_POST['sender_id'] ) ? intval($_POST['sender_id']) : '';
$receiverID = !empty( $_POST['receiver_id'] ) ? intval($_POST['receiver_id']) : '';
$lastMsgId = !empty( $_POST['last_msg_id'] ) ? intval($_POST['last_msg_id']) : '';
if ( !empty($_POST) && $senderID != $receiverID ) {
$usersThreadData = self::getUsersThreadListData($senderID, $receiverID, 'fetch_interval_thread', array(), '');
$chat_nodes = array();
$last_id = '';
$newchat = false;
$last_message = '';
if (!empty($usersThreadData)) {
foreach ($usersThreadData as $key => $val) {
$last_id = intval( $val['id'] );
$newchat = true;
//Update Chat Status in DB
self::getUsersThreadListData($senderID, $receiverID, 'set_thread_status', array(), '');
$chat_nodes[$key]['chat_is_sender'] = 'no';
if ($val['sender_id'] == $senderID) {
$chat_nodes[$key]['chat_is_sender'] = 'yes';
}
$date = !empty($val['time_gmt']) ? date_i18n(get_option('date_format'), strtotime($val['time_gmt'])) : '';
$chat_nodes[$key]['chat_avatar'] = self::getUserInfoData('avatar', $val['sender_id'], array('width' => 100, 'height' => 100));
$chat_nodes[$key]['chat_username'] = self::getUserInfoData('username', $val['sender_id'], array());
$chat_nodes[$key]['chat_message'] = html_entity_decode( stripslashes($val['chat_message']),ENT_QUOTES );
$chat_nodes[$key]['chat_date'] = $date;
$chat_nodes[$key]['chat_id'] = intval($val['id']);
$chat_nodes[$key]['chat_current_user_id'] = intval($senderID);
$last_message = $val['chat_message'];
}
if( $newchat ){
$json['type'] = 'success';
} else{
$json['type'] = 'error';
}
//excerpt
if (strlen($last_message) > 40) {
$last_message = substr($last_message, 0, 40);
}
$json['chat_nodes'] = $chat_nodes;
$json['last_id'] = intval( $last_id );
$json['receiver_id'] = $receiverID;
$json['last_message'] = $last_message;
$json['message'] = esc_html__('Chat messages found!', 'doccure_core');
wp_send_json($json);
}
} else {
$json['type'] = 'error';
$json['message'] = esc_html__('Security check failed!', 'doccure_core');
wp_send_json($json);
}
}
/**
* Delete chat message function
*
* @return void
*/
public static function deleteChatMessage()
{
global $current_user;
$json = array();
if( function_exists('doccure_validate_user') ) {
doccure_validate_user();
}; //if user is logged in
//security check
$do_check = check_ajax_referer('ajax_nonce', 'security', false);
if ( $do_check == false ) {
$json['type'] = 'error';
$json['message'] = esc_html__('No Kiddies Please', 'doccure_core');
wp_send_json( $json );
}
$senderID = !empty( $_POST['user_id'] ) ? intval($_POST['user_id']) : '';
$messageID = !empty( $_POST['msgid'] ) ? intval($_POST['msgid']) : '';
//Validation
if ( empty($senderID) || empty($messageID) ) {
$json['type'] = 'error';
$json['message'] = esc_html__('Something went wrong.', 'doccure_core');
wp_send_json($json);
}
//Check if valid User sent
if ( $current_user->ID !== $senderID ) {
$json['type'] = 'error';
$json['message'] = esc_html__('Security check failed!', 'doccure_core');
wp_send_json($json);
}
//Delete Thread Message
$delete_array_data = array(
"id" => $messageID,
"sender_id" => $senderID
);
self::getUsersThreadListData($senderID, '', 'delete_thread_msg', $delete_array_data, $messageID);
//Response
$json['type'] = 'success';
$json['message'] = esc_html__('Message deleted.', 'doccure_core');
wp_send_json($json);
}
/**
* Get User Information
*
* @param string $type
* @param string $userID
* @return void
*/
public static function getUserInfoData($type = '', $userID = '', $sizes = array())
{
$userinfo = '';
$user_data = get_userdata($userID);
$postId = doccure_get_linked_profile_id($userID);
switch ($type) {
case "avatar":
if ( apply_filters('doccure_get_user_type', $userID) === 'doctors' ) {
$userinfo = apply_filters('doccure_doctor_avatar_fallback', doccure_get_doctor_avatar($sizes, $postId), $sizes);
}
else {
$userinfo = apply_filters('doccure_doctor_avatar_fallback', doccure_get_others_avatar($sizes, $postId), $sizes);
}
break;
case "username":
$userinfo = doccure_get_username($userID);
break;
case "user_register":
$userinfo = esc_html__('Member Since','doccure_core').' '.date(get_option('date_format'), strtotime($user_data->user_registered));
break;
case "url":
$userinfo = get_the_permalink($postId);
break;
}
return $userinfo;
}
/**
* Get User Information
*
* @param string $type
* @param string $userID
* @return void
*/
public static function countUnreadMessages($userID = '',$return = 'no')
{
$users_unread = self::getUsersThreadListData($userID,'','count_unread_msgs');
if(!empty($return) && $return === 'yes' ){
return !empty( $users_unread ) ? $users_unread : 0;
}
echo !empty( $users_unread ) ? $users_unread : 0;
}
}
ChatSystem::instance();
}