Issues (1182)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/admin/class-wc-admin-setup-wizard.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Setup Wizard Class
4
 *
5
 * Takes new users through some basic steps to setup their store.
6
 *
7
 * @author      WooThemes
8
 * @category    Admin
9
 * @package     WooCommerce/Admin
10
 * @version     2.4.0
11
*/
12
if ( ! defined( 'ABSPATH' ) ) {
13
	exit;
14
}
15
16
/**
17
 * WC_Admin_Setup_Wizard class.
18
 */
19
class WC_Admin_Setup_Wizard {
20
21
	/** @var string Currenct Step */
22
	private $step   = '';
23
24
	/** @var array Steps for the setup wizard */
25
	private $steps  = array();
26
27
	/** @var array Tweets user can optionally send after install */
28
	private $tweets = array(
29
		'Someone give me woo-t, I just set up a new store with #WordPress and @WooCommerce!',
30
		'Someone give me high five, I just set up a new store with #WordPress and @WooCommerce!'
31
	);
32
33
	/**
34
	 * Hook in tabs.
35
	 */
36
	public function __construct() {
37
		if ( apply_filters( 'woocommerce_enable_setup_wizard', true ) && current_user_can( 'manage_woocommerce' ) ) {
38
			add_action( 'admin_menu', array( $this, 'admin_menus' ) );
39
			add_action( 'admin_init', array( $this, 'setup_wizard' ) );
40
		}
41
	}
42
43
	/**
44
	 * Add admin menus/screens.
45
	 */
46
	public function admin_menus() {
47
		add_dashboard_page( '', '', 'manage_options', 'wc-setup', '' );
48
	}
49
50
	/**
51
	 * Show the setup wizard.
52
	 */
53
	public function setup_wizard() {
54
		if ( empty( $_GET['page'] ) || 'wc-setup' !== $_GET['page'] ) {
55
			return;
56
		}
57
		$this->steps = array(
58
			'introduction' => array(
59
				'name'    =>  __( 'Introduction', 'woocommerce' ),
60
				'view'    => array( $this, 'wc_setup_introduction' ),
61
				'handler' => ''
62
			),
63
			'pages' => array(
64
				'name'    =>  __( 'Page Setup', 'woocommerce' ),
65
				'view'    => array( $this, 'wc_setup_pages' ),
66
				'handler' => array( $this, 'wc_setup_pages_save' )
67
			),
68
			'locale' => array(
69
				'name'    =>  __( 'Store Locale', 'woocommerce' ),
70
				'view'    => array( $this, 'wc_setup_locale' ),
71
				'handler' => array( $this, 'wc_setup_locale_save' )
72
			),
73
			'shipping_taxes' => array(
74
				'name'    =>  __( 'Shipping &amp; Tax', 'woocommerce' ),
75
				'view'    => array( $this, 'wc_setup_shipping_taxes' ),
76
				'handler' => array( $this, 'wc_setup_shipping_taxes_save' ),
77
			),
78
			'payments' => array(
79
				'name'    =>  __( 'Payments', 'woocommerce' ),
80
				'view'    => array( $this, 'wc_setup_payments' ),
81
				'handler' => array( $this, 'wc_setup_payments_save' ),
82
			),
83
			'next_steps' => array(
84
				'name'    =>  __( 'Ready!', 'woocommerce' ),
85
				'view'    => array( $this, 'wc_setup_ready' ),
86
				'handler' => ''
87
			)
88
		);
89
		$this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
90
		$suffix     = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
91
92
		wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true );
93
		wp_register_script( 'select2', WC()->plugin_url() . '/assets/js/select2/select2' . $suffix . '.js', array( 'jquery' ), '3.5.2' );
94
		wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'select2' ), WC_VERSION );
95
		wp_localize_script( 'wc-enhanced-select', 'wc_enhanced_select_params', array(
96
			'i18n_matches_1'            => _x( 'One result is available, press enter to select it.', 'enhanced select', 'woocommerce' ),
97
			'i18n_matches_n'            => _x( '%qty% results are available, use up and down arrow keys to navigate.', 'enhanced select', 'woocommerce' ),
98
			'i18n_no_matches'           => _x( 'No matches found', 'enhanced select', 'woocommerce' ),
99
			'i18n_ajax_error'           => _x( 'Loading failed', 'enhanced select', 'woocommerce' ),
100
			'i18n_input_too_short_1'    => _x( 'Please enter 1 or more characters', 'enhanced select', 'woocommerce' ),
101
			'i18n_input_too_short_n'    => _x( 'Please enter %qty% or more characters', 'enhanced select', 'woocommerce' ),
102
			'i18n_input_too_long_1'     => _x( 'Please delete 1 character', 'enhanced select', 'woocommerce' ),
103
			'i18n_input_too_long_n'     => _x( 'Please delete %qty% characters', 'enhanced select', 'woocommerce' ),
104
			'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'woocommerce' ),
105
			'i18n_selection_too_long_n' => _x( 'You can only select %qty% items', 'enhanced select', 'woocommerce' ),
106
			'i18n_load_more'            => _x( 'Loading more results&hellip;', 'enhanced select', 'woocommerce' ),
107
			'i18n_searching'            => _x( 'Searching&hellip;', 'enhanced select', 'woocommerce' ),
108
			'ajax_url'                  => admin_url( 'admin-ajax.php' ),
109
			'search_products_nonce'     => wp_create_nonce( 'search-products' ),
110
			'search_customers_nonce'    => wp_create_nonce( 'search-customers' )
111
		) );
112
		wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
