Completed
Pull Request — master (#11765)
by Mike
10:39
created

WC_Settings_Shipping::get_settings()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 56
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 41
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 56
rs 9.7251

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * WooCommerce Shipping Settings
4
 *
5
 * @author      WooThemes
6
 * @category    Admin
7
 * @package     WooCommerce/Admin
8
 * @version     2.6.0
9
 */
10
11
if ( ! defined( 'ABSPATH' ) ) {
12
	exit;
13
}
14
15
if ( ! class_exists( 'WC_Settings_Shipping' ) ) :
16
17
/**
18
 * WC_Settings_Shipping.
19
 */
20
class WC_Settings_Shipping extends WC_Settings_Page {
21
22
	/**
23
	 * Constructor.
24
	 */
25 View Code Duplication
	public function __construct() {
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...
26
		$this->id    = 'shipping';
27
		$this->label = __( 'Shipping', 'woocommerce' );
28
		add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
29
		add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_sections' ) );
30
		add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
31
		add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
32
	}
33
34
	/**
35
	 * Add this page to settings.
36
	 */
37
	public function add_settings_page( $pages ) {
38
		return wc_shipping_enabled() ? parent::add_settings_page( $pages ) : $pages;
39
	}
40
41
	/**
42
	 * Get sections.
43
	 *
44
	 * @return array
45
	 */
46
	public function get_sections() {
47
		$sections = array(
48
			''        => __( 'Shipping Zones', 'woocommerce' ),
49
			'options' => __( 'Shipping Options', 'woocommerce' ),
50
			'classes' => __( 'Shipping Classes', 'woocommerce' )
51
		);
52
53 View Code Duplication
		if ( ! defined( 'WC_INSTALLING' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
54
			// Load shipping methods so we can show any global options they may have
55
			$shipping_methods = WC()->shipping->load_shipping_methods();
56
57
			foreach ( $shipping_methods as $method ) {
58
				if ( ! $method->has_settings() ) {
59
					continue;
60
				}
61
				$title = empty( $method->method_title ) ? ucfirst( $method->id ) : $method->method_title;
62
				$sections[ strtolower( $method->id ) ] = esc_html( $title );
63
			}
64
		}
65
66
		return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections );
67
	}
68
69
	/**
70
	 * Get settings array.
71
	 *
72
	 * @return array
73
	 */
74
	public function get_settings() {
75
		$settings = apply_filters( 'woocommerce_shipping_settings', array(
76
77
			array( 'title' => __( 'Shipping Options', 'woocommerce' ), 'type' => 'title', 'id' => 'shipping_options' ),
78
79
			array(
80
				'title'         => __( 'Calculations', 'woocommerce' ),
81
				'desc'          => __( 'Enable the shipping calculator on the cart page', 'woocommerce' ),
82
				'id'            => 'woocommerce_enable_shipping_calc',
83
				'default'       => 'yes',
84
				'type'          => 'checkbox',
85
				'checkboxgroup' => 'start',
86
				'autoload'      => false
87
			),
88
89
			array(
90
				'desc'          => __( 'Hide shipping costs until an address is entered', 'woocommerce' ),
91
				'id'            => 'woocommerce_shipping_cost_requires_address',
92
				'default'       => 'no',
93
				'type'          => 'checkbox',
94
				'checkboxgroup' => 'end',
95
				'autoload'      => false
96
			),
97
98
			array(
99
				'title'   => __( 'Shipping Destination', 'woocommerce' ),
100
				'desc'    => __( 'This controls which shipping address is used by default.', 'woocommerce' ),
101
				'id'      => 'woocommerce_ship_to_destination',
102
				'default' => 'billing',
103
				'type'    => 'radio',
104
				'options' => array(
105
					'shipping'     => __( 'Default to customer shipping address', 'woocommerce' ),
106
					'billing'      => __( 'Default to customer billing address', 'woocommerce' ),
107
					'billing_only' => __( 'Force shipping to the customer billing address', 'woocommerce' ),
108
				),
109
				'autoload'        => false,
110
				'desc_tip'        =>  true,
111
				'show_if_checked' => 'option',
112
			),
113
114
			array(
115
				'title'    => __( 'Debug Mode', 'woocommerce' ),
116
				'desc'     => __( 'Enable Debug Mode', 'woocommerce' ),
117
				'desc_tip' => __( 'Enable Shipping Debug Mode to show matching shipping zones and to bypass shipping rate cache.', 'woocommerce' ),
118
				'id'       => 'woocommerce_shipping_debug_mode',
119
				'default'  => 'no',
120
				'type'     => 'checkbox',
121
				'autoload' => false
122
			),
123
124
			array( 'type' => 'sectionend', 'id' => 'shipping_options' ),
125
126
		) );
127
128
		return apply_filters( 'woocommerce_get_settings_' . $this->id, $settings );
129
	}
130
131
	/**
132
	 * Output the settings.
133
	 */
134
	public function output() {
135
		global $current_section, $hide_save_button;
136
137
		// Load shipping methods so we can show any global options they may have
138
		$shipping_methods = WC()->shipping->load_shipping_methods();
139
140
		if ( '' === $current_section ) {
141
			$this->output_zones_screen();
142
		} elseif ( 'options' === $current_section ) {
143
			$settings = $this->get_settings();
144
			WC_Admin_Settings::output_fields( $settings );
145
		} elseif ( 'classes' === $current_section ) {
146
			$hide_save_button = true;
147
			$this->output_shipping_class_screen();
148
		} else {
149
			foreach ( $shipping_methods as $method ) {
150
				if ( in_array( $current_section, array( $method->id, sanitize_title( get_class( $method ) ) ) ) && $method->has_settings() ) {
151
					$method->admin_options();
152
				}
153
			}
154
		}
155
	}
156
157
	/**
158
	 * Save settings.
159
	 */
160
	public function save() {
161
		global $current_section;
162
163
		switch ( $current_section ) {
164
			case 'options' :
165
				WC_Admin_Settings::save_fields( $this->get_settings() );
166
			break;
167
			case 'classes' :
168
			case '' :
169
			break;
170
			default :
171
				$wc_shipping = WC_Shipping::instance();
172
173
				foreach ( $wc_shipping->get_shipping_methods() as $method_id => $method ) {
0 ignored issues
show
Bug introduced by
The expression $wc_shipping->get_shipping_methods() of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
174
					if ( in_array( $current_section, array( $method->id, sanitize_title( get_class( $method ) ) ) ) ) {
175
						do_action( 'woocommerce_update_options_' . $this->id . '_' . $method->id );
176
					}
177
				}
178
			break;
179
		}
180
181
		// Increments the transient version to invalidate cache
182
		WC_Cache_Helper::get_transient_version( 'shipping', true );
183
	}
184
185
	/**
186
	 * Handles output of the shipping zones page in admin.
187
	 */
188
	protected function output_zones_screen() {
189
		global $hide_save_button;
190
191
		if ( isset( $_REQUEST['zone_id'] ) ) {
192
			$hide_save_button = true;
193
			$this->zone_methods_screen( absint( $_REQUEST['zone_id'] ) );
194
		} elseif ( isset( $_REQUEST['instance_id'] ) ) {
195
			$this->instance_settings_screen( absint( $_REQUEST['instance_id'] ) );
196
		} else {
197
			$hide_save_button = true;
198
			$this->zones_screen();
199
		}
200
	}
201
202
	/**
203
	 * Show method for a zone
204
	 * @param  int $zone_id
205
	 */
206
	protected function zone_methods_screen( $zone_id ) {
207
		$wc_shipping      = WC_Shipping      ::instance();
208
		$zone             = WC_Shipping_Zones::get_zone( $zone_id );
209
		$shipping_methods = $wc_shipping->get_shipping_methods();
210
211
		if ( ! $zone ) {
212
			wp_die( __( 'Zone does not exist!', 'woocommerce' ) );
213
		}
214
215
		wp_localize_script( 'wc-shipping-zone-methods', 'shippingZoneMethodsLocalizeScript', array(
216
			'methods'                 => $zone->get_shipping_methods(),
217
			'zone_id'                 => $zone->get_zone_id(),
218
			'wc_shipping_zones_nonce' => wp_create_nonce( 'wc_shipping_zones_nonce' ),
219
			'strings'                 => array(
220
				'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ),
221
				'save_changes_prompt'     => __( 'Do you wish to save your changes first? Your changed data will be discarded if you choose to cancel.', 'woocommerce' ),
222
				'save_failed'             => __( 'Your changes were not saved. Please retry.', 'woocommerce' ),
223
				'add_method_failed'       => __( 'Shipping method could not be added. Please retry.', 'woocommerce' ),
224
				'yes'                     => __( 'Yes', 'woocommerce' ),
225
				'no'                      => __( 'No', 'woocommerce' ),
226
			),
227
		) );
228
		wp_enqueue_script( 'wc-shipping-zone-methods' );
229
230
		include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-zone-methods.php' );
231
	}
232
233
	/**
234
	 * Show zones
235
	 */
236
	protected function zones_screen() {
237
		global $wpdb;
238
239
		$allowed_countries = WC()->countries->get_allowed_countries();
240
		$continents        = WC()->countries->get_continents();
241
		$method_count      = wc_get_shipping_method_count();
242
243
		wp_localize_script( 'wc-shipping-zones', 'shippingZonesLocalizeScript', array(
244
			'zones'         => WC_Shipping_Zones::get_zones(),
245
			'default_zone'  => array(
246
				'zone_id'    => 0,
247
				'zone_name'  => '',
248
				'zone_order' => null,
249
			),
250
			'wc_shipping_zones_nonce'  => wp_create_nonce( 'wc_shipping_zones_nonce' ),
251
			'strings'       => array(
252
				'unload_confirmation_msg'     => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ),
253
				'save_failed'                 => __( 'Your changes were not saved. Please retry.', 'woocommerce' ),
254
				'no_shipping_methods_offered' => __( 'No shipping methods offered to this zone.', 'woocommerce' ),
255
			),
256
		) );
257
		wp_enqueue_script( 'wc-shipping-zones' );
258
259
		include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-zones.php' );
260
	}
261
262
	/**
263
	 * Show instance settings
264
	 * @param  int $instance_id
265
	 */
266
	protected function instance_settings_screen( $instance_id ) {
267
		$zone            = WC_Shipping_Zones::get_zone_by( 'instance_id', $instance_id );
268
		$shipping_method = WC_Shipping_Zones::get_shipping_method( $instance_id );
269
270
		if ( ! $shipping_method ) {
271
			wp_die( __( 'Invalid shipping method!', 'woocommerce' ) );
272
		}
273
		if ( ! $zone ) {
274
			wp_die( __( 'Zone does not exist!', 'woocommerce' ) );
275
		}
276
		if ( ! $shipping_method->has_settings() ) {
277
			wp_die( __( 'This shipping method does not have any settings to configure.', 'woocommerce' ) );
278
		}
279
280
		if ( ! empty( $_POST['save'] ) ) {
281
282
			if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
283
				echo '<div class="updated error"><p>' . __( 'Edit failed. Please try again.', 'woocommerce' ) . '</p></div>';
284
			}
285
286
			$shipping_method->process_admin_options();
287
			$shipping_method->display_errors();
288
		}
289
290
		include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-zones-instance.php' );
291
	}
