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, true ); } /** * Should we show the MailChimp install option? * True only if the user can install plugins. * * @return boolean */ protected function should_show_mailchimp() { return current_user_can( 'install_plugins' ); } /** * Should we show the Facebook install option? * True only if the user can install plugins, * and up until the end date of the recommendation. * * @return boolean */ protected function should_show_facebook() { return current_user_can( 'install_plugins' ); } /** * Is the WooCommerce Admin actively included in the WooCommerce core? * Based on presence of a basic WC Admin function. * * @return boolean */ protected function is_wc_admin_included_in_wc() { return function_exists( 'wc_admin_url' ); } /** * Should we show the WooCommerce Admin install option? * True only if the user can install plugins, * and is running the correct version of WordPress. * * @see WC_Admin_Setup_Wizard::$wc_admin_plugin_minimum_wordpress_version * * @return boolean */ protected function should_show_wc_admin() { $wordpress_minimum_met = version_compare( get_bloginfo( 'version' ), $this->wc_admin_plugin_minimum_wordpress_version, '>=' ); return current_user_can( 'install_plugins' ) && $wordpress_minimum_met && ! $this->is_wc_admin_included_in_wc(); } /** * Should we show the new WooCommerce Admin onboarding experience? * * @return boolean */ protected function should_show_wc_admin_onboarding() { if ( ! $this->should_show_wc_admin() && ! $this->is_wc_admin_included_in_wc() ) { return false; } $ab_test = get_option( 'woocommerce_setup_ab_wc_admin_onboarding' ); // If it doesn't exist yet, generate it for later use and save it, so we always show the same to this user. if ( ! $ab_test ) { $ab_test = 1 !== rand( 1, 2 ) ? 'a' : 'b'; // 50% of users. b gets the new experience. update_option( 'woocommerce_setup_ab_wc_admin_onboarding', $ab_test ); } return 'b' === $ab_test; } /** * Should we display the 'Recommended' step? * True if at least one of the recommendations will be displayed. * * @return boolean */ protected function should_show_recommended_step() { return $this->should_show_theme() || $this->should_show_automated_tax() || $this->should_show_mailchimp() || $this->should_show_facebook() || $this->should_show_wc_admin(); } /** * Register/enqueue scripts and styles for the Setup Wizard. * * Hooked onto 'admin_enqueue_scripts'. */ public function enqueue_scripts() { // Whether or not there is a pending background install of Jetpack. $pending_jetpack = ! class_exists( 'Jetpack' ) && get_option( 'woocommerce_setup_background_installing_jetpack' ); $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true ); wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.6' ); wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), WC_VERSION ); 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…', 'enhanced select', 'woocommerce' ), 'i18n_searching' => _x( 'Searching…', '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' ), ) ); 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', 'jquery-tiptip', 'backbone', 'wc-backbone-modal' ), WC_VERSION ); wp_localize_script( 'wc-setup', 'wc_setup_params', array( 'pending_jetpack_install' => $pending_jetpack ? 'yes' : 'no', 'states' => WC()->countries->get_states(), 'postcodes' => $this->get_postcodes(), 'current_step' => isset( $this->steps[ $this->step ] ) ? $this->step : false, 'i18n' => array( 'extra_plugins' => array( 'payment' => array( 'stripe_create_account' => __( 'Stripe setup is powered by Jetpack and WooCommerce Services.', 'woocommerce' ), 'ppec_paypal_reroute_requests' => __( 'PayPal setup is powered by Jetpack and WooCommerce Services.', 'woocommerce' ), 'stripe_create_account,ppec_paypal_reroute_requests' => __( 'Stripe and PayPal setup are powered by Jetpack and WooCommerce Services.', 'woocommerce' ), ), ), ), ) ); } /** * Helper method to get postcode configurations from `WC()->countries->get_country_locale()`. * We don't use `wp_list_pluck` because it will throw notices when postcode configuration is not defined for a country. * * @return array */ private function get_postcodes() { $locales = WC()->countries->get_country_locale(); $postcodes = array(); foreach ( $locales as $country_code => $locale ) { if ( isset( $locale['postcode'] ) ) { $postcodes[ $country_code ] = $locale['postcode']; } } return $postcodes; } /** * Show the setup wizard. */ public function setup_wizard() { if ( empty( $_GET['page'] ) || 'wc-setup' !== $_GET['page'] ) { // WPCS: CSRF ok, input var ok. return; } $default_steps = array( 'new_onboarding' => array( 'name' => '', 'view' => array( $this, 'wc_setup_new_onboarding' ), 'handler' => array( $this, 'wc_setup_new_onboarding_save' ), ), 'store_setup' => array( 'name' => __( 'Store setup', 'woocommerce' ), 'view' => array( $this, 'wc_setup_store_setup' ), 'handler' => array( $this, 'wc_setup_store_setup_save' ), ), 'payment' => array( 'name' => __( 'Payment', 'woocommerce' ), 'view' => array( $this, 'wc_setup_payment' ), 'handler' => array( $this, 'wc_setup_payment_save' ), ), 'shipping' => array( 'name' => __( 'Shipping', 'woocommerce' ), 'view' => array( $this, 'wc_setup_shipping' ), 'handler' => array( $this, 'wc_setup_shipping_save' ), ), 'recommended' => array( 'name' => __( 'Recommended', 'woocommerce' ), 'view' => array( $this, 'wc_setup_recommended' ), 'handler' => array( $this, 'wc_setup_recommended_save' ), ), 'activate' => array( 'name' => __( 'Activate', 'woocommerce' ), 'view' => array( $this, 'wc_setup_activate' ), 'handler' => array( $this, 'wc_setup_activate_save' ), ), 'next_steps' => array( 'name' => __( 'Ready!', 'woocommerce' ), 'view' => array( $this, 'wc_setup_ready' ), 'handler' => '', ), ); // Hide the new/improved onboarding experience screen if the user is not part of the a/b test. if ( ! $this->should_show_wc_admin_onboarding() ) { unset( $default_steps['new_onboarding'] ); } // Hide recommended step if nothing is going to be shown there. if ( ! $this->should_show_recommended_step() ) { unset( $default_steps['recommended'] ); } // Hide shipping step if the store is selling digital products only. if ( 'virtual' === get_option( 'woocommerce_product_type' ) ) { unset( $default_steps['shipping'] ); } // Hide activate section when the user does not have capabilities to install plugins, think multiside admins not being a super admin. if ( ! current_user_can( 'install_plugins' ) ) { unset( $default_steps['activate'] ); } $this->steps = apply_filters( 'woocommerce_setup_wizard_steps', $default_steps ); $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) ); // WPCS: CSRF ok, input var ok. // @codingStandardsIgnoreStart if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { call_user_func( $this->steps[ $this->step ]['handler'], $this ); } // @codingStandardsIgnoreEnd ob_start(); $this->setup_wizard_header(); $this->setup_wizard_steps(); $this->setup_wizard_content(); $this->setup_wizard_footer(); exit; } /** * 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. * @since 3.0.0 */ public function get_next_step_link( $step = '' ) { if ( ! $step ) { $step = $this->step; } $keys = array_keys( $this->steps ); if ( end( $keys ) === $step ) { return admin_url(); } $step_index = array_search( $step, $keys, true ); if ( false === $step_index ) { return ''; } return add_query_arg( 'step', $keys[ $step_index + 1 ], remove_query_arg( 'activate_error' ) ); } /** * Setup Wizard Header. */ public function setup_wizard_header() { // same as default WP from wp-admin/admin-header.php. $wp_version_class = 'branch-' . str_replace( array( '.', ',' ), '-', floatval( get_bloginfo( 'version' ) ) ); set_current_screen(); ?> > <?php esc_html_e( 'WooCommerce › Setup Wizard', 'woocommerce' ); ?>

<?php esc_attr_e( 'WooCommerce', 'woocommerce' ); ?>

step ) : ?> step ) : ?> step || 'activate' === $this->step ) : ?> steps; $selected_features = array_filter( $this->wc_setup_activate_get_feature_list() ); // Hide the activate step if Jetpack is already active, unless WooCommerce Services // features are selected, or unless the Activate step was already taken. if ( class_exists( 'Jetpack' ) && Jetpack::is_active() && empty( $selected_features ) && 'yes' !== get_transient( 'wc_setup_activated' ) ) { unset( $output_steps['activate'] ); } unset( $output_steps['new_onboarding'] ); ?>
    $step ) { $is_completed = array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ); if ( $step_key === $this->step ) { ?>
'; if ( ! empty( $this->steps[ $this->step ]['view'] ) ) { call_user_func( $this->steps[ $this->step ]['view'], $this ); } echo ''; } /** * Display's a prompt for users to try out the new improved WooCommerce onboarding experience in WooCommerce Admin. */ public function wc_setup_new_onboarding() { ?>

<?php esc_attr_e( 'WooCommerce', 'woocommerce' ); ?>

is_wc_admin_included_in_wc() ) : ?>

is_wc_admin_included_in_wc() ) { $this->wc_setup_redirect_to_wc_admin_onboarding(); } WC_Install::background_installer( 'woocommerce-admin', array( 'name' => __( 'WooCommerce Admin', 'woocommerce' ), 'repo-slug' => 'woocommerce-admin', ) ); // The plugin was not successfully installed, so continue with normal setup. if ( ! $this->is_wc_admin_included_in_wc() ) { wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) ); exit; } $this->wc_setup_redirect_to_wc_admin_onboarding(); } /** * Redirects to the onboarding wizard in WooCommerce Admin. */ private function wc_setup_redirect_to_wc_admin_onboarding() { if ( ! function_exists( 'wc_admin_url' ) ) { return; } // Renables the wizard. $profile_updates = array( 'completed' => false ); $onboarding_data = get_option( 'woocommerce_onboarding_profile', array() ); update_option( 'woocommerce_onboarding_profile', array_merge( $onboarding_data, $profile_updates ) ); wp_safe_redirect( wc_admin_url( '&enable_onboarding=1' ) ); exit; } /** * 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', 'both' ); $sell_in_person = get_option( 'woocommerce_sell_in_person', 'none_selected' ); if ( empty( $country ) ) { $user_location = WC_Geolocation::geolocate_ip(); $country = $user_location['country']; $state = $user_location['state']; } $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; $currency_by_country = wp_list_pluck( $locale_info, 'currency_code' ); ?>

