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

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