PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.5.2
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.5.2
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 / rest-api / class-wpsc-rest-tickets.php

class-wpsc-rest-tickets.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.5.2, at includes/rest-api/class-wpsc-rest-tickets.php

533 lines 15.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_REST_Tickets' ) ) :
7
8 final class WPSC_REST_Tickets {
9
10 /**
11 * Initialize this class
12 *
13 * @return void
14 */
15 public static function init() {
16
17 add_action( 'wpsc_rest_register_routes', array( __CLASS__, 'register_routes' ) );
18 }
19
20 /**
21 * Register routes
22 *
23 * @return void
24 */
25 public static function register_routes() {
26
27 // create new ticket.
28 register_rest_route(
29 'supportcandy/v2',
30 '/tickets',
31 array(
32 'methods' => 'POST',
33 'callback' => array( 'WPSC_REST_Individual_Ticket', 'create' ),
34 'permission_callback' => 'is_user_logged_in',
35 )
36 );
37
38 // list tickets.
39 register_rest_route(
40 'supportcandy/v2',
41 '/tickets',
42 array(
43 'methods' => 'GET',
44 'callback' => array( __CLASS__, 'get_tickets' ),
45 'args' => array(
46 'per_page' => array(
47 'default' => 20,
48 'validate_callback' => array( 'WPSC_REST_API', 'validate_integer_value' ),
49 ),
50 'page' => array(
51 'default' => 1,
52 'validate_callback' => array( 'WPSC_REST_API', 'validate_integer_value' ),
53 ),
54 'filter' => array(
55 'default' => 'all',
56 'validate_callback' => array( __CLASS__, 'validate_ticket_filter' ),
57 ),
58 'orderby' => array(
59 'default' => 'date_updated',
60 'validate_callback' => array( __CLASS__, 'validate_filter_orderby' ),
61 ),
62 'order' => array(
63 'default' => 'DESC',
64 'validate_callback' => function ( $param, $request, $key ) {
65 return in_array( strtoupper( $param ), array( 'ASC', 'DESC' ) );
66 },
67 'sanitize_callback' => function ( $param, $request, $key ) {
68 return strtoupper( $param );
69 },
70 ),
71 'search' => array(
72 'default' => '',
73 'sanitize_callback' => function ( $param, $request, $key ) {
74 return sanitize_text_field( $param );
75 },
76 ),
77 ),
78 'permission_callback' => 'is_user_logged_in',
79 )
80 );
81
82 // get individual ticket.
83 register_rest_route(
84 'supportcandy/v2',
85 '/tickets/(?P<id>\d+)',
86 array(
87 'methods' => 'GET',
88 'callback' => array( 'WPSC_REST_Individual_Ticket', 'get' ),
89 'args' => array(
90 'id' => array(
91 'validate_callback' => array( 'WPSC_REST_Individual_Ticket', 'validate_id' ),
92 ),
93 ),
94 'permission_callback' => 'is_user_logged_in',
95 ),
96 );
97
98 // update individual ticket.
99 register_rest_route(
100 'supportcandy/v2',
101 '/tickets/(?P<id>\d+)/update-fields',
102 array(
103 'methods' => 'POST',
104 'callback' => array( 'WPSC_REST_Individual_Ticket', 'update' ),
105 'args' => array(
106 'id' => array(
107 'validate_callback' => array( 'WPSC_REST_Individual_Ticket', 'validate_id' ),
108 ),
109 ),
110 'permission_callback' => 'is_user_logged_in',
111 ),
112 );
113
114 // delete individual ticket.
115 register_rest_route(
116 'supportcandy/v2',
117 '/tickets/(?P<id>\d+)',
118 array(
119 'methods' => 'DELETE',
120 'callback' => array( 'WPSC_REST_Individual_Ticket', 'delete' ),
121 'args' => array(
122 'id' => array(
123 'validate_callback' => array( 'WPSC_REST_Individual_Ticket', 'validate_id' ),
124 ),
125 ),
126 'permission_callback' => 'is_user_logged_in',
127 ),
128 );
129
130 // thread listing.
131 register_rest_route(
132 'supportcandy/v2',
133 '/tickets/(?P<id>\d+)/threads',
134 array(
135 'methods' => 'GET',
136 'callback' => array( 'WPSC_REST_Individual_Ticket', 'get_threads' ),
137 'args' => array(
138 'per_page' => array(
139 'default' => 20,
140 'validate_callback' => array( 'WPSC_REST_API', 'validate_integer_value' ),
141 ),
142 'page' => array(
143 'default' => 1,
144 'validate_callback' => array( 'WPSC_REST_API', 'validate_integer_value' ),
145 ),
146 'order' => array(
147 'default' => 'DESC',
148 'validate_callback' => function ( $param, $request, $key ) {
149 return in_array( strtoupper( $param ), array( 'ASC', 'DESC' ) );
150 },
151 'sanitize_callback' => function ( $param, $request, $key ) {
152 return strtoupper( $param );
153 },
154 ),
155 ),
156 'permission_callback' => 'is_user_logged_in',
157 )
158 );
159
160 // add new thread.
161 register_rest_route(
162 'supportcandy/v2',
163 '/tickets/(?P<id>\d+)/threads',
164 array(
165 'methods' => 'POST',
166 'callback' => array( 'WPSC_REST_Individual_Ticket', 'add_new_thread' ),
167 'args' => array(
168 'type' => array(
169 'required' => true,
170 'validate_callback' => function ( $param, $request, $key ) {
171 return in_array( strtolower( $param ), array( 'reply', 'note' ) );
172 },
173 'sanitize_callback' => function ( $param, $request, $key ) {
174 return strtolower( $param );
175 },
176 ),
177 'body' => array(
178 'required' => true,
179 'sanitize_callback' => function ( $param, $request, $key ) {
180 $is_html = $param != wp_strip_all_tags( $param ) ? true : false;
181 return $is_html ? wp_kses_post( $param ) : str_replace( PHP_EOL, '<br />', $param );
182 },
183 ),
184 'source' => array( // we can use this api in some another api like slack, telegram, etc. where source is different.
185 'default' => 'rest-api',
186 'sanitize_callback' => function ( $param, $request, $key ) {
187 return sanitize_text_field( $param );
188 },
189 ),
190 'attachments' => array(
191 'default' => array(),
192 'sanitize_callback' => function ( $param, $request, $key ) {
193 return array_unique(
194 array_filter(
195 array_map(
196 fn( $attachment ) => WPSC_Functions::sanitize_attachment( intval( $attachment ) ),
197 explode( ',', sanitize_text_field( $param ) )
198 )
199 )
200 );
201 },
202 ),
203 ),
204 'permission_callback' => 'is_user_logged_in',
205 )
206 );
207
208 // ticket list filters.
209 register_rest_route(
210 'supportcandy/v2',
211 '/tickets/filters',
212 array(
213 'methods' => 'GET',
214 'callback' => array( __CLASS__, 'get_filters' ),
215 'permission_callback' => 'is_user_logged_in',
216 ),
217 );
218
219 // ticket list orderby filters.
220 register_rest_route(
221 'supportcandy/v2',
222 '/tickets/filters/orderby',
223 array(
224 'methods' => 'GET',
225 'callback' => array( __CLASS__, 'get_orderby_fields' ),
226 'permission_callback' => 'is_user_logged_in',
227 ),
228 );
229
230 // ticket list items.
231 register_rest_route(
232 'supportcandy/v2',
233 '/tickets/list-items',
234 array(
235 'methods' => 'GET',
236 'callback' => array( __CLASS__, 'get_list_items' ),
237 'permission_callback' => 'is_user_logged_in',
238 ),
239 );
240
241 // ticket form fields.
242 register_rest_route(
243 'supportcandy/v2',
244 '/tickets/form-fields',
245 array(
246 'methods' => 'GET',
247 'callback' => array( __CLASS__, 'get_form_fields' ),
248 'permission_callback' => 'is_user_logged_in',
249 ),
250 );
251 }
252
253 /**
254 * Ticket list collection
255 *
256 * @param WP_REST_Request $request - request object.
257 * @return WP_Error|WP_REST_Response
258 */
259 public static function get_tickets( $request ) {
260
261 $current_user = WPSC_Current_User::$current_user;
262
263 // triggers loading of prevent ticket data property.
264 do_action( 'wpsc_rest_load_ticket_prevent_data' );
265
266 // We need to use functions from WPSC_Ticket_List class. Initialize required static fields.
267 $current_user_filters = $current_user->get_tl_filters();
268 WPSC_Ticket_List::$default_filters = $current_user_filters['default'];
269 WPSC_Ticket_List::$more_settings = $current_user->get_tl_default_settings();
270
271 // initialize filters.
272 $filters = array(
273 'items_per_page' => $request->get_param( 'per_page' ),
274 'page_no' => $request->get_param( 'page' ),
275 'orderby' => $request->get_param( 'orderby' ),
276 'order' => $request->get_param( 'order' ),
277 'search' => $request->get_param( 'search' ),
278 );
279
280 // system query.
281 $filters['system_query'] = $current_user->get_tl_system_query( $filters );
282
283 // meta query.
284 $meta_query = array( 'relation' => 'AND' );
285 if ( preg_match( '/saved-(\d*)$/', $request->get_param( 'filter' ), $matches ) ) {
286
287 // parent meta query.
288 $meta_query = array_merge(
289 $meta_query,
290 WPSC_Ticket_List::get_parent_meta_query( $current_user_filters['saved'][ $matches[1] ]['parent-filter'] )
291 );
292
293 // filter meta query.
294 $filters_str = $current_user_filters['saved'][ $matches[1] ]['filters'];
295 $filters_str = str_replace( '^^', '\n', $filters_str );
296 $meta_query = array_merge( $meta_query, WPSC_Ticket_Conditions::get_meta_query( $filters_str, true ) );
297 } elseif ( preg_match( '/default-(\d*)$/', $request->get_param( 'filter' ), $matches ) ) {
298
299 // parent meta query.
300 $meta_query = array_merge(
301 $meta_query,
302 WPSC_Ticket_List::get_parent_meta_query( $current_user_filters['default'][ $matches[1] ]['parent-filter'] )
303 );
304
305 // filter meta query.
306 $filters_arr = json_decode( html_entity_decode( $current_user_filters['default'][ $matches[1] ]['filters'] ), true );
307 $filters_str = $current_user_filters['saved'][ $matches[1] ]['filters'];
308 $filters_str = str_replace( '^^', '\n', $filters_str );
309 $meta_query = array_merge( $meta_query, WPSC_Ticket_Conditions::get_meta_query( $filters_str, true ) );
310 } else {
311
312 $meta_query = array_merge(
313 $meta_query,
314 WPSC_Ticket_List::get_parent_meta_query( $request->get_param( 'filter' ) )
315 );
316 }
317
318 // set meta query.
319 $filters['meta_query'] = $meta_query;
320
321 // is active.
322 $filters['is_active'] = WPSC_Ticket_List::$is_active;
323
324 // get tickets.
325 $tickets = WPSC_Ticket::find( $filters, false );
326 $tickets['results'] = array_map(
327 fn( $ticket ) => WPSC_REST_Individual_Ticket::modify_response( $ticket ),
328 $tickets['results']
329 );
330
331 return new WP_REST_Response( $tickets, 200 );
332 }
333
334 /**
335 * Ticket list filters
336 *
337 * @param WP_REST_Request $request - request object.
338 * @return WP_Error|WP_REST_Response
339 */
340 public static function get_filters( $request ) {
341
342 $current_user = WPSC_Current_User::$current_user;
343 $current_user_filters = $current_user->get_tl_filters();
344 $tl_default_settings = $current_user->get_tl_default_settings();
345 $data = array(
346 'default' => array(),
347 'saved' => array(),
348 );
349
350 // default filtes.
351 foreach ( $current_user_filters['default'] as $index => $filter ) {
352
353 if ( is_numeric( $index ) ) {
354
355 $data['default'][ 'default-' . $index ] = array(
356 'slug' => 'default-' . $index,
357 'label' => $filter['label'],
358 'orderby' => $filter['sort-by'],
359 'order' => $filter['sort-order'],
360 );
361
362 } else {
363
364 $data['default'][ $index ] = array(
365 'slug' => $index,
366 'label' => $filter['label'],
367 'orderby' => $tl_default_settings['default-sort-by'],
368 'order' => $tl_default_settings['default-sort-order'],
369 );
370 }
371 }
372
373 // saved filters.
374 foreach ( $current_user_filters['saved'] as $index => $filter ) {
375
376 $data['saved'][ 'saved-' . $index ] = array(
377 'slug' => 'saved-' . $index,
378 'label' => $filter['label'],
379 'orderby' => $filter['sort-by'],
380 'order' => $filter['sort-order'],
381 );
382 }
383
384 return new WP_REST_Response( $data, 200 );
385 }
386
387 /**
388 * Ticket list orderby filters
389 *
390 * @param WP_REST_Request $request - request object.
391 * @return WP_Error|WP_REST_Response
392 */
393 public static function get_orderby_fields( $request ) {
394
395 $current_user = WPSC_Current_User::$current_user;
396 $list_items = $current_user->get_tl_list_items();
397
398 $data = array();
399 foreach ( $list_items as $slug ) {
400
401 $cf = WPSC_Custom_Field::get_cf_by_slug( $slug );
402 if ( ! $cf ) {
403 continue;
404 }
405
406 $data[ $slug ] = $cf->name;
407 }
408
409 return new WP_REST_Response( $data, 200 );
410 }
411
412 /**
413 * Ticket list items route
414 *
415 * @param WP_REST_Request $request - request object.
416 * @return WP_Error|WP_REST_Response
417 */
418 public static function get_list_items( $request ) {
419
420 $current_user = WPSC_Current_User::$current_user;
421 $list_items = $current_user->get_tl_list_items();
422
423 $data = array();
424 foreach ( $list_items as $slug ) {
425
426 $cf = WPSC_Custom_Field::get_cf_by_slug( $slug );
427 if ( ! $cf ) {
428 continue;
429 }
430
431 $data[ $slug ] = WPSC_REST_Custom_Fields::modify_response( $cf );
432 }
433
434 return new WP_REST_Response( $data, 200 );
435 }
436
437 /**
438 * Ticket list items route
439 *
440 * @param WP_REST_Request $request - request object.
441 * @return WP_Error|WP_REST_Response
442 */
443 public static function get_form_fields( $request ) {
444
445 $current_user = WPSC_Current_User::$current_user;
446 $tff = get_option( 'wpsc-tff' );
447
448 $data = array();
449 foreach ( $tff as $slug => $value ) {
450
451 $cf = WPSC_Custom_Field::get_cf_by_slug( $slug );
452 if ( ! $cf ) {
453 continue;
454 }
455
456 if (
457 isset( $value['allowed_user'] ) &&
458 (
459 ( $current_user->is_agent && ! in_array( $value['allowed_user'], array( 'agent', 'both' ) ) ) ||
460 ( ! $current_user->is_agent && ! in_array( $value['allowed_user'], array( 'customer', 'both' ) ) )
461 )
462 ) {
463 continue;
464 }
465
466 $data[ $slug ] = WPSC_REST_Custom_Fields::modify_response( $cf );
467 $data[ $slug ]['is-required'] = $value['is-required'];
468 }
469
470 return new WP_REST_Response( $data, 200 );
471 }
472
473 /**
474 * Validate ticket filter
475 *
476 * @param string $param - parameter value.
477 * @param WP_REST_Request $request - request object.
478 * @param string $key - filter key.
479 * @return boolean
480 */
481 public static function validate_ticket_filter( $param, $request, $key ) {
482
483 $current_user = WPSC_Current_User::$current_user;
484 $current_user_filters = $current_user->get_tl_filters();
485
486 // system defaults.
487 if ( isset( $current_user_filters['default'][ $param ] ) ) {
488 return true;
489 }
490
491 // custom defaults.
492 if ( preg_match( '/default-(\d*)$/', $param, $matches ) && isset( $current_user_filters['default'][ $matches[1] ] ) ) {
493 return true;
494 }
495
496 // saved filters.
497 if ( preg_match( '/saved-(\d*)$/', $param, $matches ) && isset( $current_user_filters['saved'][ $matches[1] ] ) ) {
498 return true;
499 }
500
501 return false;
502 }
503
504 /**
505 * Validate ticket filter orderby slug
506 *
507 * @param string $param - parameter value.
508 * @param WP_REST_Request $request - request object.
509 * @param string $key - filter key.
510 * @return boolean
511 */
512 public static function validate_filter_orderby( $param, $request, $key ) {
513
514 $current_user = WPSC_Current_User::$current_user;
515 $list_items = $current_user->get_tl_list_items();
516 $flag = false;
517 foreach ( $list_items as $slug ) {
518 $cf = WPSC_Custom_Field::get_cf_by_slug( $slug );
519 if ( ! $cf || ! $cf->type::$is_sort ) {
520 continue;
521 }
522 if ( $cf->slug == $param ) {
523 $flag = true;
524 break;
525 }
526 }
527 return $flag;
528 }
529 }
530 endif;
531
532 WPSC_REST_Tickets::init();
533