1
|
|
|
<?php |
2
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
3
|
|
|
exit; |
4
|
|
|
} |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Free Shipping Method. |
8
|
|
|
* |
9
|
|
|
* A simple shipping method for free shipping. |
10
|
|
|
* |
11
|
|
|
* @class WC_Shipping_Free_Shipping |
12
|
|
|
* @version 2.6.0 |
13
|
|
|
* @package WooCommerce/Classes/Shipping |
14
|
|
|
* @author WooThemes |
15
|
|
|
*/ |
16
|
|
|
class WC_Shipping_Free_Shipping extends WC_Shipping_Method { |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Min amount to be valid. |
20
|
|
|
* |
21
|
|
|
* @var integer |
22
|
|
|
*/ |
23
|
|
|
public $min_amount = 0; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Requires option. |
27
|
|
|
* |
28
|
|
|
* @var string |
29
|
|
|
*/ |
30
|
|
|
public $requires = ''; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Constructor. |
34
|
|
|
* |
35
|
|
|
* @param int $instance_id Shipping method instance. |
36
|
|
|
*/ |
37
|
|
View Code Duplication |
public function __construct( $instance_id = 0 ) { |
|
|
|
|
38
|
|
|
$this->id = 'free_shipping'; |
39
|
|
|
$this->instance_id = absint( $instance_id ); |
40
|
|
|
$this->method_title = __( 'Free Shipping', 'woocommerce' ); |
41
|
|
|
$this->method_description = __( 'Free Shipping is a special method which can be triggered with coupons and minimum spends.', 'woocommerce' ); |
42
|
|
|
$this->supports = array( |
43
|
|
|
'shipping-zones', |
44
|
|
|
'instance-settings', |
45
|
|
|
'instance-settings-modal', |
46
|
|
|
); |
47
|
|
|
|
48
|
|
|
$this->init(); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Initialize free shipping. |
53
|
|
|
*/ |
54
|
|
View Code Duplication |
public function init() { |
|
|
|
|
55
|
|
|
// Load the settings. |
56
|
|
|
$this->init_form_fields(); |
57
|
|
|
$this->init_settings(); |
58
|
|
|
|
59
|
|
|
// Define user set variables. |
60
|
|
|
$this->title = $this->get_option( 'title' ); |
61
|
|
|
$this->min_amount = $this->get_option( 'min_amount', 0 ); |
62
|
|
|
$this->requires = $this->get_option( 'requires' ); |
63
|
|
|
|
64
|
|
|
// Actions. |
65
|
|
|
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Init form fields. |
70
|
|
|
*/ |
71
|
|
|
public function init_form_fields() { |
72
|
|
|
$this->instance_form_fields = array( |
73
|
|
|
'title' => array( |
74
|
|
|
'title' => __( 'Title', 'woocommerce' ), |
75
|
|
|
'type' => 'text', |
76
|
|
|
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), |
77
|
|
|
'default' => $this->method_title, |
78
|
|
|
'desc_tip' => true, |
79
|
|
|
), |
80
|
|
|
'requires' => array( |
81
|
|
|
'title' => __( 'Free Shipping Requires...', 'woocommerce' ), |
82
|
|
|
'type' => 'select', |
83
|
|
|
'class' => 'wc-enhanced-select', |
84
|
|
|
'default' => '', |
85
|
|
|
'options' => array( |
86
|
|
|
'' => __( 'N/A', 'woocommerce' ), |
87
|
|
|
'coupon' => __( 'A valid free shipping coupon', 'woocommerce' ), |
88
|
|
|
'min_amount' => __( 'A minimum order amount', 'woocommerce' ), |
89
|
|
|
'either' => __( 'A minimum order amount OR a coupon', 'woocommerce' ), |
90
|
|
|
'both' => __( 'A minimum order amount AND a coupon', 'woocommerce' ), |
91
|
|
|
), |
92
|
|
|
), |
93
|
|
|
'min_amount' => array( |
94
|
|
|
'title' => __( 'Minimum Order Amount', 'woocommerce' ), |
95
|
|
|
'type' => 'price', |
96
|
|
|
'placeholder' => wc_format_localized_price( 0 ), |
97
|
|
|
'description' => __( 'Users will need to spend this amount to get free shipping (if enabled above).', 'woocommerce' ), |
98
|
|
|
'default' => '0', |
99
|
|
|
'desc_tip' => true, |
100
|
|
|
), |
101
|
|
|
); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Get setting form fields for instances of this shipping method within zones. |
106
|
|
|
* |
107
|
|
|
* @return array |
108
|
|
|
*/ |
109
|
|
|
public function get_instance_form_fields() { |
110
|
|
|
wc_enqueue_js( " |
111
|
|
|
jQuery( function( $ ) { |
112
|
|
|
function wcFreeShippingShowHideminAmountField( el ) { |
113
|
|
|
var form = $( el ).closest( 'form' ); |
114
|
|
|
var minAmountField = $( '#woocommerce_free_shipping_min_amount', form ).closest( 'tr' ); |
115
|
|
|
if ( 'coupon' === $( el ).val() || '' === $( el ).val() ) { |
116
|
|
|
minAmountField.hide(); |
117
|
|
|
} else { |
118
|
|
|
minAmountField.show(); |
119
|
|
|
} |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
$( document.body ).on( 'change', '#woocommerce_free_shipping_requires', function() { |
123
|
|
|
wcFreeShippingShowHideminAmountField( this ); |
124
|
|
|
}); |
125
|
|
|
|
126
|
|
|
// Change while load. |
127
|
|
|
$( '#woocommerce_free_shipping_requires' ).change(); |
128
|
|
|
$( document.body ).on( 'wc_backbone_modal_loaded', function( evt, target ) { |
129
|
|
|
if ( 'wc-modal-shipping-method-settings' === target ) { |
130
|
|
|
wcFreeShippingShowHideminAmountField( $( '#wc-backbone-modal-dialog #woocommerce_free_shipping_requires', evt.currentTarget ) ); |
131
|
|
|
} |
132
|
|
|
} ); |
133
|
|
|
}); |
134
|
|
|
" ); |
135
|
|
|
|
136
|
|
|
return parent::get_instance_form_fields(); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* See if free shipping is available based on the package and cart. |
141
|
|
|
* |
142
|
|
|
* @param array $package Shipping package. |
143
|
|
|
* @return bool |
144
|
|
|
*/ |
145
|
|
|
public function is_available( $package ) { |
146
|
|
|
$has_coupon = false; |
147
|
|
|
$has_met_min_amount = false; |
148
|
|
|
|
149
|
|
|
if ( in_array( $this->requires, array( 'coupon', 'either', 'both' ) ) ) { |
150
|
|
|
if ( $coupons = WC()->cart->get_coupons() ) { |
151
|
|
|
foreach ( $coupons as $code => $coupon ) { |
152
|
|
|
if ( $coupon->is_valid() && $coupon->enable_free_shipping() ) { |
153
|
|
|
$has_coupon = true; |
154
|
|
|
break; |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ) ) && isset( WC()->cart->cart_contents_total ) ) { |
161
|
|
|
$total = WC()->cart->get_displayed_subtotal(); |
162
|
|
|
|
163
|
|
|
if ( 'incl' === WC()->cart->tax_display_cart ) { |
164
|
|
|
$total = $total - ( WC()->cart->get_cart_discount_total() + WC()->cart->get_cart_discount_tax_total() ); |
165
|
|
|
} else { |
166
|
|
|
$total = $total - WC()->cart->get_cart_discount_total(); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
if ( $total >= $this->min_amount ) { |
170
|
|
|
$has_met_min_amount = true; |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
switch ( $this->requires ) { |
175
|
|
|
case 'min_amount' : |
176
|
|
|
$is_available = $has_met_min_amount; |
177
|
|
|
break; |
178
|
|
|
case 'coupon' : |
179
|
|
|
$is_available = $has_coupon; |
180
|
|
|
break; |
181
|
|
|
case 'both' : |
182
|
|
|
$is_available = $has_met_min_amount && $has_coupon; |
183
|
|
|
break; |
184
|
|
|
case 'either' : |
185
|
|
|
$is_available = $has_met_min_amount || $has_coupon; |
186
|
|
|
break; |
187
|
|
|
default : |
188
|
|
|
$is_available = true; |
189
|
|
|
break; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package ); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Called to calculate shipping rates for this method. Rates can be added using the add_rate() method. |
197
|
|
|
* |
198
|
|
|
* @uses WC_Shipping_Method::add_rate() |
199
|
|
|
* |
200
|
|
|
* @param array $package Shipping package. |
201
|
|
|
*/ |
202
|
|
|
public function calculate_shipping( $package = array() ) { |
203
|
|
|
$this->add_rate( array( |
204
|
|
|
'label' => $this->title, |
205
|
|
|
'cost' => 0, |
206
|
|
|
'taxes' => false, |
207
|
|
|
'package' => $package, |
208
|
|
|
) ); |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.