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

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

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