diff --git a/includes/Data/Brands.php b/includes/Data/Brands.php
index d6518789a..d77c4754e 100644
--- a/includes/Data/Brands.php
+++ b/includes/Data/Brands.php
@@ -13,10 +13,10 @@ final class Brands {
*/
public static function get_default_brand() {
$default_brand_data = array(
- 'brand' => 'wordpress',
- 'name' => __( 'your web host', 'wp-module-onboarding' ),
- 'pluginDashboardPage' => \admin_url(),
- 'hireExpertsInfo' => array(
+ 'brand' => 'wordpress',
+ 'name' => __( 'your web host', 'wp-module-onboarding' ),
+ 'pluginDashboardPage' => \admin_url(),
+ 'hireExpertsInfo' => array(
'defaultLink' => 'https://www.bluehost.com/wp-live',
'queryParameters' => array(
'page' => 'bluehost',
@@ -92,7 +92,11 @@ public static function get_brands() {
),
),
'config' => array(
- 'net_new_signup_date_threshold' => '2022-08-18T15:30:00.000Z',
+ 'net_new_signup_date_threshold' => '2023-05-04T00:00:00.000Z',
+ 'enabled_flows' => array(
+ 'ecommerce' => true,
+ 'wp-setup' => true,
+ ),
),
),
'bluehost-india' => array(
@@ -146,6 +150,10 @@ public static function get_brands() {
),
'config' => array(
'net_new_signup_date_threshold' => '2022-08-18T15:30:00.000Z',
+ 'enabled_flows' => array(
+ 'ecommerce' => true,
+ 'wp-setup' => false,
+ ),
),
),
'webcom' => array(
@@ -200,6 +208,10 @@ public static function get_brands() {
),
'config' => array(
'net_new_signup_date_threshold' => '2022-08-18T15:30:00.000Z',
+ 'enabled_flows' => array(
+ 'ecommerce' => false,
+ 'wp-setup' => false,
+ ),
),
),
'crazy-domains' => array(
@@ -253,7 +265,11 @@ public static function get_brands() {
),
),
'config' => array(
- 'net_new_signup_date_threshold' => '2022-08-18T15:30:00.000Z',
+ 'net_new_signup_date_threshold' => '2023-05-04T00:00:00.000Z',
+ 'enabled_flows' => array(
+ 'ecommerce' => true,
+ 'wp-setup' => true,
+ ),
'views' => array(
'sidebar' => array(
'illustration' => array(
diff --git a/includes/Data/Data.php b/includes/Data/Data.php
index 8616e1343..49f63e57a 100644
--- a/includes/Data/Data.php
+++ b/includes/Data/Data.php
@@ -80,6 +80,15 @@ public static function current_plan() {
}
}
+ $current_flow = Flows::get_flow_from_top_priority();
+ if ( false !== $current_flow ) {
+ return array(
+ 'flow' => 'ecommerce',
+ 'subtype' => 'wc_priority',
+ 'type' => null,
+ );
+ }
+
return array(
'flow' => Flows::get_default_flow(),
'subtype' => null,
@@ -93,24 +102,8 @@ public static function current_plan() {
* @return string
*/
public static function current_flow() {
-
- $current_flow = Flows::get_flow_from_params();
- if ( false !== $current_flow ) {
- return $current_flow;
- }
-
- $current_flow = Flows::get_flow_from_plugins();
- if ( false !== $current_flow ) {
- return $current_flow;
- }
-
- $customer_data = self::customer_data();
- $current_flow = Flows::get_flow_from_customer_data( $customer_data );
- if ( false !== $current_flow ) {
- return $current_flow;
- }
-
- return Flows::get_default_flow();
+ $current_plan = self::current_plan();
+ return $current_plan['flow'];
}
/**
diff --git a/includes/Data/Flows.php b/includes/Data/Flows.php
index 982cbda8e..a04f56778 100644
--- a/includes/Data/Flows.php
+++ b/includes/Data/Flows.php
@@ -1,6 +1,7 @@
true,
- 'ecommerce' => true,
+ $current_brand = Data::current_brand();
+ return isset( $current_brand['config']['enabled_flows'] )
+ ? $current_brand['config']['enabled_flows'] : array(
+ 'wp-setup' => false,
+ 'ecommerce' => false,
);
}
@@ -212,15 +215,15 @@ public static function get_flow_from_params() {
$flows = self::get_flows();
if ( isset( $_GET['flow'] ) ) {
- $current_flow_type = \sanitize_text_field( $_GET['flow'] );
+ $current_flow_type = \sanitize_text_field( $_GET['flow'] );
}
- if ( ! empty( $current_flow_type ) && isset( $flows[ $current_flow_type ] ) ) {
+ if ( ! empty( $current_flow_type ) && true === $flows[ $current_flow_type ] ) {
return $current_flow_type;
}
$current_flow_type = \get_option( Options::get_option_name( 'flow_preset' ), false );
- if ( $current_flow_type && isset( $flows[ $current_flow_type ] ) ) {
+ if ( $current_flow_type && true === $flows[ $current_flow_type ] ) {
return $current_flow_type;
}
@@ -234,7 +237,7 @@ public static function get_flow_from_params() {
*/
public static function get_flow_from_plugins() {
if ( PluginInstaller::exists( 'woocommerce', true ) ) {
- return 'ecommerce';
+ return true === self::get_flows()['ecommerce'] ? 'ecommerce' : false;
}
return false;
}
@@ -260,8 +263,20 @@ public static function get_flow_from_customer_data( $customer_data = array() ) {
*/
public static function get_flow_from_plan_subtype( $plan_subtype ) {
if ( self::is_ecommerce_plan( $plan_subtype ) ) {
- return isset( self::get_flows()['ecommerce'] ) ? 'ecommerce' : false;
+ return true === self::get_flows()['ecommerce'] ? 'ecommerce' : false;
}
- return false;
+ return false;
+ }
+ /**
+ * Get the corresponding flow from the top priority in flow data.
+ *
+ * @return string|boolean
+ */
+ public static function get_flow_from_top_priority() {
+ $flow_data = FlowService::read_data_from_wp_option();
+ if ( $flow_data && isset( $flow_data['data']['topPriority']['priority1'] ) && 'selling' === $flow_data['data']['topPriority']['priority1'] ) {
+ return true === self::get_flows()['ecommerce'] ? 'ecommerce' : false;
+ }
+ return false;
}
}
diff --git a/includes/Data/Plugins.php b/includes/Data/Plugins.php
index 3b759f5b7..68b2082ef 100644
--- a/includes/Data/Plugins.php
+++ b/includes/Data/Plugins.php
@@ -18,8 +18,9 @@ final class Plugins {
'path' => 'jetpack/jetpack.php',
),
'woocommerce' => array(
- 'approved' => true,
- 'path' => 'woocommerce/woocommerce.php',
+ 'approved' => true,
+ 'path' => 'woocommerce/woocommerce.php',
+ 'post_install_callback' => array( __CLASS__, 'wc_prevent_redirect_on_activation' ),
),
'wordpress-seo' => array(
'approved' => true,
@@ -420,4 +421,13 @@ public static function get_init() {
return $init_list;
}
+ /**
+ * Prevent redirect to woo wizard after activation of woocommerce.
+ *
+ * @return void
+ */
+ public static function wc_prevent_redirect_on_activation() {
+ \delete_transient( '_wc_activation_redirect' );
+ }
+
}
diff --git a/includes/Data/Preview.php b/includes/Data/Preview.php
index c4f7930b8..886994f35 100644
--- a/includes/Data/Preview.php
+++ b/includes/Data/Preview.php
@@ -4,12 +4,25 @@
use NewfoldLabs\WP\Module\Onboarding\Services\PluginInstaller;
use NewfoldLabs\WP\Module\Onboarding\Services\ThemeInstaller;
+/**
+ * Class Preview
+ */
final class Preview {
-
+ /**
+ * Convert boolean to plugin/theme status.
+ *
+ * @param boolean $boolean The boolean value.
+ * @return string
+ */
private static function boolean_to_status( $boolean ) {
- return $boolean ? 'activated' : 'init';
+ return $boolean ? 'activated' : 'init';
}
+ /**
+ * Map of pre requisites to show the live preview successfully for a flow.
+ *
+ * @return array
+ */
private static function pre_requisites() {
$theme_map = Themes::get();
return array(
@@ -30,21 +43,35 @@ private static function pre_requisites() {
);
}
- public static function get_pre_requisites() {
- $pre_requisites = self::pre_requisites();
- return isset( $pre_requisites[ Data::current_flow() ] ) ? $pre_requisites[ Data::current_flow() ] : array();
+ /**
+ * Get the pre requisites for a given flow.
+ *
+ * @param string $flow A valid Onboarding flow.
+ * @return array
+ */
+ public static function get_pre_requisites( $flow = null ) {
+ $pre_requisites = self::pre_requisites();
+ if ( ! isset( $flow ) ) {
+ $flow = Data::current_flow();
+ }
+ return isset( $pre_requisites[ $flow ] ) ? $pre_requisites[ $flow ] : array();
}
+ /**
+ * Get all the settings necessary to load the live preview
+ *
+ * @return array
+ */
public static function get_settings() {
- $block_editor_context = new \WP_Block_Editor_Context( array( 'name' => 'core/edit-site' ) );
- $custom_settings = array(
- 'siteUrl' => \site_url(),
- );
+ $block_editor_context = new \WP_Block_Editor_Context( array( 'name' => 'core/edit-site' ) );
+ $custom_settings = array(
+ 'siteUrl' => \site_url(),
+ );
- return array(
- 'settings' => \get_block_editor_settings( $custom_settings, $block_editor_context ),
- 'globalStyles' => \wp_get_global_styles(),
- 'preRequisites' => self::get_pre_requisites(),
- );
+ return array(
+ 'settings' => \get_block_editor_settings( $custom_settings, $block_editor_context ),
+ 'globalStyles' => \wp_get_global_styles(),
+ 'preRequisites' => self::get_pre_requisites(),
+ );
}
}
diff --git a/includes/Data/SiteFeatures.php b/includes/Data/SiteFeatures.php
index d0f2c5092..727a167a9 100644
--- a/includes/Data/SiteFeatures.php
+++ b/includes/Data/SiteFeatures.php
@@ -11,144 +11,203 @@ final class SiteFeatures {
*
* @var array
*/
- protected static $site_features_flow_plan_map = array(
- 'wp-setup' => array(),
- 'ecommerce' => array(
- 'default' => array(
- 'jetpack' => array(
- 'slug' => 'jetpack',
- 'icon' => '--site-features-security',
- 'title' => 'Security, Speed & Growth',
- 'subtitle' => 'Powered by Jetpack',
- 'desc' => 'Jetpack includes dozens of powerful, unique capabilities for your WordPress sites from Automattic.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'wpforms-lite' => array(
- 'slug' => 'wpforms-lite',
- 'icon' => '--site-features-form',
- 'title' => 'Forms',
- 'subtitle' => 'Powered by WP Forms',
- 'desc' => 'Five million people build smarter forms and surveys with WPForms from Awesome Motive.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'google-analytics-for-wordpress' => array(
- 'slug' => 'google-analytics-for-wordpress',
- 'icon' => '--site-features-analytics',
- 'title' => 'Site Traffic',
- 'subtitle' => 'Powered by MonsterInsights',
- 'desc' => 'See the opportunities in your website analytics traffic data using MonsterInsights from Awesome Motive.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'wordpress-seo' => array(
- 'slug' => 'wordpress-seo',
- 'icon' => '--site-features-share',
- 'title' => 'Search Engine Optimization',
- 'subtitle' => 'Powered by Yoast',
- 'desc' => 'Get more traffic to your WordPress site with powerful analysis and tools from our colleagues at Yoast.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'creative-mail-by-constant-contact' => array(
- 'slug' => 'creative-mail-by-constant-contact',
- 'icon' => '--site-features-email',
- 'title' => 'Email Newsletters',
- 'subtitle' => 'Powered by Creative Email',
- 'desc' => 'A professional logo builder, marketing automations with WooCommerce and social management -- CreativeMail is a whole lot more than mail from Constant Contact.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'optinmonster' => array(
- 'slug' => 'optinmonster',
- 'icon' => '--site-features-lead',
- 'title' => 'Lead Generation',
- 'subtitle' => 'Powered by Optin Monster',
- 'desc' => 'Connect with website visitors using a proven kit of tools for growth using this offering from Awesome Motive.',
- 'selected' => false,
- 'shown' => true,
- ),
- ),
- 'wc_standard' => array(
- 'yith-woocommerce-ajax-search' => array(
- 'slug' => 'yith-woocommerce-ajax-search',
- 'icon' => '--site-features-search',
- 'title' => 'Enhanced Product Search',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Give your visitors great search experiences with this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'nfd_slug_yith_woocommerce_ajax_product_filter' => array(
- 'slug' => 'nfd_slug_yith_woocommerce_ajax_product_filter',
- 'icon' => '--site-features-filter',
- 'title' => 'Enhanced Product Filters',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Give your visitors powerful tools to discover your great products with this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'nfd_slug_yith_woocommerce_booking' => array(
- 'slug' => 'nfd_slug_yith_woocommerce_booking',
- 'icon' => '--site-features-bookingcalendar',
- 'title' => 'Bookings & Appointments',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Have visitors book meetings and services with you, accepting payment and more using this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'nfd_slug_yith_woocommerce_wishlist' => array(
- 'slug' => 'nfd_slug_yith_woocommerce_wishlist',
- 'icon' => '--site-features-wishlist',
- 'title' => 'Product Wishlists',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Let discerning shoppers curate their selections with a system of favorites using this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
+ protected static function get_site_features_flow_plan_map() {
+ return array(
+ 'wp-setup' => array(
+ 'default' => array(
+ 'jetpack' => array(
+ 'slug' => 'jetpack',
+ 'icon' => '--site-features-security',
+ 'title' => __( 'Security, Speed & Growth', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Jetpack', 'wp-module-onboarding' ),
+ 'desc' => __( 'Jetpack includes dozens of powerful, unique capabilities for your WordPress sites from Automattic.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'wpforms-lite' => array(
+ 'slug' => 'wpforms-lite',
+ 'icon' => '--site-features-form',
+ 'title' => __( 'Forms', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by WP Forms', 'wp-module-onboarding' ),
+ 'desc' => __( 'Five million people build smarter forms and surveys with WPForms from Awesome Motive.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'google-analytics-for-wordpress' => array(
+ 'slug' => 'google-analytics-for-wordpress',
+ 'icon' => '--site-features-analytics',
+ 'title' => __( 'Site Traffic', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by MonsterInsights', 'wp-module-onboarding' ),
+ 'desc' => __( 'See the opportunities in your website analytics traffic data using MonsterInsights from Awesome Motive.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'wordpress-seo' => array(
+ 'slug' => 'wordpress-seo',
+ 'icon' => '--site-features-share',
+ 'title' => __( 'Search Engine Optimization', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Yoast', 'wp-module-onboarding' ),
+ 'desc' => __( 'Get more traffic to your WordPress site with powerful analysis and tools from our colleagues at Yoast.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'creative-mail-by-constant-contact' => array(
+ 'slug' => 'creative-mail-by-constant-contact',
+ 'icon' => '--site-features-email',
+ 'title' => __( 'Email Newsletters', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Creative Email', 'wp-module-onboarding' ),
+ 'desc' => __( 'A professional logo builder, marketing automations with WooCommerce and social management -- CreativeMail is a whole lot more than mail from Constant Contact.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'optinmonster' => array(
+ 'slug' => 'optinmonster',
+ 'icon' => '--site-features-lead',
+ 'title' => __( 'Lead Generation', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Optin Monster', 'wp-module-onboarding' ),
+ 'desc' => __( 'Connect with website visitors using a proven kit of tools for growth using this offering from Awesome Motive.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
),
),
- 'wc_premium' => array(
- 'yith-woocommerce-ajax-search' => array(
- 'slug' => 'yith-woocommerce-ajax-search',
- 'icon' => '--site-features-search',
- 'title' => 'Enhanced Product Search',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Give your visitors great search experiences with this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
- ),
- 'nfd_slug_yith_woocommerce_ajax_product_filter' => array(
- 'slug' => 'nfd_slug_yith_woocommerce_ajax_product_filter',
- 'icon' => '--site-features-filter',
- 'title' => 'Enhanced Product Filters',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Give your visitors powerful tools to discover your great products with this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
+ 'ecommerce' => array(
+ 'default' => array(
+ 'jetpack' => array(
+ 'slug' => 'jetpack',
+ 'icon' => '--site-features-security',
+ 'title' => __( 'Security, Speed & Growth', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Jetpack', 'wp-module-onboarding' ),
+ 'desc' => __( 'Jetpack includes dozens of powerful, unique capabilities for your WordPress sites from Automattic.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'wpforms-lite' => array(
+ 'slug' => 'wpforms-lite',
+ 'icon' => '--site-features-form',
+ 'title' => __( 'Forms', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by WP Forms', 'wp-module-onboarding' ),
+ 'desc' => __( 'Five million people build smarter forms and surveys with WPForms from Awesome Motive.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'google-analytics-for-wordpress' => array(
+ 'slug' => 'google-analytics-for-wordpress',
+ 'icon' => '--site-features-analytics',
+ 'title' => __( 'Site Traffic', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by MonsterInsights', 'wp-module-onboarding' ),
+ 'desc' => __( 'See the opportunities in your website analytics traffic data using MonsterInsights from Awesome Motive.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'wordpress-seo' => array(
+ 'slug' => 'wordpress-seo',
+ 'icon' => '--site-features-share',
+ 'title' => __( 'Search Engine Optimization', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Yoast', 'wp-module-onboarding' ),
+ 'desc' => __( 'Get more traffic to your WordPress site with powerful analysis and tools from our colleagues at Yoast.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'creative-mail-by-constant-contact' => array(
+ 'slug' => 'creative-mail-by-constant-contact',
+ 'icon' => '--site-features-email',
+ 'title' => __( 'Email Newsletters', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Creative Email', 'wp-module-onboarding' ),
+ 'desc' => __( 'A professional logo builder, marketing automations with WooCommerce and social management -- CreativeMail is a whole lot more than mail from Constant Contact.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'optinmonster' => array(
+ 'slug' => 'optinmonster',
+ 'icon' => '--site-features-lead',
+ 'title' => __( 'Lead Generation', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by Optin Monster', 'wp-module-onboarding' ),
+ 'desc' => __( 'Connect with website visitors using a proven kit of tools for growth using this offering from Awesome Motive.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
),
- 'nfd_slug_yith_woocommerce_booking' => array(
- 'slug' => 'nfd_slug_yith_woocommerce_booking',
- 'icon' => '--site-features-bookingcalendar',
- 'title' => 'Bookings & Appointments',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Have visitors book meetings and services with you, accepting payment and more using this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
+ 'wc_standard' => array(
+ 'yith-woocommerce-ajax-search' => array(
+ 'slug' => 'yith-woocommerce-ajax-search',
+ 'icon' => '--site-features-search',
+ 'title' => __( 'Enhanced Product Search', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Give your visitors great search experiences with this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'nfd_slug_yith_woocommerce_ajax_product_filter' => array(
+ 'slug' => 'nfd_slug_yith_woocommerce_ajax_product_filter',
+ 'icon' => '--site-features-filter',
+ 'title' => __( 'Enhanced Product Filters', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Give your visitors powerful tools to discover your great products with this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'nfd_slug_yith_woocommerce_booking' => array(
+ 'slug' => 'nfd_slug_yith_woocommerce_booking',
+ 'icon' => '--site-features-bookingcalendar',
+ 'title' => __( 'Bookings & Appointments', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Have visitors book meetings and services with you, accepting payment and more using this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'nfd_slug_yith_woocommerce_wishlist' => array(
+ 'slug' => 'nfd_slug_yith_woocommerce_wishlist',
+ 'icon' => '--site-features-wishlist',
+ 'title' => __( 'Product Wishlists', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Let discerning shoppers curate their selections with a system of favorites using this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
),
- 'nfd_slug_yith_woocommerce_wishlist' => array(
- 'slug' => 'nfd_slug_yith_woocommerce_wishlist',
- 'icon' => '--site-features-wishlist',
- 'title' => 'Product Wishlists',
- 'subtitle' => 'Powered by YITH',
- 'desc' => 'Let discerning shoppers curate their selections with a system of favorites using this exclusive offering from our colleagues at YITH.',
- 'selected' => false,
- 'shown' => true,
+ 'wc_premium' => array(
+ 'yith-woocommerce-ajax-search' => array(
+ 'slug' => 'yith-woocommerce-ajax-search',
+ 'icon' => '--site-features-search',
+ 'title' => __( 'Enhanced Product Search', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Give your visitors great search experiences with this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'nfd_slug_yith_woocommerce_ajax_product_filter' => array(
+ 'slug' => 'nfd_slug_yith_woocommerce_ajax_product_filter',
+ 'icon' => '--site-features-filter',
+ 'title' => __( 'Enhanced Product Filters', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Give your visitors powerful tools to discover your great products with this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'nfd_slug_yith_woocommerce_booking' => array(
+ 'slug' => 'nfd_slug_yith_woocommerce_booking',
+ 'icon' => '--site-features-bookingcalendar',
+ 'title' => __( 'Bookings & Appointments', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Have visitors book meetings and services with you, accepting payment and more using this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
+ 'nfd_slug_yith_woocommerce_wishlist' => array(
+ 'slug' => 'nfd_slug_yith_woocommerce_wishlist',
+ 'icon' => '--site-features-wishlist',
+ 'title' => __( 'Product Wishlists', 'wp-module-onboarding' ),
+ 'subtitle' => __( 'Powered by YITH', 'wp-module-onboarding' ),
+ 'desc' => __( 'Let discerning shoppers curate their selections with a system of favorites using this exclusive offering from our colleagues at YITH.', 'wp-module-onboarding' ),
+ 'selected' => false,
+ 'shown' => true,
+ ),
),
+ 'wc_priority' => array(),
),
- 'wc_priority' => array(),
- ),
- );
+ );
+ }
/**
* Retrieves all the site features for a particular flow and plan.
@@ -156,17 +215,18 @@ final class SiteFeatures {
* @return array
*/
public static function get() {
- $plan_data = Data::current_plan();
- $plan_flow = $plan_data['flow'];
- $plan_subtype = $plan_data['subtype'];
+ $plan_data = Data::current_plan();
+ $plan_flow = $plan_data['flow'];
+ $plan_subtype = $plan_data['subtype'];
+ $site_features_flow_plan_map = self::get_site_features_flow_plan_map();
$site_features = array();
- if ( $plan_flow && isset( self::$site_features_flow_plan_map[ $plan_flow ] ) ) {
- if ( isset( self::$site_features_flow_plan_map[ $plan_flow ]['default'] ) ) {
- $site_features = array_merge( $site_features, self::$site_features_flow_plan_map[ $plan_flow ]['default'] );
+ if ( $plan_flow && isset( $site_features_flow_plan_map[ $plan_flow ] ) ) {
+ if ( isset( $site_features_flow_plan_map[ $plan_flow ]['default'] ) ) {
+ $site_features = array_merge( $site_features, $site_features_flow_plan_map[ $plan_flow ]['default'] );
}
- if ( 'default' !== $plan_subtype && isset( self::$site_features_flow_plan_map[ $plan_flow ][ $plan_subtype ] ) ) {
- $site_features = array_merge( $site_features, self::$site_features_flow_plan_map[ $plan_flow ][ $plan_subtype ] );
+ if ( 'default' !== $plan_subtype && isset( $site_features_flow_plan_map[ $plan_flow ][ $plan_subtype ] ) ) {
+ $site_features = array_merge( $site_features, $site_features_flow_plan_map[ $plan_flow ][ $plan_subtype ] );
}
}
return $site_features;
diff --git a/includes/Data/Themes.php b/includes/Data/Themes.php
index cb9a0b7b8..96ad22a56 100644
--- a/includes/Data/Themes.php
+++ b/includes/Data/Themes.php
@@ -28,24 +28,33 @@ final class Themes {
* @var array
*/
protected static $flow_default_theme_slugs = array(
- 'wp-setup' => 'twentytwentythree',
+ 'wp-setup' => 'yith-wonder',
'ecommerce' => 'yith-wonder',
);
- /**
- * Key 'default' contains a list of default themes to be installed irrespective of the plan.
- * Key contains a Key 'default' and a list of Key 's.
- * Key => 'default' contains a list of default theme installs for .
- * Key => contains a list of themes to be installed for a particular .
- *
- * The final queue of themes to be installed makes use of a max heap and hence the greater the number the earlier
- * a theme will be placed for install in the queue. This will also allow us to
- * prevent entering negative numbers when queueing a theme for earlier installs.
- *
- * @var array Initial themes to be installed classified based on the hosting plan.
- */
+ /**
+ * Key 'default' contains a list of default themes to be installed irrespective of the plan.
+ * Key contains a Key 'default' and a list of Key 's.
+ * Key => 'default' contains a list of default theme installs for .
+ * Key => contains a list of themes to be installed for a particular .
+ *
+ * The final queue of themes to be installed makes use of a max heap and hence the greater the number the earlier
+ * a theme will be placed for install in the queue. This will also allow us to
+ * prevent entering negative numbers when queueing a theme for earlier installs.
+ *
+ * @var array Initial themes to be installed classified based on the hosting plan.
+ */
protected static $init_list = array(
'default' => array(),
+ 'wp-setup' => array(
+ 'default' => array(
+ array(
+ 'slug' => 'nfd_slug_yith_wonder',
+ 'activate' => true,
+ 'priority' => 20,
+ ),
+ ),
+ ),
'ecommerce' => array(
'default' => array(
array(
@@ -57,26 +66,26 @@ final class Themes {
),
);
- /**
- * Returns the list of themes in a data structure that is faster to search.
- *
- * @return array
- */
+ /**
+ * Returns the list of themes in a data structure that is faster to search.
+ *
+ * @return array
+ */
public static function get() {
- return array(
- 'nfd_slugs' => self::$nfd_slugs,
- );
+ return array(
+ 'nfd_slugs' => self::$nfd_slugs,
+ );
}
- /**
- * Get all the approved theme slugs.
- *
- * @return array
- */
+ /**
+ * Get all the approved theme slugs.
+ *
+ * @return array
+ */
public static function get_approved() {
- return array(
- 'nfd_slugs' => array_keys( array_filter( self::$nfd_slugs, array( __CLASS__, 'check_approved' ) ) ),
- );
+ return array(
+ 'nfd_slugs' => array_keys( array_filter( self::$nfd_slugs, array( __CLASS__, 'check_approved' ) ) ),
+ );
}
/**
@@ -89,12 +98,12 @@ private static function check_approved( $value ) {
return true === $value['approved'];
}
- /**
- * Get the number of previews that will be fetched in each step.
- * This helps us show the number of necessary skeletons in the front end.
- *
- * @return array
- */
+ /**
+ * Get the number of previews that will be fetched in each step.
+ * This helps us show the number of necessary skeletons in the front end.
+ *
+ * @return array
+ */
public static function step_preview_data() {
$theme_step_data = Patterns::get_count_of_patterns();
$site_features = count( SiteFeatures::get() );
@@ -102,11 +111,11 @@ public static function step_preview_data() {
return $theme_step_data;
}
- /**
- * Get a list of initial themes to be installed for a particular hosting plan.
- *
- * @return array
- */
+ /**
+ * Get a list of initial themes to be installed for a particular hosting plan.
+ *
+ * @return array
+ */
public static function get_init() {
$plan_data = Data::current_plan();
$plan_flow = $plan_data['flow'];
diff --git a/includes/ModuleController.php b/includes/ModuleController.php
index 8df4b8afc..6de4298b2 100644
--- a/includes/ModuleController.php
+++ b/includes/ModuleController.php
@@ -35,8 +35,10 @@ public static function module_switcher() {
Brands::set_current_brand( container() );
$customer_data = Data::customer_data();
+ $enable_onboarding = self::verify_onboarding_criteria( $customer_data );
+
// Check if he is a Non-Ecom Cust and Disable Redirect and Module
- if ( ! self::is_new_commerce_signup( $customer_data ) ) {
+ if ( ! $enable_onboarding ) {
// Check if the Module Does Exist
if ( ModuleRegistry::get( $module_name ) ) {
@@ -56,6 +58,37 @@ public static function module_switcher() {
}
+ /**
+ * Verify all the necessary criteria to enable Onboarding for the site.
+ *
+ * @param array $customer_data The brand customer data.
+ * @return boolean
+ */
+ public static function verify_onboarding_criteria( $customer_data ) {
+ $brand_enabled_flows = Flows::get_flows();
+
+ foreach ( $brand_enabled_flows as $flow => $enabled ) {
+ if ( ! $enabled ) {
+ continue;
+ }
+
+ switch ( $flow ) {
+ case 'ecommerce':
+ if ( self::is_new_commerce_signup( $customer_data ) ) {
+ return true;
+ }
+ break;
+ case 'wp-setup':
+ if ( self::is_net_new_signup( $customer_data ) ) {
+ return true;
+ }
+ break;
+ }
+ }
+
+ return false;
+ }
+
/**
* Get signup date of the install.
*
@@ -82,6 +115,31 @@ public static function get_signup_date( $customer_data ) {
return false;
}
+ /**
+ * Determines if the signup data is after the brand's net_new_signup_date_threshold.
+ *
+ * @param array $customer_data The brand customer data.
+ * @return boolean
+ */
+ public static function is_net_new_signup( $customer_data ) {
+ $current_brand = Data::current_brand();
+ if ( ! isset( $current_brand['config']['net_new_signup_date_threshold'] ) ) {
+ return false;
+ }
+ $net_new_signup_date_threshold = gmdate( 'Y-m-d H:i:s', strtotime( $current_brand['config']['net_new_signup_date_threshold'] ) );
+
+ // Get the actual signup date of the install.
+ $signup_date = self::get_signup_date( $customer_data );
+
+ // As a safety measure, return false if a signup date cannot be determined.
+ if ( false === $signup_date ) {
+ return false;
+ }
+
+ // Determine whether the commerce install is a net new signup.
+ return $signup_date >= $net_new_signup_date_threshold;
+ }
+
/**
* Determine if the install is a new commerce signup
*
@@ -106,26 +164,8 @@ public static function is_new_commerce_signup( $customer_data ) {
return false;
}
- /*
- Get the net new signup date threshold from the brand configuration.
- As a safety measure, return false if a threshold is not set for a particular brand.
- */
- $current_brand = Data::current_brand();
- if ( ! isset( $current_brand['config']['net_new_signup_date_threshold'] ) ) {
- return false;
- }
- $net_new_signup_date_threshold = gmdate( 'Y-m-d H:i:s', strtotime( $current_brand['config']['net_new_signup_date_threshold'] ) );
-
- // Get the actual signup date of the install.
- $signup_date = self::get_signup_date( $customer_data );
-
- // As a safety measure, return false if a signup date cannot be determined.
- if ( false === $signup_date ) {
- return false;
- }
-
// Determine whether the commerce install is a net new signup.
- $is_net_new_signup = $signup_date >= $net_new_signup_date_threshold;
+ $is_net_new_signup = self::is_net_new_signup( $customer_data );
if ( ! $is_net_new_signup ) {
return false;
}
diff --git a/includes/RestApi/FlowController.php b/includes/RestApi/FlowController.php
index d749b9512..34fed044b 100644
--- a/includes/RestApi/FlowController.php
+++ b/includes/RestApi/FlowController.php
@@ -1,13 +1,8 @@
namespace,
+ $this->rest_base . '/switch',
+ array(
+ array(
+ 'methods' => \WP_REST_Server::CREATABLE,
+ 'callback' => array( $this, 'switch' ),
+ 'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ),
+ 'args' => $this->get_switch_args(),
+ ),
+ )
+ );
}
/**
- * Fetch onboarding flow details from database.
+ * Get the valid request params for the switch endpoint.
*
- * @param \WP_REST_Request $request Request model.
+ * @return array
+ */
+ public function get_switch_args() {
+ return array(
+ 'flow' => array(
+ 'required' => true,
+ 'type' => 'string',
+ 'sanitize_callback' => 'sanitize_text_field',
+ ),
+ );
+ }
+
+ /**
+ * Get Onboarding flow data.
*
* @return \WP_REST_Response
*/
- public function get_onboarding_flow_data( \WP_REST_Request $request ) {
- // check if data is available in the database if not then fetch the default dataset
- $result = $this->read_details_from_wp_options();
- if ( ! $result ) {
- $result = Flows::get_data();
- $result['createdAt'] = time();
- // update default data if flow type is ecommerce
- $result = $this->update_default_data_for_ecommerce( $result );
- $this->save_details_to_wp_options( $result );
- }
-
+ public function get_onboarding_flow_data() {
return new \WP_REST_Response(
- $result,
+ FlowService::get_flow_data(),
200
);
}
/**
- * Save / Update onboarding flow details to database.
+ * Update the Onboarding flow data.
*
- * @param \WP_REST_Request $request Request model.
+ * @param \WP_REST_Request $request The incoming request.
*
- * @return \WP_REST_Response|\WP_Error
+ * @return \WP_Error|\WP_REST_Response
*/
public function save_onboarding_flow_data( \WP_REST_Request $request ) {
- $flow_data = array();
- $params = json_decode( $request->get_body(), true );
-
- if ( is_null( $params ) ) {
- return new \WP_Error(
- 'no_post_data',
- 'No Data Provided',
- array( 'status' => 404 )
- );
- }
+ $params = json_decode( $request->get_body(), true );
- $flow_data = $this->read_details_from_wp_options();
- if ( ! $flow_data ) {
- $flow_data = Flows::get_data();
- $flow_data['createdAt'] = time();
- // update default data if flow type is ecommerce
- $flow_data = $this->update_default_data_for_ecommerce( $flow_data );
- $this->save_details_to_wp_options( $flow_data );
- }
-
- foreach ( $params as $key => $param ) {
- $value = $this->array_search_key( $key, $flow_data );
- if ( false === $value ) {
- return new \WP_Error(
- 'wrong_param_provided',
- "Wrong Parameter Provided : $key",
- array( 'status' => 404 )
- );
- }
- }
-
- /*
- [TODO] Handle this and some of the site name, logo, description logic in a cleaner way.
- At least the primary and secondary update does not run on every flow data request.
- */
- if ( ! empty( $params['data']['siteType']['primary']['refers'] ) &&
- ( empty( $flow_data['data']['siteType']['primary']['value'] ) || $flow_data['data']['siteType']['primary']['value'] !== $params['data']['siteType']['primary']['value'] ) ) {
- if ( class_exists( 'NewfoldLabs\WP\Module\Data\SiteClassification\PrimaryType' ) ) {
- $primary_type = new PrimaryType( $params['data']['siteType']['primary']['refers'], $params['data']['siteType']['primary']['value'] );
- if ( ! $primary_type->save() ) {
- return new \WP_Error(
- 'wrong_param_provided',
- __( 'Wrong Parameter Provided : primary => value', 'wp-module-onboarding' ),
- array( 'status' => 404 )
- );
- }
- }
- }
-
- if ( ! empty( $params['data']['siteType']['secondary']['refers'] ) &&
- ( empty( $flow_data['data']['siteType']['secondary']['value'] ) || $flow_data['data']['siteType']['secondary']['value'] !== $params['data']['siteType']['secondary']['value'] ) ) {
- if ( class_exists( 'NewfoldLabs\WP\Module\Data\SiteClassification\SecondaryType' ) ) {
- $secondary_type = new SecondaryType( $params['data']['siteType']['secondary']['refers'], $params['data']['siteType']['secondary']['value'] );
- if ( ! $secondary_type->save() ) {
- return new \WP_Error(
- 'wrong_param_provided',
- __( 'Wrong Parameter Provided : secondary => value', 'wp-module-onboarding' ),
- array( 'status' => 404 )
- );
- }
- }
- }
-
- $flow_data = array_replace_recursive( $flow_data, $params );
-
- // update timestamp once data is updated
- $flow_data['updatedAt'] = time();
-
- // Update Blog Information from Basic Info
- if ( ( ! empty( $flow_data['data']['blogName'] ) ) ) {
- \update_option( Options::get_option_name( 'blog_name', false ), $flow_data['data']['blogName'] );
- }
-
- if ( ( ! empty( $flow_data['data']['blogDescription'] ) ) ) {
- \update_option( Options::get_option_name( 'blog_description', false ), $flow_data['data']['blogDescription'] );
- }
-
- if ( ( ! empty( $flow_data['data']['siteLogo'] ) ) && ! empty( $flow_data['data']['siteLogo']['id'] ) ) {
- \update_option( Options::get_option_name( 'site_icon', false ), $flow_data['data']['siteLogo']['id'] );
- \update_option( Options::get_option_name( 'site_logo', false ), $flow_data['data']['siteLogo']['id'] );
- } else {
- \update_option( Options::get_option_name( 'site_icon', false ), 0 );
- \delete_option( Options::get_option_name( 'site_logo', false ) );
- }
-
- // save data to database
- if ( ! $this->update_wp_options_data_in_database( $flow_data ) ) {
- return new \WP_Error(
- 'database_update_failed',
- 'There was an error saving the data',
- array( 'status' => 404 )
- );
+ $flow_data = FlowService::update_flow_data( $params );
+ if ( \is_wp_error( $flow_data ) ) {
+ return $flow_data;
}
return new \WP_REST_Response(
@@ -196,78 +120,7 @@ public function save_onboarding_flow_data( \WP_REST_Request $request ) {
}
/**
- * Check the current flow type and update default data if flowtype is ecommerce.
- *
- * @param array $data default blueprint flow data.
- *
- * @return array
- */
- private function update_default_data_for_ecommerce( $data ) {
- // get current flow type
- $flow_type = Data::current_flow();
- if ( 'ecommerce' === $flow_type ) {
- // update default data with ecommerce data
- $data['data']['topPriority']['priority1'] = 'selling';
- }
- return $data;
- }
-
- /**
- * Read onboarding flow options from database
- *
- * @return array
- */
- public function read_details_from_wp_options() {
- return \get_option( Options::get_option_name( 'flow' ) );
- }
-
- /**
- * Add onboarding flow options
- *
- * @param array $data default blueprint flow data.
- *
- * @return array
- */
- private function save_details_to_wp_options( $data ) {
- return \add_option( Options::get_option_name( 'flow' ), $data );
- }
-
- /**
- * Update onboarding flow options
- *
- * @param array $data default blueprint flow data.
- *
- * @return array
- */
- private function update_wp_options_data_in_database( $data ) {
- return \update_option( Options::get_option_name( 'flow' ), $data );
- }
-
- /**
- * Function to search for key in array recursively with case sensitive exact match
- *
- * @param array $needle_key specific key in flow data.
- * @param array $array WP Options Data.
- *
- * @return boolean
- */
- private function array_search_key( $needle_key, $array ) {
- foreach ( $array as $key => $value ) {
- if ( strcmp( $key, $needle_key ) === 0 ) {
- return true;
- }
- if ( is_array( $value ) ) {
- $result = $this->array_search_key( $needle_key, $value );
- if ( false !== $result ) {
- return $result;
- }
- }
- }
- return false;
- }
-
- /**
- * Flow completion API for child theme generation, verify child theme and publish site pages
+ * Flow completion API for child theme generation, verify child theme and publish site pages.
*
* @return \WP_REST_Response
*/
@@ -294,4 +147,23 @@ public function complete() {
201
);
}
+
+ /**
+ * Switch the Onboarding flow.
+ *
+ * @param \WP_REST_Request $request The incoming switch request.
+ * @return \WP_Error|\WP_REST_Response
+ */
+ public function switch( \WP_REST_Request $request ) {
+ $flow = $request->get_param( 'flow' );
+ $status = FlowService::switch_flow( $flow );
+ if ( \is_wp_error( $status ) ) {
+ return $status;
+ }
+
+ return new \WP_REST_Response(
+ array(),
+ 200
+ );
+ }
}
diff --git a/includes/Services/FlowService.php b/includes/Services/FlowService.php
new file mode 100644
index 000000000..dab38ca00
--- /dev/null
+++ b/includes/Services/FlowService.php
@@ -0,0 +1,232 @@
+ 404 )
+ );
+ }
+
+ $flow_data = self::get_flow_data();
+
+ foreach ( $params as $key => $param ) {
+ $value = self::array_search_key( $key, $flow_data );
+ if ( false === $value ) {
+ return new \WP_Error(
+ 'wrong_param_provided',
+ "Wrong Parameter Provided : $key",
+ array( 'status' => 404 )
+ );
+ }
+ }
+
+ /*
+ [TODO] Handle this and some of the site name, logo, description logic in a cleaner way.
+ At least the primary and secondary update does not run on every flow data request.
+ */
+ if ( ! empty( $params['data']['siteType']['primary']['refers'] ) &&
+ ( empty( $flow_data['data']['siteType']['primary']['value'] ) || $flow_data['data']['siteType']['primary']['value'] !== $params['data']['siteType']['primary']['value'] ) ) {
+ if ( class_exists( 'NewfoldLabs\WP\Module\Data\SiteClassification\PrimaryType' ) ) {
+ $primary_type = new PrimaryType( $params['data']['siteType']['primary']['refers'], $params['data']['siteType']['primary']['value'] );
+ if ( ! $primary_type->save() ) {
+ return new \WP_Error(
+ 'wrong_param_provided',
+ __( 'Wrong Parameter Provided : primary => value', 'wp-module-onboarding' ),
+ array( 'status' => 404 )
+ );
+ }
+ }
+ }
+
+ if ( ! empty( $params['data']['siteType']['secondary']['refers'] ) &&
+ ( empty( $flow_data['data']['siteType']['secondary']['value'] ) || $flow_data['data']['siteType']['secondary']['value'] !== $params['data']['siteType']['secondary']['value'] ) ) {
+ if ( class_exists( 'NewfoldLabs\WP\Module\Data\SiteClassification\SecondaryType' ) ) {
+ $secondary_type = new SecondaryType( $params['data']['siteType']['secondary']['refers'], $params['data']['siteType']['secondary']['value'] );
+ if ( ! $secondary_type->save() ) {
+ return new \WP_Error(
+ 'wrong_param_provided',
+ __( 'Wrong Parameter Provided : secondary => value', 'wp-module-onboarding' ),
+ array( 'status' => 404 )
+ );
+ }
+ }
+ }
+
+ $flow_data = array_replace_recursive( $flow_data, $params );
+
+ // Update timestamp everytime the Onboarding flow data is updated.
+ $flow_data['updatedAt'] = time();
+
+ // Update Blog Information from Basic Info
+ if ( ( ! empty( $flow_data['data']['blogName'] ) ) ) {
+ \update_option( Options::get_option_name( 'blog_name', false ), $flow_data['data']['blogName'] );
+ }
+
+ if ( ( ! empty( $flow_data['data']['blogDescription'] ) ) ) {
+ \update_option( Options::get_option_name( 'blog_description', false ), $flow_data['data']['blogDescription'] );
+ }
+
+ if ( ( ! empty( $flow_data['data']['siteLogo'] ) ) && ! empty( $flow_data['data']['siteLogo']['id'] ) ) {
+ \update_option( Options::get_option_name( 'site_icon', false ), $flow_data['data']['siteLogo']['id'] );
+ \update_option( Options::get_option_name( 'site_logo', false ), $flow_data['data']['siteLogo']['id'] );
+ } else {
+ \update_option( Options::get_option_name( 'site_icon', false ), 0 );
+ \delete_option( Options::get_option_name( 'site_logo', false ) );
+ }
+
+ if ( ! self::update_data_in_wp_option( $flow_data ) ) {
+ return new \WP_Error(
+ 'database_update_failed',
+ 'There was an error saving the data',
+ array( 'status' => 404 )
+ );
+ }
+
+ return $flow_data;
+ }
+
+ /**
+ * Switch the Onboarding flow.
+ *
+ * @param string $flow A valid Onboarding flow for a brand.
+ * @return \WP_Error|boolean
+ */
+ public static function switch_flow( $flow ) {
+ // Get all the enabled flows for a brand.
+ $enabled_flows = Flows::get_flows();
+ // If the request flow does not exist or is not enabled then return an error.
+ if ( ! isset( $enabled_flows[ $flow ] ) || true !== $enabled_flows[ $flow ] ) {
+ return new \WP_Error(
+ 'nfd_onboarding_error',
+ 'Flow not enabled.',
+ array( 'status' => 400 )
+ );
+ }
+
+ // Reset the Plugin Install Status and Queue.
+ PluginInstallTaskManager::reset_install_status();
+
+ // Get the pre requisites for a flow.
+ $pre_requisites = Preview::get_pre_requisites( $flow );
+ if ( ! isset( $pre_requisites ) || ! isset( $pre_requisites['plugins'] ) ) {
+ return true;
+ }
+
+ // Install and activate all the required plugins.
+ foreach ( $pre_requisites['plugins'] as $plugin => $active ) {
+ // Skip if the plugin installation if it is already active.
+ if ( 'activated' === $active ) {
+ continue;
+ }
+
+ $plugin_install_task = new PluginInstallTask( $plugin, true );
+ $status = $plugin_install_task->execute();
+
+ if ( \is_wp_error( $status ) ) {
+ return $status;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Read Onboarding flow data from the wp_option.
+ *
+ * @return array
+ */
+ public static function read_data_from_wp_option() {
+ return \get_option( Options::get_option_name( 'flow' ), false );
+ }
+
+ /**
+ * Update flow data params if the current flow is ecommerce.
+ *
+ * @param array $data The flow data.
+ *
+ * @return array
+ */
+ private static function update_data_for_ecommerce( $data ) {
+ // get current flow type
+ $flow_type = Data::current_flow();
+ if ( 'ecommerce' === $flow_type ) {
+ // update default data with ecommerce data
+ $data['data']['topPriority']['priority1'] = 'selling';
+ }
+ return $data;
+ }
+
+ /**
+ * Update Onboarding flow data in the wp_option.
+ *
+ * @param array $data default blueprint flow data.
+ *
+ * @return array
+ */
+ private static function update_data_in_wp_option( $data ) {
+ return \update_option( Options::get_option_name( 'flow' ), $data );
+ }
+
+ /**
+ * Search for $needle_key in $array recursively.
+ *
+ * @param string $needle_key The key to be searched for.
+ * @param array $array The array in which the search occurs.
+ *
+ * @return boolean
+ */
+ private static function array_search_key( $needle_key, $array ) {
+ foreach ( $array as $key => $value ) {
+ if ( strcmp( $key, $needle_key ) === 0 ) {
+ return true;
+ }
+ if ( is_array( $value ) ) {
+ $result = self::array_search_key( $needle_key, $value );
+ if ( false !== $result ) {
+ return $result;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/includes/Services/PluginInstaller.php b/includes/Services/PluginInstaller.php
index 5dc155e39..89d2eb497 100644
--- a/includes/Services/PluginInstaller.php
+++ b/includes/Services/PluginInstaller.php
@@ -2,10 +2,20 @@
namespace NewfoldLabs\WP\Module\Onboarding\Services;
use NewfoldLabs\WP\Module\Onboarding\Data\Plugins;
-use NewfoldLabs\WP\Module\Onboarding\Data\Options;
+/**
+ * Class PluginInstaller
+ */
class PluginInstaller {
+ /**
+ * Install a whitelisted plugin.
+ *
+ * @param string $plugin The plugin slug from Plugins.php.
+ * @param boolean $activate Whether to activate the plugin after install.
+ *
+ * @return \WP_Error|\WP_REST_Response
+ */
public static function install( $plugin, $activate ) {
$plugins_list = Plugins::get();
@@ -36,23 +46,23 @@ public static function install( $plugin, $activate ) {
// If it is not a zip URL then check if it is an approved slug.
$plugin = \sanitize_text_field( $plugin );
if ( self::is_nfd_slug( $plugin ) ) {
- // [TODO] Better handle mu-plugins and direct file downloads.
- if ( $plugin === 'nfd_slug_endurance_page_cache' ) {
+ // [TODO] Better handle mu-plugins and direct file downloads.
+ if ( 'nfd_slug_endurance_page_cache' === $plugin ) {
return self::install_endurance_page_cache();
}
- $plugin_path = $plugins_list['nfd_slugs'][ $plugin ]['path'];
+ $plugin_path = $plugins_list['nfd_slugs'][ $plugin ]['path'];
if ( ! self::is_plugin_installed( $plugin_path ) ) {
- $status = self::install_from_zip( $plugins_list['nfd_slugs'][ $plugin ]['url'], $activate );
+ $status = self::install_from_zip( $plugins_list['nfd_slugs'][ $plugin ]['url'], $activate );
if ( \is_wp_error( $status ) ) {
return $status;
}
}
if ( $activate && ! \is_plugin_active( $plugin_path ) ) {
- $status = \activate_plugin( $plugin_path );
+ $status = \activate_plugin( $plugin_path );
if ( \is_wp_error( $status ) ) {
- $status->add_data( array( 'status' => 500 ) );
+ $status->add_data( array( 'status' => 500 ) );
- return $status;
+ return $status;
}
}
return new \WP_REST_Response(
@@ -69,20 +79,26 @@ public static function install( $plugin, $activate ) {
);
}
- $plugin_path = $plugins_list['wp_slugs'][ $plugin ]['path'];
+ $plugin_path = $plugins_list['wp_slugs'][ $plugin ]['path'];
+ $plugin_post_install_callback = isset( $plugins_list['wp_slugs'][ $plugin ]['post_install_callback'] )
+ ? $plugins_list['wp_slugs'][ $plugin ]['post_install_callback']
+ : false;
if ( ! self::is_plugin_installed( $plugin_path ) ) {
- $status = self::install_from_wordpress( $plugin, $activate );
+ $status = self::install_from_wordpress( $plugin, $activate );
if ( \is_wp_error( $status ) ) {
- return $status;
+ return $status;
+ }
+ if ( is_callable( $plugin_post_install_callback ) ) {
+ $plugin_post_install_callback();
}
}
if ( $activate && ! \is_plugin_active( $plugin_path ) ) {
- $status = \activate_plugin( $plugin_path );
+ $status = \activate_plugin( $plugin_path );
if ( \is_wp_error( $status ) ) {
- $status->add_data( array( 'status' => 500 ) );
+ $status->add_data( array( 'status' => 500 ) );
- return $status;
+ return $status;
}
}
@@ -93,12 +109,14 @@ public static function install( $plugin, $activate ) {
}
/**
- * @param string $slug Representing the wordpress.org slug.
+ * Install a plugin from wordpress.org.
*
+ * @param string $plugin The wp_slug to install.
+ * @param boolean $activate Whether to activate the plugin after install.
* @return \WP_REST_Response|\WP_Error
*/
public static function install_from_wordpress( $plugin, $activate ) {
- require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
$api = \plugins_api(
'plugin_information',
@@ -121,9 +139,9 @@ public static function install_from_wordpress( $plugin, $activate ) {
return $api;
}
- $status = self::install_from_zip( $api->download_link, $activate );
+ $status = self::install_from_zip( $api->download_link, $activate );
if ( \is_wp_error( $status ) ) {
- return $status;
+ return $status;
}
return new \WP_REST_Response(
@@ -133,8 +151,10 @@ public static function install_from_wordpress( $plugin, $activate ) {
}
/**
- * @param string $url URL to the zip for the plugin.
+ * Install the plugin from a custom ZIP.
*
+ * @param string $url The ZIP URL to install from.
+ * @param boolean $activate Whether to activate the plugin after install.
* @return \WP_REST_Response|\WP_Error
*/
public static function install_from_zip( $url, $activate ) {
@@ -192,11 +212,11 @@ public static function install_from_zip( $url, $activate ) {
}
if ( $activate && ! \is_plugin_active( $plugin_file ) ) {
- $status = \activate_plugin( $plugin_file );
+ $status = \activate_plugin( $plugin_file );
if ( \is_wp_error( $status ) ) {
- $status->add_data( array( 'status' => 500 ) );
+ $status->add_data( array( 'status' => 500 ) );
- return $status;
+ return $status;
}
}
@@ -207,25 +227,23 @@ public static function install_from_zip( $url, $activate ) {
}
/**
- * @param string $plugin Slug of the plugin.
- *
* Checks if a given slug is a valid nfd_slug. Ref: includes/Data/Plugins.php for nfd_slug.
*
+ * @param string $plugin Slug of the plugin.
* @return boolean
*/
public static function is_nfd_slug( $plugin ) {
- $plugins_list = Plugins::get();
+ $plugins_list = Plugins::get();
if ( isset( $plugins_list['nfd_slugs'][ $plugin ]['approved'] ) ) {
- return true;
+ return true;
}
- return false;
+ return false;
}
/**
- * @param string $plugin_path Path to the plugin's header file.
- *
* Determines if a plugin has already been installed.
*
+ * @param string $plugin_path Path to the plugin's header file.
* @return boolean
*/
public static function is_plugin_installed( $plugin_path ) {
@@ -241,50 +259,51 @@ public static function is_plugin_installed( $plugin_path ) {
}
/**
- * @param string $plugin
+ * Get the type of plugin slug. Ref: includes/Data/Plugins.php for the different types.
*
- * @return string Type of plugin. Ref: includes/Data/Plugins.php for the different types.
+ * @param string $plugin The plugin slug to retrieve the type.
+ * @return string
*/
public static function get_plugin_type( $plugin ) {
if ( \wp_http_validate_url( $plugin ) ) {
- return 'urls';
+ return 'urls';
}
if ( self::is_nfd_slug( $plugin ) ) {
- return 'nfd_slugs';
+ return 'nfd_slugs';
}
- return 'wp_slugs';
+ return 'wp_slugs';
}
/**
- * @param string $plugin
- * @param string $plugin_type
+ * Get the path to the Plugin's header file.
*
- * @return string Path to the Plugin's header file.
+ * @param string $plugin The slug of the plugin.
+ * @param string $plugin_type The type of plugin.
+ * @return string
*/
public static function get_plugin_path( $plugin, $plugin_type ) {
- $plugin_list = Plugins::get();
- return $plugin_list[ $plugin_type ][ $plugin ]['path'];
+ $plugin_list = Plugins::get();
+ return $plugin_list[ $plugin_type ][ $plugin ]['path'];
}
/**
- * @param string $plugin
- * @param string $activate
- *
* Checks if a plugin with the given slug and activation criteria already exists.
*
+ * @param string $plugin The slug of the plugin to check for
+ * @param boolean $activate The activation criteria.
* @return boolean
*/
public static function exists( $plugin, $activate ) {
- $plugin_type = self::get_plugin_type( $plugin );
- $plugin_path = self::get_plugin_path( $plugin, $plugin_type );
+ $plugin_type = self::get_plugin_type( $plugin );
+ $plugin_path = self::get_plugin_path( $plugin, $plugin_type );
if ( ! self::is_plugin_installed( $plugin_path ) ) {
- return false;
+ return false;
}
if ( $activate && ! \is_plugin_active( $plugin_path ) ) {
- return false;
+ return false;
}
- return true;
+ return true;
}
/**
@@ -303,11 +322,11 @@ public static function install_endurance_page_cache() {
);
}
- global $wp_filesystem;
+ global $wp_filesystem;
- $plugin_list = Plugins::get();
- $plugin_url = $plugin_list['nfd_slugs']['nfd_slug_endurance_page_cache']['url'];
- $plugin_path = $plugin_list['nfd_slugs']['nfd_slug_endurance_page_cache']['path'];
+ $plugin_list = Plugins::get();
+ $plugin_url = $plugin_list['nfd_slugs']['nfd_slug_endurance_page_cache']['url'];
+ $plugin_path = $plugin_list['nfd_slugs']['nfd_slug_endurance_page_cache']['path'];
if ( $wp_filesystem->exists( $plugin_path ) ) {
return new \WP_REST_Response(
@@ -317,15 +336,15 @@ public static function install_endurance_page_cache() {
}
if ( ! $wp_filesystem->is_dir( WP_CONTENT_DIR . '/mu-plugins' ) ) {
- $wp_filesystem->mkdir( WP_CONTENT_DIR . '/mu-plugins' );
+ $wp_filesystem->mkdir( WP_CONTENT_DIR . '/mu-plugins' );
}
- $request = \wp_remote_get( $plugin_url );
+ $request = \wp_remote_get( $plugin_url );
if ( \is_wp_error( $request ) ) {
- return $request;
+ return $request;
}
- $wp_filesystem->put_contents( $plugin_path, $request['body'], FS_CHMOD_FILE );
+ $wp_filesystem->put_contents( $plugin_path, $request['body'], FS_CHMOD_FILE );
return new \WP_REST_Response(
array(),
@@ -343,7 +362,7 @@ protected static function connect_to_filesystem() {
// We want to ensure that the user has direct access to the filesystem.
$access_type = \get_filesystem_method();
- if ( $access_type !== 'direct' ) {
+ if ( 'direct' !== $access_type ) {
return false;
}
diff --git a/includes/TaskManagers/PluginInstallTaskManager.php b/includes/TaskManagers/PluginInstallTaskManager.php
index c03014281..f5e1d7e4f 100644
--- a/includes/TaskManagers/PluginInstallTaskManager.php
+++ b/includes/TaskManagers/PluginInstallTaskManager.php
@@ -12,16 +12,24 @@
*/
class PluginInstallTaskManager {
- /**
- * The number of times a PluginInstallTask can be retried.
- *
- * @var int
- */
+ /**
+ * The number of times a PluginInstallTask can be retried.
+ *
+ * @var int
+ */
private static $retry_limit = 1;
+ /**
+ * The name of the queue, might be prefixed.
+ *
+ * @var string
+ */
private static $queue_name = 'plugin_install_queue';
- function __construct() {
+ /**
+ * Schedules the crons.
+ */
+ public function __construct() {
// Ensure there is a thirty second option in the cron schedules
add_filter( 'cron_schedules', array( $this, 'add_thirty_seconds_schedule' ) );
@@ -34,10 +42,21 @@ function __construct() {
}
}
+ /**
+ * Returns the queue name, might be prefixed.
+ *
+ * @return string
+ */
public static function get_queue_name() {
- return self::$queue_name;
+ return self::$queue_name;
}
+ /**
+ * Adds a 30 second cron schedule.
+ *
+ * @param array $schedules The existing cron schedule.
+ * @return array
+ */
public function add_thirty_seconds_schedule( $schedules ) {
if ( ! array_key_exists( 'thirty_seconds', $schedules ) || 30 !== $schedules['thirty_seconds']['interval'] ) {
$schedules['thirty_seconds'] = array(
@@ -46,9 +65,14 @@ public function add_thirty_seconds_schedule( $schedules ) {
);
}
- return $schedules;
+ return $schedules;
}
+ /**
+ * Queues the initial list of Plugin Installs for a flow.
+ *
+ * @return boolean
+ */
public static function queue_initial_installs() {
// Checks if the init_list of plugins have already been queued.
@@ -57,7 +81,7 @@ public static function queue_initial_installs() {
}
// Set option to installing to prevent re-queueing the init_list again on page load.
- \update_option( Options::get_option_name( 'plugins_init_status' ), 'installing' );
+ \update_option( Options::get_option_name( 'plugins_init_status' ), 'installing' );
// Get the initial list of plugins to be installed based on the plan.
$init_plugins = Plugins::get_init();
@@ -86,17 +110,19 @@ public static function queue_initial_installs() {
*/
public function install() {
/*
- Get the plugins queued up to be installed, the PluginInstall task gets
- converted to an associative array before storing it in the option. */
+ Get the plugins queued up to be installed, the PluginInstall task gets
+ converted to an associative array before storing it in the option.
+ */
$plugins = \get_option( Options::get_option_name( self::$queue_name ), array() );
/*
- Conversion of the max heap to an array will always place the PluginInstallTask with the highest
- priority at the beginning of the array */
+ Conversion of the max heap to an array will always place the PluginInstallTask with the highest
+ priority at the beginning of the array
+ */
$plugin_to_install = array_shift( $plugins );
// Update the plugin install queue.
- \update_option( Options::get_option_name( self::$queue_name ), $plugins );
+ \update_option( Options::get_option_name( self::$queue_name ), $plugins );
// Recreate the PluginInstall task from the associative array.
$plugin_install_task = new PluginInstallTask(
@@ -113,15 +139,16 @@ public function install() {
$status = $plugin_install_task->execute();
if ( \is_wp_error( $status ) ) {
- // If there is an error, then increase the retry count for the task.
- $plugin_install_task->increment_retries();
+ // If there is an error, then increase the retry count for the task.
+ $plugin_install_task->increment_retries();
- // Get Latest Value of the install queue
- $plugins = \get_option( Options::get_option_name( self::$queue_name ), array() );
+ // Get Latest Value of the install queue
+ $plugins = \get_option( Options::get_option_name( self::$queue_name ), array() );
- /*
- If the number of retries have not exceeded the limit
- then re-queue the task at the end of the queue to be retried. */
+ /*
+ If the number of retries have not exceeded the limit
+ then re-queue the task at the end of the queue to be retried.
+ */
if ( $plugin_install_task->get_retries() <= self::$retry_limit ) {
array_push( $plugins, $plugin_install_task->to_array() );
@@ -139,30 +166,30 @@ public function install() {
}
/**
- * @param PluginInstallTask $plugin_install_task
- *
* Adds a new PluginInstallTask to the Plugin Install queue.
* The Task will be inserted at an appropriate position in the queue based on it's priority.
*
+ * @param PluginInstallTask $plugin_install_task The task to be inserted.
* @return array|false
*/
public static function add_to_queue( PluginInstallTask $plugin_install_task ) {
/*
- Get the plugins queued up to be installed, the PluginInstall task gets
- converted to an associative array before storing it in the option. */
+ Get the plugins queued up to be installed, the PluginInstall task gets
+ converted to an associative array before storing it in the option.
+ */
$plugins = \get_option( Options::get_option_name( self::$queue_name ), array() );
$queue = new PriorityQueue();
foreach ( $plugins as $queued_plugin ) {
-
/*
- Check if there is an already existing PluginInstallTask in the queue
- for a given slug and activation criteria. */
+ Check if there is an already existing PluginInstallTask in the queue
+ for a given slug and activation criteria.
+ */
if ( $queued_plugin['slug'] === $plugin_install_task->get_slug()
- && $queued_plugin['activate'] === $plugin_install_task->get_activate() ) {
- return false;
+ && $queued_plugin['activate'] === $plugin_install_task->get_activate() ) {
+ return false;
}
- $queue->insert( $queued_plugin, $queued_plugin['priority'] );
+ $queue->insert( $queued_plugin, $queued_plugin['priority'] );
}
// Insert a new PluginInstallTask at the appropriate position in the queue.
@@ -171,29 +198,53 @@ public static function add_to_queue( PluginInstallTask $plugin_install_task ) {
$plugin_install_task->get_priority()
);
- return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() );
+ return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() );
}
+ /**
+ * Removes a PluginInstallTask from the queue.
+ *
+ * @param string $plugin The slug of the task to remove.
+ * @return array
+ */
public static function remove_from_queue( $plugin ) {
/*
- Get the plugins queued up to be installed, the PluginInstall task gets
- converted to an associative array before storing it in the option. */
+ Get the plugins queued up to be installed, the PluginInstall task gets
+ converted to an associative array before storing it in the option.
+ */
$plugins = \get_option( Options::get_option_name( self::$queue_name ), array() );
$queue = new PriorityQueue();
foreach ( $plugins as $queued_plugin ) {
/*
- If the Plugin slug does not match add it back to the queue. */
+ If the Plugin slug does not match add it back to the queue.
+ */
if ( $queued_plugin['slug'] !== $plugin ) {
- $queue->insert( $queued_plugin, $queued_plugin['priority'] );
+ $queue->insert( $queued_plugin, $queued_plugin['priority'] );
}
}
- return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() );
+ return \update_option( Options::get_option_name( self::$queue_name ), $queue->to_array() );
}
+ /**
+ * Get the status of a given plugin slug from the queue.
+ *
+ * @param string $plugin The slug of the plugin.
+ * @return boolean
+ */
public static function status( $plugin ) {
$plugins = \get_option( Options::get_option_name( self::$queue_name ), array() );
- return array_search( $plugin, array_column( $plugins, 'slug' ) );
+ return array_search( $plugin, array_column( $plugins, 'slug' ), true );
+ }
+
+ /**
+ * Reset the Plugin install status and the queue.
+ *
+ * @return void
+ */
+ public static function reset_install_status() {
+ \delete_option( Options::get_option_name( 'plugins_init_status' ) );
+ \delete_option( Options::get_option_name( 'plugin_install_queue' ) );
}
}
diff --git a/src/OnboardingSPA/components/Content/index.js b/src/OnboardingSPA/components/Content/index.js
index f111868d9..46a050b79 100644
--- a/src/OnboardingSPA/components/Content/index.js
+++ b/src/OnboardingSPA/components/Content/index.js
@@ -3,6 +3,7 @@ import { Fragment, memo, Suspense, useCallback } from '@wordpress/element';
import { store as nfdOnboardingStore } from '../../store';
import { useSelect } from '@wordpress/data';
+import FlowStateHandler from '../StateHandlers/Flow';
/**
* Primary content area within the .
@@ -17,24 +18,23 @@ const Content = () => {
};
} );
- const getMappedPages = useCallback(
- ( routes ) => {
- return routes?.map( ( route ) => (
- }
- />
- ) );
- },
- [ routes ]
- );
+ const getMappedPages = useCallback( () => {
+ return routes?.map( ( route ) => (
+ }
+ />
+ ) );
+ }, [ routes ] );
return (
}>
- { getMappedPages( routes ) }
+
+ { getMappedPages( routes ) }
+
);
diff --git a/src/OnboardingSPA/components/Loaders/Step/Ecommerce/contents.js b/src/OnboardingSPA/components/Loaders/Step/Ecommerce/contents.js
new file mode 100644
index 000000000..a9feb7449
--- /dev/null
+++ b/src/OnboardingSPA/components/Loaders/Step/Ecommerce/contents.js
@@ -0,0 +1,22 @@
+import { __, sprintf } from '@wordpress/i18n';
+import { translations } from '../../../../utils/locales/translations';
+
+const getContents = ( brandName ) => {
+ return {
+ title: sprintf(
+ /* translators: 1: Brand 2: Site */
+ __(
+ 'Making the keys to your %1$s Online %2$s',
+ 'wp-module-onboarding'
+ ),
+ brandName,
+ translations( 'Site' )
+ ),
+ subtitle: __(
+ 'We’re installing WooCommerce for you to fill with your amazing products & services!',
+ 'wp-module-onboarding'
+ ),
+ };
+};
+
+export default getContents;
diff --git a/src/OnboardingSPA/components/Loaders/Step/Ecommerce/index.js b/src/OnboardingSPA/components/Loaders/Step/Ecommerce/index.js
new file mode 100644
index 000000000..71a7dd320
--- /dev/null
+++ b/src/OnboardingSPA/components/Loaders/Step/Ecommerce/index.js
@@ -0,0 +1,19 @@
+import StepLoader from '..';
+import getContents from './contents';
+import { useSelect } from '@wordpress/data';
+
+import { store as nfdOnboardingStore } from '../../../../store';
+
+const EcommerceStepLoader = () => {
+ const { brandName } = useSelect( ( select ) => {
+ return {
+ brandName: select( nfdOnboardingStore ).getNewfoldBrandName(),
+ };
+ }, [] );
+ const contents = getContents( brandName );
+ return (
+
+ );
+};
+
+export default EcommerceStepLoader;
diff --git a/src/OnboardingSPA/components/Sidebar/components/LearnMore/Menu.js b/src/OnboardingSPA/components/Sidebar/components/LearnMore/Menu.js
index f95b9b86f..355a41cc1 100644
--- a/src/OnboardingSPA/components/Sidebar/components/LearnMore/Menu.js
+++ b/src/OnboardingSPA/components/Sidebar/components/LearnMore/Menu.js
@@ -33,7 +33,7 @@ const LearnMoreMenu = () => {
return (
<>
- { currentStep?.sidebars?.LearnMore && (
+ { sideBarView && currentStep?.sidebars?.LearnMore && (
diff --git a/src/OnboardingSPA/components/SkipButton/index.js b/src/OnboardingSPA/components/SkipButton/index.js
index 96a475971..d47cb3636 100644
--- a/src/OnboardingSPA/components/SkipButton/index.js
+++ b/src/OnboardingSPA/components/SkipButton/index.js
@@ -9,12 +9,7 @@ import { store as nfdOnboardingStore } from '../../store';
import { getSettings, setSettings } from '../../utils/api/settings';
import { wpAdminPage, pluginDashboardPage } from '../../../constants';
-/**
- * Interface Text Inputs with standard design.
- *
- * @return {WPComponent} SkipButton Component
- */
-const SkipButton = () => {
+const SkipButton = ( { callback = false } ) => {
const navigate = useNavigate();
const location = useLocation();
const { nextStep, currentData, socialData } = useSelect( ( select ) => {
@@ -75,7 +70,12 @@ const SkipButton = () => {
return (
diff --git a/src/OnboardingSPA/components/StateHandlers/Ecommerce/contents.js b/src/OnboardingSPA/components/StateHandlers/Ecommerce/contents.js
index 6090ca529..e9d1b5707 100644
--- a/src/OnboardingSPA/components/StateHandlers/Ecommerce/contents.js
+++ b/src/OnboardingSPA/components/StateHandlers/Ecommerce/contents.js
@@ -3,26 +3,11 @@ import { translations } from '../../../utils/locales/translations';
const getContents = ( brandName ) => {
return {
- loader: {
- title: sprintf(
- /* translators: 1: Brand 2: Site */
- __(
- 'Making the keys to your %s Online %s',
- 'wp-module-onboarding'
- ),
- brandName,
- translations( 'Site' )
- ),
- subtitle: __(
- 'We’re installing WooCommerce for you to fill with your amazing products & services!',
- 'wp-module-onboarding'
- ),
- },
errorState: {
title: sprintf(
/* translators: 1: Brand 2: Site */
__(
- 'Making the keys to your %s Online %s',
+ 'Making the keys to your %1$s Online %2$s',
'wp-module-onboarding'
),
brandName,
diff --git a/src/OnboardingSPA/components/StateHandlers/Ecommerce/index.js b/src/OnboardingSPA/components/StateHandlers/Ecommerce/index.js
index bf3d7af1a..af582f672 100644
--- a/src/OnboardingSPA/components/StateHandlers/Ecommerce/index.js
+++ b/src/OnboardingSPA/components/StateHandlers/Ecommerce/index.js
@@ -2,7 +2,6 @@ import { useViewportMatch } from '@wordpress/compose';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
-import { StepLoader } from '../../Loaders';
import { store as nfdOnboardingStore } from '../../../store';
import { getPluginStatus } from '../../../utils/api/plugins';
import {
@@ -15,6 +14,7 @@ import {
} from '../../../../constants';
import { StepErrorState } from '../../ErrorState';
import getContents from './contents';
+import EcommerceStepLoader from '../../Loaders/Step/Ecommerce';
const EcommerceStateHandler = ( {
children,
@@ -110,8 +110,7 @@ const EcommerceStateHandler = ( {
window.location.reload();
break;
default:
- pluginsStatus[ ECOMMERCE_STEPS_PLUGIN ] =
- pluginStatus;
+ pluginsStatus[ ECOMMERCE_STEPS_PLUGIN ] = pluginStatus;
setWoocommerceStatus( pluginStatus );
updatePluginsStatus( pluginsStatus );
}
@@ -139,12 +138,7 @@ const EcommerceStateHandler = ( {
case PLUGIN_STATUS_ACTIVE:
return children;
default:
- return (
-
- );
+ return ;
}
};
diff --git a/src/OnboardingSPA/components/StateHandlers/Flow/index.js b/src/OnboardingSPA/components/StateHandlers/Flow/index.js
new file mode 100644
index 000000000..d562e3845
--- /dev/null
+++ b/src/OnboardingSPA/components/StateHandlers/Flow/index.js
@@ -0,0 +1,93 @@
+import { useEffect, useState } from '@wordpress/element';
+import { useLocation } from 'react-router-dom';
+import { useSelect, useDispatch } from '@wordpress/data';
+
+import { store as nfdOnboardingStore } from '../../../store';
+import { getFirstEcommerceStep } from '../../../data/routes/ecommerce-flow';
+import EcommerceStepLoader from '../../Loaders/Step/Ecommerce';
+import { switchFlow } from '../../../utils/api/flow';
+import { removeQueryParam } from '../../../utils';
+import { MAX_RETRIES_FLOW_SWITCH } from '../../../../constants';
+import { getFragment } from '@wordpress/url';
+
+const FlowStateHandler = ( { children } ) => {
+ const location = useLocation();
+ const [ newFlow, setNewFlow ] = useState( false );
+
+ const { brandConfig } = useSelect( ( select ) => {
+ return {
+ brandName: select( nfdOnboardingStore ).getNewfoldBrandName(),
+ brandConfig: select( nfdOnboardingStore ).getNewfoldBrandConfig(),
+ };
+ }, [] );
+
+ const {
+ setIsDrawerOpened,
+ setIsDrawerSuppressed,
+ setIsHeaderNavigationEnabled,
+ setSidebarActiveView,
+ } = useDispatch( nfdOnboardingStore );
+
+ const disableNavigation = () => {
+ setIsDrawerOpened( false );
+ setIsDrawerSuppressed( true );
+ setIsHeaderNavigationEnabled( false );
+ setSidebarActiveView( false );
+ };
+
+ const handleCommerceFlow = async ( flow, retries = 0 ) => {
+ if ( retries >= MAX_RETRIES_FLOW_SWITCH ) {
+ return setNewFlow( false );
+ }
+ const response = await switchFlow( flow );
+ if ( response?.error ) {
+ retries = retries + 1;
+ return handleCommerceFlow( flow, retries );
+ }
+ const firstEcommerceStep = getFirstEcommerceStep();
+ const fragment = getFragment( window.location.href );
+ const redirect = removeQueryParam(
+ window.location.href,
+ 'flow'
+ ).replace( fragment, '' );
+ window.location.replace( `${ redirect }#${ firstEcommerceStep.path }` );
+ window.location.reload();
+ };
+
+ const switchToNewFlow = async ( flow ) => {
+ const enabledFlows = brandConfig?.enabled_flows ?? {};
+ if ( ! ( flow in enabledFlows ) || enabledFlows[ flow ] !== true ) {
+ return setNewFlow( false );
+ }
+
+ switch ( flow ) {
+ case 'ecommerce':
+ handleCommerceFlow( flow );
+ break;
+ default:
+ setNewFlow( false );
+ }
+ };
+
+ useEffect( () => {
+ if ( window.nfdOnboarding?.newFlow ) {
+ const flow = window.nfdOnboarding.newFlow;
+ disableNavigation();
+ setNewFlow( flow );
+ switchToNewFlow( flow );
+ window.nfdOnboarding.newFlow = undefined;
+ }
+ }, [ location.pathname ] );
+
+ const handleRender = () => {
+ switch ( newFlow ) {
+ case 'ecommerce':
+ return ;
+ default:
+ return children;
+ }
+ };
+ return <>{ handleRender() }>;
+};
+
+export default FlowStateHandler;
diff --git a/src/OnboardingSPA/data/routes/ecommerce-flow.js b/src/OnboardingSPA/data/routes/ecommerce-flow.js
index 014c2cd85..1a23100a9 100644
--- a/src/OnboardingSPA/data/routes/ecommerce-flow.js
+++ b/src/OnboardingSPA/data/routes/ecommerce-flow.js
@@ -1,6 +1,7 @@
import { __ } from '@wordpress/i18n';
import { store, institution, shipping } from '@wordpress/icons';
import { lazy } from '@wordpress/element';
+// eslint-disable-next-line import/no-extraneous-dependencies
import { orderBy, filter } from 'lodash';
import {
@@ -37,11 +38,11 @@ export const ecommerceSteps = [
title: __( 'Street Address', 'wp-module-onboarding' ),
heading: __( 'Street Address', 'wp-module-onboarding' ),
subheading: __(
- 'In this step you confirm the business address of your store. Simply confirm the one you provided during your initial Bluehost account setup or provide a new one.',
+ 'In this step you confirm the business address of your store. Simply confirm the one you provided during your initial Bluehost account setup or provide a new one.',
'wp-module-onboarding'
),
description: __(
- 'In this step you confirm the business address of your store. Simply confirm the one you provided during your initial Bluehost account setup or provide a new one.',
+ 'In this step you confirm the business address of your store. Simply confirm the one you provided during your initial Bluehost account setup or provide a new one.',
'wp-module-onboarding'
),
Component: StepAddress,
@@ -156,3 +157,7 @@ export const ecommerceGetStartedSteps = () => {
( step ) => ! step.path.includes( '/step/get-started/site-primary' )
);
};
+
+export const getFirstEcommerceStep = () => {
+ return ecommerceSteps[ 0 ];
+};
diff --git a/src/OnboardingSPA/pages/Steps/TopPriority/index.js b/src/OnboardingSPA/pages/Steps/TopPriority/index.js
index 186f01b1b..ffeb3ce32 100644
--- a/src/OnboardingSPA/pages/Steps/TopPriority/index.js
+++ b/src/OnboardingSPA/pages/Steps/TopPriority/index.js
@@ -2,7 +2,7 @@ import { __ } from '@wordpress/i18n';
import { useViewportMatch } from '@wordpress/compose';
import { useEffect, useState } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
-import { SIDEBAR_LEARN_MORE, VIEW_NAV_PRIMARY } from '../../../../constants';
+import { VIEW_NAV_PRIMARY } from '../../../../constants';
import SkipButton from '../../../components/SkipButton';
import { store as nfdOnboardingStore } from '../../../store';
@@ -48,7 +48,7 @@ const StepTopPriority = () => {
if ( isLargeViewport ) {
setIsDrawerOpened( true );
}
- setSidebarActiveView( SIDEBAR_LEARN_MORE );
+ setSidebarActiveView( false );
setIsDrawerSuppressed( false );
setDrawerActiveView( VIEW_NAV_PRIMARY );
setIsHeaderNavigationEnabled( true );
@@ -58,8 +58,9 @@ const StepTopPriority = () => {
async function setInitialData() {
if ( currentData ) {
const val = await currentData?.data.topPriority.priority1;
- if ( val !== '' ) setSelected( parseInt( getKey( val ) ) );
- else {
+ if ( val !== '' ) {
+ setSelected( parseInt( getKey( val ) ) );
+ } else {
currentData.data.topPriority.priority1 =
priorityTypes[ selected ];
setCurrentOnboardingData( currentData );
@@ -67,16 +68,34 @@ const StepTopPriority = () => {
}
setisLoaded( true );
}
- if ( ! isLoaded ) setInitialData();
+ if ( ! isLoaded ) {
+ setInitialData();
+ }
}, [ isLoaded ] );
+ const handleSelling = () => {
+ if ( 'ecommerce' !== window.nfdOnboarding.currentFlow ) {
+ window.nfdOnboarding.newFlow = 'ecommerce';
+ }
+ };
+
useEffect( () => {
- if ( isLoaded ) {
- currentData.data.topPriority.priority1 = priorityTypes[ selected ];
- setCurrentOnboardingData( currentData );
+ const selectedPriorityType = priorityTypes[ selected ];
+ currentData.data.topPriority.priority1 = selectedPriorityType;
+ setCurrentOnboardingData( currentData );
+ if ( 'selling' === selectedPriorityType ) {
+ handleSelling();
+ } else {
+ window.nfdOnboarding.newFlow = undefined;
}
}, [ selected ] );
+ const handleSkip = () => {
+ window.nfdOnboarding.newFlow = undefined;
+ currentData.data.topPriority.priority1 = priorityTypes[ 0 ];
+ setCurrentOnboardingData( currentData );
+ };
+
const content = getContents();
return (
@@ -101,7 +120,7 @@ const StepTopPriority = () => {
'wp-module-onboarding'
) }
-
+
);
diff --git a/src/OnboardingSPA/utils/api/flow.js b/src/OnboardingSPA/utils/api/flow.js
index 3610d0b5c..cf0366213 100644
--- a/src/OnboardingSPA/utils/api/flow.js
+++ b/src/OnboardingSPA/utils/api/flow.js
@@ -37,3 +37,15 @@ export async function completeFlow() {
} ).then()
);
}
+
+export async function switchFlow( flow ) {
+ return await resolve(
+ apiFetch( {
+ url: onboardingRestURL( 'flow/switch' ),
+ method: 'POST',
+ data: {
+ flow,
+ },
+ } ).then()
+ );
+}
diff --git a/src/OnboardingSPA/utils/index.js b/src/OnboardingSPA/utils/index.js
index 6202713d3..5abb1f9f2 100644
--- a/src/OnboardingSPA/utils/index.js
+++ b/src/OnboardingSPA/utils/index.js
@@ -1,18 +1,13 @@
-import { findIndex } from 'lodash';
-
-export const insertBeforeStep = (steps, path, newStep) => {};
-
-export const insertAfterStep = (steps, path, newStep) => {};
-
-export const insertStepAtIndex = (steps, index, newStep) => {};
-
-export const findStepIndex = ( steps, path ) => {
- const index = findIndex( steps, { path } );
-
- return -1 !== index ? index : false;
-};
+import { removeQueryArgs, hasQueryArg } from '@wordpress/url';
export const getQueryParam = ( paramName ) => {
- const urlParams = new URLSearchParams( location.search );
+ const urlParams = new URLSearchParams( window.location.search );
return urlParams.get( paramName );
};
+
+export const removeQueryParam = ( url, paramName ) => {
+ if ( hasQueryArg( url, paramName ) ) {
+ return removeQueryArgs( url, paramName );
+ }
+ return url;
+};
diff --git a/src/constants.js b/src/constants.js
index 0d74c016b..eed2f4c2b 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -32,6 +32,7 @@ export const SIDEBAR_LEARN_MORE = 'LearnMore';
export const MAX_RETRIES_API_QUEUER = 2;
export const MAX_RETRIES_SETTINGS_INIT = 2;
+export const MAX_RETRIES_FLOW_SWITCH = 2;
export const NFD_PLUGINS_QUERY_PARAM = 'nfd_plugins';
export const NFD_THEMES_QUERY_PARAM = 'nfd_themes';