blocking_error( $this->posted_email() );
if ( $error ) {
wc_add_notice( $error, 'error' );
}
}
/**
* @param \WP_Error $errors
*/
public function validate_store_api( $errors ) {
$error = $this->blocking_error( $this->customer_email() );
if ( $error && $errors instanceof \WP_Error ) {
$errors->add( 'submex_login_required', $error );
}
return $errors;
}
/**
* Give the order an owner, creating the account if there is nobody to give it to.
*
* @param \WC_Order $order
*/
public function assign_owner( $order ): void {
if ( ! $order instanceof \WC_Order || $order->get_customer_id() || ! Subscription_Product::cart_has_subscription() ) {
return;
}
$email = sanitize_email( (string) $order->get_billing_email() );
if ( ! is_email( $email ) ) {
return;
}
$user_id = $this->create_account( $email, $order );
if ( $user_id ) {
$order->set_customer_id( $user_id );
}
}
/**
* Warn when the store's own settings make a subscription impossible to buy.
*/
public function warn_if_unreachable(): void {
if ( ! current_user_can( 'manage_woocommerce' ) || ! Notices::in_context() ) {
return;
}
$unreachable = self::REQUIRE === self::mode()
&& 'yes' !== get_option( 'woocommerce_enable_signup_and_login_from_checkout', 'no' )
&& 'yes' !== get_option( 'woocommerce_enable_checkout_login_reminder', 'no' );
// Asked even when all is well, so a fixed setting that breaks again shows again.
if ( ! Notice_Dismissals::shows_problem( self::NOTICE_UNREACHABLE, $unreachable ? 'unreachable' : '' ) ) {
return;
}
printf(
'
',
esc_attr( Notices::important( 'warning' ) ),
esc_html__( 'Submex requires customers to log in before buying a subscription, but WooCommerce is not offering a login or sign-up on the checkout page. Customers will be turned away with no way forward.', 'submex' ),
esc_url( Notice_Dismissals::problem_url( self::NOTICE_UNREACHABLE, 'unreachable' ) ),
esc_html__( 'Dismiss', 'submex' )
);
}
private function blocking_error( string $email = '' ): string {
if ( is_user_logged_in() || ! Subscription_Product::cart_has_subscription() ) {
return '';
}
if ( self::REQUIRE === self::mode() ) {
return __( 'Please log in or create an account to buy a subscription. You will need one to manage or cancel it later.', 'submex' );
}
// Letting this through would create a subscription owned by nobody, which the
// customer could never see or cancel. Better to stop here than to sell that.
if ( '' !== $email && email_exists( $email ) ) {
return __( 'You already have an account with this email address. Please log in to buy a subscription.', 'submex' );
}
return '';
}
private function posted_email(): string {
// Nonce is WooCommerce's own, verified by the checkout process this runs inside.
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$email = isset( $_POST['billing_email'] ) ? sanitize_email( wp_unslash( $_POST['billing_email'] ) ) : '';
return is_email( $email ) ? $email : '';
}
private function customer_email(): string {
$customer = function_exists( 'WC' ) && WC()->customer ? WC()->customer->get_billing_email() : '';
$email = sanitize_email( (string) $customer );
return is_email( $email ) ? $email : '';
}
/**
* An account already registered to this address is never claimed silently: the buyer
* has not proved they own it, and attaching the subscription would put a stranger's
* payment details and address inside somebody else's account.
*/
private function create_account( string $email, \WC_Order $order ): int {
if ( email_exists( $email ) ) {
return 0;
}
$username = wc_create_new_customer_username(
$email,
array(
'first_name' => $order->get_billing_first_name(),
'last_name' => $order->get_billing_last_name(),
)
);
$user_id = wc_create_new_customer(
$email,
$username,
'',
array(
'first_name' => $order->get_billing_first_name(),
'last_name' => $order->get_billing_last_name(),
)
);
if ( is_wp_error( $user_id ) ) {
return 0;
}
$order->add_order_note( __( 'An account was created for this customer so they can manage their subscription.', 'submex' ) );
return (int) $user_id;
}
}