WC_Settings_Shipping::get_sections()   B
last analyzed

Complexity

Conditions 5
Paths 2

Size

Total Lines 22
Code Lines 13

Duplication

Lines 12
Ratio 54.55 %

Importance

Changes 0
Metric Value
cc 5
dl 12
loc 22
rs 8.6737
c 0
b 0
f 0
eloc 13
nc 2
nop 0
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( 'type' => 'sectionend', 'id' => 'shipping_options' ),
115
116
		) );
117
118
		return apply_filters( 'woocommerce_get_settings_' . $this->id, $settings );
119
	}
120
121
	/**
122
	 * Output the settings.
123
	 */
124
	public function output() {
125
		global $current_section, $hide_save_button;
126
127
		// Load shipping methods so we can show any global options they may have
128
		$shipping_methods = WC()->shipping->load_shipping_methods();
129
130
		if ( '' === $current_section ) {
131
			$this->output_zones_screen();
132
		} elseif ( 'options' === $current_section ) {
133
			$settings = $this->get_settings();
134
			WC_Admin_Settings::output_fields( $settings );
135
		} elseif ( 'classes' === $current_section ) {
136
			$hide_save_button = true;
137
			$this->output_shipping_class_screen();
138
		} else {
139
			foreach ( $shipping_methods as $method ) {
140
				if ( in_array( $current_section, array( $method->id, sanitize_title( get_class( $method ) ) ) ) && $method->has_settings() ) {
141
					$method->admin_options();
142
				}
143
			}
144
		}
145
	}
146
147
	/**
148
	 * Save settings.
149
	 */
150
	public function save() {
151
		global $current_section;
152
153
		switch ( $current_section ) {
154
			case 'options' :
155
				WC_Admin_Settings::save_fields( $this->get_settings() );
156
			break;
157
			case 'classes' :
158
			case '' :
159
			break;
160
			default :
161
				$wc_shipping = WC_Shipping::instance();
162
163
				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...
164
					if ( in_array( $current_section, array( $method->id, sanitize_title( get_class( $method ) ) ) ) ) {
165
						do_action( 'woocommerce_update_options_' . $this->id . '_' . $method->id );
166
					}
167
				}
168
			break;
169
		}
170
171
		// Increments the transient version to invalidate cache
172
		WC_Cache_Helper::get_transient_version( 'shipping', true );
173
	}
174
175
	/**
176
	 * Handles output of the shipping zones page in admin.
177
	 */
178
	protected function output_zones_screen() {
179
		global $hide_save_button;
180
181
		if ( isset( $_REQUEST['zone_id'] ) ) {
182
			$hide_save_button = true;
183
			$this->zone_methods_screen( absint( $_REQUEST['zone_id'] ) );
184
		} elseif ( isset( $_REQUEST['instance_id'] ) ) {
185
			$this->instance_settings_screen( absint( $_REQUEST['instance_id'] ) );
186
		} else {
187
			$hide_save_button = true;
188
			$this->zones_screen();
189
		}
190
	}
191
192
	/**
193
	 * Show method for a zone
194
	 * @param  int $zone_id
195
	 */
196
	protected function zone_methods_screen( $zone_id ) {
197
		$wc_shipping      = WC_Shipping      ::instance();
198
		$zone             = WC_Shipping_Zones::get_zone( $zone_id );
199
		$shipping_methods = $wc_shipping->get_shipping_methods();
200
201
		if ( ! $zone ) {
202
			wp_die( __( 'Zone does not exist!', 'woocommerce' ) );
203
		}
204
205
		wp_localize_script( 'wc-shipping-zone-methods', 'shippingZoneMethodsLocalizeScript', array(
206
			'methods'                 => $zone->get_shipping_methods(),
207
			'zone_id'                 => $zone->get_zone_id(),
208
			'wc_shipping_zones_nonce' => wp_create_nonce( 'wc_shipping_zones_nonce' ),
209
			'strings'                 => array(
210
				'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ),
211
				'save_changes_prompt'     => __( 'Do you wish to save your changes first? Your changed data will be discarded if you choose to cancel.', 'woocommerce' ),
212
				'save_failed'             => __( 'Your changes were not saved. Please retry.', 'woocommerce' ),
213
				'add_method_failed'       => __( 'Shipping method could not be added. Please retry.', 'woocommerce' ),
214
				'yes'                     => __( 'Yes', 'woocommerce' ),
215
				'no'                      => __( 'No', 'woocommerce' ),
216
			),
217
		) );
218
		wp_enqueue_script( 'wc-shipping-zone-methods' );
219
220
		include_once( 'views/html-admin-page-shipping-zone-methods.php' );
221
	}
