close_http_connection();
foreach ( $this->deferred_actions as $action ) {
call_user_func_array( $action['func'], $action['args'] );
}
}
/**
* 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 ) {
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 )
) );
}
/**
* 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',
) );
update_option( 'woocommerce_setup_queued_jetpack_install', true );
}
/**
* 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' => __( 'Shipping rates updated in realtime. Powered by 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' ),
),
),
),
'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 );
?>
$method ) : ?>
$method ) : ?>
$setting ) : ?>
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 );
// TODO: determine how to handle existing shipping zones (or choose not to)
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 ( $wcs_carrier ) {
$intro_text = sprintf(
/* 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' ),
$prefixed_country_name,
$wcs_carrier
);
} else {
$intro_text = sprintf(
/* 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
);
}
?>
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();
}
/*
* If enabled, create a shipping zone containing the country the
* store is located in, with the selected method preconfigured.
*/
if ( $setup_domestic ) {
$country = WC()->countries->get_base_country();
$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 );
}
$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 ],
) );
}
}
// 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' );
}
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
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 = '
' . sprintf(
__( 'Accept all major debit and credit cards from customers in 135+ countries on your site. Learn more.', 'woocommerce' ),
'https://wordpress.org/plugins/woocommerce-gateway-stripe/'
) . '
';
$paypal_bt_description = '
' . sprintf(
__( 'Safe and secure payments using credit cards or your customer\'s PayPal account. Learn more.', 'woocommerce' ),
'https://wordpress.org/plugins/woocommerce-gateway-paypal-powered-by-braintree/'
) . '
';
$paypal_ec_description = '
' . sprintf(
__( 'Safe and secure payments using credit cards or your customer\'s PayPal account. Learn more.', 'woocommerce' ),
'https://wordpress.org/plugins/woocommerce-gateway-paypal-express-checkout/'
) . '
';
$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 an account for me', 'woocommerce' ),
'type' => 'checkbox',
'value' => 'yes',
'placeholder' => '',
'required' => false,
),
),
'enabled' => $can_stripe,
'featured' => true,
),
'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',
),
'ppec_paypal' => array(
'name' => __( 'PayPal Express Checkout', 'woocommerce' ),
'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' ),
'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' ),
'description' => __( 'A simple offline gateway that lets you accept BACS payment.', 'woocommerce' ),
'image' => '',
'class' => '',
),
'cod' => array(
'name' => __( 'Cash on delivery', 'woocommerce' ),
'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'];
}
$settings_array = 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( $settings_array ) ) {
$should_enable_toggle = 'yes' === $settings_array['enabled'];
} else {
$should_enable_toggle = isset( $item_info['enabled'] ) && $item_info['enabled'];
}
?>
$setting ) : ?>
/>
/>
is_featured_service( $service );
}
/**
* Payment Step.
*/
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();
?>
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';
if ( ! empty( $gateway['settings'] ) ) {
foreach ( $gateway['settings'] as $setting_id => $setting ) {
$settings[ $setting_id ] = wc_clean( $_POST[ $gateway_id . '_' . $setting_id ] );
}
}
update_option( $settings_key, $settings );
}
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}
/**
* Extras.
*/
public function wc_setup_extras() {
?>
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;
}
}
/**
* Activate step.
*/
public function wc_setup_activate() {
$this->wc_setup_activate_actions();
$description = false;
$stripe_settings = get_option( 'woocommerce_stripe_settings', false );
$stripe_enabled = is_array( $stripe_settings )
&& ( 'yes' === $stripe_settings['create_account'] )
&& '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' ) );
}
?>
'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;
}
/**
* Final step.
*/
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 guided tour videos to learn more about WooCommerce, and visit WooCommerce.com to learn more about getting started.' ),
$videos_url,
$docs_url
);
?>