1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) exit;
4
5 6 7 8 9 10 11 12 13 14
15 class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
16
17 18 19 20 21 22
23 function __construct() {
24 $this->id = 'free_shipping';
25 $this->method_title = __( 'Free Shipping', 'woocommerce' );
26 $this->init();
27 }
28
29 30 31 32 33 34
35 function init() {
36
37
38 $this->init_form_fields();
39 $this->init_settings();
40
41
42 $this->enabled = $this->get_option( 'enabled' );
43 $this->title = $this->get_option( 'title' );
44 $this->min_amount = $this->get_option( 'min_amount', 0 );
45 $this->availability = $this->get_option( 'availability' );
46 $this->countries = $this->get_option( 'countries' );
47 $this->requires = $this->get_option( 'requires' );
48
49
50 add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
51 }
52
53
54 55 56 57 58 59
60 function init_form_fields() {
61
62 $this->form_fields = array(
63 'enabled' => array(
64 'title' => __( 'Enable/Disable', 'woocommerce' ),
65 'type' => 'checkbox',
66 'label' => __( 'Enable Free Shipping', 'woocommerce' ),
67 'default' => 'yes'
68 ),
69 'title' => array(
70 'title' => __( 'Method Title', 'woocommerce' ),
71 'type' => 'text',
72 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
73 'default' => __( 'Free Shipping', 'woocommerce' ),
74 'desc_tip' => true,
75 ),
76 'availability' => array(
77 'title' => __( 'Method availability', 'woocommerce' ),
78 'type' => 'select',
79 'default' => 'all',
80 'class' => 'availability',
81 'options' => array(
82 'all' => __( 'All allowed countries', 'woocommerce' ),
83 'specific' => __( 'Specific Countries', 'woocommerce' )
84 )
85 ),
86 'countries' => array(
87 'title' => __( 'Specific Countries', 'woocommerce' ),
88 'type' => 'multiselect',
89 'class' => 'chosen_select',
90 'css' => 'width: 450px;',
91 'default' => '',
92 'options' => WC()->countries->get_shipping_countries(),
93 'custom_attributes' => array(
94 'data-placeholder' => __( 'Select some countries', 'woocommerce' )
95 )
96 ),
97 'requires' => array(
98 'title' => __( 'Free Shipping Requires...', 'woocommerce' ),
99 'type' => 'select',
100 'default' => '',
101 'options' => array(
102 '' => __( 'N/A', 'woocommerce' ),
103 'coupon' => __( 'A valid free shipping coupon', 'woocommerce' ),
104 'min_amount' => __( 'A minimum order amount (defined below)', 'woocommerce' ),
105 'either' => __( 'A minimum order amount OR a coupon', 'woocommerce' ),
106 'both' => __( 'A minimum order amount AND a coupon', 'woocommerce' ),
107 )
108 ),
109 'min_amount' => array(
110 'title' => __( 'Minimum Order Amount', 'woocommerce' ),
111 'type' => 'price',
112 'placeholder' => wc_format_localized_price( 0 ),
113 'description' => __( 'Users will need to spend this amount to get free shipping (if enabled above).', 'woocommerce' ),
114 'default' => '0',
115 'desc_tip' => true
116 )
117 );
118
119 }
120
121
122 123 124 125 126 127 128 129
130 public function admin_options() {
131
132 ?>
133 <h3><?php _e( 'Free Shipping', 'woocommerce' ); ?></h3>
134 <table class="form-table">
135 <?php
136
137 $this->generate_settings_html();
138 ?>
139 </table><!--/.form-table-->
140 <?php
141 }
142
143
144 145 146 147 148 149 150
151 function is_available( $package ) {
152
153 if ( $this->enabled == "no" ) return false;
154
155 $ship_to_countries = '';
156
157 if ( $this->availability == 'specific' )
158 $ship_to_countries = $this->countries;
159 else
160 $ship_to_countries = array_keys( WC()->countries->get_shipping_countries() );
161
162 if ( is_array( $ship_to_countries ) )
163 if ( ! in_array( $package['destination']['country'], $ship_to_countries ) )
164 return false;
165
166
167 $is_available = false;
168 $has_coupon = false;
169 $has_met_min_amount = false;
170
171 if ( in_array( $this->requires, array( 'coupon', 'either', 'both' ) ) ) {
172
173 if ( $coupons = WC()->cart->get_coupons() ) {
174 foreach ( $coupons as $code => $coupon ) {
175 if ( $coupon->is_valid() && $coupon->enable_free_shipping() )
176 $has_coupon = true;
177 }
178 }
179 }
180
181 if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ) ) && isset( WC()->cart->cart_contents_total ) ) {
182
183 if ( WC()->cart->prices_include_tax )
184 $total = WC()->cart->cart_contents_total + array_sum( WC()->cart->taxes );
185 else
186 $total = WC()->cart->cart_contents_total;
187
188 if ( $total >= $this->min_amount )
189 $has_met_min_amount = true;
190 }
191
192 switch ( $this->requires ) {
193 case 'min_amount' :
194 if ( $has_met_min_amount ) $is_available = true;
195 break;
196 case 'coupon' :
197 if ( $has_coupon ) $is_available = true;
198 break;
199 case 'both' :
200 if ( $has_met_min_amount && $has_coupon ) $is_available = true;
201 break;
202 case 'either' :
203 if ( $has_met_min_amount || $has_coupon ) $is_available = true;
204 break;
205 default :
206 $is_available = true;
207 break;
208 }
209
210 return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package );
211 }
212
213
214 215 216 217 218 219
220 function calculate_shipping() {
221 $args = array(
222 'id' => $this->id,
223 'label' => $this->title,
224 'cost' => 0,
225 'taxes' => false
226 );
227 $this->add_rate( $args );
228 }
229
230 }