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

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

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