PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.4.1
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.4.1
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-number.php

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

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