222
223
	/**
224
	 * Show zones
225
	 */
226
	protected function zones_screen() {
227
		global $wpdb;
228
229
		$allowed_countries = WC()->countries->get_allowed_countries();
230
		$continents        = WC()->countries->get_continents();
231
		$method_count      = wc_get_shipping_method_count();
232
233
		wp_localize_script( 'wc-shipping-zones', 'shippingZonesLocalizeScript', array(
234
			'zones'         => WC_Shipping_Zones::get_zones(),
235
			'default_zone'  => array(
236
				'zone_id'    => 0,
237
				'zone_name'  => '',
238
				'zone_order' => null,
239
			),
240
			'wc_shipping_zones_nonce'  => wp_create_nonce( 'wc_shipping_zones_nonce' ),
241
			'strings'       => array(
242
				'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ),
243
				'save_failed'             => __( 'Your changes were not saved. Please retry.', 'woocommerce' ),
244
			),
245
		) );
246
		wp_enqueue_script( 'wc-shipping-zones' );
247
248
		include_once( 'views/html-admin-page-shipping-zones.php' );
249
	}
250
251
	/**
252
	 * Show instance settings
253
	 * @param  int $instance_id
254
	 */
255
	protected function instance_settings_screen( $instance_id ) {
256
		$zone            = WC_Shipping_Zones::get_zone_by( 'instance_id', $instance_id );
257
		$shipping_method = WC_Shipping_Zones::get_shipping_method( $instance_id );
258
259
		if ( ! $shipping_method ) {
260
			wp_die( __( 'Invalid shipping method!', 'woocommerce' ) );
261
		}
262
		if ( ! $zone ) {
263
			wp_die( __( 'Zone does not exist!', 'woocommerce' ) );
264
		}
265
		if ( ! $shipping_method->has_settings() ) {
266
			wp_die( __( 'This shipping method does not have any settings to configure.', 'woocommerce' ) );
267
		}
268
269
		if ( ! empty( $_POST['save'] ) ) {
270
271
			if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
272
				echo '<div class="updated error"><p>' . __( 'Edit failed. Please try again.', 'woocommerce' ) . '</p></div>';
273
			}
274
275
			$shipping_method->process_admin_options();
276
			$shipping_method->display_errors();
277
		}
278
279
		include_once( 'views/html-admin-page-shipping-zones-instance.php' );
280
	}
281
282
	/**
283
	 * Handles output of the shipping class settings screen.
284
	 */
285
	protected function output_shipping_class_screen() {
286
		$wc_shipping = WC_Shipping::instance();
287
		wp_localize_script( 'wc-shipping-classes', 'shippingClassesLocalizeScript', array(
288
			'classes'         => $wc_shipping->get_shipping_classes(),
289
			'default_shipping_class'  => array(
290
				'term_id'     => 0,
291
				'name'        => '',
292
				'description' => '',
293
			),
294
			'wc_shipping_classes_nonce' => wp_create_nonce( 'wc_shipping_classes_nonce' ),
295
			'strings'       => array(
296
				'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ),
297
				'save_failed'             => __( 'Your changes were not saved. Please retry.', 'woocommerce' )
298
			),
299
		) );
300
		wp_enqueue_script( 'wc-shipping-classes' );
301
302
		// Extendable columns to show on the shipping classes screen.
303
		$shipping_class_columns = apply_filters( 'woocommerce_shipping_classes_columns', array(
304
			'wc-shipping-class-name'        => __( 'Shipping Class', 'woocommerce' ),
305
			'wc-shipping-class-slug'        => __( 'Slug', 'woocommerce' ),
306
			'wc-shipping-class-description' => __( 'Description', 'woocommerce' ),
307
			'wc-shipping-class-count'       => __( 'Product Count', 'woocommerce' ),
308
		) );
309
310
		include_once( 'views/html-admin-page-shipping-classes.php' );
311
	}
312
}
313
314
endif;
315
316
return new WC_Settings_Shipping();
317