PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.4.4
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.4.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 / custom-field-types / class-wpsc-cf-single-select.php

class-wpsc-cf-single-select.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.4.4, at includes/custom-field-types/class-wpsc-cf-single-select.php

1,500 lines 47.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_CF_Single_Select' ) ) :
7
8 final class WPSC_CF_Single_Select {
9
10 /**
11 * Slug for this custom field type
12 *
13 * @var string
14 */
15 public static $slug = 'cf_single_select';
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 = false;
37
38 /**
39 * Data type for column created in tickets table
40 *
41 * @var string
42 */
43 public static $data_type = 'TINYTEXT 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_option';
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 = false;
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 = true;
72
73 /**
74 * Set whether this custom field type can accept personal info.
75 *
76 * @var boolean
77 */
78 public static $has_personal_info = true;
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 = true;
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 = true;
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 = true;
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 = true;
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 = true;
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 = true;
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 = true;
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 // Set custom field type.
168 add_filter( 'wpsc_cf_types', array( __CLASS__, 'add_cf_type' ), 2 );
169
170 // ticket form.
171 add_action( 'wpsc_js_validate_ticket_form', array( __CLASS__, 'js_validate_ticket_form' ) );
172 add_filter( 'wpsc_create_ticket_data', array( __CLASS__, 'set_create_ticket_data' ), 10, 3 );
173 add_action( 'wpsc_js_clear_value_hidden_fields', array( __CLASS__, 'js_clear_value_hidden_fields' ) );
174
175 // create ticket data for rest api.
176 add_filter( 'wpsc_rest_create_ticket', array( __CLASS__, 'set_rest_ticket_data' ), 10, 3 );
177
178 // Ticket model.
179 add_filter( 'wpsc_ticket_joins', array( __CLASS__, 'ticket_join' ), 9, 2 );
180 add_filter( 'wpsc_archive_ticket_joins', array( __CLASS__, 'ticket_join' ), 9, 2 );
181
182 // ticket search query.
183 add_filter( 'wpsc_ticket_search', array( __CLASS__, 'ticket_search' ), 10, 5 );
184 add_filter( 'wpsc_archive_ticket_search', array( __CLASS__, 'ticket_search' ), 10, 5 );
185 }
186
187 /**
188 * Load current class to reference classes
189 *
190 * @param array $classes - Associative array of class names indexed by its slug.
191 * @return array
192 */
193 public static function load_ref_class( $classes ) {
194
195 $classes[ self::$slug ] = array(
196 'class' => __CLASS__,
197 'save-key' => 'id',
198 );
199 return $classes;
200 }
201
202 /**
203 * Add custom field type to list
204 *
205 * @param array $cf_types - custom field types array.
206 * @return array
207 */
208 public static function add_cf_type( $cf_types ) {
209
210 $cf_types[ self::$slug ] = array(
211 'label' => esc_attr__( 'Dropdown (single-select)', 'supportcandy' ),
212 'class' => __CLASS__,
213 );
214 return $cf_types;
215 }
216
217 /**
218 * Print operators for ticket form filter
219 *
220 * @param WPSC_Custom_Field $cf - custom field object.
221 * @param array $filter - Existing filters (if any).
222 * @return void
223 */
224 public static function get_operators( $cf, $filter = array() ) {
225 ?>
226
227 <div class="item conditional">
228 <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' ) ); ?>');">
229 <option value=""><?php esc_attr_e( 'Compare As', 'supportcandy' ); ?></option>
230 <option <?php isset( $filter['operator'] ) && selected( $filter['operator'], '=' ); ?> value="="><?php esc_attr_e( 'Equals', 'supportcandy' ); ?></option>
231 <option <?php isset( $filter['operator'] ) && selected( $filter['operator'], 'IN' ); ?> value="IN"><?php esc_attr_e( 'Matches', 'supportcandy' ); ?></option>
232 <option <?php isset( $filter['operator'] ) && selected( $filter['operator'], 'NOT IN' ); ?> value="NOT IN"><?php esc_attr_e( 'Not Matches', 'supportcandy' ); ?></option>
233 </select>
234 </div>
235 <?php
236 }
237
238 /**
239 * Print operators for ticket form filter
240 *
241 * @param string $operator - condition operator on which operands should be returned.
242 * @param WPSC_Custom_Field $cf - custom field object.
243 * @param array $filter - Exising functions (if any).
244 * @return void
245 */
246 public static function get_operands( $operator, $cf, $filter = array() ) {
247
248 $is_multiple = $operator !== '=' ? true : false;
249 $options = $cf->get_options();
250 $unique_id = uniqid( 'wpsc_' );
251 ?>
252 <div class="item conditional operand single">
253 <select class="operand_val_1 <?php echo esc_attr( $unique_id ); ?>" <?php echo $is_multiple ? 'multiple' : ''; ?>>
254 <?php
255 foreach ( $options as $option ) {
256 $selected = '';
257 if ( isset( $filter['operand_val_1'] ) && ( ( $is_multiple && in_array( $option->id, $filter['operand_val_1'] ) ) || ( ! $is_multiple && $option->id == $filter['operand_val_1'] ) ) ) {
258 $selected = 'selected="selected"';
259 }
260 ?>
261 <option <?php echo esc_attr( $selected ); ?> value="<?php echo esc_attr( $option->id ); ?>"><?php echo esc_attr( $option->name ); ?></option>
262 <?php
263 }
264 ?>
265 </select>
266 </div>
267 <script>jQuery('.operand_val_1.<?php echo esc_attr( $unique_id ); ?>').selectWoo();</script>
268 <?php
269 }
270
271 /**
272 * Check condition for this type
273 *
274 * @param array $condition - condition data.
275 * @param WPSC_Custom_Field $cf - custom field object.
276 * @param mixed $option - value to compare.
277 * @return boolean
278 */
279 public static function is_valid( $condition, $cf, $option ) {
280
281 $response = false;
282 switch ( $condition['operator'] ) {
283
284 case '=':
285 $response = $condition['operand_val_1'] == $option ? true : false;
286 break;
287
288 case 'IN':
289 $response = in_array( $option, $condition['operand_val_1'] ) ? true : false;
290 break;
291
292 case 'NOT IN':
293 $response = ! in_array( $option, $condition['operand_val_1'] ) ? true : false;
294 break;
295 }
296 return $response;
297 }
298
299 /**
300 * Parse filter and return sql query to be merged in ticket model query builder
301 *
302 * @param WPSC_Custom_Field $cf - custom field of this type.
303 * @param mixed $compare - comparison operator.
304 * @param mixed $val - value to compare.
305 * @return string
306 */
307 public static function parse_filter( $cf, $compare, $val ) {
308
309 $str = '';
310
311 switch ( $compare ) {
312
313 case '=':
314 $str = self::get_sql_slug( $cf ) . '=\'' . esc_sql( $val ) . '\'';
315 break;
316
317 case 'IN':
318 $str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) IN(\'' . implode( '\', \'', esc_sql( $val ) ) . '\')';
319 break;
320
321 case 'NOT IN':
322 $str = 'CONVERT(' . self::get_sql_slug( $cf ) . ' USING utf8) NOT IN(\'' . implode( '\', \'', esc_sql( $val ) ) . '\')';
323 break;
324
325 default:
326 $str = '1=1';
327 }
328
329 return $str;
330 }
331
332 /**
333 * Return orderby string
334 *
335 * @param WPSC_Custom_Field $cf - custom field object.
336 * @return string
337 */
338 public static function get_orderby_string( $cf ) {
339
340 return 'op.name';
341 }
342
343 /**
344 * Check ticket condition
345 *
346 * @param array $condition - array with condition data.
347 * @param WPSC_Custom_Field $cf - custom field object.
348 * @param WPSC_Ticket $ticket - ticket object.
349 * @return boolean
350 */
351 public static function is_valid_ticket_condition( $condition, $cf, $ticket ) {
352
353 if ( ! is_object( $ticket->{$cf->slug} ) ) {
354 return false;
355 }
356
357 $flag = true;
358
359 switch ( $condition['operator'] ) {
360
361 case '=':
362 $flag = $ticket->{$cf->slug}->id == $condition['operand_val_1'] ? true : false;
363 break;
364
365 case 'IN':
366 $flag = in_array( $ticket->{$cf->slug}->id, $condition['operand_val_1'] );
367 break;
368
369 case 'NOT IN':
370 $flag = ! in_array( $ticket->{$cf->slug}->id, $condition['operand_val_1'] );
371 break;
372
373 default:
374 $flag = true;
375 }
376
377 return $flag;
378 }
379
380 /**
381 * Check customer condition
382 *
383 * @param array $condition - array with condition data.
384 * @param WPSC_Custom_Field $cf - custom field object.
385 * @param WPSC_Customer $customer - customer object.
386 * @return boolean
387 */
388 public static function is_valid_customer_condition( $condition, $cf, $customer ) {
389
390 if ( ! is_object( $customer->{$cf->slug} ) ) {
391 return false;
392 }
393
394 $flag = true;
395
396 switch ( $condition['operator'] ) {
397
398 case '=':
399 $flag = $customer->{$cf->slug}->id == $condition['operand_val_1'] ? true : false;
400 break;
401
402 case 'IN':
403 $flag = in_array( $customer->{$cf->slug}->id, $condition['operand_val_1'] );
404 break;
405
406 case 'NOT IN':
407 $flag = ! in_array( $customer->{$cf->slug}->id, $condition['operand_val_1'] );
408 break;
409
410 default:
411 $flag = true;
412 }
413
414 return $flag;
415 }
416
417 /**
418 * Print ticket form field
419 *
420 * @param WPSC_Custom_Field $cf - Custom field object.
421 * @param array $tff - Array of ticket form field settings for this field.
422 * @return string
423 */
424 public static function print_tff( $cf, $tff ) {
425
426 $options = $cf->get_options();
427 $val = '';
428 if ( $cf->field == 'ticket' ) {
429 $val = $cf->is_auto_fill && $cf->default_value ? stripslashes( htmlspecialchars( $cf->default_value[0] ) ) : '';
430 } else {
431 $current_user = WPSC_Current_User::$current_user;
432 $val = $current_user->is_customer && $current_user->customer->{$cf->slug} ? intval( $current_user->customer->{$cf->slug}->id ) : 0;
433 }
434 $unique_id = uniqid( 'wpsc_' );
435
436 ob_start();
437 ?>
438 <div class="<?php echo esc_attr( WPSC_Functions::get_tff_classes( $cf, $tff ) ); ?>" data-cft="<?php echo esc_attr( self::$slug ); ?>" data-slug="<?php echo esc_attr( $cf->slug ); ?>">
439 <div class="wpsc-tff-label">
440 <span class="name"><?php echo esc_attr( $cf->name ); ?></span>
441 <?php
442 if ( $tff['is-required'] ) {
443 ?>
444 <span class="required-indicator">*</span>
445 <?php
446 }
447 ?>
448 </div>
449 <span class="extra-info"><?php echo esc_attr( $cf->extra_info ); ?></span>
450 <select class="<?php echo esc_attr( $unique_id ); ?>" name="<?php echo esc_attr( $cf->slug ); ?>" onchange="wpsc_check_tff_visibility()">
451 <option value=""></option>
452 <?php
453 foreach ( $options as $option ) :
454 ?>
455 <option <?php selected( $option->id, $val ); ?> value="<?php echo esc_attr( $option->id ); ?>"><?php echo esc_attr( $option->name ); ?></option>
456 <?php
457 endforeach;
458 ?>
459 </select>
460 <script>
461 jQuery('select.<?php echo esc_attr( $unique_id ); ?>').selectWoo({
462 allowClear: true,
463 placeholder: "<?php echo esc_attr( $cf->placeholder_text ); ?>"
464 });
465 </script>
466 </div>
467 <?php
468 return ob_get_clean();
469 }
470
471 /**
472 * Validate this type field in create ticket
473 *
474 * @return void
475 */
476 public static function js_validate_ticket_form() {
477 ?>
478
479 case '<?php echo esc_attr( self::$slug ); ?>':
480 var val = customField.find('select').first().val();
481 if (customField.hasClass('required') && !val) {
482 isValid = false;
483 alert(supportcandy.translations.req_fields_missing);
484 }
485 break;
486 <?php
487 echo PHP_EOL;
488 }
489
490 /**
491 * Return custom field value in $_POST
492 * Ignore phpcs nonce issue as we already checked where it is called from.
493 *
494 * @param string $slug - Custom field slug.
495 * @param mixed $cf - Custom field object or false.
496 * @return mixed
497 */
498 public static function get_tff_value( $slug, $cf = false ) {
499
500 return isset( $_POST[ $slug ] ) ? intval( $_POST[ $slug ] ) : 0; // phpcs:ignore
501 }
502
503 /**
504 * Return default value for custom field of this type
505 *
506 * @param WPSC_Custom_Field $cf - custom field object.
507 * @return mixed
508 */
509 public static function get_default_value( $cf ) {
510
511 return $cf->default_value ? $cf->default_value[0] : '';
512 }
513
514 /**
515 * Check and return custom field value for new ticket to be created.
516 * This function is used by filter for set create ticket form and called directly by my-profile for each applicable custom fields.
517 * Ignore phpcs nonce issue as we already checked where it is called from.
518 *
519 * @param array $data - Array of values to to stored in ticket in an insert function.
520 * @param array $custom_fields - Array containing all applicable custom fields indexed by unique custom field types.
521 * @param boolean $is_my_profile - Whether it or not it is created from my-profile. This function is used by create ticket as well as my-profile. Due to customer fields handling is done same way, this flag gives apportunity to identify where it being called.
522 * @return array
523 */
524 public static function set_create_ticket_data( $data, $custom_fields, $is_my_profile ) {
525
526 if ( isset( $custom_fields[ self::$slug ] ) ) {
527 foreach ( $custom_fields[ self::$slug ] as $cf ) {
528 $value = self::get_tff_value( $cf->slug );
529 if ( $cf->field == 'ticket' ) {
530
531 $default_val = self::get_default_value( $cf );
532 $data[ $cf->slug ] = $value ? $value : $default_val;
533
534 } elseif ( $cf->field == 'agentonly' ) {
535
536 $data[ $cf->slug ] = self::get_default_value( $cf );
537
538 } elseif ( $cf->field == 'customer' && $data['customer'] != 0 ) {
539
540 $tff = get_option( 'wpsc-tff' );
541 if ( ! $is_my_profile && ! isset( $tff[ $cf->slug ] ) ) {
542 continue;
543 }
544 $customer = new WPSC_Customer( $data['customer'] );
545 $existing_val = $customer->{$cf->slug} ? $customer->{$cf->slug}->id : '';
546 $value = $value === 0 ? '' : $value;
547 if ( $existing_val != $value ) {
548 $customer->{$cf->slug} = $value;
549 $customer->save();
550
551 // Set log for this change.
552 WPSC_Log::insert(
553 array(
554 'type' => 'customer',
555 'ref_id' => $customer->id,
556 'modified_by' => WPSC_Current_User::$current_user->customer->id,
557 'body' => wp_json_encode(
558 array(
559 'slug' => $cf->slug,
560 'prev' => $existing_val,
561 'new' => $value,
562 )
563 ),
564 'date_created' => ( new DateTime() )->format( 'Y-m-d H:i:s' ),
565 )
566 );
567 }
568 }
569 }
570 }
571 return $data;
572 }
573
574 /**
575 * Set create ticket data for rest api request
576 *
577 * @param array $data - create ticket data array.
578 * @param WP_REST_Request $request - rest request object.
579 * @param array $custom_fields - custom field objects indexed by unique custom field types.
580 * @return array
581 */
582 public static function set_rest_ticket_data( $data, $request, $custom_fields ) {
583
584 $current_user = WPSC_Current_User::$current_user;
585 $tff = get_option( 'wpsc-tff' );
586
587 if ( isset( $custom_fields[ self::$slug ] ) ) {
588 foreach ( $custom_fields[ self::$slug ] as $cf ) {
589
590 if (
591 ! in_array( $cf->field, array( 'ticket', 'agentonly', 'customer' ) ) ||
592 ( $cf->field == 'customer' && ! isset( $tff[ $cf->slug ] ) )
593 ) {
594 continue;
595 }
596
597 $option = new WPSC_Option( intval( $request->get_param( $cf->slug ) ) );
598
599 if ( in_array( $cf->field, array( 'ticket', 'agentonly' ) ) ) {
600
601 $data[ $cf->slug ] = $cf->field == 'ticket' && $option->id ? $option->id : self::get_default_value( $cf );
602
603 } else {
604
605 $customer = new WPSC_Customer( $data['customer'] );
606 $existing_val = $customer->{$cf->slug};
607
608 if ( $option->id && $option->id != $existing_val->id ) {
609
610 $customer->{$cf->slug} = $option;
611 $customer->save();
612
613 // Set log for this change..
614 WPSC_Log::insert(
615 array(
616 'type' => 'customer',
617 'ref_id' => $customer->id,
618 'modified_by' => $current_user->customer->id,
619 'body' => wp_json_encode(
620 array(
621 'slug' => $cf->slug,
622 'prev' => $existing_val->id,
623 'new' => $option->id,
624 )
625 ),
626 'date_created' => ( new DateTime() )->format( 'Y-m-d H:i:s' ),
627 )
628 );
629 }
630 }
631 }
632 }
633
634 return $data;
635 }
636
637 /**
638 * Return slug string to be used in where condition of ticket model for this type of field
639 *
640 * @param WPSC_Custom_Field $cf - custom field object.
641 * @return string
642 */
643 public static function get_sql_slug( $cf ) {
644
645 $join_char = in_array( $cf->field, array( 'ticket', 'agentonly' ) ) ? 't.' : 'c.';
646 return $join_char . $cf->slug;
647 }
648
649 /**
650 * Return val field for meta query of this type of custom field
651 *
652 * @param array $condition - condition data.
653 * @return mixed
654 */
655 public static function get_meta_value( $condition ) {
656
657 $operator = $condition['operator'];
658 switch ( $operator ) {
659
660 case '=':
661 case 'IN':
662 case 'NOT IN':
663 return $condition['operand_val_1'];
664 }
665 return false;
666 }
667
668 /**
669 * Print generic input field for this type.
670 *
671 * @param WPSC_Custom_Field $cf - Custom field object.
672 * @param mixed $value - optional. Input field will be printed with given value if given.
673 * @return void
674 */
675 public static function print_cf_input( $cf, $value = '' ) {
676
677 if ( $value && ! is_object( $value ) ) {
678
679 $option = new WPSC_Option( $value );
680 if ( $option && $option->id ) {
681 $value = $option;
682 }
683 }
684
685 $options = $cf->get_options();
686 $unique_id = uniqid( 'wpsc_' );
687 ?>
688 <div class="wpsc-tff wpsc-sm-12 wpsc-md-12 wpsc-lg-12 wpsc-visible wpsc-xs-12" data-cft="<?php echo esc_attr( self::$slug ); ?>">
689 <div class="wpsc-tff-label">
690 <span class="name"><?php echo esc_attr( $cf->name ); ?></span>
691 </div>
692 <?php
693 $extra_info = stripslashes( $cf->extra_info );
694 if ( $extra_info ) :
695 ?>
696 <span class="extra-info"><?php echo esc_attr( $cf->extra_info ); ?></span>
697 <?php
698 endif
699 ?>
700 <select class="<?php echo esc_attr( $unique_id ); ?>" name="<?php echo esc_attr( $cf->slug ); ?>">
701 <option value=""></option>
702 <?php
703 foreach ( $options as $option ) {
704 ?>
705 <option <?php $value && selected( $option->id, $value->id ); ?> value="<?php echo esc_attr( $option->id ); ?>"><?php echo esc_attr( $option->name ); ?></option>
706 <?php
707 }
708 ?>
709 </select>
710 <script>
711 jQuery('select.<?php echo esc_attr( $unique_id ); ?>').selectWoo({
712 allowClear: true,
713 placeholder: ""
714 });
715 </script>
716 </div>
717 <?php
718 }
719
720 /**
721 * Get value for generic field from post.
722 * Ignore phpcs nonce issue as we already checked where it is called from.
723 *
724 * @param WPSC_Custom_Field $cf - custom field object.
725 * @return string
726 */
727 public static function get_cf_input_val( $cf ) {
728
729 return isset( $_POST[ $cf->slug ] ) ? intval( $_POST[ $cf->slug ] ) : ''; // phpcs:ignore
730 }
731
732 /**
733 * Print edit ticket custom field in individual ticket
734 *
735 * @param WPSC_Custom_Field $cf - custom field object.
736 * @param WPSC_Ticket $ticket - ticket object.
737 * @return void
738 */
739 public static function print_edit_ticket_cf( $cf, $ticket ) {
740
741 $options = $cf->get_options();
742 $unique_id = uniqid( 'wpsc_' );
743 ?>
744 <div class="wpsc-tff wpsc-sm-12 wpsc-md-12 wpsc-lg-12 wpsc-visible wpsc-xs-12" data-cft="<?php echo esc_attr( self::$slug ); ?>">
745 <div class="wpsc-tff-label">
746 <span class="name"><?php echo esc_attr( $cf->name ); ?></span>
747 </div>
748 <?php
749 $extra_info = stripslashes( $cf->extra_info );
750 if ( $extra_info ) {
751 ?>
752 <span class="extra-info"><?php echo esc_attr( $cf->extra_info ); ?></span>
753 <?php
754 }
755 ?>
756 <select class="<?php echo esc_attr( $unique_id ); ?>" name="<?php echo esc_attr( $cf->slug ); ?>">
757 <option value=""></option>
758 <?php
759 foreach ( $options as $option ) {
760 ?>
761 <option <?php $ticket->{$cf->slug} && selected( $option->id, $ticket->{$cf->slug}->id ); ?> value="<?php echo esc_attr( $option->id ); ?>"><?php echo esc_attr( $option->name ); ?></option>
762 <?php
763 }
764 ?>
765 </select>
766 <script>
767 jQuery('select.<?php echo esc_attr( $unique_id ); ?>').selectWoo({
768 allowClear: true,
769 placeholder: "<?php echo esc_attr( $cf->placeholder_text ); ?>"
770 });
771 </script>
772 </div>
773 <?php
774 }
775
776 /**
777 * Set edit individual ticket for this custom field type.
778 * Ignore phpcs nonce issue as we already checked where it is called from.
779 *
780 * @param WPSC_Custom_Field $cf - custom field object.
781 * @param WPSC_Ticket $ticket - ticket object.
782 * @return WPSC_Ticket
783 */
784 public static function set_edit_ticket_cf( $cf, $ticket ) {
785
786 $prev = $ticket->{$cf->slug} ? $ticket->{$cf->slug}->id : '';
787 $new = isset( $_POST[ $cf->slug ] ) ? intval( $_POST[ $cf->slug ] ) : ''; // phpcs:ignore
788 $new = $new === 0 ? '' : $new;
789
790 // Exit if there is no change.
791 if ( $prev == $new ) {
792 return $ticket;
793 }
794
795 // Change value.
796 $ticket->{$cf->slug} = $new;
797 $ticket->save();
798
799 return $ticket;
800 }
801
802 /**
803 * Modify ticket field value of this custom field type using rest api
804 *
805 * @param WPSC_Ticket $ticket - ticket object.
806 * @param WPSC_Custom_Field $cf - custom field.
807 * @param mixed $value - value to be set.
808 * @return void
809 */
810 public static function set_rest_edit_ticket_cf( $ticket, $cf, $value ) {
811
812 $id = WPSC_Functions::sanitize_option( intval( $value ), $cf, $cf->get_options() );
813 $prev = is_object( $ticket->{$cf->slug} ) ? $ticket->{$cf->slug}->id : 0;
814 if ( $prev != $id ) {
815 $ticket->{$cf->slug} = $id ? $id : '';
816 }
817 }
818
819 /**
820 * Insert log thread for this custom field type change
821 *
822 * @param WPSC_Custom_Field $cf - current custom field of this type.
823 * @param WPSC_Ticket $prev - ticket object before making any changes.
824 * @param WPSC_Ticket $new - ticket object after making changes.
825 * @param string $current_date - date string to be stored as create time.
826 * @param int $customer_id - current user customer id for blame.
827 * @return void
828 */
829 public static function insert_ticket_log( $cf, $prev, $new, $current_date, $customer_id ) {
830
831 // Exit if there is no change.
832 if ( $prev->{$cf->slug} == $new->{$cf->slug} ) {
833 return;
834 }
835
836 $prev_val = $prev->{$cf->slug} ? $prev->{$cf->slug}->id : '';
837 $new_val = $new->{$cf->slug} ? $new->{$cf->slug}->id : '';
838
839 $thread = WPSC_Thread::insert(
840 array(
841 'ticket' => $prev->id,
842 'customer' => $customer_id,
843 'type' => 'log',
844 'body' => wp_json_encode(
845 array(
846 'slug' => $cf->slug,
847 'prev' => $prev_val,
848 'new' => $new_val,
849 )
850 ),
851 'date_created' => $current_date,
852 'date_updated' => $current_date,
853 )
854 );
855 }
856
857 /**
858 * Return data for this custom field while creating duplicate ticket
859 *
860 * @param WPSC_Custom_Field $cf - custom field object.
861 * @param WPSC_Ticket $ticket - ticket object.
862 * @return mixed
863 */
864 public static function get_duplicate_ticket_data( $cf, $ticket ) {
865
866 return $ticket->{$cf->slug} ? $ticket->{$cf->slug}->id : '';
867 }
868
869 /**
870 * Print edit field for this type in edit customer info
871 *
872 * @param WPSC_Custom_field $cf - custom field object.
873 * @param WPSC_Customer $customer - customer object.
874 * @param array $tff - ticket form field data.
875 * @return string
876 */
877 public static function print_edit_customer_info( $cf, $customer, $tff ) {
878
879 $options = $cf->get_options();
880 $val = $customer->id && $customer->{$cf->slug} ? intval( $customer->{$cf->slug}->id ) : 0;
881 $unique_id = uniqid( 'wpsc_' );
882
883 ob_start();
884 ?>
885 <div class="<?php echo esc_attr( WPSC_Functions::get_tff_classes( $cf, $tff ) ); ?>" data-cft="<?php echo esc_attr( self::$slug ); ?>">
886 <div class="wpsc-tff-label">
887 <span class="name"><?php echo esc_attr( $cf->name ); ?></span>
888 </div>
889 <span class="extra-info"><?php echo esc_attr( $cf->extra_info ); ?></span>
890 <select class="<?php echo esc_attr( $unique_id ); ?>" name="<?php echo esc_attr( $cf->slug ); ?>">
891 <option value=""></option>
892 <?php
893 foreach ( $options as $option ) :
894 ?>
895 <option <?php selected( $option->id, $val ); ?> value="<?php echo esc_attr( $option->id ); ?>"><?php echo esc_attr( $option->name ); ?></option>
896 <?php
897 endforeach;
898 ?>
899 </select>
900 <script>
901 jQuery('select.<?php echo esc_attr( $unique_id ); ?>').selectWoo({
902 allowClear: false,
903 placeholder: "<?php echo esc_attr( $cf->placeholder_text ); ?>"
904 });
905 </script>
906 </div>
907 <?php
908 return ob_get_clean();
909 }
910
911 /**
912 * Print add new custom field setting properties
913 *
914 * @param string $field_class - Class name of the field.
915 * @return void
916 */
917 public static function get_add_new_custom_field_properties( $field_class ) {
918
919 if ( in_array( 'extra_info', $field_class::$allowed_properties ) ) :
920 ?>
921 <div data-type="textfield" data-required="false" class="wpsc-input-group extra-info">
922 <div class="label-container">
923 <label for=""><?php esc_attr_e( 'Extra info', 'supportcandy' ); ?></label>
924 </div>
925 <input name="extra_info" type="text" autocomplete="off" />
926 </div>
927 <?php
928 endif;
929 ?>
930
931 <div data-type="select-options" data-required="true" class="wpsc-input-group options">
932 <div class="label-container">
933 <label for="">
934 <?php esc_attr_e( 'Field options', 'supportcandy' ); ?>
935 <span class="required-char">*</span>
936 </label>
937 </div>
938 <div class="wpsc-options-container ui-sortable"></div>
939 <script>jQuery(".wpsc-options-container").sortable({ handle: '.wpsc-sort-handle' });</script>
940 <button class="wpsc-button small secondary" onclick="wpsc_get_add_new_option();">
941 <?php esc_attr_e( 'Add new', 'supportcandy' ); ?>
942 </button>
943 </div>
944 <?php
945
946 if ( in_array( 'default_value', $field_class::$allowed_properties ) ) :
947 ?>
948 <div data-type="single-select" data-required="false" class="wpsc-input-group default-val-option-single">
949 <div class="label-container">
950 <label for="">
951 <?php esc_attr_e( 'Default value', 'supportcandy' ); ?>
952 </label>
953 </div>
954 <select name="default-val-option-single[]" id="wpsc-default-val-option-single">
955 <option value=""></option>
956 </select>
957 </div>
958 <?php
959 endif;
960
961 if ( in_array( 'is_auto_fill', $field_class::$allowed_properties ) ) :
962 ?>
963 <div data-type="single-select" data-required="false" class="wpsc-input-group is_auto_fill">
964 <div class="label-container">
965 <label for="">
966 <?php esc_attr_e( 'Auto-fill in ticket form', 'supportcandy' ); ?>
967 </label>
968 </div>
969 <select name="is_auto_fill">
970 <option value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
971 <option value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
972 </select>
973 </div>
974 <?php
975 endif;
976
977 if ( in_array( 'placeholder_text', $field_class::$allowed_properties ) ) :
978 ?>
979 <div data-type="textfield" data-required="false" class="wpsc-input-group placeholder_text">
980 <div class="label-container">
981 <label for="">
982 <?php esc_attr_e( 'Placeholder', 'supportcandy' ); ?>
983 </label>
984 </div>
985 <input type="text" name="placeholder_text" autocomplete="off">
986 </div>
987 <?php
988 endif;
989
990 if ( in_array( 'tl_width', $field_class::$allowed_properties ) ) :
991 ?>
992 <div data-type="number" data-required="false" class="wpsc-input-group tl_width">
993 <div class="label-container">
994 <label for="">
995 <?php esc_attr_e( 'Ticket list width (pixels)', 'supportcandy' ); ?>
996 </label>
997 </div>
998 <input type="number" name="tl_width" autocomplete="off">
999 </div>
1000 <?php
1001 endif;
1002
1003 if ( in_array( 'is_personal_info', $field_class::$allowed_properties ) ) :
1004 ?>
1005 <div data-type="single-select" data-required="false" class="wpsc-input-group is_personal_info">
1006 <div class="label-container">
1007 <label for="">
1008 <?php esc_attr_e( 'Has personal info', 'supportcandy' ); ?>
1009 </label>
1010 </div>
1011 <select name="is_personal_info">
1012 <option value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
1013 <option value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
1014 </select>
1015 </div>
1016 <?php
1017 endif;
1018
1019 if ( in_array( 'allow_my_profile', $field_class::$allowed_properties ) ) :
1020 ?>
1021 <div data-type="single-select" data-required="false" class="wpsc-input-group allow_my_profile">
1022 <div class="label-container">
1023 <label for="">
1024 <?php esc_attr_e( 'Allow in my profile?', 'supportcandy' ); ?>
1025 </label>
1026 </div>
1027 <select name="allow_my_profile">
1028 <option value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
1029 <option value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
1030 </select>
1031 </div>
1032 <?php
1033 endif;
1034
1035 if ( in_array( 'allow_ticket_form', $field_class::$allowed_properties ) ) :
1036 ?>
1037 <div data-type="single-select" data-required="false" class="wpsc-input-group allow_ticket_form">
1038 <div class="label-container">
1039 <label for="">
1040 <?php esc_attr_e( 'Allow in ticket form?', 'supportcandy' ); ?>
1041 </label>
1042 </div>
1043 <select name="allow_ticket_form">
1044 <option value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
1045 <option value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
1046 </select>
1047 </div>
1048 <?php
1049 endif;
1050 }
1051
1052 /**
1053 * Print edit custom field properties
1054 *
1055 * @param WPSC_Custom_Fields $cf - custom field object.
1056 * @param string $field_class - class name of field category.
1057 * @return void
1058 */
1059 public static function get_edit_custom_field_properties( $cf, $field_class ) {
1060
1061 if ( in_array( 'extra_info', $field_class::$allowed_properties ) ) :
1062 ?>
1063 <div data-type="textfield" data-required="false" class="wpsc-input-group extra-info">
1064 <div class="label-container">
1065 <label for=""><?php esc_attr_e( 'Extra info', 'supportcandy' ); ?></label>
1066 </div>
1067 <input name="extra_info" type="text" value="<?php echo esc_attr( $cf->extra_info ); ?>" autocomplete="off" />
1068 </div>
1069 <?php
1070 endif;
1071 ?>
1072
1073 <div data-type="select-options" data-required="true" class="wpsc-input-group options">
1074 <div class="label-container">
1075 <label for="">
1076 <?php esc_attr_e( 'Field options', 'supportcandy' ); ?>
1077 <span class="required-char">*</span>
1078 </label>
1079 </div>
1080 <div class="wpsc-options-container ui-sortable">
1081 <?php
1082 $options = $cf->get_options();
1083 foreach ( $options as $option ) :
1084 ?>
1085 <div class="wpsc-option-item">
1086 <div class="content">
1087 <div class="wpsc-edit-option-container" style="display: none;">
1088 <input class="edit-option-text" type="text" value="" autocomplete="off" />
1089 <button onclick="wpsc_set_edit_option(this, '<?php echo esc_attr( wp_create_nonce( 'wpsc_set_edit_option' ) ); ?>');">
1090 <?php WPSC_Icons::get( 'check' ); ?>
1091 </button>
1092 <button class="cancel" onclick="wpsc_edit_option_cancel(this);">
1093 <?php WPSC_Icons::get( 'times' ); ?>
1094 </button>
1095 </div>
1096 <div class="wpsc-option-listing-container">
1097 <span class="sort wpsc-sort-handle"><?php WPSC_Icons::get( 'sort' ); ?></span>
1098 <div class="text"><?php echo esc_attr( $option->name ); ?></div>
1099 <span class="edit" onclick="wpsc_edit_option(this);"><?php WPSC_Icons::get( 'edit' ); ?></span>
1100 </div>
1101 </div>
1102 <div class="remove-container">
1103 <span onclick="wpsc_remove_option_item(this)"><?php WPSC_Icons::get( 'times-circle' ); ?></span>
1104 </div>
1105 <input type="hidden" class="option_id" name="options[]" value="<?php echo esc_attr( $option->id ); ?>">
1106 </div>
1107 <?php
1108 endforeach;
1109 ?>
1110 </div>
1111 <script>jQuery(".wpsc-options-container").sortable({ handle: '.wpsc-sort-handle' });</script>
1112 <button class="wpsc-button small secondary" onclick="wpsc_get_add_new_option();">
1113 <?php esc_attr_e( 'Add new', 'supportcandy' ); ?>
1114 </button>
1115 </div>
1116 <?php
1117
1118 if ( in_array( 'default_value', $field_class::$allowed_properties ) ) :
1119 $default_val = $cf->default_value ? $cf->default_value[0] : '';
1120 ?>
1121 <div data-type="single-select" data-required="false" class="wpsc-input-group default_value">
1122 <div class="label-container">
1123 <label for="">
1124 <?php esc_attr_e( 'Default value', 'supportcandy' ); ?>
1125 </label>
1126 </div>
1127 <select name="default-val-option-single[]" id="wpsc-default-val-option-single">
1128 <option value=""></option>
1129 <?php
1130 $options = $cf->get_options();
1131 foreach ( $options as $option ) :
1132 echo '<option ' . selected( $default_val, $option->id ) . ' value=' . esc_attr( $option->id ) . '>' . esc_attr( $option->name ) . '</option>';
1133 endforeach;
1134 ?>
1135 </select>
1136 </div>
1137 <?php
1138 endif;
1139
1140 if ( in_array( 'is_auto_fill', $field_class::$allowed_properties ) ) :
1141 ?>
1142 <div data-type="single-select" data-required="false" class="wpsc-input-group is_auto_fill">
1143 <div class="label-container">
1144 <label for="">
1145 <?php esc_attr_e( 'Auto-fill in ticket form', 'supportcandy' ); ?>
1146 </label>
1147 </div>
1148 <select name="is_auto_fill">
1149 <option <?php selected( $cf->is_auto_fill, '0' ); ?> value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
1150 <option <?php selected( $cf->is_auto_fill, '1' ); ?> value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
1151 </select>
1152 </div>
1153 <?php
1154 endif;
1155
1156 if ( in_array( 'placeholder_text', $field_class::$allowed_properties ) ) :
1157 ?>
1158 <div data-type="textfield" data-required="false" class="wpsc-input-group placeholder_text">
1159 <div class="label-container">
1160 <label for="">
1161 <?php esc_attr_e( 'Placeholder', 'supportcandy' ); ?>
1162 </label>
1163 </div>
1164 <input type="text" name="placeholder_text" value="<?php echo esc_attr( $cf->placeholder_text ); ?>" autocomplete="off">
1165 </div>
1166 <?php
1167 endif;
1168
1169 if ( in_array( 'tl_width', $field_class::$allowed_properties ) ) :
1170 ?>
1171 <div data-type="number" data-required="false" class="wpsc-input-group tl_width">
1172 <div class="label-container">
1173 <label for="">
1174 <?php esc_attr_e( 'Ticket list width (pixels)', 'supportcandy' ); ?>
1175 </label>
1176 </div>
1177 <input type="number" name="tl_width" value="<?php echo intval( $cf->tl_width ); ?>" autocomplete="off">
1178 </div>
1179 <?php
1180 endif;
1181
1182 if ( in_array( 'is_personal_info', $field_class::$allowed_properties ) ) :
1183 ?>
1184 <div data-type="single-select" data-required="false" class="wpsc-input-group is_personal_info">
1185 <div class="label-container">
1186 <label for="">
1187 <?php esc_attr_e( 'Has personal info', 'supportcandy' ); ?>
1188 </label>
1189 </div>
1190 <select name="is_personal_info">
1191 <option <?php selected( $cf->is_personal_info, '0' ); ?> value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
1192 <option <?php selected( $cf->is_personal_info, '1' ); ?> value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
1193 </select>
1194 </div>
1195 <?php
1196 endif;
1197
1198 if ( in_array( 'allow_my_profile', $field_class::$allowed_properties ) ) :
1199 ?>
1200 <div data-type="single-select" data-required="false" class="wpsc-input-group allow_my_profile">
1201 <div class="label-container">
1202 <label for="">
1203 <?php esc_attr_e( 'Allow in my profile?', 'supportcandy' ); ?>
1204 </label>
1205 </div>
1206 <select name="allow_my_profile">
1207 <option <?php selected( $cf->allow_my_profile, '0' ); ?> value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
1208 <option <?php selected( $cf->allow_my_profile, '1' ); ?> value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
1209 </select>
1210 </div>
1211 <?php
1212 endif;
1213
1214 if ( in_array( 'allow_ticket_form', $field_class::$allowed_properties ) ) :
1215 ?>
1216 <div data-type="single-select" data-required="false" class="wpsc-input-group allow_ticket_form">
1217 <div class="label-container">
1218 <label for="">
1219 <?php esc_attr_e( 'Allow in ticket form?', 'supportcandy' ); ?>
1220 </label>
1221 </div>
1222 <select name="allow_ticket_form">
1223 <option <?php selected( $cf->allow_ticket_form, '0' ); ?> value="0"><?php esc_attr_e( 'No', 'supportcandy' ); ?></option>
1224 <option <?php selected( $cf->allow_ticket_form, '1' ); ?> value="1"><?php esc_attr_e( 'Yes', 'supportcandy' ); ?></option>
1225 </select>
1226 </div>
1227 <?php
1228 endif;
1229 }
1230
1231 /**
1232 * Set custom field properties. Can be used by add/edit custom field.
1233 * Ignore phpcs nonce issue as we already checked where it is called from.
1234 *
1235 * @param WPSC_Custom_Field $cf - custom field object.
1236 * @param string $field_class - class of field category.
1237 * @return void
1238 */
1239 public static function set_cf_properties( $cf, $field_class ) {
1240
1241 // extra info.
1242 if ( in_array( 'extra_info', $field_class::$allowed_properties ) ) {
1243 $cf->extra_info = isset( $_POST['extra_info'] ) ? sanitize_text_field( wp_unslash( $_POST['extra_info'] ) ) : ''; // phpcs:ignore
1244 }
1245
1246 // options.
1247 $options = isset( $_POST['options'] ) ? array_filter( array_map( 'sanitize_text_field', wp_unslash($_POST['options']) ) ) : array(); // phpcs:ignore
1248 if ( ! $options ) {
1249 wp_send_json_error( new WP_Error( '001', 'Bad request!' ), 400 );
1250 }
1251
1252 // default value.
1253 if ( in_array( 'default_value', $field_class::$allowed_properties ) ) {
1254 $cf->default_value = isset( $_POST['default-val-option-single'] ) ? array_filter( array_map( 'intval', $_POST['default-val-option-single'] ) ) : array(); // phpcs:ignore
1255 }
1256
1257 // auto fill.
1258 if ( in_array( 'is_auto_fill', $field_class::$allowed_properties ) ) {
1259 $cf->is_auto_fill = isset( $_POST['is_auto_fill'] ) ? sanitize_text_field( wp_unslash( $_POST['is_auto_fill'] ) ) : ''; // phpcs:ignore
1260 }
1261
1262 // placeholder!
1263 if ( in_array( 'placeholder_text', $field_class::$allowed_properties ) ) {
1264 $cf->placeholder_text = isset( $_POST['placeholder_text'] ) ? sanitize_text_field( wp_unslash( $_POST['placeholder_text'] ) ) : ''; // phpcs:ignore
1265 }
1266
1267 // personal info.
1268 if ( in_array( 'is_personal_info', $field_class::$allowed_properties ) ) {
1269 $cf->is_personal_info = isset( $_POST['is_personal_info'] ) ? intval( $_POST['is_personal_info'] ) : 0; // phpcs:ignore
1270 }
1271
1272 // my-profile.
1273 if ( in_array( 'allow_my_profile', $field_class::$allowed_properties ) ) {
1274 $cf->allow_my_profile = isset( $_POST['allow_my_profile'] ) ? intval( $_POST['allow_my_profile'] ) : 0; // phpcs:ignore
1275 }
1276
1277 // ticket form.
1278 if ( in_array( 'allow_ticket_form', $field_class::$allowed_properties ) ) {
1279 $cf->allow_ticket_form = isset( $_POST['allow_ticket_form'] ) ? intval( $_POST['allow_ticket_form'] ) : 0; // phpcs:ignore
1280 }
1281
1282 // tl_width!
1283 if ( in_array( 'tl_width', $field_class::$allowed_properties ) ) {
1284 $tl_width = isset( $_POST['tl_width'] ) ? intval( $_POST['tl_width'] ) : 0; // phpcs:ignore
1285 $cf->tl_width = $tl_width ? $tl_width : 100;
1286 }
1287
1288 // save!
1289 $cf->save();
1290 $cf->set_options( $options, true );
1291 }
1292
1293 /**
1294 * Add SQL joins to ticket model for this field type
1295 *
1296 * @param array $joins - array of join string that can be imploded later.
1297 * @param array $filter - user filter.
1298 * @return array
1299 */
1300 public static function ticket_join( $joins, $filter ) {
1301
1302 global $wpdb;
1303
1304 $cf = WPSC_Custom_Field::get_cf_by_slug( $filter['orderby_slug'] );
1305
1306 if ( $cf && $cf->type::$slug == 'cf_single_select' ) {
1307 $join_str = self::get_sql_slug( $cf );
1308 $joins[] = 'LEFT JOIN ' . $wpdb->prefix . 'psmsc_options op ON ' . $join_str . ' = op.id';
1309 }
1310
1311 return $joins;
1312 }
1313
1314 /**
1315 * Add ticket search compatibility for fields of this custom field type.
1316 *
1317 * @param array $sql - Array of sql peices that can be joined later.
1318 * @param array $filter - User filter.
1319 * @param array $custom_fields - Custom fields array applicable for search.
1320 * @param string $search - search string.
1321 * @param array $allowed_search_fields - Allowed search fields.
1322 * @return array
1323 */
1324 public static function ticket_search( $sql, $filter, $custom_fields, $search, $allowed_search_fields ) {
1325
1326 if ( isset( $custom_fields[ self::$slug ] ) ) {
1327
1328 $search_items = false;
1329 foreach ( $custom_fields[ self::$slug ] as $cf ) {
1330 if ( in_array( $cf->slug, $allowed_search_fields ) ) {
1331 if ( ! $search_items ) {
1332 $search_items = WPSC_Option::get_tl_search_string( $search );
1333 if ( ! $search_items ) {
1334 break;
1335 }
1336 }
1337 $join_char = in_array( $cf->field, array( 'ticket', 'agentonly' ) ) ? 't.' : 'c.';
1338 $sql[] = $join_char . $cf->slug . ' IN(' . implode( ', ', $search_items ) . ')';
1339 }
1340 }
1341 }
1342
1343 return $sql;
1344 }
1345
1346 /**
1347 * Returns printable ticket value for custom field. Can be used in export tickets, replace macros etc.
1348 *
1349 * @param WPSC_Custom_Field $cf - custom field object.
1350 * @param WPSC_Ticket $ticket - ticket object.
1351 * @param string $module - module name.
1352 * @return string
1353 */
1354 public static function get_ticket_field_val( $cf, $ticket, $module = '' ) {
1355
1356 $option = $ticket->{$cf->slug};
1357 $value = is_object( $option ) && $option->id ? $option->name : '';
1358 return apply_filters( 'wpsc_ticket_field_val_single_select', $value, $cf, $ticket, $module );
1359 }
1360
1361 /**
1362 * Print ticket value for given custom field on ticket list
1363 *
1364 * @param WPSC_Custom_Field $cf - custom field object.
1365 * @param WPSC_Ticket $ticket - ticket object.
1366 * @return void
1367 */
1368 public static function print_tl_ticket_field_val( $cf, $ticket ) {
1369
1370 echo esc_attr( self::get_ticket_field_val( $cf, $ticket ) );
1371 }
1372
1373 /**
1374 * Print ticket value for given custom field on widget
1375 *
1376 * @param WPSC_Custom_Field $cf - custom field object.
1377 * @param WPSC_Ticket $ticket - ticket object.
1378 * @return void
1379 */
1380 public static function print_widget_ticket_field_val( $cf, $ticket ) {
1381
1382 echo esc_attr( self::get_ticket_field_val( $cf, $ticket ) );
1383 }
1384
1385 /**
1386 * Returns printable customer value for custom field. Can be used in export tickets, replace macros etc.
1387 *
1388 * @param WPSC_Custom_Field $cf - custom field object.
1389 * @param WPSC_Customer $customer - customer object.
1390 * @return string
1391 */
1392 public static function get_customer_field_val( $cf, $customer ) {
1393
1394 $option = $customer->{$cf->slug};
1395 return is_object( $option ) && $option->id ? $option->name : '';
1396 }
1397
1398 /**
1399 * Print customer value for given custom field on ticket list
1400 *
1401 * @param WPSC_Custom_Field $cf - custom field object.
1402 * @param WPSC_Customer $customer - customer object.
1403 * @return void
1404 */
1405 public static function print_tl_customer_field_val( $cf, $customer ) {
1406
1407 echo esc_attr( self::get_customer_field_val( $cf, $customer ) );
1408 }
1409
1410 /**
1411 * Print customer value for given custom field on widget
1412 *
1413 * @param WPSC_Custom_Field $cf - custom field object.
1414 * @param WPSC_Customer $customer - customer object.
1415 * @return void
1416 */
1417 public static function print_widget_customer_field_val( $cf, $customer ) {
1418
1419 echo esc_attr( self::get_customer_field_val( $cf, $customer ) );
1420 }
1421
1422 /**
1423 * Print given value for custom field
1424 *
1425 * @param WPSC_Custom_Field $cf - custom field object.
1426 * @param mixed $val - value to convert and print.
1427 * @return void
1428 */
1429 public static function print_val( $cf, $val ) {
1430
1431 $option = is_object( $val ) ? $val : new WPSC_Option( $val );
1432 echo $option->id ? esc_attr( $option->name ) : esc_attr__( 'None', 'supportcandy' );
1433 }
1434
1435 /**
1436 * Return printable value for history log macro
1437 *
1438 * @param WPSC_Custom_Field $cf - custom field object.
1439 * @param mixed $val - value to convert and return.
1440 * @return string
1441 */
1442 public static function get_history_log_val( $cf, $val ) {
1443
1444 ob_start();
1445 self::print_val( $cf, $val );
1446 return ob_get_clean();
1447 }
1448
1449 /**
1450 * Print dashboard activity function
1451 *
1452 * @param WPSC_Custom_Field $cf - custom field object.
1453 * @param array $recent_logs - recent_logs object.
1454 * @param array $body - body object.
1455 * @param int $view - check if frontend.
1456 * @return string
1457 */
1458 public static function print_activity( $cf, $recent_logs, $body, $view ) {
1459
1460 $url = WPSC_Functions::get_ticket_url( $recent_logs->ticket->id, $view );
1461 if ( $body->new ) {
1462 $ss_value = new WPSC_Option( $body->new );
1463 $value = $ss_value->name;
1464 } else {
1465 $value = 'None';
1466 }
1467 return esc_attr( $recent_logs->customer->name ) . ' updated the' . esc_attr( $cf->name ) . ' value of <a href="' . esc_attr( $url ) . '" target="_blank">#' . esc_attr( $recent_logs->ticket->id ) . '</a> to ' . esc_attr( $value );
1468 }
1469
1470 /**
1471 * Print given value for custom field
1472 *
1473 * @param WPSC_Custom_Field $cf - custom field object.
1474 * @param mixed $val - value to convert and print.
1475 * @return string
1476 */
1477 public static function get_field_value( $cf, $val ) {
1478
1479 $option = is_object( $val ) ? $val : new WPSC_Option( $val );
1480 return $option->id ? esc_attr( $option->name ) : esc_attr__( 'None', 'supportcandy' );
1481 }
1482
1483 /**
1484 * Clear value of hidden fields
1485 *
1486 * @return void
1487 */
1488 public static function js_clear_value_hidden_fields() {
1489 ?>
1490 case '<?php echo esc_attr( self::$slug ); ?>':
1491 customField.find('select').first().val('');
1492 break;
1493 <?php
1494 echo PHP_EOL;
1495 }
1496 }
1497 endif;
1498
1499 WPSC_CF_Single_Select::init();
1500