/>
/> tracking_modal(); ?>

plugin_path() . '/i18n/locale-info.php'; if ( isset( $locale_info[ $country ] ) ) { update_option( 'woocommerce_weight_unit', $locale_info[ $country ]['weight_unit'] ); update_option( 'woocommerce_dimension_unit', $locale_info[ $country ]['dimension_unit'] ); // Set currency formatting options based on chosen location and currency. if ( $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' ); wp_schedule_single_event( time() + 10, 'woocommerce_tracker_send_event', array( true ) ); } else { update_option( 'woocommerce_allow_tracking', 'no' ); } WC_Install::create_pages(); wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) ); exit; } /** * 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. // @codingStandardsIgnoreStart if ( session_id() ) { session_write_close(); } // @codingStandardsIgnoreEnd 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(); // @codingStandardsIgnoreLine. 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 ) { $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 name and repo-slug, and optionally file if different from [repo-slug].php. */ 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; } $plugin_file = isset( $plugin_info['file'] ) ? $plugin_info['file'] : $plugin_info['repo-slug'] . '.php'; if ( is_plugin_active( $plugin_info['repo-slug'] . '/' . $plugin_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( '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( 'name' => __( 'WooCommerce Services', 'woocommerce' ), 'repo-slug' => 'woocommerce-services', ) ); } /** * Retrieve info for missing WooCommerce Services and/or Jetpack plugin. * * @return array */ protected function get_wcs_requisite_plugins() { $plugins = array(); if ( ! is_plugin_active( 'woocommerce-services/woocommerce-services.php' ) && ! get_option( 'woocommerce_setup_background_installing_woocommerce-services' ) ) { $plugins[] = array( 'name' => __( 'WooCommerce Services', 'woocommerce' ), 'slug' => 'woocommerce-services', ); } if ( ! is_plugin_active( 'jetpack/jetpack.php' ) && ! get_option( 'woocommerce_setup_background_installing_jetpack' ) ) { $plugins[] = array( 'name' => __( 'Jetpack', 'woocommerce' ), 'slug' => 'jetpack', ); } return $plugins; } /** * Plugin install info message markup with heading. */ public function plugin_install_info() { ?> array( 'name' => __( 'Flat Rate', 'woocommerce' ), 'description' => __( 'Set a fixed price to cover shipping costs.', 'woocommerce' ), 'settings' => array( 'cost' => array( 'type' => 'text', 'default_value' => __( 'Cost', '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' ), ), ); return $shipping_methods; } /** * Render the available shipping methods for a given country code. * * @param string $country_code Country code. * @param string $currency_code Currency code. * @param string $input_prefix Input prefix. */ protected function shipping_method_selection_form( $country_code, $currency_code, $input_prefix ) { $selected = 'flat_rate'; $shipping_methods = $this->get_wizard_shipping_methods( $country_code, $currency_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; $currency_code = get_woocommerce_currency(); $existing_zones = WC_Shipping_Zones::get_zones(); $intro_text = ''; if ( empty( $existing_zones ) ) { $intro_text = sprintf( /* translators: %s: country name including the 'the' prefix if needed */ __( "We've created two Shipping Zones - for %s and for the rest of the world. Below you can set Flat Rate shipping costs for these Zones or offer Free Shipping.", 'woocommerce' ), $prefixed_country_name ); } $is_wcs_labels_supported = $this->is_wcs_shipping_labels_supported_country( $country_code ); $is_shipstation_supported = $this->is_shipstation_supported_country( $country_code ); ?>

get_product_weight_selection(), $this->get_product_dimension_selection() ), array( 'span' => array( 'class' => array(), ), 'select' => array( 'id' => array(), 'name' => array(), 'class' => array(), ), 'option' => array( 'value' => array(), 'selected' => array(), ), ) ); ?>