113
		wp_enqueue_style( 'wc-setup', WC()->plugin_url() . '/assets/css/wc-setup.css', array( 'dashicons', 'install' ), WC_VERSION );
114
115
		wp_register_script( 'wc-setup', WC()->plugin_url() . '/assets/js/admin/wc-setup.min.js', array( 'jquery', 'wc-enhanced-select', 'jquery-blockui' ), WC_VERSION );
116
		wp_localize_script( 'wc-setup', 'wc_setup_params', array(
117
			'locale_info' => json_encode( include( WC()->plugin_path() . '/i18n/locale-info.php' ) )
118
		) );
119
120
		if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) {
121
			call_user_func( $this->steps[ $this->step ]['handler'] );
122
		}
123
124
		ob_start();
125
		$this->setup_wizard_header();
126
		$this->setup_wizard_steps();
127
		$this->setup_wizard_content();
128
		$this->setup_wizard_footer();
129
		exit;
130
	}
131
132
	public function get_next_step_link() {
133
		$keys = array_keys( $this->steps );
134
		return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ) ) + 1 ] );
135
	}
136
137
	/**
138
	 * Setup Wizard Header.
139
	 */
140
	public function setup_wizard_header() {
141
		?>
142
		<!DOCTYPE html>
143
		<html <?php language_attributes(); ?>>
144
		<head>
145
			<meta name="viewport" content="width=device-width" />
146
			<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
147
			<title><?php _e( 'WooCommerce &rsaquo; Setup Wizard', 'woocommerce' ); ?></title>
148
			<?php wp_print_scripts( 'wc-setup' ); ?>
149
			<?php do_action( 'admin_print_styles' ); ?>
150
			<?php do_action( 'admin_head' ); ?>
151
		</head>
152
		<body class="wc-setup wp-core-ui">
153
			<h1 id="wc-logo"><a href="https://woothemes.com/woocommerce"><img src="<?php echo WC()->plugin_url(); ?>/assets/images/woocommerce_logo.png" alt="WooCommerce" /></a></h1>
154
		<?php
155
	}
156
157
	/**
158
	 * Setup Wizard Footer.
159
	 */
160
	public function setup_wizard_footer() {
161
		?>
162
			<?php if ( 'next_steps' === $this->step ) : ?>
163
				<a class="wc-return-to-dashboard" href="<?php echo esc_url( admin_url() ); ?>"><?php _e( 'Return to the WordPress Dashboard', 'woocommerce' ); ?></a>
164
			<?php endif; ?>
165
			</body>
166
		</html>
167
		<?php
168
	}
169
170
	/**
171
	 * Output the steps.
172
	 */
173
	public function setup_wizard_steps() {
174
		$ouput_steps = $this->steps;
175
		array_shift( $ouput_steps );
176
		?>
177
		<ol class="wc-setup-steps">
178
			<?php foreach ( $ouput_steps as $step_key => $step ) : ?>
179
				<li class="<?php
180
					if ( $step_key === $this->step ) {
181
						echo 'active';
182
					} elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
183
						echo 'done';
184
					}
185
				?>"><?php echo esc_html( $step['name'] ); ?></li>
186
			<?php endforeach; ?>
187
		</ol>
188
		<?php
189
	}
190
191
	/**
192
	 * Output the content for the current step.
193
	 */
194
	public function setup_wizard_content() {
195
		echo '<div class="wc-setup-content">';
196
		call_user_func( $this->steps[ $this->step ]['view'] );
197
		echo '</div>';
198
	}
199
200
	/**
201
	 * Introduction step.
202
	 */
203
	public function wc_setup_introduction() {
204
		?>
205
		<h1><?php _e( 'Welcome to the world of WooCommerce!', 'woocommerce' ); ?></h1>
206
		<p><?php _e( 'Thank you for choosing WooCommerce to power your online store! This quick setup wizard will help you configure the basic settings. <strong>It’s completely optional and shouldn’t take longer than five minutes.</strong>', 'woocommerce' ); ?></p>
207
		<p><?php _e( 'No time right now? If you don’t want to go through the wizard, you can skip and return to the WordPress dashboard. Come back anytime if you change your mind!', 'woocommerce' ); ?></p>
208
		<p class="wc-setup-actions step">
209
			<a href="<?php echo esc_url( $this->get_next_step_link() ); ?>" class="button-primary button button-large button-next"><?php _e( 'Let\'s Go!', 'woocommerce' ); ?></a>
210
			<a href="<?php echo esc_url( admin_url() ); ?>" class="button button-large"><?php _e( 'Not right now', 'woocommerce' ); ?></a>
211
		</p>
212
		<?php
213
	}
214
215
	/**
216
	 * Page setup.
217
	 */
