PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.5.4
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.5.4
3.5.4 3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / includes / admin / ai-chatbot / models / class-wpsc-acb-sessions.php

class-wpsc-acb-sessions.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.5.4, at includes/admin/ai-chatbot/models/class-wpsc-acb-sessions.php

540 lines 13.0 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; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_ACB_Sessions' ) ) :
7
8 final class WPSC_ACB_Sessions {
9
10 /**
11 * Object data in key => val pair.
12 *
13 * @var array
14 */
15 private $data = array();
16
17 /**
18 * Set whether or not current object properties modified
19 *
20 * @var boolean
21 */
22 private $is_modified = false;
23
24 /**
25 * Schema for this model
26 *
27 * @var array
28 */
29 public static $schema = array();
30
31 /**
32 * Prevent fields to modify
33 *
34 * @var array
35 */
36 public static $prevent_modify = array();
37
38 /**
39 * DB object caching
40 *
41 * @var array
42 */
43 private static $cache = array();
44
45 /**
46 * Initialize this class
47 *
48 * @return void
49 */
50 public static function init() {
51
52 // Apply schema for this model.
53 add_action( 'init', array( __CLASS__, 'apply_schema' ), 2 );
54
55 // Get object of this class.
56 add_filter( 'wpsc_load_ref_classes', array( __CLASS__, 'load_ref_class' ) );
57 }
58
59 /**
60 * Apply schema for this model
61 *
62 * @return void
63 */
64 public static function apply_schema() {
65
66 $schema = array(
67 'id' => array(
68 'has_ref' => false,
69 'ref_class' => '',
70 'has_multiple_val' => false,
71 ),
72 'session_id' => array(
73 'has_ref' => false,
74 'ref_class' => '',
75 'has_multiple_val' => false,
76 ),
77 'visitor_id' => array(
78 'has_ref' => false,
79 'ref_class' => '',
80 'has_multiple_val' => false,
81 ),
82 'subject' => array(
83 'has_ref' => false,
84 'ref_class' => '',
85 'has_multiple_val' => false,
86 ),
87 'provider' => array(
88 'has_ref' => false,
89 'ref_class' => '',
90 'has_multiple_val' => false,
91 ),
92 'reaction' => array(
93 'has_ref' => false,
94 'ref_class' => '',
95 'has_multiple_val' => false,
96 ),
97 'ticket_id' => array(
98 'has_ref' => true,
99 'ref_class' => 'wpsc_ticket',
100 'has_multiple_val' => false,
101 ),
102 'status' => array(
103 'has_ref' => false,
104 'ref_class' => '',
105 'has_multiple_val' => false,
106 ),
107 'token_count' => array(
108 'has_ref' => false,
109 'ref_class' => '',
110 'has_multiple_val' => false,
111 ),
112 'last_activity' => array(
113 'has_ref' => true,
114 'ref_class' => 'datetime',
115 'has_multiple_val' => false,
116 ),
117 'date_created' => array(
118 'has_ref' => true,
119 'ref_class' => 'datetime',
120 'has_multiple_val' => false,
121 ),
122 );
123 self::$schema = apply_filters( 'wpsc_acb_sessions_schema', $schema );
124
125 // Prevent modify.
126 $prevent_modify = array( 'id', 'session_id', 'visitor_id' );
127 self::$prevent_modify = apply_filters( 'wpsc_acb_sessions_prevent_modify', $prevent_modify );
128 }
129
130 /**
131 * Model constructor
132 *
133 * @param int $id - Optional. Data record id to retrieve object for.
134 * @return void
135 */
136 public function __construct( $id = 0 ) {
137
138 global $wpdb;
139 $id = intval( $id );
140
141 if ( isset( self::$cache[ $id ] ) ) {
142 $this->data = self::$cache[ $id ]->data;
143 return;
144 }
145
146 if ( $id > 0 ) {
147 $tag = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}psmsc_acb_sessions WHERE id = %d", $id ), ARRAY_A );
148 if ( ! is_array( $tag ) ) {
149 return;
150 }
151
152 foreach ( $tag as $key => $val ) {
153 $this->data[ $key ] = $val !== null ? $val : '';
154 }
155 self::$cache[ $id ] = $this;
156 }
157 }
158
159 /**
160 * Magic get function to use with object arrow function
161 *
162 * @param string $var_name - variable name.
163 * @return mixed
164 */
165 public function __get( $var_name ) {
166
167 if ( ! isset( $this->data[ $var_name ] ) ||
168 $this->data[ $var_name ] == null ||
169 $this->data[ $var_name ] == ''
170 ) {
171 return self::$schema[ $var_name ]['has_multiple_val'] ? array() : '';
172 }
173
174 if ( self::$schema[ $var_name ]['has_multiple_val'] ) {
175
176 $response = array();
177 $values = $this->data[ $var_name ] ? explode( '|', $this->data[ $var_name ] ) : array();
178 foreach ( $values as $val ) {
179 $response[] = self::$schema[ $var_name ]['has_ref'] ?
180 WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $val ) :
181 $val;
182 }
183 return $response;
184 } else {
185
186 return self::$schema[ $var_name ]['has_ref'] && $this->data[ $var_name ] ?
187 WPSC_Functions::get_object( self::$schema[ $var_name ]['ref_class'], $this->data[ $var_name ] ) :
188 $this->data[ $var_name ];
189 }
190 }
191
192 /**
193 * Magic function to use setting object field with arrow function
194 *
195 * @param string $var_name - (Required) property slug.
196 * @param mixed $value - (Required) value to set for a property.
197 * @return void
198 */
199 public function __set( $var_name, $value ) {
200
201 if ( ! isset( $this->data[ $var_name ] ) ) {
202 return;
203 }
204
205 if ( in_array( $var_name, self::$prevent_modify ) ) {
206 return;
207 }
208
209 $data_val = '';
210 if ( self::$schema[ $var_name ]['has_multiple_val'] ) {
211 $data_vals = array_map(
212 fn( $val ) => is_object( $val ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $val ) : $val,
213 $value
214 );
215 $data_val = $data_vals ? implode( '|', $data_vals ) : '';
216 } else {
217
218 $data_val = is_object( $value ) ? WPSC_Functions::set_object( self::$schema[ $var_name ]['ref_class'], $value ) : $value;
219 }
220
221 if ( isset( $this->data[ $var_name ] ) && $this->data[ $var_name ] == $data_val ) {
222 return;
223 }
224
225 $this->data[ $var_name ] = $data_val;
226 $this->is_modified = true;
227 }
228
229 /**
230 * Save changes made
231 *
232 * @return boolean
233 */
234 public function save() {
235
236 global $wpdb;
237
238 if ( ! $this->is_modified ) {
239 return true;
240 }
241
242 $data = $this->data;
243 $success = true;
244
245 if ( ! isset( $data['id'] ) ) {
246
247 $cr = self::insert( $data );
248 if ( $cr ) {
249 $this->data = $cr->data;
250 $success = true;
251 } else {
252 $success = false;
253 }
254 } else {
255
256 unset( $data['id'] );
257 $success = $wpdb->update(
258 $wpdb->prefix . 'psmsc_acb_sessions',
259 $data,
260 array( 'id' => $this->data['id'] )
261 );
262 }
263 $this->is_modified = false;
264 self::$cache[ $this->id ] = $this;
265 return $success ? true : false;
266 }
267
268 /**
269 * Insert new record
270 *
271 * @param array $data - insert data.
272 * @return boolean|WPSC_ACB_Sessions
273 */
274 public static function insert( $data ) {
275
276 global $wpdb;
277 $success = $wpdb->insert(
278 $wpdb->prefix . 'psmsc_acb_sessions',
279 $data
280 );
281
282 if ( ! $success ) {
283 return false;
284 }
285
286 $log = new WPSC_ACB_Sessions( $wpdb->insert_id );
287 self::$cache[ $log->id ] = $log;
288 return $log;
289 }
290
291 /**
292 * Update record based on given date
293 *
294 * @param string $data - date to update records.
295 * @return WPSC_ACB_Sessions
296 */
297 public static function update( $data ) {
298
299 global $wpdb;
300
301 $wpdb->update(
302 $wpdb->prefix . 'psmsc_acb_sessions',
303 $data,
304 array( 'id' => $data['id'] )
305 );
306 return new WPSC_ACB_Sessions( $data['id'] );
307 }
308
309 /**
310 * Increment token count for a session using atomic SQL update.
311 *
312 * @param int $session_id Session internal ID.
313 * @param int $tokens Number of tokens to add.
314 * @return bool
315 */
316 public static function increment_token_count( $session_id, $tokens ) {
317
318 global $wpdb;
319
320 $session_id = absint( $session_id );
321 $tokens = (int) $tokens;
322
323 if ( $session_id <= 0 || $tokens <= 0 ) {
324 return true;
325 }
326
327 $success = $wpdb->query(
328 $wpdb->prepare(
329 "UPDATE {$wpdb->prefix}psmsc_acb_sessions SET token_count = token_count + %d WHERE id = %d",
330 $tokens,
331 $session_id
332 )
333 );
334
335 if ( false === $success ) {
336 return false;
337 }
338
339 if ( isset( self::$cache[ $session_id ] ) ) {
340 $current = (int) ( self::$cache[ $session_id ]->data['token_count'] ?? 0 );
341 self::$cache[ $session_id ]->data['token_count'] = $current + $tokens;
342 }
343
344 return true;
345 }
346
347 /**
348 * Make it inactive so that garbage collector will delete files associated in
349 * background and then delete the record. This will improve its performance.
350 *
351 * @param WPSC_ACB_Sessions $log - log object.
352 * @return boolean
353 */
354 public static function destroy( $log ) {
355
356 global $wpdb;
357
358 $success = $wpdb->delete(
359 $wpdb->prefix . 'psmsc_acb_messages',
360 array( 'session_id' => $log->id )
361 );
362
363 $success = $wpdb->delete(
364 $wpdb->prefix . 'psmsc_acb_sessions',
365 array( 'id' => $log->id )
366 );
367
368 unset( self::$cache[ $log->id ] );
369 return ! $success ? false : true;
370 }
371
372 /**
373 * Set data to create new object using direct data. Used in find method
374 *
375 * @param array $data - data to set for object.
376 * @return void
377 */
378 private function set_data( $data ) {
379
380 foreach ( $data as $var_name => $val ) {
381 $this->data[ $var_name ] = $val !== null ? $val : '';
382 }
383 self::$cache[ $this->id ] = $this;
384 }
385
386 /**
387 * Find records based on given filters
388 *
389 * @param array $filter - array containing array items like search, where, orderby, order, page_no, items_per_page, etc.
390 * @param boolean $is_object - return data as array or object. Default object.
391 * @return mixed
392 */
393 public static function find( $filter = array(), $is_object = true ) {
394
395 global $wpdb;
396
397 $filter['items_per_page'] = isset( $filter['items_per_page'] ) ? $filter['items_per_page'] : 20;
398 $filter['page_no'] = isset( $filter['page_no'] ) ? $filter['page_no'] : 1;
399 $filter['orderby'] = isset( $filter['orderby'] ) ? $filter['orderby'] : 'date_created';
400 $filter['order'] = isset( $filter['order'] ) ? $filter['order'] : 'ASC';
401
402 $sql = 'SELECT acbs.* FROM ' . $wpdb->prefix . 'psmsc_acb_sessions acbs ';
403 $where = self::get_where( $filter );
404
405 // Add table alias to orderby.
406 $filter['orderby'] = 'acbs.' . $filter['orderby'];
407
408 $order = WPSC_Functions::parse_order( $filter );
409 $limit = WPSC_Functions::parse_limit( $filter );
410
411 $group_by = 'GROUP BY acbs.id ';
412
413 $sql = $sql . $where . $group_by . $order . $limit;
414 $results = $wpdb->get_results( $sql, ARRAY_A );
415
416 // total results.
417 $sql = 'SELECT count(DISTINCT acbs.id) FROM ' . $wpdb->prefix . 'psmsc_acb_sessions acbs ';
418 $total_items = $wpdb->get_var( $sql . $where );
419
420 $response = WPSC_Functions::parse_response( $results, $total_items, $filter );
421
422 // Return array.
423 if ( ! $is_object ) {
424 return $response;
425 }
426
427 // create and return array of objects.
428 $temp_results = array();
429 foreach ( $response['results'] as $customer ) {
430
431 $ob = new WPSC_ACB_Sessions();
432 $data = array();
433 foreach ( $customer as $key => $val ) {
434 $data[ $key ] = $val;
435 }
436 $ob->set_data( $data );
437 $temp_results[] = $ob;
438 }
439 $response['results'] = $temp_results;
440 return $response;
441 }
442
443 /**
444 * Get where for find method
445 *
446 * @param array $filter - user filter.
447 * @return array
448 */
449 private static function get_where( $filter ) {
450 $where = array( '1=1' );
451
452 // Load meta filters.
453 $meta_query = isset( $filter['meta_query'] ) ? $filter['meta_query'] : array();
454 if ( $meta_query ) {
455 $where[] = WPSC_Functions::parse_user_filters( __CLASS__, $meta_query );
456 }
457
458 global $wpdb;
459 $search = WPSC_Functions::get_filter_search_str( $filter );
460 if ( $search ) {
461 $escaped_search = esc_sql( $wpdb->esc_like( $search ) );
462 $like = '%' . $escaped_search . '%';
463
464 $search_query = array();
465
466 // AI chatbot sessions table cols.
467 foreach ( self::$schema as $slug => $schema ) {
468 if ( ! $schema['has_ref'] && $slug != 'id' ) {
469 $search_query[] = $wpdb->prepare( 'CONVERT(acbs.' . $slug . ' USING utf8) LIKE %s', $like );
470 }
471 }
472 $where[] = implode( ' OR ', $search_query );
473 }
474
475 return 'WHERE (' . implode( ') AND (', $where ) . ') ';
476 }
477
478 /**
479 * Load current class to reference classes
480 *
481 * @param array $classes - Associative array of class names indexed by its slug.
482 * @return array
483 */
484 public static function load_ref_class( $classes ) {
485
486 $classes['wpsc_acb_sessions'] = array(
487 'class' => __CLASS__,
488 'save-key' => 'id',
489 );
490 return $classes;
491 }
492
493 /**
494 * Count total records based on given filters
495 *
496 * @param array $filter - array containing array items like search, where, orderby, order, page_no, items_per_page, etc.
497 * @return int
498 */
499 public static function count( $filter = array() ) {
500
501 global $wpdb;
502
503 $sql = 'SELECT COUNT(DISTINCT acbs.id) FROM ' . $wpdb->prefix . 'psmsc_acb_sessions acbs ';
504 $where = self::get_where( $filter );
505
506 $sql = $sql . $where;
507
508 return (int) $wpdb->get_var( $sql );
509 }
510
511 /**
512 * Get session by session uuid
513 *
514 * @param string $session_id - session uuid.
515 * @return WPSC_ACB_Sessions|null
516 */
517 public static function get_session_by_session_uuid( $session_id ) {
518 global $wpdb;
519
520 $sql = $wpdb->prepare(
521 "SELECT * FROM {$wpdb->prefix}psmsc_acb_sessions WHERE session_id = %s",
522 $session_id
523 );
524
525 $result = $wpdb->get_row( $sql, ARRAY_A );
526
527 if ( ! $result ) {
528 return null;
529 }
530
531 $session = new WPSC_ACB_Sessions();
532 $session->set_data( $result );
533
534 return $session;
535 }
536 }
537 endif;
538
539 WPSC_ACB_Sessions::init();
540