WooCommerce Advanced Free Shipping - Version 1.0.1

Version Description

  • Fix - Wrongful url for sub-domain websites
  • Add - Added states as condition
Download this release

Release Info

Developer sormano
Plugin Icon 128x128 WooCommerce Advanced Free Shipping
Version 1.0.1
Comparing to
See all releases

Version 1.0.1

assets/css/admin-style.css ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Hide visibility from admin */
2
+ .post-type-wafs .misc-pub-visibility#visibility {
3
+ display: none;
4
+ }
5
+
6
+ .wafs-option label {
7
+ display: inline-block;
8
+ width: 150px;
9
+ }
10
+
11
+ .wafs_conditions_meta_box > p:first-child + div > .or_match {
12
+ display: none;
13
+ }
14
+ /*
15
+ * Condition group
16
+ */
17
+ .condition-group {
18
+ margin-bottom: 30px;
19
+ background-color: #f5f5f5;
20
+ padding: 15px 20px 20px;
21
+ border: 1px solid #ddd;
22
+ -webkit-box-shadow: 0 1px 1px rgba( 0, 0, 0, .04);
23
+ box-shadow: 0 1px 1px rgba( 0, 0, 0, .04);
24
+ }
25
+ .wafs-condition-wrap {
26
+ margin: 10px 0px 5px;
27
+ }
28
+ .wafs-condition-wrap .wafs-condition {
29
+ width: 30%;
30
+ }
31
+ .wafs-condition-wrap .wafs-operator {
32
+ width: 12%;
33
+ min-width: 140px;
34
+ }
35
+ .wafs-condition-wrap .wafs-value {
36
+ width: 30%;
37
+ }
38
+ .wafs-condition-wrap input {
39
+ vertical-align: top;
40
+ }
41
+
42
+ #wafs_conditions p + p {
43
+ display: none;
44
+ }
45
+ /* Description */
46
+ .wafs_desc {
47
+ display: none;
48
+ position: absolute;
49
+ background: rgba( 0, 0, 0, .8 );
50
+ min-width: 25px;
51
+ max-width: 200px;
52
+ border-radius: 6px;
53
+ padding: 5px 10px;
54
+ color: white;
55
+ margin-top: 10px;
56
+ right: 40px;
57
+ text-align: center;
58
+ }
59
+ .wafs_desc:after {
60
+ border-top: 0px solid transparent;
61
+ border-right: 10px solid transparent;
62
+ border-left: 10px solid transparent;
63
+ border-bottom: 10px solid rgba( 0, 0, 0, .8 );
64
+ content: ' ';
65
+ position: absolute;
66
+ top: -10px;
67
+ right: 10px;
68
+ z-index: 999;
69
+ }
70
+ .wafs_tip:hover ~ .wafs_desc {
71
+ display: block !important;
72
+ }
73
+ .wafs-description {
74
+ width: 40px;
75
+ float: right;
76
+ line-height: 20px;
77
+ }
78
+
79
+ /*
80
+ * Loading icon
81
+ */
82
+
83
+ /* Load icon condition row */
84
+ .wafs-condition-wrap ~ .loading-icon {
85
+ display: block;
86
+ }
87
+ .loading-icon {
88
+ width: 30%;
89
+ clear: both;
90
+ display: inline-block;
91
+ text-align: center;
92
+ line-height: 110%;
93
+ margin: 0 1px;
94
+ }
95
+
96
+ .condition-delete {
97
+ display: none;
98
+ opacity: 0;
99
+ transition: opacity .3s ease-in-out;
100
+ }
101
+ .wafs-condition-wrap:hover .condition-delete {
102
+ display: inline-block;
103
+ opacity: 1;
104
+ }
105
+
106
+
107
+ /* � WooCommerce Add icon */
108
+ .add.button:before {
109
+ font-family: WooCommerce;
110
+ speak: none;
111
+ font-weight: 400;
112
+ font-variant: normal;
113
+ text-transform: none;
114
+ line-height: 1;
115
+ -webkit-font-smoothing: antialiased;
116
+ margin-right: 7px;
117
+ content: "\e007";
118
+ }
assets/js/wafs-js.js ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( function( $ ) {
2
+
3
+ var loading_icon = '<span class="loading-icon"><img src="/wp-admin/images/wpspin_light.gif"/></span>';
4
+
5
+ // Add condition
6
+ $( '#wafs_conditions' ).on( 'click', '.condition-add', function() {
7
+
8
+ var data = { action: 'wafs_add_condition', group: $( this ).attr( 'data-group' ) };
9
+
10
+ $( '.condition-group-' + data.group ).append( loading_icon ).children( ':last' );
11
+
12
+ $.post( ajaxurl, data, function( response ) {
13
+ $( '.condition-group-' + data.group ).append( response ).children( ':last' ).hide().fadeIn( 'normal' );
14
+ $( '.condition-group-' + data.group + ' .loading-icon' ).children( ':first' ).remove();
15
+ });
16
+
17
+ });
18
+
19
+ // Delete condition
20
+ $( '#wafs_conditions' ).on( 'click', '.condition-delete', function() {
21
+
22
+ if ( $( this ).closest( '.condition-group' ).children( '.wafs-condition-wrap' ).length == 1 ) {
23
+ $( this ).closest( '.condition-group' ).fadeOut( 'normal', function() { $( this ).remove(); });
24
+
25
+ } else {
26
+ $( this ).closest( '.wafs-condition-wrap' ).fadeOut( 'normal', function() { $( this ).remove(); });
27
+ }
28
+
29
+ });
30
+
31
+ // Add condition group
32
+ $( '#wafs_conditions' ).on( 'click', '.condition-group-add', function() {
33
+
34
+ // Display loading icon
35
+ $( '.wafs_conditions' ).append( loading_icon ).children( ':last' );
36
+
37
+ var data = {
38
+ action: 'wafs_add_condition_group',
39
+ group: parseInt( $( '.condition-group' ).last().attr( 'data-group') ) + 1
40
+ };
41
+
42
+ // Insert condition group
43
+ $.post( ajaxurl, data, function( response ) {
44
+ $( '.condition-group ~ .loading-icon' ).last().remove();
45
+ $( '.wafs_conditions' ).append( response ).children( ':last' ).hide().fadeIn( 'normal' );
46
+ });
47
+
48
+ });
49
+
50
+ // Update condition values
51
+ $( '#wafs_conditions' ).on( 'change', '.wafs-condition', function () {
52
+
53
+ var data = {
54
+ action: 'wafs_update_condition_value',
55
+ id: $( this ).attr( 'data-id' ),
56
+ group: $( this ).attr( 'data-group' ),
57
+ condition: $( this ).val()
58
+ };
59
+
60
+ var replace = '.wafs-value-wrap-' + data.id;
61
+
62
+ $( replace ).html( loading_icon );
63
+
64
+ $.post( ajaxurl, data, function( response ) {
65
+ $( replace ).replaceWith( response );
66
+ });
67
+
68
+ // Update condition description
69
+ var description = {
70
+ action: 'wafs_update_condition_description',
71
+ condition: data.condition
72
+ };
73
+
74
+ $.post( ajaxurl, description, function( description_response ) {
75
+ $( replace + ' ~ .wafs-description' ).replaceWith( description_response );
76
+ })
77
+
78
+
79
+ });
80
+
81
+ });
includes/admin/settings/conditions/class-wafs-condition.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Wafs_Condition
4
+ *
5
+ * Create a condition rule
6
+ *
7
+ * @class Wafs_Condition
8
+ * @author Jeroen Sormani
9
+ * @package WooCommerce Advanced Free Shipping
10
+ * @version 1.0.0
11
+ */
12
+
13
+ class Wafs_Condition {
14
+
15
+ public $condition;
16
+ public $operator;
17
+ public $value;
18
+ public $group;
19
+ public $id;
20
+
21
+
22
+ /**
23
+ * __construct functon.
24
+ */
25
+ public function __construct( $id = null, $group = 0, $condition = null, $operator = null, $value = null ) {
26
+
27
+ $this->id = $id;
28
+ $this->group = $group;
29
+ $this->condition = $condition;
30
+ $this->operator = $operator;
31
+ $this->value = $value;
32
+
33
+ if ( ! $id )
34
+ $this->id = rand();
35
+
36
+ $this->wafs_create_object();
37
+
38
+ }
39
+
40
+
41
+ /**
42
+ * Create condition.
43
+ *
44
+ * Created a condition rule object
45
+ */
46
+ public function wafs_create_object() {
47
+
48
+ ?><div class='wafs-condition-wrap'><?php
49
+
50
+ do_action( 'wafs_before_condition' );
51
+
52
+ $this->wafs_condition_conditions();
53
+ $this->wafs_condition_operator();
54
+ $this->wafs_condition_values();
55
+
56
+ $this->wafs_add_condition_button();
57
+ $this->wafs_remove_condition_button();
58
+
59
+ $this->wafs_condition_description();
60
+
61
+ do_action( 'wafs_after_condition' );
62
+
63
+ ?></div><?php
64
+
65
+ }
66
+
67
+
68
+ /**
69
+ * Condition dropdown.
70
+ *
71
+ * Render and load condition dropdown
72
+ */
73
+ public function wafs_condition_conditions() {
74
+
75
+ wafs_condition_conditions( $this->id, $this->group, $this->condition );
76
+
77
+ }
78
+
79
+
80
+ /**
81
+ * Operator dropdown.
82
+ *
83
+ * Render and load operator dropdown
84
+ */
85
+ public function wafs_condition_operator() {
86
+
87
+ wafs_condition_operator( $this->id, $this->group, $this->operator );
88
+
89
+ }
90
+
91
+
92
+ /**
93
+ * Value dropdown.
94
+ *
95
+ * Render and load value dropdown
96
+ */
97
+ public function wafs_condition_values() {
98
+
99
+ wafs_condition_values( $this->id, $this->group, $this->condition, $this->value );
100
+
101
+ }
102
+
103
+ public function wafs_add_condition_button() {
104
+ ?>
105
+ <a class='button condition-add' data-group='<?php echo $this->group; ?>' href='javascript:void(0);'>+</a>
106
+ <?php
107
+ }
108
+
109
+ public function wafs_remove_condition_button() {
110
+ ?>
111
+ <a class='button condition-delete' href='javascript:void(0);'>-</a>
112
+ <?php
113
+ }
114
+
115
+ public function wafs_condition_description() {
116
+
117
+ wafs_condition_description( $this->condition );
118
+
119
+ }
120
+
121
+ }
122
+ /**
123
+ * Load condition keys dropdown.
124
+ */
125
+ require_once plugin_dir_path( __FILE__ ) . 'condition-conditions.php';
126
+
127
+ /**
128
+ * Load condition operator dropdown.
129
+ */
130
+ require_once plugin_dir_path( __FILE__ ) . 'condition-operators.php';
131
+
132
+ /**
133
+ * Load condition value dropdown.
134
+ */
135
+ require_once plugin_dir_path( __FILE__ ) . 'condition-values.php';
136
+
137
+ /**
138
+ * Load condition descriptions.
139
+ */
140
+ require_once plugin_dir_path( __FILE__ ) . 'condition-descriptions.php';
141
+
142
+
143
+ ?>
includes/admin/settings/conditions/condition-conditions.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function wafs_condition_conditions( $id, $group = 0, $current_value = 'total' ) {
4
+
5
+ $conditions = array(
6
+ __( 'Cart', 'wafs' ) => array(
7
+ 'subtotal' => __( 'Subtotal', 'wafs' ),
8
+ 'subtotal_ex_tax' => __( 'Subtotal ex. taxes', 'wafs' ),
9
+ 'tax' => __( 'Tax', 'wafs' ),
10
+ 'quantity' => __( 'Quantity', 'wafs' ),
11
+ 'contains_product' => __( 'Contains product', 'wafs' ),
12
+ 'coupon' => __( 'Coupon', 'wafs' ),
13
+ ),
14
+ __( 'User Details', 'wafs' ) => array(
15
+ 'zipcode' => __( 'Zipcode', 'wafs' ),
16
+ 'city' => __( 'City', 'wafs' ),
17
+ 'state' => __( 'State', 'wafs' ),
18
+ 'country' => __( 'Country', 'wafs' ),
19
+ 'role' => __( 'User role', 'wafs' ),
20
+ ),
21
+ __( 'Product', 'wafs' ) => array(
22
+ 'width' => __( 'Width', 'wafs' ),
23
+ 'height' => __( 'Height', 'wafs' ),
24
+ 'length' => __( 'Length', 'wafs' ),
25
+ 'weight' => __( 'Weight', 'wafs' ),
26
+ 'stock' => __( 'Stock', 'wafs' ),
27
+ 'stock_status' => __( 'Stock status', 'wafs' ),
28
+ 'backorder' => __( 'Backorders', 'wafs' ),
29
+ 'category' => __( 'Category', 'wafs' ),
30
+ ),
31
+ );
32
+
33
+ $conditions = apply_filters( 'wafs_conditions', $conditions );
34
+
35
+ ?>
36
+
37
+ <span class='wafs-condition-wrap wafs-condition-wrap-<?php echo $id; ?>'>
38
+
39
+ <select class='wafs-condition' data-group='<?php echo $group; ?>' data-id='<?php echo $id; ?>'
40
+ name='_wafs_shipping_method_conditions[<?php echo $group; ?>][<?php echo $id; ?>][condition]'>
41
+
42
+ <?php echo $selected;
43
+ foreach ( $conditions as $option_group => $values ) :
44
+
45
+ ?><optgroup label='<?php echo $option_group; ?>'><?php
46
+
47
+ foreach ( $values as $key => $value ) :
48
+
49
+ $selected = ( $key == $current_value ) ? "SELECTED" : null;
50
+
51
+ ?><option value='<?php echo $key; ?>' <?php echo $selected; ?>><?php echo $value; ?></option><?php
52
+
53
+ endforeach;
54
+
55
+ ?></optgroup><?php
56
+
57
+ endforeach;
58
+ ?>
59
+
60
+ </select>
61
+
62
+ </span>
63
+
64
+ <?php
65
+
66
+ }
67
+
68
+ ?>
includes/admin/settings/conditions/condition-descriptions.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function wafs_condition_description( $condition ) {
4
+
5
+ global $woocommerce;
6
+
7
+ $descriptions = array(
8
+ 'state' => __( 'States are only available in the U.S.', 'wafs' ),
9
+ 'weight' => __( 'Weight calculated on all the cart contents', 'wafs' ),
10
+ 'length' => __( 'Compared to lengthiest product in cart', 'wafs' ),
11
+ 'width' => __( 'Compared to widest product in cart', 'wafs' ),
12
+ 'height' => __( 'Compared to highest product in cart', 'wafs' ),
13
+ 'stock_status' => __( 'All products in cart must match stock status', 'wafs' ),
14
+ 'backorder' => __( 'All products in cart must match backorder', 'wafs' ),
15
+ 'category' => __( 'All products in cart must match category', 'wafs' ),
16
+ 'contains_product' => __( 'Cart must contain one of this product', 'wafs' ),
17
+ );
18
+
19
+ // Display description
20
+ ?>
21
+ <span class='wafs-description <?php echo $descriptions[ $condition ]; ?>-description'>
22
+
23
+ <div class='description'>
24
+
25
+ <?php if ( isset( $descriptions[ $condition ] ) ) : ?>
26
+
27
+ <img class='wafs_tip' src='<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png' height='24' width='24' />
28
+
29
+ <div class='wafs_desc'>
30
+ <?php echo $descriptions[ $condition ]; ?>
31
+ </div>
32
+
33
+ <?php endif; ?>
34
+
35
+ </div>
36
+
37
+ </span>
38
+ <?php
39
+
40
+ }
41
+ ?>
includes/admin/settings/conditions/condition-operators.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function wafs_condition_operator( $id, $group = 0, $current_value = '==' ) {
4
+
5
+ $operators = array(
6
+ '==' => __( 'Equal to', 'wafs' ),
7
+ '!=' => __( 'Not equal to', 'wafs' ),
8
+ '>=' => __( 'Greater or equal to', 'wafs' ),
9
+ '<=' => __( 'Less or equal to ', 'wafs' ),
10
+ );
11
+
12
+ $operators = apply_filters( 'wafs_operators', $operators );
13
+
14
+ ?>
15
+
16
+ <span class='wafs-operator-wrap wafs-operator-wrap-<?php echo $id; ?>'>
17
+
18
+ <select id='' class='wafs-operator' name='_wafs_shipping_method_conditions[<?php echo $group; ?>][<?php echo $id; ?>][operator]'>
19
+
20
+ <?php
21
+ foreach ( $operators as $key => $value ) :
22
+ $selected = ( $key == $current_value ) ? "SELECTED" : null;
23
+ ?>
24
+ <option value='<?php echo $key; ?>' <?php echo $selected; ?>><?php echo $value; ?></option>
25
+ <?php
26
+ endforeach;
27
+ ?>
28
+
29
+ </select>
30
+
31
+ </span>
32
+
33
+ <?php
34
+
35
+ }
36
+
37
+ ?>
includes/admin/settings/conditions/condition-values.php ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function wafs_condition_values( $id, $group = 0, $condition = 'subtotal', $current_value = '' ) {
4
+
5
+ global $woocommerce;
6
+
7
+ switch ( $condition ) :
8
+
9
+ default:
10
+ case 'subtotal' :
11
+
12
+ $values['field'] = 'number';
13
+
14
+ break;
15
+
16
+ case 'subtotal_ex_tax' :
17
+
18
+ $values['field'] = 'number';
19
+
20
+ break;
21
+
22
+ case 'tax' :
23
+
24
+ $values['field'] = 'number';
25
+
26
+ break;
27
+
28
+ case 'quantity' :
29
+
30
+ $values['field'] = 'number';
31
+
32
+ break;
33
+
34
+ case 'contains_product' :
35
+
36
+ $values['field'] = 'select';
37
+
38
+ $products = get_posts( array( 'posts_per_page' => '-1', 'post_type' => 'product', 'order' => 'asc', 'orderby' => 'title' ) );
39
+ foreach ( $products as $product ) :
40
+ $values['values'][$product->ID ] = $product->post_title;
41
+ endforeach;
42
+
43
+ break;
44
+
45
+ case 'coupon' :
46
+
47
+ $values['field'] = 'text';
48
+
49
+ break;
50
+
51
+ /**
52
+ * User details
53
+ */
54
+
55
+ case 'zipcode' :
56
+
57
+ $values['field'] = 'text';
58
+
59
+ break;
60
+
61
+ case 'city' :
62
+
63
+ $values['field'] = 'text';
64
+
65
+ break;
66
+
67
+ case 'state' :
68
+
69
+ $values['field'] = 'select';
70
+ $values['values'] = $woocommerce->countries->get_states( 'US' );
71
+
72
+ break;
73
+
74
+ case 'country' :
75
+
76
+ $values['field'] = 'select';
77
+ $values['values'] = $woocommerce->countries->get_allowed_countries();
78
+
79
+ break;
80
+
81
+ case 'role' :
82
+
83
+ $values['field'] = 'select';
84
+ $roles = array_keys( get_editable_roles() );
85
+ $values['values'] = array_combine( $roles, $roles );
86
+
87
+ break;
88
+
89
+ /**
90
+ * Product
91
+ */
92
+
93
+ case 'width' :
94
+
95
+ $values['field'] = 'text';
96
+
97
+ break;
98
+
99
+
100
+ case 'height' :
101
+
102
+ $values['field'] = 'text';
103
+
104
+ break;
105
+
106
+
107
+ case 'length' :
108
+
109
+ $values['field'] = 'text';
110
+
111
+ break;
112
+
113
+ case 'weight' :
114
+
115
+ $values['field'] = 'text';
116
+
117
+ break;
118
+
119
+ case 'stock' :
120
+
121
+ $values['field'] = 'text';
122
+
123
+ break;
124
+
125
+ case 'stock_status' :
126
+
127
+ $values['field'] = 'select';
128
+ $values['values'] = array(
129
+ 'instock' => __( 'In stock', 'wafs' ),
130
+ 'outofstock' => __( 'Out of stock', 'wafs' ),
131
+ );
132
+
133
+ break;
134
+
135
+ case 'backorder' :
136
+
137
+ $values['backorder'] = 'select';
138
+ $values['values'] = array(
139
+ 'no' => __( 'Do not allow', 'woocommerce' ),
140
+ 'notify' => __( 'Allow, but notify customer', 'woocommerce' ),
141
+ 'yes' => __( 'Allow', 'woocommerce' )
142
+ );
143
+
144
+ break;
145
+
146
+ case 'category' :
147
+
148
+ $values['field'] = 'select';
149
+
150
+ $categories = get_terms( 'product_cat', array( 'hide_empty' => false ) );
151
+ foreach ( $categories as $category ) :
152
+ $values['values'][ $category->slug ] = $category->name;
153
+ endforeach;
154
+
155
+ break;
156
+
157
+
158
+ endswitch;
159
+ ?>
160
+
161
+ <span class='wafs-value-wrap wafs-value-wrap-<?php echo $id; ?>'>
162
+
163
+ <?php
164
+ switch ( $values['field'] ) :
165
+
166
+ case 'text' :
167
+ ?>
168
+ <input type='text' class='wafs-value' name='_wafs_shipping_method_conditions[<?php echo $group; ?>][<?php echo $id; ?>][value]'
169
+ placeholder='<?php echo $values['placeholder']; ?>' value='<?php echo $current_value; ?>'>
170
+ <?php
171
+ break;
172
+
173
+ case 'number' :
174
+ ?>
175
+ <input type='text' class='wafs-value' name='_wafs_shipping_method_conditions[<?php echo $group; ?>][<?php echo $id; ?>][value]'
176
+ min='<?php echo $values['min']; ?>' max='<?php echo $values['max']; ?>' placeholder='<?php echo $values['placeholder']; ?>'
177
+ value='<?php echo $current_value; ?>'>
178
+ <?php
179
+ break;
180
+
181
+ default :
182
+ case 'select' :
183
+ ?><select class='wafs-value' name='_wafs_shipping_method_conditions[<?php echo $group; ?>][<?php echo $id; ?>][value]'><?php
184
+ foreach ( $values['values'] as $key => $value ) :
185
+ $selected = ( $key == $current_value ) ? 'SELECTED' : null;
186
+ ?><option value='<?php echo $key; ?>' <?php echo $selected; ?>><?php echo $value; ?></option><?php
187
+ endforeach;
188
+ ?></select><?php
189
+ break;
190
+
191
+ endswitch;
192
+
193
+ ?>
194
+
195
+ </span>
196
+
197
+ <?php
198
+
199
+ }
200
+
201
+ ?>
includes/admin/settings/meta-box-conditions.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WAFS meta box conditions
4
+ *
5
+ * Display the shipping conditions in the meta box
6
+ *
7
+ * @author Jeroen Sormani
8
+ * @package WooCommerce Advanced Free Shipping
9
+ * @version 1.0.0
10
+ */
11
+
12
+ wp_nonce_field( 'wafs_conditions_meta_box', 'wafs_conditions_meta_box_nonce' );
13
+
14
+ global $post;
15
+ $conditions = get_post_meta( $post->ID, '_wafs_shipping_method_conditions', true );
16
+
17
+ ?>
18
+ <div class='wafs wafs_conditions wafs_meta_box wafs_conditions_meta_box'>
19
+
20
+ <p><strong><?php _e( 'Match all of the following rules to allow free shipping:', 'wafs' ); ?></strong></p>
21
+
22
+ <?php
23
+ if ( !empty( $conditions ) ) :
24
+
25
+ foreach ( $conditions as $condition_group => $conditions ) :
26
+ ?>
27
+ <div class='condition-group condition-group-<?php echo $condition_group; ?>' data-group='<?php echo $condition_group; ?>'>
28
+
29
+ <p class='or_match'><?php _e( 'Or match all of the following rules to allow free shipping:', 'wafs' );?></p>
30
+ <?php
31
+ foreach ( $conditions as $condition_id => $condition ) :
32
+
33
+ new Wafs_Condition( $condition_id, $condition_group, $condition['condition'], $condition['operator'], $condition['value'] );
34
+
35
+ endforeach;
36
+ ?>
37
+ </div>
38
+
39
+ <p><strong><?php _e( 'Or', 'wafs' ); ?></strong></p>
40
+ <?php
41
+ endforeach;
42
+
43
+ else :
44
+
45
+ ?><div class='condition-group condition-group-0' data-group='0'><?php
46
+ new Wafs_Condition();
47
+ ?></div><?php
48
+
49
+ endif;
50
+ ?>
51
+
52
+ </div>
53
+
54
+ <a class='button condition-group-add' href='javascript:void(0);'><?php _e( 'Add \'Or\' group', 'wafs' ); ?></a>
includes/admin/settings/meta-box-settings.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WAFS meta box settings
4
+ *
5
+ * Display the shipping settings in the meta box
6
+ *
7
+ * @author Jeroen Sormani
8
+ * @package WooCommerce Advanced Free Shipping
9
+ * @version 1.0.0
10
+ */
11
+
12
+ wp_nonce_field( 'wafs_settings_meta_box', 'wafs_settings_meta_box_nonce' );
13
+
14
+ global $post;
15
+ $settings = get_post_meta( $post->ID, '_wafs_shipping_method' );
16
+ ?>
17
+ <div class='wafs wafs_settings wafs_meta_box wafs_settings_meta_box'>
18
+
19
+ <p class='wafs-option'>
20
+
21
+ <label for='shipping_title'><?php _e( 'Shipping title', 'wafs' ); ?></label>
22
+ <input type='text' class='' id='shipping_title' name='_wafs_shipping_method[shipping_title]'
23
+ value='<?php echo $settings[0]['shipping_title']; ?>' placeholder='<?php _e( 'e.g. Free Shipping', 'wafs' ); ?>'>
24
+
25
+ </p>
26
+
27
+
28
+ </div>
29
+ <?php
30
+
31
+ ?>
includes/admin/views/conditions-table.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Conditions table
4
+ *
5
+ * Display table with all the user configured Free shipping conditions
6
+ *
7
+ * @author Jeroen Sormani
8
+ * @package WooCommerce Advanced Free Shipping
9
+ * @version 1.0.0
10
+ */
11
+ $method_conditions = get_posts( array( 'posts_per_page' => '-1', 'post_type' => 'wafs' ) );
12
+ ?>
13
+ <tr valign="top">
14
+ <th scope="row" class="titledesc">
15
+ <?php _e( 'Method conditions', 'wafs' ); ?>:<br />
16
+ <small>Read more</small>
17
+ </th>
18
+ <td class="forminp" id="<?php echo $this->id; ?>_flat_rates">
19
+
20
+ <table class='wp-list-table wafs-table widefat'>
21
+ <thead>
22
+ <tr>
23
+ <th style='padding-left: 10px;'><?php _e( 'Title', 'wafs' ); ?></th>
24
+ <th><?php _e( 'Shipping title', 'wafs' ); ?></th>
25
+ <th><?php _e( 'Condition groups', 'wafs' ); ?></th>
26
+ <th><?php _e( 'Author', 'wafs' ); ?></th>
27
+ </tr>
28
+ </thead>
29
+ <tbody>
30
+ <?php
31
+ foreach ( $method_conditions as $method_condition ) :
32
+ $method_details = get_post_meta( $method_condition->ID, '_wafs_shipping_method', true );
33
+ $conditions = get_post_meta( $method_condition->ID, '_wafs_shipping_method_conditions', true );
34
+ ?>
35
+ <tr>
36
+ <td>
37
+ <strong>
38
+ <a href='<?php echo get_edit_post_link( $method_condition->ID ); ?>' class='row-title' title='<?php _e( 'Edit Method', 'wafs' ); ?>'>
39
+ <?php echo $method_condition->post_title; echo empty( $method_condition->post_title) ? __( 'Untitled', 'wafs' ) : null; ?>
40
+ </a>
41
+ </strong>
42
+ <div class='row-actions'>
43
+ <span class='edit'>
44
+ <a href='<?php echo get_edit_post_link( $method_condition->ID ); ?>' title='<?php _e( 'Edit Method', 'wafs' ); ?>'>
45
+ <?php _e( 'Edit', 'wafs' ); ?>
46
+ </a>
47
+ |
48
+ </span>
49
+ <span class='trash'>
50
+ <a href='<?php echo get_delete_post_link( $method_condition->ID ); ?>' title='<?php _e( 'Delete Method', 'wafs' ); ?>'>
51
+ <?php _e( 'Delete', 'wafs' ); ?>
52
+ </a>
53
+ </span>
54
+ </div>
55
+ </td>
56
+ <td><?php echo empty( $method_details['shipping_title'] ) ? __( 'Free Shipping', 'wafs') : $method_details['shipping_title']; ?></td>
57
+ <td><?php echo count( $conditions ); ?></td>
58
+ <td><?php echo get_the_author_meta( 'display_name', $method_condition->post_author ); ?></a>
59
+ </td>
60
+ </tr>
61
+ <?php
62
+ endforeach;
63
+
64
+ if ( empty( $method_conditions ) ) :
65
+ ?>
66
+ <tr>
67
+ <td colspan='2'><?php _e( 'There are no Free Shipping conditions. Yet...', 'wafs' ); ?></td>
68
+ </tr>
69
+ <?php
70
+ endif;
71
+ ?>
72
+ </tbody>
73
+ <tfoot>
74
+ <tr>
75
+ <th colspan='4' style='padding-left: 10px;'>
76
+ <a href='<?php echo admin_url( 'post-new.php?post_type=wafs' ); ?>' class='add button'><?php _e( 'Add Free Shipping Method', 'wapl' ); ?></a>
77
+ </th>
78
+ </tr>
79
+ </tfoot>
80
+ </table>
81
+ </td>
82
+ </tr>
includes/class-wafs-ajax.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Wafs_post_type
4
+ *
5
+ * Initialize the WAFS post type
6
+ *
7
+ * @class Wafs_post_type
8
+ * @author Jeroen Sormani
9
+ * @package WooCommerce Advanced Free Shipping
10
+ * @version 1.0.0
11
+ */
12
+ class Wafs_Ajax {
13
+
14
+
15
+ /* Construct.
16
+ *
17
+ * Add ajax actions in order to work.
18
+ */
19
+ public function __construct() {
20
+
21
+ // Add elements
22
+ add_action( 'wp_ajax_wafs_add_condition', array( $this, 'wafs_add_condition' ) );
23
+ add_action( 'wp_ajax_wafs_add_condition_group', array( $this, 'wafs_add_condition_group' ) );
24
+
25
+ // Update elements
26
+ add_action( 'wp_ajax_wafs_update_condition_value', array( $this, 'wafs_update_condition_value' ) );
27
+ add_action( 'wp_ajax_wafs_update_condition_description', array( $this, 'wafs_update_condition_description' ) );
28
+
29
+ }
30
+
31
+ /*
32
+ * Render new condition
33
+ */
34
+ public function wafs_add_condition() {
35
+
36
+ new Wafs_Condition( null, $_POST['group'] );
37
+ die();
38
+
39
+ }
40
+
41
+ /*
42
+ * Render new condition group.
43
+ */
44
+ public function wafs_add_condition_group() {
45
+ ?>
46
+ <div class='condition-group condition-group-<?php echo $_POST['group']; ?>' data-group='<?php echo $_POST['group']; ?>'>
47
+
48
+ <p class='or_match'><?php _e( 'Or match all of the following rules to allow free shipping:', 'wafs' );?></p>
49
+ <?php
50
+ new Wafs_Condition( null, $_POST['group'] );
51
+ ?>
52
+
53
+ </div>
54
+
55
+ <p><strong><?php _e( 'Or', 'wafs' ); ?></strong></p>
56
+
57
+ <?php
58
+ die();
59
+ }
60
+
61
+ /* Update condition values.
62
+ *
63
+ * Retreive and render the new condition values according to the condition key
64
+ */
65
+ public function wafs_update_condition_value() {
66
+
67
+ wafs_condition_values( $_POST['id'], $_POST['group'], $_POST['condition'] );
68
+ die();
69
+
70
+ }
71
+
72
+ /* Update condition description
73
+ *
74
+ * Render the corresponding description for the condition key
75
+ */
76
+ public function wafs_update_condition_description() {
77
+
78
+ wafs_condition_description( $_POST['condition'] );
79
+ die();
80
+
81
+ }
82
+
83
+
84
+ }
85
+ new Wafs_Ajax();
includes/class-wafs-match-conditions.php ADDED
@@ -0,0 +1,664 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Wafs_Match_Conditions
4
+ *
5
+ * The WAFS Match Conditions class handles the matching rules for Free Shipping
6
+ *
7
+ * @class Wapl_Conditions
8
+ * @author Jeroen Sormani
9
+ * @package WooCommerce Advanced Product Labels
10
+ * @version 1.0.0
11
+ */
12
+ class Wafs_Match_Conditions {
13
+
14
+
15
+ /**
16
+ * __construct functon.
17
+ */
18
+ public function __construct() {
19
+
20
+ global $woocommerce;
21
+
22
+ add_action( 'wafs_match_condition_subtotal', array( $this, 'wafs_match_condition_subtotal' ), 10, 3 );
23
+ add_action( 'wafs_match_condition_subtotal_ex_tax', array( $this, 'wafs_match_condition_subtotal_ex_tax' ), 10, 3 );
24
+ add_action( 'wafs_match_condition_tax', array( $this, 'wafs_match_condition_tax' ), 10, 3 );
25
+ add_action( 'wafs_match_condition_quantity', array( $this, 'wafs_match_condition_quantity' ), 10, 3 );
26
+ add_action( 'wafs_match_condition_contains_product', array( $this, 'wafs_match_condition_contains_product' ), 10, 3 );
27
+ add_action( 'wafs_match_condition_coupon', array( $this, 'wafs_match_condition_coupon' ), 10, 3 );
28
+
29
+ add_action( 'wafs_match_condition_zipcode', array( $this, 'wafs_match_condition_zipcode' ), 10, 3 );
30
+ add_action( 'wafs_match_condition_city', array( $this, 'wafs_match_condition_city' ), 10, 3 );
31
+ add_action( 'wafs_match_condition_state', array( $this, 'wafs_match_condition_state' ), 10, 3 );
32
+ add_action( 'wafs_match_condition_country', array( $this, 'wafs_match_condition_country' ), 10, 3 );
33
+ add_action( 'wafs_match_condition_role', array( $this, 'wafs_match_condition_role' ), 10, 3 );
34
+
35
+ add_action( 'wafs_match_condition_width', array( $this, 'wafs_match_condition_width' ), 10, 3 );
36
+ add_action( 'wafs_match_condition_height', array( $this, 'wafs_match_condition_height' ), 10, 3 );
37
+ add_action( 'wafs_match_condition_length', array( $this, 'wafs_match_condition_length' ), 10, 3 );
38
+ add_action( 'wafs_match_condition_weight', array( $this, 'wafs_match_condition_weight' ), 10, 3 );
39
+ add_action( 'wafs_match_condition_stock', array( $this, 'wafs_match_condition_stock' ), 10, 3 );
40
+ add_action( 'wafs_match_condition_stock_status', array( $this, 'wafs_match_condition_stock_status' ), 10, 3 );
41
+ add_action( 'wafs_match_condition_backorder', array( $this, 'wafs_match_condition_backorder' ), 10, 3 );
42
+ add_action( 'wafs_match_condition_category', array( $this, 'wafs_match_condition_category' ), 10, 3 );
43
+
44
+ }
45
+
46
+
47
+ /* Match subtotal
48
+ *
49
+ * @param bool $match
50
+ * @param string $operator
51
+ * @param mixed $value
52
+ * @return bool
53
+ */
54
+ public function wafs_match_condition_subtotal( $match, $operator, $value ) {
55
+
56
+ global $woocommerce;
57
+
58
+ if ( ! isset( $woocommerce->cart ) ) return;
59
+
60
+ if ( '==' == $operator ) :
61
+ $match = ( $woocommerce->cart->subtotal == $value );
62
+ elseif ( '!=' == $operator ) :
63
+ $match = ( $woocommerce->cart->subtotal != $value );
64
+ elseif ( '>=' == $operator ) :
65
+ $match = ( $woocommerce->cart->subtotal >= $value );
66
+ elseif ( '<=' == $operator ) :
67
+ $match = ( $woocommerce->cart->subtotal <= $value );
68
+ endif;
69
+
70
+ return $match;
71
+
72
+ }
73
+
74
+
75
+ /* Match subtotal excluding taxes
76
+ *
77
+ * @param bool $match
78
+ * @param string $operator
79
+ * @param mixed $value
80
+ * @return bool
81
+ */
82
+ public function wafs_match_condition_subtotal_ex_tax( $match, $operator, $value ) {
83
+
84
+ global $woocommerce;
85
+
86
+ if ( ! isset( $woocommerce->cart ) ) return;
87
+
88
+ if ( '==' == $operator ) :
89
+ $match = ( $woocommerce->cart->subtotal_ex_tax == $value );
90
+ elseif ( '!=' == $operator ) :
91
+ $match = ( $woocommerce->cart->subtotal_ex_tax != $value );
92
+ elseif ( '>=' == $operator ) :
93
+ $match = ( $woocommerce->cart->subtotal_ex_tax >= $value );
94
+ elseif ( '<=' == $operator ) :
95
+ $match = ( $woocommerce->cart->subtotal_ex_tax <= $value );
96
+ endif;
97
+
98
+ return $match;
99
+
100
+ }
101
+
102
+
103
+ /* Match taxes
104
+ *
105
+ * @param bool $match
106
+ * @param string $operator
107
+ * @param mixed $value
108
+ * @return bool
109
+ */
110
+ public function wafs_match_condition_tax( $match, $operator, $value ) {
111
+
112
+ global $woocommerce;
113
+
114
+ if ( ! isset( $woocommerce->cart ) ) return;
115
+
116
+ $taxes = array_sum( (array) $woocommerce->cart->taxes );
117
+
118
+ if ( '==' == $operator ) :
119
+ $match = ( $taxes == $value );
120
+ elseif ( '!=' == $operator ) :
121
+ $match = ( $taxes != $value );
122
+ elseif ( '>=' == $operator ) :
123
+ $match = ( $taxes >= $value );
124
+ elseif ( '<=' == $operator ) :
125
+ $match = ( $taxes <= $value );
126
+ endif;
127
+
128
+ return $match;
129
+
130
+ }
131
+
132
+
133
+ /* Match quantity
134
+ *
135
+ * @param bool $match
136
+ * @param string $operator
137
+ * @param mixed $value
138
+ * @return bool
139
+ */
140
+ public function wafs_match_condition_quantity( $match, $operator, $value ) {
141
+
142
+ global $woocommerce;
143
+
144
+ if ( ! isset( $woocommerce->cart ) ) return;
145
+
146
+ if ( '==' == $operator ) :
147
+ $match = ( $woocommerce->cart->cart_contents_count == $value );
148
+ elseif ( '!=' == $operator ) :
149
+ $match = ( $woocommerce->cart->cart_contents_count != $value );
150
+ elseif ( '>=' == $operator ) :
151
+ $match = ( $woocommerce->cart->cart_contents_count >= $value );
152
+ elseif ( '<=' == $operator ) :
153
+ $match = ( $woocommerce->cart->cart_contents_count <= $value );
154
+ endif;
155
+
156
+ return $match;
157
+
158
+ }
159
+
160
+
161
+ /* Match quantity
162
+ *
163
+ * @param bool $match
164
+ * @param string $operator
165
+ * @param mixed $value
166
+ * @return bool
167
+ */
168
+ public function wafs_match_condition_contains_product( $match, $operator, $value ) {
169
+
170
+ global $woocommerce;
171
+
172
+ if ( ! isset( $woocommerce->cart ) || empty( $woocommerce->cart->cart_contents ) ) return;
173
+
174
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
175
+ $product_ids[] = $product['product_id'];
176
+ endforeach;
177
+
178
+ if ( '==' == $operator ) :
179
+ $match = ( in_array( $value, $product_ids ) );
180
+ elseif ( '!=' == $operator ) :
181
+ $match = ( ! in_array( $value, $product_ids ) );
182
+ endif;
183
+
184
+ return $match;
185
+
186
+ }
187
+
188
+
189
+ /* Match coupon
190
+ *
191
+ * @param bool $match
192
+ * @param string $operator
193
+ * @param mixed $value
194
+ * @return bool
195
+ */
196
+ public function wafs_match_condition_coupon( $match, $operator, $value ) {
197
+
198
+ global $woocommerce;
199
+
200
+ if ( ! isset( $woocommerce->cart ) ) return;
201
+
202
+ if ( '==' == $operator ) :
203
+ $match = ( in_array( $value, $woocommerce->cart->applied_coupons ) );
204
+ elseif ( '!=' == $operator ) :
205
+ $match = ( ! in_array( $value, $woocommerce->cart->applied_coupons ) );
206
+ endif;
207
+
208
+ return $match;
209
+
210
+ }
211
+
212
+
213
+ /***************************
214
+ *
215
+ * User details
216
+ *
217
+ ***************************
218
+ */
219
+
220
+
221
+ /* Match zipcode
222
+ *
223
+ * @param bool $match
224
+ * @param string $operator
225
+ * @param mixed $value
226
+ * @return bool
227
+ */
228
+ public function wafs_match_condition_zipcode( $match, $operator, $value ) {
229
+
230
+ global $woocommerce;
231
+
232
+ if ( !isset( $woocommerce->customer ) ) return;
233
+
234
+ if ( '==' == $operator ) :
235
+ $match = ( $woocommerce->customer->get_shipping_postcode() == $value );
236
+ elseif ( '!=' == $operator ) :
237
+ $match = ( $woocommerce->customer->get_shipping_postcode() != $value );
238
+ elseif ( '>=' == $operator ) :
239
+ $match = ( $woocommerce->customer->get_shipping_postcode() >= $value );
240
+ elseif ( '<=' == $operator ) :
241
+ $match = ( $woocommerce->customer->get_shipping_postcode() <= $value );
242
+ endif;
243
+
244
+ return $match;
245
+
246
+ }
247
+
248
+
249
+ /* Match city
250
+ *
251
+ * @param bool $match
252
+ * @param string $operator
253
+ * @param mixed $value
254
+ * @return bool
255
+ */
256
+ public function wafs_match_condition_city( $match, $operator, $value ) {
257
+
258
+ global $woocommerce;
259
+
260
+ if ( ! isset( $woocommerce->customer ) ) return;
261
+
262
+ if ( '==' == $operator ) :
263
+ $match = ( preg_match( "/^$value$/i", $woocommerce->customer->get_shipping_city() ) );
264
+ elseif ( '!=' == $operator ) :
265
+ $match = ( ! preg_match( "/^$value$/i", $woocommerce->customer->get_shipping_city() ) );
266
+ endif;
267
+
268
+ return $match;
269
+
270
+ }
271
+
272
+
273
+ /* Match state
274
+ *
275
+ * @param bool $match
276
+ * @param string $operator
277
+ * @param mixed $value
278
+ * @return bool
279
+ */
280
+ public function wafs_match_condition_state( $match, $operator, $value ) {
281
+
282
+ global $woocommerce;
283
+
284
+ if ( ! isset( $woocommerce->customer ) ) return;
285
+
286
+ if ( '==' == $operator ) :
287
+ $match = ( $woocommerce->customer->get_shipping_state() == $value );
288
+ elseif ( '!=' == $operator ) :
289
+ $match = ( $woocommerce->customer->get_shipping_state() != $value );
290
+ endif;
291
+
292
+ return $match;
293
+
294
+ }
295
+
296
+
297
+ /* Match city
298
+ *
299
+ * @param bool $match
300
+ * @param string $operator
301
+ * @param mixed $value
302
+ * @return bool
303
+ */
304
+ public function wafs_match_condition_country( $match, $operator, $value ) {
305
+
306
+ global $woocommerce;
307
+
308
+ if ( ! isset( $woocommerce->customer ) ) return;
309
+
310
+ if ( '==' == $operator ) :
311
+ $match = ( preg_match( "/^$value$/i", $woocommerce->customer->get_shipping_country() ) );
312
+ elseif ( '!=' == $operator ) :
313
+ $match = ( ! preg_match( "/^$value$/i", $woocommerce->customer->get_shipping_country() ) );
314
+ endif;
315
+
316
+ return $match;
317
+
318
+ }
319
+
320
+
321
+ /* Match role
322
+ *
323
+ * @param bool $match
324
+ * @param string $operator
325
+ * @param mixed $value
326
+ * @return bool
327
+ */
328
+ public function wafs_match_condition_role( $match, $operator, $value ) {
329
+
330
+ global $woocommerce, $current_user;
331
+
332
+ if ( '==' == $operator ) :
333
+ $match = ( array_key_exists( $value, $current_user->caps ) );
334
+ elseif ( '!=' == $operator ) :
335
+ $match = ( ! array_key_exists( $value, $current_user->caps ) );
336
+ endif;
337
+
338
+ return $match;
339
+
340
+ }
341
+
342
+
343
+ /***************************
344
+ *
345
+ * Product
346
+ *
347
+ ***************************
348
+ */
349
+
350
+
351
+ /* Match width
352
+ *
353
+ * Match the user value to the widest product
354
+ *
355
+ * @param bool $match
356
+ * @param string $operator
357
+ * @param mixed $value
358
+ * @return bool
359
+ */
360
+ public function wafs_match_condition_width( $match, $operator, $value ) {
361
+
362
+ global $woocommerce;
363
+
364
+ if ( ! isset( $woocommerce->cart ) || empty( $woocommerce->cart->cart_contents ) ) return;
365
+
366
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
367
+
368
+ if ( true == $product['data']->variation_has_width ) :
369
+ $width[] = ( get_post_meta( $product['data']->variation_id, '_width', true ) );
370
+ else :
371
+ $width[] = ( get_post_meta( $product['product_id'], '_width', true ) );
372
+ endif;
373
+
374
+ endforeach;
375
+
376
+ $max_width = max( (array) $width );
377
+
378
+ if ( '==' == $operator ) :
379
+ $match = ( $max_width == $value );
380
+ elseif ( '!=' == $operator ) :
381
+ $match = ( $max_width != $value );
382
+ elseif ( '>=' == $operator ) :
383
+ $match = ( $max_width >= $value );
384
+ elseif ( '<=' == $operator ) :
385
+ $match = ( $max_width <= $value );
386
+ endif;
387
+
388
+ return $match;
389
+
390
+ }
391
+
392
+
393
+ /* Match height
394
+ *
395
+ * Match the user value to the highest product
396
+ *
397
+ * @param bool $match
398
+ * @param string $operator
399
+ * @param mixed $value
400
+ * @return bool
401
+ */
402
+
403
+ public function wafs_match_condition_height( $match, $operator, $value ) {
404
+
405
+ global $woocommerce;
406
+
407
+ if ( ! isset( $woocommerce->cart ) || empty( $woocommerce->cart->cart_contents ) ) return;
408
+
409
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
410
+
411
+ if ( true == $product['data']->variation_has_height ) :
412
+ $height[] = ( get_post_meta( $product['data']->variation_id, '_height', true ) );
413
+ else :
414
+ $height[] = ( get_post_meta( $product['product_id'], '_height', true ) );
415
+ endif;
416
+
417
+ endforeach;
418
+
419
+ $max_height = max( $height );
420
+
421
+ if ( '==' == $operator ) :
422
+ $match = ( $max_height == $value );
423
+ elseif ( '!=' == $operator ) :
424
+ $match = ( $max_height != $value );
425
+ elseif ( '>=' == $operator ) :
426
+ $match = ( $max_height >= $value );
427
+ elseif ( '<=' == $operator ) :
428
+ $match = ( $max_height <= $value );
429
+ endif;
430
+
431
+ return $match;
432
+
433
+ }
434
+
435
+
436
+ /* Match length
437
+ *
438
+ * Match the user value to the biggest product
439
+ *
440
+ * @param bool $match
441
+ * @param string $operator
442
+ * @param mixed $value
443
+ * @return bool
444
+ */
445
+
446
+ public function wafs_match_condition_length( $match, $operator, $value ) {
447
+
448
+ global $woocommerce;
449
+
450
+ if ( ! isset( $woocommerce->cart ) || empty( $woocommerce->cart->cart_contents ) ) return;
451
+
452
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
453
+
454
+ if ( true == $product['data']->variation_has_length ) :
455
+ $length[] = ( get_post_meta( $product['data']->variation_id, '_length', true ) );
456
+ else :
457
+ $length[] = ( get_post_meta( $product['product_id'], '_length', true ) );
458
+ endif;
459
+
460
+ endforeach;
461
+
462
+ $max_length = max( $length );
463
+
464
+ if ( '==' == $operator ) :
465
+ $match = ( $max_length == $value );
466
+ elseif ( '!=' == $operator ) :
467
+ $match = ( $max_length != $value );
468
+ elseif ( '>=' == $operator ) :
469
+ $match = ( $max_length >= $value );
470
+ elseif ( '<=' == $operator ) :
471
+ $match = ( $max_length <= $value );
472
+ endif;
473
+
474
+ return $match;
475
+
476
+ }
477
+
478
+
479
+ /* Match weight
480
+ *
481
+ * @param bool $match
482
+ * @param string $operator
483
+ * @param mixed $value
484
+ * @return bool
485
+ */
486
+ public function wafs_match_condition_weight( $match, $operator, $value ) {
487
+
488
+ global $woocommerce;
489
+
490
+ if ( ! isset( $woocommerce->cart ) ) return;
491
+
492
+ if ( '==' == $operator ) :
493
+ $match = ( $woocommerce->cart->cart_contents_weight == $value );
494
+ elseif ( '!=' == $operator ) :
495
+ $match = ( $woocommerce->cart->cart_contents_weight != $value );
496
+ elseif ( '>=' == $operator ) :
497
+ $match = ( $woocommerce->cart->cart_contents_weight >= $value );
498
+ elseif ( '<=' == $operator ) :
499
+ $match = ( $woocommerce->cart->cart_contents_weight <= $value );
500
+ endif;
501
+
502
+ return $match;
503
+
504
+ }
505
+
506
+
507
+ /* Match all product stock
508
+ *
509
+ * @param bool $match
510
+ * @param string $operator
511
+ * @param mixed $value
512
+ * @return bool
513
+ */
514
+ public function wafs_match_condition_stock( $match, $operator, $value ) {
515
+
516
+ global $woocommerce;
517
+
518
+ if ( ! isset( $woocommerce->cart ) || empty( $woocommerce->cart->cart_contents ) ) return;
519
+
520
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
521
+
522
+ if ( true == $product['data']->variation_has_stock ) :
523
+ $stock[] = ( get_post_meta( $product['data']->variation_id, '_stock', true ) );
524
+ else :
525
+ $stock[] = ( get_post_meta( $product['product_id'], '_stock', true ) );
526
+ endif;
527
+
528
+ endforeach;
529
+
530
+ $min_stock = min( $stock );
531
+
532
+ if ( '==' == $operator ) :
533
+ $match = ( $min_stock == $value );
534
+ elseif ( '!=' == $operator ) :
535
+ $match = ( $min_stock != $value );
536
+ elseif ( '>=' == $operator ) :
537
+ $match = ( $min_stock >= $value );
538
+ elseif ( '<=' == $operator ) :
539
+ $match = ( $min_stock <= $value );
540
+ endif;
541
+
542
+ return $match;
543
+
544
+ }
545
+
546
+
547
+ /* Match all product stock statusses
548
+ *
549
+ * @param bool $match
550
+ * @param string $operator
551
+ * @param mixed $value
552
+ * @return bool
553
+ */
554
+ public function wafs_match_condition_stock_status( $match, $operator, $value ) {
555
+
556
+ global $woocommerce;
557
+
558
+ if ( ! isset( $woocommerce->cart ) ) return;
559
+
560
+ if ( '==' == $operator ) :
561
+
562
+ $match = true;
563
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
564
+ if ( get_post_meta( $product['product_id'], '_stock_status', true ) != $value )
565
+ $match = false;
566
+ endforeach;
567
+
568
+ elseif ( '!=' == $operator ) :
569
+
570
+ $match = true;
571
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
572
+ if ( get_post_meta( $product['product_id'], '_stock_status', true ) == $value )
573
+ $match = false;
574
+ endforeach;
575
+
576
+ endif;
577
+
578
+ return $match;
579
+
580
+ }
581
+
582
+
583
+ /* Match all products backorder
584
+ *
585
+ * @param bool $match
586
+ * @param string $operator
587
+ * @param mixed $value
588
+ * @return bool
589
+ */
590
+ public function wafs_match_condition_backorder( $match, $operator, $value ) {
591
+
592
+ global $woocommerce;
593
+
594
+ if ( ! isset( $woocommerce->cart ) ) return;
595
+
596
+ $match = true;
597
+
598
+ if ( '==' == $operator ) :
599
+
600
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
601
+ if ( get_post_meta( $product['product_id'], '_backorders', true ) != $value ) :
602
+ $match = false;
603
+ endif;
604
+ endforeach;
605
+
606
+ elseif ( '!=' == $operator ) :
607
+
608
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
609
+ if ( get_post_meta( $product['product_id'], '_backorders', true ) == $value )
610
+ $match = false;
611
+ endforeach;
612
+
613
+ endif;
614
+
615
+ return $match;
616
+
617
+ }
618
+
619
+
620
+ /* Match category
621
+ *
622
+ * @param bool $match
623
+ * @param string $operator
624
+ * @param mixed $value
625
+ * @return bool
626
+ */
627
+ public function wafs_match_condition_category( $match, $operator, $value ) {
628
+
629
+ global $woocommerce;
630
+
631
+ if ( ! isset( $woocommerce->cart ) ) return;
632
+
633
+ $match = true;
634
+
635
+ if ( '==' == $operator ) :
636
+
637
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
638
+
639
+ if ( ! has_term( $value, 'product_cat', $product['product_id'] ) ) :
640
+ $match = false;
641
+ endif;
642
+
643
+ endforeach;
644
+
645
+ elseif ( '!=' == $operator ) :
646
+
647
+ foreach ( $woocommerce->cart->cart_contents as $product ) :
648
+
649
+ if ( has_term( $value, 'product_cat', $post->ID ) ) :
650
+ $match = false;
651
+ endif;
652
+
653
+ endforeach;
654
+
655
+ endif;
656
+
657
+ return $match;
658
+
659
+ }
660
+
661
+ }
662
+ new Wafs_Match_Conditions();
663
+
664
+ ?>
includes/class-wafs-method.php ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! class_exists( 'Wafs_Free_Shipping_Method' ) ) {
4
+
5
+
6
+ class Wafs_Free_Shipping_Method extends WC_Shipping_Method {
7
+
8
+
9
+ /**
10
+ * Constructor for your shipping class
11
+ *
12
+ * @access public
13
+ * @return void
14
+ */
15
+ public function __construct() {
16
+
17
+ $this->id = 'advanced_free_shipping';
18
+ $this->title = __( 'Free Shipping <small>(may change at user configuration)</small>', 'wafs' );
19
+ $this->method_title = __( 'Advanced Free Shipping', 'wafs' );
20
+ $this->method_description = __( 'Configure WooCommerce Advanced Free Shipping' ); //
21
+
22
+ $this->matched_methods = $this->wafs_match_methods();
23
+
24
+ $this->init();
25
+
26
+ }
27
+
28
+
29
+ /**
30
+ * Init your settings
31
+ *
32
+ * @access public
33
+ * @return void
34
+ */
35
+ function init() {
36
+
37
+ $this->init_form_fields();
38
+ $this->init_settings();
39
+
40
+ $this->enabled = $this->get_option( 'enabled' );
41
+ $this->hide_shipping = $this->get_option( 'hide_other_shipping_when_available' );
42
+
43
+ // Save settings in admin if you have any defined
44
+ add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
45
+
46
+ // Hide shipping methods
47
+ add_filter( 'woocommerce_available_shipping_methods', array( $this, 'hide_all_shipping_when_free_is_available' ) );
48
+
49
+ }
50
+
51
+
52
+ /**
53
+ * Match methods
54
+ *
55
+ * Checks if methods matches conditions
56
+ *
57
+ * @access public
58
+ * @return void
59
+ */
60
+ public function wafs_match_methods() {
61
+
62
+ $methods = get_posts( array( 'posts_per_page' => '-1', 'post_type' => 'wafs' ) );
63
+
64
+ foreach ( $methods as $method ) :
65
+
66
+ $condition_groups = get_post_meta( $method->ID, '_wafs_shipping_method_conditions', true );
67
+
68
+ // Check if method conditions match
69
+ $match = $this->wafs_match_conditions( $condition_groups );
70
+
71
+ // Add (single) match to parameter
72
+ if ( true == $match ) :
73
+ $matched_methods = $method->ID;
74
+ endif;
75
+
76
+ endforeach;
77
+
78
+ return $matched_methods;
79
+
80
+ }
81
+
82
+
83
+ /**
84
+ * Match conditions
85
+ *
86
+ * @access public
87
+ * @return void
88
+ */
89
+ public function wafs_match_conditions( $condition_groups = array() ) {
90
+
91
+ if ( empty( $condition_groups ) ) return false;
92
+
93
+ foreach ( $condition_groups as $condition_group => $conditions ) :
94
+
95
+ $match_condition_group = true;
96
+
97
+ foreach ( $conditions as $condition ) :
98
+
99
+ $match = apply_filters( 'wafs_match_condition_' . $condition['condition'], false, $condition['operator'], $condition['value'] );
100
+
101
+ if ( false == $match ) :
102
+ $match_condition_group = false;
103
+ endif;
104
+
105
+ endforeach;
106
+
107
+ // return true if one condition group matches
108
+ if ( true == $match_condition_group ) :
109
+ return true;
110
+ endif;
111
+
112
+ endforeach;
113
+
114
+ return false;
115
+
116
+ }
117
+
118
+
119
+ /**
120
+ * Init form fields
121
+ *
122
+ * @access public
123
+ * @return void
124
+ */
125
+ public function init_form_fields() {
126
+
127
+ $this->form_fields = array(
128
+ 'enabled' => array(
129
+ 'title' => __( 'Enable/Disable', 'woocommerce' ),
130
+ 'type' => 'checkbox',
131
+ 'label' => __( 'Enable Advanced Free Shipping', 'wafs' ),
132
+ 'default' => 'yes'
133
+ ),
134
+ 'hide_other_shipping_when_available' => array(
135
+ 'title' => __( 'Hide other shipping', 'wafs' ),
136
+ 'type' => 'checkbox',
137
+ 'label' => __( 'Hide other shipping methods when free shipping is available', 'wafs' ),
138
+ 'default' => 'no'
139
+ ),
140
+ 'conditions' => array(
141
+ 'type' => 'conditions_table',
142
+ )
143
+ );
144
+
145
+
146
+ }
147
+
148
+ /* Settings tab table.
149
+ *
150
+ * Load and render the table on the Advanced Free Shipping settings tab.
151
+ *
152
+ * @return string
153
+ */
154
+ public function generate_conditions_table_html() {
155
+
156
+ ob_start();
157
+
158
+ /**
159
+ * Load conditions table file
160
+ */
161
+ require_once plugin_dir_path( __FILE__ ) . 'admin/views/conditions-table.php';
162
+
163
+ return ob_get_clean();
164
+
165
+ }
166
+
167
+
168
+ /**
169
+ * validate_additional_conditions_table_field function.
170
+ *
171
+ * @access public
172
+ * @param mixed $key
173
+ * @return bool
174
+ */
175
+ public function validate_additional_conditions_table_field( $key ) {
176
+ return false;
177
+ }
178
+
179
+
180
+
181
+ /**
182
+ * calculate_shipping function.
183
+ *
184
+ * @access public
185
+ * @param mixed $package
186
+ * @return void
187
+ */
188
+ public function calculate_shipping( $package ) {
189
+
190
+ if ( false == $this->matched_methods || 'no' == $this->enabled ) return;
191
+
192
+ $match_details = get_post_meta( $this->matched_methods, '_wafs_shipping_method', true );
193
+ $label = $match_details['shipping_title'];
194
+ $calc_tax = $match_details['calc_tax'];
195
+
196
+ $rate = array(
197
+ 'id' => $this->id,
198
+ 'label' => ( null == $label ) ? __( 'Free Shipping', 'wafs' ) : $label,
199
+ 'cost' => '0',
200
+ 'calc_tax' => ( null == $calc_tax ) ? 'per_order' : $calc_tax
201
+ );
202
+
203
+ // Register the rate
204
+ $this->add_rate( $rate );
205
+
206
+
207
+ }
208
+
209
+
210
+ /**
211
+ * Hide shipping.
212
+ *
213
+ * Hide Shipping methods when regular or advanced free shipping is available
214
+ *
215
+ * @param array $available_methods
216
+ * @return array
217
+ */
218
+ public function hide_all_shipping_when_free_is_available( $available_methods ) {
219
+
220
+ if ( 'no' == $this->hide_shipping ) return $available_methods;
221
+
222
+ if ( isset( $available_methods['advanced_free_shipping'] ) ) :
223
+
224
+ return array( $available_methods['advanced_free_shipping'] );
225
+
226
+ elseif ( isset( $available_methods['free_shipping'] ) ) :
227
+
228
+ return array( $available_methods['free_shipping'] );
229
+
230
+ else :
231
+
232
+ return $available_methods;
233
+
234
+ endif;
235
+
236
+
237
+ }
238
+
239
+
240
+ }
241
+ $wafs_free_shipping_method = new Wafs_Free_Shipping_Method();
242
+
243
+ }
244
+
245
+
246
+
247
+ ?>
includes/class-wafs-post-type.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Wafs_post_type
4
+ *
5
+ * Initialize the WAFS post type
6
+ *
7
+ * @class Wafs_post_type
8
+ * @author Jeroen Sormani
9
+ * @package WooCommerce Advanced Free Shipping
10
+ * @version 1.0.0
11
+ */
12
+ class Wafs_post_type {
13
+
14
+
15
+ /**
16
+ * __construct functon.
17
+ *
18
+ *
19
+ */
20
+ public function __construct() {
21
+
22
+ $this->wafs_register_post_type();
23
+
24
+ add_action( 'add_meta_boxes', array( $this, 'wafs_post_type_meta_box' ) );
25
+ add_action( 'save_post', array( $this, 'wafs_save_meta' ) );
26
+ add_action( 'save_post', array( $this, 'wafs_save_condition_meta' ) );
27
+
28
+ }
29
+
30
+
31
+ /**
32
+ * __construct functon.
33
+ *
34
+ *
35
+ */
36
+ public function wafs_register_post_type() {
37
+
38
+ $labels = array(
39
+ 'name' => __( 'Advanced Free Shipping methods', 'wapl' ),
40
+ 'singular_name' => __( 'Advanced Free Shipping method', 'wapl' ),
41
+ 'add_new' => __( 'Add New', 'wapl' ),
42
+ 'add_new_item' => __( 'Add New Advanced Free Shipping method' , 'wapl' ),
43
+ 'edit_item' => __( 'Edit Advanced Free Shipping method' , 'wapl' ),
44
+ 'new_item' => __( 'New Advanced Free Shipping method' , 'wapl' ),
45
+ 'view_item' => __( 'View Advanced Free Shipping method', 'wapl' ),
46
+ 'search_items' => __( 'Search Advanced Free Shipping methods', 'wapl' ),
47
+ 'not_found' => __( 'No Advanced Free Shipping methods', 'wapl' ),
48
+ 'not_found_in_trash' => __( 'No Advanced Free Shipping methods found in Trash', 'wapl' ),
49
+ );
50
+
51
+ register_post_type( 'wafs', array(
52
+ 'label' => 'wafs',
53
+ 'show_ui' => true,
54
+ 'show_in_menu' => false,
55
+ 'capability_type' => 'post',
56
+ 'map_meta_cap' => true,
57
+ 'rewrite' => array( 'slug' => 'wafs', 'with_front' => true ),
58
+ '_builtin' => false,
59
+ 'query_var' => true,
60
+ 'supports' => array( 'title' ),
61
+ 'labels' => $labels,
62
+ ) );
63
+
64
+ }
65
+
66
+
67
+ /**
68
+ * wafs_post_type_meta_box functon.
69
+ *
70
+ *
71
+ */
72
+ public function wafs_post_type_meta_box() {
73
+
74
+ add_meta_box( 'wafs_conditions', __( 'Advanced Free Shipping conditions', 'wafs' ), array( $this, 'render_wafs_conditions' ), 'wafs', 'normal' );
75
+ add_meta_box( 'wafs_settings', __( 'Shipping settings', 'wafs' ), array( $this, 'render_wafs_settings' ), 'wafs', 'normal' );
76
+
77
+ }
78
+
79
+
80
+ /**
81
+ * wafs_conditions_callback functon.
82
+ *
83
+ *
84
+ */
85
+ public function render_wafs_conditions() {
86
+
87
+ /**
88
+ * Load meta box conditions view
89
+ */
90
+ require_once plugin_dir_path( __FILE__ ) . 'admin/settings/meta-box-conditions.php';
91
+
92
+ }
93
+
94
+
95
+ /**
96
+ * wafs_settings_callback functon.
97
+ *
98
+ *
99
+ */
100
+ public function render_wafs_settings() {
101
+
102
+ /**
103
+ * Load meta box settings view
104
+ */
105
+ require_once plugin_dir_path( __FILE__ ) . 'admin/settings/meta-box-settings.php';
106
+
107
+ }
108
+
109
+
110
+ /**
111
+ * wafs_save_meta functon.
112
+ *
113
+ * Validate and save post meta
114
+ */
115
+ public function wafs_save_meta( $post_id ) {
116
+
117
+ if ( !isset( $_POST['wafs_settings_meta_box_nonce'] ) )
118
+ return $post_id;
119
+
120
+ $nonce = $_POST['wafs_settings_meta_box_nonce'];
121
+
122
+ if ( ! wp_verify_nonce( $nonce, 'wafs_settings_meta_box' ) )
123
+ return $post_id;
124
+
125
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
126
+ return $post_id;
127
+
128
+ if ( ! current_user_can( 'manage_woocommerce' ) )
129
+ return $post_id;
130
+
131
+ $shipping_method = $_POST['_wafs_shipping_method'];
132
+
133
+ update_post_meta( $post_id, '_wafs_shipping_method', $shipping_method );
134
+
135
+ }
136
+
137
+
138
+ /**
139
+ * wafs_save_condition_meta functon.
140
+ *
141
+ * Validate and save post meta
142
+ */
143
+ public function wafs_save_condition_meta( $post_id ) {
144
+
145
+ if ( !isset( $_POST['wafs_conditions_meta_box_nonce'] ) )
146
+ return $post_id;
147
+
148
+ $nonce = $_POST['wafs_conditions_meta_box_nonce'];
149
+
150
+ if ( ! wp_verify_nonce( $nonce, 'wafs_conditions_meta_box' ) )
151
+ return $post_id;
152
+
153
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
154
+ return $post_id;
155
+
156
+ if ( ! current_user_can( 'manage_woocommerce' ) )
157
+ return $post_id;
158
+
159
+ $shipping_method_conditions = $_POST['_wafs_shipping_method_conditions'];
160
+
161
+ update_post_meta( $post_id, '_wafs_shipping_method_conditions', $shipping_method_conditions );
162
+
163
+ }
164
+
165
+ }
166
+ $wafs_post_type = new Wafs_post_type();
167
+
168
+ /**
169
+ * Load condition object
170
+ */
171
+ require_once plugin_dir_path( __FILE__ ) . 'admin/settings/conditions/class-wafs-condition.php';
172
+ /**
173
+ * Load ajax methods
174
+ */
175
+ require_once plugin_dir_path( __FILE__ ) . '/class-wafs-ajax.php';
176
+
177
+ ?>
languages/wafs-en_US.mo ADDED
Binary file
languages/wafs-en_US.po ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: WooCommerce Advanced Free Shipping\n"
4
+ "POT-Creation-Date: 2014-04-24 19:17+0100\n"
5
+ "PO-Revision-Date: 2014-04-24 19:18+0100\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: Jeroen Sormani <info@jeroensormani.com>\n"
8
+ "Language: nl_NL\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.5.5\n"
13
+ "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
14
+ "X-Poedit-Basepath: ../\n"
15
+ "X-Poedit-SearchPath-0: ..\n"
16
+
17
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-ajax.php:48
18
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/meta-box-conditions.php:29
19
+ msgid "Or match all of the following rules to allow free shipping:"
20
+ msgstr ""
21
+
22
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-ajax.php:55
23
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/meta-box-conditions.php:39
24
+ msgid "Or"
25
+ msgstr ""
26
+
27
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-method.php:18
28
+ msgid "Advanced Free Shipping"
29
+ msgstr ""
30
+
31
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-method.php:19
32
+ msgid "Configure WooCommerce Advanced Free Shipping"
33
+ msgstr ""
34
+
35
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-method.php:128
36
+ msgid "Enable/Disable"
37
+ msgstr ""
38
+
39
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-method.php:130
40
+ msgid "Enable Advanced Free Shipping"
41
+ msgstr ""
42
+
43
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-method.php:134
44
+ msgid "Hide other shipping"
45
+ msgstr ""
46
+
47
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-method.php:136
48
+ msgid "Hide other shipping methods when free shipping is available"
49
+ msgstr ""
50
+
51
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-method.php:197
52
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:56
53
+ msgid "Free Shipping"
54
+ msgstr ""
55
+
56
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:39
57
+ msgid "Advanced Free Shipping methods"
58
+ msgstr ""
59
+
60
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:40
61
+ msgid "Advanced Free Shipping method"
62
+ msgstr ""
63
+
64
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:41
65
+ msgid "Add New"
66
+ msgstr ""
67
+
68
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:42
69
+ msgid "Add New Advanced Free Shipping method"
70
+ msgstr ""
71
+
72
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:43
73
+ msgid "Edit Advanced Free Shipping method"
74
+ msgstr ""
75
+
76
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:44
77
+ msgid "New Advanced Free Shipping method"
78
+ msgstr ""
79
+
80
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:45
81
+ msgid "View Advanced Free Shipping method"
82
+ msgstr ""
83
+
84
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:46
85
+ msgid "Search Advanced Free Shipping methods"
86
+ msgstr ""
87
+
88
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:47
89
+ msgid "No Advanced Free Shipping methods"
90
+ msgstr ""
91
+
92
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:48
93
+ msgid "No Advanced Free Shipping methods found in Trash"
94
+ msgstr ""
95
+
96
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:74
97
+ msgid "Advanced Free Shipping conditions"
98
+ msgstr ""
99
+
100
+ #: ../woocommerce-advanced-free-shipping/includes/class-wafs-post-type.php:75
101
+ msgid "Shipping settings"
102
+ msgstr ""
103
+
104
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/meta-box-conditions.php:20
105
+ msgid "Match all of the following rules to allow free shipping:"
106
+ msgstr ""
107
+
108
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/meta-box-conditions.php:54
109
+ msgid "Add 'Or' group"
110
+ msgstr ""
111
+
112
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/meta-box-settings.php:21
113
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:24
114
+ msgid "Shipping title"
115
+ msgstr ""
116
+
117
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/meta-box-settings.php:23
118
+ msgid "e.g. Free Shipping"
119
+ msgstr ""
120
+
121
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:6
122
+ msgid "Cart"
123
+ msgstr ""
124
+
125
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:7
126
+ msgid "Subtotal"
127
+ msgstr ""
128
+
129
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:8
130
+ msgid "Subtotal ex. taxes"
131
+ msgstr ""
132
+
133
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:9
134
+ msgid "Tax"
135
+ msgstr ""
136
+
137
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:10
138
+ msgid "Quantity"
139
+ msgstr ""
140
+
141
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:11
142
+ msgid "Contains product"
143
+ msgstr ""
144
+
145
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:12
146
+ msgid "Coupon"
147
+ msgstr ""
148
+
149
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:14
150
+ msgid "User Details"
151
+ msgstr ""
152
+
153
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:15
154
+ msgid "Zipcode"
155
+ msgstr ""
156
+
157
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:16
158
+ msgid "City"
159
+ msgstr ""
160
+
161
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:17
162
+ msgid "Country"
163
+ msgstr ""
164
+
165
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:18
166
+ msgid "User role"
167
+ msgstr ""
168
+
169
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:20
170
+ msgid "Product"
171
+ msgstr ""
172
+
173
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:21
174
+ msgid "Width"
175
+ msgstr ""
176
+
177
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:22
178
+ msgid "Height"
179
+ msgstr ""
180
+
181
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:23
182
+ msgid "Length"
183
+ msgstr ""
184
+
185
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:24
186
+ msgid "Weight"
187
+ msgstr ""
188
+
189
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:25
190
+ msgid "Stock"
191
+ msgstr ""
192
+
193
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:26
194
+ msgid "Stock status"
195
+ msgstr ""
196
+
197
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:27
198
+ msgid "Backorders"
199
+ msgstr ""
200
+
201
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-conditions.php:28
202
+ msgid "Category"
203
+ msgstr ""
204
+
205
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:8
206
+ msgid "Weight calculated on all the cart contents"
207
+ msgstr ""
208
+
209
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:9
210
+ msgid "Compared to lengthiest product in cart"
211
+ msgstr ""
212
+
213
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:10
214
+ msgid "Compared to widest product in cart"
215
+ msgstr ""
216
+
217
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:11
218
+ msgid "Compared to highest product in cart"
219
+ msgstr ""
220
+
221
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:12
222
+ msgid "All products in cart must match stock status"
223
+ msgstr ""
224
+
225
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:13
226
+ msgid "All products in cart must match backorder"
227
+ msgstr ""
228
+
229
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:14
230
+ msgid "All products in cart must match category"
231
+ msgstr ""
232
+
233
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-descriptions.php:15
234
+ msgid "Cart must contain one of this product"
235
+ msgstr ""
236
+
237
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-operators.php:6
238
+ msgid "Equal to"
239
+ msgstr ""
240
+
241
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-operators.php:7
242
+ msgid "Not equal to"
243
+ msgstr ""
244
+
245
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-operators.php:8
246
+ msgid "Greater or equal to"
247
+ msgstr ""
248
+
249
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-operators.php:9
250
+ msgid "Less or equal to "
251
+ msgstr ""
252
+
253
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-values.php:122
254
+ msgid "In stock"
255
+ msgstr ""
256
+
257
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-values.php:123
258
+ msgid "Out of stock"
259
+ msgstr ""
260
+
261
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-values.php:132
262
+ msgid "Do not allow"
263
+ msgstr ""
264
+
265
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-values.php:133
266
+ msgid "Allow, but notify customer"
267
+ msgstr ""
268
+
269
+ #: ../woocommerce-advanced-free-shipping/includes/admin/settings/conditions/condition-values.php:134
270
+ msgid "Allow"
271
+ msgstr ""
272
+
273
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:15
274
+ msgid "Method conditions"
275
+ msgstr ""
276
+
277
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:23
278
+ msgid "Title"
279
+ msgstr ""
280
+
281
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:25
282
+ msgid "Condition groups"
283
+ msgstr ""
284
+
285
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:26
286
+ msgid "Author"
287
+ msgstr ""
288
+
289
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:38
290
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:44
291
+ msgid "Edit Method"
292
+ msgstr ""
293
+
294
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:39
295
+ msgid "Untitled"
296
+ msgstr ""
297
+
298
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:45
299
+ msgid "Edit"
300
+ msgstr ""
301
+
302
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:50
303
+ msgid "Delete Method"
304
+ msgstr ""
305
+
306
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:51
307
+ msgid "Delete"
308
+ msgstr ""
309
+
310
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:67
311
+ msgid "There are no Free Shipping conditions. Yet..."
312
+ msgstr ""
313
+
314
+ #: ../woocommerce-advanced-free-shipping/includes/admin/views/conditions-table.php:76
315
+ msgid "Add Free Shipping Method"
316
+ msgstr ""
license.txt ADDED
@@ -0,0 +1,621 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+ Preamble
9
+
10
+ The GNU General Public License is a free, copyleft license for
11
+ software and other kinds of works.
12
+
13
+ The licenses for most software and other practical works are designed
14
+ to take away your freedom to share and change the works. By contrast,
15
+ the GNU General Public License is intended to guarantee your freedom to
16
+ share and change all versions of a program--to make sure it remains free
17
+ software for all its users. We, the Free Software Foundation, use the
18
+ GNU General Public License for most of our software; it applies also to
19
+ any other work released this way by its authors. You can apply it to
20
+ your programs, too.
21
+
22
+ When we speak of free software, we are referring to freedom, not
23
+ price. Our General Public Licenses are designed to make sure that you
24
+ have the freedom to distribute copies of free software (and charge for
25
+ them if you wish), that you receive source code or can get it if you
26
+ want it, that you can change the software or use pieces of it in new
27
+ free programs, and that you know you can do these things.
28
+
29
+ To protect your rights, we need to prevent others from denying you
30
+ these rights or asking you to surrender the rights. Therefore, you have
31
+ certain responsibilities if you distribute copies of the software, or if
32
+ you modify it: responsibilities to respect the freedom of others.
33
+
34
+ For example, if you distribute copies of such a program, whether
35
+ gratis or for a fee, you must pass on to the recipients the same
36
+ freedoms that you received. You must make sure that they, too, receive
37
+ or can get the source code. And you must show them these terms so they
38
+ know their rights.
39
+
40
+ Developers that use the GNU GPL protect your rights with two steps:
41
+ (1) assert copyright on the software, and (2) offer you this License
42
+ giving you legal permission to copy, distribute and/or modify it.
43
+
44
+ For the developers' and authors' protection, the GPL clearly explains
45
+ that there is no warranty for this free software. For both users' and
46
+ authors' sake, the GPL requires that modified versions be marked as
47
+ changed, so that their problems will not be attributed erroneously to
48
+ authors of previous versions.
49
+
50
+ Some devices are designed to deny users access to install or run
51
+ modified versions of the software inside them, although the manufacturer
52
+ can do so. This is fundamentally incompatible with the aim of
53
+ protecting users' freedom to change the software. The systematic
54
+ pattern of such abuse occurs in the area of products for individuals to
55
+ use, which is precisely where it is most unacceptable. Therefore, we
56
+ have designed this version of the GPL to prohibit the practice for those
57
+ products. If such problems arise substantially in other domains, we
58
+ stand ready to extend this provision to those domains in future versions
59
+ of the GPL, as needed to protect the freedom of users.
60
+
61
+ Finally, every program is threatened constantly by software patents.
62
+ States should not allow patents to restrict development and use of
63
+ software on general-purpose computers, but in those that do, we wish to
64
+ avoid the special danger that patents applied to a free program could
65
+ make it effectively proprietary. To prevent this, the GPL assures that
66
+ patents cannot be used to render the program non-free.
67
+
68
+ The precise terms and conditions for copying, distribution and
69
+ modification follow.
70
+
71
+ TERMS AND CONDITIONS
72
+
73
+ 0. Definitions.
74
+
75
+ "This License" refers to version 3 of the GNU General Public License.
76
+
77
+ "Copyright" also means copyright-like laws that apply to other kinds of
78
+ works, such as semiconductor masks.
79
+
80
+ "The Program" refers to any copyrightable work licensed under this
81
+ License. Each licensee is addressed as "you". "Licensees" and
82
+ "recipients" may be individuals or organizations.
83
+
84
+ To "modify" a work means to copy from or adapt all or part of the work
85
+ in a fashion requiring copyright permission, other than the making of an
86
+ exact copy. The resulting work is called a "modified version" of the
87
+ earlier work or a work "based on" the earlier work.
88
+
89
+ A "covered work" means either the unmodified Program or a work based
90
+ on the Program.
91
+
92
+ To "propagate" a work means to do anything with it that, without
93
+ permission, would make you directly or secondarily liable for
94
+ infringement under applicable copyright law, except executing it on a
95
+ computer or modifying a private copy. Propagation includes copying,
96
+ distribution (with or without modification), making available to the
97
+ public, and in some countries other activities as well.
98
+
99
+ To "convey" a work means any kind of propagation that enables other
100
+ parties to make or receive copies. Mere interaction with a user through
101
+ a computer network, with no transfer of a copy, is not conveying.
102
+
103
+ An interactive user interface displays "Appropriate Legal Notices"
104
+ to the extent that it includes a convenient and prominently visible
105
+ feature that (1) displays an appropriate copyright notice, and (2)
106
+ tells the user that there is no warranty for the work (except to the
107
+ extent that warranties are provided), that licensees may convey the
108
+ work under this License, and how to view a copy of this License. If
109
+ the interface presents a list of user commands or options, such as a
110
+ menu, a prominent item in the list meets this criterion.
111
+
112
+ 1. Source Code.
113
+
114
+ The "source code" for a work means the preferred form of the work
115
+ for making modifications to it. "Object code" means any non-source
116
+ form of a work.
117
+
118
+ A "Standard Interface" means an interface that either is an official
119
+ standard defined by a recognized standards body, or, in the case of
120
+ interfaces specified for a particular programming language, one that
121
+ is widely used among developers working in that language.
122
+
123
+ The "System Libraries" of an executable work include anything, other
124
+ than the work as a whole, that (a) is included in the normal form of
125
+ packaging a Major Component, but which is not part of that Major
126
+ Component, and (b) serves only to enable use of the work with that
127
+ Major Component, or to implement a Standard Interface for which an
128
+ implementation is available to the public in source code form. A
129
+ "Major Component", in this context, means a major essential component
130
+ (kernel, window system, and so on) of the specific operating system
131
+ (if any) on which the executable work runs, or a compiler used to
132
+ produce the work, or an object code interpreter used to run it.
133
+
134
+ The "Corresponding Source" for a work in object code form means all
135
+ the source code needed to generate, install, and (for an executable
136
+ work) run the object code and to modify the work, including scripts to
137
+ control those activities. However, it does not include the work's
138
+ System Libraries, or general-purpose tools or generally available free
139
+ programs which are used unmodified in performing those activities but
140
+ which are not part of the work. For example, Corresponding Source
141
+ includes interface definition files associated with source files for
142
+ the work, and the source code for shared libraries and dynamically
143
+ linked subprograms that the work is specifically designed to require,
144
+ such as by intimate data communication or control flow between those
145
+ subprograms and other parts of the work.
146
+
147
+ The Corresponding Source need not include anything that users
148
+ can regenerate automatically from other parts of the Corresponding
149
+ Source.
150
+
151
+ The Corresponding Source for a work in source code form is that
152
+ same work.
153
+
154
+ 2. Basic Permissions.
155
+
156
+ All rights granted under this License are granted for the term of
157
+ copyright on the Program, and are irrevocable provided the stated
158
+ conditions are met. This License explicitly affirms your unlimited
159
+ permission to run the unmodified Program. The output from running a
160
+ covered work is covered by this License only if the output, given its
161
+ content, constitutes a covered work. This License acknowledges your
162
+ rights of fair use or other equivalent, as provided by copyright law.
163
+
164
+ You may make, run and propagate covered works that you do not
165
+ convey, without conditions so long as your license otherwise remains
166
+ in force. You may convey covered works to others for the sole purpose
167
+ of having them make modifications exclusively for you, or provide you
168
+ with facilities for running those works, provided that you comply with
169
+ the terms of this License in conveying all material for which you do
170
+ not control copyright. Those thus making or running the covered works
171
+ for you must do so exclusively on your behalf, under your direction
172
+ and control, on terms that prohibit them from making any copies of
173
+ your copyrighted material outside their relationship with you.
174
+
175
+ Conveying under any other circumstances is permitted solely under
176
+ the conditions stated below. Sublicensing is not allowed; section 10
177
+ makes it unnecessary.
178
+
179
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
+
181
+ No covered work shall be deemed part of an effective technological
182
+ measure under any applicable law fulfilling obligations under article
183
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184
+ similar laws prohibiting or restricting circumvention of such
185
+ measures.
186
+
187
+ When you convey a covered work, you waive any legal power to forbid
188
+ circumvention of technological measures to the extent such circumvention
189
+ is effected by exercising rights under this License with respect to
190
+ the covered work, and you disclaim any intention to limit operation or
191
+ modification of the work as a means of enforcing, against the work's
192
+ users, your or third parties' legal rights to forbid circumvention of
193
+ technological measures.
194
+
195
+ 4. Conveying Verbatim Copies.
196
+
197
+ You may convey verbatim copies of the Program's source code as you
198
+ receive it, in any medium, provided that you conspicuously and
199
+ appropriately publish on each copy an appropriate copyright notice;
200
+ keep intact all notices stating that this License and any
201
+ non-permissive terms added in accord with section 7 apply to the code;
202
+ keep intact all notices of the absence of any warranty; and give all
203
+ recipients a copy of this License along with the Program.
204
+
205
+ You may charge any price or no price for each copy that you convey,
206
+ and you may offer support or warranty protection for a fee.
207
+
208
+ 5. Conveying Modified Source Versions.
209
+
210
+ You may convey a work based on the Program, or the modifications to
211
+ produce it from the Program, in the form of source code under the
212
+ terms of section 4, provided that you also meet all of these conditions:
213
+
214
+ a) The work must carry prominent notices stating that you modified
215
+ it, and giving a relevant date.
216
+
217
+ b) The work must carry prominent notices stating that it is
218
+ released under this License and any conditions added under section
219
+ 7. This requirement modifies the requirement in section 4 to
220
+ "keep intact all notices".
221
+
222
+ c) You must license the entire work, as a whole, under this
223
+ License to anyone who comes into possession of a copy. This
224
+ License will therefore apply, along with any applicable section 7
225
+ additional terms, to the whole of the work, and all its parts,
226
+ regardless of how they are packaged. This License gives no
227
+ permission to license the work in any other way, but it does not
228
+ invalidate such permission if you have separately received it.
229
+
230
+ d) If the work has interactive user interfaces, each must display
231
+ Appropriate Legal Notices; however, if the Program has interactive
232
+ interfaces that do not display Appropriate Legal Notices, your
233
+ work need not make them do so.
234
+
235
+ A compilation of a covered work with other separate and independent
236
+ works, which are not by their nature extensions of the covered work,
237
+ and which are not combined with it such as to form a larger program,
238
+ in or on a volume of a storage or distribution medium, is called an
239
+ "aggregate" if the compilation and its resulting copyright are not
240
+ used to limit the access or legal rights of the compilation's users
241
+ beyond what the individual works permit. Inclusion of a covered work
242
+ in an aggregate does not cause this License to apply to the other
243
+ parts of the aggregate.
244
+
245
+ 6. Conveying Non-Source Forms.
246
+
247
+ You may convey a covered work in object code form under the terms
248
+ of sections 4 and 5, provided that you also convey the
249
+ machine-readable Corresponding Source under the terms of this License,
250
+ in one of these ways:
251
+
252
+ a) Convey the object code in, or embodied in, a physical product
253
+ (including a physical distribution medium), accompanied by the
254
+ Corresponding Source fixed on a durable physical medium
255
+ customarily used for software interchange.
256
+
257
+ b) Convey the object code in, or embodied in, a physical product
258
+ (including a physical distribution medium), accompanied by a
259
+ written offer, valid for at least three years and valid for as
260
+ long as you offer spare parts or customer support for that product
261
+ model, to give anyone who possesses the object code either (1) a
262
+ copy of the Corresponding Source for all the software in the
263
+ product that is covered by this License, on a durable physical
264
+ medium customarily used for software interchange, for a price no
265
+ more than your reasonable cost of physically performing this
266
+ conveying of source, or (2) access to copy the
267
+ Corresponding Source from a network server at no charge.
268
+
269
+ c) Convey individual copies of the object code with a copy of the
270
+ written offer to provide the Corresponding Source. This
271
+ alternative is allowed only occasionally and noncommercially, and
272
+ only if you received the object code with such an offer, in accord
273
+ with subsection 6b.
274
+
275
+ d) Convey the object code by offering access from a designated
276
+ place (gratis or for a charge), and offer equivalent access to the
277
+ Corresponding Source in the same way through the same place at no
278
+ further charge. You need not require recipients to copy the
279
+ Corresponding Source along with the object code. If the place to
280
+ copy the object code is a network server, the Corresponding Source
281
+ may be on a different server (operated by you or a third party)
282
+ that supports equivalent copying facilities, provided you maintain
283
+ clear directions next to the object code saying where to find the
284
+ Corresponding Source. Regardless of what server hosts the
285
+ Corresponding Source, you remain obligated to ensure that it is
286
+ available for as long as needed to satisfy these requirements.
287
+
288
+ e) Convey the object code using peer-to-peer transmission, provided
289
+ you inform other peers where the object code and Corresponding
290
+ Source of the work are being offered to the general public at no
291
+ charge under subsection 6d.
292
+
293
+ A separable portion of the object code, whose source code is excluded
294
+ from the Corresponding Source as a System Library, need not be
295
+ included in conveying the object code work.
296
+
297
+ A "User Product" is either (1) a "consumer product", which means any
298
+ tangible personal property which is normally used for personal, family,
299
+ or household purposes, or (2) anything designed or sold for incorporation
300
+ into a dwelling. In determining whether a product is a consumer product,
301
+ doubtful cases shall be resolved in favor of coverage. For a particular
302
+ product received by a particular user, "normally used" refers to a
303
+ typical or common use of that class of product, regardless of the status
304
+ of the particular user or of the way in which the particular user
305
+ actually uses, or expects or is expected to use, the product. A product
306
+ is a consumer product regardless of whether the product has substantial
307
+ commercial, industrial or non-consumer uses, unless such uses represent
308
+ the only significant mode of use of the product.
309
+
310
+ "Installation Information" for a User Product means any methods,
311
+ procedures, authorization keys, or other information required to install
312
+ and execute modified versions of a covered work in that User Product from
313
+ a modified version of its Corresponding Source. The information must
314
+ suffice to ensure that the continued functioning of the modified object
315
+ code is in no case prevented or interfered with solely because
316
+ modification has been made.
317
+
318
+ If you convey an object code work under this section in, or with, or
319
+ specifically for use in, a User Product, and the conveying occurs as
320
+ part of a transaction in which the right of possession and use of the
321
+ User Product is transferred to the recipient in perpetuity or for a
322
+ fixed term (regardless of how the transaction is characterized), the
323
+ Corresponding Source conveyed under this section must be accompanied
324
+ by the Installation Information. But this requirement does not apply
325
+ if neither you nor any third party retains the ability to install
326
+ modified object code on the User Product (for example, the work has
327
+ been installed in ROM).
328
+
329
+ The requirement to provide Installation Information does not include a
330
+ requirement to continue to provide support service, warranty, or updates
331
+ for a work that has been modified or installed by the recipient, or for
332
+ the User Product in which it has been modified or installed. Access to a
333
+ network may be denied when the modification itself materially and
334
+ adversely affects the operation of the network or violates the rules and
335
+ protocols for communication across the network.
336
+
337
+ Corresponding Source conveyed, and Installation Information provided,
338
+ in accord with this section must be in a format that is publicly
339
+ documented (and with an implementation available to the public in
340
+ source code form), and must require no special password or key for
341
+ unpacking, reading or copying.
342
+
343
+ 7. Additional Terms.
344
+
345
+ "Additional permissions" are terms that supplement the terms of this
346
+ License by making exceptions from one or more of its conditions.
347
+ Additional permissions that are applicable to the entire Program shall
348
+ be treated as though they were included in this License, to the extent
349
+ that they are valid under applicable law. If additional permissions
350
+ apply only to part of the Program, that part may be used separately
351
+ under those permissions, but the entire Program remains governed by
352
+ this License without regard to the additional permissions.
353
+
354
+ When you convey a copy of a covered work, you may at your option
355
+ remove any additional permissions from that copy, or from any part of
356
+ it. (Additional permissions may be written to require their own
357
+ removal in certain cases when you modify the work.) You may place
358
+ additional permissions on material, added by you to a covered work,
359
+ for which you have or can give appropriate copyright permission.
360
+
361
+ Notwithstanding any other provision of this License, for material you
362
+ add to a covered work, you may (if authorized by the copyright holders of
363
+ that material) supplement the terms of this License with terms:
364
+
365
+ a) Disclaiming warranty or limiting liability differently from the
366
+ terms of sections 15 and 16 of this License; or
367
+
368
+ b) Requiring preservation of specified reasonable legal notices or
369
+ author attributions in that material or in the Appropriate Legal
370
+ Notices displayed by works containing it; or
371
+
372
+ c) Prohibiting misrepresentation of the origin of that material, or
373
+ requiring that modified versions of such material be marked in
374
+ reasonable ways as different from the original version; or
375
+
376
+ d) Limiting the use for publicity purposes of names of licensors or
377
+ authors of the material; or
378
+
379
+ e) Declining to grant rights under trademark law for use of some
380
+ trade names, trademarks, or service marks; or
381
+
382
+ f) Requiring indemnification of licensors and authors of that
383
+ material by anyone who conveys the material (or modified versions of
384
+ it) with contractual assumptions of liability to the recipient, for
385
+ any liability that these contractual assumptions directly impose on
386
+ those licensors and authors.
387
+
388
+ All other non-permissive additional terms are considered "further
389
+ restrictions" within the meaning of section 10. If the Program as you
390
+ received it, or any part of it, contains a notice stating that it is
391
+ governed by this License along with a term that is a further
392
+ restriction, you may remove that term. If a license document contains
393
+ a further restriction but permits relicensing or conveying under this
394
+ License, you may add to a covered work material governed by the terms
395
+ of that license document, provided that the further restriction does
396
+ not survive such relicensing or conveying.
397
+
398
+ If you add terms to a covered work in accord with this section, you
399
+ must place, in the relevant source files, a statement of the
400
+ additional terms that apply to those files, or a notice indicating
401
+ where to find the applicable terms.
402
+
403
+ Additional terms, permissive or non-permissive, may be stated in the
404
+ form of a separately written license, or stated as exceptions;
405
+ the above requirements apply either way.
406
+
407
+ 8. Termination.
408
+
409
+ You may not propagate or modify a covered work except as expressly
410
+ provided under this License. Any attempt otherwise to propagate or
411
+ modify it is void, and will automatically terminate your rights under
412
+ this License (including any patent licenses granted under the third
413
+ paragraph of section 11).
414
+
415
+ However, if you cease all violation of this License, then your
416
+ license from a particular copyright holder is reinstated (a)
417
+ provisionally, unless and until the copyright holder explicitly and
418
+ finally terminates your license, and (b) permanently, if the copyright
419
+ holder fails to notify you of the violation by some reasonable means
420
+ prior to 60 days after the cessation.
421
+
422
+ Moreover, your license from a particular copyright holder is
423
+ reinstated permanently if the copyright holder notifies you of the
424
+ violation by some reasonable means, this is the first time you have
425
+ received notice of violation of this License (for any work) from that
426
+ copyright holder, and you cure the violation prior to 30 days after
427
+ your receipt of the notice.
428
+
429
+ Termination of your rights under this section does not terminate the
430
+ licenses of parties who have received copies or rights from you under
431
+ this License. If your rights have been terminated and not permanently
432
+ reinstated, you do not qualify to receive new licenses for the same
433
+ material under section 10.
434
+
435
+ 9. Acceptance Not Required for Having Copies.
436
+
437
+ You are not required to accept this License in order to receive or
438
+ run a copy of the Program. Ancillary propagation of a covered work
439
+ occurring solely as a consequence of using peer-to-peer transmission
440
+ to receive a copy likewise does not require acceptance. However,
441
+ nothing other than this License grants you permission to propagate or
442
+ modify any covered work. These actions infringe copyright if you do
443
+ not accept this License. Therefore, by modifying or propagating a
444
+ covered work, you indicate your acceptance of this License to do so.
445
+
446
+ 10. Automatic Licensing of Downstream Recipients.
447
+
448
+ Each time you convey a covered work, the recipient automatically
449
+ receives a license from the original licensors, to run, modify and
450
+ propagate that work, subject to this License. You are not responsible
451
+ for enforcing compliance by third parties with this License.
452
+
453
+ An "entity transaction" is a transaction transferring control of an
454
+ organization, or substantially all assets of one, or subdividing an
455
+ organization, or merging organizations. If propagation of a covered
456
+ work results from an entity transaction, each party to that
457
+ transaction who receives a copy of the work also receives whatever
458
+ licenses to the work the party's predecessor in interest had or could
459
+ give under the previous paragraph, plus a right to possession of the
460
+ Corresponding Source of the work from the predecessor in interest, if
461
+ the predecessor has it or can get it with reasonable efforts.
462
+
463
+ You may not impose any further restrictions on the exercise of the
464
+ rights granted or affirmed under this License. For example, you may
465
+ not impose a license fee, royalty, or other charge for exercise of
466
+ rights granted under this License, and you may not initiate litigation
467
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
468
+ any patent claim is infringed by making, using, selling, offering for
469
+ sale, or importing the Program or any portion of it.
470
+
471
+ 11. Patents.
472
+
473
+ A "contributor" is a copyright holder who authorizes use under this
474
+ License of the Program or a work on which the Program is based. The
475
+ work thus licensed is called the contributor's "contributor version".
476
+
477
+ A contributor's "essential patent claims" are all patent claims
478
+ owned or controlled by the contributor, whether already acquired or
479
+ hereafter acquired, that would be infringed by some manner, permitted
480
+ by this License, of making, using, or selling its contributor version,
481
+ but do not include claims that would be infringed only as a
482
+ consequence of further modification of the contributor version. For
483
+ purposes of this definition, "control" includes the right to grant
484
+ patent sublicenses in a manner consistent with the requirements of
485
+ this License.
486
+
487
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
488
+ patent license under the contributor's essential patent claims, to
489
+ make, use, sell, offer for sale, import and otherwise run, modify and
490
+ propagate the contents of its contributor version.
491
+
492
+ In the following three paragraphs, a "patent license" is any express
493
+ agreement or commitment, however denominated, not to enforce a patent
494
+ (such as an express permission to practice a patent or covenant not to
495
+ sue for patent infringement). To "grant" such a patent license to a
496
+ party means to make such an agreement or commitment not to enforce a
497
+ patent against the party.
498
+
499
+ If you convey a covered work, knowingly relying on a patent license,
500
+ and the Corresponding Source of the work is not available for anyone
501
+ to copy, free of charge and under the terms of this License, through a
502
+ publicly available network server or other readily accessible means,
503
+ then you must either (1) cause the Corresponding Source to be so
504
+ available, or (2) arrange to deprive yourself of the benefit of the
505
+ patent license for this particular work, or (3) arrange, in a manner
506
+ consistent with the requirements of this License, to extend the patent
507
+ license to downstream recipients. "Knowingly relying" means you have
508
+ actual knowledge that, but for the patent license, your conveying the
509
+ covered work in a country, or your recipient's use of the covered work
510
+ in a country, would infringe one or more identifiable patents in that
511
+ country that you have reason to believe are valid.
512
+
513
+ If, pursuant to or in connection with a single transaction or
514
+ arrangement, you convey, or propagate by procuring conveyance of, a
515
+ covered work, and grant a patent license to some of the parties
516
+ receiving the covered work authorizing them to use, propagate, modify
517
+ or convey a specific copy of the covered work, then the patent license
518
+ you grant is automatically extended to all recipients of the covered
519
+ work and works based on it.
520
+
521
+ A patent license is "discriminatory" if it does not include within
522
+ the scope of its coverage, prohibits the exercise of, or is
523
+ conditioned on the non-exercise of one or more of the rights that are
524
+ specifically granted under this License. You may not convey a covered
525
+ work if you are a party to an arrangement with a third party that is
526
+ in the business of distributing software, under which you make payment
527
+ to the third party based on the extent of your activity of conveying
528
+ the work, and under which the third party grants, to any of the
529
+ parties who would receive the covered work from you, a discriminatory
530
+ patent license (a) in connection with copies of the covered work
531
+ conveyed by you (or copies made from those copies), or (b) primarily
532
+ for and in connection with specific products or compilations that
533
+ contain the covered work, unless you entered into that arrangement,
534
+ or that patent license was granted, prior to 28 March 2007.
535
+
536
+ Nothing in this License shall be construed as excluding or limiting
537
+ any implied license or other defenses to infringement that may
538
+ otherwise be available to you under applicable patent law.
539
+
540
+ 12. No Surrender of Others' Freedom.
541
+
542
+ If conditions are imposed on you (whether by court order, agreement or
543
+ otherwise) that contradict the conditions of this License, they do not
544
+ excuse you from the conditions of this License. If you cannot convey a
545
+ covered work so as to satisfy simultaneously your obligations under this
546
+ License and any other pertinent obligations, then as a consequence you may
547
+ not convey it at all. For example, if you agree to terms that obligate you
548
+ to collect a royalty for further conveying from those to whom you convey
549
+ the Program, the only way you could satisfy both those terms and this
550
+ License would be to refrain entirely from conveying the Program.
551
+
552
+ 13. Use with the GNU Affero General Public License.
553
+
554
+ Notwithstanding any other provision of this License, you have
555
+ permission to link or combine any covered work with a work licensed
556
+ under version 3 of the GNU Affero General Public License into a single
557
+ combined work, and to convey the resulting work. The terms of this
558
+ License will continue to apply to the part which is the covered work,
559
+ but the special requirements of the GNU Affero General Public License,
560
+ section 13, concerning interaction through a network will apply to the
561
+ combination as such.
562
+
563
+ 14. Revised Versions of this License.
564
+
565
+ The Free Software Foundation may publish revised and/or new versions of
566
+ the GNU General Public License from time to time. Such new versions will
567
+ be similar in spirit to the present version, but may differ in detail to
568
+ address new problems or concerns.
569
+
570
+ Each version is given a distinguishing version number. If the
571
+ Program specifies that a certain numbered version of the GNU General
572
+ Public License "or any later version" applies to it, you have the
573
+ option of following the terms and conditions either of that numbered
574
+ version or of any later version published by the Free Software
575
+ Foundation. If the Program does not specify a version number of the
576
+ GNU General Public License, you may choose any version ever published
577
+ by the Free Software Foundation.
578
+
579
+ If the Program specifies that a proxy can decide which future
580
+ versions of the GNU General Public License can be used, that proxy's
581
+ public statement of acceptance of a version permanently authorizes you
582
+ to choose that version for the Program.
583
+
584
+ Later license versions may give you additional or different
585
+ permissions. However, no additional obligations are imposed on any
586
+ author or copyright holder as a result of your choosing to follow a
587
+ later version.
588
+
589
+ 15. Disclaimer of Warranty.
590
+
591
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596
+ PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597
+ IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598
+ ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
+
600
+ 16. Limitation of Liability.
601
+
602
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604
+ THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605
+ GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606
+ USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609
+ EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610
+ SUCH DAMAGES.
611
+
612
+ 17. Interpretation of Sections 15 and 16.
613
+
614
+ If the disclaimer of warranty and limitation of liability provided
615
+ above cannot be given local legal effect according to their terms,
616
+ reviewing courts shall apply local law that most closely approximates
617
+ an absolute waiver of all civil liability in connection with the
618
+ Program, unless a warranty or assumption of liability accompanies a
619
+ copy of the Program in return for a fee.
620
+
621
+ END OF TERMS AND CONDITIONS
readme.txt ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === WooCommerce Advanced Free Shipping ===
2
+ Contributors: sormano
3
+ Donate link: http://www.jeroensormani.com/donate/
4
+ Tags: woocommerce, shipping, woocommerce shipping, woocommerce free shipping, woocommerce free, woocommerce advanced free shipping, wc free shipping, wc shipping, advanced shipping, pro shipping, table rate shipping, country shipping, free shipping
5
+ Requires at least: 3.6
6
+ Tested up to: 3.9
7
+ Stable tag: 1.0.1
8
+ License: GPLv3 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
+
11
+ WooCommerce Advanced Free Shipping is an plugin which allows you to set up advanced free shipping conditions.
12
+
13
+ == Description ==
14
+ WooCommerce Advanced Free Shipping is an plugin which allows you to set up advanced free shipping conditions.
15
+
16
+ *Conditions like:*
17
+
18
+ - Cart total
19
+ - Country
20
+ - Zipcode
21
+ - Stock / stock status
22
+ - Weight
23
+ - Quantity
24
+ - Coupon
25
+ - many, many more...
26
+
27
+ **Look at the screenshots!**
28
+
29
+ **Translations, feature requests, ratings and donations are welcome and appreciated!**
30
+
31
+ == Installation ==
32
+
33
+ 1. Upload the folder `woocommerce-advanced-free-shipping` to the `/wp-content/plugins/` directory
34
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
35
+ 3. Go to the settings page to fine-tune the settings if desired
36
+
37
+ == Screenshots ==
38
+
39
+ 1. WooCommerce Shipping options
40
+ 2. WAFS shipping conditions
41
+ 3. WAFS shipping conditions possibilities
42
+
43
+ == Changelog ==
44
+
45
+ = 1.0.1 =
46
+ * Fix - Wrongful url for sub-domain websites
47
+ * Add - Added states as condition
48
+
49
+ = 1.0.0 =
50
+ * Initial release
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file
woocommerce-advanced-free-shipping.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?PHP
2
+ /*
3
+ Plugin Name: Woocommerce Advanced Free Shipping
4
+ Plugin URI: http://www.jeroensormani.com/
5
+ Donate link: http://www.jeroensormani.com/donate/
6
+ Description: WooCommerce Advanced Free Shipping is an plugin which allows you to set up advanced free shipping conditions.
7
+ Version: 1.0.1
8
+ Author: Jeroen Sormani
9
+ Author URI: http://www.jeroensormani.com/
10
+ Text Domain: wafs
11
+
12
+ * Copyright Jeroen Sormani
13
+ *
14
+ * This file is part of Woocommerce Advanced Free Shipping,
15
+ * a plugin for WordPress.
16
+ *
17
+ * Woocommerce Advanced Free Shipping is free software:
18
+ * You can redistribute it and/or modify it under the terms of the
19
+ * GNU General Public License as published by the Free Software
20
+ * Foundation, either version 3 of the License, or (at your option)
21
+ * any later version.
22
+ *
23
+ * Woocommerce Advanced Free Shipping is distributed in the hope that
24
+ * it will be useful, but WITHOUT ANY WARRANTY; without even the
25
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
26
+ * PURPOSE. See the GNU General Public License for more details.
27
+ *
28
+ * You should have received a copy of the GNU General Public License
29
+ * along with WordPress. If not, see <http://www.gnu.org/licenses/>.
30
+ */
31
+
32
+
33
+ /**
34
+ * Class Woocommerce_Advanced_Free_Shipping
35
+ *
36
+ * Main WAFS class, add filters and handling all other files
37
+ *
38
+ * @class Woocommerce_Advanced_Free_Shipping
39
+ * @version 1.0.0
40
+ * @author Jeroen Sormani
41
+ */
42
+ class Woocommerce_Advanced_Free_Shipping {
43
+
44
+
45
+ /**
46
+ * __construct functon.
47
+ */
48
+ public function __construct() {
49
+
50
+ // check if woocommerce is activated
51
+ if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) )
52
+ return;
53
+
54
+ $this->wafs_hooks();
55
+
56
+ }
57
+
58
+
59
+ /**
60
+ * wafs_hooks functon.
61
+ *
62
+ * Initialize all hooks
63
+ */
64
+ public function wafs_hooks() {
65
+
66
+ // Initialize shipping method class
67
+ add_action( 'woocommerce_shipping_init', array( $this, 'wafs_free_shipping' ) );
68
+
69
+ // Add shipping method
70
+ add_action( 'woocommerce_shipping_methods', array( $this, 'wafs_add_shipping_method' ) );
71
+
72
+ // Register post type
73
+ add_action( 'init', array( $this, 'wafs_register_post_type' ) );
74
+
75
+ // Enqueue scripts
76
+ add_action( 'admin_enqueue_scripts', array( $this, 'wafs_admin_enqueue_scripts' ) );
77
+
78
+ }
79
+
80
+
81
+ /**
82
+ * wafs_free_shipping functon.
83
+ *
84
+ *
85
+ */
86
+ public function wafs_free_shipping() {
87
+
88
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-wafs-method.php';
89
+
90
+ }
91
+
92
+
93
+ /**
94
+ * wafs_add_shipping_method functon.
95
+ *
96
+ *
97
+ */
98
+ public function wafs_add_shipping_method( $methods ) {
99
+
100
+ if ( class_exists( 'Wafs_Free_Shipping_Method' ) )
101
+ $methods[] = 'Wafs_Free_Shipping_Method';
102
+
103
+ return $methods;
104
+
105
+ }
106
+
107
+
108
+ /**
109
+ * Register post type 'wafs'.
110
+ */
111
+ public function wafs_register_post_type() {
112
+
113
+ /**
114
+ * Require file with settings
115
+ */
116
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-wafs-post-type.php';
117
+
118
+ }
119
+
120
+ /**
121
+ * Enqueue style and java scripts.
122
+ */
123
+ public function wafs_admin_enqueue_scripts() {
124
+
125
+ wp_enqueue_style( 'wafs-style', plugins_url( 'assets/css/admin-style.css', __FILE__ ) );
126
+ wp_enqueue_script( 'wafs-js', plugins_url( 'assets/js/wafs-js.js', __FILE__ ), array( 'jquery' ), false, true );
127
+
128
+ }
129
+
130
+ }
131
+ $wafs = new Woocommerce_Advanced_Free_Shipping();
132
+
133
+ /**
134
+ * Require matching conditions hooks
135
+ */
136
+ require_once plugin_dir_path( __FILE__ ) . '/includes/class-wafs-match-conditions.php';
137
+ ?>