File: /var/www/html/wp-content/plugins/bp-better-messages/inc/chats.php
<?php
defined( 'ABSPATH' ) || exit;
class Better_Messages_Chats
{
public static function instance()
{
// Store the instance locally to avoid private static replication
static $instance = null;
// Only run these methods if they haven't been run previously
if ( null === $instance ) {
$instance = new Better_Messages_Chats;
$instance->setup_actions();
}
// Always return the instance
return $instance;
// The last metroid is in captivity. The galaxy is at peace.
}
public function setup_actions(){
add_action( 'init', array( $this, 'register_post_type' ) );
add_action( 'save_post', array( $this, 'save_post' ), 1, 2 );
add_shortcode( 'bp_better_messages_chat_room', array( $this, 'layout' ) );
add_shortcode( 'better_messages_chat_room', array( $this, 'layout' ) );
//add_action( 'messages_message_sent', array( $this, 'on_message_sent' ) );
add_action( "save_post_bpbm-chat", array( $this, 'on_chat_update' ), 10, 3 );
add_action( 'before_delete_post', array( $this, 'on_chat_delete' ), 10, 1 );
add_action( 'better_messages_chat_room_sync_auto_add_users', array( $this, 'sync_auto_add_users'), 10, 1 );
add_action( 'user_register', array( $this, 'on_user_register' ), 20, 2 );
add_action( 'add_user_role', array( $this, 'on_user_role_change' ), 20, 2 );
add_action( 'remove_user_role', array( $this, 'on_user_role_change' ), 20, 2 );
add_action( 'set_user_role', array( $this, 'on_user_role_change' ), 20, 3 );
add_action( 'better_messages_guest_registered', array( $this, 'guest_registered' ), 20, 1 );
add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
add_filter( 'better_messages_rest_thread_item', array( $this, 'rest_thread_item'), 10, 5 );
add_filter('better_messages_thread_title', array( $this, 'chat_thread_title' ), 10, 3 );
add_action('better_messages_before_message_send', array( $this, 'before_message_send' ), 20, 2 );
add_filter( 'better_messages_guest_register_allowed', array( $this, 'check_if_chat_room_guests_allowed' ), 10,2 );
}
public function check_if_chat_room_guests_allowed( $allowed, $registerData )
{
if( is_array( $registerData ) && isset( $registerData['chatId'] ) ){
$chat_id = intval($registerData['chatId']);
if( $this->is_chat_room( $chat_id ) ) {
$settings = $this->get_chat_settings($chat_id);
if( in_array( 'bm-guest', $settings['can_join'] ) ){
$allowed = true;
}
}
}
return $allowed;
}
public function is_chat_room( $chat_id )
{
$chat = get_post( $chat_id );
if( $chat && $chat->post_type === 'bpbm-chat' ){
return true;
}
return false;
}
function before_message_send( &$args, &$errors ){
$thread_id = $args['thread_id'];
$type = Better_Messages()->functions->get_thread_type( $thread_id );
if( $type !== 'chat-room' ) return;
$chat_id = Better_Messages()->functions->get_thread_meta( $thread_id, 'chat_id' );
if( !! $chat_id ) {
$user_id = (isset($args['sender_id'])) ? $args['sender_id'] : Better_Messages()->functions->get_current_user_id();
if (!$this->user_can_reply($user_id, $chat_id)) {
$settings = $this->get_chat_settings($chat_id);
$errors['not_allowed_to_reply'] = $settings['not_allowed_reply_text'];
}
}
}
/**
* @param string $title
* @param int $thread_id
* @param BM_Thread $thread
* @return string
*/
public function chat_thread_title(string $title, int $thread_id, $thread ){
$thread_type = Better_Messages()->functions->get_thread_type( $thread_id );
if( $thread_type !== 'chat-room' ) return $title;
$chat_id = (int) Better_Messages()->functions->get_thread_meta($thread_id, 'chat_id');
$chat = get_post( $chat_id );
if( $chat ){
return $chat->post_title;
}
return $title;
}
public function rest_api_init(){
register_rest_route('better-messages/v1/admin', '/getChatParticipants', array(
'methods' => 'POST',
'callback' => array($this, 'get_chat_participants'),
'permission_callback' => array($this, 'user_is_admin'),
));
register_rest_route( 'better-messages/v1', '/chat/(?P<id>\d+)/join', array(
'methods' => 'POST',
'callback' => array( $this, 'join_chat' ),
'permission_callback' => array( Better_Messages_Rest_Api(), 'is_user_authorized' )
) );
register_rest_route( 'better-messages/v1', '/chat/(?P<id>\d+)/leave', array(
'methods' => 'POST',
'callback' => array( $this, 'leave_chat' ),
'permission_callback' => array( Better_Messages_Rest_Api(), 'is_user_authorized' )
) );
}
public function user_is_admin(){
return current_user_can('manage_options');
}
public function get_chat_participants( WP_REST_Request $request ){
global $wpdb;
$chat_id = intval( $request->get_param('chatId') );
$thread_id = $this->get_chat_thread_id( $chat_id );
$page = ( $request->has_param('page') ) ? intval( $request->get_param('page') ) : 1;
$per_page = 10;
$offset = 0;
if( $page > 1 ){
$offset = ( $page - 1 ) * $per_page;
}
$table = bm_get_table('recipients');
$total_results = (int) $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*)
FROM `{$table}` `recipients`
LEFT JOIN " . $wpdb->users . " `users`
ON `users`.`ID` = `recipients`.`user_id`
WHERE `thread_id` = %d
AND ( ( `recipients`.`user_id` >= 0 AND `users`.`ID` IS NOT NULL ) OR ( `recipients`.`user_id` < 0 ) )", $thread_id ) );
$sql = $wpdb->prepare("
SELECT `user_id`
FROM `{$table}` `recipients`
LEFT JOIN " . $wpdb->users . " `users`
ON `users`.`ID` = `recipients`.`user_id`
WHERE `thread_id` = %d
AND ( ( `recipients`.`user_id` >= 0 AND `users`.`ID` IS NOT NULL ) OR ( `recipients`.`user_id` < 0 ) )
LIMIT {$offset}, {$per_page}", $thread_id );
$results = $wpdb->get_col( $sql );
$pages = ceil( $total_results / $per_page );
$users = [];
foreach ( $results as $user_id ) {
$users[] = Better_Messages()->functions->rest_user_item($user_id);
}
$result = [
'total' => $total_results,
'pages' => $pages,
'users' => $users
];
return $result;
}
public function rest_thread_item( $thread_item, $thread_id, $thread_type, $include_personal, $user_id ){
if( $thread_type !== 'chat-room'){
return $thread_item;
}
$chat_id = (int) Better_Messages()->functions->get_thread_meta($thread_id, 'chat_id');
$settings = $this->get_chat_settings( $chat_id );
$recipients = Better_Messages()->functions->get_recipients( $thread_id );
$is_participant = isset( $recipients[$user_id] );
if( has_post_thumbnail( $chat_id ) ) {
$image_id = get_post_thumbnail_id($chat_id);
if ($image_id) {
$image_src = wp_get_attachment_image_src($image_id, [100, 100]);
if ($image_src) {
$thread_item['image'] = $image_src[0];
}
}
}
$thread_item['chatRoom']['id'] = (int) $chat_id;
$template = $settings['template'];
$thread_item['chatRoom']['template'] = $template;
$thread_item['chatRoom']['modernLayout'] = $settings['modernLayout'];
$thread_item['chatRoom']['onlyJoinedCanRead'] = ( $settings['only_joined_can_read'] === '1' );
$thread_item['chatRoom']['enableFiles'] = ( $settings['enable_files'] === '1' );
$thread_item['chatRoom']['guestAllowed'] = in_array( 'bm-guest', $settings['can_join'] );
$thread_item['chatRoom']['mustJoinMessage'] = $settings['must_join_message'];
$thread_item['chatRoom']['joinButtonText'] = $settings['join_button_text'];
$thread_item['chatRoom']['notAllowedText'] = $settings['not_allowed_text'];
$thread_item['chatRoom']['notAllowedReplyText'] = $settings['not_allowed_reply_text'];
$thread_item['chatRoom']['mustLoginText'] = $settings['must_login_text'];
$thread_item['chatRoom']['loginButtonText'] = $settings['login_button_text'];
$thread_item['chatRoom']['guestButtonText'] = $settings['guest_button_text'];
if( $include_personal ) {
$is_moderator = user_can( $user_id, 'manage_options') || Better_Messages()->functions->is_thread_moderator( $thread_id, $user_id ) ;
$auto_join = $this->auto_join_enabled( $chat_id, $user_id );
if( $auto_join && ! $is_participant ){
$is_participant = $this->add_to_chat( $user_id, $chat_id );
}
$thread_item['chatRoom']['autoJoin'] = $auto_join;
$thread_item['chatRoom']['isJoined'] = $is_participant;
$thread_item['chatRoom']['canJoin'] = $this->user_can_join($user_id, $chat_id);
$thread_item['chatRoom']['hideParticipants'] = ( ! $is_moderator && $settings['hide_participants'] === '1' );
if ( ! $is_participant ) {
$thread_item['isHidden'] = 1;
$thread_item['permissions']['canReply'] = false;
$thread_item['permissions']['canMinimize'] = false;
$thread_item['permissions']['canMuteThread'] = false;
$thread_item['chatRoom']['hideParticipants'] = true;
} else {
$can_reply = $this->user_can_reply( $user_id, $chat_id );
if( $is_moderator ){
$thread_item['restricted'] = Better_Messages()->moderation->get_restricted_users( $thread_id );
}
$thread_item['permissions']['canReply'] = $can_reply;
if( ! $can_reply ){
if( count($thread_item['permissions']['canReplyMsg']) === 0 ) $thread_item['permissions']['canReplyMsg']['cant_reply_to_chat'] = $settings['not_allowed_reply_text'];
}
}
}
return $thread_item;
}
public function on_user_register( $user_id, $userdata = null ){
$roles = Better_Messages()->functions->get_user_roles( $user_id );
if( count($roles) === 0 ) return false;
global $wpdb;
$clauses = [];
foreach( $roles as $role ){
$clauses[] = $wpdb->prepare("( `postmeta`.`meta_key` = 'bpbm-chat-auto-add' AND `postmeta`.`meta_value` LIKE %s )", '%"' . $role . '"%');
}
$chat_ids = $wpdb->get_col("SELECT
`posts`.`ID`
FROM {$wpdb->posts} posts
INNER JOIN {$wpdb->postmeta} postmeta
ON ( `posts`.`ID` = `postmeta`.`post_id` )
WHERE 1=1
AND ( " . implode(' OR ', $clauses ) . " )
AND `posts`.`post_type` = 'bpbm-chat'
GROUP BY `posts`.ID");
if( count( $chat_ids ) > 0 ){
foreach ( $chat_ids as $chat_id ) {
$this->add_to_chat( $user_id, $chat_id );
}
}
}
public function guest_registered( $guest_id ){
global $wpdb;
$guest_id = -1 * abs( $guest_id );
$chat_ids = $wpdb->get_col("SELECT
`posts`.`ID`
FROM {$wpdb->posts} posts
INNER JOIN {$wpdb->postmeta} postmeta
ON ( `posts`.`ID` = `postmeta`.`post_id` )
WHERE 1=1
AND `postmeta`.`meta_key` = 'bpbm-chat-auto-add'
AND `postmeta`.`meta_value` LIKE '%bm-guest%'
AND `posts`.`post_type` = 'bpbm-chat'
GROUP BY `posts`.ID");
if( count( $chat_ids ) > 0 ){
foreach ( $chat_ids as $chat_id ) {
$this->add_to_chat( $guest_id, $chat_id );
}
}
}
public function on_user_role_change( $user_id, $role, $old_roles = [] ){
$old_roles[] = $role;
$this->sync_roles_update( array_unique( $old_roles ) );
}
public function on_chat_update( $post_ID, $post, $update ){
$thread_id = $this->get_chat_thread_id( $post_ID );
$name = get_the_title( $post_ID );
global $wpdb;
$wpdb->update(
bm_get_table('threads'),
array(
'subject' => $name,
),
array(
'id' => $thread_id,
),
array( '%s' ), array( '%d' )
);
wp_cache_delete( 'thread_' . $thread_id . '_type', 'bm_messages' );
wp_cache_delete( 'thread_' . $thread_id, 'bm_messages' );
}
public function on_chat_delete( $post_ID ){
$post = get_post( $post_ID );
if( $post->post_type === 'bpbm-chat' ){
$thread_id = $this->get_chat_thread_id( $post_ID );
Better_Messages()->functions->erase_thread( $thread_id );
}
}
public function on_message_sent( $message )
{
if( ! isset($message->thread_id) ) return false;
$thread_id = $message->thread_id;
$chat_id = Better_Messages()->functions->get_thread_meta( $thread_id, 'chat_id' );
if( ! $chat_id ) return false;
global $wpdb;
$wpdb->update(bm_get_table('recipients'), ['unread_count' => 0], ['thread_id' => $thread_id], ['%d'], ['%d']);
Better_Messages()->hooks->clean_thread_cache( $thread_id );
return true;
}
public function auto_join_enabled( $chat_id, $user_id ){
$settings = Better_Messages()->chats->get_chat_settings( $chat_id );
$auto_join = $settings['auto_join'] === '1';
if( ! $auto_join && isset($settings['auto_add']) && count($settings['auto_add']) > 0 ){
$user_roles = Better_Messages()->functions->get_user_roles($user_id);
$common_roles = array_intersect($user_roles, $settings['auto_add']);
if( count($common_roles) > 0 ){
$auto_join = true;
}
}
return $auto_join;
}
public function leave_chat( WP_REST_Request $request ){
global $wpdb;
$user_id = Better_Messages()->functions->get_current_user_id();
$chat_id = intval($request->get_param('id'));
$thread_id = $this->get_chat_thread_id( $chat_id );
$auto_join = $this->auto_join_enabled( $chat_id, $user_id );
if( $auto_join ){
return new WP_Error(
'rest_forbidden',
_x( 'Sorry, you are not allowed to do that', 'Rest API Error', 'bp-better-messages' ),
array( 'status' => rest_authorization_required_code() )
);
}
$result = false;
$userIsParticipant = (bool) $wpdb->get_var($wpdb->prepare("
SELECT COUNT(*) FROM `" . bm_get_table('recipients') . "` WHERE `user_id` = %d AND `thread_id` = %d
", $user_id, $thread_id));
if( $userIsParticipant ) {
$result = (bool) $wpdb->delete(
bm_get_table('recipients'),
array(
'user_id' => $user_id,
'thread_id' => $thread_id
),
array( '%d', '%d' )
);
}
Better_Messages()->hooks->clean_thread_cache( $thread_id );
do_action( 'better_messages_after_chat_left', $thread_id, $chat_id );
do_action( 'better_messages_thread_updated', $thread_id );
do_action( 'better_messages_info_changed', $thread_id );
$return = Better_Messages()->api->get_threads( [ $thread_id ], false, false );
$return['result'] = $result;
return $return;
}
public function join_chat( WP_REST_Request $request ){
$user_id = Better_Messages()->functions->get_current_user_id();
$chat_id = intval($request->get_param('id'));
$is_joined = $this->add_to_chat( $user_id, $chat_id );
$thread_id = $this->get_chat_thread_id( $chat_id );
$return = Better_Messages()->api->get_threads( [ $thread_id ], false, false );
$return['result'] = $is_joined;
return $return;
}
public function add_to_chat( $user_id, $chat_id ){
if( ! $this->user_can_join( $user_id, $chat_id ) ){
return false;
}
$thread_id = $this->get_chat_thread_id( $chat_id );
$result = Better_Messages()->functions->add_participant_to_thread( $thread_id, $user_id );
do_action( 'better_messages_after_chat_join', $thread_id, $chat_id );
do_action( 'better_messages_thread_updated', $thread_id );
do_action( 'better_messages_info_changed', $thread_id );
return $result;
}
public function register_post_type(){
$args = array(
'public' => false,
'labels' => [
'name' => _x( 'Chat Rooms', 'Chat Rooms', 'bp-better-messages' ),
'singular_name' => _x( 'Chat Room', 'Chat Rooms', 'bp-better-messages' ),
'add_new' => _x( 'Create new Chat Room', 'Chat Rooms', 'bp-better-messages' ),
'add_new_item' => _x( 'Create new Chat Room', 'Chat Rooms', 'bp-better-messages' ),
'edit_item' => _x( 'Edit Chat Room', 'Chat Rooms', 'bp-better-messages' ),
'new_item' => _x( 'New Chat Room', 'Chat Rooms', 'bp-better-messages' ),
'featured_image' => _x( 'Chat Thumbnail', 'Chat Rooms', 'bp-better-messages' ),
'set_featured_image' => _x( 'Set chat thumbnail', 'Chat Rooms', 'bp-better-messages' ),
'remove_featured_image' => _x( 'Remove chat thumbnail', 'Chat Rooms', 'bp-better-messages' ),
'use_featured_image' => _x( 'Use as chat thumbnail', 'Chat Rooms', 'bp-better-messages' ),
],
'publicly_queryable' => false,
'show_ui' => true,
'show_in_menu' => 'bp-better-messages',
'menu_position' => 1,
'query_var' => false,
'capability_type' => 'page',
'has_archive' => false,
'hierarchical' => false,
'show_in_admin_bar' => false,
'show_in_nav_menus' => false,
'supports' => array( 'title', 'thumbnail' ),
'register_meta_box_cb' => array( $this, 'register_meta_box' )
);
register_post_type( 'bpbm-chat', $args );
}
public function register_meta_box(){
add_meta_box(
'bm-chat-settings',
_x( 'Settings', 'Chat rooms settings page', 'bp-better-messages' ),
array( $this, 'bpbm_chat_settings' ),
null,
'advanced'
);
/*add_meta_box(
'bm-chat-participants',
_x( 'Participants', 'Chat rooms settings page', 'bp-better-messages' ),
array( $this, 'chat_participants' ),
null,
'normal'
);*/
}
public function chat_participants( $post ){
echo '<div class="bm-chat-participants" data-chat-id="' . intval( $post->ID ) . '">' . __( 'Loading', 'bp-better-messages' ) . '</div>';
}
public function get_chat_settings( $chat_id ){
$defaults = array(
'only_joined_can_read' => '0',
'enable_chat_email_notifications' => '0',
'can_join' => [],
'can_reply' => [],
'auto_add' => [],
'template' => 'default',
'modernLayout' => 'default',
'auto_join' => '0',
'auto_exclude' => '0',
'enable_notifications' => '0',
'allow_guests' => '0',
'hide_participants' => '0',
'enable_files' => '0',
'hide_from_thread_list' => '1',
'must_join_message' => _x('You need to join this chat room to send messages', 'Chat rooms settings page', 'bp-better-messages'),
'join_button_text' => _x('Join chat room', 'Chat rooms settings page', 'bp-better-messages'),
'not_allowed_text' => _x('You are not allowed to join this chat room', 'Chat rooms settings page', 'bp-better-messages'),
'not_allowed_reply_text' => _x('You are not allowed to reply in this chat room', 'Chat rooms settings page', 'bp-better-messages'),
'must_login_text' => _x('You need to login to website to send messages', 'Chat rooms settings page', 'bp-better-messages'),
'login_button_text' => _x('Login', 'Chat rooms settings page', 'bp-better-messages'),
'guest_button_text' => _x('Chat as Guest', 'Chat rooms settings page', 'bp-better-messages')
);
$args = get_post_meta( $chat_id, 'bpbm-chat-settings', true );
if( empty($args) || ! is_array($args) ){
$args = array();
}
$result = wp_parse_args( $args, $defaults );
if( isset($result['allow_guests_chat']) && $result['allow_guests_chat'] === '1' ){
$result['can_join'][] = 'bm-guest';
$result['can_reply'][] = 'bm-guest';
}
return $result;
}
public function save_post( $post_id, $post ){
if( ! isset($_POST['bpbm_save_chat_nonce']) ){
return $post->ID;
}
//Verify it came from proper authorization.
if ( ! wp_verify_nonce($_POST['bpbm_save_chat_nonce'], 'bpbm-save-chat-settings-' . $post->ID ) ) {
return $post->ID;
}
//Check if the current user can edit the post
if ( ! current_user_can( 'manage_options' ) ) {
return $post->ID;
}
$thread_id = $this->get_chat_thread_id( $post->ID );
if( isset( $_POST['bpbm'] ) && is_array($_POST['bpbm']) ){
$settings = (array) $_POST['bpbm'];
if ( ! isset( $settings['only_joined_can_read'] ) ) {
$settings['only_joined_can_read'] = '0';
}
if ( ! isset( $settings['auto_join'] ) ) {
$settings['auto_join'] = '0';
}
if ( ! isset( $settings['auto_exclude'] ) ) {
$settings['auto_exclude'] = '0';
Better_Messages()->functions->delete_thread_meta( $thread_id, 'auto_exclude_hash' );
}
if ( ! isset( $settings['hide_participants'] ) ) {
$settings['hide_participants'] = '0';
}
if ( ! isset( $settings['enable_chat_email_notifications'] ) ) {
$settings['enable_chat_email_notifications'] = '0';
}
if ( ! isset( $settings['enable_files'] ) ) {
$settings['enable_files'] = '0';
}
if ( ! isset( $settings['hide_from_thread_list'] ) ) {
$settings['hide_from_thread_list'] = '0';
}
if ( ! isset( $settings['enable_notifications'] ) ) {
$settings['enable_notifications'] = '0';
}
if ( ! isset( $settings['allow_guests'] ) ) {
$settings['allow_guests'] = '0';
}
if ( ! isset( $settings['must_join_message'] ) || empty( $settings['must_join_message'] ) ) {
$settings['must_join_message'] = _x('You need to join this chat room to send messages', 'Chat rooms settings page', 'bp-better-messages');
} else {
$settings['must_join_message'] = wp_kses( $settings['must_join_message'], 'user_description' );
}
if ( ! isset( $settings['join_button_text'] ) || empty( $settings['join_button_text'] ) ) {
$settings['join_button_text'] = _x('Join chat room', 'Chat rooms settings page', 'bp-better-messages');
} else {
$settings['join_button_text'] = sanitize_text_field( $settings['join_button_text'] );
}
if ( ! isset( $settings['login_button_text'] ) || empty( $settings['login_button_text'] ) ) {
$settings['login_button_text'] = _x('Login', 'Chat rooms settings page', 'bp-better-messages');
} else {
$settings['login_button_text'] = sanitize_text_field( $settings['login_button_text'] );
}
if ( ! isset( $settings['guest_button_text'] ) || empty( $settings['guest_button_text'] ) ) {
$settings['guest_button_text'] = _x('Chat as Guest', 'Chat rooms settings page', 'bp-better-messages');
} else {
$settings['guest_button_text'] = sanitize_text_field( $settings['guest_button_text'] );
}
if ( ! isset( $settings['must_login_text'] ) || empty( $settings['must_login_text'] ) ) {
$settings['must_login_text'] = _x('You need to login to website to send messages', 'Chat rooms settings page', 'bp-better-messages');
} else {
$settings['must_login_text'] = wp_kses( $settings['must_login_text'], 'user_description' );
}
if ( ! isset( $settings['not_allowed_text'] ) || empty( $settings['not_allowed_text'] ) ) {
$settings['not_allowed_text'] = _x('You are not allowed to join this chat room', 'Chat rooms settings page', 'bp-better-messages');
} else {
$settings['not_allowed_text'] = wp_kses( $settings['not_allowed_text'], 'user_description' );
}
if ( ! isset( $settings['not_allowed_reply_text'] ) || empty( $settings['not_allowed_reply_text'] ) ) {
$settings['not_allowed_reply_text'] = _x('You are not allowed to reply in this chat room', 'Chat rooms settings page', 'bp-better-messages');
} else {
$settings['not_allowed_reply_text'] = wp_kses( $settings['not_allowed_reply_text'], 'user_description' );
}
update_post_meta( $post->ID, 'bpbm-chat-settings', $settings );
$notifications_enabled = true;
if( $settings['hide_from_thread_list'] === '1' ) {
Better_Messages()->functions->update_thread_meta($thread_id, 'exclude_from_threads_list', '1');
$notifications_enabled = false;
} else {
Better_Messages()->functions->delete_thread_meta($thread_id, 'exclude_from_threads_list');
}
if( $settings['enable_notifications'] === '1' ) {
Better_Messages()->functions->update_thread_meta($thread_id, 'enable_notifications', '1');
} else {
Better_Messages()->functions->delete_thread_meta($thread_id, 'enable_notifications');
$notifications_enabled = false;
}
if( ! $notifications_enabled ){
Better_Messages()->functions->update_thread_meta($thread_id, 'email_disabled', '1');
} else {
Better_Messages()->functions->delete_thread_meta( $thread_id, 'email_disabled' );
}
if( isset( $settings['can_join'] ) ) {
update_post_meta( $post->ID, 'bpbm-chat-can-join', $settings['can_join'] );
} else {
delete_post_meta( $post->ID, 'bpbm-chat-can-join' );
Better_Messages()->functions->delete_thread_meta( $thread_id, 'auto_exclude_hash' );
}
if( isset( $settings['auto_add'] ) ) {
update_post_meta( $post->ID, 'bpbm-chat-auto-add', $settings['auto_add'] );
} else {
delete_post_meta( $post->ID, 'bpbm-chat-auto-add' );
Better_Messages()->functions->delete_thread_meta( $thread_id, 'auto_add_hash' );
}
$this->sync_auto_add_users( $post->ID );
do_action( 'better_messages_thread_updated', $thread_id );
do_action( 'better_messages_info_changed', $thread_id );
}
}
public function bpbm_chat_settings( $post ){
$roles = get_editable_roles();
if(isset($roles['administrator'])) unset( $roles['administrator'] );
$roles['bm-guest'] = [
'name' => _x('Guests', 'Settings page', 'bp-better-messages' )
];
wp_nonce_field( 'bpbm-save-chat-settings-' . $post->ID, 'bpbm_save_chat_nonce' );
$settings = $this->get_chat_settings( $post->ID ); ?>
<div class="bm-chat-settings" data-chat-id="<?php echo esc_attr($post->ID); ?>" data-settings="<?php echo esc_attr(json_encode($settings)); ?>" data-roles="<?php echo esc_attr(json_encode($roles)); ?>">
<p style="text-align: center"><?php _ex( 'Loading', 'WP Admin', 'bp-better-messages' ); ?></p>
</div>
<?php
}
public function layout( $args ){
$chat_id = $args['id'];
$disable_init = isset($args['disable_auto_init']);
if (defined('WP_DEBUG') && true === WP_DEBUG) {
// some debug to add later
} else {
error_reporting(0);
}
$thread_id = $this->get_chat_thread_id( $chat_id );
if( ! $thread_id ) return false;
$chat_settings = $this->get_chat_settings( $chat_id );
if( ! is_user_logged_in() ){
$allow_guests = $chat_settings['allow_guests'] === '1';
if( ! $allow_guests ) {
return Better_Messages()->functions->render_login_form();
} else {
Better_Messages()->enqueue_js();
Better_Messages()->enqueue_css();
add_action('wp_footer', array( Better_Messages_Customize(), 'header_output' ), 100);
}
}
$this->sync_auto_add_users( $chat_id );
global $bpbm_errors;
$bpbm_errors = [];
do_action('bp_better_messages_before_chat', $chat_id, $thread_id );
ob_start();
if( ! Better_Messages()->functions->is_ajax() && count( $bpbm_errors ) > 0 ) {
echo '<p class="bpbm-notice">' . implode('</p><p class="bpbm-notice">', $bpbm_errors) . '</p>';
}
$initialHeight = (int) apply_filters( 'bp_better_messages_max_height', Better_Messages()->settings['messagesHeight'] );
$class = 'bp-messages-chat-wrap';
if( $disable_init ) $class .= ' bm-disable-auto-init';
echo '<div class="' . $class . '" style="height: ' . $initialHeight . 'px" data-thread-id="' . esc_attr($thread_id) . '" data-chat-id="' . esc_attr($chat_id) . '">' . Better_Messages()->functions->container_placeholder() . '</div>';
$content = ob_get_clean();
$content = str_replace( 'loading="lazy"', '', $content );
$content = Better_Messages()->functions->minify_html( $content );
do_action('bp_better_messages_after_chat', $chat_id, $thread_id);
return $content;
}
public function user_can_join( $user_id, $chat_id ){
if( user_can( $user_id, 'manage_options') ) return true;
$settings = $this->get_chat_settings( $chat_id );
$thread_id = $this->get_chat_thread_id( $chat_id );
$has_access = false;
$user_roles = Better_Messages()->functions->get_user_roles($user_id);
foreach ($user_roles as $role) {
if (in_array($role, $settings['can_join'])) {
$has_access = true;
}
}
return apply_filters( 'better_messages_chat_user_can_join', $has_access, $user_id, $chat_id, $thread_id );
}
public function user_can_reply( $user_id, $chat_id ){
if( user_can( $user_id, 'manage_options') ) return true;
$settings = $this->get_chat_settings( $chat_id );
$thread_id = $this->get_chat_thread_id( $chat_id );
$has_access = false;
$user_roles = Better_Messages()->functions->get_user_roles($user_id);
foreach ($user_roles as $role) {
if (in_array($role, $settings['can_reply'])) {
$has_access = true;
}
}
return Better_Messages()->functions->can_send_message_filter( $has_access, $user_id, $thread_id );
}
public function get_chat_thread_id( $chat_id ){
global $wpdb;
$thread_id = (int) $wpdb->get_var( $wpdb->prepare( "
SELECT bm_thread_id
FROM `" . bm_get_table('threadsmeta') . "`
WHERE `meta_key` = 'chat_id'
AND `meta_value` = %s
", $chat_id ) );
if( $thread_id === 0 ) {
$thread_id = false;
} else {
$messages_count = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM `" . bm_get_table('threads') . "` WHERE `id` = %d", $thread_id));
if( $messages_count === 0 ) {
$thread_id = false;
}
}
if( ! $thread_id ) {
$chat = get_post($chat_id);
if( ! $chat ) return false;
$wpdb->query( $wpdb->prepare( "
DELETE
FROM `" . bm_get_table('threadsmeta') . "`
WHERE `meta_key` = 'chat_id'
AND `meta_value` = %s
", $chat_id ) );
$name = get_the_title( $chat_id );
$wpdb->insert(
bm_get_table('threads'),
array(
'subject' => $name,
'type' => 'chat-room'
)
);
$thread_id = $wpdb->insert_id;
Better_Messages()->functions->update_thread_meta( $thread_id, 'chat_thread', true );
Better_Messages()->functions->update_thread_meta( $thread_id, 'chat_id', $chat_id );
wp_cache_delete( 'thread_' . $thread_id . '_type', 'bm_messages' );
wp_cache_delete( 'thread_' . $thread_id, 'bm_messages' );
}
return $thread_id;
}
public function sync_roles_update( $roles = [] ){
if( count( $roles ) === 0 ) return false;
global $wpdb;
$clauses = [];
foreach( $roles as $role ){
$clauses[] = $wpdb->prepare("( `postmeta`.`meta_key` = 'bpbm-chat-auto-add' AND `postmeta`.`meta_value` LIKE %s )", '%"' . $role . '"%');
}
$chat_ids = $wpdb->get_col("SELECT
`posts`.`ID`
FROM {$wpdb->posts} posts
INNER JOIN {$wpdb->postmeta} postmeta
ON ( `posts`.`ID` = `postmeta`.`post_id` )
WHERE 1=1
AND ( " . implode(' OR ', $clauses ) . " )
AND `posts`.`post_type` = 'bpbm-chat'
GROUP BY `posts`.ID");
foreach( $chat_ids as $chat_id ){
if( ! wp_get_scheduled_event( 'better_messages_chat_room_sync_auto_add_users', [ $chat_id ] ) ){
wp_schedule_single_event( time(), 'better_messages_chat_room_sync_auto_add_users', [ $chat_id ] );
}
}
}
public function sync_auto_add_users( $chat_id ){
$thread_id = $this->get_chat_thread_id( $chat_id );
if( ! $thread_id ) return false;
$settings = Better_Messages()->chats->get_chat_settings( $chat_id );
$auto_exclude = $settings['auto_exclude'] === '1';
$auto_add = count( $settings['auto_add'] ) > 0;
if( ! $auto_add && ! $auto_exclude ) {
return false;
}
$changed = false;
set_time_limit(0);
ignore_user_abort(true);
ini_set('memory_limit', '-1');
global $wpdb;
if( $auto_add ){
$roles = [];
foreach ( $settings['auto_add'] as $role ){
$roles[] = $wpdb->prepare('%s', $role );
}
$users_hash_sql = $wpdb->prepare("
SELECT MD5(GROUP_CONCAT(DISTINCT(`roles`.`user_id`))) as users_hash
FROM `" . bm_get_table('roles') . "` `roles`
LEFT JOIN `" . bm_get_table('moderation') . "` `moderation`
ON `roles`.`user_id` = `moderation`.`user_id`
AND `moderation`.`thread_id` = %d
AND `moderation`.`type` = 'ban'
WHERE `roles`.`role` IN (". implode(',', $roles ) .")
AND `moderation`.`user_id` IS NULL
ORDER BY `roles`.`user_id` ASC", $thread_id);
$users_hash = $wpdb->get_var($users_hash_sql);
$thread_hash = Better_Messages()->functions->get_thread_meta( $thread_id, 'auto_add_hash' );
if( $users_hash !== $thread_hash ){
$not_added_users_count_sql = $wpdb->prepare("
SELECT COUNT(DISTINCT(`roles`.`user_id`)) as user_ids
FROM `" . bm_get_table('roles') . "` `roles`
LEFT JOIN `" . bm_get_table('recipients') . "` `recipients`
ON `roles`.`user_id` = `recipients`.`user_id`
AND `recipients`.`thread_id` = %d
LEFT JOIN `" . bm_get_table('moderation') . "` `moderation`
ON `roles`.`user_id` = `moderation`.`user_id`
AND `moderation`.`thread_id` = %d
AND `moderation`.`type` = 'ban'
AND `moderation`.`expiration` > NOW()
WHERE `roles`.`role` IN (". implode(',', $roles ) .")
AND `recipients`.`user_id` IS NULL
AND `moderation`.`user_id` IS NULL", $thread_id, $thread_id);
$not_added_users_count = (int) $wpdb->get_var($not_added_users_count_sql);
if( $not_added_users_count > 0 ){
$insert_sql = $wpdb->prepare("
INSERT INTO " . bm_get_table('recipients') . " (user_id, thread_id, unread_count, is_deleted)
SELECT DISTINCT(`roles`.`user_id`) as user_id, %d, 0, 0
FROM `" . bm_get_table('roles') . "` `roles`
LEFT JOIN `" . bm_get_table('recipients') . "` `recipients`
ON `roles`.`user_id` = `recipients`.`user_id`
AND `recipients`.`thread_id` = %d
LEFT JOIN `" . bm_get_table('moderation') . "` `moderation`
ON `roles`.`user_id` = `moderation`.`user_id`
AND `moderation`.`thread_id` = %d
AND `moderation`.`type` = 'ban'
AND `moderation`.`expiration` > NOW()
WHERE `roles`.`role` IN (" . implode(',', $roles) . ")
AND `recipients`.`user_id` IS NULL
AND `moderation`.`user_id` IS NULL", $thread_id, $thread_id, $thread_id);
$wpdb->query($insert_sql);
$changed = true;
}
Better_Messages()->functions->update_thread_meta( $thread_id, 'auto_add_hash', $users_hash );
}
}
if( $auto_exclude ){
$not_exclude_roles = [
"'administrator'"
];
foreach ( $settings['can_join'] as $role ){
$not_exclude_roles[] = $wpdb->prepare('%s', $role );
}
$users_hash_sql = "SELECT MD5(GROUP_CONCAT(DISTINCT(`roles`.`user_id`))) as users_hash
FROM `" . bm_get_table('roles') . "` `roles`
WHERE `roles`.`role` IN (". implode(',', $not_exclude_roles ) .")
ORDER BY `roles`.`user_id` ASC";
$users_hash = $wpdb->get_var($users_hash_sql);
$thread_hash = Better_Messages()->functions->get_thread_meta( $thread_id, 'auto_exclude_hash' );
if( $users_hash !== $thread_hash ){
$to_exclude_users_sql = $wpdb->prepare("
SELECT DISTINCT(`roles`.`user_id`) as user_id
FROM `" . bm_get_table('roles') . "` `roles`
LEFT JOIN `" . bm_get_table('recipients') . "` `recipients`
ON `roles`.`user_id` = `recipients`.`user_id`
AND `recipients`.`thread_id` = %d
WHERE `recipients`.`user_id` NOT IN (
SELECT DISTINCT(`roles`.`user_id`) as user_id
FROM `" . bm_get_table('roles') . "` `roles`
LEFT JOIN `" . bm_get_table('recipients') . "` `recipients`
ON `roles`.`user_id` = `recipients`.`user_id`
AND `recipients`.`thread_id` = %d
WHERE `roles`.`role` IN (". implode(',', $not_exclude_roles ) .")
AND `recipients`.`user_id` IS NOT NULL
)", $thread_id, $thread_id);
$to_exclude_users = array_map('intval', $wpdb->get_col($to_exclude_users_sql));
if( count($to_exclude_users) > 0 ){
$delete_sql = $wpdb->prepare("
DELETE FROM `" . bm_get_table('recipients') . "`
WHERE `user_id` IN (" . implode(',', $to_exclude_users) . ")
AND `thread_id` = %d", $thread_id);
$wpdb->query( $delete_sql );
$changed = true;
}
Better_Messages()->functions->update_thread_meta( $thread_id, 'auto_exclude_hash', $users_hash );
}
}
if( $changed ) {
Better_Messages()->hooks->clean_thread_cache($thread_id);
do_action('better_messages_thread_updated', $thread_id);
do_action('better_messages_info_changed', $thread_id);
}
}
}
function Better_Messages_Chats()
{
return Better_Messages_Chats::instance();
}