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 / settings / class-wpsc-ticket-categories.php

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

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