218
	public function wc_setup_pages() {
219
		?>
220
		<h1><?php _e( 'Page Setup', 'woocommerce' ); ?></h1>
221
		<form method="post">
222
			<p><?php printf( __( 'Your store needs a few essential %spages%s. The following will be created automatically (if they do not already exist):', 'woocommerce' ), '<a href="' . esc_url( admin_url( 'edit.php?post_type=page' ) ) . '" target="_blank">', '</a>' ); ?></p>
223
			<table class="wc-setup-pages" cellspacing="0">
224
				<thead>
225
					<tr>
226
						<th class="page-name"><?php _e( 'Page Name', 'woocommerce' ); ?></th>
227
						<th class="page-description"><?php _e( 'Description', 'woocommerce' ); ?></th>
228
					</tr>
229
				</thead>
230
				<tbody>
231
					<tr>
232
						<td class="page-name"><?php echo _x( 'Shop', 'Page title', 'woocommerce' ); ?></td>
233
						<td><?php _e( 'The shop page will display your products.', 'woocommerce' ); ?></td>
234
					</tr>
235
					<tr>
236
						<td class="page-name"><?php echo _x( 'Cart', 'Page title', 'woocommerce' ); ?></td>
237
						<td><?php _e( 'The cart page will be where the customers go to view their cart and begin checkout.', 'woocommerce' ); ?></td>
238
					</tr>
239
					<tr>
240
						<td class="page-name"><?php echo _x( 'Checkout', 'Page title', 'woocommerce' ); ?></td>
241
						<td>
242
							<?php _e( 'The checkout page will be where the customers go to pay for their items.', 'woocommerce' ); ?>
243
						</td>
244
					</tr>
245
					<tr>
246
						<td class="page-name"><?php echo _x( 'My Account', 'Page title', 'woocommerce' ); ?></td>
247
						<td>
248
							<?php _e( 'Registered customers will be able to manage their account details and view past orders on this page.', 'woocommerce' ); ?>
249
						</td>
250
					</tr>
251
				</tbody>
252
			</table>
253
254
			<p><?php printf( __( 'Once created, these pages can be managed from your admin dashboard on the %sPages screen%s. You can control which pages are shown on your website via %sAppearance > Menus%s.', 'woocommerce' ), '<a href="' . esc_url( admin_url( 'edit.php?post_type=page' ) ) . '" target="_blank">', '</a>', '<a href="' . esc_url( admin_url( 'nav-menus.php' ) ) . '" target="_blank">', '</a>' ); ?></p>
255
256
			<p class="wc-setup-actions step">
257
				<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
258
				<a href="<?php echo esc_url( $this->get_next_step_link() ); ?>" class="button button-large button-next"><?php _e( 'Skip this step', 'woocommerce' ); ?></a>
259
				<?php wp_nonce_field( 'wc-setup' ); ?>
260
			</p>
261
		</form>
262
		<?php
263
	}
264
265
	/**
266
	 * Save Page Settings.
267
	 */
268
	public function wc_setup_pages_save() {
269
		check_admin_referer( 'wc-setup' );
270
271
		WC_Install::create_pages();
272
		wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
273
		exit;
274
	}
275
276
	/**
277
	 * Locale settings.
278
	 */
