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

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

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