plugin_install_info(); ?>

install_woocommerce_services(); } if ( $setup_shipstation ) { $this->install_plugin( 'woocommerce-shipstation-integration', array( 'name' => __( 'ShipStation', 'woocommerce' ), 'repo-slug' => 'woocommerce-shipstation-integration', 'file' => 'woocommerce-shipstation.php', ) ); } // For now, limit this setup to the first run. if ( ! empty( $existing_zones ) ) { wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) ); exit; } /* * If enabled, create a shipping zone containing the country the * store is located in, with the selected method preconfigured. */ if ( $setup_domestic ) { $zone = new WC_Shipping_Zone( null ); $zone->set_zone_order( 0 ); $zone->add_location( WC()->countries->get_base_country(), 'country' ); $zone_id = $zone->save(); // Save chosen shipping method settings (using REST controller for convenience). if ( ! empty( $_POST['shipping_zones']['domestic'][ $domestic_method ] ) ) { // WPCS: input var ok. // Sanitize the cost field. $domestic_cost = wc_clean( wp_unslash( $_POST['shipping_zones']['domestic'][ $domestic_method ] ) ); $domestic_cost = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $domestic_cost ); // Build and make a REST request to save the shipping zone and method set. $request = new WP_REST_Request( 'POST', "/wc/v3/shipping/zones/{$zone_id}/methods" ); $request->add_header( 'Content-Type', 'application/json' ); $request->set_body( wp_json_encode( array( 'method_id' => $domestic_method, 'settings' => $domestic_cost, ) ) ); rest_do_request( $request ); } } // If enabled, set the selected method for the "rest of world" zone. if ( $setup_intl ) { // Save chosen shipping method settings (using REST controller for convenience). if ( ! empty( $_POST['shipping_zones']['intl'][ $intl_method ] ) ) { // WPCS: input var ok. // Sanitize the cost field. $intl_cost = wc_clean( wp_unslash( $_POST['shipping_zones']['intl'][ $intl_method ] ) ); $intl_cost = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $intl_cost ); // Build and make a REST request to save the shipping zone and method set. $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/0/methods' ); $request->add_header( 'Content-Type', 'application/json' ); $request->set_body( wp_json_encode( array( 'method_id' => $intl_method, 'settings' => $intl_cost, ) ) ); rest_do_request( $request ); } } // Notify the user that no shipping methods are configured. if ( ! $setup_domestic && ! $setup_intl ) { WC_Admin_Notices::add_notice( 'no_shipping_methods' ); } wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) ); exit; } /** * Is Stripe country supported * https://stripe.com/global . * * @param string $country_code Country code. */ 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, true ); } /** * Is PayPal currency supported. * * @param string $currency Currency code. * @return boolean */ protected function is_paypal_supported_currency( $currency ) { $supported_currencies = array( 'AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB', 'RUB', 'INR', ); return in_array( $currency, $supported_currencies, true ); } /** * Is Klarna Checkout country supported. * * @param string $country_code Country code. */ protected function is_klarna_checkout_supported_country( $country_code ) { $supported_countries = array( 'SE', // Sweden. 'FI', // Finland. 'NO', // Norway. 'NL', // Netherlands. ); return in_array( $country_code, $supported_countries, true ); } /** * Is Klarna Payments country supported. * * @param string $country_code Country code. */ protected function is_klarna_payments_supported_country( $country_code ) { $supported_countries = array( 'DK', // Denmark. 'DE', // Germany. 'AT', // Austria. ); return in_array( $country_code, $supported_countries, true ); } /** * Is Square country supported * * @param string $country_code Country code. */ protected function is_square_supported_country( $country_code ) { $square_supported_countries = array( 'US', 'CA', 'JP', 'GB', 'AU', ); return in_array( $country_code, $square_supported_countries, true ); } /** * Is eWAY Payments country supported * * @param string $country_code Country code. */ protected function is_eway_payments_supported_country( $country_code ) { $supported_countries = array( 'AU', // Australia. 'NZ', // New Zealand. ); return in_array( $country_code, $supported_countries, true ); } /** * Is ShipStation country supported * * @param string $country_code Country code. */ protected function is_shipstation_supported_country( $country_code ) { $supported_countries = array( 'AU', // Australia. 'CA', // Canada. 'GB', // United Kingdom. ); return in_array( $country_code, $supported_countries, true ); } /** * Is WooCommerce Services shipping label country supported * * @param string $country_code Country code. */ protected function is_wcs_shipping_labels_supported_country( $country_code ) { $supported_countries = array( 'US', // United States. ); return in_array( $country_code, $supported_countries, true ); } /** * 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; } /** * Array of all possible "in cart" gateways that can be offered. * * @return array */ protected function get_wizard_available_in_cart_payment_gateways() { $user_email = $this->get_current_user_email(); $stripe_description = '