279
	public function wc_setup_locale() {
280
		$user_location  = WC_Geolocation::geolocate_ip();
281
		$country        = ! empty( $user_location['country'] ) ? $user_location['country'] : 'US';
282
		$state          = ! empty( $user_location['state'] ) ? $user_location['state'] : '*';
283
		$state          = 'US' === $country && '*' === $state ? 'AL' : $state;
284
285
		// Defaults
286
		$currency       = get_option( 'woocommerce_currency', 'GBP' );
287
		$currency_pos   = get_option( 'woocommerce_currency_pos', 'left' );
288
		$decimal_sep    = get_option( 'woocommerce_price_decimal_sep', '.' );
289
		$num_decimals   = get_option( 'woocommerce_price_num_decimals', '2' );
290
		$thousand_sep   = get_option( 'woocommerce_price_thousand_sep', ',' );
291
		$dimension_unit = get_option( 'woocommerce_dimension_unit', 'cm' );
292
		$weight_unit    = get_option( 'woocommerce_weight_unit', 'kg' );
293
		?>
294
		<h1><?php _e( 'Store Locale Setup', 'woocommerce' ); ?></h1>
295
		<form method="post">
296
			<table class="form-table">
297
				<tr>
298
					<th scope="row"><label for="store_location"><?php _e( 'Where is your store based?', 'woocommerce' ); ?></label></th>
299
					<td>
300
					<select id="store_location" name="store_location" style="width:100%;" required data-placeholder="<?php esc_attr_e( 'Choose a country&hellip;', 'woocommerce' ); ?>" class="wc-enhanced-select">
301
							<?php WC()->countries->country_dropdown_options( $country, $state ); ?>
302
						</select>
303
					</td>
304
				</tr>
305
				<tr>
306
					<th scope="row"><label for="currency_code"><?php _e( 'Which currency will your store use?', 'woocommerce' ); ?></label></th>
307
					<td>
308
						<select id="currency_code" name="currency_code" style="width:100%;" data-placeholder="<?php esc_attr_e( 'Choose a currency&hellip;', 'woocommerce' ); ?>" class="wc-enhanced-select">
309
							<option value=""><?php _e( 'Choose a currency&hellip;', 'woocommerce' ); ?></option>
310
							<?php
311
							foreach ( get_woocommerce_currencies() as $code => $name ) {
312
								echo '<option value="' . esc_attr( $code ) . '" ' . selected( $currency, $code, false ) . '>' . esc_html( $name . ' (' . get_woocommerce_currency_symbol( $code ) . ')' ) . '</option>';
313
							}
314
							?>
315
						</select>
316
						<span class="description"><?php printf( __( 'If your currency is not listed you can %sadd it later%s.', 'woocommerce' ), '<a href="https://docs.woothemes.com/document/add-a-custom-currency-symbol/" target="_blank">', '</a>' ); ?></span>
317
					</td>
318
				</tr>
319
				<tr>
320
					<th scope="row"><label for="currency_pos"><?php _e( 'Currency Position', 'woocommerce' ); ?></label></th>
321
					<td>
322
						<select id="currency_pos" name="currency_pos" class="wc-enhanced-select">
323
							<option value="left" <?php selected( $currency_pos, 'left' ); ?>><?php echo __( 'Left', 'woocommerce' ); ?></option>
324
							<option value="right" <?php selected( $currency_pos, 'right' ); ?>><?php echo __( 'Right', 'woocommerce' ); ?></option>
325
							<option value="left_space" <?php selected( $currency_pos, 'left_space' ); ?>><?php echo __( 'Left with space', 'woocommerce' ); ?></option>
326
							<option value="right_space" <?php selected( $currency_pos, 'right_space' ); ?>><?php echo __( 'Right with space', 'woocommerce' ); ?></option>
327
						</select>
328
					</td>
329
				</tr>
330
				<tr>
331
					<th scope="row"><label for="thousand_sep"><?php _e( 'Thousand Separator', 'woocommerce' ); ?></label></th>
332
					<td>
333
						<input type="text" id="thousand_sep" name="thousand_sep" size="2" value="<?php echo esc_attr( $thousand_sep ) ; ?>" />
334
					</td>
335
				</tr>
336
				<tr>
337
					<th scope="row"><label for="decimal_sep"><?php _e( 'Decimal Separator', 'woocommerce' ); ?></label></th>
338
					<td>
339
						<input type="text" id="decimal_sep" name="decimal_sep" size="2" value="<?php echo esc_attr( $decimal_sep ) ; ?>" />
340
					</td>
341
				</tr>
342
				<tr>
343
					<th scope="row"><label for="num_decimals"><?php _e( 'Number of Decimals', 'woocommerce' ); ?></label></th>
344
					<td>
345
						<input type="text" id="num_decimals" name="num_decimals" size="2" value="<?php echo esc_attr( $num_decimals ) ; ?>" />
346
					</td>
347
				</tr>
348
				<tr>
349
					<th scope="row"><label for="weight_unit"><?php _e( 'Which unit should be used for product weights?', 'woocommerce' ); ?></label></th>
350
					<td>
351
						<select id="weight_unit" name="weight_unit" class="wc-enhanced-select">
352
							<option value="kg" <?php selected( $weight_unit, 'kg' ); ?>><?php echo __( 'kg', 'woocommerce' ); ?></option>
353
							<option value="g" <?php selected( $weight_unit, 'g' ); ?>><?php echo __( 'g', 'woocommerce' ); ?></option>
354
							<option value="lbs" <?php selected( $weight_unit, 'lbs' ); ?>><?php echo __( 'lbs', 'woocommerce' ); ?></option>
355
							<option value="oz" <?php selected( $weight_unit, 'oz' ); ?>><?php echo __( 'oz', 'woocommerce' ); ?></option>
356
						</select>
357
					</td>
358
				</tr>
359
				<tr>
360
					<th scope="row"><label for="dimension_unit"><?php _e( 'Which unit should be used for product dimensions?', 'woocommerce' ); ?></label></th>
361
					<td>
362
						<select id="dimension_unit" name="dimension_unit" class="wc-enhanced-select">
363
							<option value="m" <?php selected( $dimension_unit, 'm' ); ?>><?php echo __( 'm', 'woocommerce' ); ?></option>
364
							<option value="cm" <?php selected( $dimension_unit, 'cm' ); ?>><?php echo __( 'cm', 'woocommerce' ); ?></option>
365
							<option value="mm" <?php selected( $dimension_unit, 'mm' ); ?>><?php echo __( 'mm', 'woocommerce' ); ?></option>
366
							<option value="in" <?php selected( $dimension_unit, 'in' ); ?>><?php echo __( 'in', 'woocommerce' ); ?></option>
367
							<option value="yd" <?php selected( $dimension_unit, 'yd' ); ?>><?php echo __( 'yd', 'woocommerce' ); ?></option>
368
						</select>
369
					</td>
370
				</tr>
371
			</table>
372
			<p class="wc-setup-actions step">
373
				<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
374
				<a href="<?php echo esc_url( $this->get_next_step_link() ); ?>" class="button button-large button-next"><?php _e( 'Skip this step', 'woocommerce' ); ?></a>
375
				<?php wp_nonce_field( 'wc-setup' ); ?>
376
			</p>
377
		</form>
378
		<?php
379
	}
380
381
	/**
382
	 * Save Locale Settings.
383
	 */
384
	public function wc_setup_locale_save() {
385
		check_admin_referer( 'wc-setup' );
386
387
		$store_location = sanitize_text_field( $_POST['store_location'] );
388
		$currency_code  = sanitize_text_field( $_POST['currency_code'] );
389
		$currency_pos   = sanitize_text_field( $_POST['currency_pos'] );
390
		$decimal_sep    = sanitize_text_field( $_POST['decimal_sep'] );
391
		$num_decimals   = sanitize_text_field( $_POST['num_decimals'] );
392
		$thousand_sep   = sanitize_text_field( $_POST['thousand_sep'] );
393
		$weight_unit    = sanitize_text_field( $_POST['weight_unit'] );
394
		$dimension_unit = sanitize_text_field( $_POST['dimension_unit'] );
395
396
		update_option( 'woocommerce_default_country', $store_location );
397
		update_option( 'woocommerce_currency', $currency_code );
398
		update_option( 'woocommerce_currency_pos', $currency_pos );
399
		update_option( 'woocommerce_price_decimal_sep', $decimal_sep );
400
		update_option( 'woocommerce_price_num_decimals', $num_decimals );
401
		update_option( 'woocommerce_price_thousand_sep', $thousand_sep );
402
		update_option( 'woocommerce_weight_unit', $weight_unit );
403
		update_option( 'woocommerce_dimension_unit', $dimension_unit );
404
405
		wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
406
		exit;
407
	}
