PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.4.9
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.4.9
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 / settings / class-wpsc-ticket-categories.php

class-wpsc-ticket-categories.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.4.9, at includes/admin/settings/class-wpsc-ticket-categories.php

576 lines 17.1 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_Ticket_Categories' ) ) :
7
8 final class WPSC_Ticket_Categories {
9
10 /**
11 * Initialize this class
12 */
13 public static function init() {
14
15 // List.
16 add_action( 'wp_ajax_wpsc_get_ticket_categories', array( __CLASS__, 'get_ticket_categories' ) );
17
18 // Add new.
19 add_action( 'wp_ajax_wpsc_get_add_new_category', array( __CLASS__, 'get_add_new_category' ) );
20 add_action( 'wp_ajax_wpsc_set_add_category', array( __CLASS__, 'wpsc_set_add_category' ) );
21
22 // Edit.
23 add_action( 'wp_ajax_wpsc_get_edit_category', array( __CLASS__, 'get_edit_category' ) );
24 add_action( 'wp_ajax_wpsc_set_edit_category', array( __CLASS__, 'set_edit_category' ) );
25
26 // Delete.
27 add_action( 'wp_ajax_wpsc_get_delete_category', array( __CLASS__, 'get_delete_category' ) );
28 add_action( 'wp_ajax_wpsc_set_delete_category', array( __CLASS__, 'set_delete_category' ) );
29 }
30
31 /**
32 * Load ticket category list
33 */
34 public static function get_ticket_categories() {
35
36 if ( ! WPSC_Functions::is_site_admin() ) {
37 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
38 }
39
40 $categories = WPSC_Category::find( array( 'items_per_page' => 0 ) )['results'];
41
42 $cf = WPSC_Custom_Field::get_cf_by_slug( 'category' );?>
43
44 <div class="wpsc-setting-header">
45 <h2><?php esc_attr_e( 'Ticket Categories', 'supportcandy' ); ?></h2>
46 </div>
47 <div class="wpsc-setting-section-body">
48 <div class="wpsc-dock-container">
49 <?php
50 printf(
51 /* translators: Click here to see the documentation */
52 esc_attr__( '%s to see the documentation!', 'supportcandy' ),
53 '<a href="https://supportcandy.net/docs/ticket-categories/" target="_blank">' . esc_attr__( 'Click here', 'supportcandy' ) . '</a>'
54 );
55 ?>
56 </div>
57 <table class="wpsc-ticket-categories wpsc-setting-tbl">
58 <thead>
59 <tr>
60 <th><?php esc_attr_e( 'Name', 'supportcandy' ); ?></th>
61 <th><?php esc_attr_e( 'Actions', 'supportcandy' ); ?></th>
62 </tr>
63 </thead>
64 <tbody>
65 <?php
66 foreach ( $categories as $category ) {
67 ?>
68 <tr>
69 <td><span class="title"><?php echo esc_attr( $category->name ); ?></span></td>
70 <td>
71 <div class="actions">
72 <span class="wpsc-link" onclick="wpsc_get_edit_category(<?php echo esc_attr( $category->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_edit_category' ) ); ?>');" ><?php echo esc_attr__( 'Edit', 'supportcandy' ); ?></span>
73 <?php
74 if ( $cf->default_value[0] != $category->id ) :
75 ?>
76 | <span class="wpsc-link" onclick="wpsc_get_delete_category(<?php echo esc_attr( $category->id ); ?>, '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_delete_category' ) ); ?>');" ><?php echo esc_attr__( 'Delete', 'supportcandy' ); ?></span>
77 <?php
78 endif;
79 ?>
80 </div>
81 </td>
82 </tr>
83 <?php
84 }
85 ?>
86 </tbody>
87 </table>
88 </div>
89 <script>
90 jQuery('table.wpsc-ticket-categories').DataTable({
91 ordering: false,
92 pageLength: 20,
93 bLengthChange: false,
94 columnDefs: [
95 { targets: -1, searchable: false },
96 { targets: '_all', className: 'dt-left' }
97 ],
98 layout: {
99 topStart: {
100 buttons: [
101 {
102 text: '<?php esc_attr_e( 'Add new', 'supportcandy' ); ?>',
103 className: 'wpsc-button small primary',
104 action: function ( e, dt, node, config ) {
105 wpsc_show_modal();
106 var data = { action: 'wpsc_get_add_new_category' };
107 jQuery.post(
108 supportcandy.ajax_url,
109 data,
110 function (response) {
111
112 // Set to modal.
113 jQuery( '.wpsc-modal-header' ).text( response.title );
114 jQuery( '.wpsc-modal-body' ).html( response.body );
115 jQuery( '.wpsc-modal-footer' ).html( response.footer );
116 // Display modal.
117 wpsc_show_modal_inner_container();
118 }
119 );
120 }
121 }
122 ],
123 },
124 },
125 language: supportcandy.translations.datatables
126 });
127 </script>
128 <?php
129 wp_die();
130 }
131
132 /**
133 * Get add new category
134 *
135 * @return void
136 */
137 public static function get_add_new_category() {
138
139 if ( ! WPSC_Functions::is_site_admin() ) {
140 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
141 }
142 $title = esc_attr__( 'Add new', 'supportcandy' );
143
144 $categories = WPSC_Category::find( array( 'items_per_page' => 0 ) )['results'];
145 ob_start();
146 ?>
147 <form action="#" onsubmit="return false;" class="wpsc-frm-add-category">
148 <div class="wpsc-input-group">
149 <div class="label-container">
150 <label for=""><?php esc_attr_e( 'Name', 'supportcandy' ); ?></label>
151 <span class="required-char">*</span>
152 </div>
153 <input name="label" type="text" autocomplete="off">
154 </div>
155
156 <div data-type="" data-required="true" class="wpsc-input-group load-after">
157 <div class="label-container">
158 <label for="">
159 <?php esc_attr_e( 'Load after', 'supportcandy' ); ?>
160 </label>
161 </div>
162 <select name="load-after" class="load-after">
163 <option value="__TOP__">-- <?php esc_attr_e( 'TOP', 'supportcandy' ); ?> --</option>
164 <?php
165 foreach ( $categories as $category ) {
166 ?>
167 <option value="<?php echo esc_attr( $category->id ); ?>"><?php echo esc_attr( $category->name ); ?></option>
168 <?php
169 }
170 ?>
171 <option selected value="__END__">-- <?php esc_attr_e( 'END', 'supportcandy' ); ?> --</option>
172 </select>
173 <script>jQuery('select.load-after').selectWoo();</script>
174 </div>
175
176 <?php do_action( 'wpsc_get_add_category_body' ); ?>
177 <input type="hidden" name="action" value="wpsc_set_add_category">
178 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_add_category' ) ); ?>">
179 </form>
180 <?php
181 $body = ob_get_clean();
182
183 ob_start();
184 ?>
185 <button class="wpsc-button small primary" onclick="wpsc_set_add_category(this);">
186 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
187 </button>
188 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
189 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
190 </button>
191 <?php
192 do_action( 'wpsc_get_add_category_footer' );
193 $footer = ob_get_clean();
194
195 $response = array(
196 'title' => $title,
197 'body' => $body,
198 'footer' => $footer,
199 );
200 wp_send_json( $response );
201 }
202
203 /**
204 * Insert new category
205 *
206 * @return void
207 */
208 public static function wpsc_set_add_category() {
209
210 if ( check_ajax_referer( 'wpsc_set_add_category', '_ajax_nonce', false ) != 1 ) {
211 wp_send_json_error( 'Unauthorized request!', 401 );
212 }
213
214 if ( ! WPSC_Functions::is_site_admin() ) {
215 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
216 }
217
218 $label = isset( $_POST['label'] ) ? sanitize_text_field( wp_unslash( $_POST['label'] ) ) : '';
219 if ( ! $label ) {
220 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
221 }
222
223 $data = array( 'name' => $label );
224 $category = WPSC_Category::insert( $data );
225
226 // set laod order.
227 $categories = WPSC_Category::find( array( 'items_per_page' => 0 ) )['results'];
228 $load_after = isset( $_POST['load-after'] ) ? sanitize_text_field( wp_unslash( $_POST['load-after'] ) ) : '__END__';
229
230 if ( $load_after != '__END__' ) {
231
232 $count = 1;
233
234 if ( $load_after == '__TOP__' ) {
235 $category->load_order = $count++;
236 $category->save();
237 }
238
239 foreach ( $categories as $cat ) {
240
241 if ( $cat->id == $category->id ) {
242 continue;
243 }
244
245 $cat->load_order = $count++;
246 $cat->save();
247
248 if ( $cat->id == $load_after ) {
249 $category->load_order = $count++;
250 $category->save();
251 }
252 }
253 }
254
255 wp_die();
256 }
257
258 /**
259 * Edit category modal
260 *
261 * @return void
262 */
263 public static function get_edit_category() {
264
265 global $wpdb;
266
267 if ( check_ajax_referer( 'wpsc_get_edit_category', '_ajax_nonce', false ) != 1 ) {
268 wp_send_json_error( 'Unauthorized request!', 401 );
269 }
270
271 if ( ! WPSC_Functions::is_site_admin() ) {
272 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
273 }
274
275 $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
276 if ( ! $id ) {
277 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
278 }
279
280 $category = new WPSC_Category( $id );
281 if ( ! $category->id ) {
282 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
283 }
284
285 $title = esc_attr( $category->name );
286
287 $categories = WPSC_Category::find( array( 'items_per_page' => 0 ) )['results'];
288 ob_start();
289 ?>
290 <form action="#" onsubmit="return false;" class="wpsc-frm-edit-category">
291 <div class="wpsc-input-group">
292 <div class="label-container">
293 <label for=""><?php esc_attr_e( 'Name', 'supportcandy' ); ?></label>
294 <span class="required-char">*</span>
295 </div>
296 <input name="label" type="text" value="<?php echo esc_attr( $category->name ); ?>" autocomplete="off">
297 </div>
298
299 <div data-type="" data-required="true" class="wpsc-input-group load-after">
300 <div class="label-container">
301 <label for="">
302 <?php esc_attr_e( 'Load after', 'supportcandy' ); ?>
303 </label>
304 </div>
305 <select name="load-after" class="load-after">
306 <option value="__TOP__">-- <?php esc_attr_e( 'TOP', 'supportcandy' ); ?> --</option>
307 <?php
308 $load_after = $wpdb->get_var( "SELECT id FROM {$wpdb->prefix}psmsc_categories WHERE load_order < {$category->load_order} ORDER BY load_order DESC LIMIT 1" );
309 foreach ( $categories as $cat ) {
310 if ( $cat->id == $category->id ) {
311 continue;
312 }
313 ?>
314 <option <?php selected( $load_after, $cat->id ); ?> value="<?php echo esc_attr( $cat->id ); ?>"><?php echo esc_attr( $cat->name ); ?></option>
315 <?php
316 }
317 ?>
318 <option value="__END__">-- <?php esc_attr_e( 'END', 'supportcandy' ); ?> --</option>
319 </select>
320 <script>jQuery('select.load-after').selectWoo();</script>
321 </div>
322
323 <?php do_action( 'wpsc_get_edit_category_body' ); ?>
324 <input type="hidden" name="id" value="<?php echo esc_attr( $category->id ); ?>">
325 <input type="hidden" name="action" value="wpsc_set_edit_category">
326 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_edit_category' ) ); ?>">
327 </form>
328 <?php
329 $body = ob_get_clean();
330
331 ob_start();
332 ?>
333 <button class="wpsc-button small primary" onclick="wpsc_set_edit_category(this);">
334 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
335 </button>
336 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
337 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
338 </button>
339 <?php
340 do_action( 'wpsc_get_edit_category_footer' );
341 $footer = ob_get_clean();
342
343 $response = array(
344 'title' => $title,
345 'body' => $body,
346 'footer' => $footer,
347 );
348 wp_send_json( $response );
349 }
350
351 /**
352 * Set edit category
353 *
354 * @return void
355 */
356 public static function set_edit_category() {
357
358 global $wpdb;
359
360 if ( check_ajax_referer( 'wpsc_set_edit_category', '_ajax_nonce', false ) != 1 ) {
361 wp_send_json_error( 'Unauthorized request!', 401 );
362 }
363
364 if ( ! WPSC_Functions::is_site_admin() ) {
365 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
366 }
367
368 $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
369 if ( ! $id ) {
370 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
371 }
372
373 $label = isset( $_POST['label'] ) ? sanitize_text_field( wp_unslash( $_POST['label'] ) ) : '';
374 if ( ! $label ) {
375 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
376 }
377
378 $category = new WPSC_Category( $id );
379 if ( ! $category->id ) {
380 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
381 }
382
383 $category->name = $label;
384 $category->save();
385
386 // set laod order.
387 $categories = WPSC_Category::find( array( 'items_per_page' => 0 ) )['results'];
388 $load_after = isset( $_POST['load-after'] ) ? sanitize_text_field( wp_unslash( $_POST['load-after'] ) ) : '__END__';
389
390 if ( $load_after != '__END__' ) {
391
392 $count = 1;
393
394 if ( $load_after == '__TOP__' ) {
395 $category->load_order = $count++;
396 $category->save();
397 }
398
399 foreach ( $categories as $cat ) {
400
401 if ( $cat->id == $category->id ) {
402 continue;
403 }
404
405 $cat->load_order = $count++;
406 $cat->save();
407
408 if ( $cat->id == $load_after ) {
409 $category->load_order = $count++;
410 $category->save();
411 }
412 }
413 } else {
414
415 $max_load_order = (int) $wpdb->get_var( "SELECT max(load_order) FROM {$wpdb->prefix}psmsc_categories" );
416 $category->load_order = ++$max_load_order;
417 $category->save();
418 }
419
420 wp_die();
421 }
422
423 /**
424 * Delete category modal
425 *
426 * @return void
427 */
428 public static function get_delete_category() {
429
430 if ( ! WPSC_Functions::is_site_admin() ) {
431 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
432 }
433
434 if ( check_ajax_referer( 'wpsc_get_delete_category', '_ajax_nonce', false ) != 1 ) {
435 wp_send_json_error( 'Unauthorized request!', 401 );
436 }
437
438 $title = esc_attr__( 'Delete category', 'supportcandy' );
439
440 $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
441 if ( ! $id ) {
442 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
443 }
444
445 $category = new WPSC_Category( $id );
446 if ( ! $category->id ) {
447 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
448 }
449
450 $categories = WPSC_Category::find( array( 'items_per_page' => 0 ) )['results'];
451 ob_start();
452 ?>
453 <form action="#" onsubmit="return false;" class="wpsc-frm-delete-category">
454 <div class="wpsc-input-group">
455 <div class="label-container">
456 <label for=""><?php esc_attr_e( 'Replace with', 'supportcandy' ); ?></label>
457 </div>
458 <select name="replace_id">
459 <?php
460 foreach ( $categories as $cat ) {
461 if ( $cat->id == $category->id ) {
462 continue;
463 }
464 ?>
465 <option value="<?php echo esc_attr( $cat->id ); ?>"><?php echo esc_attr( $cat->name ); ?></option>
466 <?php
467 }
468 ?>
469 </select>
470 </div>
471 <input type="hidden" name="id" value="<?php echo esc_attr( $category->id ); ?>">
472 <input type="hidden" name="action" value="wpsc_set_delete_category">
473 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_delete_category' ) ); ?>">
474 </form>
475 <?php
476 $body = ob_get_clean();
477
478 ob_start();
479 ?>
480 <button class="wpsc-button small primary" onclick="wpsc_set_delete_category(this);">
481 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?>
482 </button>
483 <button class="wpsc-button small secondary" onclick="wpsc_close_modal();">
484 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?>
485 </button>
486 <?php
487 $footer = ob_get_clean();
488
489 $response = array(
490 'title' => $title,
491 'body' => $body,
492 'footer' => $footer,
493 );
494
495 wp_send_json( $response );
496 }
497
498 /**
499 * Delete Category
500 */
501 public static function set_delete_category() {
502
503 global $wpdb;
504
505 if ( ! WPSC_Functions::is_site_admin() ) {
506 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
507 }
508
509 if ( check_ajax_referer( 'wpsc_set_delete_category', '_ajax_nonce', false ) != 1 ) {
510 wp_send_json_error( 'Unauthorized request!', 401 );
511 }
512
513 $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
514 if ( ! $id ) {
515 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
516 }
517
518 $category = new WPSC_Category( $id );
519 if ( ! $category->id ) {
520 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
521 }
522
523 $replace_id = isset( $_POST['replace_id'] ) ? intval( $_POST['replace_id'] ) : 0;
524 if ( ! $replace_id ) {
525 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
526 }
527
528 $replace = new WPSC_Category( $replace_id );
529 if ( ! $replace->id ) {
530 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
531 }
532
533 $cf = WPSC_Custom_Field::get_cf_by_slug( 'category' );
534 if ( $id == $cf->default_value[0] ) {
535 wp_send_json_error( __( 'Bad request!', 'supportcandy' ), 400 );
536 }
537
538 // replace in ticket table.
539 $success = $wpdb->update(
540 $wpdb->prefix . 'psmsc_tickets',
541 array( 'category' => $replace->id ),
542 array( 'category' => $category->id )
543 );
544
545 // replace in logs.
546 $results = $wpdb->get_results(
547 "SELECT * FROM {$wpdb->prefix}psmsc_threads WHERE
548 (type = 'log') AND
549 JSON_VALID(body) AND
550 JSON_EXTRACT(body, '$.slug') = 'category' AND
551 (
552 JSON_UNQUOTE(JSON_EXTRACT(body, '$.new')) = '" . $category->id . "' OR
553 JSON_UNQUOTE(JSON_EXTRACT(body, '$.prev')) = '" . $category->id . "'
554 )"
555 );
556 foreach ( $results as $log ) {
557 $body = json_decode( $log->body );
558 $body->prev = $body->prev == $category->id ? $replace->id : $body->prev;
559 $body->new = $body->new == $category->id ? $replace->id : $body->new;
560 $body = wp_json_encode( $body );
561 $wpdb->update(
562 $wpdb->prefix . 'psmsc_threads',
563 array( 'body' => $body ),
564 array( 'id' => $log->id )
565 );
566 }
567
568 $category->destroy( $category );
569
570 wp_die();
571 }
572 }
573 endif;
574
575 WPSC_Ticket_Categories::init();
576