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

1708 lines
64 KiB
PHP
Raw Normal View History

2015-04-28 12:19:16 +00:00
<?php
/**
2015-11-03 13:53:50 +00:00
* Setup Wizard Class
2015-04-28 12:19:16 +00:00
*
* Takes new users through some basic steps to setup their store.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
2016-06-13 15:14:35 +00:00
* @version 2.6.0
*/
2015-04-28 12:19:16 +00:00
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Admin_Setup_Wizard class.
2015-04-28 12:19:16 +00:00
*/
class WC_Admin_Setup_Wizard {
/** @var string Current Step */
2015-04-28 12:19:16 +00:00
private $step = '';
/** @var array Steps for the setup wizard */
private $steps = array();
/** @var array Actions to be executed after the HTTP response has completed */
private $deferred_actions = array();
2015-04-28 12:19:16 +00:00
/** @var array Tweets user can optionally send after install */
private $tweets = array(
2015-08-21 17:57:14 +00:00
'Someone give me woo-t, I just set up a new store with #WordPress and @WooCommerce!',
'Someone give me high five, I just set up a new store with #WordPress and @WooCommerce!',
2015-04-28 12:19:16 +00:00
);
/**
* Hook in tabs.
*/
public function __construct() {
2015-04-29 10:32:03 +00:00
if ( apply_filters( 'woocommerce_enable_setup_wizard', true ) && current_user_can( 'manage_woocommerce' ) ) {
add_action( 'admin_menu', array( $this, 'admin_menus' ) );
add_action( 'admin_init', array( $this, 'setup_wizard' ) );
}
2015-04-28 12:19:16 +00:00
}
/**
* Add admin menus/screens.
*/
public function admin_menus() {
add_dashboard_page( '', '', 'manage_options', 'wc-setup', '' );
}
/**
* The theme "extra" should only be shown if the current user can modify themes
* and the store doesn't already have a WooCommerce compatible theme.
*/
protected function should_show_theme_extra() {
return (
current_user_can( 'install_themes' ) &&
current_user_can( 'switch_themes' ) &&
! is_multisite() &&
! current_theme_supports( 'woocommerce' )
);
}
/**
* The "automated tax" extra should only be shown if the current user can
* install plugins and the store is in a supported country.
*/
protected function should_show_automated_tax_extra() {
if ( ! current_user_can( 'install_plugins' ) ) {
return false;
}
$country_code = WC()->countries->get_base_country();
// https://developers.taxjar.com/api/reference/#countries
$tax_supported_countries = array_merge(
array( 'US', 'CA', 'AU' ),
WC()->countries->get_european_union_countries()
);
return in_array( $country_code, $tax_supported_countries );
}
2015-04-28 12:19:16 +00:00
/**
* Show the setup wizard.
2015-04-28 12:19:16 +00:00
*/
public function setup_wizard() {
2015-04-28 12:27:56 +00:00
if ( empty( $_GET['page'] ) || 'wc-setup' !== $_GET['page'] ) {
2015-04-28 12:19:16 +00:00
return;
}
2017-03-28 21:45:12 +00:00
$default_steps = array(
'store_setup' => array(
'name' => __( 'Store setup', 'woocommerce' ),
'view' => array( $this, 'wc_setup_store_setup' ),
'handler' => array( $this, 'wc_setup_store_setup_save' ),
2015-04-28 12:19:16 +00:00
),
'payment' => array(
'name' => __( 'Payment', 'woocommerce' ),
'view' => array( $this, 'wc_setup_payment' ),
'handler' => array( $this, 'wc_setup_payment_save' ),
2015-04-28 12:19:16 +00:00
),
'shipping' => array(
'name' => __( 'Shipping', 'woocommerce' ),
'view' => array( $this, 'wc_setup_shipping' ),
'handler' => array( $this, 'wc_setup_shipping_save' ),
2015-04-28 12:19:16 +00:00
),
'extras' => array(
'name' => __( 'Extras', 'woocommerce' ),
'view' => array( $this, 'wc_setup_extras' ),
'handler' => array( $this, 'wc_setup_extras_save' ),
),
'activate' => array(
'name' => __( 'Activate', 'woocommerce' ),
'view' => array( $this, 'wc_setup_activate' ),
'handler' => array( $this, 'wc_setup_activate_save' ),
),
2015-04-28 12:19:16 +00:00
'next_steps' => array(
'name' => __( 'Ready!', 'woocommerce' ),
2015-04-28 12:19:16 +00:00
'view' => array( $this, 'wc_setup_ready' ),
'handler' => '',
),
2015-04-28 12:19:16 +00:00
);
2017-03-28 21:45:12 +00:00
// Hide the extras step if this store/user isn't eligible for them.
if ( ! $this->should_show_theme_extra() && ! $this->should_show_automated_tax_extra() ) {
unset( $default_steps['extras'] );
}
// Hide shipping step if the store is selling digital products only.
if ( 'virtual' === get_option( 'woocommerce_product_type' ) ) {
unset( $default_steps['shipping'] );
}
// Hide the activate step if Jetpack is already active, but not
// if we're returning from connecting Jetpack on WordPress.com.
if (
class_exists( 'Jetpack' ) &&
Jetpack::is_active() &&
! isset( $_GET['from'] ) &&
! isset( $_GET['activate_error'] )
) {
unset( $default_steps['activate'] );
}
// Whether or not there is a pending background install of Jetpack.
$pending_jetpack = ! class_exists( 'Jetpack' ) && get_option( 'woocommerce_setup_background_installing_jetpack' );
2017-03-28 21:45:12 +00:00
$this->steps = apply_filters( 'woocommerce_setup_wizard_steps', $default_steps );
2015-04-28 12:19:16 +00:00
$this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
2015-04-28 12:27:56 +00:00
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
2015-04-28 12:19:16 +00:00
wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true );
2017-07-06 15:43:10 +00:00
wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.0' );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), WC_VERSION );
2015-04-28 12:19:16 +00:00
wp_localize_script( 'wc-enhanced-select', 'wc_enhanced_select_params', array(
'i18n_no_matches' => _x( 'No matches found', 'enhanced select', 'woocommerce' ),
'i18n_ajax_error' => _x( 'Loading failed', 'enhanced select', 'woocommerce' ),
'i18n_input_too_short_1' => _x( 'Please enter 1 or more characters', 'enhanced select', 'woocommerce' ),
'i18n_input_too_short_n' => _x( 'Please enter %qty% or more characters', 'enhanced select', 'woocommerce' ),
'i18n_input_too_long_1' => _x( 'Please delete 1 character', 'enhanced select', 'woocommerce' ),
'i18n_input_too_long_n' => _x( 'Please delete %qty% characters', 'enhanced select', 'woocommerce' ),
'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'woocommerce' ),
'i18n_selection_too_long_n' => _x( 'You can only select %qty% items', 'enhanced select', 'woocommerce' ),
'i18n_load_more' => _x( 'Loading more results&hellip;', 'enhanced select', 'woocommerce' ),
'i18n_searching' => _x( 'Searching&hellip;', 'enhanced select', 'woocommerce' ),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'search_products_nonce' => wp_create_nonce( 'search-products' ),
'search_customers_nonce' => wp_create_nonce( 'search-customers' ),
2015-04-28 12:19:16 +00:00
) );
2015-04-28 12:27:56 +00:00
wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
wp_enqueue_style( 'wc-setup', WC()->plugin_url() . '/assets/css/wc-setup.css', array( 'dashicons', 'install' ), WC_VERSION );
wp_register_script( 'wc-setup', WC()->plugin_url() . '/assets/js/admin/wc-setup' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'jquery-blockui', 'wp-util' ), WC_VERSION );
2015-04-28 12:19:16 +00:00
wp_localize_script( 'wc-setup', 'wc_setup_params', array(
'pending_jetpack_install' => $pending_jetpack ? 'yes' : 'no',
2015-04-28 12:19:16 +00:00
) );
if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) {
2017-03-31 17:32:19 +00:00
call_user_func( $this->steps[ $this->step ]['handler'], $this );
2015-04-28 12:19:16 +00:00
}
2015-04-29 15:34:07 +00:00
ob_start();
2015-04-28 12:19:16 +00:00
$this->setup_wizard_header();
$this->setup_wizard_steps();
$this->setup_wizard_content();
$this->setup_wizard_footer();
exit;
}
2017-03-31 17:32:19 +00:00
/**
* Get the URL for the next step's screen.
* @param string step slug (default: current step)
* @return string URL for next step if a next step exists.
* Admin URL if it's the last step.
* Empty string on failure.
2017-04-03 18:24:01 +00:00
* @since 3.0.0
2017-03-31 17:32:19 +00:00
*/
public function get_next_step_link( $step = '' ) {
if ( ! $step ) {
$step = $this->step;
}
2015-04-28 12:19:16 +00:00
$keys = array_keys( $this->steps );
2017-03-31 17:32:19 +00:00
if ( end( $keys ) === $step ) {
return admin_url();
}
2017-03-31 17:32:19 +00:00
$step_index = array_search( $step, $keys );
if ( false === $step_index ) {
2017-04-03 16:54:24 +00:00
return '';
2017-03-31 17:32:19 +00:00
}
return add_query_arg( 'step', $keys[ $step_index + 1 ], remove_query_arg( 'activate_error' ) );
2015-04-28 12:19:16 +00:00
}
/**
* Setup Wizard Header.
2015-04-28 12:19:16 +00:00
*/
public function setup_wizard_header() {
?>
<!DOCTYPE html>
2016-05-27 01:48:49 +00:00
<html <?php language_attributes(); ?>>
2015-04-28 12:19:16 +00:00
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php esc_html_e( 'WooCommerce &rsaquo; Setup Wizard', 'woocommerce' ); ?></title>
2015-04-28 12:27:56 +00:00
<?php wp_print_scripts( 'wc-setup' ); ?>
<?php do_action( 'admin_print_styles' ); ?>
<?php do_action( 'admin_head' ); ?>
2015-04-28 12:19:16 +00:00
</head>
<body class="wc-setup wp-core-ui">
<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>
2015-04-28 12:19:16 +00:00
<?php
}
/**
* Setup Wizard Footer.
2015-04-28 12:19:16 +00:00
*/
public function setup_wizard_footer() {
?>
<?php if ( 'store_setup' === $this->step ) : ?>
<a class="wc-return-to-dashboard" href="<?php echo esc_url( admin_url() ); ?>"><?php esc_html_e( 'Not right now', 'woocommerce' ); ?></a>
<?php elseif ( 'next_steps' === $this->step ) : ?>
<a class="wc-return-to-dashboard" href="<?php echo esc_url( admin_url() ); ?>"><?php esc_html_e( 'Return to your dashboard', 'woocommerce' ); ?></a>
<?php elseif ( 'activate' === $this->step ) : ?>
<a class="wc-return-to-dashboard" href="<?php echo esc_url( $this->get_next_step_link() ); ?>"><?php esc_html_e( 'Skip this step', 'woocommerce' ); ?></a>
2015-06-09 14:54:46 +00:00
<?php endif; ?>
2015-04-28 12:19:16 +00:00
</body>
</html>
<?php
}
/**
* Output the steps.
2015-04-28 12:19:16 +00:00
*/
public function setup_wizard_steps() {
$output_steps = $this->steps;
2015-04-28 12:19:16 +00:00
?>
<ol class="wc-setup-steps">
<?php foreach ( $output_steps as $step_key => $step ) : ?>
2015-04-28 12:19:16 +00:00
<li class="<?php
if ( $step_key === $this->step ) {
echo 'active';
} elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
echo 'done';
}
?>"><?php echo esc_html( $step['name'] ); ?></li>
<?php endforeach; ?>
</ol>
<?php
}
/**
* Output the content for the current step.
2015-04-28 12:19:16 +00:00
*/
public function setup_wizard_content() {
echo '<div class="wc-setup-content">';
2017-03-31 17:32:19 +00:00
call_user_func( $this->steps[ $this->step ]['view'], $this );
2015-04-28 12:19:16 +00:00
echo '</div>';
}
/**
* Initial "store setup" step.
* Location, product type, page setup, and tracking opt-in.
*/
public function wc_setup_store_setup() {
$address = WC()->countries->get_base_address();
$address_2 = WC()->countries->get_base_address_2();
$city = WC()->countries->get_base_city();
$state = WC()->countries->get_base_state();
$country = WC()->countries->get_base_country();
$postcode = WC()->countries->get_base_postcode();
$currency = get_option( 'woocommerce_currency', 'GBP' );
$product_type = get_option( 'woocommerce_product_type' );
if ( empty( $country ) ) {
$user_location = WC_Geolocation::geolocate_ip();
$country = $user_location['country'];
$state = $user_location['state'];
} elseif ( empty( $state ) ) {
$state = '*';
}
?>
2017-09-22 21:56:35 +00:00
<form method="post" class="address-step">
<?php wp_nonce_field( 'wc-setup' ); ?>
2017-10-01 08:51:09 +00:00
<p class="store-setup"><?php esc_html_e( "The following wizard will help you configure your store and get you started quickly.", 'woocommerce' ); ?></p>
2017-09-22 21:56:35 +00:00
<label for="store_country_state" class="location-prompt">
<?php esc_html_e( 'Where is your store based?', 'woocommerce' ); ?>
</label>
<select
id="store_country_state"
name="store_country_state"
required
data-placeholder="<?php esc_attr_e( 'Choose a country&hellip;', 'woocommerce' ); ?>"
aria-label="<?php esc_attr_e( 'Country', 'woocommerce' ) ?>"
class="location-input wc-enhanced-select dropdown"
>
<?php WC()->countries->country_dropdown_options( $country, $state ); ?>
2017-09-22 21:56:35 +00:00
</select>
<div class="store-address-container">
<label class="location-prompt" for="store_address">
<?php esc_html_e( 'Address', 'woocommerce' ); ?>
</label>
<input
type="text"
id="store_address"
class="location-input"
name="store_address"
required
value="<?php echo esc_attr( $address ); ?>"
/>
<label class="location-prompt" for="store_address_2">
<?php esc_html_e( 'Address line 2', 'woocommerce' ); ?>
</label>
<input
type="text"
id="store_address_2"
class="location-input"
name="store_address_2"
value="<?php echo esc_attr( $address_2 ); ?>"
/>
<div class="city-and-postcode">
<div>
<label class="location-prompt" for="store_city">
<?php esc_html_e( 'City', 'woocommerce' ); ?>
</label>
<input
type="text"
id="store_city"
class="location-input"
name="store_city"
required
value="<?php echo esc_attr( $city ); ?>"
/>
</div>
<div>
<label class="location-prompt" for="store_postcode">
<?php esc_html_e( 'Postcode / ZIP', 'woocommerce' ); ?>
</label>
<input
type="text"
id="store_postcode"
class="location-input"
name="store_postcode"
required
value="<?php echo esc_attr( $postcode ); ?>"
/>
</div>
</div>
2017-09-22 21:56:35 +00:00
</div>
<label class="location-prompt" for="currency_code">
<?php esc_html_e( 'What currency do you use?', 'woocommerce' ); ?>
</label>
<select
id="currency_code"
name="currency_code"
required
data-placeholder="<?php esc_attr_e( 'Choose a currency&hellip;', 'woocommerce' ); ?>"
class="location-input wc-enhanced-select dropdown"
>
<option value=""><?php esc_html_e( 'Choose a currency&hellip;', 'woocommerce' ); ?></option>
<?php foreach ( get_woocommerce_currencies() as $code => $name ) : ?>
2017-09-22 21:56:35 +00:00
<option value="<?php echo esc_attr( $code ); ?>" <?php selected( $currency, $code ); ?>>
<?php printf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $name, get_woocommerce_currency_symbol( $code ) ); ?>
</option>
<?php endforeach; ?>
2017-09-22 21:56:35 +00:00
</select>
<label class="location-prompt" for="product_type">
<?php esc_html_e( 'What type of product do you plan to sell?', 'woocommerce' ); ?>
</label>
<select
id="product_type"
name="product_type"
required
data-placeholder="<?php esc_attr_e( 'Please choose one&hellip;', 'woocommerce' ); ?>"
class="location-input wc-enhanced-select dropdown"
>
<option value="" <?php selected( $product_type, '' ); ?>><?php esc_html_e( 'Please choose one&hellip;', 'woocommerce' ); ?></option>
<option value="physical" <?php selected( $product_type, 'physical' ); ?>><?php esc_html_e( 'I plan to sell physical products', 'woocommerce' ); ?></option>
<option value="virtual" <?php selected( $product_type, 'virtual' ); ?>><?php esc_html_e( 'I plan to sell digital products', 'woocommerce' ); ?></option>
<option value="both" <?php selected( $product_type, 'both' ); ?>><?php esc_html_e( 'I plan to sell both physical and digital products', 'woocommerce' ); ?></option>
2017-09-22 21:56:35 +00:00
</select>
<?php if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) : ?>
2017-10-01 08:04:37 +00:00
<div class="allow-tracking">
<input type="checkbox" id="wc_tracker_optin" name="wc_tracker_optin" value="yes" checked />
<label for="wc_tracker_optin"><?php _e( 'Allow WooCommerce to collect non-sensitive diagnostic data and usage information.', 'woocommerce' ); ?></label>
</div>
<?php endif; ?>
<p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( "Let's go!", 'woocommerce' ); ?>" name="save_step" />
</p>
</form>
<?php
}
/**
* Save initial store settings.
*/
public function wc_setup_store_setup_save() {
check_admin_referer( 'wc-setup' );
$address = sanitize_text_field( $_POST['store_address'] );
$address_2 = sanitize_text_field( $_POST['store_address_2'] );
$city = sanitize_text_field( $_POST['store_city'] );
$country_state = sanitize_text_field( $_POST['store_country_state'] );
$postcode = sanitize_text_field( $_POST['store_postcode'] );
$currency_code = sanitize_text_field( $_POST['currency_code'] );
$product_type = sanitize_text_field( $_POST['product_type'] );
$tracking = isset( $_POST['wc_tracker_optin'] ) && ( 'yes' === sanitize_text_field( $_POST['wc_tracker_optin'] ) );
update_option( 'woocommerce_store_address', $address );
update_option( 'woocommerce_store_address_2', $address_2 );
update_option( 'woocommerce_store_city', $city );
update_option( 'woocommerce_default_country', $country_state );
update_option( 'woocommerce_store_postcode', $postcode );
update_option( 'woocommerce_currency', $currency_code );
update_option( 'woocommerce_product_type', $product_type );
$locale_info = include( WC()->plugin_path() . '/i18n/locale-info.php' );
$country = WC()->countries->get_base_country();
// Set currency formatting options based on chosen location and currency.
if (
isset( $locale_info[ $country ] ) &&
$locale_info[ $country ]['currency_code'] === $currency_code
) {
update_option( 'woocommerce_currency_pos', $locale_info[ $country ]['currency_pos'] );
update_option( 'woocommerce_price_decimal_sep', $locale_info[ $country ]['decimal_sep'] );
update_option( 'woocommerce_price_num_decimals', $locale_info[ $country ]['num_decimals'] );
update_option( 'woocommerce_price_thousand_sep', $locale_info[ $country ]['thousand_sep'] );
}
if ( $tracking ) {
update_option( 'woocommerce_allow_tracking', 'yes' );
WC_Tracker::send_tracking_data( true );
} else {
update_option( 'woocommerce_allow_tracking', 'no' );
}
WC_Install::create_pages();
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}
/**
* Tout WooCommerce Services for North American stores.
*/
protected function wc_setup_wcs_tout() {
$base_location = wc_get_base_location();
if ( false === $base_location['country'] ) {
$base_location = WC_Geolocation::geolocate_ip();
}
if ( ! in_array( $base_location['country'], array( 'US', 'CA' ), true ) ) {
2017-05-31 11:00:10 +00:00
return;
}
$default_content = array(
'title' => __( 'Enable WooCommerce Shipping (recommended)', 'woocommerce' ),
'description' => __( 'Print labels and get discounted USPS shipping rates, right from your WooCommerce dashboard. Powered by WooCommerce Services.', 'woocommerce' ),
);
switch ( $base_location['country'] ) {
case 'CA':
$local_content = array(
'title' => __( 'Enable WooCommerce Shipping (recommended)', 'woocommerce' ),
2017-06-27 20:00:48 +00:00
'description' => __( 'Display live rates from Canada Post at checkout to make shipping a breeze. Powered by WooCommerce Services.', 'woocommerce' ),
);
break;
default:
$local_content = array();
}
$content = wp_parse_args( $local_content, $default_content );
2017-05-31 11:00:10 +00:00
?>
<ul class="wc-wizard-shipping-methods">
<li class="wc-wizard-shipping">
<div class="wc-wizard-shipping-enable">
<input type="checkbox" name="woocommerce_install_services" class="input-checkbox" value="woo-services-enabled" checked />
2017-05-31 11:00:10 +00:00
<label>
<?php echo esc_html( $content['title'] ) ?>
2017-05-31 11:00:10 +00:00
</label>
</div>
<div class="wc-wizard-shipping-description">
<p>
<?php echo esc_html( $content['description'] ); ?>
2017-05-31 11:00:10 +00:00
</p>
</div>
</li>
</ul>
<?php
}
/**
* Finishes replying to the client, but keeps the process running for further (async) code execution.
* @see https://core.trac.wordpress.org/ticket/41358
*/
protected function close_http_connection() {
// Only 1 PHP process can access a session object at a time, close this so the next request isn't kept waiting.
if ( session_id() ) {
session_write_close();
}
wc_set_time_limit( 0 );
// fastcgi_finish_request is the cleanest way to send the response and keep the script running, but not every server has it.
if ( is_callable( 'fastcgi_finish_request' ) ) {
fastcgi_finish_request();
} else {
// Fallback: send headers and flush buffers.
if ( ! headers_sent() ) {
header( 'Connection: close' );
}
@ob_end_flush();
flush();
}
}
/**
* Function called after the HTTP request is finished, so it's executed without the client having to wait for it.
* @see WC_Admin_Setup_Wizard::install_plugin
* @see WC_Admin_Setup_Wizard::install_theme
*/
public function run_deferred_actions() {
$this->close_http_connection();
foreach ( $this->deferred_actions as $action ) {
call_user_func_array( $action['func'], $action['args'] );
// Clear the background installation flag if this is a plugin.
if (
isset( $action['func'][1] ) &&
'background_installer' === $action['func'][1] &&
isset( $action['args'][0] )
) {
delete_option( 'woocommerce_setup_background_installing_' . $action['args'][0] );
}
}
}
/**
* Helper method to queue the background install of a plugin.
*
* @param string $plugin_id Plugin id used for background install.
* @param array $plugin_info Plugin info array containing at least main file and repo slug.
*/
protected function install_plugin( $plugin_id, $plugin_info ) {
// Make sure we don't trigger multiple simultaneous installs.
if ( get_option( 'woocommerce_setup_background_installing_' . $plugin_id ) ) {
return;
}
if ( ! empty( $plugin_info['file'] ) && is_plugin_active( $plugin_info['file'] ) ) {
return;
}
if ( empty( $this->deferred_actions ) ) {
add_action( 'shutdown', array( $this, 'run_deferred_actions' ) );
}
array_push( $this->deferred_actions, array(
'func' => array( 'WC_Install', 'background_installer' ),
'args' => array( $plugin_id, $plugin_info )
) );
// Set the background installation flag for this plugin.
update_option( 'woocommerce_setup_background_installing_' . $plugin_id, true );
}
/**
* Helper method to queue the background install of a theme.
*
* @param string $theme_id Theme id used for background install.
*/
protected function install_theme( $theme_id ) {
if ( empty( $this->deferred_actions ) ) {
add_action( 'shutdown', array( $this, 'run_deferred_actions' ) );
}
array_push( $this->deferred_actions, array(
'func' => array( 'WC_Install', 'theme_background_installer' ),
'args' => array( $theme_id )
) );
}
/**
* Helper method to install Jetpack.
*/
protected function install_jetpack() {
$this->install_plugin( 'jetpack', array(
'file' => 'jetpack/jetpack.php',
'name' => __( 'Jetpack', 'woocommerce' ),
'repo-slug' => 'jetpack',
) );
}
/**
* Helper method to install WooCommerce Services and its Jetpack dependency.
*/
protected function install_woocommerce_services() {
$this->install_jetpack();
$this->install_plugin( 'woocommerce-services', array(
'file' => 'woocommerce-services/woocommerce-services.php',
'name' => __( 'WooCommerce Services', 'woocommerce' ),
'repo-slug' => 'woocommerce-services',
) );
}
/**
* Get the WCS shipping carrier for a given country code.
*
* Can also be used to determine if WCS supports a given country.
*
* @param $country_code
* @return bool|string Carrier name if supported, boolean False otherwise.
*/
protected function get_wcs_shipping_carrier( $country_code ) {
switch ( $country_code ) {
case 'US':
return 'USPS';
case 'CA':
return 'Canada Post';
default:
return false;
}
}
/**
* Get shipping methods based on country code.
*
* @param $country_code
* @return array
*/
protected function get_wizard_shipping_methods( $country_code ) {
$shipping_methods = array(
'live_rates' => array(
'name' => __( 'Live Rates', 'woocommerce' ),
'description' => __( 'Live Rates powered by WooCommerce Services and Jetpack.', 'woocommerce' ),
),
'flat_rate' => array(
'name' => __( 'Flat Rate', 'woocommerce' ),
'description' => __( 'Set a fixed price to cover shipping costs.', 'woocommerce' ),
'settings' => array(
'cost' => array(
'type' => 'text',
'default_value' => __( 'Cost', 'Short label for entering the cost of an item', 'woocommerce' ),
'description' => __( 'What would you like to charge for flat rate shipping?', 'woocommerce' ),
'required' => true,
),
),
),
'free_shipping' => array(
'name' => __( 'Free Shipping', 'woocommerce' ),
'description' => __( "Don't charge for shipping.", 'woocommerce' ),
),
);
$live_rate_carrier = $this->get_wcs_shipping_carrier( $country_code );
if ( false === $live_rate_carrier || ! current_user_can('install_plugins') ) {
unset( $shipping_methods['live_rates'] );
}
return $shipping_methods;
}
/**
* Render the available shipping methods for a given country code.
*
* @param string $country_code
* @param string $input_prefix
*/
protected function shipping_method_selection_form( $country_code, $input_prefix ) {
$live_rate_carrier = $this->get_wcs_shipping_carrier( $country_code );
$selected = $live_rate_carrier ? 'live_rates' : 'flat_rate';
$shipping_methods = $this->get_wizard_shipping_methods( $country_code );
?>
<div class="wc-wizard-shipping-method-select">
<div class="wc-wizard-shipping-method-dropdown">
<select id="<?php echo esc_attr( "{$input_prefix}[method]" ); ?>" name="<?php echo esc_attr( "{$input_prefix}[method]" ); ?>" class="method wc-enhanced-select">
<?php foreach ( $shipping_methods as $method_id => $method ) : ?>
<option value="<?php echo esc_attr( $method_id ); ?>" <?php selected( $selected, $method_id ); ?>>
<?php echo esc_html( $method['name'] ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="shipping-method-descriptions">
<?php foreach ( $shipping_methods as $method_id => $method ) : ?>
<p class="shipping-method-description <?php echo esc_attr( $method_id ); ?> <?php if ( $method_id !== $selected ) echo 'hide'; ?>">
<?php echo esc_html( $method['description'] ); ?>
</p>
<?php endforeach; ?>
</div>
</div>
<div class="shipping-method-settings">
<?php foreach ( $shipping_methods as $method_id => $method ) : ?>
<?php if ( empty( $method['settings'] ) ) continue; ?>
<div class="shipping-method-setting <?php echo esc_attr( $method_id ); ?> <?php if ( $method_id !== $selected ) echo 'hide'; ?>">
<?php foreach ( $method['settings'] as $setting_id => $setting ) : ?>
<?php $method_setting_id = "{$input_prefix}[{$method_id}][{$setting_id}]"; ?>
<input
type="<?php echo esc_attr( $setting['type'] ); ?>"
placeholder="<?php echo esc_attr( $setting['default_value'] ); ?>"
id="<?php echo esc_attr( $method_setting_id ); ?>"
name="<?php echo esc_attr( $method_setting_id ); ?>"
2017-10-10 16:49:04 +00:00
class="<?php echo esc_attr( $setting['required'] ? 'shipping-method-required-field' : '' ); ?>"
<?php echo ( $method_id === $selected && $setting['required'] ) ? 'required' : ''; ?>
/>
<p class="description">
<?php echo esc_html( $setting['description'] ); ?>
</p>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
<?php
}
2015-04-28 12:19:16 +00:00
/**
* Shipping.
2015-04-28 12:19:16 +00:00
*/
public function wc_setup_shipping() {
2017-09-27 14:24:50 +00:00
$dimension_unit = get_option( 'woocommerce_dimension_unit', false );
$weight_unit = get_option( 'woocommerce_weight_unit', false );
$country_code = WC()->countries->get_base_country();
$country_name = WC()->countries->countries[ $country_code ];
$prefixed_country_name = WC()->countries->estimated_for_prefix( $country_code ) . $country_name;
$wcs_carrier = $this->get_wcs_shipping_carrier( $country_code );
$existing_zones = WC_Shipping_Zones::get_zones();
if ( false === $dimension_unit || false === $weight_unit ) {
if ( 'US' === $country_code ) {
$dimension_unit = 'in';
$weight_unit = 'oz';
} else {
$dimension_unit = 'cm';
$weight_unit = 'kg';
}
}
if ( ! empty( $existing_zones ) ) {
$intro_text = __( 'How would you like units on your store displayed?', 'woocommerce' );
} elseif ( $wcs_carrier ) {
$intro_text = sprintf(
2017-09-27 14:24:50 +00:00
/* translators: %1$s: country name including the 'the' prefix, %2$s: shipping carrier name */
__( "You're all set up to ship anywhere in %1\$s, and outside of it. We recommend using live rates to get accurate %2\$s shipping prices to cover the cost of order fulfillment.", 'woocommerce' ),
2017-09-27 14:24:50 +00:00
$prefixed_country_name,
$wcs_carrier
);
} else {
$intro_text = sprintf(
2017-09-27 14:24:50 +00:00
/* translators: %s: country name including the 'the' prefix if needed */
__( "You can choose which countries you'll be shipping to and with which methods. To get started, we've set you up with shipping inside and outside of %s.", 'woocommerce' ),
$prefixed_country_name
);
}
?>
<h1><?php esc_html_e( 'Shipping', 'woocommerce' ); ?></h1>
<p><?php echo esc_html( $intro_text ); ?></p>
2015-04-28 12:19:16 +00:00
<form method="post">
<?php if ( empty( $existing_zones ) ) : ?>
<ul class="wc-wizard-services shipping">
<li class="wc-wizard-service-item">
<div class="wc-wizard-service-name">
<p><?php echo esc_html_e( 'Shipping Zone', 'woocommerce' ); ?></p>
</div>
<div class="wc-wizard-service-description">
<p><?php echo esc_html_e( 'Shipping Method', 'woocommerce' ); ?></p>
</div>
</li>
<li class="wc-wizard-service-item">
<div class="wc-wizard-service-name">
<p><?php echo esc_html( $country_name ); ?></p>
</div>
<div class="wc-wizard-service-description">
<?php $this->shipping_method_selection_form( $country_code, 'shipping_zones[domestic]' ); ?>
</div>
<div class="wc-wizard-service-enable">
<span class="wc-wizard-service-toggle">
<input id="shipping_zones[domestic][enabled]" type="checkbox" name="shipping_zones[domestic][enabled]" value="yes" checked="checked" class="wc-wizard-shipping-method-enable" />
<label for="shipping_zones[domestic][enabled]">
</span>
</div>
</li>
<li class="wc-wizard-service-item">
<div class="wc-wizard-service-name">
<p><?php echo esc_html_e( 'Locations not covered by your other zones', 'woocommerce' ); ?></p>
</div>
<div class="wc-wizard-service-description">
<?php $this->shipping_method_selection_form( $country_code, 'shipping_zones[intl]' ); ?>
</div>
<div class="wc-wizard-service-enable">
<span class="wc-wizard-service-toggle">
<input id="shipping_zones[intl][enabled]" type="checkbox" name="shipping_zones[intl][enabled]" value="yes" checked="checked" class="wc-wizard-shipping-method-enable"/>
<label for="shipping_zones[intl][enabled]">
</span>
</div>
</li>
</ul>
<?php endif; ?>
<div class="wc-setup-shipping-units">
<div class="wc-setup-shipping-unit">
<p>
<label for="weight_unit">
<?php
printf( wp_kses(
__( '<strong>Weight unit</strong>—used to calculate shipping rates, and more.', 'woocommerce' ),
array( 'strong' => array() )
) );
?>
</label>
</p>
<select id="weight_unit" name="weight_unit" class="wc-enhanced-select">
<option value="kg" <?php selected( $weight_unit, 'kg' ); ?>><?php esc_html_e( 'kg', 'woocommerce' ); ?></option>
<option value="g" <?php selected( $weight_unit, 'g' ); ?>><?php esc_html_e( 'g', 'woocommerce' ); ?></option>
<option value="lbs" <?php selected( $weight_unit, 'lbs' ); ?>><?php esc_html_e( 'lbs', 'woocommerce' ); ?></option>
<option value="oz" <?php selected( $weight_unit, 'oz' ); ?>><?php esc_html_e( 'oz', 'woocommerce' ); ?></option>
</select>
</div>
<div class="wc-setup-shipping-unit">
<p>
<label for="dimension_unit">
<?php
printf( wp_kses(
__( '<strong>Dimension unit</strong>—helps for accurate package selection.', 'woocommerce' ),
array( 'strong' => array() )
) );
?>
</label>
</p>
<select id="dimension_unit" name="dimension_unit" class="wc-enhanced-select">
<option value="m" <?php selected( $dimension_unit, 'm' ); ?>><?php esc_html_e( 'm', 'woocommerce' ); ?></option>
<option value="cm" <?php selected( $dimension_unit, 'cm' ); ?>><?php esc_html_e( 'cm', 'woocommerce' ); ?></option>
<option value="mm" <?php selected( $dimension_unit, 'mm' ); ?>><?php esc_html_e( 'mm', 'woocommerce' ); ?></option>
<option value="in" <?php selected( $dimension_unit, 'in' ); ?>><?php esc_html_e( 'in', 'woocommerce' ); ?></option>
<option value="yd" <?php selected( $dimension_unit, 'yd' ); ?>><?php esc_html_e( 'yd', 'woocommerce' ); ?></option>
</select>
</div>
</div>
2017-05-31 11:00:10 +00:00
<p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
<?php wp_nonce_field( 'wc-setup' ); ?>
</p>
2015-04-28 12:19:16 +00:00
</form>
<?php
}
/**
* Save shipping options.
2015-04-28 12:19:16 +00:00
*/
public function wc_setup_shipping_save() {
2015-06-17 12:35:09 +00:00
check_admin_referer( 'wc-setup' );
// If going through this step again, remove the live rates options
// in case the user saved different settings this time
delete_option( 'woocommerce_setup_domestic_live_rates_zone' );
delete_option( 'woocommerce_setup_intl_live_rates_zone' );
$setup_domestic = isset( $_POST['shipping_zones']['domestic']['enabled'] ) && ( 'yes' === $_POST['shipping_zones']['domestic']['enabled'] );
$domestic_method = sanitize_text_field( $_POST['shipping_zones']['domestic']['method'] );
$setup_intl = isset( $_POST['shipping_zones']['intl']['enabled'] ) && ( 'yes' === $_POST['shipping_zones']['intl']['enabled'] );
$intl_method = sanitize_text_field( $_POST['shipping_zones']['intl']['method'] );
$weight_unit = sanitize_text_field( $_POST['weight_unit'] );
$dimension_unit = sanitize_text_field( $_POST['dimension_unit'] );
$existing_zones = WC_Shipping_Zones::get_zones();
2016-01-06 14:21:13 +00:00
2017-05-31 11:02:46 +00:00
update_option( 'woocommerce_ship_to_countries', '' );
update_option( 'woocommerce_weight_unit', $weight_unit );
update_option( 'woocommerce_dimension_unit', $dimension_unit );
// For now, limit this setup to the first run.
if ( ! empty( $existing_zones ) ) {
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}
// Install WooCommerce Services if live rates were selected.
if (
( $setup_domestic && 'live_rates' === $domestic_method ) ||
( $setup_intl && 'live_rates' === $intl_method )
) {
$this->install_woocommerce_services();
}
2017-05-31 11:02:46 +00:00
/*
* If enabled, create a shipping zone containing the country the
* store is located in, with the selected method preconfigured.
2017-05-31 11:02:46 +00:00
*/
if ( $setup_domestic ) {
$country = WC()->countries->get_base_country();
2017-05-31 11:02:46 +00:00
$zone = new WC_Shipping_Zone( null );
$zone->set_zone_order( 0 );
$zone->add_location( $country, 'country' );
if ( 'live_rates' === $domestic_method ) {
// Signal WooCommerce Services to setup the domestic zone.
update_option( 'woocommerce_setup_domestic_live_rates_zone', true, 'no' );
} else {
$instance_id = $zone->add_shipping_method( $domestic_method );
}
2017-05-31 11:02:46 +00:00
$zone->save();
// Save chosen shipping method settings (using REST controller for convenience).
if ( isset( $instance_id ) && ! empty( $_POST['shipping_zones']['domestic'][ $domestic_method ] ) ) {
$method_controller = new WC_REST_Shipping_Zone_Methods_Controller();
$method_controller->update_item( array(
'zone_id' => $zone->get_id(),
'instance_id' => $instance_id,
'settings' => $_POST['shipping_zones']['domestic'][ $domestic_method ],
) );
}
2017-05-31 11:02:46 +00:00
}
// If enabled, set the selected method for the "rest of world" zone.
if ( $setup_intl ) {
if ( 'live_rates' === $intl_method ) {
// Signal WooCommerce Services to setup the international zone.
update_option( 'woocommerce_setup_intl_live_rates_zone', true, 'no' );
} else {
$zone = new WC_Shipping_Zone( 0 );
$instance_id = $zone->add_shipping_method( $intl_method );
$zone->save();
}
// Save chosen shipping method settings (using REST controller for convenience).
if ( isset( $instance_id ) && ! empty( $_POST['shipping_zones']['intl'][ $intl_method ] ) ) {
$method_controller = new WC_REST_Shipping_Zone_Methods_Controller();
$method_controller->update_item( array(
'zone_id' => $zone->get_id(),
'instance_id' => $instance_id,
'settings' => $_POST['shipping_zones']['intl'][ $intl_method ],
) );
}
}
// Notify the user that no shipping methods are configured.
if ( ! $setup_domestic && ! $setup_intl ) {
WC_Admin_Notices::add_notice( 'no_shipping_methods' );
2016-01-06 14:21:13 +00:00
}
2015-04-28 12:19:16 +00:00
2017-03-31 17:32:19 +00:00
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
2015-04-28 12:19:16 +00:00
exit;
}
/**
* https://stripe.com/global
*/
protected function is_stripe_supported_country( $country_code ) {
$stripe_supported_countries = array(
'AU',
'AT',
'BE',
'CA',
'DK',
'FI',
'FR',
'DE',
'HK',
'IE',
'JP',
'LU',
'NL',
'NZ',
'NO',
'SG',
'ES',
'SE',
'CH',
'GB',
'US',
);
return in_array( $country_code, $stripe_supported_countries );
}
/**
* Helper method to retrieve the current user's email address.
*
* @return string Email address
*/
protected function get_current_user_email() {
$current_user = wp_get_current_user();
$user_email = $current_user->user_email;
return $user_email;
}
/**
* Simple array of "in cart" gateways to show in wizard.
*
* @return array
*/
protected function get_wizard_in_cart_payment_gateways() {
$country = WC()->countries->get_base_country();
$can_stripe = $this->is_stripe_supported_country( $country );
$user_email = $this->get_current_user_email();
$stripe_description = '<p>' . sprintf(
__( 'Accept all major debit &amp; credit cards from customers in 135+ countries on your site. <a href="%s" target="_blank">Learn more</a>.', 'woocommerce' ),
'https://wordpress.org/plugins/woocommerce-gateway-stripe/'
) . '</p>';
$paypal_bt_description = '<p>' . sprintf(
__( 'Safe and secure payments using credit cards or your customer\'s PayPal account. <a href="%s" target="_blank">Learn more</a>.', 'woocommerce' ),
'https://wordpress.org/plugins/woocommerce-gateway-paypal-powered-by-braintree/'
) . '</p>';
$paypal_ec_description = '<p>' . sprintf(
__( 'Safe and secure payments using credit cards or your customer\'s PayPal account. <a href="%s" target="_blank">Learn more</a>.', 'woocommerce' ),
'https://wordpress.org/plugins/woocommerce-gateway-paypal-express-checkout/'
) . '</p>';
$gateways = array(
'stripe' => array(
'name' => __( 'Stripe', 'woocommerce' ),
'image' => WC()->plugin_url() . '/assets/images/stripe.png',
'description' => $stripe_description,
'class' => $can_stripe ? 'checked' : '',
'repo-slug' => 'woocommerce-gateway-stripe',
'settings' => array(
'create_account' => array(
'label' => __( 'Create a new Stripe account for me', 'woocommerce' ),
'type' => 'checkbox',
'value' => 'yes',
'placeholder' => '',
'required' => false,
),
'email' => array(
'label' => __( 'Stripe email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'Stripe email address', 'woocommerce' ),
'description' => __( "Enter your email address and we'll handle account creation. WooCommerce Services and Jetpack will be installed and activated for you.", 'woocommerce' ),
'required' => true,
),
),
'enabled' => $can_stripe,
'featured' => true,
),
2017-08-25 19:06:06 +00:00
'braintree_paypal' => array(
'name' => __( 'PayPal by Braintree', 'woocommerce' ),
'image' => WC()->plugin_url() . '/assets/images/paypal-braintree.png',
'description' => $paypal_bt_description,
'repo-slug' => 'woocommerce-gateway-paypal-powered-by-braintree',
),
2017-08-25 19:06:06 +00:00
'ppec_paypal' => array(
'name' => __( 'PayPal Express Checkout', 'woocommerce' ),
2016-04-19 11:04:52 +00:00
'image' => WC()->plugin_url() . '/assets/images/paypal.png',
'description' => $paypal_ec_description,
'repo-slug' => 'woocommerce-gateway-paypal-express-checkout',
),
'paypal' => array(
'name' => __( 'PayPal Standard', 'woocommerce' ),
'description' => __( 'Accept payments via PayPal using account balance or credit card.', 'woocommerce' ),
'image' => '',
'settings' => array(
'email' => array(
'label' => __( 'PayPal email address:', 'woocommerce' ),
'type' => 'email',
'value' => $user_email,
'placeholder' => __( 'PayPal email address', 'woocommerce' ),
'required' => true,
),
),
),
);
if ( ! $can_stripe ) {
unset( $gateways['stripe'] );
}
if ( 'US' === $country ) {
unset( $gateways['ppec_paypal'] );
} else {
unset( $gateways['braintree_paypal'] );
}
if ( ! current_user_can( 'install_plugins' ) ) {
unset( $gateways['braintree_paypal'] );
unset( $gateways['ppec_paypal'] );
unset( $gateways['stripe'] );
}
return $gateways;
}
/**
* Simple array of "manual" gateways to show in wizard.
* @return array
*/
protected function get_wizard_manual_payment_gateways() {
$gateways = array(
'cheque' => array(
'name' => _x( 'Check payments', 'Check payment method', 'woocommerce' ),
2016-06-14 14:34:28 +00:00
'description' => __( 'A simple offline gateway that lets you accept a check as method of payment.', 'woocommerce' ),
'image' => '',
'class' => '',
),
'bacs' => array(
'name' => __( 'Bank transfer (BACS) payments', 'woocommerce' ),
2016-07-26 12:50:31 +00:00
'description' => __( 'A simple offline gateway that lets you accept BACS payment.', 'woocommerce' ),
'image' => '',
'class' => '',
),
'cod' => array(
'name' => __( 'Cash on delivery', 'woocommerce' ),
2016-07-26 12:50:31 +00:00
'description' => __( 'A simple offline gateway that lets you accept cash on delivery.', 'woocommerce' ),
'image' => '',
'class' => '',
),
);
return $gateways;
}
/**
* Display service item in list.
*/
public function display_service_item( $item_id, $item_info ) {
$item_class = 'wc-wizard-service-item';
if ( isset( $item_info['class'] ) ) {
$item_class .= ' ' . $item_info['class'];
}
$previously_saved_settings = get_option( 'woocommerce_' . $item_id . '_settings' );
// Show the user-saved state if it was previously saved
// Otherwise, rely on the item info
if ( is_array( $previously_saved_settings ) ) {
$should_enable_toggle = 'yes' === $previously_saved_settings['enabled'];
} else {
$should_enable_toggle = isset( $item_info['enabled'] ) && $item_info['enabled'];
}
?>
<li class="<?php echo esc_attr( $item_class ); ?>">
<div class="wc-wizard-service-name">
<?php if ( ! empty( $item_info['image'] ) ) : ?>
<img src="<?php echo esc_attr( $item_info['image'] ); ?>" alt="<?php echo esc_attr( $item_info['name'] ); ?>" />
<?php else : ?>
<p><?php echo esc_html( $item_info['name'] ); ?></p>
<?php endif; ?>
</div>
<div class="wc-wizard-service-description">
<?php echo wp_kses_post( wpautop( $item_info['description'] ) ); ?>
<?php if ( ! empty( $item_info['settings'] ) ) : ?>
<div class="wc-wizard-service-settings <?php echo $should_enable_toggle ? '' : 'hide'; ?>">
<?php foreach ( $item_info['settings'] as $setting_id => $setting ) : ?>
<?php
$is_checkbox = 'checkbox' === $setting['type'];
if ( $is_checkbox ) {
$checked = false;
if ( isset( $previously_saved_settings[ $setting_id ] ) ) {
$checked = 'yes' === $previously_saved_settings[ $setting_id ];
}
}
if ( 'email' === $setting['type'] ) {
$value = empty( $previously_saved_settings[ $setting_id ] )
? $setting['value']
: $previously_saved_settings[ $setting_id ];
}
?>
<?php $input_id = $item_id . '_' . $setting_id; ?>
<div class="<?php echo esc_attr( 'wc-wizard-service-setting-' . $input_id ); ?>">
<label
for="<?php echo esc_attr( $input_id ); ?>"
class="<?php echo esc_attr( $input_id ); ?>"
>
<?php echo esc_html( $setting['label'] ); ?>
</label>
<input
type="<?php echo esc_attr( $setting['type'] ); ?>"
id="<?php echo esc_attr( $input_id ); ?>"
class="<?php echo esc_attr( 'payment-' . $setting['type'] . '-input' ); ?>"
name="<?php echo esc_attr( $input_id ); ?>"
value="<?php echo esc_attr( isset( $value ) ? $value : $setting['value'] ); ?>"
placeholder="<?php echo esc_attr( $setting['placeholder'] ); ?>"
<?php echo ( $setting['required'] ) ? 'required' : ''; ?>
<?php echo $is_checkbox ? checked( isset( $checked ) && $checked, true, false ) : ''; ?>
/>
<?php if ( ! empty( $setting['description'] ) ) : ?>
<span class="wc-wizard-service-settings-description"><?php echo esc_html( $setting['description'] ); ?></span>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<div class="wc-wizard-service-enable">
<span class="wc-wizard-service-toggle <?php echo esc_attr( $should_enable_toggle ? '' : 'disabled' ); ?>">
<input
id="wc-wizard-service-<?php echo esc_attr( $item_id ); ?>"
type="checkbox"
name="wc-wizard-service-<?php echo esc_attr( $item_id ); ?>-enabled"
value="yes" <?php checked( $should_enable_toggle ); ?>
/>
<label for="wc-wizard-service-<?php echo esc_attr( $item_id ); ?>">
</span>
</div>
</li>
<?php
}
public function is_featured_service( $service ) {
return ! empty( $service['featured'] );
}
public function is_not_featured_service( $service ) {
return ! $this->is_featured_service( $service );
}
2015-06-08 15:34:13 +00:00
/**
* Payment Step.
2015-06-08 15:34:13 +00:00
*/
public function wc_setup_payment() {
$featured_gateways = array_filter( $this->get_wizard_in_cart_payment_gateways(), array( $this, 'is_featured_service' ) );
$in_cart_gateways = array_filter( $this->get_wizard_in_cart_payment_gateways(), array( $this, 'is_not_featured_service' ) );
$manual_gateways = $this->get_wizard_manual_payment_gateways();
2015-06-08 15:34:13 +00:00
?>
<h1><?php esc_html_e( 'Payment', 'woocommerce' ); ?></h1>
<form method="post" class="wc-wizard-payment-gateway-form">
<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.', 'woocommerce' ),
esc_url( admin_url( 'admin.php?page=wc-addons&view=payment-gateways' ) )
); ?>
</p>
<?php if ( $featured_gateways ) : ?>
<ul class="wc-wizard-services featured">
<?php foreach ( $featured_gateways as $gateway_id => $gateway ) :
$this->display_service_item( $gateway_id, $gateway );
endforeach; ?>
</ul>
<?php endif; ?>
<?php if ( $in_cart_gateways ) : ?>
<ul class="wc-wizard-services in-cart">
2017-09-08 03:59:17 +00:00
<?php foreach ( $in_cart_gateways as $gateway_id => $gateway ) :
$this->display_service_item( $gateway_id, $gateway );
2017-09-08 03:59:17 +00:00
endforeach; ?>
</ul>
<?php endif; ?>
<ul class="wc-wizard-services manual">
<li class="wc-wizard-services-list-toggle closed">
<div class="wc-wizard-service-name">
<?php esc_html_e( 'Offline Payments', 'woocommerce' ); ?>
</div>
<div class="wc-wizard-service-description">
<?php esc_html_e( 'Collect payments from customers offline.', 'woocommerce' ); ?>
</div>
<div class="wc-wizard-service-enable">
<input class="wc-wizard-service-list-toggle" id="wc-wizard-service-list-toggle" type="checkbox">
<label for="wc-wizard-service-list-toggle"></label>
</div>
</li>
2017-09-08 03:59:17 +00:00
<?php foreach ( $manual_gateways as $gateway_id => $gateway ) :
$this->display_service_item( $gateway_id, $gateway );
2017-09-08 03:59:17 +00:00
endforeach; ?>
</ul>
2015-06-08 15:34:13 +00:00
<p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
2015-06-17 12:35:09 +00:00
<?php wp_nonce_field( 'wc-setup' ); ?>
2015-06-08 15:34:13 +00:00
</p>
</form>
<?php
}
/**
* Payment Step save.
2015-06-08 15:34:13 +00:00
*/
public function wc_setup_payment_save() {
2015-06-17 12:35:09 +00:00
check_admin_referer( 'wc-setup' );
// Install WooCommerce Services with Stripe to enable deferred account creation.
if (
! empty( $_POST['wc-wizard-service-stripe-enabled'] ) &&
! empty( $_POST['stripe_create_account'] )
) {
$this->install_woocommerce_services();
}
$gateways = $this->get_wizard_in_cart_payment_gateways();
foreach ( $gateways as $gateway_id => $gateway ) {
// If repo-slug is defined, download and install plugin from .org.
if ( ! empty( $gateway['repo-slug'] ) && ! empty( $_POST[ 'wc-wizard-service-' . $gateway_id . '-enabled' ] ) ) {
$this->install_plugin( $gateway_id, $gateway );
}
$settings_key = 'woocommerce_' . $gateway_id . '_settings';
$settings = array_filter( (array) get_option( $settings_key, array() ) );
$settings['enabled'] = ! empty( $_POST[ 'wc-wizard-service-' . $gateway_id . '-enabled' ] ) ? 'yes' : 'no';
2015-06-08 15:34:13 +00:00
if ( ! empty( $gateway['settings'] ) ) {
foreach ( $gateway['settings'] as $setting_id => $setting ) {
$settings[ $setting_id ] = 'yes' === $settings['enabled']
? wc_clean( $_POST[ $gateway_id . '_' . $setting_id ] )
: false;
}
}
update_option( $settings_key, $settings );
}
2015-06-08 15:34:13 +00:00
2017-03-31 17:32:19 +00:00
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
2015-06-08 15:34:13 +00:00
exit;
}
/**
* Extras.
*/
public function wc_setup_extras() {
?>
<h1><?php esc_html_e( 'Recommended Extras', 'woocommerce' ); ?></h1>
<form method="post">
<?php if ( $this->should_show_theme_extra() ) : ?>
<ul class="wc-wizard-services featured">
<li class="wc-wizard-service-item">
<div class="wc-wizard-service-description">
<h3><?php esc_html_e( 'Storefront Theme', 'woocommerce' ); ?></h3>
<p>
<?php esc_html_e( 'Your theme is not compatible with WooCommerce. We recommend you switch to Storefront, a free WordPress theme built and maintained by the makers of WooCommerce. If toggled on, Storefront will be installed and activated for you.', 'woocommerce' ); ?>
</p>
<p class="wc-wizard-service-learn-more">
<a href="<?php echo esc_url( 'https://woocommerce.com/storefront/' ); ?>" target="_blank">
<?php esc_html_e( 'Learn more about Storefront', 'woocommerce' ); ?>
</a>
</p>
</div>
<div class="wc-wizard-service-enable">
<span class="wc-wizard-service-toggle">
<input id="setup_storefront_theme" type="checkbox" name="setup_storefront_theme" value="yes" checked="checked" />
<label for="setup_storefront_theme">
</span>
</div>
</li>
</ul>
<?php endif; ?>
<?php if ( $this->should_show_automated_tax_extra() ) : ?>
<ul class="wc-wizard-services featured">
<li class="wc-wizard-service-item <?php echo get_option( 'woocommerce_setup_automated_taxes' ) ? 'checked' : ''; ?>">
<div class="wc-wizard-service-description">
<h3><?php esc_html_e( 'Automated Taxes', 'woocommerce' ); ?></h3>
<p>
<?php esc_html_e( 'Well automatically calculate and charge the correct rate of tax for each time a customer checks out. Powered by WooCommerce Services.', 'woocommerce' ); ?>
</p>
</div>
<div class="wc-wizard-service-enable">
<span class="wc-wizard-service-toggle <?php echo get_option( 'woocommerce_setup_automated_taxes' ) ? '' : 'disabled'; ?>">
<input
id="setup_automated_taxes"
type="checkbox"
name="setup_automated_taxes"
value="yes"
<?php checked( get_option( 'woocommerce_setup_automated_taxes', 'no' ), 'yes' ); ?>
/>
<label for="setup_automated_taxes">
</span>
</div>
</li>
</ul>
<?php endif; ?>
<p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" />
<?php wp_nonce_field( 'wc-setup' ); ?>
</p>
</form>
<?php
}
/**
* Extras step save.
*/
public function wc_setup_extras_save() {
check_admin_referer( 'wc-setup' );
$setup_automated_tax = isset( $_POST['setup_automated_taxes'] ) && 'yes' === $_POST['setup_automated_taxes'];
$install_storefront = isset( $_POST['setup_storefront_theme'] ) && 'yes' === $_POST['setup_storefront_theme'];
update_option( 'woocommerce_calc_taxes', $setup_automated_tax ? 'yes' : 'no' );
update_option( 'woocommerce_setup_automated_taxes', $setup_automated_tax );
if ( $setup_automated_tax ) {
$this->install_woocommerce_services();
}
if ( $install_storefront ) {
$this->install_theme( 'storefront' );
}
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}
/**
* Go to the next step if Jetpack was connected.
*/
protected function wc_setup_activate_actions() {
if (
isset( $_GET['from'] ) &&
'wpcom' === $_GET['from'] &&
class_exists( 'Jetpack' ) &&
Jetpack::is_active()
) {
wp_redirect( esc_url_raw( remove_query_arg( 'from', $this->get_next_step_link() ) ) );
exit;
}
}
protected function wc_setup_activate_get_description() {
$description = false;
$stripe_settings = get_option( 'woocommerce_stripe_settings', false );
$stripe_enabled = is_array( $stripe_settings )
&& isset( $stripe_settings['create_account'] ) && 'yes' === $stripe_settings['create_account']
&& isset( $stripe_settings['enabled'] ) && 'yes' === $stripe_settings['enabled'];
$taxes_enabled = (bool) get_option( 'woocommerce_setup_automated_taxes', false );
$domestic_rates = (bool) get_option( 'woocommerce_setup_domestic_live_rates_zone', false );
$intl_rates = (bool) get_option( 'woocommerce_setup_intl_live_rates_zone', false );
$rates_enabled = $domestic_rates || $intl_rates;
/* translators: %s: list of features, potentially comma separated */
$description_base = __( 'Your store is almost ready! To activate services like %s, just connect with Jetpack.', 'woocommerce' );
if ( $stripe_enabled && $taxes_enabled && $rates_enabled ) {
$description = sprintf( $description_base, __( 'Stripe payments, automated taxes, live rates and discounted shipping labels', 'woocommerce' ) );
} else if ( $stripe_enabled && $taxes_enabled ) {
$description = sprintf( $description_base, __( 'Stripe payments and automated taxes', 'woocommerce' ) );
} else if ( $stripe_enabled && $rates_enabled ) {
$description = sprintf( $description_base, __( 'Stripe payments, live rates and discounted shipping labels', 'woocommerce' ) );
} else if ( $stripe_enabled ) {
$description = sprintf( $description_base, __( 'Stripe payments', 'woocommerce' ) );
} else if ( $taxes_enabled && $rates_enabled ) {
$description = sprintf( $description_base, __( 'automated taxes, live rates and discounted shipping labels', 'woocommerce' ) );
} else if ( $taxes_enabled ) {
$description = sprintf( $description_base, __( 'automated taxes', 'woocommerce' ) );
} else if ( $rates_enabled ) {
$description = sprintf( $description_base, __( 'live rates and discounted shipping labels', 'woocommerce' ) );
}
return $description;
}
/**
* Activate step.
*/
public function wc_setup_activate() {
$this->wc_setup_activate_actions();
$has_jetpack_error = false;
if ( isset( $_GET['activate_error'] ) ) {
$has_jetpack_error = true;
$title = __( "Sorry, We couldn't connect your store to Jetpack", 'woocommerce' );
$error_message = $this->get_activate_error_message( sanitize_text_field( wp_unslash( $_GET['activate_error'] ) ) );
$description = $error_message;
} else {
$description = $this->wc_setup_activate_get_description();
$title = $description ?
__( 'Connect your store to Jetpack', 'woocommerce' ) :
__( 'Connect your store to Jetpack to enable extra features', 'woocommerce' );
}
?>
<h1><?php echo esc_html( $title ); ?></h1>
<p><?php echo esc_html( $description ); ?></p>
<img
class="jetpack-logo"
src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/jetpack-green-logo.svg' ); ?>"
alt="Jetpack logo"
/>
<?php if ( $has_jetpack_error ) : ?>
2017-09-27 19:48:33 +00:00
<p class="wc-setup-actions step">
<a
href="<?php echo esc_url( $this->get_next_step_link() ); ?>"
class="button-primary button button-large"
>
<?php esc_html_e( 'Finish setting up your store', 'woocommerce' ); ?>
</a>
</p>
<?php else : ?>
<p class="jetpack-terms">
<?php
printf(
wp_kses_post( __( 'By connecting your site you agree to our fascinating <a href="%1$s" target="_blank">Terms of Service</a> and to <a href="%2$s" target="_blank">share details</a> with WordPress.com', 'woocommerce' ) ),
'https://wordpress.com/tos',
'https://jetpack.com/support/what-data-does-jetpack-sync'
);
?>
2017-09-27 19:48:33 +00:00
</p>
<form method="post" class="activate-jetpack">
<p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large" value="<?php esc_attr_e( 'Connect with Jetpack', 'woocommerce' ); ?>" />
</p>
<input type="hidden" name="save_step" value="activate" />
<?php wp_nonce_field( 'wc-setup' ); ?>
</form>
<h3 class="jetpack-reasons"><?php esc_html_e( "Bonus reasons you'll love Jetpack", 'woocommerce' ); ?></h3>
<ul class="wc-wizard-features">
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Better security', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Protect your store from unauthorized access.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Store stats', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Get insights on how your store is doing, including total sales, top products, and more.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Store monitoring', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( 'Get an alert if your store is down for even a few minutes.', 'woocommerce' ); ?>
</p>
</li>
<li class="wc-wizard-feature-item">
<p class="wc-wizard-feature-name">
<strong><?php esc_html_e( 'Product promotion', 'woocommerce' ); ?></strong>
</p>
<p class="wc-wizard-feature-description">
<?php esc_html_e( "Share new items on social media the moment they're live in your store.", 'woocommerce' ); ?>
</p>
</li>
</ul>
<?php endif; ?>
<?php
}
protected function get_all_activate_errors() {
return array(
'default' => __( "Sorry! We tried, but we couldn't connect Jetpack just now 😭. Please go to the Plugins tab to connect Jetpack, so that you can finish setting up your store.", 'woocommerce' ),
'jetpack_cant_be_installed' => __( "Sorry! We tried, but we couldn't install Jetpack for you 😭. Please go to the Plugins tab to install it, and finish setting up your store.", 'woocommerce' ),
'register_http_request_failed' => __( "Sorry! We couldn't contact Jetpack just now 😭. Please make sure that your site is visible over the internet, and that it accepts incoming and outgoing requests via curl. You can also try to connect to Jetpack again, and if you run into any more issues, please contact support.", 'woocommerce' ),
'siteurl_private_ip_dev' => __( "Your site might be on a private network. Jetpack can only connect to public sites. Please make sure your site is visible over the internet, and then try connecting again 🙏." , 'woocommerce' ),
);
}
protected function get_activate_error_message( $code = '' ) {
$errors = $this->get_all_activate_errors();
return array_key_exists( $code, $errors ) ? $errors[ $code ] : $errors['default'];
}
/**
* Activate step save.
*
* Install, activate, and launch connection flow for Jetpack.
*/
public function wc_setup_activate_save() {
check_admin_referer( 'wc-setup' );
// Leave a note for WooCommerce Services that Jetpack has been opted into.
update_option( 'woocommerce_setup_jetpack_opted_in', true );
WC_Install::background_installer( 'jetpack', array(
'file' => 'jetpack/jetpack.php',
'name' => __( 'Jetpack', 'woocommerce' ),
'repo-slug' => 'jetpack',
) );
// Did Jetpack get successfully installed?
if ( ! class_exists( 'Jetpack' ) ) {
wp_redirect( esc_url_raw( add_query_arg( 'activate_error', 'jetpack_cant_be_installed' ) ) );
exit;
}
Jetpack::maybe_set_version_option();
$register_result = Jetpack::try_registration();
if ( is_wp_error( $register_result ) ) {
$result_error_code = $register_result->get_error_code();
$jetpack_error_code = array_key_exists( $result_error_code, $this->get_all_activate_errors() ) ? $result_error_code : 'register';
wp_redirect( esc_url_raw( add_query_arg( 'activate_error', $jetpack_error_code ) ) );
exit;
}
$redirect_url = site_url( add_query_arg( array(
'from' => 'wpcom',
'activate_error' => false,
) ) );
$connection_url = Jetpack::init()->build_connect_url( true, $redirect_url, 'woocommerce-setup-wizard' );
wp_redirect( esc_url_raw( $connection_url ) );
exit;
}
2015-04-29 15:34:07 +00:00
/**
* Final step.
2015-04-29 15:34:07 +00:00
*/
2017-03-31 17:32:19 +00:00
public function wc_setup_ready() {
// We've made it! Don't prompt the user to run the wizard again.
WC_Admin_Notices::remove_notice( 'install' );
$user_email = $this->get_current_user_email();
$videos_url = 'https://docs.woocommerce.com/document/woocommerce-guided-tour-videos/?utm_source=setupwizard&utm_medium=product&utm_content=videos&utm_campaign=woocommerceplugin';
$docs_url = 'https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/?utm_source=setupwizard&utm_medium=product&utm_content=docs&utm_campaign=woocommerceplugin';
$help_text = sprintf(
/* translators: %1$s: link to videos, %2$s: link to docs */
__( 'Watch our <a href="%1$s" target="_blank">guided tour videos</a> to learn more about WooCommerce, and visit WooCommerce.com to learn more about <a href="%2$s" target="_blank">getting started</a>.' ),
$videos_url,
$docs_url
);
2015-04-28 12:19:16 +00:00
?>
<h1><?php esc_html_e( "You're ready to start selling!", 'woocommerce' ); ?></h1>
2015-04-28 12:19:16 +00:00
2017-08-08 17:00:47 +00:00
<div class="woocommerce-message woocommerce-newsletter">
<p><?php esc_html_e( "We're here for you — get tips, product updates, and inspiration straight to your mailbox.", 'woocommerce' ); ?></p>
2017-08-08 17:00:47 +00:00
<form action="//woocommerce.us8.list-manage.com/subscribe/post?u=2c1434dc56f9506bf3c3ecd21&amp;id=13860df971" method="post" target="_blank" novalidate>
2017-09-25 12:19:36 +00:00
<div class="newsletter-form-container">
<input
class="newsletter-form-email"
type="email"
value="<?php echo esc_attr( $user_email ); ?>"
name="EMAIL"
placeholder="<?php esc_attr_e( 'Email address', 'woocommerce' ); ?>"
required
>
<p class="wc-setup-actions step newsletter-form-button-container">
<input
type="submit"
value="<?php esc_html_e( 'Yes please!', 'woocommerce' ); ?>"
name="subscribe"
id="mc-embedded-subscribe"
class="button-primary button newsletter-form-button"
>
</p>
</div>
2017-08-08 17:00:47 +00:00
</form>
</div>
<ul class="wc-wizard-next-steps">
<li class="wc-wizard-next-step-item">
<div class="wc-wizard-next-step-description">
2017-09-25 21:42:08 +00:00
<p class="next-step-heading"><?php esc_html_e( 'Next step', 'woocommerce' ); ?></p>
<h3 class="next-step-description"><?php esc_html_e( 'Create your first product', 'woocommerce' ); ?></h3>
<p class="next-step-extra-info"><?php esc_html_e( "You're ready to add your first product.", 'woocommerce' ); ?></p>
</div>
<div class="wc-wizard-next-step-action">
2017-09-25 21:42:08 +00:00
<p class="wc-setup-actions step">
<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 a product', 'woocommerce' ); ?>
</a>
</p>
</div>
</li>
<li class="wc-wizard-next-step-item">
<div class="wc-wizard-next-step-description">
2017-09-25 21:42:08 +00:00
<p class="next-step-heading"><?php esc_html_e( 'Have an existing store?', 'woocommerce' ); ?></p>
<h3 class="next-step-description"><?php esc_html_e( 'Import products', 'woocommerce' ); ?></h3>
<p class="next-step-extra-info"><?php esc_html_e( 'Transfer existing products to your new store — just import a CSV file.', 'woocommerce' ); ?></p>
</div>
<div class="wc-wizard-next-step-action">
2017-09-25 21:42:08 +00:00
<p class="wc-setup-actions step">
<a class="button button-large" href="<?php echo esc_url( admin_url( 'edit.php?post_type=product&page=product_importer' ) ); ?>">
<?php esc_html_e( 'Import products', 'woocommerce' ); ?>
</a>
</p>
</div>
</li>
</ul>
2017-09-25 21:46:11 +00:00
<p class="next-steps-help-text"><?php echo wp_kses_post( $help_text ); ?></p>
2015-04-28 12:19:16 +00:00
<?php
}
}
new WC_Admin_Setup_Wizard();