PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.3.8
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.3.8
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 / custom-field-types / class-wpsc-df-prev-assignee.php

class-wpsc-df-prev-assignee.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.3.8, at includes/custom-field-types/class-wpsc-df-prev-assignee.php

598 lines 15.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; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_DF_Prev_Assignee' ) ) :
7
8 final class WPSC_DF_Prev_Assignee {
9
10 /**
11 * Slug for this custom field type
12 *
13 * @var string
14 */
15 public static $slug = 'df_prev_assignee';
16
17 /**
18 * Set whether this custom field type is of type date
19 *
20 * @var boolean
21 */
22 public static $is_date = false;
23
24 /**
25 * Set whether this custom field type has applicable to date range
26 *
27 * @var boolean
28 */
29 public static $has_date_range = false;
30
31 /**
32 * Set whether this custom field type has multiple values
33 *
34 * @var boolean
35 */
36 public static $has_multiple_val = true;
37
38 /**
39 * Data type for column created in tickets table
40 *
41 * @var string
42 */
43 public static $data_type = 'TEXT NULL DEFAULT NULL';
44
45 /**
46 * Set whether this custom field type has reference to other class
47 *
48 * @var boolean
49 */
50 public static $has_ref = true;
51
52 /**
53 * Reference class for this custom field type so that its value(s) return with object or array of objects automatically. Empty string indicate no reference.
54 *
55 * @var string
56 */
57 public static $ref_class = 'wpsc_agent';
58
59 /**
60 * Set whether this custom field field type is system default (no fields can be created from it).
61 *
62 * @var boolean
63 */
64 public static $is_default = true;
65
66 /**
67 * Set whether this field type has extra information that can be used in ticket form, edit custom fields, etc.
68 *
69 * @var boolean
70 */
71 public static $has_extra_info = false;
72
73 /**
74 * Set whether this custom field type can accept personal info.
75 *
76 * @var boolean
77 */
78 public static $has_personal_info = false;
79
80 /**
81 * Set whether fields created from this custom field type is allowed in create ticket form
82 *
83 * @var boolean
84 */
85 public static $is_ctf = false;
86
87 /**
88 * Set whether fields created from this custom field type is allowed in ticket list
89 *
90 * @var boolean
91 */
92 public static $is_list = true;
93
94 /**
95 * Set whether fields created from this custom field type is allowed in ticket filter
96 *
97 * @var boolean
98 */
99 public static $is_filter = true;
100
101 /**
102 * Set whether fields created from this custom field type can be given character limits
103 *
104 * @var boolean
105 */
106 public static $has_char_limit = false;
107
108 /**
109 * Set whether fields created from this custom field type has custom options set in options table
110 *
111 * @var boolean
112 */
113 public static $has_options = false;
114
115 /**
116 * Set whether fields created from this custom field type can be available for ticket list sorting
117 *
118 * @var boolean
119 */
120 public static $is_sort = false;
121
122 /**
123 * Set whether fields created from this custom field type can be auto-filled
124 *
125 * @var boolean
126 */
127 public static $is_auto_fill = false;
128
129 /**
130 * Set whether fields created from this custom field type can have placeholder
131 *
132 * @var boolean
133 */
134 public static $is_placeholder = false;
135
136 /**
137 * Set whether fields created from this custom field type is applicable for visibility conditions in create ticket form
138 *
139 * @var boolean
140 */
141 public static $is_visibility_conditions = false;
142
143 /**
144 * Set whether fields created from this custom field type is applicable for macros
145 *
146 * @var boolean
147 */
148 public static $has_macro = true;
149
150 /**
151 * Set whether fields of this custom field type is applicalbe for search on ticket list page.
152 *
153 * @var boolean
154 */
155 public static $is_search = false;
156
157 /**
158 * Initialize the class
159 *
160 * @return void
161 */
162 public static function init() {
163
164 // Get object of this class.
165 add_filter( 'wpsc_load_ref_classes', array( __CLASS__, 'load_ref_class' ) );
166
167 // agent autocomplete filter access only.
168 add_action( 'wp_ajax_wpsc_agent_autocomplete_prev_assigned_agent', array( __CLASS__, 'agent_autocomplete_prev_assigned_agent' ) );
169 add_action( 'wp_ajax_nopriv_wpsc_agent_autocomplete_prev_assigned_agent', array( __CLASS__, 'agent_autocomplete_prev_assigned_agent' ) );
170
171 // rest api.
172 add_filter( 'wpsc_rest_prevent_ticket_data', array( __CLASS__, 'rest_prevent_ticket_data' ) );
173 }
174
175 /**
176 * Load current class to reference classes
177 *
178 * @param array $classes - Associative array of class names indexed by its slug.
179 * @return array
180 */
181 public static function load_ref_class( $classes ) {
182
183 $classes[ self::$slug ] = array(
184 'class' => __CLASS__,
185 'save-key' => 'id',
186 );
187 return $classes;
188 }
189
190 /**
191 * Return default value for custom field of this type
192 *
193 * @param WPSC_Custom_Field $cf - custom field object.
194 * @return mixed
195 */
196 public static function get_default_value( $cf ) {
197
198 return '';
199 }
200
201 /**
202 * Print operators for ticket form filter
203 *
204 * @param WPSC_Custom_Field $cf - custom field object.
205 * @param array $filter - Existing filters (if any).
206 * @return void
207 */
208 public static function get_operators( $cf, $filter = array() ) {
209 ?>
210
211 <div class="item conditional">
212 <select class="operator" onchange="wpsc_tc_get_operand(this, '<?php echo esc_attr( $cf->slug ); ?>', '<?php echo esc_attr( wp_create_nonce( 'wpsc_tc_get_operand' ) ); ?>');">
213 <option value=""><?php esc_attr_e( 'Compare As', 'supportcandy' ); ?></option>
214 <option <?php isset( $filter['operator'] ) && selected( $filter['operator'], '=' ); ?> value="="><?php esc_attr_e( 'Equals', 'supportcandy' ); ?></option>
215 <option <?php isset( $filter['operator'] ) && selected( $filter['operator'], 'IN' ); ?> value="IN"><?php esc_attr_e( 'Matches', 'supportcandy' ); ?></option>
216 <option <?php isset( $filter['operator'] ) && selected( $filter['operator'], 'NOT IN' ); ?> value="NOT IN"><?php esc_attr_e( 'Not Matches', 'supportcandy' ); ?></option>
217 </select>
218 </div>
219 <?php
220 }
221
222 /**
223 * Print operators for ticket form filter
224 *
225 * @param string $operator - condition operator on which operands should be returned.
226 * @param WPSC_Custom_Field $cf - custom field object.
227 * @param array $filter - Exising functions (if any).
228 * @return void
229 */
230 public static function get_operands( $operator, $cf, $filter = array() ) {
231
232 $is_multiple = $operator !== '=' ? true : false;
233 $unique_id = uniqid( 'wpsc_' );
234 ?>
235 <div class="item conditional operand single">
236 <select class="operand_val_1 <?php echo esc_attr( $unique_id ); ?>" <?php echo $is_multiple ? 'multiple' : ''; ?>>
237 <?php
238
239 if ( $is_multiple && isset( $filter['operand_val_1'] ) ) {
240
241 foreach ( $filter['operand_val_1'] as $agent_id ) {
242 $agent = new WPSC_Agent( intval( $agent_id ) )
243 ?>
244 <option selected="selected" value="<?php echo esc_attr( $agent->id ); ?>"><?php echo esc_attr( $agent->name ); ?></option>
245 <?php
246 }
247 }
248
249 if ( ! $is_multiple && isset( $filter['operand_val_1'] ) ) {
250
251 $agent = new WPSC_Agent( intval( $filter['operand_val_1'] ) )
252 ?>
253 <option selected="selected" value="<?php echo esc_attr( $agent->id ); ?>"><?php echo esc_attr( $agent->name ); ?></option>
254 <?php
255 }
256 ?>
257
258 </select>
259 </div>
260 <script>
261 jQuery('.operand_val_1.<?php echo esc_attr( $unique_id ); ?>').selectWoo({
262 ajax: {
263 url: supportcandy.ajax_url,
264 dataType: 'json',
265 delay: 250,
266 data: function (params) {
267 return {
268 q: params.term, // search term
269 page: params.page,
270 action: 'wpsc_agent_autocomplete_prev_assigned_agent',
271 _ajax_nonce: '<?php echo esc_attr( wp_create_nonce( 'wpsc_agent_autocomplete_prev_assigned_agent' ) ); ?>',
272 };
273 },
274 processResults: function (data, params) {
275 var terms = [];
276 if ( data ) {
277 jQuery.each( data, function( id, text ) {
278 terms.push( { id: text.id, text: text.title } );
279 });
280 }
281 return {
282 results: terms
283 };
284 },
285 cache: true
286 },
287 escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
288 minimumInputLength: 1
289 });
290 </script>
291 <?php
292 }
293
294 /**
295 * Check condition for this type
296 *
297 * @param array $condition - condition data.
298 * @param WPSC_Custom_Field $cf - custom field object.
299 * @param mixed $assigned_agents - value to compare.
300 * @return boolean
301 */
302 public static function is_valid( $condition, $cf, $assigned_agents ) {
303
304 $response = false;
305 switch ( $condition['operator'] ) {
306
307 case '=':
308 $response = in_array( $condition['operand_val_1'], $assigned_agents );
309 break;
310
311 case 'IN':
312 $flag = false;
313 foreach ( $condition['operand_val_1'] as $agent ) {
314 if ( in_array( $agent, $assigned_agents ) ) {
315 $flag = true;
316 break;
317 }
318 }
319 $response = $flag;
320 break;
321
322 case 'NOT IN':
323 $flag = true;
324 foreach ( $condition['operand_val_1'] as $agent ) {
325 if ( in_array( $agent, $assigned_agents ) ) {
326 $flag = false;
327 break;
328 }
329 }
330 $response = $flag;
331 break;
332 }
333 return $response;
334 }
335
336 /**
337 * Parse filter and return sql query to be merged in ticket model query builder
338 *
339 * @param WPSC_Custom_Field $cf - custom field of this type.
340 * @param mixed $compare - comparison operator.
341 * @param mixed $val - value to compare.
342 * @return string
343 */
344 public static function parse_filter( $cf, $compare, $val ) {
345
346 $str = '';
347
348 switch ( $compare ) {
349
350 case '=':
351 $str = 't.' . $cf->slug . ' RLIKE \'(^|[|])' . esc_sql( $val ) . '($|[|])\'';
352 break;
353
354 case 'IN':
355 foreach ( $val as $index => $value ) {
356 if ( $value == '' ) {
357 $val[ $index ] = '^$';
358 }
359 }
360 $str = 't.' . $cf->slug . ' RLIKE \'(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])\'';
361 break;
362
363 case 'NOT IN':
364 foreach ( $val as $index => $value ) {
365 if ( $value == '' ) {
366 $val[ $index ] = '^$';
367 }
368 }
369 $str = 't.' . $cf->slug . ' NOT RLIKE \'(^|[|])(' . implode( '|', esc_sql( $val ) ) . ')($|[|])\'';
370 break;
371
372 default:
373 $str = '1=1';
374 }
375
376 return $str;
377 }
378
379 /**
380 * Check ticket condition
381 *
382 * @param array $condition - array with condition data.
383 * @param WPSC_Custom_Field $cf - custom field object.
384 * @param WPSC_Ticket $ticket - ticket object.
385 * @return boolean
386 */
387 public static function is_valid_ticket_condition( $condition, $cf, $ticket ) {
388
389 $flag = true;
390 $agent_ids = array_filter(
391 array_map(
392 fn( $agent ) => $agent->id,
393 $ticket->{$cf->slug}
394 )
395 );
396
397 switch ( $condition['operator'] ) {
398
399 case '=':
400 if ( $condition['operand_val_1'] == 0 ) {
401 $flag = ! $agent_ids ? true : false;
402 } else {
403 $flag = in_array( $condition['operand_val_1'], $agent_ids ) ? true : false;
404 }
405 break;
406
407 case 'IN':
408 if ( ! $agent_ids ) {
409 $flag = in_array( '0', $condition['operand_val_1'] ) ? true : false;
410 } else {
411
412 $flag = false;
413 foreach ( $agent_ids as $id ) {
414 if ( in_array( $id, $condition['operand_val_1'] ) ) {
415 $flag = true;
416 break;
417 }
418 }
419 }
420 break;
421
422 case 'NOT IN':
423 if ( ! $agent_ids ) {
424 $flag = ! in_array( '0', $condition['operand_val_1'] ) ? true : false;
425 } else {
426
427 foreach ( $agent_ids as $id ) {
428 if ( in_array( $id, $condition['operand_val_1'] ) ) {
429 $flag = false;
430 break;
431 }
432 }
433 }
434 break;
435
436 default:
437 $flag = true;
438 }
439
440 return $flag;
441 }
442
443 /**
444 * Return val field for meta query of this type of custom field
445 *
446 * @param array $condition - condition data.
447 * @return mixed
448 */
449 public static function get_meta_value( $condition ) {
450
451 $operator = $condition['operator'];
452 switch ( $operator ) {
453
454 case '=':
455 case 'IN':
456 case 'NOT IN':
457 return $condition['operand_val_1'];
458 }
459 return false;
460 }
461
462 /**
463 * Print edit custom field properties
464 *
465 * @param WPSC_Custom_Fields $cf - custom field object.
466 * @param string $field_class - class name of field category.
467 * @return void
468 */
469 public static function get_edit_custom_field_properties( $cf, $field_class ) {
470
471 if ( in_array( 'tl_width', $field_class::$allowed_properties ) ) :
472 ?>
473 <div data-type="number" data-required="false" class="wpsc-input-group tl_width">
474 <div class="label-container">
475 <label for="">
476 <?php esc_attr_e( 'Ticket list width (pixels)', 'supportcandy' ); ?>
477 </label>
478 </div>
479 <input type="number" name="tl_width" value="<?php echo intval( $cf->tl_width ); ?>" autocomplete="off">
480 </div>
481 <?php
482 endif;
483 }
484
485 /**
486 * Set custom field properties. Can be used by add/edit custom field.
487 * Ignore phpcs nonce issue as we already checked where it is called from.
488 *
489 * @param WPSC_Custom_Field $cf - custom field object.
490 * @param string $field_class - class of field category.
491 * @return void
492 */
493 public static function set_cf_properties( $cf, $field_class ) {
494
495 // tl_width!
496 if ( in_array( 'tl_width', $field_class::$allowed_properties ) ) {
497 $tl_width = isset( $_POST['tl_width'] ) ? intval( $_POST['tl_width'] ) : 0; // phpcs:ignore
498 $cf->tl_width = $tl_width ? $tl_width : 100;
499 }
500
501 // save!
502 $cf->save();
503 }
504
505 /**
506 * Returns printable ticket value for custom field. Can be used in export tickets, replace macros etc.
507 *
508 * @param WPSC_Custom_Field $cf - custom field object.
509 * @param WPSC_Ticket $ticket - ticket object.
510 * @param string $module - module name.
511 * @return string
512 */
513 public static function get_ticket_field_val( $cf, $ticket, $module = '' ) {
514
515 $agents = $ticket->{$cf->slug};
516 $agent_names = array_filter(
517 array_map(
518 fn( $agent ) => $agent->id ? $agent->name : '',
519 $agents
520 )
521 );
522 $value = $agent_names ? implode( ', ', $agent_names ) : esc_attr__( 'None', 'supportcandy' );
523
524 return apply_filters( 'wpsc_ticket_field_val_prev_assignee', $value, $cf, $ticket, $module );
525 }
526
527 /**
528 * Print ticket value for given custom field on ticket list
529 *
530 * @param WPSC_Custom_Field $cf - custom field object.
531 * @param WPSC_Ticket $ticket - ticket object.
532 * @return void
533 */
534 public static function print_tl_ticket_field_val( $cf, $ticket ) {
535
536 echo esc_attr( self::get_ticket_field_val( $cf, $ticket ) );
537 }
538
539 /**
540 * Agent autocomplete for filter access
541 *
542 * @return void
543 */
544 public static function agent_autocomplete_prev_assigned_agent() {
545
546 if ( check_ajax_referer( 'wpsc_agent_autocomplete_prev_assigned_agent', '_ajax_nonce', false ) !== 1 ) {
547 wp_send_json_error( 'Unauthorised request!', 401 );
548 }
549
550 $current_user = WPSC_Current_User::$current_user;
551 if ( $current_user->is_agent ) {
552 $filter_items = get_option( 'wpsc-atl-filter-items', array() );
553 } elseif ( $current_user->is_customer && ! $current_user->is_agent ) {
554 $filter_items = get_option( 'wpsc-ctl-filter-items', array() );
555 }
556
557 if ( ! in_array( 'prev_assignee', $filter_items ) ) {
558 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
559 }
560
561 $filters = array(
562 'term' => isset( $_GET['q'] ) ? sanitize_text_field( wp_unslash( $_GET['q'] ) ) : '',
563 'filter_by' => 'all',
564 'sort_by' => 'name',
565 'isMultiple' => 0,
566 );
567
568 $filters['isAgentgroup'] = 0;
569 if ( class_exists( 'WPSC_Agentgroups' ) ) {
570 $filters['isAgentgroup'] = isset( $_GET['isAgentgroup'] ) ? intval( $_GET['isAgentgroup'] ) : null;
571 }
572
573 $response = WPSC_Agent::agent_autocomplete( $filters );
574 wp_send_json( $response );
575 }
576
577 /**
578 * Rest api filter for ticket data to prevent from sending it to client
579 *
580 * @param array $data - array of slugs to prevent from.
581 * @return array
582 */
583 public static function rest_prevent_ticket_data( $data ) {
584
585 $current_user = WPSC_Current_User::$current_user;
586 if ( ! $current_user->is_agent ) {
587 $list_items = $current_user->get_tl_list_items();
588 if ( ! in_array( 'prev_assignee', $list_items ) ) {
589 $data[] = 'prev_assignee';
590 }
591 }
592 return $data;
593 }
594 }
595 endif;
596
597 WPSC_DF_Prev_Assignee::init();
598