rebase on oct-10-2023
This commit is contained in:
@@ -94,7 +94,7 @@ class WC_Shortcode_Checkout {
|
||||
|
||||
// Logged out customer does not have permission to pay for this order.
|
||||
if ( ! current_user_can( 'pay_for_order', $order_id ) && ! is_user_logged_in() ) {
|
||||
echo '<div class="woocommerce-info">' . esc_html__( 'Please log in to your account below to continue to the payment form.', 'woocommerce' ) . '</div>';
|
||||
wc_print_notice( esc_html__( 'Please log in to your account below to continue to the payment form.', 'woocommerce' ), 'notice' );
|
||||
woocommerce_login_form(
|
||||
array(
|
||||
'redirect' => $order->get_checkout_payment_url(),
|
||||
@@ -171,6 +171,18 @@ class WC_Shortcode_Checkout {
|
||||
}
|
||||
}
|
||||
|
||||
// If we cannot match the order with the current user, ask that they verify their email address.
|
||||
if ( self::guest_should_verify_email( $order, 'order-pay' ) ) {
|
||||
wc_get_template(
|
||||
'checkout/form-verify-email.php',
|
||||
array(
|
||||
'failed_submission' => ! empty( $_POST['email'] ), // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
'verify_url' => $order->get_checkout_payment_url(),
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
WC()->customer->set_props(
|
||||
array(
|
||||
'billing_country' => $order->get_billing_country() ? $order->get_billing_country() : null,
|
||||
@@ -258,6 +270,7 @@ class WC_Shortcode_Checkout {
|
||||
|
||||
if ( $order_id > 0 ) {
|
||||
$order = wc_get_order( $order_id );
|
||||
|
||||
if ( ! $order || ! hash_equals( $order->get_order_key(), $order_key ) ) {
|
||||
$order = false;
|
||||
}
|
||||
@@ -276,6 +289,38 @@ class WC_Shortcode_Checkout {
|
||||
// Empty current cart.
|
||||
wc_empty_cart();
|
||||
|
||||
// If the specified order ID was invalid, we still render the default order received page (which will simply
|
||||
// state that the order was received, but will not output any other details: this makes it harder to probe for
|
||||
// valid order IDs than if we state that the order ID was not recognized).
|
||||
if ( ! $order ) {
|
||||
wc_get_template( 'checkout/thankyou.php', array( 'order' => false ) );
|
||||
return;
|
||||
}
|
||||
|
||||
$order_customer_id = $order->get_customer_id();
|
||||
|
||||
// For non-guest orders, require the user to be logged in before showing this page.
|
||||
if ( $order_customer_id && get_current_user_id() !== $order_customer_id ) {
|
||||
wc_get_template( 'checkout/order-received.php', array( 'order' => false ) );
|
||||
wc_print_notice( esc_html__( 'Please log in to your account to view this order.', 'woocommerce' ), 'notice' );
|
||||
woocommerce_login_form( array( 'redirect' => $order->get_checkout_order_received_url() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// For guest orders, request they verify their email address (unless we can identify them via the active user session).
|
||||
if ( self::guest_should_verify_email( $order, 'order-received' ) ) {
|
||||
wc_get_template( 'checkout/order-received.php', array( 'order' => false ) );
|
||||
wc_get_template(
|
||||
'checkout/form-verify-email.php',
|
||||
array(
|
||||
'failed_submission' => ! empty( $_POST['email'] ), // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
'verify_url' => $order->get_checkout_order_received_url(),
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, display the thank you (order received) page.
|
||||
wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
|
||||
}
|
||||
|
||||
@@ -317,4 +362,91 @@ class WC_Shortcode_Checkout {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to determine if the user's email address should be verified before rendering either the 'order received' or
|
||||
* 'order pay' pages. This should only be applied to guest orders.
|
||||
*
|
||||
* @param WC_Order $order The order for which a need for email verification is being determined.
|
||||
* @param string $context The context in which email verification is being tested.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function guest_should_verify_email( WC_Order $order, string $context ): bool {
|
||||
$order_email = $order->get_billing_email();
|
||||
$order_customer_id = $order->get_customer_id();
|
||||
|
||||
// If we do not have a billing email for the order (could happen in the order is created manually, or if the
|
||||
// requirement for this has been removed from the checkout flow), email verification does not make sense.
|
||||
if ( empty( $order_email ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No verification step is needed if the user is logged in and is already associated with the order.
|
||||
if ( $order_customer_id && get_current_user_id() === $order_customer_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$email = filter_input( INPUT_POST, 'email' );
|
||||
$nonce = filter_input( INPUT_POST, 'check_submission' );
|
||||
if ( $email && ! wp_verify_nonce( $nonce, 'wc_verify_email' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls the grace period within which we do not require any sort of email verification step before rendering
|
||||
* the 'order received' or 'order pay' pages.
|
||||
*
|
||||
* To eliminate the grace period, set to zero (or to a negative value). Note that this filter is not invoked
|
||||
* at all if email verification is deemed to be unnecessary (in other words, it cannot be used to force
|
||||
* verification in *all* cases).
|
||||
*
|
||||
* @since 8.0.0
|
||||
*
|
||||
* @param int $grace_period Time in seconds after an order is placed before email verification may be required.
|
||||
* @param WC_Order $order The order for which this grace period is being assessed.
|
||||
* @param string $context Indicates the context in which we might verify the email address. Typically 'order-pay' or 'order-received'.
|
||||
*/
|
||||
$verification_grace_period = (int) apply_filters( 'woocommerce_order_email_verification_grace_period', 10 * MINUTE_IN_SECONDS, $order, $context );
|
||||
$date_created = $order->get_date_created();
|
||||
|
||||
// We do not need to verify the email address if we are within the grace period immediately following order creation.
|
||||
if (
|
||||
is_a( $date_created, WC_DateTime::class )
|
||||
&& time() - $date_created->getTimestamp() <= $verification_grace_period
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$session = wc()->session;
|
||||
$session_email = '';
|
||||
|
||||
if ( is_a( $session, WC_Session::class ) ) {
|
||||
$customer = $session->get( 'customer' );
|
||||
$session_email = is_array( $customer ) && isset( $customer['email'] ) ? $customer['email'] : '';
|
||||
}
|
||||
|
||||
$session_email_match = $session_email === $order->get_billing_email();
|
||||
$supplied_email_match = isset( $_POST['email'] ) && sanitize_email( wp_unslash( $_POST['email'] ) ?? '' ) === $order->get_billing_email();
|
||||
$can_view_orders = current_user_can( 'read_private_shop_orders' );
|
||||
|
||||
// If we cannot match the order with the current user, the user should verify their email address.
|
||||
$email_verification_required = ! $session_email_match && ! $supplied_email_match && ! $can_view_orders;
|
||||
|
||||
/**
|
||||
* Provides an opportunity to override the (potential) requirement for shoppers to verify their email address
|
||||
* before we show information such as the order summary, or order payment page.
|
||||
*
|
||||
* Note that this hook is not always triggered, therefore it is (for example) unsuitable as a way of forcing
|
||||
* email verification across all order confirmation/order payment scenarios. Instead, the filter primarily
|
||||
* exists as a way to *remove* the email verification step.
|
||||
*
|
||||
* @since 7.9.0
|
||||
*
|
||||
* @param bool $email_verification_required If email verification is required.
|
||||
* @param WC_Order $order The relevant order.
|
||||
* @param string $context The context under which we are performing this check.
|
||||
*/
|
||||
return (bool) apply_filters( 'woocommerce_order_email_verification_required', $email_verification_required, $order, $context );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,8 +134,10 @@ class WC_Shortcode_My_Account {
|
||||
$order = wc_get_order( $order_id );
|
||||
|
||||
if ( ! $order || ! current_user_can( 'view_order', $order_id ) ) {
|
||||
echo '<div class="woocommerce-error">' . esc_html__( 'Invalid order.', 'woocommerce' ) . ' <a href="' . esc_url( wc_get_page_permalink( 'myaccount' ) ) . '" class="wc-forward">' . esc_html__( 'My account', 'woocommerce' ) . '</a></div>';
|
||||
|
||||
wc_print_notice(
|
||||
esc_html__( 'Invalid order.', 'woocommerce' ) . ' <a href="' . esc_url( wc_get_page_permalink( 'myaccount' ) ) . '" class="wc-forward">' . esc_html__( 'My account', 'woocommerce' ) . '</a>',
|
||||
'error'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -653,7 +653,7 @@ class WC_Shortcode_Products {
|
||||
$GLOBALS['post'] = get_post( $product_id ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
setup_postdata( $GLOBALS['post'] );
|
||||
|
||||
// Set custom product visibility when quering hidden products.
|
||||
// Set custom product visibility when querying hidden products.
|
||||
add_action( 'woocommerce_product_is_visible', array( $this, 'set_product_as_visible' ) );
|
||||
|
||||
// Render product template.
|
||||
|
||||
Reference in New Issue
Block a user