PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.6.7
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.6.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 8.5.0 All 532 releases
chatbot / includes / class-wpwbot-table.php

class-wpwbot-table.php in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.6.7, at includes/class-wpwbot-table.php

457 lines 17.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5 if ( ! class_exists( 'wpwBot_Table' ) ) :
6 /**
7 * Class for plugin index table
8 */
9 class wpwBot_Table {
10 /**
11 * @var wpwBot_Table Index table name
12 */
13 private $table_name;
14 /**
15 * Constructor
16 */
17 public function __construct() {
18 global $wpdb;
19 $this->table_name = $wpdb->prefix . QCLD_wpCHATBOT_INDEX_TABLE;
20 add_action( 'wp_insert_post', array( $this, 'update_table' ), 10, 3 );
21
22 if ( defined('wpCOMMERCE_VERSION') ) {
23 if ( version_compare( wpCOMMERCE_VERSION, '3.0', ">=" ) ) {
24 add_action( 'wpcommerce_variable_product_sync_data', array( $this, 'variable_product_changed' ) );
25 } else {
26 add_action( 'wpcommerce_variable_product_sync', array( $this, 'variable_product_changed' ), 10, 2 );
27 }
28 }
29
30 add_action( 'wp_ajax_qcld-wp-chabot-reindex', array( $this, 'reindex_table' ) );
31 add_action( 'wp_ajax_qcld-wp-chabot-cancel-index', array( $this, 'cancel_reindex' ) );
32 }
33 /*
34 * Reindex plugin table
35 */
36 public function reindex_table( $return) {
37 $nonce = sanitize_text_field(wp_unslash($_POST['nonce']));
38 if (! wp_verify_nonce($nonce,'wp_chatbot') || ! current_user_can('manage_options')) {
39 wp_send_json(array('success' => false, 'msg' => esc_html__('Failed in Security check', 'chatbot')));
40 wp_die();
41
42 }else{
43 global $wpdb;
44 $index_meta = get_option( 'wp_chatbot_index_meta', false );
45 $status = false;
46 // No current index going on. Let's start over
47 if ( false === $index_meta ) {
48 $status = 'start';
49 $index_meta = array(
50 'offset' => 0,
51 'start' => true,
52 );
53
54 // phpcs:ignore
55 $wpdb->query("DROP TABLE IF EXISTS {$this->table_name}"); //DB Call OK
56
57 $this->create_table();
58
59 $index_meta['found_posts'] = $this->get_number_of_products();
60 } else if ( ! empty( $index_meta['site_stack'] ) && $index_meta['offset'] >= $index_meta['found_posts'] ) {
61 $status = 'start';
62 $index_meta['start'] = true;
63 $index_meta['offset'] = 0;
64 $index_meta['current_site'] = array_shift( $index_meta['site_stack'] );
65 } else {
66 $index_meta['start'] = false;
67 }
68 $index_meta = apply_filters( 'wp_chatbot_index_meta', $index_meta );
69 $posts_per_page = apply_filters( 'wp_chatbot_index_posts_per_page', 30 );
70 $args = array(
71 'posts_per_page' => $posts_per_page,
72 'fields' => 'ids',
73 'post_type' => 'product',
74 'post_status' => 'publish',
75 'offset' => $index_meta['offset'],
76 'ignore_sticky_posts' => true,
77 'suppress_filters' => true,
78 'no_found_rows' => 1,
79 'orderby' => 'ID',
80 'order' => 'DESC',
81 );
82 $posts = get_posts( $args );
83 if ( $status !== 'start' ) {
84 if ( $posts && count( $posts ) > 0 ) {
85 $queued_posts = array();
86 foreach( $posts as $post_id ) {
87 $queued_posts[] = absint( $post_id );
88 }
89 $this->fill_table( $queued_posts );
90 $index_meta['offset'] = absint( $index_meta['offset'] + $posts_per_page );
91 if ( $index_meta['offset'] >= $index_meta['found_posts'] ) {
92 $index_meta['offset'] = $index_meta['found_posts'];
93 }
94 update_option( 'wp_chatbot_index_meta', $index_meta );
95 } else {
96 // We are done (with this site)
97 $index_meta['offset'] = (int) count( $posts );
98 delete_option( 'wp_chatbot_index_meta' );
99 update_option( 'wp_chatbot_index_count', 1 );
100 }
101 } else {
102 update_option( 'wp_chatbot_index_meta', $index_meta );
103 }
104 if ( $return ) {
105 return $index_meta;
106 } else {
107 wp_send_json_success( $index_meta );
108 }
109 }
110 }
111 /*
112 * Get total number of products
113 */
114 private function get_number_of_products() {
115 $args = array(
116 'posts_per_page' => -1,
117 'fields' => 'ids',
118 'post_type' => 'product',
119 'post_status' => 'publish',
120 'ignore_sticky_posts' => true,
121 'suppress_filters' => true,
122 'no_found_rows' => 1,
123 'orderby' => 'ID',
124 'order' => 'DESC',
125 );
126 $posts = get_posts( $args );
127 if ( $posts && count( $posts ) > 0 ) {
128 $count = count( $posts );
129 } else {
130 $count = 0;
131 }
132 return $count;
133 }
134 /*
135 * Check if index table exist
136 */
137 private function is_table_not_exist() {
138 global $wpdb;
139 return ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $this->table_name ) ) ) != $this->table_name ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
140 }
141 /*
142 * Create index table
143 */
144 private function create_table() {
145 global $wpdb;
146 $charset_collate = $wpdb->get_charset_collate();
147 $sql = "CREATE TABLE {$this->table_name} (
148 id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
149 term VARCHAR(50) NOT NULL DEFAULT 0,
150 term_source VARCHAR(20) NOT NULL DEFAULT 0,
151 type VARCHAR(50) NOT NULL DEFAULT 0,
152 count BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
153 in_stock INT(11) NOT NULL DEFAULT 0,
154 visibility VARCHAR(20) NOT NULL DEFAULT 0,
155 lang VARCHAR(20) NOT NULL DEFAULT 0
156 ) $charset_collate;";
157 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
158 dbDelta( $sql );
159
160 $table_report = $wpdb->prefix . 'wpbot_chat_report';
161
162 if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_report ) ) ) != $table_report ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
163 // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange
164 $sql_report = "
165 CREATE TABLE `$table_report` (
166 `id` int(11) NOT NULL AUTO_INCREMENT,
167 `user_id` int(11) NOT NULL,
168 `conversation_id` int(11) DEFAULT NULL,
169 `message` longtext NOT NULL,
170 `feedback` varchar(20) DEFAULT NULL,
171 `meta_info` text DEFAULT NULL,
172 `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
173 PRIMARY KEY (`id`)
174 ) $charset_collate AUTO_INCREMENT=1;
175 ";
176 // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange
177
178 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
179 dbDelta( $sql_report );
180 }
181 }
182 /*
183 * Insert data into the index table
184 */
185 private function fill_table( $posts ) {
186
187 }
188 /*
189 * Scrap all product data and insert to table
190 */
191 private function insert_into_table( $data ) {
192 global $wpdb;
193 $values = array();
194 foreach( $data['terms'] as $source => $all_terms ) {
195 foreach ( $all_terms as $term => $count ) {
196 if ( ! $term ) {
197 continue;
198 }
199 $value = $wpdb->prepare(
200 "(%d, %s, %s, %s, %d, %d, %s, %s)",
201 $data['id'], $term, $source, 'product', $count, $data['in_stock'], $data['visibility'], $data['lang']
202 );
203 $values[] = $value;
204 }
205 }
206 if ( count( $values ) > 0 ) {
207 $values = implode( ', ', $values );
208 $query = "INSERT IGNORE INTO {$this->table_name}
209 (`id`, `term`, `term_source`, `type`, `count`, `in_stock`, `visibility`, `lang`)
210 VALUES $values
211 ";
212 $wpdb->query( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
213 }
214 }
215 /*
216 * Update index table
217 */
218 public function update_table( $post_id, $post, $update ) {
219 global $wpdb;
220 if ( $this->is_table_not_exist() ) {
221 $this->create_table();
222 }
223 $slug = 'product';
224 if ( $slug != $post->post_type ) {
225 return;
226 }
227 $wpdb->delete( $this->table_name, array( 'id' => $post_id ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
228 $posts = get_posts( array(
229 'posts_per_page' => -1,
230 'fields' => 'ids',
231 'post_type' => 'product',
232 'post_status' => 'publish',
233 'suppress_filters' => false,
234 'no_found_rows' => 1,
235 'include' => $post_id
236 ) );
237 $this->fill_table( $posts );
238 }
239 /*
240 * Fires when products terms are changed
241 */
242 public function term_changed( $term_id, $tt_id, $taxonomy ) {
243 if ( $taxonomy === 'product_cat' || $taxonomy === 'product_tag' ) {
244 }
245 }
246 /*
247 * Fires when products variations are changed
248 */
249 public function variable_product_changed( $product, $children = null ) {
250 global $wpdb;
251 $product_id = '';
252
253 if ( $this->is_table_not_exist() ) {
254 $this->create_table();
255 }
256
257 if ( is_object( $product ) ) {
258 $product_id = $product->get_id();
259 } else {
260 $product_id = $product;
261 }
262
263 $wpdb->delete( $this->table_name, array( 'id' => $product_id ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
264
265 $posts = get_posts( array(
266 'posts_per_page' => -1,
267 'fields' => 'ids',
268 'post_type' => 'product',
269 'post_status' => 'publish',
270 'suppress_filters' => false,
271 'no_found_rows' => 1,
272 'include' => $product_id
273 ) );
274 $this->fill_table( $posts );
275 }
276 /*
277 * Cancel index
278 */
279 public function cancel_reindex() {
280 $nonce = sanitize_text_field(wp_unslash($_POST['nonce']));
281 if (! wp_verify_nonce($nonce,'wp_chatbot') || ! current_user_can('manage_options')) {
282 wp_send_json(array('success' => false, 'msg' => esc_html__('Failed in Security check', 'chatbot')));
283 wp_die();
284
285 }else{
286 delete_option( 'wp_chatbot_index_meta' );
287 wp_send_json_success( 'Deleted!' );
288 }
289 }
290 /*
291 * Strip shortcodes
292 */
293 private function strip_shortcodes( $content ) {
294 $content = preg_replace( '#\[[^\]]+\]#', '', $content );
295 return $content;
296 }
297 /*
298 * Extract terms from content
299 */
300 private function extract_terms( $str ) {
301 $stopwords = str_replace('\\', '', get_option('qlcd_wp_chatbot_stop_words'));
302 $str = $this->html2txt( $str );
303 // Avoid single A-Z.
304
305 $special_cars = $this->get_special_chars();
306 $str = str_replace( $special_cars, "", $str );
307 $str = str_replace( array(
308 "ˇ",
309 "°",
310 "Ë›",
311 "Ëť",
312 "¸",
313 "§",
314 "=",
315 "¨",
316 "’",
317 "‘",
318 "”",
319 "“",
320 "„",
321 "´",
322 "—",
323 "–",
324 "Ă—",
325 '&#8217;',
326 "&nbsp;",
327 chr( 194 ) . chr( 160 )
328 ), " ", $str );
329 $str = str_replace( 'Ăź', 'ss', $str );
330 $str = preg_replace( '/[[:space:]]+/', ' ', $str );
331 // Most objects except unicode characters
332 $str = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\x9F]/u', '', $str );
333 // Line feeds, carriage returns, tabs
334 $str = preg_replace( '/[\x00-\x1F\x80-\x9F]/u', '', $str );
335 if ( function_exists( 'mb_strtolower' ) ) {
336 $str = mb_strtolower( $str );
337 } else {
338 $str = strtolower( $str );
339 }
340 $str = preg_replace( '/^[a-z]$/i', "", $str );
341 $str = trim( preg_replace( '/\s+/', ' ', $str ) );
342 $str_array = array_count_values( explode( ' ', $str ) );
343 if ( $stopwords && $str_array && ! empty( $str_array ) ) {
344 $stopwords_array = explode( ',', $stopwords );
345 if ( $stopwords_array && ! empty( $stopwords_array ) ) {
346 $stopwords_array = array_map( 'trim', $stopwords_array );
347 foreach ( $str_array as $str_word => $str_count ) {
348 if ( in_array( $str_word, $stopwords_array ) ) {
349 unset( $str_array[$str_word] );
350 }
351 }
352 }
353 }
354 return $str_array;
355 }
356 /*
357 * Removes scripts, styles, html tags
358 */
359 public function html2txt( $str ) {
360 $search = array(
361 '@<script[^>]*?>.*?</script>@si',
362 '@<[\/\!]*?[^<>]*?>@si',
363 '@<style[^>]*?>.*?</style>@siU',
364 '@<![\s\S]*?--[ \t\n\r]*>@'
365 );
366 $str = preg_replace( $search, '', $str );
367 $str = esc_attr( $str );
368 $str = stripslashes( $str );
369 $str = str_replace( array( "\r", "\n" ), ' ', $str );
370 $str = str_replace( array(
371 "·",
372 "…",
373 "€",
374 "&shy;"
375 ), "", $str );
376 return $str;
377 }
378 /*
379 * Get special characters that must be striped
380 */
381 public function get_special_chars() {
382 $chars = array(
383 '-',
384 '_',
385 '|',
386 '+',
387 '`',
388 '~',
389 '!',
390 '@',
391 '#',
392 '$',
393 '%',
394 '^',
395 '&',
396 '*',
397 '(',
398 ')',
399 '\\',
400 '?',
401 ';',
402 ':',
403 "'",
404 '"',
405 ".",
406 ",",
407 "<",
408 ">",
409 "{",
410 "}",
411 "/",
412 "[",
413 "]",
414 );
415 return apply_filters( 'wp_chatbot_special_chars', $chars );
416 }
417 /*
418 * Get string with current product terms ids
419 *
420 * @return string List of terms ids
421 */
422 private function get_terms_list( $id, $taxonomy ) {
423 $terms = get_the_terms( $id, $taxonomy );
424 if ( is_wp_error( $terms ) ) {
425 return '';
426 }
427 if ( empty( $terms ) ) {
428 return '';
429 }
430 $cats_array_temp = array();
431 foreach ( $terms as $term ) {
432 $cats_array_temp[] = $term->term_id;
433 }
434 return implode( ', ', $cats_array_temp );
435 }
436 /*
437 * Get string with current product terms names
438 *
439 * @return string List of terms names
440 */
441 private function get_terms_names_list( $id, $taxonomy ) {
442 $terms = get_the_terms( $id, $taxonomy );
443 if ( is_wp_error( $terms ) ) {
444 return '';
445 }
446 if ( empty( $terms ) ) {
447 return '';
448 }
449 $cats_array_temp = array();
450 foreach ( $terms as $term ) {
451 $cats_array_temp[] = $term->name;
452 }
453 return implode( ', ', $cats_array_temp );
454 }
455 }
456 endif;
457 new wpwBot_Table();