PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.3.8
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.3.8
8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 8.5.2 All 533 releases
← All changes | includes/admin/templates/rag.php +35 -207 8.7.48.3.8 View file →
@@ -3,13 +3,10 @@
3 3 /**
4 4 * AI Assistant Template - RAG Feature Extended
5 5 * @package Botmaster
6 6 */
7 -if (get_option('wpchatbot_license_valid') == 'master' && get_option('wpchatbot_license_valid') == 'professional') {
8 - update_option('wpchatbot_license_valid', 'starter');
9 -}
10 7
11 -$wpchatbot_license_valid = get_option('wpchatbot_license_valid');
8 +$wpchatbot_license_valid = get_option('wpchatbot_license_valid');
12 9 // $wpchatbot_license_valid = 'starter';
13 10
14 11 ?>
15 12
@@ -18,9 +15,8 @@
18 15
19 16
20 17 <h2 class="nav-tab-wrapper">
21 18 <a href="#qcld-rag-settings-tab" class="nav-tab nav-tab-active"> Setting options</a>
22 - <a href="#qcld-rag-settings-sql" class="nav-tab">RAG from DB Tables</a>
23 19 <a href="#rag-sync" class="nav-tab">Sync and upload options</a>
24 20 <a href="#rag-sources" class="nav-tab">Manage Sources</a>
25 21 <a href="#rag-database" class="nav-tab">KnowledgeBase Database</a>
26 22 </h2>
@@ -26,10 +22,10 @@
26 22 </h2>
27 23
28 24 <div id="qcld-rag-settings-tab" class="qcld-tab-content active">
29 25 <!-- ===========================
30 - EMBEDDING SOURCE OPTIONS
31 - ============================ -->
26 + EMBEDDING SOURCE OPTIONS
27 + ============================ -->
32 28 <div class="wrap">
33 29 <h3>Choose Data Sources to Embed</h3>
34 30
35 31 <div class="mb-3">
@@ -65,34 +61,12 @@
65 61 <?php endforeach; ?>
66 62 </div>
67 63 <p class="description">Select multiple custom post types to embed.</p>
68 64 </div>
69 - <div class="mb-4" style="background: #f9f9f9; padding: 15px; border-radius: 8px; border-left: 4px solid #007bff;">
70 - <h4 style="margin-top: 0;"><i class="fa fa-tags"></i> Post Meta Data Settings <span class="pro-badge" style="display:inline-block; margin-left:8px; padding:2px 6px; background:#f0b429; color:#fff; border-radius:3px; font-size:11px; font-weight:bold; text-transform:uppercase;">PRO</span></h4>
71 - <div class="mb-3">
72 - <input type="checkbox" id="rag_embed_meta" <?php checked(get_option('rag_embed_meta'), '1'); ?> disabled>
73 - <label for="rag_embed_meta"><strong>Include Post Meta Data</strong></label>
74 - <p class="description">Enable this to include custom fields/meta data in the embeddings.</p>
75 - </div>
76 65
77 - <div class="mb-3">
78 - <label for="rag_embed_meta_keys"><strong>Meta Keys to Include (comma separated):</strong></label><br>
79 - <input type="text" id="rag_embed_meta_keys" value="<?php echo esc_attr(get_option('rag_embed_meta_keys', '')); ?>" placeholder="e.g. _price, _sku, custom_field_key" style="width: 100%; max-width: 400px; margin-top: 5px;" disabled>
80 - <p class="description">Specify the meta keys you want to include in the context. Leave empty to include all meta (not recommended).</p>
81 - </div>
82 - </div>
83 66
84 67 </div>
85 - <div class="wrap">
86 - <h3>Sync Settings</h3>
87 -
88 - <div class="mb-3">
89 - <input type="checkbox" id="rag_auto_sync_enabled" class="rag_auto_sync_enabled" <?php checked(get_option('rag_auto_sync_enabled'), '1'); ?>>
90 - <label for="rag_auto_sync_enabled"><strong>Enable Auto Sync (on Save)</strong></label>
91 - <p class="description">Automatically update embeddings when a post or product is saved/updated.</p>
92 - </div>
93 - </div>
94 - <!-- ===========================
68 + <!-- ===========================
95 69 EXECUTION BUTTON
96 70 ============================ -->
97 71 <div class="wrap my-4">
98 72 <p style="color: red"> <b><?php esc_html_e('Please connect to an AI service like OpenAI or Gemini before embedding. ', 'chatbot'); ?></b><b><a target="_blank" href="https://wpbot.pro/docs/knowledgebase/how-to-use-an-embedded-vector-database-and-rag-to-get-customized-responses-from-ai/"><?php esc_html_e('Check this Tutorial for more details.', 'chatbot'); ?></a></b></p>
@@ -122,154 +96,10 @@
122 96 <div class="wrap">
123 97 <button class="qcld-btn-primary" id="save_rag_setting">Save Settings</button>
124 98 </div>
125 99 </div>
126 - <div id="qcld-rag-settings-sql" class="qcld-tab-content">
127 -
128 - <div class="wrap">
129 - <h3>Choose Data Sources to Embed</h3>
130 - <?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'): ?>
131 - <div class="wrap">
132 - <div style="background-color: #fee; border: 1px solid #c33; padding: 15px; margin: 20px 0; border-radius: 4px;">
133 - <p style="color: #c33; font-weight: bold; margin: 0; font-size: 14px;">
134 - These options are available with the WPBot Pro <a href="https://www.wpbot.pro/pricing/" target="_blank" style="color: #c33; text-decoration: underline;">Professional</a> and <a href="https://www.wpbot.pro/pricing/" target="_blank" style="color: #c33; text-decoration: underline;">Master</a> Licenses
135 - </p>
136 - </div>
137 - </div>
138 - <?php endif; ?>
139 - <div class="mb-3" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
140 - <input type="checkbox" id="rag_embed_sql" checked disabled <?php checked(get_option('rag_embed_sql'), '1'); ?>>
141 - <label for="rag_embed_sql">Database Table (SQL)</label>
142 - <div id="rag_sql_options" style="">
143 - <table id="rag_sql_tables_list" class="wp-list-table widefat striped" style="max-width: 600px; margin-bottom: 10px;">
144 - <thead>
145 - <tr>
146 - <th>Table Name</th>
147 - <th>Table Field(s)</th>
148 - <th>Actions</th>
149 - </tr>
150 - </thead>
151 - <tbody>
152 - <?php
153 - $sql_tables = get_option('rag_sql_tables', []);
154 - if (!is_array($sql_tables) && !empty($sql_tables)) {
155 - $sql_tables = json_decode($sql_tables, true);
156 - }
157 -
158 - if (empty($sql_tables)) {
159 - $table_name = get_option('rag_sql_table_name', '');
160 - $table_field = get_option('rag_sql_table_field', '');
161 - if ($table_name && $table_field) {
162 - $sql_tables[] = ['table_name' => $table_name, 'table_field' => $table_field];
163 - }
164 - }
165 100
166 - if (!empty($sql_tables)) {
167 - foreach ($sql_tables as $table) {
168 - ?>
169 - <tr>
170 - <td><input type="text" name="rag_sql_table_name[]" value="<?php echo esc_attr($table['table_name']); ?>" class="regular-text" style="width:100%;"></td>
171 - <td><input type="text" name="rag_sql_table_field[]" value="<?php echo esc_attr($table['table_field']); ?>" class="regular-text" style="width:100%;"></td>
172 - <td><button type="button" class="button button-link-delete rag_sql_remove_table">Remove</button></td>
173 - </tr>
174 - <?php
175 - }
176 - } else {
177 - ?>
178 - <tr>
179 - <td><input type="text" name="rag_sql_table_name[]" value="" placeholder="e.g. wp_users" class="regular-text" style="width:100%;"></td>
180 - <td><input type="text" name="rag_sql_table_field[]" value="" placeholder="e.g. user_email" class="regular-text" style="width:100%;"></td>
181 - <td><button type="button" class="button button-link-delete rag_sql_remove_table">Remove</button></td>
182 - </tr>
183 - <?php
184 - }
185 - ?>
186 - </tbody>
187 - </table>
188 - <button type="button" class="button button-primary" id="rag_sql_add_table">Add New Table</button>
189 - <button type="button" class="button button-secondary" id="sql_instruction" style="margin-left: 5px;">View Available SQL Tables & Fields</button>
190 - <p class="description">Add multiple tables and fields. Separate multiple fields in the same table with commas. Click "Create Missing Tables" to generate empty tables in the database if they don't exist.</p>
191 - </div>
192 - <!-- New Section for Google Sheets to SQL Sync -->
193 - <div id="rag_sql_sheets_section" style="display:block; margin-top: 20px; margin-left: 20px; padding: 15px; border: 1px solid #ccc; background: #f9f9f9;">
194 - <h4>Google Sheets & CSV Database Sync</h4>
195 - <p class="description">Directly import Google Sheets or upload CSV data into SQL tables for Text-to-SQL querying.</p>
196 -
197 - <div style="margin-bottom: 15px;">
198 - <label style="display:block; font-weight:bold; margin-bottom:5px;">Import via Google Sheet URL:</label>
199 - <input type="text" id="rag_sql_sheet_url_input" placeholder="Enter Google Sheet or CSV URL" class="regular-text" style="width: 60%; margin-right: 5px;">
200 - <button type="button" class="button button-primary" id="rag_sql_import_sheet">Import URL to SQL</button>
201 - </div>
202 101
203 - <div style="margin-bottom: 15px;">
204 - <label style="display:block; font-weight:bold; margin-bottom:5px;">Upload a Local CSV File:</label>
205 - <input type="file" id="rag_sql_csv_file_input" accept=".csv" style="margin-right: 5px;">
206 - <button type="button" class="button button-primary" id="rag_sql_upload_csv">Upload CSV to SQL</button>
207 - </div>
208 -
209 - <hr style="margin: 15px 0;">
210 - <p>Sync all your previously uploaded sheets into SQL tables:</p>
211 - <button type="button" class="button button-secondary" id="rag_sql_sync_existing_sheets">Sync Existing Sheets to SQL</button>
212 -
213 - <div id="rag_sql_sync_status" style="margin-top: 10px; font-weight: bold;"></div>
214 - </div>
215 - </div>
216 - <br><br>
217 - <div class="mb-3" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?> ">
218 - <input type="checkbox" id="rag_sql_auto_sync_enabled" <?php checked(get_option('rag_sql_auto_sync_enabled'), '1'); ?>>
219 - <label for="rag_sql_auto_sync_enabled"><strong>Enable Auto Sync (on Save)</strong></label>
220 - <p class="description">Automatically update embeddings </p>
221 - </div>
222 - <hr>
223 - <?php
224 - $sql_sync_interval = get_option('rag_sql_sync_interval', 'daily');
225 - $sql_interval_labels = [
226 - 'hourly' => '(Hourly)',
227 - 'twicedaily' => '(Twice Daily)',
228 - 'daily' => '(Daily)',
229 - 'weekly' => '(Weekly)',
230 - ];
231 - $sql_interval_desc = [
232 - 'hourly' => 'once per hour',
233 - 'twicedaily' => 'twice per day',
234 - 'daily' => 'once per day',
235 - 'weekly' => 'once per week',
236 - ];
237 - $sql_current_label = $sql_interval_labels[$sql_sync_interval] ?? '(Daily)';
238 - $sql_current_desc = $sql_interval_desc[$sql_sync_interval] ?? 'once per day';
239 - ?>
240 -
241 - <div class="mb-3" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
242 - <label for="rag_sql_sync_interval"><strong>Sync Interval:</strong></label>
243 - <select id="rag_sql_sync_interval">
244 - <option value="five_minutes" <?php selected(get_option('rag_sql_sync_interval'), 'five_minutes'); ?>>Every 5 Minutes</option>
245 - <option value="hourly" <?php selected(get_option('rag_sql_sync_interval'), 'hourly'); ?>>Hourly</option>
246 - <option value="twicedaily" <?php selected(get_option('rag_sql_sync_interval'), 'twicedaily'); ?>>Twice Daily</option>
247 - <option value="daily" <?php selected(get_option('rag_sql_sync_interval', 'daily'), 'daily'); ?>>Once Daily</option>
248 - <option value="weekly" <?php selected(get_option('rag_sql_sync_interval'), 'weekly'); ?>>Weekly</option>
249 - </select>
250 - <p class="description">Choose how often to run the automated synchronization.</p>
251 - </div>
252 -
253 - </div>
254 -
255 - <div class="wrap my-4" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
256 - <button type="button" id="rag_embed_sql_btn" class="button button-primary">Embed Selected Database Data</button>
257 -
258 - <div id="rag_sql_progress_container" style="display:none; margin-top: 20px;">
259 - <div class="progress" style="height: 25px; background-color: #f1f1f1; border-radius: 5px; overflow: hidden;">
260 - <div id="rag_sql_progress_bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%; height: 100%; background-color: #007bff; transition: width 0.3s ease;"></div>
261 - </div>
262 - <p id="rag_sql_progress_status" style="margin-top: 10px; font-weight: bold;"></p>
263 - </div>
264 - </div>
265 -
266 - <!-- SAVE SETTINGS BUTTON -->
267 - <div class="wrap" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
268 - <button class="qcld-btn-primary" id="save_rag_setting">Save Settings</button>
269 - </div>
270 - </div>
271 -
272 102 <div id="rag-sync" class="qcld-tab-content">
273 103 <?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'): ?>
274 104 <div class="wrap">
275 105 <div style="background-color: #fee; border: 1px solid #c33; padding: 15px; margin: 20px 0; border-radius: 4px;">
@@ -290,10 +120,10 @@
290 120 <div class="wrap">
291 121 <h3>Sync Settings</h3>
292 122
293 123 <div class="mb-3">
294 - <input type="checkbox" id="rag_auto_sync_enabled_tab" class="rag_auto_sync_enabled" <?php checked(get_option('rag_auto_sync_enabled'), '1'); ?>>
295 - <label for="rag_auto_sync_enabled_tab"><strong>Enable Auto Sync (on Save)</strong></label>
124 + <input type="checkbox" id="rag_auto_sync_enabled" <?php checked(get_option('rag_auto_sync_enabled'), '1'); ?>>
125 + <label for="rag_auto_sync_enabled"><strong>Enable Auto Sync (on Save)</strong></label>
296 126 <p class="description">Automatically update embeddings when a post or product is saved/updated.</p>
297 127 </div>
298 128 <hr>
299 129 <?php
@@ -315,16 +145,16 @@
315 145 ?>
316 146
317 147 <div class="mb-3">
318 148 <input type="checkbox" id="rag_googlesheets_autosync_enabled" <?php checked(get_option('rag_googlesheets_autosync_enabled'), '1'); ?>>
319 - <label for="rag_googlesheets_autosync_enabled"><strong>Enable Google Sheets Auto Sync <span class="rag-sync-label"><?php echo esc_html( $current_label ); ?></span></strong></label>
320 - <p class="description">Automatically re-sync all Google Sheets in the knowledge base <span class="rag-sync-desc"><?php echo esc_html( $current_desc ); ?></span>.</p>
149 + <label for="rag_googlesheets_autosync_enabled"><strong>Enable Google Sheets Auto Sync <span class="rag-sync-label"><?php echo $current_label; ?></span></strong></label>
150 + <p class="description">Automatically re-sync all Google Sheets in the knowledge base <span class="rag-sync-desc"><?php echo $current_desc; ?></span>.</p>
321 151 </div>
322 152
323 153 <div class="mb-3">
324 154 <input type="checkbox" id="rag_googledocs_autosync_enabled" <?php checked(get_option('rag_googledocs_autosync_enabled'), '1'); ?>>
325 - <label for="rag_googledocs_autosync_enabled"><strong>Enable Google Docs Auto Sync <span class="rag-sync-label"><?php echo esc_html( $current_label ); ?></span></strong></label>
326 - <p class="description">Automatically re-sync all Google Docs in the knowledge base <span class="rag-sync-desc"><?php echo esc_html( $current_desc ); ?></span>.</p>
155 + <label for="rag_googledocs_autosync_enabled"><strong>Enable Google Docs Auto Sync <span class="rag-sync-label"><?php echo $current_label; ?></span></strong></label>
156 + <p class="description">Automatically re-sync all Google Docs in the knowledge base <span class="rag-sync-desc"><?php echo $current_desc; ?></span>.</p>
327 157 </div>
328 158
329 159 <div class="mb-3">
330 160 <label for="rag_sync_interval"><strong>Sync Interval:</strong></label>
@@ -366,9 +196,9 @@
366 196 CSV UPLOAD (AJAX)
367 197 ============================ -->
368 198 <div class="wrap">
369 199 <h3>Upload CSV Data for RAG</h3>
370 - <p>Upload CSV files with data to be embedded. Each row will be processed as a separate document. <a href="<?php echo esc_url( plugin_dir_url(__FILE__).'download/rag_test_data.csv' ); ?>">Download Test Data</a></p>
200 + <p>Upload CSV files with data to be embedded. Each row will be processed as a separate document. <a href="<?php echo plugin_dir_url(__FILE__).'download/rag_test_data.csv'; ?>">Download Test Data</a></p>
371 201
372 202 <form id="rag-csv-form">
373 203 <input type="file" id="rag-csv-files" name="rag_csv[]" multiple accept=".csv,text/csv" />
374 204 <br><br>
@@ -472,9 +302,9 @@
472 302
473 303 <div id="botmaster_googledoc_status" style="margin-top: 10px;"></div>
474 304 </div>
475 305 </div>
476 - <h5 style="color: #c33;">Notes: These are based on AI system, so make sure you have enabled any AI features and set up valid API keys. <b><a href="<?php echo esc_url('https://wpbot.pro/docs/knowledgebase/how-to-use-an-embedded-vector-database-and-rag-to-get-customized-responses-from-ai/'); ?>" target="_blank">Check this Tutorial for more details.</a></b></h5>
306 + <h5 style="color: #c33;">Notes: These are based on AI system, so make sure you have enabled any AI features and set up valid API keys. <b><a href="https://wpbot.pro/docs/knowledgebase/how-to-use-an-embedded-vector-database-and-rag-to-get-customized-responses-from-ai/" target="_blank">Check this Tutorial for more details.</a></b></h5>
477 307 <div class="wrap">
478 308 <button class="qcld-btn-primary" id="save_rag_setting">Save Settings</button>
479 309 </div>
480 310 </div>
@@ -505,9 +335,9 @@
505 335
506 336 $.post(ajaxurl, {
507 337 action: 'botmaster_submit_sitemap',
508 338 sitemap_url: sitemapUrl,
509 - nonce: '<?php echo esc_attr( wp_create_nonce('botmaster_kb_nonce') ); ?>'
339 + nonce: '<?php echo wp_create_nonce("botmaster_kb_nonce"); ?>'
510 340 }, function(response) {
511 341 $('#botmaster_submit_sitemap_btn').prop('disabled', false);
512 342 if (response.success) {
513 343 statusDiv.html('<div class="notice notice-success inline"><p>' + response.data.message + '</p></div>');
@@ -522,9 +352,9 @@
522 352 <?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'): ?>
523 353 <div class="wrap">
524 354 <div style="background-color: #fee; border: 1px solid #c33; padding: 15px; margin: 20px 0; border-radius: 4px;">
525 355 <p style="color: #c33; font-weight: bold; margin: 0; font-size: 14px;">
526 - These options are available with the WPBot Pro <a href="<?php echo esc_url('https://www.wpbot.pro/pricing/'); ?>" target="_blank" style="color: #c33; text-decoration: underline;">Professional</a> and <a href="<?php echo esc_url('https://www.wpbot.pro/pricing/'); ?>" target="_blank" style="color: #c33; text-decoration: underline;">Master</a> Licenses
356 + These options are available with the WPBot Pro <a href="https://www.wpbot.pro/pricing/" target="_blank" style="color: #c33; text-decoration: underline;">Professional</a> and <a href="https://www.wpbot.pro/pricing/" target="_blank" style="color: #c33; text-decoration: underline;">Master</a> Licenses
527 357 </p>
528 358 </div>
529 359 </div>
530 360 <?php endif; ?>
@@ -547,9 +377,9 @@
547 377 <tbody id="rag-sources-list">
548 378 <?php
549 379 global $wpdb;
550 380 $table = $wpdb->prefix . 'rag_documents';
551 - $sources = $wpdb->get_results("SELECT source_url, source_type, COUNT(*) as count, MAX(title) as display_name FROM {$table} GROUP BY source_url, source_type ORDER BY count DESC"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
381 + $sources = $wpdb->get_results("SELECT source_url, source_type, COUNT(*) as count, MAX(title) as display_name FROM $table GROUP BY source_url, source_type ORDER BY count DESC");
552 382
553 383 if ($sources) {
554 384 foreach ($sources as $source) {
555 385 $display_url = $source->source_url ?: "Manual Upload";
@@ -661,9 +491,9 @@
661 491 echo '<div class="notice notice-success inline"><p>Database table created successfully.</p></div>';
662 492 }
663 493
664 494 // Check if table exists
665 - $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $wpdb->esc_like($table_rag_documents))) === $table_rag_documents; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
495 + $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $wpdb->esc_like($table_rag_documents))) === $table_rag_documents;
666 496
667 497 if (!$table_exists) {
668 498 ?>
669 499 <div class="wrap">
@@ -686,11 +516,11 @@
686 516 $search_query = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
687 517
688 518 if ($search_query) {
689 519 $like = '%' . $wpdb->esc_like($search_query) . '%';
690 - $total_items = $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM {$table_name} WHERE title LIKE %s OR content LIKE %s", $like, $like)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
520 + $total_items = $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM {$table_name} WHERE title LIKE %s OR content LIKE %s", $like, $like));
691 521 } else {
692 - $total_items = $wpdb->get_var("SELECT COUNT(id) FROM {$table_name}"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
522 + $total_items = $wpdb->get_var("SELECT COUNT(id) FROM {$table_name}");
693 523 }
694 524 $items_per_page = 50;
695 525 $page = isset($_GET['paged']) ? absint(wp_unslash($_GET['paged'])) : 1;
696 526 $offset = ($page - 1) * $items_per_page;
@@ -698,10 +528,10 @@
698 528
699 529 $pagination_args = array(
700 530 'base' => add_query_arg(array('paged' => '%#%', 's' => $search_query), '?page=wpbot_openAi') . '#ai-knowledge-base-tab#rag-database',
701 531 'format' => '',
702 - 'prev_text' => __( '&laquo;', 'chatbot' ),
703 - 'next_text' => __( '&raquo;', 'chatbot' ),
532 + 'prev_text' => __('&laquo;'),
533 + 'next_text' => __('&raquo;'),
704 534 'total' => $total_pages,
705 535 'current' => $page,
706 536 'type' => 'plain',
707 537 );
@@ -706,11 +536,10 @@
706 536 'type' => 'plain',
707 537 );
708 538
709 539 if ($total_pages > 1) {
710 - // translators: %s: number of items.
711 - echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf( esc_html( _n( '%s item', '%s items', $total_items, 'chatbot' ) ), esc_html( number_format_i18n($total_items) ) ) . '</span>';
712 - echo wp_kses_post( paginate_links($pagination_args) );
540 + echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf(_n('%s item', '%s items', $total_items), number_format_i18n($total_items)) . '</span>';
541 + echo paginate_links($pagination_args);
713 542 echo '</div>';
714 543 }
715 544 ?>
716 545
@@ -731,19 +560,19 @@
731 560 <tbody id="rag-knowledge-base-list">
732 561 <?php
733 562 if ($search_query) {
734 563 $like = '%' . $wpdb->esc_like($search_query) . '%';
735 - $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} WHERE title LIKE %s OR content LIKE %s ORDER BY created_at DESC LIMIT %d OFFSET %d", $like, $like, $items_per_page, $offset)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
564 + $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} WHERE title LIKE %s OR content LIKE %s ORDER BY created_at DESC LIMIT %d OFFSET %d", $like, $like, $items_per_page, $offset));
736 565 } else {
737 - $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} ORDER BY created_at DESC LIMIT %d OFFSET %d", $items_per_page, $offset)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
566 + $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} ORDER BY created_at DESC LIMIT %d OFFSET %d", $items_per_page, $offset));
738 567 }
739 568
740 569 if ($documents) {
741 570 foreach ($documents as $doc) {
742 571 ?>
743 - <tr id="rag-doc-<?php echo esc_attr( $doc->id ); ?>">
572 + <tr id="rag-doc-<?php echo $doc->id; ?>">
744 573 <th scope="qcld-row" class="check-column">
745 - <input type="checkbox" class="rag-doc-checkbox" value="<?php echo esc_attr( $doc->id ); ?>">
574 + <input type="checkbox" class="rag-doc-checkbox" value="<?php echo $doc->id; ?>">
746 575 </th>
747 576 <td><?php echo esc_html($doc->title); ?></td>
748 577 <td>
749 578 <div style="max-height: 4.5em; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; line-height: 1.5em; font-size: 13px; color: #666;">
@@ -754,12 +583,12 @@
754 583 <td><?php echo esc_html($doc->source_url ?: $doc->file_url); ?></td>
755 584 <td><?php echo esc_html($doc->status); ?></td>
756 585 <td>
757 586 <?php if (!in_array($doc->source_type, ['csv', 'xml', 'xaml','sitemap'])): ?>
758 - <button class="button button-small rag-sync-doc" data-id="<?php echo esc_attr( $doc->id ); ?>" title="Re-sync data from source">Sync</button>
587 + <button class="button button-small rag-sync-doc" data-id="<?php echo $doc->id; ?>" title="Re-sync data from source">Sync</button>
759 588 <?php endif; ?>
760 - <button class="button button-small rag-edit-doc" data-id="<?php echo esc_attr( $doc->id ); ?>">Edit</button>
761 - <button class="button button-small button-link-delete rag-delete-doc" data-id="<?php echo esc_attr( $doc->id ); ?>">Delete</button>
589 + <button class="button button-small rag-edit-doc" data-id="<?php echo $doc->id; ?>">Edit</button>
590 + <button class="button button-small button-link-delete rag-delete-doc" data-id="<?php echo $doc->id; ?>">Delete</button>
762 591 </td>
763 592 </tr>
764 593 <?php
765 594 }
@@ -772,11 +601,10 @@
772 601
773 602 <div class="tablenav bottom">
774 603 <?php
775 604 if ($total_pages > 1) {
776 - // translators: %s: number of items.
777 - echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf( esc_html( _n( '%s item', '%s items', $total_items, 'chatbot' ) ), esc_html( number_format_i18n($total_items) ) ) . '</span>';
778 - echo wp_kses_post( paginate_links($pagination_args) );
605 + echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf(_n('%s item', '%s items', $total_items), number_format_i18n($total_items)) . '</span>';
606 + echo paginate_links($pagination_args);
779 607 echo '</div>';
780 608 }
781 609 ?>
782 610 <br class="clear">
@@ -825,9 +653,9 @@
825 653 for (var i = 0; i < fileInput.files.length; i++) {
826 654 formData.append('rag_pdf[]', fileInput.files[i]);
827 655 }
828 656 formData.append('action', 'rag_upload_pdf');
829 - formData.append('nonce', '<?php echo esc_js( wp_create_nonce('rag_upload_nonce') ); ?>');
657 + formData.append('nonce', '<?php echo wp_create_nonce('rag_upload_nonce'); ?>');
830 658
831 659 $('#rag-pdf-submit').prop('disabled', true);
832 660 $('#rag-pdf-status').html('<span class="spinner is-active" style="float:none;"></span> Uploading and processing...');
833 661 $('#rag-pdf-output').html('');
@@ -871,9 +699,9 @@
871 699 for (var i = 0; i < fileInput.files.length; i++) {
872 700 formData.append('rag_csv[]', fileInput.files[i]);
873 701 }
874 702 formData.append('action', 'rag_upload_csv');
875 - formData.append('nonce', '<?php echo esc_js( wp_create_nonce('rag_upload_nonce') ); ?>');
703 + formData.append('nonce', '<?php echo wp_create_nonce('rag_upload_nonce'); ?>');
876 704
877 705 $('#rag-csv-submit').prop('disabled', true);
878 706 $('#rag-csv-status').html('<span class="spinner is-active" style="float:none;"></span> Uploading and processing...');
879 707 $('#rag-csv-output').html('');
@@ -917,9 +745,9 @@
917 745 for (var i = 0; i < fileInput.files.length; i++) {
918 746 formData.append('rag_xaml[]', fileInput.files[i]);
919 747 }
920 748 formData.append('action', 'rag_upload_xaml');
921 - formData.append('nonce', '<?php echo esc_js( wp_create_nonce('rag_upload_nonce') ); ?>');
749 + formData.append('nonce', '<?php echo wp_create_nonce('rag_upload_nonce'); ?>');
922 750
923 751 $('#rag-xaml-submit').prop('disabled', true);
924 752 $('#rag-xaml-status').html('<span class="spinner is-active" style="float:none;"></span> Uploading and processing...');
925 753 $('#rag-xaml-output').html('');
@@ -995,5 +823,5 @@
995 823 // Default to first tab if no sub-tab specified
996 824 $('.nav-tab-wrapper a').first().trigger('click');
997 825 }
998 826 });
999 -</script>
827 +</script>