408
409
	/**
410
	 * Shipping and taxes.
411
	 */
412
	public function wc_setup_shipping_taxes() {
413
		?>
414
		<h1><?php _e( 'Shipping &amp; Tax Setup', 'woocommerce' ); ?></h1>
415
		<form method="post">
416
			<p><?php _e( 'If you will be charging sales tax, or shipping physical goods to customers, you can enable these below. This is optional and can be changed later.', 'woocommerce' ); ?></p>
417
			<table class="form-table">
418
				<tr>
419
					<th scope="row"><label for="woocommerce_calc_shipping"><?php _e( 'Will you be shipping products?', 'woocommerce' ); ?></label></th>
420
					<td>
421
						<input type="checkbox" id="woocommerce_calc_shipping" <?php checked( get_option( 'woocommerce_ship_to_countries', '' ) !== 'disabled', true ); ?> name="woocommerce_calc_shipping" class="input-checkbox" value="1" />
422
						<label for="woocommerce_calc_shipping"><?php _e( 'Yes, I will be shipping physical goods to customers', 'woocommerce' ); ?></label>
423
					</td>
424
				</tr>
425
				<tr>
426
					<th scope="row"><label for="woocommerce_calc_taxes"><?php _e( 'Will you be charging sales tax?', 'woocommerce' ); ?></label></th>
427
					<td>
428
						<input type="checkbox" <?php checked( get_option( 'woocommerce_calc_taxes', 'no' ), 'yes' ); ?> id="woocommerce_calc_taxes" name="woocommerce_calc_taxes" class="input-checkbox" value="1" />
429
						<label for="woocommerce_calc_taxes"><?php _e( 'Yes, I will be charging sales tax', 'woocommerce' ); ?></label>
430
					</td>
431
				</tr>
432
				<tr>
433
					<th scope="row"><label for="woocommerce_prices_include_tax"><?php _e( 'How will you enter product prices?', 'woocommerce' ); ?></label></th>
434
					<td>
435
						<label><input type="radio" <?php checked( get_option( 'woocommerce_prices_include_tax', 'no' ), 'yes' ); ?> id="woocommerce_prices_include_tax" name="woocommerce_prices_include_tax" class="input-radio" value="yes" /> <?php _e( 'I will enter prices inclusive of tax', 'woocommerce' ); ?></label><br/>
436
						<label><input type="radio" <?php checked( get_option( 'woocommerce_prices_include_tax', 'no' ), 'no' ); ?> id="woocommerce_prices_include_tax" name="woocommerce_prices_include_tax" class="input-radio" value="no" /> <?php _e( 'I will enter prices exclusive of tax', 'woocommerce' ); ?></label>
437
					</td>
438
				</tr>
439
				<?php
440
					$locale_info = include( WC()->plugin_path() . '/i18n/locale-info.php' );
441
					$tax_rates   = array();
442
					$country     = WC()->countries->get_base_country();
443
					$state       = WC()->countries->get_base_state();
444
445 View Code Duplication
					if ( isset( $locale_info[ $country ] ) ) {
0 ignored issues
show
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...
446
						if ( isset( $locale_info[ $country ]['tax_rates'][ $state ] ) ) {
447
							$tax_rates = $locale_info[ $country ]['tax_rates'][ $state ];
448
						} elseif ( isset( $locale_info[ $country ]['tax_rates'][''] ) ) {
449
							$tax_rates = $locale_info[ $country ]['tax_rates'][''];
450
						}
451
						if ( isset( $locale_info[ $country ]['tax_rates']['*'] ) ) {
452
							$tax_rates = array_merge( $locale_info[ $country ]['tax_rates']['*'], $tax_rates );
453
						}
454
					}
455
					if ( $tax_rates ) {
456
						?>
457
						<tr class="tax-rates">
458
							<td colspan="2">
459
								<p><?php printf( __( 'The following tax rates will be imported automatically for you. You can read more about taxes in %1$sour documentation%2$s.', 'woocommerce' ), '<a href="https://docs.woothemes.com/document/setting-up-taxes-in-woocommerce/" target="_blank">', '</a>' ); ?></p>
460
								<div class="importing-tax-rates">
461
									<table class="tax-rates">
462
										<thead>
463
											<tr>
464
												<th><?php _e( 'Country', 'woocommerce' ); ?></th>
465
												<th><?php _e( 'State', 'woocommerce' ); ?></th>
466
												<th><?php _e( 'Rate (%)', 'woocommerce' ); ?></th>
467
												<th><?php _e( 'Name', 'woocommerce' ); ?></th>
468
											</tr>
469
										</thead>
470
										<tbody>
471
											<?php
472
												foreach ( $tax_rates as $rate ) {
473
													?>
474
													<tr>
475
														<td class="readonly"><?php echo esc_attr( $rate['country'] ); ?></td>
476
														<td class="readonly"><?php echo esc_attr( $rate['state'] ? $rate['state'] : '*' ); ?></td>
477
														<td class="readonly"><?php echo esc_attr( $rate['rate'] ); ?></td>
478
														<td class="readonly"><?php echo esc_attr( $rate['name'] ); ?></td>
479
													</tr>
480
													<?php
481
												}
482
											?>
483
										</tbody>
484
									</table>
485
								</div>
486
								<p class="description"><?php printf( __( 'You may you need to add/edit rates based on your products or business location which can be done from the %1$stax settings%2$s screen. If in doubt, speak to an accountant.', 'woocommerce' ), '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=tax' ) . '" target="_blank">', '</a>' ); ?></p>
487
							</td>
488
						</tr>
489
						<?php
490
					}
491
				?>