' . sprintf( /* translators: %s: URL */ __( 'Accept debit and credit cards in 135+ currencies, methods such as Alipay, and one-touch checkout with Apple Pay. Learn more.', 'woocommerce' ), 'https://woocommerce.com/products/stripe/' ) . '

'; $paypal_checkout_description = '

' . sprintf( /* translators: %s: URL */ __( 'Safe and secure payments using credit cards or your customer\'s PayPal account. Learn more.', 'woocommerce' ), 'https://woocommerce.com/products/woocommerce-gateway-paypal-checkout/' ) . '

'; $klarna_checkout_description = '

' . sprintf( /* translators: %s: URL */ __( 'Full checkout experience with pay now, pay later and slice it. No credit card numbers, no passwords, no worries. Learn more about Klarna.', 'woocommerce' ), 'https://woocommerce.com/products/klarna-checkout/' ) . '

'; $klarna_payments_description = '

' . sprintf( /* translators: %s: URL */ __( 'Choose the payment that you want, pay now, pay later or slice it. No credit card numbers, no passwords, no worries. Learn more about Klarna.', 'woocommerce' ), 'https://woocommerce.com/products/klarna-payments/ ' ) . '

'; $square_description = '

' . sprintf( /* translators: %s: URL */ __( 'Securely accept credit and debit cards with one low rate, no surprise fees (custom rates available). Sell online and in store and track sales and inventory in one place. Learn more about Square.', 'woocommerce' ), 'https://woocommerce.com/products/square/' ) . '

