prefix . 'arwp_sessions'; $table_messages = $wpdb->prefix . 'arwp_messages'; $wpdb->delete( $table_messages, array( 'session_id' => $session_id ), array( '%d' ) ); $wpdb->delete( $table_sessions, array( 'id' => $session_id ), array( '%d' ) ); } $redirect = admin_url( 'edit.php?post_type=arwp_agent&page=arwp-conversations' ); if ( ! empty( $_GET['agent_id'] ) ) { $redirect = add_query_arg( 'agent_id', intval( $_GET['agent_id'] ), $redirect ); } wp_safe_redirect( $redirect ); exit; } /** * Render list or single-session view. */ public function render_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } // Read-only admin screen navigation (which session to view / which page); intval()-cast, no data is written. $session_id = isset( $_GET['session_id'] ) ? intval( $_GET['session_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( $session_id ) { $this->render_session_view( $session_id ); return; } $this->render_list_view(); } /** * Paginated session list. */ private function render_list_view() { global $wpdb; $table_sessions = $wpdb->prefix . 'arwp_sessions'; $table_messages = $wpdb->prefix . 'arwp_messages'; $per_page = 20; // Read-only pagination/filter params, intval()-cast, no data is written. $paged = isset( $_GET['paged'] ) ? max( 1, intval( $_GET['paged'] ) ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $offset = ( $paged - 1 ) * $per_page; $agent_filter = isset( $_GET['agent_id'] ) ? intval( $_GET['agent_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $where = '1=1'; $params = array(); if ( $agent_filter ) { $where .= ' AND s.agent_id = %d'; $params[] = $agent_filter; } // $where only ever concatenates the static ' AND s.agent_id = %d' fragment above; the value itself is always bound through prepare() via $count_params, never interpolated raw. $count_sql = "SELECT COUNT(*) FROM %i s WHERE $where"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $count_params = array_merge( array( $table_sessions ), $params ); $total = (int) $wpdb->get_var( $wpdb->prepare( $count_sql, $count_params ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $total_pages = max( 1, (int) ceil( $total / $per_page ) ); // Same $where fragment as above -- safe, values bound via $list_params, never interpolated raw. $list_sql = "SELECT s.*, (SELECT COUNT(*) FROM %i m WHERE m.session_id = s.id AND m.role != 'system') AS message_count, (SELECT COALESCE(SUM(tokens_used),0) FROM %i m WHERE m.session_id = s.id) AS tokens_used FROM %i s WHERE $where ORDER BY s.created_at DESC LIMIT %d OFFSET %d"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $list_params = array_merge( array( $table_messages, $table_messages, $table_sessions ), $params ); $list_params[] = $per_page; $list_params[] = $offset; $sessions = $wpdb->get_results( $wpdb->prepare( $list_sql, $list_params ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter $agents = get_posts( array( 'post_type' => 'arwp_agent', 'posts_per_page' => -1, 'post_status' => 'any', ) ); ?>

'arwp_agent', 'page' => 'arwp-conversations', 'session_id' => $session->id, ), admin_url( 'edit.php' ) ); $delete_url = wp_nonce_url( add_query_arg( array( 'action' => 'arwp_delete_session', 'session_id' => $session->id, 'agent_id' => $agent_filter, ), admin_url( 'admin-post.php' ) ), 'arwp_delete_session' ); $user_label = intval( $session->user_id ) > 0 ? $this->user_label( $session->user_id ) : __( 'Guest', 'arwp-agents' ); $chat_title = arwp_redact_personal_details( $session->title ? $session->title : __( 'Untitled', 'arwp-agents' ) ); ?>
agent_id ); echo esc_html( $agent_title ? $agent_title : '#' . intval( $session->agent_id ) ); ?> message_count ) ); ?> tokens_used ) ) ); ?> created_at ); ?> |
1 ) : ?>
add_query_arg( 'paged', '%#%' ), 'format' => '', 'prev_text' => '«', 'next_text' => '»', 'total' => $total_pages, 'current' => $paged, ) ) ); ?>
prefix . 'arwp_sessions'; $table_messages = $wpdb->prefix . 'arwp_messages'; $session = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM %i WHERE id = %d', $table_sessions, $session_id ) ); if ( ! $session ) { echo '

' . esc_html__( 'Conversation not found.', 'arwp-agents' ) . '

'; return; } $messages = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE session_id = %d ORDER BY id ASC', $table_messages, $session_id ) ); $back_url = admin_url( 'edit.php?post_type=arwp_agent&page=arwp-conversations' ); $delete_url = wp_nonce_url( add_query_arg( array( 'action' => 'arwp_delete_session', 'session_id' => $session->id, ), admin_url( 'admin-post.php' ) ), 'arwp_delete_session' ); ?>

title ? $session->title : __( 'Untitled', 'arwp-agents' ) ) ); ?>

← |

agent_id ) ); ?>
user_id ) > 0 ? $this->user_label( $session->user_id ) : __( 'Guest', 'arwp-agents' ) ); ?>
created_at ); ?>

role ) ); ?> · created_at ); ?> tokens_used ) ) : ?> · tokens_used ) ) ); ?>

content ) ); ?>
0 ? __( 'Logged-in visitor', 'arwp-agents' ) : __( 'Guest', 'arwp-agents' ); } if ( $user_id <= 0 ) { return __( 'Guest', 'arwp-agents' ); } $user = get_userdata( $user_id ); if ( ! $user ) { return '#' . $user_id; } return $user->display_name . ' (' . $user->user_login . ')'; } }