292
293
	/**
294
	 * Handles output of the shipping class settings screen.
295
	 */
296
	protected function output_shipping_class_screen() {
297
		$wc_shipping = WC_Shipping::instance();
298
		wp_localize_script( 'wc-shipping-classes', 'shippingClassesLocalizeScript', array(
299
			'classes'         => $wc_shipping->get_shipping_classes(),
300
			'default_shipping_class'  => array(
301
				'term_id'     => 0,
302
				'name'        => '',
303
				'description' => '',
304
			),
305
			'wc_shipping_classes_nonce' => wp_create_nonce( 'wc_shipping_classes_nonce' ),
306
			'strings'       => array(
307
				'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ),
308
				'save_failed'             => __( 'Your changes were not saved. Please retry.', 'woocommerce' )
309
			),
310
		) );
311
		wp_enqueue_script( 'wc-shipping-classes' );
312
313
		// Extendable columns to show on the shipping classes screen.
314
		$shipping_class_columns = apply_filters( 'woocommerce_shipping_classes_columns', array(
315
			'wc-shipping-class-name'        => __( 'Shipping Class', 'woocommerce' ),
316
			'wc-shipping-class-slug'        => __( 'Slug', 'woocommerce' ),
317
			'wc-shipping-class-description' => __( 'Description', 'woocommerce' ),
318
			'wc-shipping-class-count'       => __( 'Product Count', 'woocommerce' ),
319
		) );
320
321
		include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-classes.php' );
322
	}
323
}
324
325
endif;
326
327
return new WC_Settings_Shipping();
328