Move LYS coming soon initialization to core profiler flow (#46708)
Co-authored-by: Ilyas Foo <foo.ilyas@gmail.com>
This commit is contained in:
parent
007a4238c3
commit
fd52f18f6b
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Move LYS coming soon initialization to core profiler flow
|
|
@ -37,6 +37,9 @@ const TYPES = {
|
|||
KEEP_COMPLETED_TASKS_REQUEST: 'KEEP_COMPLETED_TASKS_REQUEST',
|
||||
KEEP_COMPLETED_TASKS_SUCCESS: 'KEEP_COMPLETED_TASKS_SUCCESS',
|
||||
SET_JETPACK_AUTH_URL: 'SET_JETPACK_AUTH_URL',
|
||||
CORE_PROFILER_COMPLETED_REQUEST: 'CORE_PROFILER_COMPLETED_REQUEST',
|
||||
CORE_PROFILER_COMPLETED_SUCCESS: 'CORE_PROFILER_COMPLETED_SUCCESS',
|
||||
CORE_PROFILER_COMPLETED_ERROR: 'CORE_PROFILER_COMPLETED_ERROR',
|
||||
} as const;
|
||||
|
||||
export default TYPES;
|
||||
|
|
|
@ -502,6 +502,41 @@ export function setJetpackAuthUrl(
|
|||
};
|
||||
}
|
||||
|
||||
export function coreProfilerCompletedError( error: unknown ) {
|
||||
return {
|
||||
type: TYPES.CORE_PROFILER_COMPLETED_ERROR,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
export function coreProfilerCompletedRequest() {
|
||||
return {
|
||||
type: TYPES.CORE_PROFILER_COMPLETED_REQUEST,
|
||||
};
|
||||
}
|
||||
|
||||
export function coreProfilerCompletedSuccess() {
|
||||
return {
|
||||
type: TYPES.CORE_PROFILER_COMPLETED_SUCCESS,
|
||||
};
|
||||
}
|
||||
|
||||
export function* coreProfilerCompleted() {
|
||||
yield coreProfilerCompletedRequest();
|
||||
|
||||
try {
|
||||
yield apiFetch( {
|
||||
path: `${ WC_ADMIN_NAMESPACE }/launch-your-store/initialize-coming-soon`,
|
||||
method: 'POST',
|
||||
} );
|
||||
} catch ( error ) {
|
||||
yield coreProfilerCompletedError( error );
|
||||
throw error;
|
||||
} finally {
|
||||
yield coreProfilerCompletedSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
export type Action = ReturnType<
|
||||
| typeof getFreeExtensionsError
|
||||
| typeof getFreeExtensionsSuccess
|
||||
|
@ -539,4 +574,7 @@ export type Action = ReturnType<
|
|||
| typeof getProductTypesError
|
||||
| typeof getProductTypesSuccess
|
||||
| typeof setJetpackAuthUrl
|
||||
| typeof coreProfilerCompletedRequest
|
||||
| typeof coreProfilerCompletedSuccess
|
||||
| typeof coreProfilerCompletedError
|
||||
>;
|
||||
|
|
|
@ -437,6 +437,34 @@ const reducer: Reducer< OnboardingState, Action > = (
|
|||
[ action.redirectUrl ]: action.results,
|
||||
},
|
||||
};
|
||||
case TYPES.CORE_PROFILER_COMPLETED_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
requesting: {
|
||||
...state.requesting,
|
||||
coreProfilerCompleted: true,
|
||||
},
|
||||
};
|
||||
case TYPES.CORE_PROFILER_COMPLETED_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
requesting: {
|
||||
...state.requesting,
|
||||
coreProfilerCompleted: false,
|
||||
},
|
||||
};
|
||||
case TYPES.CORE_PROFILER_COMPLETED_ERROR:
|
||||
return {
|
||||
...state,
|
||||
errors: {
|
||||
...state.errors,
|
||||
coreProfilerCompleted: action.error,
|
||||
},
|
||||
requesting: {
|
||||
...state.requesting,
|
||||
coreProfilerCompleted: false,
|
||||
},
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
AnyEventObject,
|
||||
BaseActionObject,
|
||||
Sender,
|
||||
raise,
|
||||
} from 'xstate';
|
||||
import { useMachine, useSelector } from '@xstate/react';
|
||||
import { useEffect, useMemo, useState } from '@wordpress/element';
|
||||
|
@ -371,7 +372,12 @@ const handleGeolocation = assign( {
|
|||
},
|
||||
} );
|
||||
|
||||
const redirectToWooHome = () => {
|
||||
const redirectToWooHome = raise( 'REDIRECT_TO_WOO_HOME' );
|
||||
|
||||
const exitToWooHome = async () => {
|
||||
if ( window.wcAdminFeatures[ 'launch-your-store' ] ) {
|
||||
await dispatch( ONBOARDING_STORE_NAME ).coreProfilerCompleted();
|
||||
}
|
||||
window.location.href = getNewPath( {}, '/', {} );
|
||||
};
|
||||
|
||||
|
@ -699,6 +705,7 @@ const coreProfilerMachineServices = {
|
|||
browserPopstateHandler,
|
||||
updateBusinessInfo,
|
||||
updateTrackingOption,
|
||||
exitToWooHome,
|
||||
};
|
||||
export const coreProfilerStateMachineDefinition = createMachine( {
|
||||
id: 'coreProfiler',
|
||||
|
@ -711,6 +718,9 @@ export const coreProfilerStateMachineDefinition = createMachine( {
|
|||
EXTERNAL_URL_UPDATE: {
|
||||
target: 'navigate',
|
||||
},
|
||||
REDIRECT_TO_WOO_HOME: {
|
||||
target: 'redirectingToWooHome',
|
||||
},
|
||||
},
|
||||
context: {
|
||||
// these are safe default values if for some reason the steps fail to complete correctly
|
||||
|
@ -1397,15 +1407,23 @@ export const coreProfilerStateMachineDefinition = createMachine( {
|
|||
},
|
||||
sendToJetpackAuthPage: {
|
||||
invoke: {
|
||||
src: async () =>
|
||||
await resolveSelect(
|
||||
src: async () => {
|
||||
if (
|
||||
window.wcAdminFeatures[ 'launch-your-store' ]
|
||||
) {
|
||||
await dispatch(
|
||||
ONBOARDING_STORE_NAME
|
||||
).coreProfilerCompleted();
|
||||
}
|
||||
return await resolveSelect(
|
||||
ONBOARDING_STORE_NAME
|
||||
).getJetpackAuthUrl( {
|
||||
redirectUrl: getAdminLink(
|
||||
'admin.php?page=wc-admin'
|
||||
),
|
||||
from: 'woocommerce-core-profiler',
|
||||
} ),
|
||||
} );
|
||||
},
|
||||
onDone: {
|
||||
actions: actions.choose( [
|
||||
{
|
||||
|
@ -1523,6 +1541,11 @@ export const coreProfilerStateMachineDefinition = createMachine( {
|
|||
},
|
||||
},
|
||||
settingUpStore: {},
|
||||
redirectingToWooHome: {
|
||||
invoke: {
|
||||
src: 'exitToWooHome',
|
||||
},
|
||||
},
|
||||
},
|
||||
} );
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ describe( 'All states in CoreProfilerMachine should be reachable', () => {
|
|||
test( `${ path.description }`, async () => {
|
||||
const rendered = render(
|
||||
<CoreProfilerController
|
||||
// @ts-expect-error -- types are wrong
|
||||
actionOverrides={ actionOverrides }
|
||||
servicesOverrides={ servicesOverrides }
|
||||
/>
|
||||
|
|
|
@ -58,6 +58,7 @@ declare global {
|
|||
'woo-mobile-welcome': boolean;
|
||||
'shipping-smart-defaults': boolean;
|
||||
'shipping-setting-tour': boolean;
|
||||
'launch-your-store': boolean;
|
||||
};
|
||||
wp: {
|
||||
updates?: {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Move LYS coming soon initialization to core profiler flow
|
|
@ -256,8 +256,6 @@ final class WooCommerce {
|
|||
add_action( 'woocommerce_updated', array( $this, 'add_woocommerce_inbox_variant' ) );
|
||||
add_action( 'woocommerce_installed', array( $this, 'add_woocommerce_remote_variant' ) );
|
||||
add_action( 'woocommerce_updated', array( $this, 'add_woocommerce_remote_variant' ) );
|
||||
add_action( 'woocommerce_newly_installed', array( $this, 'add_lys_default_values' ) );
|
||||
add_action( 'woocommerce_updated', array( $this, 'add_lys_default_values' ) );
|
||||
|
||||
// These classes set up hooks on instantiation.
|
||||
$container = wc_get_container();
|
||||
|
@ -315,35 +313,6 @@ final class WooCommerce {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default option values for launch your store task.
|
||||
*/
|
||||
public function add_lys_default_values() {
|
||||
if ( ! Features::is_enabled( 'launch-your-store' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$is_new_install = current_action() === 'woocommerce_newly_installed';
|
||||
|
||||
$coming_soon = $is_new_install ? 'yes' : 'no';
|
||||
$store_pages_only = WCAdminHelper::is_site_fresh() ? 'no' : 'yes';
|
||||
$private_link = 'no';
|
||||
$share_key = wp_generate_password( 32, false );
|
||||
|
||||
if ( false === get_option( 'woocommerce_coming_soon', false ) ) {
|
||||
update_option( 'woocommerce_coming_soon', $coming_soon );
|
||||
}
|
||||
if ( false === get_option( 'woocommerce_store_pages_only', false ) ) {
|
||||
update_option( 'woocommerce_store_pages_only', $store_pages_only );
|
||||
}
|
||||
if ( false === get_option( 'woocommerce_private_link', false ) ) {
|
||||
update_option( 'woocommerce_private_link', $private_link );
|
||||
}
|
||||
if ( false === get_option( 'woocommerce_share_key', false ) ) {
|
||||
update_option( 'woocommerce_share_key', $share_key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures fatal errors are logged so they can be picked up in the status report.
|
||||
*
|
||||
|
|
|
@ -104,6 +104,10 @@ class Init {
|
|||
$product_form_controllers[] = 'Automattic\WooCommerce\Admin\API\ProductForm';
|
||||
}
|
||||
|
||||
if ( Features::is_enabled( 'launch-your-store' ) ) {
|
||||
$controllers[] = 'Automattic\WooCommerce\Admin\API\LaunchYourStore';
|
||||
}
|
||||
|
||||
if ( Features::is_enabled( 'analytics' ) ) {
|
||||
$analytics_controllers = array(
|
||||
'Automattic\WooCommerce\Admin\API\Customers',
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
/**
|
||||
* REST API Launch Your Store Controller
|
||||
*
|
||||
* Handles requests to /launch-your-store/*
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\API;
|
||||
|
||||
use Automattic\WooCommerce\Admin\WCAdminHelper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Launch Your Store controller.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LaunchYourStore {
|
||||
|
||||
/**
|
||||
* Endpoint namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'wc-admin';
|
||||
|
||||
/**
|
||||
* Route base.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rest_base = 'launch-your-store';
|
||||
|
||||
/**
|
||||
* Register routes.
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . '/initialize-coming-soon',
|
||||
array(
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'callback' => array( $this, 'initialize_coming_soon' ),
|
||||
'permission_callback' => array( $this, 'must_be_shop_manager_or_admin' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* User must be either shop_manager or administrator.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function must_be_shop_manager_or_admin() {
|
||||
// phpcs:ignore
|
||||
if ( ! current_user_can( 'manage_woocommerce' ) && ! current_user_can( 'administrator' ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes options for coming soon. Does not override if options exist.
|
||||
*
|
||||
* @return bool|void
|
||||
*/
|
||||
public function initialize_coming_soon() {
|
||||
$current_user_id = get_current_user_id();
|
||||
// Abort if we don't have a user id for some reason.
|
||||
if ( ! $current_user_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$coming_soon = 'yes';
|
||||
$store_pages_only = WCAdminHelper::is_site_fresh() ? 'no' : 'yes';
|
||||
$private_link = 'no';
|
||||
$share_key = wp_generate_password( 32, false );
|
||||
|
||||
add_option( 'woocommerce_coming_soon', $coming_soon );
|
||||
add_option( 'woocommerce_store_pages_only', $store_pages_only );
|
||||
add_option( 'woocommerce_private_link', $private_link );
|
||||
add_option( 'woocommerce_share_key', $share_key );
|
||||
|
||||
wc_admin_record_tracks_event(
|
||||
'launch_your_store_initialize_coming_soon',
|
||||
array(
|
||||
'coming_soon' => $coming_soon,
|
||||
'store_pages_only' => $store_pages_only,
|
||||
'private_link' => $private_link,
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -27,78 +27,4 @@ class WooCommerce_Test extends \WC_Unit_Test_Case {
|
|||
$this->assertTrue( $property->isPublic() );
|
||||
$this->assertInstanceOf( WC_API::class, $property->getValue( WC() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down.
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
parent::tearDown();
|
||||
|
||||
delete_option( 'woocommerce_coming_soon' );
|
||||
delete_option( 'woocommerce_store_pages_only' );
|
||||
delete_option( 'woocommerce_private_link' );
|
||||
delete_option( 'woocommerce_share_key' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for add_lys_default_values method on fresh installation.
|
||||
*/
|
||||
public function test_add_lys_default_values_on_fresh_installation() {
|
||||
update_option( 'fresh_site', '1' );
|
||||
|
||||
$this->set_current_action( 'woocommerce_newly_installed' );
|
||||
( WooCommerce::instance() )->add_lys_default_values();
|
||||
|
||||
$this->assertEquals( 'yes', get_option( 'woocommerce_coming_soon' ) );
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_store_pages_only' ) );
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_private_link' ) );
|
||||
$this->assertNotEmpty( get_option( 'woocommerce_share_key' ) );
|
||||
$this->assertMatchesRegularExpression( '/^[a-zA-Z0-9]{32}$/', get_option( 'woocommerce_share_key' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for add_lys_default_values method on WooCommerce update.
|
||||
*/
|
||||
public function test_add_lys_default_values_on_woocommerce_update() {
|
||||
update_option( 'fresh_site', '0' );
|
||||
|
||||
$this->set_current_action( 'woocommerce_updated' );
|
||||
( WooCommerce::instance() )->add_lys_default_values();
|
||||
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_coming_soon' ) );
|
||||
$this->assertEquals( 'yes', get_option( 'woocommerce_store_pages_only' ) );
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_private_link' ) );
|
||||
$this->assertNotEmpty( get_option( 'woocommerce_share_key' ) );
|
||||
$this->assertMatchesRegularExpression( '/^[a-zA-Z0-9]{32}$/', get_option( 'woocommerce_share_key' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for add_lys_default_values method when options are already set.
|
||||
*
|
||||
*/
|
||||
public function test_add_lys_default_values_when_options_are_already_set() {
|
||||
update_option( 'fresh_site', '0' );
|
||||
update_option( 'woocommerce_coming_soon', 'yes' );
|
||||
update_option( 'woocommerce_store_pages_only', 'no' );
|
||||
update_option( 'woocommerce_private_link', 'yes' );
|
||||
update_option( 'woocommerce_share_key', 'test' );
|
||||
|
||||
$this->set_current_action( 'woocommerce_updated' );
|
||||
( WooCommerce::instance() )->add_lys_default_values();
|
||||
|
||||
$this->assertEquals( 'yes', get_option( 'woocommerce_coming_soon' ) );
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_store_pages_only' ) );
|
||||
$this->assertEquals( 'yes', get_option( 'woocommerce_private_link' ) );
|
||||
$this->assertEquals( 'test', get_option( 'woocommerce_share_key' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the current action for testing.
|
||||
*
|
||||
* @param string $action The action to set.
|
||||
*/
|
||||
private function set_current_action( $action ) {
|
||||
global $wp_current_filter;
|
||||
$wp_current_filter[] = $action; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue