Completed
Push — master ( 394da4...31ec7c )
by Mike
10:43
created

WC_Shipping_Legacy_Local_Pickup   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 206
Duplicated Lines 2.91 %

Coupling/Cohesion

Components 3
Dependencies 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 6
loc 206
rs 10
wmc 26
lcom 3
cbo 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	exit; // Exit if accessed directly
5
}
6
7
/**
8
 * Local Pickup Shipping Method.
9
 *
10
 * This class is here for backwards commpatility for methods existing before zones existed.
11
 *
12
 * @deprecated  2.6.0
13
 * @version		2.3.0
14
 * @package		WooCommerce/Classes/Shipping
15
 * @author 		WooThemes
16
 */
17
class WC_Shipping_Legacy_Local_Pickup extends WC_Shipping_Method {
18
19
	/**
20
	 * Constructor.
21
	 */
22
	public function __construct() {
23
		$this->id                 = 'legacy_local_pickup';
24
		$this->method_title       = __( 'Local Pickup (Legacy)', 'woocommerce' );
25
		$this->method_description = sprintf( __( '<strong>This method is deprecated in 2.6.0 and will be removed in future versions - we recommend disabling it and instead setting up a new rate within your <a href="%s">Shipping Zones</a>.</strong>', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping' ) );
26
		$this->init();
27
	}
28
29
	/**
30
	 * Process and redirect if disabled.
31
	 */
32
	public function process_admin_options() {
33
		parent::process_admin_options();
34
35
		if ( 'no' === $this->settings[ 'enabled' ] ) {
36
			wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=shipping&section=options' ) );
37
			exit;
38
		}
39
	}
40
	
41
	/**
42
	 * Return the name of the option in the WP DB.
43
	 * @since 2.6.0
44
	 * @return string
45
	 */
46
	public function get_option_key() {
47
		return $this->plugin_id . 'local_pickup' . '_settings';
48
	}
49
50
	/**
51
	 * init function.
52
	 */
53
	public function init() {
54
55
		// Load the settings.
56
		$this->init_form_fields();
57
		$this->init_settings();
58
59
		// Define user set variables
60
		$this->enabled		= $this->get_option( 'enabled' );
61
		$this->title		= $this->get_option( 'title' );
62
		$this->codes		= $this->get_option( 'codes' );
63
		$this->availability	= $this->get_option( 'availability' );
64
		$this->countries	= $this->get_option( 'countries' );
65
66
		// Actions
67
		add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
68
	}
69
70
	/**
71
	 * calculate_shipping function.
72
	 */
73
	public function calculate_shipping( $package = array() ) {
74
		$rate = array(
75
			'id' 		 => $this->id,
76
			'label' 	 => $this->title,
77
			'package'    => $package,
78
		);
79
		$this->add_rate( $rate );
80
	}
81
82
	/**
83
	 * init_form_fields function.
84
	 */
85
	public function init_form_fields() {
86
		$this->form_fields = array(
87
			'enabled' => array(
88
				'title'   => __( 'Enable', 'woocommerce' ),
89
				'type'    => 'checkbox',
90
				'label'   => __( 'Once disabled, this legacy method will no longer be available.', 'woocommerce' ),
91
				'default' => 'no'
92
			),
93
			'title' => array(
94
				'title'       => __( 'Title', 'woocommerce' ),
95
				'type'        => 'text',
96
				'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
97
				'default'     => __( 'Local Pickup', 'woocommerce' ),
98
				'desc_tip'    => true,
99
			),
100
			'codes' => array(
101
				'title'       => __( 'Allowed ZIP/Post Codes', 'woocommerce' ),
102
				'type'        => 'text',
103
				'desc_tip'    => __( 'What ZIP/post codes are available for local pickup?', 'woocommerce' ),
104
				'default'     => '',
105
				'description' => __( 'Separate codes with a comma. Accepts wildcards, e.g. <code>P*</code> will match a postcode of PE30. Also accepts a pattern, e.g. <code>NG1___</code> would match NG1 1AA but not NG10 1AA', 'woocommerce' ),
106
				'placeholder' => 'e.g. 12345, 56789'
107
			),
108
			'availability' => array(
109
				'title'    => __( 'Method availability', 'woocommerce' ),
110
				'type'     => 'select',
111
				'default'  => 'all',
112
				'class'    => 'availability wc-enhanced-select',
113
				'options'  => array(
114
					'all'      => __( 'All allowed countries', 'woocommerce' ),
115
					'specific' => __( 'Specific Countries', 'woocommerce' )
116
				)
117
			),
118
			'countries' => array(
119
				'title'             => __( 'Specific Countries', 'woocommerce' ),
120
				'type'              => 'multiselect',
121
				'class'             => 'wc-enhanced-select',
122
				'css'               => 'width: 450px;',
123
				'default'           => '',
124
				'options'           => WC()->countries->get_shipping_countries(),
125
				'custom_attributes' => array(
126
					'data-placeholder'  => __( 'Select some countries', 'woocommerce' )
127
				)
128
			)
129
		);
130
	}
131
132
	/**
133
	 * Get postcodes for this method.
134
	 * @return array
135
	 */
136
	public function get_valid_postcodes() {
137
		$codes = array();
138
139
		if ( $this->codes != '' ) {
140
			foreach( explode( ',', $this->codes ) as $code ) {
141
				$codes[] = strtoupper( trim( $code ) );
142
			}
143
		}
144
145
		return $codes;
146
	}
147
148
	/**
149
	 * See if a given postcode matches valid postcodes.
150
	 * @param  string postcode
151
	 * @param  string country code
152
	 * @return boolean
153
	 */
154
	public function is_valid_postcode( $postcode, $country ) {
155
		$codes              = $this->get_valid_postcodes();
156
		$postcode           = $this->clean( $postcode );
157
		$formatted_postcode = wc_format_postcode( $postcode, $country );
158
159
		if ( in_array( $postcode, $codes ) || in_array( $formatted_postcode, $codes ) ) {
160
			return true;
161
		}
162
163
		// Pattern matching
164
		foreach ( $codes as $c ) {
165
			$pattern = '/^' . str_replace( '_', '[0-9a-zA-Z]', preg_quote( $c ) ) . '$/i';
166
			if ( preg_match( $pattern, $postcode ) ) {
167
				return true;
168
			}
169
		}
170
171
		// Wildcard search
172
		$wildcard_postcode = $formatted_postcode . '*';
173
		$postcode_length   = strlen( $formatted_postcode );
174
175
		for ( $i = 0; $i < $postcode_length; $i++ ) {
176
			if ( in_array( $wildcard_postcode, $codes ) ) {
177
				return true;
178
			}
179
			$wildcard_postcode = substr( $wildcard_postcode, 0, -2 ) . '*';
180
		}
181
182
		return false;
183
	}
184
185
	/**
186
	 * See if the method is available.
187
	 *
188
	 * @param array $package
189
	 * @return bool
190
	 */
191
	public function is_available( $package ) {
192
		$is_available = "yes" === $this->enabled;
193
194
		if ( $is_available && $this->get_valid_postcodes() ) {
195
			$is_available = $this->is_valid_postcode( $package['destination']['postcode'], $package['destination']['country'] );
196
		}
197
198
		if ( $is_available ) {
199
			if ( $this->availability === 'specific' ) {
200
				$ship_to_countries = $this->countries;
201
			} else {
202
				$ship_to_countries = array_keys( WC()->countries->get_shipping_countries() );
203
			}
204
			if ( is_array( $ship_to_countries ) && ! in_array( $package['destination']['country'], $ship_to_countries ) ) {
205
				$is_available = false;
206
			}
207
		}
208
209
		return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package );
210
	}
211
212
	/**
213
	 * clean function.
214
	 *
215
	 * @access public
216
	 * @param mixed $code
217
	 * @return string
218
	 */
219
	public function clean( $code ) {
220
		return str_replace( '-', '', sanitize_title( $code ) ) . ( strstr( $code, '*' ) ? '*' : '' );
221
	}
222
}
223