'; return array( 'stripe' => array( 'name' => __( 'WooCommerce Stripe Gateway', 'woocommerce' ), 'image' => WC()->plugin_url() . '/assets/images/stripe.png', 'description' => $stripe_description, 'class' => 'checked stripe-logo', 'repo-slug' => 'woocommerce-gateway-stripe', 'settings' => array( 'create_account' => array( 'label' => __( 'Set up Stripe for me using this email:', 'woocommerce' ), 'type' => 'checkbox', 'value' => 'yes', 'default' => 'yes', 'placeholder' => '', 'required' => false, 'plugins' => $this->get_wcs_requisite_plugins(), ), 'email' => array( 'label' => __( 'Stripe email address:', 'woocommerce' ), 'type' => 'email', 'value' => $user_email, 'placeholder' => __( 'Stripe email address', 'woocommerce' ), 'required' => true, ), ), ), 'ppec_paypal' => array( 'name' => __( 'WooCommerce PayPal Checkout Gateway', 'woocommerce' ), 'image' => WC()->plugin_url() . '/assets/images/paypal.png', 'description' => $paypal_checkout_description, 'enabled' => false, 'class' => 'checked paypal-logo', 'repo-slug' => 'woocommerce-gateway-paypal-express-checkout', 'settings' => array( 'reroute_requests' => array( 'label' => __( 'Set up PayPal for me using this email:', 'woocommerce' ), 'type' => 'checkbox', 'value' => 'yes', 'default' => 'yes', 'placeholder' => '', 'required' => false, 'plugins' => $this->get_wcs_requisite_plugins(), ), 'email' => array( 'label' => __( 'Direct payments to email address:', 'woocommerce' ), 'type' => 'email', 'value' => $user_email, 'placeholder' => __( 'Email address to receive payments', 'woocommerce' ), 'required' => true, ), ), ), '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, ), ), ), 'klarna_checkout' => array( 'name' => __( 'Klarna Checkout for WooCommerce', 'woocommerce' ), 'description' => $klarna_checkout_description, 'image' => WC()->plugin_url() . '/assets/images/klarna-black.png', 'enabled' => true, 'class' => 'klarna-logo', 'repo-slug' => 'klarna-checkout-for-woocommerce', ), 'klarna_payments' => array( 'name' => __( 'Klarna Payments for WooCommerce', 'woocommerce' ), 'description' => $klarna_payments_description, 'image' => WC()->plugin_url() . '/assets/images/klarna-black.png', 'enabled' => true, 'class' => 'klarna-logo', 'repo-slug' => 'klarna-payments-for-woocommerce', ), 'square' => array( 'name' => __( 'WooCommerce Square', 'woocommerce' ), 'description' => $square_description, 'image' => WC()->plugin_url() . '/assets/images/square-black.png', 'class' => 'square-logo', 'enabled' => false, 'repo-slug' => 'woocommerce-square', ), 'eway' => array( 'name' => __( 'WooCommerce eWAY Gateway', 'woocommerce' ), 'description' => __( 'The eWAY extension for WooCommerce allows you to take credit card payments directly on your store without redirecting your customers to a third party site to make payment.', 'woocommerce' ), 'image' => WC()->plugin_url() . '/assets/images/eway-logo.jpg', 'enabled' => false, 'class' => 'eway-logo', 'repo-slug' => 'woocommerce-gateway-eway', ), 'payfast' => array( 'name' => __( 'WooCommerce PayFast Gateway', 'woocommerce' ), 'description' => __( 'The PayFast extension for WooCommerce enables you to accept payments by Credit Card and EFT via one of South Africa’s most popular payment gateways. No setup fees or monthly subscription costs.', 'woocommerce' ), 'image' => WC()->plugin_url() . '/assets/images/payfast.png', 'class' => 'payfast-logo', 'enabled' => false, 'repo-slug' => 'woocommerce-payfast-gateway', 'file' => 'gateway-payfast.php', ), ); } /** * Simple array of "in cart" gateways to show in wizard. * * @return array */ public function get_wizard_in_cart_payment_gateways() { $gateways = $this->get_wizard_available_in_cart_payment_gateways(); $country = WC()->countries->get_base_country(); $currency = get_woocommerce_currency(); $can_stripe = $this->is_stripe_supported_country( $country ); $can_eway = $this->is_eway_payments_supported_country( $country ); $can_payfast = ( 'ZA' === $country ); // South Africa. $can_paypal = $this->is_paypal_supported_currency( $currency ); if ( ! current_user_can( 'install_plugins' ) ) { return $can_paypal ? array( 'paypal' => $gateways['paypal'] ) : array(); } $klarna_or_square = false; if ( $this->is_klarna_checkout_supported_country( $country ) ) { $klarna_or_square = 'klarna_checkout'; } elseif ( $this->is_klarna_payments_supported_country( $country ) ) { $klarna_or_square = 'klarna_payments'; } elseif ( $this->is_square_supported_country( $country ) && get_option( 'woocommerce_sell_in_person' ) ) { $klarna_or_square = 'square'; } $offered_gateways = array(); if ( $can_stripe ) { $gateways['stripe']['enabled'] = true; $gateways['stripe']['featured'] = true; $offered_gateways += array( 'stripe' => $gateways['stripe'] ); } elseif ( $can_paypal ) { $gateways['ppec_paypal']['enabled'] = true; } if ( $klarna_or_square ) { if ( in_array( $klarna_or_square, array( 'klarna_checkout', 'klarna_payments' ), true ) ) { $gateways[ $klarna_or_square ]['enabled'] = true; $gateways[ $klarna_or_square ]['featured'] = false; $offered_gateways += array( $klarna_or_square => $gateways[ $klarna_or_square ], ); } else { $offered_gateways += array( $klarna_or_square => $gateways[ $klarna_or_square ], ); } } if ( $can_paypal ) { $offered_gateways += array( 'ppec_paypal' => $gateways['ppec_paypal'] ); } if ( $can_eway ) { $offered_gateways += array( 'eway' => $gateways['eway'] ); } if ( $can_payfast ) { $offered_gateways += array( 'payfast' => $gateways['payfast'] ); } return $offered_gateways; } /** * Simple array of "manual" gateways to show in wizard. * * @return array */ public 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. * * @param int $item_id Item ID. * @param array $item_info Item info array. */ 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 = ( isset( $previously_saved_settings['enabled'] ) && 'yes' === $previously_saved_settings['enabled'] ) ? true : ( isset( $item_info['enabled'] ) && $item_info['enabled'] ); } else { $should_enable_toggle = isset( $item_info['enabled'] ) && $item_info['enabled']; } $plugins = null; if ( isset( $item_info['repo-slug'] ) ) { $plugin = array( 'slug' => $item_info['repo-slug'], 'name' => $item_info['name'], ); $plugins = array( $plugin ); } ?>
  • <?php echo esc_attr( $item_info['name'] ); ?>

    data-plugins="" />
    $setting ) : ?>
    data-plugins="" />
  • 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(); ?>

    Additional payment methods can be installed later.', 'woocommerce' ), array( 'a' => array( 'href' => array(), 'target' => array(), ), ) ), esc_url( admin_url( 'admin.php?page=wc-addons§ion=payment-gateways' ) ) ); ?>

    plugin_install_info(); ?>

    install_woocommerce_services(); } $gateways = array_merge( $this->get_wizard_in_cart_payment_gateways(), $this->get_wizard_manual_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' ] ) ) { // WPCS: CSRF ok, input var ok. $this->install_plugin( $gateway_id, $gateway ); } $settings = array( 'enabled' => ! empty( $_POST[ 'wc-wizard-service-' . $gateway_id . '-enabled' ] ) ? 'yes' : 'no' ); // WPCS: CSRF ok, input var ok. // @codingStandardsIgnoreStart if ( ! empty( $gateway['settings'] ) ) { foreach ( $gateway['settings'] as $setting_id => $setting ) { $settings[ $setting_id ] = 'yes' === $settings['enabled'] && isset( $_POST[ $gateway_id . '_' . $setting_id ] ) ? wc_clean( wp_unslash( $_POST[ $gateway_id . '_' . $setting_id ] ) ) : false; } } // @codingStandardsIgnoreSEnd if ( 'ppec_paypal' === $gateway_id && empty( $settings['reroute_requests'] ) ) { unset( $settings['enabled'] ); } $settings_key = 'woocommerce_' . $gateway_id . '_settings'; $previously_saved_settings = array_filter( (array) get_option( $settings_key, array() ) ); update_option( $settings_key, array_merge( $previously_saved_settings, $settings ) ); } wp_redirect( esc_url_raw( $this->get_next_step_link() ) ); exit; } protected function display_recommended_item( $item_info ) { $type = $item_info['type']; $title = $item_info['title']; $description = $item_info['description']; $img_url = $item_info['img_url']; $img_alt = $item_info['img_alt']; ?>

    plugin_install_info(); ?>

    install_theme( 'storefront' ); } if ( $setup_automated_tax ) { $this->install_woocommerce_services(); } if ( $setup_mailchimp ) { // Prevent MailChimp from redirecting to its settings page during the OBW flow. add_option( 'mailchimp_woocommerce_plugin_do_activation_redirect', false ); $this->install_plugin( 'mailchimp-for-woocommerce', array( 'name' => __( 'MailChimp for WooCommerce', 'woocommerce' ), 'repo-slug' => 'mailchimp-for-woocommerce', 'file' => 'mailchimp-woocommerce.php', ) ); } if ( $setup_facebook ) { $this->install_plugin( 'facebook-for-woocommerce', array( 'name' => __( 'Facebook for WooCommerce', 'woocommerce' ), 'repo-slug' => 'facebook-for-woocommerce', ) ); } if ( $setup_wc_admin ) { $this->install_plugin( 'woocommerce-admin', array( 'name' => __( 'WooCommerce Admin', 'woocommerce' ), 'repo-slug' => 'woocommerce-admin', ) ); } 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_feature_list() { $features = array(); $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']; $ppec_settings = get_option( 'woocommerce_ppec_paypal_settings', false ); $ppec_enabled = is_array( $ppec_settings ) && isset( $ppec_settings['reroute_requests'] ) && 'yes' === $ppec_settings['reroute_requests'] && isset( $ppec_settings['enabled'] ) && 'yes' === $ppec_settings['enabled']; $features['payment'] = $stripe_enabled || $ppec_enabled; $features['taxes'] = (bool) get_option( 'woocommerce_setup_automated_taxes', false ); $features['labels'] = (bool) get_option( 'woocommerce_setup_shipping_labels', false ); return $features; } protected function wc_setup_activate_get_feature_list_str() { $features = $this->wc_setup_activate_get_feature_list(); if ( $features['payment'] && $features['taxes'] && $features['labels'] ) { return __( 'payment setup, automated taxes and discounted shipping labels', 'woocommerce' ); } else if ( $features['payment'] && $features['taxes'] ) { return __( 'payment setup and automated taxes', 'woocommerce' ); } else if ( $features['payment'] && $features['labels'] ) { return __( 'payment setup and discounted shipping labels', 'woocommerce' ); } else if ( $features['payment'] ) { return __( 'payment setup', 'woocommerce' ); } else if ( $features['taxes'] && $features['labels'] ) { return __( 'automated taxes and discounted shipping labels', 'woocommerce' ); } else if ( $features['taxes'] ) { return __( 'automated taxes', 'woocommerce' ); } else if ( $features['labels'] ) { return __( 'discounted shipping labels', 'woocommerce' ); } return false; } /** * Activate step. */ public function wc_setup_activate() { $this->wc_setup_activate_actions(); $jetpack_connected = class_exists( 'Jetpack' ) && Jetpack::is_active(); $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 { $feature_list = $this->wc_setup_activate_get_feature_list_str(); $description = false; if ( $feature_list ) { if ( ! $jetpack_connected ) { /* 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' ); } else { $description_base = __( 'Thanks for using Jetpack! Your store is almost ready: to activate services like %s, just connect your store.', 'woocommerce' ); } $description = sprintf( $description_base, $feature_list ); } if ( ! $jetpack_connected ) { $title = $feature_list ? __( 'Connect your store to Jetpack', 'woocommerce' ) : __( 'Connect your store to Jetpack to enable extra features', 'woocommerce' ); $button_text = __( 'Continue with Jetpack', 'woocommerce' ); } elseif ( $feature_list ) { $title = __( 'Connect your store to activate WooCommerce Services', 'woocommerce' ); $button_text = __( 'Continue with WooCommerce Services', 'woocommerce' ); } else { wp_redirect( esc_url_raw( $this->get_next_step_link() ) ); exit; } } ?>

    Terms of Service and to share details with WordPress.com', 'woocommerce' ) ), 'https://wordpress.com/tos', 'https://jetpack.com/support/what-data-does-jetpack-sync' ); ?>

    __( "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' ); set_transient( 'wc_setup_activated', 'yes', MINUTE_IN_SECONDS * 10 ); // Leave a note for WooCommerce Services that Jetpack has been opted into. update_option( 'woocommerce_setup_jetpack_opted_in', true ); if ( class_exists( 'Jetpack' ) && Jetpack::is_active() ) { wp_safe_redirect( esc_url_raw( $this->get_next_step_link() ) ); exit; } WC_Install::background_installer( 'jetpack', array( '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 = esc_url_raw( add_query_arg( array( 'page' => 'wc-setup', 'step' => 'activate', 'from' => 'wpcom', 'activate_error' => false, ), admin_url() ) ); $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.', 'woocommerce' ), $videos_url, $docs_url ); ?>