Merge branch 'trunk' into fix/32837-48761-48775-48954-inconsistent-behavior-of-net-sales-in-analytics

This commit is contained in:
Ian Yu-Hsun Lin 2024-09-12 21:25:07 +08:00
commit d5a9f55e5d
65 changed files with 894 additions and 148 deletions

View File

@ -874,7 +874,7 @@
"menu_title": "Development environment setup",
"tags": "tutorial, setup",
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/getting-started/development-environment.md",
"hash": "b9f56987247aee67eaa2c74d1059e1cadfd335fa81c77b76c0717648d5631c0f",
"hash": "9e471d3f44a882fe61dcad9e5207d51b280a7220aae1bf6e4ae1fbdd68b7e3d4",
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/getting-started/development-environment.md",
"id": "9080572a3904349c44c565ca7e1bef1212c58757"
},
@ -1804,5 +1804,5 @@
"categories": []
}
],
"hash": "8199f0d3c854474839300ed606f03f9f286ace35f65d7c47ffc6477762eaf51e"
"hash": "ffae56d5a4993b151a54ec2117be1acf6a02c9fcab5b5662a2a583ea0e743f1d"
}

View File

@ -14,7 +14,7 @@ If you would like to contribute to the WooCommerce core platform; please read ou
## Prerequisites
WooCommerce does adhere to WordPress code standards and guidelines, so its best to familiarize yourself with [WordPress Development](https://learn.wordpress.org/tutorial/introduction-to-wordpress/) as well as [PHP](https://www.php.net/).
WooCommerce does adhere to WordPress code standards and guidelines, so it's best to familiarize yourself with [WordPress Development](https://learn.wordpress.org/tutorial/introduction-to-wordpress/) as well as [PHP](https://www.php.net/).
Knowledge and understanding of [WooCommerce Hooks and Filters](https://woocommerce.com/document/introduction-to-hooks-actions-and-filters/) will allow you to add and change code without editing core files. You can learn more about WordPress hooks and filters in the [WordPress Plugin Development Handbook](https://developer.wordpress.org/plugins/hooks/).

View File

@ -2,7 +2,8 @@
.woocommerce-marketplace__footer {
background: $gray-0;
border-top: 1px solid $gray-200;
border-radius: 4px;
max-width: 1600px;
margin: auto;
padding: $content-spacing-xlarge $content-spacing-small;
@ -34,16 +35,6 @@
gap: $large-gap;
}
.woocommerce-marketplace__footer-logo {
color: $wp-gray-50;
display: flex;
font-size: 14px;
font-weight: 600;
line-height: 20px;
gap: $small-gap;
margin: 48px 0 0;
}
@media screen and (min-width: $breakpoint-medium) {
.woocommerce-marketplace__footer {
padding: $content-spacing-xlarge $content-spacing-large;

View File

@ -2,7 +2,7 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { check, commentContent, shield } from '@wordpress/icons';
import { check, commentContent, shield, people } from '@wordpress/icons';
import { createInterpolateElement } from '@wordpress/element';
/**
@ -10,7 +10,6 @@ import { createInterpolateElement } from '@wordpress/element';
*/
import './footer.scss';
import IconWithText from '../icon-with-text/icon-with-text';
import WooIcon from '../../assets/images/woo-icon.svg';
import { MARKETPLACE_HOST } from '../constants';
const refundPolicyTitle = createInterpolateElement(
@ -71,10 +70,14 @@ function FooterContent(): JSX.Element {
'woocommerce'
) }
/>
</div>
<div className="woocommerce-marketplace__footer-logo">
<img src={ WooIcon } alt="Woo Logo" aria-hidden="true" />
<span>{ __( 'Woo Marketplace', 'woocommerce' ) }</span>
<IconWithText
icon={ people }
title={ __( 'Support the ecosystem', 'woocommerce' ) }
description={ __(
'Our team and partners are continuously improving your extensions, themes, and WooCommerce experience.',
'woocommerce'
) }
/>
</div>
</div>
);

View File

@ -11,7 +11,7 @@ import './icon-with-text.scss';
export interface IconWithTextProps {
icon: JSX.Element;
title: ReactElement;
title: ReactElement | string;
description: string;
}

View File

@ -4,6 +4,7 @@
&__product-card {
padding: $large-gap;
border-radius: $grid-unit-05 !important;
margin-bottom: 0;
/* When product card is loading, contents will be empty and we render skeleton loader wireframes: */
&.is-loading {
@ -243,7 +244,7 @@
}
&.woocommerce-marketplace__product-card--theme {
padding: 0 0 $medium-gap;
padding: 0 0 $large-gap;
overflow: hidden;
.woocommerce-marketplace__product-card__content {
@ -265,10 +266,10 @@
right: 0;
}
.woocommerce-marketplace__product-card__header {
padding-left: $medium-gap;
padding: 0 $large-gap;
}
.woocommerce-marketplace__product-card__footer {
padding: 0 $medium-gap;
padding: 0 $large-gap;
}
.woocommerce-marketplace__product-card__price {
margin-right: $medium-gap;
@ -313,7 +314,7 @@
display: flex;
flex-direction: column;
gap: $small-gap;
padding: 16px 24px;
padding: $large-gap;
height: 100%;
}

View File

@ -32,6 +32,12 @@
}
}
&:disabled {
.wc-block-components-button__text {
opacity: 0.5;
}
}
&.outlined {
background: transparent;
color: currentColor;

View File

@ -18,4 +18,5 @@ export { default as ShippingRatesControlPackage } from './shipping-rates-control
export { default as PaymentMethodIcons } from './payment-method-icons';
export { default as PaymentMethodLabel } from './payment-method-label';
export { default as AdditionalFieldsPlaceholder } from './additional-fields-placeholder';
export { default as PasswordStrengthMeter } from './password-strength-meter';
export * from './totals';

View File

@ -60,7 +60,7 @@
}
.wc-block-components-password-strength__meter[value="2"],
.wc-block-components-password-strength__meter[value="2"] + .wc-block-components-password-strength__result {
color: #ff6f00;
color: $alert-red;
}
.wc-block-components-password-strength__meter[value="3"],
.wc-block-components-password-strength__meter[value="3"] + .wc-block-components-password-strength__result {

View File

@ -6,11 +6,7 @@ import { useState } from '@wordpress/element';
import { ValidatedTextInput } from '@woocommerce/blocks-components';
import { useDispatch, useSelect } from '@wordpress/data';
import { CHECKOUT_STORE_KEY } from '@woocommerce/block-data';
/**
* Internal dependencies
*/
import PasswordStrengthMeter from '../../password-strength-meter';
import PasswordStrengthMeter from '@woocommerce/base-components/cart-checkout/password-strength-meter';
const CreatePassword = () => {
const [ passwordStrength, setPasswordStrength ] = useState( 0 );

View File

@ -0,0 +1,56 @@
{
"name": "woocommerce/order-confirmation-create-account",
"version": "1.0.0",
"title": "Account Creation",
"description": "Allow customers to create an account after their purchase. Configure this feature in your store settings.",
"category": "woocommerce",
"keywords": [
"WooCommerce"
],
"attributes": {
"customerEmail": {
"type": "string",
"default": ""
},
"nonceToken": {
"type": "string",
"default": ""
},
"align": {
"type": "string",
"default": "wide"
},
"className": {
"type": "string",
"default": ""
},
"hasDarkControls": {
"type": "boolean",
"default": false
}
},
"supports": {
"color": {
"background": true,
"text": true,
"button": true
},
"multiple": false,
"align": [
"wide",
"full"
],
"html": false,
"spacing": {
"padding": true,
"margin": true,
"__experimentalDefaultControls": {
"margin": false,
"padding": false
}
}
},
"textdomain": "woocommerce",
"apiVersion": 3,
"$schema": "https://schemas.wp.org/trunk/block.json"
}

View File

@ -0,0 +1,125 @@
/**
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import clsx from 'clsx';
import type { TemplateArray, BlockAttributes } from '@wordpress/blocks';
import { Disabled, PanelBody, ToggleControl } from '@wordpress/components';
import {
InnerBlocks,
useBlockProps,
InspectorControls,
} from '@wordpress/block-editor';
/**
* Internal dependencies
*/
import './style.scss';
import { SITE_TITLE } from '../../../settings/shared/default-constants';
import Form from './form';
const defaultTemplate = [
[
'core/heading',
{
level: 3,
content: sprintf(
/* translators: %s: site name */
__( 'Create an account with %s', 'woocommerce' ),
SITE_TITLE
),
},
],
[
'core/list',
{},
[
[
'core/list-item',
{
content: __( 'Faster future purchases', 'woocommerce' ),
},
],
[
'core/list-item',
{
content: __( 'Securely save payment info', 'woocommerce' ),
},
],
[
'core/list-item',
{
content: __(
'Track orders & view shopping history',
'woocommerce'
),
},
],
],
],
] as TemplateArray;
type EditProps = {
attributes: {
hasDarkControls: boolean;
};
setAttributes: ( attrs: BlockAttributes ) => void;
};
export const Edit = ( {
attributes,
setAttributes,
}: EditProps ): JSX.Element => {
const className = clsx( 'wc-block-order-confirmation-create-account', {
'has-dark-controls': attributes.hasDarkControls,
} );
const blockProps = useBlockProps( {
className,
} );
return (
<div { ...blockProps }>
<InnerBlocks
allowedBlocks={ [
'core/heading',
'core/paragraph',
'core/list',
'core/list-item',
'core/image',
] }
template={ defaultTemplate }
templateLock={ false }
/>
<Disabled>
<Form isEditor={ true } />
</Disabled>
<InspectorControls>
<PanelBody title={ __( 'Style', 'woocommerce' ) }>
<ToggleControl
label={ __( 'Dark mode inputs', 'woocommerce' ) }
help={ __(
'Inputs styled specifically for use on dark background colors.',
'woocommerce'
) }
checked={ attributes.hasDarkControls }
onChange={ () =>
setAttributes( {
hasDarkControls: ! attributes.hasDarkControls,
} )
}
/>
</PanelBody>
</InspectorControls>
</div>
);
};
export const Save = (): JSX.Element => {
return (
<div { ...useBlockProps.save() }>
<InnerBlocks.Content />
</div>
);
};
export default Edit;

View File

@ -0,0 +1,143 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState, createInterpolateElement } from '@wordpress/element';
import Button from '@woocommerce/base-components/button';
import PasswordStrengthMeter from '@woocommerce/base-components/cart-checkout/password-strength-meter';
import { PRIVACY_URL, TERMS_URL } from '@woocommerce/block-settings';
import { ValidatedTextInput } from '@woocommerce/blocks-components';
import { useSelect } from '@wordpress/data';
import { VALIDATION_STORE_KEY } from '@woocommerce/block-data';
const termsPageLink = TERMS_URL ? (
<a href={ TERMS_URL } target="_blank" rel="noreferrer">
{ __( 'Terms', 'woocommerce' ) }
</a>
) : (
<span>{ __( 'Terms', 'woocommerce' ) }</span>
);
const privacyPageLink = PRIVACY_URL ? (
<a href={ PRIVACY_URL } target="_blank" rel="noreferrer">
{ __( 'Privacy Policy', 'woocommerce' ) }
</a>
) : (
<span>{ __( 'Privacy Policy', 'woocommerce' ) }</span>
);
const Form = ( {
attributes: blockAttributes,
isEditor,
}: {
attributes?: { customerEmail?: string; nonceToken?: string };
isEditor: boolean;
} ) => {
const [ isLoading, setIsLoading ] = useState( false );
const [ password, setPassword ] = useState( '' );
const [ passwordStrength, setPasswordStrength ] = useState( 0 );
const hasValidationError = useSelect( ( select ) =>
select( VALIDATION_STORE_KEY ).getValidationError( 'account-password' )
);
const customerEmail =
blockAttributes?.customerEmail ||
( isEditor ? 'customer@email.com' : '' );
const nonceToken = blockAttributes?.nonceToken || '';
return (
<form
className={ 'wc-block-order-confirmation-create-account-form' }
id="create-account"
method="POST"
action="#create-account"
onSubmit={ ( event ) => {
if ( hasValidationError ) {
event.preventDefault();
return;
}
setIsLoading( true );
} }
>
<p>
{ createInterpolateElement(
__( 'Set a password for <email/>', 'woocommerce' ),
{
email: <strong>{ customerEmail }</strong>,
}
) }
</p>
<div>
<ValidatedTextInput
disabled={ isLoading }
type="password"
label={ __( 'Password', 'woocommerce' ) }
className={ `wc-block-components-address-form__password` }
value={ password }
required={ true }
errorId={ 'account-password' }
customValidityMessage={ (
validity: ValidityState
): string | undefined => {
if (
validity.valueMissing ||
validity.badInput ||
validity.typeMismatch
) {
return __(
'Please enter a valid password',
'woocommerce'
);
}
} }
customValidation={ ( inputObject ) => {
if ( passwordStrength < 2 ) {
inputObject.setCustomValidity(
__(
'Please create a stronger password',
'woocommerce'
)
);
return false;
}
return true;
} }
onChange={ ( value: string ) => setPassword( value ) }
feedback={
<PasswordStrengthMeter
password={ password }
onChange={ ( strength: number ) =>
setPasswordStrength( strength )
}
/>
}
/>
</div>
<Button
className={
'wc-block-order-confirmation-create-account-button'
}
type="submit"
disabled={ !! hasValidationError || ! password || isLoading }
showSpinner={ isLoading }
>
{ __( 'Create account', 'woocommerce' ) }
</Button>
<input type="hidden" name="email" value={ customerEmail } />
<input type="hidden" name="password" value={ password } />
<input type="hidden" name="create-account" value="1" />
<input type="hidden" name="_wpnonce" value={ nonceToken } />
<p className={ 'wc-block-order-confirmation-create-account-terms' }>
{ createInterpolateElement(
/* translators: %1$s terms page link, %2$s privacy page link. */
__(
'By creating an account you agree to our <terms/> and <privacy/>.',
'woocommerce'
),
{ terms: termsPageLink, privacy: privacyPageLink }
) }
</p>
</form>
);
};
export default Form;

View File

@ -0,0 +1,24 @@
/**
* External dependencies
*/
import { renderFrontend } from '@woocommerce/base-utils';
/**
* Internal dependencies
*/
import Block from './form';
import { parseAttributes } from './utils';
const getProps = ( el: HTMLElement ) => {
return {
attributes: parseAttributes( el.dataset ),
isEditor: false,
};
};
// This does not replace the entire block markup, just the form part.
renderFrontend( {
selector: '.woocommerce-order-confirmation-create-account-form',
Block,
getProps,
} );

View File

@ -0,0 +1,45 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { Icon, people } from '@wordpress/icons';
import { isExperimentalBlocksEnabled } from '@woocommerce/block-settings';
import { ExternalLink } from '@wordpress/components';
import { ADMIN_URL } from '@woocommerce/settings';
/**
* Internal dependencies
*/
import metadata from './block.json';
import { Save, Edit } from './edit';
if ( isExperimentalBlocksEnabled() ) {
registerBlockType( metadata, {
apiVersion: 3,
description: (
<>
{ metadata.description }
<br />
<ExternalLink
href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=account` }
>
{ __( 'Manage account settings', 'woocommerce' ) }
</ExternalLink>
</>
),
icon: {
src: (
<Icon
icon={ people }
className="wc-block-editor-components-block-icon"
/>
),
},
attributes: {
...metadata.attributes,
},
edit: Edit,
save: Save,
} );
}

View File

@ -0,0 +1,82 @@
.wc-block-order-confirmation-create-account {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: $gap;
padding: $gap-larger;
margin-top: $gap-larger !important;
margin-bottom: $gap-larger !important;
background: rgba(0, 0, 0, 0.04);
box-sizing: border-box;
> div {
flex: 1;
}
p {
margin-top: 0;
margin-bottom: 0;
}
.woocommerce-order-confirmation-create-account-content,
.block-editor-block-list__layout {
> :first-child {
margin-top: 0 !important;
}
> :last-child {
margin-bottom: 0 !important;
}
ul {
li {
margin-bottom: $gap;
}
}
* {
color: inherit;
}
}
form {
display: flex;
flex-direction: column;
gap: $gap;
p,
.wc-block-components-text-input {
margin-top: 0;
margin-bottom: 0;
}
.wc-block-components-button {
width: 100%;
padding: 1em;
}
.wc-block-order-confirmation-create-account-terms {
@include font-size(small);
text-align: center;
a,
span {
white-space: nowrap;
}
}
.wc-block-components-password-strength.hidden {
display: none;
}
}
.woocommerce-order-confirmation-create-account-success {
text-align: center;
padding: $gap-larger 0;
> :first-child {
margin-top: 0 !important;
}
> :last-child {
margin-bottom: 0 !important;
}
}
}

View File

@ -0,0 +1,6 @@
export const parseAttributes = ( data: Record< string, unknown > ) => {
return {
customerEmail: data?.customerEmail || '',
nonceToken: data?.nonceToken || '',
};
};

View File

@ -163,6 +163,10 @@ const blocks = {
'order-confirmation-additional-fields': {
customDir: 'order-confirmation/additional-fields',
},
'order-confirmation-create-account': {
customDir: 'order-confirmation/create-account',
isExperimental: true,
},
};
// Intentional separation of cart and checkout entry points to allow for better code splitting.

View File

@ -58,6 +58,10 @@ The majority of our feature flagging is blocks, this is a list of them:
- [PHP flag](https://github.com/woocommerce/woocommerce/blob/a0f9d159e5196983d93064762fd20a510de57d55/plugins/woocommerce/src/Blocks/BlockTypesController.php#L303)
- [Webpack flag](https://github.com/woocommerce/woocommerce/blob/a0f9d159e5196983d93064762fd20a510de57d55/plugins/woocommerce-blocks/bin/webpack-entries.js#L101)
- [JS flag](https://github.com/woocommerce/woocommerce/blob/a0f9d159e5196983d93064762fd20a510de57d55/plugins/woocommerce-blocks/assets/js/blocks/product-filter/inner-blocks/stock-filter/index.tsx#L15)
- Delayed Account Creation (Experimental)
- [PHP flag](https://github.com/woocommerce/woocommerce/blob/9897737880dcbef9831ee41799684dab1960d94f/plugins/woocommerce/src/Blocks/BlockTypesController.php#L417)
- [Webpack flag](https://github.com/woocommerce/woocommerce/blob/9897737880dcbef9831ee41799684dab1960d94f/plugins/woocommerce-blocks/bin/webpack-entries.js#L168)
- [JS flag](https://github.com/woocommerce/woocommerce/blob/9897737880dcbef9831ee41799684dab1960d94f/plugins/woocommerce-blocks/assets/js/blocks/order-confirmation/create-account/index.tsx#L14)
## Features behind flags

View File

@ -3,6 +3,7 @@
*/
import { useSelect } from '@wordpress/data';
import { VALIDATION_STORE_KEY } from '@woocommerce/block-data';
import { Icon, warning } from '@wordpress/icons';
/**
* Internal dependencies
@ -38,7 +39,10 @@ export const ValidationInputError = ( {
return (
<div className="wc-block-components-validation-error" role="alert">
<p id={ validationErrorId }>{ errorMessage }</p>
<p id={ validationErrorId }>
<Icon icon={ warning } />
<span>{ errorMessage }</span>
</p>
</div>
);
};

View File

@ -6,7 +6,17 @@
> p {
margin: 0;
padding: $gap-smallest 0 0 0;
padding: $gap-smaller 0 0 0;
display: flex;
align-items: center;
gap: 2px;
}
svg {
fill: currentColor;
width: 1.5em;
height: 1.5em;
margin-top: -1px;
}
}

View File

@ -482,6 +482,8 @@ test.describe( 'Shopper → Checkout Form Errors (guest user)', () => {
await frontendUtils.goToCheckout();
await page.getByLabel( 'Email address' ).clear();
// Notices on the email field will move content when the field loses focus. This can cause the click to "miss".
await page.getByRole( 'button', { name: 'Place order' } ).focus();
await page.getByRole( 'button', { name: 'Place order' } ).click();
// Verify that all required fields show the correct warning.

View File

@ -174,7 +174,9 @@ test.describe( 'Filters Overlay Template Part', () => {
await expect( productFiltersDialog ).toBeHidden();
} );
test( 'should hide Product Filters Overlay Navigation block when the Overlay mode is set to `Never`', async ( {
// Since we need to overhaul the overlay area, we can skip this test for now.
// eslint-disable-next-line playwright/no-skipped-test
test.skip( 'should hide Product Filters Overlay Navigation block when the Overlay mode is set to `Never`', async ( {
editor,
page,
frontendUtils,

View File

@ -0,0 +1,4 @@
Significance: patch
Type: tweak
Update product card content padding to 24px and add 0 margin bottom to product cards

View File

@ -0,0 +1,4 @@
Significance: patch
Type: tweak
Update footer design, add one more element to footer content and remove `woo-marketplace` copy at footer bottom.

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Added experimental delayed order creation block.

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Fix slow test for Reports

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix wc_admin_unsnooze_admin_notes events are being needlessly created

View File

@ -0,0 +1,5 @@
Significance: patch
Type: dev
Comment: It's a test skip for experimental feature, not worth explaining

View File

@ -534,7 +534,7 @@ class Note extends \WC_Data {
$this->error( 'admin_note_invalid_data', __( 'The admin note date prop cannot be empty.', 'woocommerce' ) );
}
if ( is_string( $date ) ) {
if ( is_string( $date ) && ! is_numeric( $date ) ) {
$date = wc_string_to_timestamp( $date );
}
$this->set_date_prop( 'date_created', $date );
@ -546,7 +546,7 @@ class Note extends \WC_Data {
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if there is no date.
*/
public function set_date_reminder( $date ) {
if ( is_string( $date ) ) {
if ( is_string( $date ) && ! is_numeric( $date ) ) {
$date = wc_string_to_timestamp( $date );
}
$this->set_date_prop( 'date_reminder', $date );

View File

@ -24,6 +24,7 @@ class Notes {
add_action( 'admin_init', array( __CLASS__, 'schedule_unsnooze_notes' ) );
add_action( 'admin_init', array( __CLASS__, 'possibly_delete_survey_notes' ) );
add_action( 'update_option_woocommerce_show_marketplace_suggestions', array( __CLASS__, 'possibly_delete_marketing_notes' ), 10, 2 );
add_action( self::UNSNOOZE_HOOK, array( __CLASS__, 'unsnooze_notes' ) );
}
/**
@ -406,7 +407,6 @@ class Notes {
wp_set_current_user( $user_id );
self::record_tracks_event_without_cookies( $event_name, $params );
wp_set_current_user( $current_user_id );
}
/**

View File

@ -186,7 +186,13 @@ abstract class AbstractOrderConfirmationBlock extends AbstractBlock {
*/
protected function is_email_verified( $order ) {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
if ( empty( $_POST ) || ! isset( $_POST['email'] ) || ! wp_verify_nonce( $_POST['check_submission'] ?? '', 'wc_verify_email' ) ) {
if ( empty( $_POST ) || ! isset( $_POST['email'], $_POST['_wpnonce'] ) ) {
return false;
}
$nonce_value = sanitize_key( wp_unslash( $_POST['_wpnonce'] ?? '' ) );
if ( ! wp_verify_nonce( $nonce_value, 'wc_verify_email' ) && ! wp_verify_nonce( $nonce_value, 'wc_create_account' ) ) {
return false;
}

View File

@ -0,0 +1,174 @@
<?php
declare( strict_types = 1 );
namespace Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation;
use Automattic\WooCommerce\StoreApi\Utilities\OrderController;
/**
* CreateAccount class.
*/
class CreateAccount extends AbstractOrderConfirmationBlock {
/**
* Block name.
*
* @var string
*/
protected $block_name = 'order-confirmation-create-account';
/**
* Get the frontend script handle for this block type.
*
* @see $this->register_block_type()
* @param string $key Data to get, or default to everything.
* @return array|string
*/
protected function get_block_type_script( $key = null ) {
$script = [
'handle' => 'wc-order-confirmation-create-account-block-frontend',
'path' => $this->asset_api->get_block_asset_build_path( 'order-confirmation-create-account-frontend' ),
'dependencies' => [],
];
return $key ? $script[ $key ] : $script;
}
/**
* Process posted account form.
*
* @param \WC_Order $order Order object.
* @return \WP_Error|int
*/
protected function process_form_post( $order ) {
if ( ! isset( $_POST['create-account'], $_POST['email'], $_POST['password'], $_POST['_wpnonce'] ) ) {
return 0;
}
if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'wc_create_account' ) ) {
return new \WP_Error( 'invalid_nonce', __( 'Unable to create account. Please try again.', 'woocommerce' ) );
}
$user_email = sanitize_email( wp_unslash( $_POST['email'] ) );
$password = wp_unslash( $_POST['password'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// Does order already have user?
if ( $order->get_customer_id() ) {
return new \WP_Error( 'order_already_has_user', __( 'This order is already linked to a user account.', 'woocommerce' ) );
}
// Check given details match the current viewed order.
if ( $order->get_billing_email() !== $user_email ) {
return new \WP_Error( 'email_mismatch', __( 'The email address provided does not match the email address on this order.', 'woocommerce' ) );
}
if ( empty( $password ) || strlen( $password ) < 8 ) {
return new \WP_Error( 'password_too_short', __( 'Password must be at least 8 characters.', 'woocommerce' ) );
}
$customer_id = wc_create_new_customer(
$user_email,
'',
$password,
[
'first_name' => $order->get_billing_first_name(),
'last_name' => $order->get_billing_last_name(),
'source' => 'delayed-account-creation',
]
);
if ( is_wp_error( $customer_id ) ) {
return $customer_id;
}
// Associate customer with the order.
$order->set_customer_id( $customer_id );
$order->save();
// Associate addresses from the order with the customer.
$order_controller = new OrderController();
$order_controller->sync_customer_data_with_order( $order );
// Set the customer auth cookie.
wc_set_customer_auth_cookie( $customer_id );
return $customer_id;
}
/**
* This renders the content of the block within the wrapper.
*
* @param \WC_Order $order Order object.
* @param string|false $permission If the current user can view the order details or not.
* @param array $attributes Block attributes.
* @param string $content Original block content.
* @return string
*/
protected function render_content( $order, $permission = false, $attributes = [], $content = '' ) {
if ( ! $permission ) {
return '';
}
// Check registration is possible for this order/customer, and if not, return early.
if ( is_user_logged_in() || email_exists( $order->get_billing_email() ) ) {
return '';
}
$result = $this->process_form_post( $order );
if ( is_wp_error( $result ) ) {
$notice = wc_print_notice( $result->get_error_message(), 'error', [], true );
} elseif ( $result ) {
return $this->render_confirmation();
}
$processor = new \WP_HTML_Tag_Processor(
$content .
'<div class="woocommerce-order-confirmation-create-account-form-wrapper">' .
$notice .
'<div class="woocommerce-order-confirmation-create-account-form"></div>' .
'</div>'
);
if ( ! $processor->next_tag( array( 'class_name' => 'wp-block-woocommerce-order-confirmation-create-account' ) ) ) {
return $content;
}
$processor->set_attribute( 'class', '' );
$processor->set_attribute( 'style', '' );
$processor->add_class( 'woocommerce-order-confirmation-create-account-content' );
if ( ! $processor->next_tag( array( 'class_name' => 'woocommerce-order-confirmation-create-account-form' ) ) ) {
return $content;
}
$processor->set_attribute( 'data-customer-email', $order->get_billing_email() );
$processor->set_attribute( 'data-nonce-token', wp_create_nonce( 'wc_create_account' ) );
if ( ! empty( $attributes['hasDarkControls'] ) ) {
$processor->add_class( 'has-dark-controls' );
}
return $processor->get_updated_html();
}
/**
* Render the block when an account has been registered.
*
* @return string
*/
protected function render_confirmation() {
$content = '<div class="woocommerce-order-confirmation-create-account-success" id="create-account">';
$content .= '<h3>' . esc_html__( 'Your account has been successfully created', 'woocommerce' ) . '</h3>';
$content .= '<p>' . sprintf(
/* translators: 1: link to my account page, 2: link to shipping and billing addresses, 3: link to account details, 4: closing tag */
esc_html__( 'You can now %1$sview your recent orders%4$s, manage your %2$sshipping and billing addresses%4$s, and edit your %3$spassword and account details%4$s.', 'woocommerce' ),
'<a href="' . esc_url( wc_get_endpoint_url( 'orders', '', wc_get_page_permalink( 'myaccount' ) ) ) . '">',
'<a href="' . esc_url( wc_get_endpoint_url( 'edit-address', '', wc_get_page_permalink( 'myaccount' ) ) ) . '">',
'<a href="' . esc_url( wc_get_endpoint_url( 'edit-account', '', wc_get_page_permalink( 'myaccount' ) ) ) . '">',
'</a>'
) . '</p>';
$content .= '</div>';
return $content;
}
}

View File

@ -265,7 +265,7 @@ class Status extends AbstractOrderConfirmationBlock {
</p>',
esc_attr( 'verify-email-submit' ),
esc_html__( 'Confirm email and view order', 'woocommerce' ),
wp_nonce_field( 'wc_verify_email', 'check_submission', true, false ),
wp_nonce_field( 'wc_verify_email', '_wpnonce', true, false ),
esc_attr( wc_wp_theme_get_element_class_name( 'button' ) )
) .
'</form>';

View File

@ -414,6 +414,7 @@ final class BlockTypesController {
$block_types[] = 'ProductFilterRating';
$block_types[] = 'ProductFilterActive';
$block_types[] = 'ProductFilterClearButton';
$block_types[] = 'OrderConfirmation\CreateAccount';
}
/**

View File

@ -241,7 +241,7 @@ class FeaturesController {
'Enable this feature to log errors and related data to Automattic servers for debugging purposes and to improve WooCommerce',
'woocommerce'
),
'enabled_by_default' => true,
'enabled_by_default' => false,
'disable_ui' => true,
'is_legacy' => false,
'is_experimental' => true,

View File

@ -13,36 +13,42 @@
class WC_Helper_Queue {
/**
* Get all pending queued actions.
*
* @param string|null $group Optionally. Filter the actions by group.
* @return array Pending jobs.
*/
public static function get_all_pending() {
$jobs = WC()->queue()->search(
array(
'per_page' => -1,
'status' => 'pending',
'claimed' => false,
)
public static function get_all_pending( $group = null ) {
$args = array(
'per_page' => -1,
'status' => 'pending',
'claimed' => false,
);
return $jobs;
if ( $group ) {
$args['group'] = $group;
}
return WC()->queue()->search( $args );
}
/**
* Run all pending queued actions.
*
* @param string|null $group Optionally. Filter the actions by group.
* @return void
*/
public static function run_all_pending() {
public static function run_all_pending( $group = null ) {
$queue_runner = new ActionScheduler_QueueRunner();
while ( $jobs = self::get_all_pending() ) {
$jobs = self::get_all_pending( $group );
while ( $jobs ) {
foreach ( $jobs as $job_id => $job ) {
$queue_runner->process_action( $job_id );
}
$jobs = self::get_all_pending( $group );
}
}
/**
* Cancel all pending actions.
*

View File

@ -51,7 +51,7 @@ class WC_Admin_Tests_API_ProductsLowInStock extends WC_REST_Unit_Test_Case {
$order->save();
// Sync analytics data (used for last order date).
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', '/wc-analytics/products/low-in-stock' );
$request->set_param( 'low_in_stock', true );

View File

@ -66,7 +66,7 @@ class WC_Admin_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case {
$order->set_total( 100 ); // $25 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' );
@ -114,7 +114,7 @@ class WC_Admin_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case {
$product->set_category_ids( array( $second_category_id ) );
$product->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' );
@ -170,7 +170,7 @@ class WC_Admin_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case {
$order->set_total( 100 ); // $25 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Populate all of the data.
$product = new WC_Product_Simple();
@ -186,7 +186,7 @@ class WC_Admin_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case {
$order->set_total( 400 ); // $100 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' );
$params = array(

View File

@ -87,7 +87,7 @@ class WC_Admin_Tests_API_Reports_Coupons_Stats extends WC_REST_Unit_Test_Case {
$order_2c->set_date_created( $time );
$order_2c->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(

View File

@ -82,7 +82,7 @@ class WC_Admin_Tests_API_Reports_Coupons extends WC_REST_Unit_Test_Case {
$order_2c->calculate_totals();
$order_2c->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) );
$coupon_reports = $response->get_data();
@ -132,7 +132,7 @@ class WC_Admin_Tests_API_Reports_Coupons extends WC_REST_Unit_Test_Case {
$order_1c->calculate_totals();
$order_1c->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(

View File

@ -127,7 +127,7 @@ class WC_Admin_Tests_API_Reports_Customers_Stats extends WC_REST_Unit_Test_Case
$order->set_total( 9.12 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$response = $this->server->dispatch( $request );

View File

@ -149,7 +149,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_total( 100 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params( array( 'per_page' => 10 ) );
@ -164,7 +164,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
// Creating a customer should show up regardless of orders.
$customer = WC_Helper_Customer::create_customer( 'customer', 'password', 'customer@example.com' );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(
@ -221,7 +221,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_total( 100 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(
@ -317,7 +317,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->save();
// Ensure order customer data is synced to lookup table.
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$query_params = array(
'force_cache_refresh' => true,
@ -400,7 +400,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$customer->set_billing_city( '' );
$customer->set_first_name( 'customer_andrei_1' );
$customer->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request->set_query_params(
array(
@ -433,7 +433,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
// Test filter_empty param by state and postcode non empty.
$customer = WC_Helper_Customer::create_customer( 'customer_2', 'password', 'customer_2@example.com' );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request->set_query_params(
array(
@ -498,7 +498,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_total( 100 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$response = $this->server->dispatch( $request );
@ -527,7 +527,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_total( 100 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$response = $this->server->dispatch( $request );
@ -555,7 +555,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_total( 100 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$response = $this->server->dispatch( $request );
@ -584,7 +584,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
// Creating a customer should show up regardless of orders.
$customer = WC_Helper_Customer::create_customer( 'deleteme', 'password', 'deleteme@example.com' );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(
@ -602,7 +602,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
// Delete the user associated with the customer.
wp_delete_user( $customer->get_id() );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Verify they are gone.
$request = new WP_REST_Request( 'GET', $this->endpoint );
@ -630,7 +630,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_total( 100 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// update order info.
$order->set_billing_city( 'Random' );
@ -638,11 +638,11 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_billing_postcode( '54321' );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$result = CustomersDataStore::sync_order_customer( $order->get_id() );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$this->assertNotEquals( -1, $result );
@ -671,7 +671,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order2->set_total( 100 );
$order2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$customer_id = CustomersDataStore::get_existing_customer_id_from_order( $order );
$customer2_id = CustomersDataStore::get_existing_customer_id_from_order( $order2 );
@ -682,11 +682,11 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_billing_postcode( '54321' );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$result = CustomersDataStore::sync_order_customer( $order->get_id() );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Didn't update anything.
$this->assertTrue( -1 === $result );
@ -721,7 +721,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order3->set_billing_email( 'different@example.org' );
$order3->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$customer_id = CustomersDataStore::get_existing_customer_id_from_order( $order );
$customer2_id = CustomersDataStore::get_existing_customer_id_from_order( $order2 );
@ -734,11 +734,11 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order3->set_billing_postcode( '54321' );
$order3->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$result = CustomersDataStore::sync_order_customer( $order3->get_id() );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Didn't update anything.
$this->assertNotEquals( -1, $result );
@ -780,7 +780,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order3->set_total( 100 );
$order3->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$customer_id = CustomersDataStore::get_existing_customer_id_from_order( $order );
$customer2_id = CustomersDataStore::get_existing_customer_id_from_order( $order2 );
@ -794,7 +794,7 @@ class WC_Admin_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case {
$order->set_date_created( time() + 60 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$latest_order = CustomersDataStore::get_last_order( $customer_id );

View File

@ -152,7 +152,7 @@ class WC_Admin_Tests_API_Reports_Downloads_Stats extends WC_REST_Unit_Test_Case
$order->save();
$order_1 = $order->get_id();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$download = new WC_Customer_Download();
$download->set_user_id( 1 );

View File

@ -169,7 +169,7 @@ class WC_Admin_Tests_API_Reports_Downloads extends WC_REST_Unit_Test_Case {
$object->set_timestamp( gmdate( 'Y-m-d H:00:00', $time - ( 2 * DAY_IN_SECONDS ) ) );
$id = $object->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
return array(
'time' => $time,

View File

@ -119,7 +119,7 @@ class WC_Admin_Tests_API_Reports_Export extends WC_REST_Unit_Test_Case {
$order->calculate_totals();
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Initiate an export of the taxes report.
$response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc-analytics/reports/taxes/export' ) );
@ -143,7 +143,7 @@ class WC_Admin_Tests_API_Reports_Export extends WC_REST_Unit_Test_Case {
$this->assertStringMatchesFormat( '%s/wc-analytics/reports/taxes/export/%d/status', $status['_links']['self'][0]['href'] );
// Run the pending export jobs.
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Check that the status shows 100% and includes a download url.
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $status_route ) );

View File

@ -119,7 +119,7 @@ class WC_Admin_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case {
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 'success', $report['status'] );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', '/wc-analytics/reports/customers' );
$response = $this->server->dispatch( $request );
@ -161,7 +161,7 @@ class WC_Admin_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case {
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 'success', $report['status'] );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', '/wc-analytics/reports/customers' );
$response = $this->server->dispatch( $request );
@ -247,7 +247,7 @@ class WC_Admin_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case {
}
// Check that stats exist before deleting.
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', '/wc-analytics/reports/orders' );
$request->set_query_params( array( 'per_page' => 25 ) );
@ -273,7 +273,7 @@ class WC_Admin_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case {
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 'success', $report['status'] );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Check that stats have been deleted.
$request = new WP_REST_Request( 'GET', '/wc-analytics/reports/orders' );
@ -375,7 +375,7 @@ class WC_Admin_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case {
$this->assertEquals( 0, $report['orders']['imported'] );
$this->assertEquals( 4, $report['orders']['total'] );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Test import status after processing.
$request = new WP_REST_Request( 'GET', $this->endpoint . '/status' );

View File

@ -154,7 +154,7 @@ class WC_Admin_Tests_API_Reports_Orders_Stats extends WC_REST_Unit_Test_Case {
$global_attribute = new WC_Product_Attribute();
$global_attribute->set_id( $size_attr_id );
$global_attribute->set_name( 'pa_size' );
$global_attribute->set_options( array( $large_term->term_id ) ); // Set to small.
$global_attribute->set_options( array( $large_term->term_id ) ); // Set to large.
$global_attribute->set_position( 1 );
$global_attribute->set_visible( true );
$global_attribute->set_variation( false );
@ -187,7 +187,8 @@ class WC_Admin_Tests_API_Reports_Orders_Stats extends WC_REST_Unit_Test_Case {
$order->save();
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
WC_Helper_Queue::run_all_pending( 'woocommerce-db-updates' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params( array( 'per_page' => 15 ) );

View File

@ -69,7 +69,7 @@ class WC_Admin_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case {
$order->set_total( 100 ); // $25 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$expected_customer_id = CustomersDataStore::get_customer_id_by_user_id( 1 );
@ -126,7 +126,7 @@ class WC_Admin_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case {
)
);
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) );
$reports = $response->get_data();
@ -238,7 +238,8 @@ class WC_Admin_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case {
$order->save();
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
WC_Helper_Queue::run_all_pending( 'woocommerce-db-updates' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params( array( 'per_page' => 15 ) );
@ -369,7 +370,7 @@ class WC_Admin_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case {
$order->save();
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params( array( 'per_page' => 15 ) );
@ -438,7 +439,7 @@ class WC_Admin_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case {
$order_to_be_included->set_status( 'completed' );
$order_to_be_included->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Test product exclusion.
$request = new WP_REST_Request( 'GET', $this->endpoint );
@ -515,7 +516,7 @@ class WC_Admin_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case {
$second_order->set_status( 'on-hold' );
$second_order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Get the created orders from REST API.
$request = new WP_REST_Request( 'GET', $this->endpoint );

View File

@ -90,7 +90,7 @@ class WC_Admin_Tests_API_Reports_Performance_Indicators extends WC_REST_Unit_Tes
$object->set_user_ip_address( '1.2.3.4' );
$object->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$time = time();
$request = new WP_REST_Request( 'GET', $this->endpoint );

View File

@ -71,7 +71,7 @@ class WC_Admin_Tests_API_Reports_Products_Stats extends WC_REST_Unit_Test_Case {
$order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(

View File

@ -67,7 +67,7 @@ class WC_Admin_Tests_API_Reports_Products extends WC_REST_Unit_Test_Case {
$order->set_total( 100 ); // $25 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) );
$reports = $response->get_data();
@ -109,7 +109,7 @@ class WC_Admin_Tests_API_Reports_Products extends WC_REST_Unit_Test_Case {
$order->set_total( 100 ); // $25 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(

View File

@ -99,7 +99,7 @@ class WC_Admin_Tests_API_Reports_Taxes_Stats extends WC_REST_Unit_Test_Case {
$wc_refund = wc_create_refund( $refund );
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) );
$reports = $response->get_data();

View File

@ -115,7 +115,7 @@ class WC_Admin_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case {
)
);
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) );
$reports = $response->get_data();
@ -416,6 +416,6 @@ class WC_Admin_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case {
)
);
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
}
}

View File

@ -69,7 +69,7 @@ class WC_Admin_Tests_API_Reports_Variations extends WC_REST_Unit_Test_Case {
$order->set_total( 100 ); // $25 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) );
$reports = $response->get_data();
@ -102,7 +102,7 @@ class WC_Admin_Tests_API_Reports_Variations extends WC_REST_Unit_Test_Case {
$order->set_total( 15 );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(
@ -146,7 +146,7 @@ class WC_Admin_Tests_API_Reports_Variations extends WC_REST_Unit_Test_Case {
$order->set_total( 100 ); // $25 x 4.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$request = new WP_REST_Request( 'GET', $this->endpoint );
$request->set_query_params(

View File

@ -53,4 +53,31 @@ class WC_Admin_Tests_Notes_Note extends WC_Unit_Test_Case {
$this->assertEquals( $date_created_from_first_save, $date_created_from_second_save );
}
/**
* Tests setting date_reminder with various input types.
*
* @dataProvider date_reminder_provider
* @param mixed $input Input date value.
* @param int $expected_timestamp Expected timestamp.
*/
public function test_set_date_reminder_with_various_inputs( $input, $expected_timestamp ) {
$note = new Note();
$note->set_date_reminder( $input );
$date_reminder = $note->get_date_reminder();
$this->assertEquals( $expected_timestamp, $date_reminder );
}
/**
* Data provider for test_set_date_reminder_with_various_inputs.
*
* @return array
*/
public function date_reminder_provider() {
return array(
'timestamp' => array( 1609459200, '2021-01-01T00:00:00+00:00' ),
'timestamp string' => array( '1609459200', '2021-01-01T00:00:00+00:00' ),
'date string' => array( '2021-01-01', '2021-01-01T00:00:00+00:00' ),
'WC_DateTime object' => array( new WC_DateTime( '2021-01-01' ), '2021-01-01T00:00:00+00:00' ),
);
}
}

View File

@ -57,7 +57,7 @@ class WC_Admin_Tests_Reports_Coupons_Stats extends WC_Unit_Test_Case {
$order_2c->calculate_totals();
$order_2c->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new CouponsStatsDataStore();
$start_time = gmdate( 'Y-m-d 00:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -133,7 +133,7 @@ class WC_Admin_Tests_Reports_Coupons_Stats extends WC_Unit_Test_Case {
// Delete the coupon.
$coupon_1->delete( true );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$start_time = gmdate( 'Y-m-d 00:00:00', $order->get_date_created()->getOffsetTimestamp() );
$end_time = gmdate( 'Y-m-d 23:59:59', $order->get_date_created()->getOffsetTimestamp() );

View File

@ -59,7 +59,7 @@ class WC_Admin_Tests_Reports_Coupons extends WC_Unit_Test_Case {
$order_2c->calculate_totals();
$order_2c->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new CouponsDataStore();
$start_time = gmdate( 'Y-m-d 00:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -375,7 +375,7 @@ class WC_Admin_Tests_Reports_Coupons extends WC_Unit_Test_Case {
// Delete the coupons.
$coupon_2->delete( true );
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new CouponsDataStore();
$start_time = gmdate( 'Y-m-d 00:00:00', $order->get_date_created()->getOffsetTimestamp() );

View File

@ -29,7 +29,7 @@ class WC_Admin_Tests_Reports_Customer extends WC_Unit_Test_Case {
$product->set_regular_price( 25 );
$product->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$customer_id = DataStore::get_customer_id_by_user_id( $customer->get_id() ); // This is the customer ID from lookup table.
@ -39,7 +39,7 @@ class WC_Admin_Tests_Reports_Customer extends WC_Unit_Test_Case {
$order->save();
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Customer should have 3 orders.
$this->assertSame( 3, DataStore::get_order_count( $customer_id ) );
@ -75,7 +75,7 @@ class WC_Admin_Tests_Reports_Customer extends WC_Unit_Test_Case {
$product2->set_regular_price( 2 );
$product2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Create the first order.
$order1 = WC_Helper_Order::create_order( $customer->get_id(), $product1 );
@ -85,7 +85,7 @@ class WC_Admin_Tests_Reports_Customer extends WC_Unit_Test_Case {
$order2 = WC_Helper_Order::create_order( $customer->get_id(), $product2 );
$order2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$customer_id = DataStore::get_customer_id_by_user_id( $customer->get_id() ); // This is the customer ID from lookup table.

View File

@ -63,7 +63,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
)
);
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersStatsDataStore();
@ -208,7 +208,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order->save();
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersStatsDataStore();
@ -377,7 +377,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
)
);
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersStatsDataStore();
@ -666,7 +666,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$orders[] = $order;
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersStatsDataStore();
@ -917,7 +917,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
}
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersStatsDataStore();
@ -3865,7 +3865,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order->apply_coupon( $coupon );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Check if lookup tables are populated.
foreach ( $tables as $table ) {
@ -3996,7 +3996,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order_2->calculate_totals();
$order_2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersStatsDataStore();
@ -4544,7 +4544,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$orders[] = $order;
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersStatsDataStore();
@ -5328,7 +5328,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$orders[] = $order;
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
global $wpdb;
$res = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wc_order_stats" );
@ -6094,7 +6094,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order_0->set_total( 100 );
$order_0->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$start_time = gmdate( 'Y-m-d H:00:00', $order_0->get_date_created()->getOffsetTimestamp() );
$end_time = gmdate( 'Y-m-d H:59:59', $order_0->get_date_created()->getOffsetTimestamp() );
@ -6114,7 +6114,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order_1->set_total( 100 );
$order_1->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Time frame includes both orders -> customer is a new customer.
$start_time = gmdate( 'Y-m-d H:00:00', $order_0->get_date_created()->getOffsetTimestamp() );
@ -6153,7 +6153,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order_2->set_total( 100 );
$order_2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Time frame includes second and third order -> there is one returning customer.
$start_time = gmdate( 'Y-m-d H:i:s', $order_0_time + 1 );
@ -6204,7 +6204,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order_0->set_total( 100 );
$order_0->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$start_time = gmdate( 'Y-m-d H:00:00', $order_0->get_date_created()->getOffsetTimestamp() );
$end_time = gmdate( 'Y-m-d H:59:59', $order_0->get_date_created()->getOffsetTimestamp() );
@ -6224,7 +6224,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order_1->set_total( 100 );
$order_1->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Time frame includes both orders -> customer is a new customer.
$start_time = gmdate( 'Y-m-d H:00:00', $order_0->get_date_created()->getOffsetTimestamp() );
@ -6263,7 +6263,7 @@ class WC_Admin_Tests_Reports_Orders_Stats extends WC_Unit_Test_Case {
$order_2->set_total( 100 );
$order_2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// Time frame includes second and third order -> there is one returning customer.
$start_time = gmdate( 'Y-m-d H:i:s', $order_0_time + 1 );

View File

@ -64,7 +64,7 @@ class WC_Admin_Tests_Reports_Orders extends WC_Unit_Test_Case {
$order->set_status( 'completed' );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -143,7 +143,7 @@ class WC_Admin_Tests_Reports_Orders extends WC_Unit_Test_Case {
)
);
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -255,7 +255,7 @@ class WC_Admin_Tests_Reports_Orders extends WC_Unit_Test_Case {
$order2->set_status( 'completed' );
$order2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new OrdersDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -310,7 +310,7 @@ class WC_Admin_Tests_Reports_Orders extends WC_Unit_Test_Case {
$order_2->set_status( 'completed' );
$order_2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
$end_time = gmdate( 'Y-m-d H:59:59', $order->get_date_created()->getOffsetTimestamp() );

View File

@ -42,7 +42,7 @@ class WC_Admin_Tests_Reports_Products extends WC_Unit_Test_Case {
$order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new ProductsDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -119,7 +119,7 @@ class WC_Admin_Tests_Reports_Products extends WC_Unit_Test_Case {
$order_2->set_date_created( $date_created_2 );
$order_2->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new ProductsDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -220,7 +220,7 @@ class WC_Admin_Tests_Reports_Products extends WC_Unit_Test_Case {
$order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new ProductsDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -301,7 +301,7 @@ class WC_Admin_Tests_Reports_Products extends WC_Unit_Test_Case {
$order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new ProductsDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -383,7 +383,7 @@ class WC_Admin_Tests_Reports_Products extends WC_Unit_Test_Case {
break;
}
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new ProductsDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -441,7 +441,7 @@ class WC_Admin_Tests_Reports_Products extends WC_Unit_Test_Case {
$order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$term = wp_insert_term( 'Unused Category', 'product_cat' );

View File

@ -43,7 +43,7 @@ class WC_Admin_Tests_Reports_Revenue_Stats extends WC_Unit_Test_Case {
$order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax.
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
// /reports/revenue/stats is mapped to Orders_Data_Store.
$data_store = new OrdersStatsDataStore();

View File

@ -42,7 +42,7 @@ class WC_Admin_Tests_Reports_Variations extends WC_Unit_Test_Case {
$order->set_status( 'completed' );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new VariationsDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -111,7 +111,7 @@ class WC_Admin_Tests_Reports_Variations extends WC_Unit_Test_Case {
$order->set_status( 'completed' );
$order->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new VariationsDataStore();
$start_time = gmdate( 'Y-m-d H:00:00', $order->get_date_created()->getOffsetTimestamp() );
@ -228,7 +228,7 @@ class WC_Admin_Tests_Reports_Variations extends WC_Unit_Test_Case {
$order_3->set_status( 'completed' );
$order_3->save();
WC_Helper_Queue::run_all_pending();
WC_Helper_Queue::run_all_pending( 'wc-admin-data' );
$data_store = new VariationsDataStore();