492
			</table>
493
			<p class="wc-setup-actions step">
494
				<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
495
				<a href="<?php echo esc_url( $this->get_next_step_link() ); ?>" class="button button-large button-next"><?php _e( 'Skip this step', 'woocommerce' ); ?></a>
496
				<?php wp_nonce_field( 'wc-setup' ); ?>
497
			</p>
498
		</form>
499
		<?php
500
	}
501
502
	/**
503
	 * Save shipping and tax options.
504
	 */
505
	public function wc_setup_shipping_taxes_save() {
506
		check_admin_referer( 'wc-setup' );
507
508
		$enable_shipping = isset( $_POST['woocommerce_calc_shipping'] );
509
		$enable_taxes    = isset( $_POST['woocommerce_calc_taxes'] );
510
511
		if ( $enable_shipping ) {
512
			update_option( 'woocommerce_ship_to_countries', '' );
513
			WC_Admin_Notices::add_notice( 'no_shipping_methods' );
514
		} else {
515
			update_option( 'woocommerce_ship_to_countries', 'disabled' );
516
		}
517
518
		update_option( 'woocommerce_calc_taxes', $enable_taxes ? 'yes' : 'no' );
519
		update_option( 'woocommerce_prices_include_tax', sanitize_text_field( $_POST['woocommerce_prices_include_tax'] ) );
520
521
		if ( $enable_taxes ) {
522
			$locale_info = include( WC()->plugin_path() . '/i18n/locale-info.php' );
523
			$tax_rates   = array();
524
			$country     = WC()->countries->get_base_country();
525
			$state       = WC()->countries->get_base_state();
526
527 View Code Duplication
			if ( isset( $locale_info[ $country ] ) ) {
0 ignored issues
show
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...
528
				if ( isset( $locale_info[ $country ]['tax_rates'][ $state ] ) ) {
529
					$tax_rates = $locale_info[ $country ]['tax_rates'][ $state ];
530
				} elseif ( isset( $locale_info[ $country ]['tax_rates'][''] ) ) {
531
					$tax_rates = $locale_info[ $country ]['tax_rates'][''];
532
				}
533
				if ( isset( $locale_info[ $country ]['tax_rates']['*'] ) ) {
534
					$tax_rates = array_merge( $locale_info[ $country ]['tax_rates']['*'], $tax_rates );
535
				}
536
			}
537
			if ( $tax_rates ) {
538
				$loop = 0;
539
				foreach ( $tax_rates as $rate ) {
540
					$tax_rate = array(
541
						'tax_rate_country'  => $rate['country'],
542
						'tax_rate_state'    => $rate['state'],
543
						'tax_rate'          => $rate['rate'],
544
						'tax_rate_name'     => $rate['name'],
545
						'tax_rate_priority' => isset( $rate['priority'] ) ? absint( $rate['priority'] ) : 1,
546
						'tax_rate_compound' => 0,
547
						'tax_rate_shipping' => $rate['shipping'] ? 1 : 0,
548
						'tax_rate_order'    => $loop ++,
549
						'tax_rate_class'    => ''
550
					);
551
					WC_Tax::_insert_tax_rate( $tax_rate );
552
				}
553
			}
554
		}
555
556
		wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
557
		exit;
558
	}
559
560
	/**
561
	 * Simple array of gateways to show in wizard.
562
	 * @return array
563
	 */
564
	protected function get_wizard_payment_gateways() {
565
		$gateways = array(
566
			'paypal-braintree' => array(
567
				'name'        => __( 'PayPal by Braintree', 'woocommerce' ),
568
				'image'       => WC()->plugin_url() . '/assets/images/paypal-braintree.png',
569
				'description' => sprintf( __( 'Safe and secure payments using credit cards or your customer\'s PayPal account. %sLearn more about PayPal%s.', 'woocommerce' ), '<a href="https://wordpress.org/plugins/woocommerce-gateway-paypal-powered-by-braintree/" target="_blank">', '</a>' ),
570
				'class'       => 'featured featured-row-last',
571
				'repo-slug'   => 'woocommerce-gateway-paypal-powered-by-braintree',
572
			),
573
			'paypal-ec' => array(
574
				'name'        => __( 'PayPal Express Checkout', 'woocommerce' ),
575
				'image'       => WC()->plugin_url() . '/assets/images/paypal.png',
576
				'description' => sprintf( __( 'Safe and secure payments using credit cards or your customer\'s PayPal account. %sLearn more about PayPal%s.', 'woocommerce' ), '<a href="https://wordpress.org/plugins/woocommerce-gateway-paypal-express-checkout/" target="_blank">', '</a>' ),
577
				'class'       => 'featured featured-row-last',
578
				'repo-slug'   => 'woocommerce-gateway-paypal-express-checkout',
579
			),
580
			'stripe' => array(
581
				'name'        => __( 'Stripe', 'woocommerce' ),
582
				'image'       => WC()->plugin_url() . '/assets/images/stripe.png',
583
				'description' => sprintf( __( 'A modern and robust way to accept credit card payments on your store. %sLearn more about Stripe%s.', 'woocommerce' ), '<a href="https://wordpress.org/plugins/woocommerce-gateway-stripe/" target="_blank">', '</a>' ),
584
				'class'       => 'featured featured-row-first',
585
				'repo-slug'   => 'woocommerce-gateway-stripe',
586
			),
587
			'paypal' => array(
588
				'name'        => __( 'PayPal Standard', 'woocommerce' ),
589
				'description' => __( 'Accept payments via PayPal using account balance or credit card.', 'woocommerce' ),
590
				'image'       => '',
591
				'class'       => '',
592
				'settings'    => array(
593
					'email' => array(
594
						'label'       => __( 'PayPal email address', 'woocommerce' ),
595
						'type'        => 'email',
596
						'value'       => get_option( 'admin_email' ),
597
						'placeholder' => __( 'PayPal email address', 'woocommerce' ),
598
					),
599
				),
600
			),
601
			'cheque' => array(
602
				'name'        => _x( 'Check Payments', 'Check payment method', 'woocommerce' ),
603
				'description' => __( 'An simple offline gateway that lets you accept a check as method of payment.', 'woocommerce' ),
604
				'image'       => '',
605
				'class'       => '',
606
			),
607
			'bacs' => array(
608
				'name'        => __( 'Bank Transfer (BACS) Payments', 'woocommerce' ),
609
				'description' => __( 'An simple offline gateway that lets you accept BACS payment.', 'woocommerce' ),
610
				'image'       => '',
611
				'class'       => '',
612
			),
613
			'cod' => array(
614
				'name'        => __( 'Cash on Delivery', 'woocommerce' ),
615
				'description' => __( 'An simple offline gateway that lets you accept cash on delivery.', 'woocommerce' ),
616
				'image'       => '',
617
				'class'       => '',
618
			)
619
		);
620
621
		$country = WC()->countries->get_base_country();
622
623
		if ( 'US' === $country ) {
624
			unset( $gateways['paypal-ec'] );
625
		} else {
626
			unset( $gateways['paypal-braintree'] );
627
		}
628
629
		if ( ! current_user_can( 'install_plugins' ) ) {
630
			unset( $gateways['paypal-braintree'] );
631
			unset( $gateways['paypal-ec'] );
632
			unset( $gateways['stripe'] );
633
		}
634
635
		return $gateways;
636
	}
