PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.3.7
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.3.7
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 / admin / custom-fields / class-wpsc-cf-settings.php

class-wpsc-cf-settings.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.3.7, at includes/admin/custom-fields/class-wpsc-cf-settings.php

993 lines 30.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_CF_Settings' ) ) :
7
8 final class WPSC_CF_Settings {
9
10 /**
11 * Set if current screen is settings page
12 *
13 * @var boolean
14 */
15 public static $is_current_page;
16
17 /**
18 * Sections for this view
19 *
20 * @var array
21 */
22 private static $sections = array();
23
24 /**
25 * Current section to load
26 *
27 * @var string
28 */
29 public static $current_section;
30
31 /**
32 * Custom field category (e.g. ticket, agentonly, customer, etc.)
33 *
34 * @var array
35 */
36 public static $fields = array();
37
38 /**
39 * Allowed modules for custom field categories
40 *
41 * @var array
42 */
43 public static $allowed_modules = array();
44
45 /**
46 * Initialize this class
47 */
48 public static function init() {
49
50 // Load sections for this screen.
51 add_action( 'admin_init', array( __CLASS__, 'load_sections' ), 1 );
52
53 // Humbargar modal.
54 add_action( 'admin_footer', array( __CLASS__, 'humbargar_menu' ) );
55
56 // Footer scripts.
57 add_action( 'admin_footer', array( __CLASS__, 'footer_scripts' ) );
58
59 // Add current section to admin localization data.
60 add_filter( 'wpsc_admin_localizations', array( __CLASS__, 'localizations' ) );
61
62 // Register ready function.
63 add_action( 'wpsc_js_ready', array( __CLASS__, 'register_js_ready_function' ) );
64
65 // Register fields.
66 add_action( 'init', array( __CLASS__, 'register_fields' ), 10 );
67
68 // Register allowed modules.
69 add_action( 'init', array( __CLASS__, 'register_allowed_modules' ), 11 );
70
71 // Add new custom field.
72 add_action( 'wp_ajax_wpsc_get_add_new_custom_field', array( __CLASS__, 'get_add_new_custom_field' ) );
73 add_action( 'wp_ajax_wpsc_get_add_new_custom_field_properties', array( __CLASS__, 'get_add_new_custom_field_properties' ) );
74 add_action( 'wp_ajax_wpsc_set_add_new_custom_field', array( __CLASS__, 'set_add_new_custom_field' ) );
75
76 // Edit custom field.
77 add_action( 'wp_ajax_wpsc_get_edit_custom_field', array( __CLASS__, 'get_edit_custom_field' ) );
78 add_action( 'wp_ajax_wpsc_set_edit_custom_field', array( __CLASS__, 'set_edit_custom_field' ) );
79
80 // Delete.
81 add_action( 'wp_ajax_wpsc_delete_custom_field', array( __CLASS__, 'delete_custom_field' ) );
82 }
83
84 /**
85 * Load section (nav elements) for this screen
86 *
87 * @return void
88 */
89 public static function load_sections() {
90
91 self::$is_current_page = isset( $_REQUEST['page'] ) && wp_unslash( $_REQUEST['page'] ) === 'wpsc-ticket-form' ? true : false; //phpcs:ignore
92
93 if ( ! self::$is_current_page ) {
94 return;
95 }
96
97 self::$sections = apply_filters(
98 'wpsc_ticket_form_page_sections',
99 array(
100 'ticket-form-fields' => array(
101 'slug' => 'ticket_form_fields',
102 'icon' => 'contact-form',
103 'label' => esc_attr__( 'Ticket Form Fields', 'supportcandy' ),
104 'callback' => 'wpsc_get_tff',
105 ),
106 'ticket-fields' => array(
107 'slug' => 'ticket_fields',
108 'icon' => 'ticket-alt',
109 'label' => esc_attr__( 'Ticket Fields', 'supportcandy' ),
110 'callback' => 'wpsc_get_ticket_fields',
111 ),
112 'customer-fields' => array(
113 'slug' => 'customer_fields',
114 'icon' => 'user-tie',
115 'label' => esc_attr__( 'Customer Fields', 'supportcandy' ),
116 'callback' => 'wpsc_get_customer_fields',
117 ),
118 'agent-only-fields' => array(
119 'slug' => 'agent_only_fields',
120 'icon' => 'headset',
121 'label' => esc_attr__( 'Agent Only Fields', 'supportcandy' ),
122 'callback' => 'wpsc_get_agent_only_fields',
123 ),
124 )
125 );
126
127 self::$current_section = isset( $_REQUEST['section'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ) : 'ticket-form-fields'; //phpcs:ignore
128 }
129
130 /**
131 * Add localizations to local JS
132 *
133 * @param array $localizations - localizations.
134 * @return array
135 */
136 public static function localizations( $localizations ) {
137
138 if ( ! self::$is_current_page ) {
139 return $localizations;
140 }
141
142 // Humbargar Titles.
143 $localizations['humbargar_titles'] = self::get_humbargar_titles();
144
145 // Current section.
146 $localizations['current_section'] = self::$current_section;
147
148 return $localizations;
149 }
150
151 /**
152 * UI foundation for this screen
153 *
154 * @return void
155 */
156 public static function layout() {
157 ?>
158
159 <div class="wrap">
160 <hr class="wp-header-end">
161 <div id="wpsc-container" style="display:none;">
162 <div class="wpsc-header wpsc-setting-header-xs wpsc-visible-xs">
163 <div class="wpsc-humbargar-title">
164 <?php WPSC_Icons::get( self::$sections[ self::$current_section ]['icon'] ); ?>
165 <label><?php echo esc_attr( self::$sections[ self::$current_section ]['label'] ); ?></label>
166 </div>
167 <div class="wpsc-humbargar" onclick="wpsc_toggle_humbargar();">
168 <?php WPSC_Icons::get( 'bars' ); ?>
169 </div>
170 </div>
171 <div class="wpsc-settings-page">
172 <div class="wpsc-setting-section-container wpsc-hidden-xs">
173 <h2><?php esc_attr_e( 'Custom Fields', 'supportcandy' ); ?></h2>
174 <?php
175 foreach ( self::$sections as $key => $section ) {
176
177 $active = self::$current_section === $key ? 'active' : '';
178 ?>
179 <div
180 class="wpsc-setting-nav <?php echo esc_attr( $key ) . ' ' . esc_attr( $active ); ?>"
181 onclick="<?php echo esc_attr( $section['callback'] ) . '();'; ?>">
182 <?php WPSC_Icons::get( $section['icon'] ); ?>
183 <label><?php echo esc_attr( $section['label'] ); ?></label>
184 </div>
185 <?php
186 }
187 ?>
188 </div>
189 <div class="wpsc-setting-body"></div>
190 </div>
191 </div>
192 </div>
193 <?php
194
195 self::print_snippets();
196 }
197
198 /**
199 * Print humbargar menu in footer
200 *
201 * @return void
202 */
203 public static function humbargar_menu() {
204
205 if ( ! self::$is_current_page ) {
206 return;
207 }
208 ?>
209
210 <div class="wpsc-humbargar-overlay" onclick="wpsc_toggle_humbargar();" style="display:none"></div>
211 <div class="wpsc-humbargar-menu" style="display:none">
212 <div class="box-inner">
213 <div class="wpsc-humbargar-close" onclick="wpsc_toggle_humbargar();">
214 <?php WPSC_Icons::get( 'times' ); ?>
215 </div>
216 <?php
217 foreach ( self::$sections as $key => $section ) :
218
219 $active = self::$current_section === $key ? 'active' : '';
220 ?>
221 <div
222 class="wpsc-humbargar-menu-item <?php echo esc_attr( $key ) . ' ' . esc_attr( $active ); ?>"
223 onclick="<?php echo esc_attr( $section['callback'] ) . '(true);'; ?>">
224 <?php WPSC_Icons::get( $section['icon'] ); ?>
225 <label><?php echo esc_attr( $section['label'] ); ?></label>
226 </div>
227 <?php
228 endforeach;
229 ?>
230 </div>
231 </div>
232 <?php
233 }
234
235 /**
236 * Humbargar mobile titles to be used in localizations
237 *
238 * @return array
239 */
240 private static function get_humbargar_titles() {
241
242 $titles = array();
243 foreach ( self::$sections as $section ) {
244
245 ob_start();
246 WPSC_Icons::get( $section['icon'] );
247 echo '<label>' . esc_attr( $section['label'] ) . '</label>';
248 $titles[ $section['slug'] ] = ob_get_clean();
249 }
250 return $titles;
251 }
252
253 /**
254 * Register JS functions to call on document ready
255 *
256 * @return void
257 */
258 public static function register_js_ready_function() {
259
260 if ( ! self::$is_current_page ) {
261 return;
262 }
263 echo esc_attr( self::$sections[ self::$current_section ]['callback'] ) . '();' . PHP_EOL;
264 }
265
266 /**
267 * Register fields (ticket, agentonly, customer, etc.)
268 *
269 * @return void
270 */
271 public static function register_fields() {
272
273 self::$fields = apply_filters( 'wpsc_custom_field_categories', array() );
274 }
275
276 /**
277 * Register allowed modules
278 *
279 * @return void
280 */
281 public static function register_allowed_modules() {
282
283 self::$allowed_modules = apply_filters(
284 'wpsc_cf_allowed_modules',
285 array(
286
287 'ticket-form' => array( 'ticket', 'customer' ),
288 'ticket-list' => array( 'ticket', 'customer', 'agentonly' ),
289 'ticket-filter' => array( 'ticket', 'customer', 'agentonly' ),
290 'ticket-macro' => array( 'ticket', 'customer', 'agentonly' ),
291 )
292 );
293 }
294
295 /**
296 * Add new custom field form
297 *
298 * String $field - custom field (ticket, agentonly, customer, etc.).
299 *
300 * @return void
301 */
302 public static function get_add_new_custom_field() {
303
304 if ( check_ajax_referer( 'wpsc_get_add_new_custom_field', '_ajax_nonce', false ) !== 1 ) {
305 wp_send_json_error( 'Unauthorised request!', 401 );
306 }
307
308 if ( ! WPSC_Functions::is_site_admin() ) {
309 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
310 }
311
312 $field = isset( $_POST['field'] ) ? sanitize_text_field( wp_unslash( $_POST['field'] ) ) : '';
313 if ( ! $field ) {
314 wp_send_json_error( 'Incorrect request!', 400 );
315 }
316 ?>
317
318 <form action="#" onsubmit="return false;" class="frm-add-new-custom-field">
319
320 <div data-type="textfield" data-required="true" class="wpsc-input-group label">
321 <div class="label-container">
322 <label for="">
323 <?php esc_attr_e( 'Label', 'supportcandy' ); ?>
324 <span class="required-char">*</span>
325 </label>
326 </div>
327 <input name="label" type="text" autocomplete="off"/>
328 </div>
329
330 <div data-type="" data-required="true" class="wpsc-input-group load-after">
331 <div class="label-container">
332 <label for="">
333 <?php esc_attr_e( 'Load after', 'supportcandy' ); ?>
334 </label>
335 </div>
336 <select name="load-after" class="load-after">
337 <option value="__TOP__">-- <?php esc_attr_e( 'TOP', 'supportcandy' ); ?> --</option>
338 <?php
339 foreach ( WPSC_Custom_Field::$custom_fields as $cf ) {
340 if ( $cf->field != $field ) {
341 continue;
342 }
343 ?>
344 <option value="<?php echo esc_attr( $cf->slug ); ?>"><?php echo esc_attr( $cf->name ); ?></option>
345 <?php
346 }
347 ?>
348 <option selected value="__END__">-- <?php esc_attr_e( 'END', 'supportcandy' ); ?> --</option>
349 </select>
350 <script>jQuery('select.load-after').selectWoo();</script>
351 </div>
352
353 <div data-type="single-select" data-required="true" class="wpsc-input-group field-type">
354 <div class="label-container">
355 <label for="">
356 <?php esc_attr_e( 'Select field type', 'supportcandy' ); ?>
357 <span class="required-char">*</span>
358 </label>
359 </div>
360 <select id="wpsc-select-ticket-field" name="type">
361 <option value=""></option>
362 <?php
363 $cf_types = apply_filters( 'wpsc_add_new_custom_field_cf_types', WPSC_Custom_Field::$cf_types, $field );
364 foreach ( $cf_types as $slug => $type ) :
365 ?>
366 <option value="<?php echo esc_attr( $slug ); ?>"><?php echo esc_attr( $type['label'] ); ?></option>
367 <?php
368 endforeach;
369 ?>
370 </select>
371 <script>
372 jQuery('#wpsc-select-ticket-field').selectWoo({ allowClear: true, placeholder: "" });
373 jQuery('#wpsc-select-ticket-field').change(function(){
374 // validate custom field type.
375 jQuery('div.cft-properties').remove();
376 var curEl = jQuery(this);
377 var cft = curEl.val();
378 if (!cft) return;
379 // get custome field properties.
380 jQuery(this).prop('disabled', true);
381 var form = jQuery('.frm-add-new-custom-field');
382 form.append(supportcandy.loader_html);
383 var dataform = new FormData(form[0]);
384 var data = {
385 action: 'wpsc_get_add_new_custom_field_properties',
386 field: dataform.get('field'),
387 cft,
388 _ajax_nonce: '<?php echo esc_attr( wp_create_nonce( 'wpsc_get_add_new_custom_field_properties' ) ); ?>'
389 };
390 jQuery.post(supportcandy.ajax_url, data, function (response) {
391 form.children().last().remove();
392 form.append(response);
393 curEl.prop('disabled', false);
394 });
395 });
396 </script>
397 </div>
398
399 <input type="hidden" name="field" value="<?php echo esc_attr( $field ); ?>">
400 <input type="hidden" name="action" value="wpsc_set_add_new_custom_field">
401 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_add_new_custom_field' ) ); ?>">
402
403 </form>
404
405 <div class="setting-footer-actions">
406 <button
407 class="wpsc-button normal primary margin-right"
408 onclick="wpsc_set_add_new_custom_field(this);">
409 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?></button>
410 <button
411 class="wpsc-button normal secondary"
412 onclick="jQuery('.wpsc-setting-nav.active').trigger('click');">
413 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?></button>
414 </div>
415 <?php
416
417 wp_die();
418 }
419
420 /**
421 * Add new custom field properties like extra-info, char-limit, etc.
422 *
423 * @return void
424 */
425 public static function get_add_new_custom_field_properties() {
426
427 if ( check_ajax_referer( 'wpsc_get_add_new_custom_field_properties', '_ajax_nonce', false ) != 1 ) {
428 wp_send_json_error( 'Unauthorised request!', 401 );
429 }
430
431 if ( ! WPSC_Functions::is_site_admin() ) {
432 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
433 }
434
435 $field = isset( $_POST['field'] ) ? sanitize_text_field( wp_unslash( $_POST['field'] ) ) : '';
436 if ( ! $field ) {
437 wp_send_json_error( 'Incorrect request!', 400 );
438 }
439
440 $cft = isset( $_POST['cft'] ) ? sanitize_text_field( wp_unslash( $_POST['cft'] ) ) : '';
441 if ( ! $cft ) {
442 wp_send_json_error( 'Incorrect request!', 400 );
443 }
444
445 ?>
446 <div class="cft-properties">
447 <?php
448 WPSC_Custom_Field::$cf_types[ $cft ]['class']::get_add_new_custom_field_properties( self::$fields[ $field ] );
449 ?>
450 </div>
451 <?php
452
453 wp_die();
454 }
455
456 /**
457 * Set add new custom field
458 *
459 * @return void
460 */
461 public static function set_add_new_custom_field() {
462
463 if ( check_ajax_referer( 'wpsc_set_add_new_custom_field', '_ajax_nonce', false ) != 1 ) {
464 wp_send_json_error( 'Unauthorised request!', 401 );
465 }
466
467 if ( ! WPSC_Functions::is_site_admin() ) {
468 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
469 }
470
471 $field = isset( $_POST['field'] ) ? sanitize_text_field( wp_unslash( $_POST['field'] ) ) : '';
472 if ( ! $field || ! in_array( $field, array_keys( self::$fields ) ) ) {
473 wp_send_json_error( 'Incorrect request!', 400 );
474 }
475
476 $cf = new WPSC_Custom_Field();
477 $cf->field = $field;
478
479 $cf->name = isset( $_POST['label'] ) ? sanitize_text_field( wp_unslash( $_POST['label'] ) ) : '';
480 if ( ! $cf->name ) {
481 wp_send_json_error( 'Incorrect request!', 400 );
482 }
483
484 $cf->type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
485 if ( ! $cf->type ) {
486 wp_send_json_error( 'Incorrect request!', 400 );
487 }
488
489 $cf->type::set_cf_properties( $cf, self::$fields[ $field ] );
490
491 // set load after.
492 $load_after = isset( $_POST['load-after'] ) ? sanitize_text_field( wp_unslash( $_POST['load-after'] ) ) : '__END__';
493 if ( $load_after != '__END__' ) {
494
495 $count = 1;
496
497 if ( $load_after == '__TOP__' ) {
498 $cf->load_order = $count++;
499 $cf->save();
500 }
501
502 foreach ( WPSC_Custom_Field::$custom_fields as $cff ) {
503
504 if ( $cff->field != $cf->field || $cff->slug == $cf->slug ) {
505 continue;
506 }
507
508 $cff->load_order = $count++;
509 $cff->save();
510
511 if ( $cff->slug == $load_after ) {
512 $cf->load_order = $count++;
513 $cf->save();
514 }
515 }
516 }
517
518 wp_die();
519 }
520
521 /**
522 * Get edit custom field screen
523 *
524 * @return void
525 */
526 public static function get_edit_custom_field() {
527
528 global $wpdb;
529
530 if ( check_ajax_referer( 'wpsc_get_edit_custom_field', '_ajax_nonce', false ) != 1 ) {
531 wp_send_json_error( 'Unauthorised request!', 401 );
532 }
533
534 if ( ! WPSC_Functions::is_site_admin() ) {
535 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
536 }
537
538 $id = isset( $_POST['cf_id'] ) ? intval( $_POST['cf_id'] ) : 0;
539 if ( ! $id ) {
540 wp_send_json_error( 'Incorrect request!', 400 );
541 }
542
543 $cf = new WPSC_Custom_Field( $id );
544 if ( ! $cf->id ) {
545 wp_send_json_error( 'Incorrect request!', 400 );
546 }
547 ?>
548
549 <form action="#" onsubmit="return false;" class="frm-edit-custom-field">
550
551 <div data-type="textfield" data-required="true" class="wpsc-input-group label">
552 <div class="label-container">
553 <label for="">
554 <?php esc_attr_e( 'Label', 'supportcandy' ); ?>
555 <span class="required-char">*</span>
556 </label>
557 </div>
558 <input name="label" type="text" value="<?php echo esc_attr( $cf->name ); ?>" autocomplete="off"/>
559 </div>
560
561 <div data-type="" data-required="true" class="wpsc-input-group load-after">
562 <div class="label-container">
563 <label for="">
564 <?php esc_attr_e( 'Load after', 'supportcandy' ); ?>
565 </label>
566 </div>
567 <select name="load-after" class="load-after">
568 <option value="__TOP__">-- <?php esc_attr_e( 'TOP', 'supportcandy' ); ?> --</option>
569 <?php
570 $load_after = $wpdb->get_var( "SELECT slug FROM {$wpdb->prefix}psmsc_custom_fields WHERE field='{$cf->field}' AND load_order < {$cf->load_order} ORDER BY load_order DESC LIMIT 1" );
571 foreach ( WPSC_Custom_Field::$custom_fields as $cff ) {
572 if ( $cff->field != $cf->field || $cff == $cf ) {
573 continue;
574 }
575 ?>
576 <option <?php selected( $load_after, $cff->slug ); ?> value="<?php echo esc_attr( $cff->slug ); ?>"><?php echo esc_attr( $cff->name ); ?></option>
577 <?php
578 }
579 ?>
580 <option value="__END__">-- <?php esc_attr_e( 'END', 'supportcandy' ); ?> --</option>
581 </select>
582 <script>jQuery('select.load-after').selectWoo();</script>
583 </div>
584 <?php
585
586 if ( ! $cf->type::$is_default ) :
587 ?>
588 <div data-type="textfield" data-required="true" class="wpsc-input-group label">
589 <div class="label-container">
590 <label for="">
591 <?php esc_attr_e( 'Field Type', 'supportcandy' ); ?>
592 <span class="required-char">*</span>
593 </label>
594 </div>
595 <input disabled type="text" value="<?php echo esc_attr( WPSC_Custom_Field::$cf_types[ $cf->type::$slug ]['label'] ); ?>" autocomplete="off"/>
596 </div>
597 <?php
598 endif
599 ?>
600
601 <?php $cf->type::get_edit_custom_field_properties( $cf, self::$fields[ $cf->field ] ); ?>
602
603 <input type="hidden" name="action" value="wpsc_set_edit_custom_field">
604 <input type="hidden" name="cf_id" value="<?php echo esc_attr( $cf->id ); ?>">
605 <input type="hidden" name="type" value="<?php echo esc_attr( $cf->type::$slug ); ?>">
606 <input type="hidden" name="field" value="<?php echo esc_attr( $cf->field ); ?>">
607 <input type="hidden" name="_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpsc_set_edit_custom_field' ) ); ?>">
608
609 </form>
610
611 <div class="setting-footer-actions">
612 <button
613 class="wpsc-button normal primary margin-right"
614 onclick="wpsc_set_edit_custom_field(this);">
615 <?php esc_attr_e( 'Submit', 'supportcandy' ); ?></button>
616 <button
617 class="wpsc-button normal secondary"
618 onclick="jQuery('.wpsc-setting-nav.active').trigger('click');">
619 <?php esc_attr_e( 'Cancel', 'supportcandy' ); ?></button>
620 </div>
621 <?php
622
623 wp_die();
624 }
625
626 /**
627 * Set edit custom field
628 *
629 * @return void
630 */
631 public static function set_edit_custom_field() {
632
633 global $wpdb;
634
635 if ( check_ajax_referer( 'wpsc_set_edit_custom_field', '_ajax_nonce', false ) != 1 ) {
636 wp_send_json_error( 'Unauthorised request!', 401 );
637 }
638
639 if ( ! WPSC_Functions::is_site_admin() ) {
640 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
641 }
642
643 $id = isset( $_POST['cf_id'] ) ? intval( $_POST['cf_id'] ) : 0;
644 if ( ! $id ) {
645 wp_send_json_error( 'Incorrect request!', 400 );
646 }
647
648 $cf = new WPSC_Custom_Field( $id );
649 if ( ! $cf->id ) {
650 wp_send_json_error( 'Incorrect request!', 400 );
651 }
652
653 $cf->name = isset( $_POST['label'] ) ? sanitize_text_field( wp_unslash( $_POST['label'] ) ) : '';
654 if ( ! $cf->name ) {
655 wp_send_json_error( 'Incorrect request!', 400 );
656 }
657
658 $cf->type::set_cf_properties( $cf, self::$fields[ $cf->field ] );
659
660 // set load after.
661 $load_after = isset( $_POST['load-after'] ) ? sanitize_text_field( wp_unslash( $_POST['load-after'] ) ) : '__END__';
662 if ( $load_after != '__END__' ) {
663
664 $count = 1;
665
666 if ( $load_after == '__TOP__' ) {
667 $cf->load_order = $count++;
668 $cf->save();
669 }
670
671 foreach ( WPSC_Custom_Field::$custom_fields as $cff ) {
672
673 if ( $cff->field != $cf->field || $cff->slug == $cf->slug ) {
674 continue;
675 }
676
677 $cff->load_order = $count++;
678 $cff->save();
679
680 if ( $cff->slug == $load_after ) {
681 $cf->load_order = $count++;
682 $cf->save();
683 }
684 }
685 } else {
686
687 $max_load_order = (int) $wpdb->get_var( "SELECT max(load_order) FROM {$wpdb->prefix}psmsc_custom_fields WHERE field='{$cf->field}'" );
688 $cf->load_order = ++$max_load_order;
689 $cf->save();
690 }
691
692 wp_die();
693 }
694
695 /**
696 * Delete custom feild
697 */
698 public static function delete_custom_field() {
699
700 if ( check_ajax_referer( 'wpsc_delete_custom_field', '_ajax_nonce', false ) != 1 ) {
701 wp_send_json_error( 'Unauthorised request!', 401 );
702 }
703
704 if ( ! WPSC_Functions::is_site_admin() ) {
705 wp_send_json_error( __( 'Unauthorized access!', 'supportcandy' ), 401 );
706 }
707
708 $id = isset( $_POST['cf_id'] ) ? intval( $_POST['cf_id'] ) : 0;
709 if ( ! $id ) {
710 wp_send_json_error( 'Incorrect request!', 400 );
711 }
712
713 $cf = new WPSC_Custom_Field( $id );
714 if ( ! $cf->id ) {
715 wp_send_json_error( 'Incorrect request!', 400 );
716 }
717
718 do_action( 'wpsc_delete_custom_field', $cf );
719
720 WPSC_Custom_Field::destroy( $id );
721 wp_die();
722 }
723
724 /**
725 * Static snippets for this page
726 *
727 * @return void
728 */
729 public static function print_snippets() {
730 ?>
731
732 <div class="wpsc-snippets">
733 <div class="wpsc-add-option">
734 <div class="wpsc-option-item">
735 <div class="content">
736 <div class="wpsc-add-option-container">
737 <input type="text" value="" autocomplete="off"/>
738 <button onclick="wpsc_add_new_option(this, '<?php echo esc_attr( wp_create_nonce( 'wpsc_add_new_option' ) ); ?>');">
739 <?php WPSC_Icons::get( 'check' ); ?>
740 </button>
741 </div>
742 <div class="wpsc-edit-option-container" style="display: none;">
743 <input class="edit-option-text" type="text" value="" autocomplete="off" />
744 <button onclick="wpsc_set_edit_option(this, '<?php echo esc_attr( wp_create_nonce( 'wpsc_set_edit_option' ) ); ?>');">
745 <?php WPSC_Icons::get( 'check' ); ?>
746 </button>
747 <button class="cancel" onclick="wpsc_edit_option_cancel(this);">
748 <?php WPSC_Icons::get( 'times' ); ?>
749 </button>
750 </div>
751 <div class="wpsc-option-listing-container" style="display: none;">
752 <span class="sort wpsc-sort-handle"><?php WPSC_Icons::get( 'sort' ); ?></span>
753 <div class="text"></div>
754 <span class="edit" onclick="wpsc_edit_option(this);"><?php WPSC_Icons::get( 'edit' ); ?></span>
755 </div>
756 </div>
757 <div class="remove-container">
758 <span onclick="wpsc_remove_option_item(this)"><?php WPSC_Icons::get( 'times-circle' ); ?></span>
759 </div>
760 </div>
761 </div>
762 </div>
763 <?php
764 }
765
766 /**
767 * Footer scripts (dynamic)
768 *
769 * @return void
770 */
771 public static function footer_scripts() {
772 ?>
773
774 <script>
775
776 /**
777 * Set add new custom field
778 */
779 function wpsc_set_add_new_custom_field(el) {
780
781 var form = jQuery('.frm-add-new-custom-field');
782 var dataform = new FormData(form[0]);
783 var field = dataform.get('field');
784 var fieldType = dataform.get('type');
785
786 // general validations
787 if (!wpsc_cf_settings_general_validations(form)) return;
788
789 // check whether char-limit honored by default value
790 if (
791 (field == 'ticket' || field == 'agentonly') &&
792 (fieldType == 'cf_textfield' || fieldType == 'cf_textarea' || fieldType == 'cf_number' ||
793 fieldType == 'cf_email' || fieldType == 'cf_url')
794 ) {
795 var defaultVal = dataform.get('default_value').trim();
796 var char_limit = dataform.get('char_limit');
797 if ( defaultVal && char_limit && defaultVal.length > char_limit) {
798 alert('<?php esc_attr_e( 'Default value exceeds character limit!', 'supportcandy' ); ?>');
799 return;
800 }
801 }
802
803 var dateRange = dataform.get('date_range');
804 if(
805 (field == 'ticket' || field == 'agentonly') &&
806 (fieldType == 'cf_date' || fieldType == 'cf_datetime') && dateRange == 'range'){
807 var defaultVal = dataform.get('default_value').trim();
808 fromDate = new Date(jQuery('#from-date-range').val());
809 toDate = new Date(jQuery('#to-date-range').val());
810 defaultDate = new Date(defaultVal);
811 if(!(Date.parse(defaultDate) <= Date.parse(toDate) && Date.parse(defaultDate) >= Date.parse(fromDate)) ){
812 alert('<?php esc_attr_e( 'Default value is not in the range!', 'supportcandy' ); ?>');
813 return;
814 }
815 }
816
817 if (field == 'ticket' && fieldType == 'cf_html') {
818 var defaultVal = dataform.get('html_text').trim();
819 if(!defaultVal){
820 alert(supportcandy.translations.req_fields_missing);
821 return;
822 }
823 }
824
825 <?php do_action( 'wpsc_js_set_add_new_custom_field' ); ?>
826
827 jQuery(el).text(supportcandy.translations.please_wait);
828 jQuery.ajax({
829 url: supportcandy.ajax_url,
830 type: 'POST',
831 data: dataform,
832 processData: false,
833 contentType: false
834 }).done(function (res) {
835 jQuery('.wpsc-setting-nav.active').trigger('click');
836 });
837 }
838
839 /**
840 * Set edit custom field
841 */
842 function wpsc_set_edit_custom_field(el) {
843
844 var form = jQuery('.frm-edit-custom-field');
845 var dataform = new FormData(form[0]);
846 var field = dataform.get('field');
847 var fieldType = dataform.get('type');
848
849 if ( ( fieldType == 'df_status' || fieldType == 'df_priority' || fieldType == 'df_category' ) && dataform.get('default_value') == null ) {
850 alert( supportcandy.translations.req_fields_missing );
851 return;
852 }
853
854 // general validations
855 if (!wpsc_cf_settings_general_validations(form)) return;
856
857 // check whether char-limit honored by default value
858 if (
859 (field == 'ticket' || field == 'agentonly') &&
860 (fieldType == 'cf_textfield' || fieldType == 'cf_textarea' || fieldType == 'cf_number' ||
861 fieldType == 'cf_email' || fieldType == 'cf_url')
862 ) {
863 var defaultVal = dataform.get('default_value').trim();
864 var char_limit = parseInt(dataform.get('char_limit'));
865 if ( defaultVal && char_limit && defaultVal.length > char_limit) {
866 alert('<?php esc_attr_e( 'Default value exceeds character limit!', 'supportcandy' ); ?>');
867 return;
868 }
869 }
870
871 var dateRange = dataform.get('date_range');
872 if(
873 (field == 'ticket' || field == 'agentonly') &&
874 (fieldType == 'cf_date' || fieldType == 'cf_datetime') && dateRange == 'range'){
875 var defaultVal = dataform.get('default_value').trim();
876 fromDate = new Date(jQuery('#from-date-range').val());
877 toDate = new Date(jQuery('#to-date-range').val());
878 defaultDate = new Date(defaultVal);
879 if(!(Date.parse(defaultDate) <= Date.parse(toDate) && Date.parse(defaultDate) >= Date.parse(fromDate)) ){
880 alert('<?php esc_attr_e( 'Default value is not in the range!', 'supportcandy' ); ?>');
881 return;
882 }
883 }
884
885 if (field == 'ticket' && fieldType == 'cf_html') {
886 var defaultVal = dataform.get('html_text').trim();
887 if(!defaultVal){
888 alert(supportcandy.translations.req_fields_missing);
889 return;
890 }
891 }
892
893 <?php do_action( 'wpsc_js_set_edit_custom_field' ); ?>
894
895 jQuery(el).text(supportcandy.translations.please_wait);
896 jQuery.ajax({
897 url: supportcandy.ajax_url,
898 type: 'POST',
899 data: dataform,
900 processData: false,
901 contentType: false
902 }).done(function (res) {
903 jQuery('.wpsc-setting-nav.active').trigger('click');
904 });
905 }
906
907 /**
908 * General validations
909 */
910 function wpsc_cf_settings_general_validations(form) {
911
912 var flag = true;
913 form.find('.wpsc-input-group').each(function(index, element){
914
915 var inputData = jQuery(element).data();
916 switch(inputData.type) {
917
918 case 'textfield':
919 var fieldValue = jQuery(this).find('input').val().trim();
920 if (inputData.required && !fieldValue) {
921 alert(supportcandy.translations.req_fields_missing);
922 jQuery(this).find('input').focus();
923 return flag = false;
924 }
925 break;
926
927 case 'single-select':
928 var fieldValue = jQuery(this).find('select').val();
929 if (inputData.required && !fieldValue) {
930 alert(supportcandy.translations.req_fields_missing);
931 return flag = false;
932 }
933 break;
934
935 case 'select-options':
936 var fieldValue = jQuery(this).find('.wpsc-options-container .option_id').length;
937 if (inputData.required && !fieldValue) {
938 alert(supportcandy.translations.submit_option_error);
939 return flag = false;
940 }
941 break;
942
943 case 'number':
944 var fieldValue = jQuery(this).find('input').val().trim();
945 if (inputData.required && !fieldValue) {
946 alert(supportcandy.translations.req_fields_missing);
947 return flag = false;
948 }
949 if (fieldValue && isNaN(fieldValue)) {
950 alert('<?php esc_attr_e( 'Incorrect number value!', 'supportcandy' ); ?>');
951 jQuery(this).find('input').focus();
952 return flag = false;
953 }
954 break;
955
956 case 'email':
957 var fieldValue = jQuery(this).find('input').val().trim();
958 if (inputData.required && !fieldValue) {
959 alert(supportcandy.translations.req_fields_missing);
960 return flag = false;
961 }
962 if (fieldValue && !validateEmail(fieldValue)) {
963 alert('<?php esc_attr_e( 'Incorrect email!', 'supportcandy' ); ?>');
964 jQuery(this).find('input').focus();
965 return flag = false;
966 }
967 break;
968
969 case 'url':
970 var fieldValue = jQuery(this).find('input').val().trim();
971 if (inputData.required && !fieldValue) {
972 alert(supportcandy.translations.req_fields_missing);
973 return flag = false;
974 }
975 if (fieldValue && !validateURL(fieldValue)) {
976 alert('<?php esc_attr_e( 'Incorrect url!', 'supportcandy' ); ?>');
977 jQuery(this).find('input').focus();
978 return flag = false;
979 }
980 break;
981 }
982 });
983
984 return flag;
985 }
986 </script>
987 <?php
988 }
989 }
990 endif;
991
992 WPSC_CF_Settings::init();
993