Completed
Pull Request — master (#11471)
by Claudio
09:36
created

WC_Shipping_Free_Shipping::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 13
Ratio 100 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 7
c 1
b 1
f 0
nc 1
nop 0
dl 13
loc 13
rs 9.4285
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 ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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