1 <?php
2 3 4 5 6 7 8 9 10
11 abstract class WC_Settings_API {
12
13
14 public $plugin_id = 'woocommerce_';
15
16
17 public $settings = array();
18
19
20 public $form_fields = array();
21
22
23 public $errors = array();
24
25
26 public $sanitized_fields = array();
27
28 29 30 31 32 33 34 35 36 37
38 public function admin_options() { ?>
39 <h3><?php echo ( ! empty( $this->method_title ) ) ? $this->method_title : __( 'Settings', 'woocommerce' ) ; ?></h3>
40
41 <?php echo ( ! empty( $this->method_description ) ) ? wpautop( $this->method_description ) : ''; ?>
42
43 <table class="form-table">
44 <?php $this->generate_settings_html(); ?>
45 </table><?php
46 }
47
48 49 50 51 52 53 54 55 56 57
58 public function init_form_fields() {}
59
60 61 62 63 64
65 public function get_form_fields() {
66 return apply_filters( 'woocommerce_settings_api_form_fields_' . $this->id, $this->form_fields );
67 }
68
69 70 71 72 73 74 75 76
77 public function process_admin_options() {
78 $this->validate_settings_fields();
79
80 if ( count( $this->errors ) > 0 ) {
81 $this->display_errors();
82 return false;
83 } else {
84 update_option( $this->plugin_id . $this->id . '_settings', apply_filters( 'woocommerce_settings_api_sanitized_fields_' . $this->id, $this->sanitized_fields ) );
85 $this->init_settings();
86 return true;
87 }
88 }
89
90 91 92 93 94 95 96
97 public function display_errors() {}
98
99 100 101 102 103 104 105 106 107 108 109 110
111 public function init_settings() {
112
113 $this->settings = get_option( $this->plugin_id . $this->id . '_settings', null );
114
115 if ( ! $this->settings || ! is_array( $this->settings ) ) {
116
117 $this->settings = array();
118
119
120 if ( $form_fields = $this->get_form_fields() )
121 foreach ( $form_fields as $k => $v )
122 $this->settings[ $k ] = isset( $v['default'] ) ? $v['default'] : '';
123 }
124
125 if ( $this->settings && is_array( $this->settings ) ) {
126 $this->settings = array_map( array( $this, 'format_settings' ), $this->settings );
127 $this->enabled = isset( $this->settings['enabled'] ) && $this->settings['enabled'] == 'yes' ? 'yes' : 'no';
128 }
129 }
130
131 132 133 134 135 136 137 138 139 140
141 public function get_option( $key, $empty_value = null ) {
142 if ( empty( $this->settings ) )
143 $this->init_settings();
144
145
146 if ( ! isset( $this->settings[ $key ] ) ) {
147 $form_fields = $this->get_form_fields();
148 $this->settings[ $key ] = isset( $form_fields[ $key ]['default'] ) ? $form_fields[ $key ]['default'] : '';
149 }
150
151 if ( ! is_null( $empty_value ) && empty( $this->settings[ $key ] ) )
152 $this->settings[ $key ] = $empty_value;
153
154 return $this->settings[ $key ];
155 }
156
157 158 159 160 161 162 163
164 public function format_settings( $value ) {
165 return is_array( $value ) ? $value : $value;
166 }
167
168 169 170 171 172 173 174 175 176 177 178 179
180 public function generate_settings_html( $form_fields = false ) {
181 if ( ! $form_fields )
182 $form_fields = $this->get_form_fields();
183
184 $html = '';
185 foreach ( $form_fields as $k => $v ) {
186 if ( ! isset( $v['type'] ) || ( $v['type'] == '' ) )
187 $v['type'] = 'text';
188
189 if ( method_exists( $this, 'generate_' . $v['type'] . '_html' ) ) {
190 $html .= $this->{'generate_' . $v['type'] . '_html'}( $k, $v );
191 } else {
192 $html .= $this->{'generate_text_html'}( $k, $v );
193 }
194 }
195
196 echo $html;
197 }
198
199 200 201 202 203
204 public function get_tooltip_html( $data ) {
205 if ( $data['desc_tip'] === true ) {
206 $tip = $data['description'];
207 } elseif ( ! empty( $data['desc_tip'] ) ) {
208 $tip = $data['desc_tip'];
209 } else {
210 $tip = '';
211 }
212
213 return $tip ? '<img class="help_tip" data-tip="' . esc_attr( $tip ) . '" src="' . WC()->plugin_url() . '/assets/images/help.png" height="16" width="16" />' : '';
214 }
215
216 217 218 219 220
221 public function get_description_html( $data ) {
222 if ( $data['desc_tip'] === true ) {
223 $description = '';
224 } elseif ( ! empty( $data['desc_tip'] ) ) {
225 $description = $data['description'];
226 } elseif ( ! empty( $data['description'] ) ) {
227 $description = $data['description'];
228 } else {
229 $description = '';
230 }
231
232 return $description ? '<p class="description">' . wp_kses_post( $description ) . '</p>' . "\n" : '';
233 }
234
235 236 237 238 239
240 public function get_custom_attribute_html( $data ) {
241 $custom_attributes = array();
242
243 if ( ! empty( $data['custom_attributes'] ) && is_array( $data['custom_attributes'] ) )
244 foreach ( $data['custom_attributes'] as $attribute => $attribute_value )
245 $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
246
247 return implode( ' ', $custom_attributes );
248 }
249
250 251 252 253 254 255 256 257 258
259 public function generate_text_html( $key, $data ) {
260 $field = $this->plugin_id . $this->id . '_' . $key;
261 $defaults = array(
262 'title' => '',
263 'disabled' => false,
264 'class' => '',
265 'css' => '',
266 'placeholder' => '',
267 'type' => 'text',
268 'desc_tip' => false,
269 'description' => '',
270 'custom_attributes' => array()
271 );
272
273 $data = wp_parse_args( $data, $defaults );
274
275 ob_start();
276 ?>
277 <tr valign="top">
278 <th scope="row" class="titledesc">
279 <label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
280 <?php echo $this->get_tooltip_html( $data ); ?>
281 </th>
282 <td class="forminp">
283 <fieldset>
284 <legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
285 <input class="input-text regular-input <?php echo esc_attr( $data['class'] ); ?>" type="<?php echo esc_attr( $data['type'] ); ?>" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" value="<?php echo esc_attr( $this->get_option( $key ) ); ?>" placeholder="<?php echo esc_attr( $data['placeholder'] ); ?>" <?php disabled( $data['disabled'], true ); ?> <?php echo $this->get_custom_attribute_html( $data ); ?> />
286 <?php echo $this->get_description_html( $data ); ?>
287 </fieldset>
288 </td>
289 </tr>
290 <?php
291 return ob_get_clean();
292 }
293
294 295 296 297 298 299 300 301 302
303 public function generate_price_html( $key, $data ) {
304 $field = $this->plugin_id . $this->id . '_' . $key;
305 $defaults = array(
306 'title' => '',
307 'disabled' => false,
308 'class' => '',
309 'css' => '',
310 'placeholder' => '',
311 'type' => 'text',
312 'desc_tip' => false,
313 'description' => '',
314 'custom_attributes' => array()
315 );
316
317 $data = wp_parse_args( $data, $defaults );
318
319 ob_start();
320 ?>
321 <tr valign="top">
322 <th scope="row" class="titledesc">
323 <label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
324 <?php echo $this->get_tooltip_html( $data ); ?>
325 </th>
326 <td class="forminp">
327 <fieldset>
328 <legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
329 <input class="wc_input_price input-text regular-input <?php echo esc_attr( $data['class'] ); ?>" type="text" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $this->get_option( $key ) ) ); ?>" placeholder="<?php echo esc_attr( $data['placeholder'] ); ?>" <?php disabled( $data['disabled'], true ); ?> <?php echo $this->get_custom_attribute_html( $data ); ?> />
330 <?php echo $this->get_description_html( $data ); ?>
331 </fieldset>
332 </td>
333 </tr>
334 <?php
335 return ob_get_clean();
336 }
337
338 339 340 341 342 343 344 345 346
347 public function generate_decimal_html( $key, $data ) {
348 $field = $this->plugin_id . $this->id . '_' . $key;
349 $defaults = array(
350 'title' => '',
351 'disabled' => false,
352 'class' => '',
353 'css' => '',
354 'placeholder' => '',
355 'type' => 'text',
356 'desc_tip' => false,
357 'description' => '',
358 'custom_attributes' => array()
359 );
360
361 $data = wp_parse_args( $data, $defaults );
362
363 ob_start();
364 ?>
365 <tr valign="top">
366 <th scope="row" class="titledesc">
367 <label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
368 <?php echo $this->get_tooltip_html( $data ); ?>
369 </th>
370 <td class="forminp">
371 <fieldset>
372 <legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
373 <input class="wc_input_decimal input-text regular-input <?php echo esc_attr( $data['class'] ); ?>" type="text" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" value="<?php echo esc_attr( wc_format_localized_decimal( $this->get_option( $key ) ) ); ?>" placeholder="<?php echo esc_attr( $data['placeholder'] ); ?>" <?php disabled( $data['disabled'], true ); ?> <?php echo $this->get_custom_attribute_html( $data ); ?> />
374 <?php echo $this->get_description_html( $data ); ?>
375 </fieldset>
376 </td>
377 </tr>
378 <?php
379 return ob_get_clean();
380 }
381
382 383 384 385 386 387 388 389 390
391 public function generate_password_html( $key, $data ) {
392 $data['type'] = 'password';
393 return $this->generate_text_html( $key, $data );
394 }
395
396 397 398 399 400 401 402 403 404
405 public function generate_textarea_html( $key, $data ) {
406 $field = $this->plugin_id . $this->id . '_' . $key;
407 $defaults = array(
408 'title' => '',
409 'disabled' => false,
410 'class' => '',
411 'css' => '',
412 'placeholder' => '',
413 'type' => 'text',
414 'desc_tip' => false,
415 'description' => '',
416 'custom_attributes' => array()
417 );
418
419 $data = wp_parse_args( $data, $defaults );
420
421 ob_start();
422 ?>
423 <tr valign="top">
424 <th scope="row" class="titledesc">
425 <label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
426 <?php echo $this->get_tooltip_html( $data ); ?>
427 </th>
428 <td class="forminp">
429 <fieldset>
430 <legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
431 <textarea rows="3" cols="20" class="input-text wide-input <?php echo esc_attr( $data['class'] ); ?>" type="<?php echo esc_attr( $data['type'] ); ?>" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" placeholder="<?php echo esc_attr( $data['placeholder'] ); ?>" <?php disabled( $data['disabled'], true ); ?> <?php echo $this->get_custom_attribute_html( $data ); ?>><?php echo esc_textarea( $this->get_option( $key ) ); ?></textarea>
432 <?php echo $this->get_description_html( $data ); ?>
433 </fieldset>
434 </td>
435 </tr>
436 <?php
437 return ob_get_clean();
438 }
439
440 441 442 443 444 445 446 447 448
449 public function generate_checkbox_html( $key, $data ) {
450 $field = $this->plugin_id . $this->id . '_' . $key;
451 $defaults = array(
452 'title' => '',
453 'label' => '',
454 'disabled' => false,
455 'class' => '',
456 'css' => '',
457 'type' => 'text',
458 'desc_tip' => false,
459 'description' => '',
460 'custom_attributes' => array()
461 );
462
463 $data = wp_parse_args( $data, $defaults );
464
465 if ( ! $data['label'] )
466 $data['label'] = $data['title'];
467
468 ob_start();
469 ?>
470 <tr valign="top">
471 <th scope="row" class="titledesc">
472 <label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
473 <?php echo $this->get_tooltip_html( $data ); ?>
474 </th>
475 <td class="forminp">
476 <fieldset>
477 <legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
478 <label for="<?php echo esc_attr( $field ); ?>">
479 <input <?php disabled( $data['disabled'], true ); ?> class="<?php echo esc_attr( $data['class'] ); ?>" type="checkbox" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" value="1" <?php checked( $this->get_option( $key ), 'yes' ); ?> <?php echo $this->get_custom_attribute_html( $data ); ?> /> <?php echo wp_kses_post( $data['label'] ); ?></label><br/>
480 <?php echo $this->get_description_html( $data ); ?>
481 </fieldset>
482 </td>
483 </tr>
484 <?php
485 return ob_get_clean();
486 }
487
488 489 490 491 492 493 494 495 496
497 public function generate_select_html( $key, $data ) {
498 $field = $this->plugin_id . $this->id . '_' . $key;
499 $defaults = array(
500 'title' => '',
501 'disabled' => false,
502 'class' => '',
503 'css' => '',
504 'placeholder' => '',
505 'type' => 'text',
506 'desc_tip' => false,
507 'description' => '',
508 'custom_attributes' => array(),
509 'options' => array()
510 );
511
512 $data = wp_parse_args( $data, $defaults );
513
514 ob_start();
515 ?>
516 <tr valign="top">
517 <th scope="row" class="titledesc">
518 <label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
519 <?php echo $this->get_tooltip_html( $data ); ?>
520 </th>
521 <td class="forminp">
522 <fieldset>
523 <legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
524 <select class="select <?php echo esc_attr( $data['class'] ); ?>" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" <?php disabled( $data['disabled'], true ); ?> <?php echo $this->get_custom_attribute_html( $data ); ?>>
525 <?php foreach ( (array) $data['options'] as $option_key => $option_value ) : ?>
526 <option value="<?php echo esc_attr( $option_key ); ?>" <?php selected( $option_key, esc_attr( $this->get_option( $key ) ) ); ?>><?php echo esc_attr( $option_value ); ?></option>
527 <?php endforeach; ?>
528 </select>
529 <?php echo $this->get_description_html( $data ); ?>
530 </fieldset>
531 </td>
532 </tr>
533 <?php
534 return ob_get_clean();
535 }
536
537 538 539 540 541 542 543 544 545
546 public function generate_multiselect_html( $key, $data ) {
547 $field = $this->plugin_id . $this->id . '_' . $key;
548 $defaults = array(
549 'title' => '',
550 'disabled' => false,
551 'class' => '',
552 'css' => '',
553 'placeholder' => '',
554 'type' => 'text',
555 'desc_tip' => false,
556 'description' => '',
557 'custom_attributes' => array(),
558 'options' => array()
559 );
560
561 $data = wp_parse_args( $data, $defaults );
562
563 ob_start();
564 ?>
565 <tr valign="top">
566 <th scope="row" class="titledesc">
567 <label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
568 <?php echo $this->get_tooltip_html( $data ); ?>
569 </th>
570 <td class="forminp">
571 <fieldset>
572 <legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
573 <select multiple="multiple" class="multiselect <?php echo esc_attr( $data['class'] ); ?>" name="<?php echo esc_attr( $field ); ?>[]" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" <?php disabled( $data['disabled'], true ); ?> <?php echo $this->get_custom_attribute_html( $data ); ?>>
574 <?php foreach ( (array) $data['options'] as $option_key => $option_value ) : ?>
575 <option value="<?php echo esc_attr( $option_key ); ?>" <?php selected( in_array( $option_key, $this->get_option( $key, array() ) ), true ); ?>><?php echo esc_attr( $option_value ); ?></option>
576 <?php endforeach; ?>
577 </select>
578 <?php echo $this->get_description_html( $data ); ?>
579 </fieldset>
580 </td>
581 </tr>
582 <?php
583 return ob_get_clean();
584 }
585
586 587 588 589 590 591 592 593 594
595 public function generate_title_html( $key, $data ) {
596 $defaults = array(
597 'title' => '',
598 'class' => '',
599 'css' => ''
600 );
601
602 $data = wp_parse_args( $data, $defaults );
603
604 ob_start();
605 ?>
606 </table>
607 <h4 class="<?php echo esc_attr( $data['class'] ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></h4>
608 <?php if ( ! empty( $data['description'] ) ) : ?>
609 <p><?php echo wp_kses_post( $data['description'] ); ?></p>
610 <?php endif; ?>
611 <table class="form-table">
612 <?php
613 return ob_get_clean();
614 }
615
616 617 618 619 620 621 622 623 624
625 public function validate_settings_fields( $form_fields = false ) {
626 if ( ! $form_fields )
627 $form_fields = $this->get_form_fields();
628
629 $this->sanitized_fields = array();
630
631 foreach ( $form_fields as $k => $v ) {
632 if ( empty( $v['type'] ) )
633 $v['type'] = 'text';
634
635
636 if ( method_exists( $this, 'validate_' . $k . '_field' ) ) {
637 $field = $this->{'validate_' . $k . '_field'}( $k );
638 $this->sanitized_fields[ $k ] = $field;
639
640
641 } elseif ( method_exists( $this, 'validate_' . $v['type'] . '_field' ) ) {
642 $field = $this->{'validate_' . $v['type'] . '_field'}( $k );
643 $this->sanitized_fields[ $k ] = $field;
644
645
646 } else {
647 $field = $this->{'validate_text_field'}( $k );
648 $this->sanitized_fields[ $k ] = $field;
649 }
650 }
651 }
652
653 654 655 656 657 658 659 660 661 662
663 public function validate_checkbox_field( $key ) {
664 $status = 'no';
665 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) && ( 1 == $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
666 $status = 'yes';
667 }
668
669 return $status;
670 }
671
672 673 674 675 676 677
678 public function validate_text_field( $key ) {
679 $text = $this->get_option( $key );
680
681 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) )
682 $text = wp_kses_post( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
683
684 return $text;
685 }
686
687 688 689 690 691 692
693 public function validate_price_field( $key ) {
694 $text = $this->get_option( $key );
695
696 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
697 if ( $_POST[ $this->plugin_id . $this->id . '_' . $key ] !== '' )
698 $text = wc_format_decimal( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
699 else
700 $text = '';
701 }
702
703 return $text;
704 }
705
706 707 708 709 710 711
712 public function validate_decimal_field( $key ) {
713 $text = $this->get_option( $key );
714
715 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
716 if ( $_POST[ $this->plugin_id . $this->id . '_' . $key ] !== '' )
717 $text = wc_format_decimal( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
718 else
719 $text = '';
720 }
721
722 return $text;
723 }
724
725 726 727 728 729 730 731 732 733 734
735 public function validate_password_field( $key ) {
736 $text = $this->get_option( $key );
737
738 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
739 $text = wc_clean( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
740 }
741
742 return $text;
743 }
744
745 746 747 748 749 750 751 752 753 754
755 public function validate_textarea_field( $key ) {
756 $text = $this->get_option( $key );
757
758 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
759 $text = wp_kses( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ),
760 array_merge(
761 array(
762 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true )
763 ),
764 wp_kses_allowed_html( 'post' )
765 )
766 );
767 }
768
769 return $text;
770 }
771
772 773 774 775 776 777 778 779 780 781
782 public function validate_select_field( $key ) {
783 $value = $this->get_option( $key );
784
785 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
786 $value = wc_clean( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
787 }
788
789 return $value;
790 }
791
792 793 794 795 796 797 798 799 800 801
802 public function validate_multiselect_field( $key ) {
803 $value = $this->get_option( $key );
804
805 if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
806 $value = array_map( 'wc_clean', array_map( 'stripslashes', (array) $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
807 } else {
808 $value = '';
809 }
810
811 return $value;
812 }
813 }