PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.5.4
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.5.4
3.5.4 3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / includes / custom-field-types / class-wpsc-cf-number.php

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

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