/includes/admin/class-wc-admin-setup-wizard.php

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