637
638
	/**
639
	 * Payments Step.
640
	 */
641
	public function wc_setup_payments() {
642
		$gateways = $this->get_wizard_payment_gateways();
643
		?>
644
		<h1><?php _e( 'Payments', 'woocommerce' ); ?></h1>
645
		<form method="post" class="wc-wizard-payment-gateway-form">
646
			<p><?php printf( __( 'WooCommerce can accept both online and offline payments. %2$sAdditional payment methods%3$s can be installed later and managed from the %1$scheckout settings%3$s screen.', 'woocommerce' ), '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout' ) . '" target="_blank">', '<a href="' . admin_url( 'admin.php?page=wc-addons&view=payment-gateways' ) . '" target="_blank">', '</a>' ); ?></p>
647
648
			<ul class="wc-wizard-payment-gateways">
649
				<?php foreach ( $gateways as $gateway_id => $gateway ) : ?>
650
					<li class="wc-wizard-gateway wc-wizard-gateway-<?php echo esc_attr( $gateway_id ); ?> <?php echo esc_attr( $gateway['class'] ); ?>">
651
						<div class="wc-wizard-gateway-enable">
652
							<input type="checkbox" name="wc-wizard-gateway-<?php echo esc_attr( $gateway_id ); ?>-enabled" class="input-checkbox" value="yes" />
653
							<label>
654
								<?php if ( $gateway['image'] ) : ?>
655
									<img src="<?php echo esc_attr( $gateway['image'] ); ?>" alt="<?php echo esc_attr( $gateway['name'] ); ?>" />
656
								<?php else : ?>
657
									<?php echo esc_html( $gateway['name'] ); ?>
658
								<?php endif; ?>
659
							</label>
660
						</div>
661
						<div class="wc-wizard-gateway-description">
662
							<?php echo wp_kses_post( wpautop( $gateway['description'] ) ); ?>
663
						</div>
664
						<?php if ( ! empty( $gateway['settings'] ) ) : ?>
665
							<table class="form-table wc-wizard-gateway-settings">
666
								<?php foreach ( $gateway['settings'] as $setting_id => $setting ) : ?>
667
									<tr>
668
										<th scope="row"><label for="<?php echo esc_attr( $gateway_id ); ?>_<?php echo esc_attr( $setting_id ); ?>"><?php echo esc_html( $setting['label'] ); ?>:</label></th>
669
										<td>
670
											<input
671
												type="<?php echo esc_attr( $setting['type'] ); ?>"
672
												id="<?php echo esc_attr( $gateway_id ); ?>_<?php echo esc_attr( $setting_id ); ?>"
673
												name="<?php echo esc_attr( $gateway_id ); ?>_<?php echo esc_attr( $setting_id ); ?>"
674
												class="input-text"
675
												value="<?php echo esc_attr( $setting['value'] ); ?>"
676
												placeholder="<?php echo esc_attr( $setting['placeholder'] ); ?>"
677
												/>
678
										</td>
679
									</tr>
680
								<?php endforeach; ?>
681
							</table>
682
						<?php endif; ?>
683
					</li>
684
				<?php endforeach; ?>
685
			</ul>
686
			<p class="wc-setup-actions step">
687
				<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
688
				<a href="<?php echo esc_url( $this->get_next_step_link() ); ?>" class="button button-large button-next"><?php _e( 'Skip this step', 'woocommerce' ); ?></a>
689
				<?php wp_nonce_field( 'wc-setup' ); ?>
690
			</p>
691
		</form>
692
		<?php
693
	}
694
695
	/**
696
	 * Payments Step save.
697
	 */
698
	public function wc_setup_payments_save() {
699
		check_admin_referer( 'wc-setup' );
700
701
		$gateways = $this->get_wizard_payment_gateways();
702
703
		foreach ( $gateways as $gateway_id => $gateway ) {
704
			// If repo-slug is defined, download and install plugin from .org.
705
			if ( ! empty( $gateway['repo-slug'] ) && ! empty( $_POST[ 'wc-wizard-gateway-' . $gateway_id . '-enabled' ] ) ) {
706
				wp_schedule_single_event( time() + 10, 'woocommerce_plugin_background_installer', array( $gateway_id, $gateway ) );
707
			}
708
709
			$settings_key        = 'woocommerce_' . $gateway_id . '_settings';
710
			$settings            = array_filter( (array) get_option( $settings_key, array() ) );
711
			$settings['enabled'] = ! empty( $_POST[ 'wc-wizard-gateway-' . $gateway_id . '-enabled' ] ) ? 'yes' : 'no';
712
713
			if ( ! empty( $gateway['settings'] ) ) {
714
				foreach ( $gateway['settings'] as $setting_id => $setting ) {
715
					$settings[ $setting_id ] = wc_clean( $_POST[ $gateway_id . '_' . $setting_id ] );
716
				}
717
			}
718
719
			update_option( $settings_key, $settings );
720
		}
721
722
		wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
723
		exit;
724
	}
725
726
	/**
727
	 * Actions on the final step.
728
	 */
729
	private function wc_setup_ready_actions() {
730
		WC_Admin_Notices::remove_notice( 'install' );
731
732
		if ( isset( $_GET['wc_tracker_optin'] ) && isset( $_GET['wc_tracker_nonce'] ) && wp_verify_nonce( $_GET['wc_tracker_nonce'], 'wc_tracker_optin' ) ) {
733
			update_option( 'woocommerce_allow_tracking', 'yes' );
734
			WC_Tracker::send_tracking_data( true );
735
736
		} elseif ( isset( $_GET['wc_tracker_optout'] ) && isset( $_GET['wc_tracker_nonce'] ) && wp_verify_nonce( $_GET['wc_tracker_nonce'], 'wc_tracker_optout' ) ) {
737
			update_option( 'woocommerce_allow_tracking', 'no' );
738
		}
739
	}
740
741
	/**
742
	 * Final step.
743
	 */
744
	public function wc_setup_ready() {
745
		$this->wc_setup_ready_actions();
746
		shuffle( $this->tweets );
747
		?>
748
		<a href="https://twitter.com/share" class="twitter-share-button" data-url="https://www.woothemes.com/woocommerce/" data-text="<?php echo esc_attr( $this->tweets[0] ); ?>" data-via="WooThemes" data-size="large">Tweet</a>
749
		<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
750
751
		<h1><?php _e( 'Your Store is Ready!', 'woocommerce' ); ?></h1>
752
753
		<?php if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) : ?>
754
			<div class="woocommerce-message woocommerce-tracker">
755
				<p><?php printf( __( 'Want to help make WooCommerce even more awesome? Allow WooThemes to collect non-sensitive diagnostic data and usage information. %sFind out more%s.', 'woocommerce' ), '<a href="https://www.woothemes.com/woocommerce/usage-tracking/" target="_blank">', '</a>' ); ?></p>
756
				<p class="submit">
757
					<a class="button-primary button button-large" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc_tracker_optin', 'true' ), 'wc_tracker_optin', 'wc_tracker_nonce' ) ); ?>"><?php _e( 'Allow', 'woocommerce' ); ?></a>
758
					<a class="button-secondary button button-large skip"  href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc_tracker_optout', 'true' ), 'wc_tracker_optout', 'wc_tracker_nonce' ) ); ?>"><?php _e( 'No thanks', 'woocommerce' ); ?></a>
759
				</p>
760
			</div>
761
		<?php endif; ?>
762
763
		<div class="wc-setup-next-steps">
764
			<div class="wc-setup-next-steps-first">
765
				<h2><?php _e( 'Next Steps', 'woocommerce' ); ?></h2>
766
				<ul>
767
					<li class="setup-product"><a class="button button-primary button-large" href="<?php echo esc_url( admin_url( 'post-new.php?post_type=product&tutorial=true' ) ); ?>"><?php _e( 'Create your first product!', 'woocommerce' ); ?></a></li>
768
				</ul>
769
			</div>
770
			<div class="wc-setup-next-steps-last">
771
				<h2><?php _e( 'Learn More', 'woocommerce' ); ?></h2>
772
				<ul>
773
					<li class="video-walkthrough"><a href="https://docs.woothemes.com/document/woocommerce-101-video-series/?utm_source=WooCommercePlugin&amp;utm_medium=Wizard&amp;utm_content=Videos&amp;utm_campaign=Onboarding"><?php _e( 'Watch the WC 101 video walkthroughs', 'woocommerce' ); ?></a></li>
774
					<li class="newsletter"><a href="https://www.woothemes.com/woocommerce-onboarding-email/?utm_source=WooCommercePlugin&amp;utm_medium=Wizard&amp;utm_content=Newsletter&amp;utm_campaign=Onboarding"><?php _e( 'Get eCommerce advice in your inbox', 'woocommerce' ); ?></a></li>
775
					<li class="learn-more"><a href="https://docs.woothemes.com/documentation/plugins/woocommerce/getting-started/?utm_source=WooCommercePlugin&amp;utm_medium=Wizard&amp;utm_content=Docs&amp;utm_campaign=Onboarding"><?php _e( 'Learn more about getting started', 'woocommerce' ); ?></a></li>
776
				</ul>
777
			</div>
778
		</div>
779
		<?php
780
	}
781
}
782
783
new WC_Admin_Setup_Wizard();
784