PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.5.2
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.5.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.5.2, at includes/custom-field-types/class-wpsc-cf-email.php

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