Use store-themed set password form for checkout signup (https://github.com/woocommerce/woocommerce-blocks/pull/3236)

* use my-account/lost-password endpoint url for set password (tbd):
- companion for working on https://github.com/woocommerce/woocommerce/issues/27754

* use more appropriate (new) set-password endpoint

* add version check - use new woo core endpoint if woo version is new enough

* use my-account/lost-password for setting password in checkout signup:
- this has been available forever - no need for a version check
- page will show `Lost password`; looking at options for overriding that

* use more explicit `newaccount` action for set password url if available

* tweak feature gating for checkout signup:
- only available in dev builds (will change soon)
- only available if Woo core 4.7 or newer
- checkout signup relies on fixes in 4.7+ (tbc) to
  my-account/lost-password endpoint for setting initial password
- standardise feature gate logic so is consistent, ensure feature is
  disabled in API/backend, hide editor option, and disable front end
- add new setting `wcVersion` to allow feature gating on woo version

* fix woo-version feature gate of checkout signup:
- fixed version logic, explicit 4.7.0 reference version
- refactor version compare routine so can be used for woo or WP version

* revamp Woo 4.7+ logic so PHPunit tests aren't dependent on Woo version:
- Woo-version feature gating is implemented at integration layer:
  - checkout REST API
  - register/override new account email handler
This commit is contained in:
Rua Haszard 2020-10-15 14:13:49 +13:00 committed by GitHub
parent 2aa507fef5
commit c7b4e3aa76
7 changed files with 65 additions and 23 deletions

View File

@ -22,9 +22,12 @@ import {
SidebarLayout,
Main,
} from '@woocommerce/base-components/sidebar-layout';
import { getSetting } from '@woocommerce/settings';
import withScrollToTop from '@woocommerce/base-hocs/with-scroll-to-top';
import { CHECKOUT_ALLOWS_GUEST } from '@woocommerce/block-settings';
import {
CHECKOUT_ALLOWS_GUEST,
isExperimentalBuild,
} from '@woocommerce/block-settings';
import { compareWithWooVersion, getSetting } from '@woocommerce/settings';
/**
* Internal dependencies
@ -81,6 +84,15 @@ const Checkout = ( { attributes, scrollToTop } ) => {
checkoutHasError &&
( hasValidationErrors || hasNoticesOfType( 'default' ) );
// Checkout signup is feature gated to WooCommerce 4.7 and newer;
// uses updated my-account/lost-password screen from 4.7+ for
// setting initial password.
// Also currently gated to dev builds only.
const allowCreateAccount =
attributes.allowCreateAccount &&
isExperimentalBuild() &&
compareWithWooVersion( '4.7.0', '<=' );
useEffect( () => {
if ( hasErrorsToDisplay ) {
showAllValidationErrors();
@ -96,7 +108,7 @@ const Checkout = ( { attributes, scrollToTop } ) => {
! isEditor &&
! customerId &&
! CHECKOUT_ALLOWS_GUEST &&
! attributes.allowCreateAccount
! allowCreateAccount
) {
return (
<>
@ -128,7 +140,7 @@ const Checkout = ( { attributes, scrollToTop } ) => {
showPhoneField={ attributes.showPhoneField }
requireCompanyField={ attributes.requireCompanyField }
requirePhoneField={ attributes.requirePhoneField }
allowCreateAccount={ attributes.allowCreateAccount }
allowCreateAccount={ allowCreateAccount }
/>
<div className="wc-block-checkout__actions">
{ attributes.showReturnToCart && (

View File

@ -19,7 +19,7 @@ import {
CHECKOUT_PAGE_ID,
isExperimentalBuild,
} from '@woocommerce/block-settings';
import { getAdminLink } from '@woocommerce/settings';
import { compareWithWooVersion, getAdminLink } from '@woocommerce/settings';
import { createInterpolateElement } from 'wordpress-element';
import { useRef } from '@wordpress/element';
import {
@ -55,6 +55,12 @@ const BlockSettings = ( { attributes, setAttributes } ) => {
} = attributes;
const { currentPostId } = useEditorContext();
const { current: savedCartPageId } = useRef( cartPageId );
// Checkout signup is feature gated to WooCommerce 4.7 and newer;
// uses updated my-account/lost-password screen from 4.7+ for
// setting initial password.
// Also currently gated to dev builds only.
const showCreateAccountOption =
isExperimentalBuild() && compareWithWooVersion( '4.7.0', '<=' );
return (
<InspectorControls>
{ currentPostId !== CHECKOUT_PAGE_ID && (
@ -156,7 +162,7 @@ const BlockSettings = ( { attributes, setAttributes } ) => {
/>
) }
</PanelBody>
{ isExperimentalBuild() && (
{ showCreateAccountOption && (
<PanelBody
title={ __(
'Account options',

View File

@ -23,10 +23,15 @@ export { setSetting } from './set-setting';
* to `rc`.
*
* @param {string} version Version to compare.
* @param {string} setting Setting name (e.g. wpVersion or wcVersion).
* @param {string} operator Comparison operator.
*/
export const compareWithWpVersion = ( version, operator ) => {
let replacement = getSetting( 'wpVersion', '' ).replace(
const compareVersionSettingIgnorePrerelease = (
version,
setting,
operator
) => {
let replacement = getSetting( setting, '' ).replace(
/-[a-zA-Z0-9]*[\-]*/,
'.0-rc.'
);
@ -36,6 +41,22 @@ export const compareWithWpVersion = ( version, operator ) => {
return compareVersions.compare( version, replacement, operator );
};
export const compareWithWpVersion = ( version, operator ) => {
return compareVersionSettingIgnorePrerelease(
version,
'wpVersion',
operator
);
};
export const compareWithWooVersion = ( version, operator ) => {
return compareVersionSettingIgnorePrerelease(
version,
'wcVersion',
operator
);
};
export { compareVersions, getSetting };
/**

View File

@ -72,6 +72,7 @@ class AssetDataRegistry {
$currency = get_woocommerce_currency();
return [
'wpVersion' => get_bloginfo( 'version' ),
'wcVersion' => defined( 'WC_VERSION' ) ? WC_VERSION : '',
'adminUrl' => admin_url(),
'countries' => WC()->countries->get_countries(),
'currency' => [

View File

@ -32,11 +32,10 @@ class CreateAccount {
* @return True if Checkout sign-up feature should be made available.
*/
private static function is_feature_enabled() {
// This new checkout signup flow is gated to dev builds for now.
// The main reason for this is that we are waiting on an new
// set-password endpoint/form in WooCommerce Core.
// When that's available we can review this and include in feature
// plugin alongside checkout block.
// Checkout signup is feature gated to WooCommerce 4.7 and newer;
// uses updated my-account/lost-password screen from 4.7+ for
// setting initial password.
// Also currently gated to dev builds only.
return Package::is_experimental_build();
}
@ -44,7 +43,7 @@ class CreateAccount {
* Init - register handlers for WooCommerce core email hooks.
*/
public function init() {
if ( ! self::is_feature_enabled() ) {
if ( ! self::is_feature_enabled() || defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '4.7', '<' ) ) {
return;
}

View File

@ -102,10 +102,8 @@ class CustomerNewAccount extends \WC_Email {
// Generate a magic link so user can set initial password.
$key = get_password_reset_key( $this->object );
if ( ! is_wp_error( $key ) ) {
$this->set_password_url = network_site_url(
"wp-login.php?action=rp&key=$key&login=" . rawurlencode( $this->object->user_login ),
'login'
);
$action = 'newaccount';
$this->set_password_url = wc_get_account_endpoint_url( 'lost-password' ) . "?action=$action&key=$key&login=" . rawurlencode( $this->object->user_login );
}
$this->user_login = stripslashes( $this->object->user_login );

View File

@ -167,11 +167,16 @@ class Checkout extends AbstractRoute {
// Create a new user account as necessary.
// Note - CreateAccount class includes feature gating logic (i.e. this
// may not create an account depending on build).
try {
$create_account = Package::container()->get( CreateAccount::class );
$create_account->from_order_request( $order_object, $request );
} catch ( Exception $error ) {
$this->handle_error( $error );
if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '4.7', '>=' ) ) {
// Checkout signup is feature gated to WooCommerce 4.7 and newer;
// Because it requires updated my-account/lost-password screen in 4.7+
// for setting initial password.
try {
$create_account = Package::container()->get( CreateAccount::class );
$create_account->from_order_request( $order_object, $request );
} catch ( Exception $error ) {
$this->handle_error( $error );
}
}
// Persist customer address data to account.