should be created as part of order processing. * * @param \WP_REST_Request $request The current request object being handled. * * @return boolean True if a new user account should be created. */ protected function should_create_customer_account( \WP_REST_Request $request ) { if ( is_user_logged_in() ) { // User is already logged in - no need to create an account. return false; } // From here we know that the shopper is not logged in. // check for whether account creation is enabled at the global level. $checkout = WC()->checkout(); if ( ! $checkout instanceof \WC_Checkout ) { // If checkout class is not available, we have major problems, don't create account. return false; } if ( false === filter_var( $checkout->is_registration_enabled(), FILTER_VALIDATE_BOOLEAN ) ) { // Registration is not enabled for the store, so return false. return false; } if ( true === filter_var( $checkout->is_registration_required(), FILTER_VALIDATE_BOOLEAN ) ) { // Store requires an account for all checkouts (purchases). // Create an account independent of shopper option in $request. // Note - checkbox is not displayed to shopper in this case. return true; } // From here we know that the store allows guest checkout; // shopper can choose whether they sign up (`should_create_account`). if ( true === filter_var( $request['should_create_account'], FILTER_VALIDATE_BOOLEAN ) ) { // User has requested an account as part of checkout processing. return true; } return false; } /** * Convert an account creation error to an exception. * * @param \WP_Error $error An error object. * * @return Exception. */ private function map_create_account_error( \WP_Error $error ) { switch ( $error->get_error_code() ) { // WordPress core error codes. case 'empty_username': case 'invalid_username': case 'empty_email': case 'invalid_email': case 'email_exists': case 'registerfail': return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); } return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); } /** * Create a new account for a customer (using a new blocks-specific PHP API). * * The account is created with a generated username. The customer is sent * an email notifying them about the account and containing a link to set * their (initial) password. * * Intended as a replacement for wc_create_new_customer in WC core. * * @throws \Exception If an error is encountered when creating the user account. * * @param string $user_email The email address to use for the new account. * @param string $first_name The first name to use for the new account. * @param string $last_name The last name to use for the new account. * * @return int User id if successful */ private function create_customer_account( $user_email, $first_name, $last_name ) { if ( empty( $user_email ) || ! is_email( $user_email ) ) { throw new \Exception( 'registration-error-invalid-email' ); } if ( email_exists( $user_email ) ) { throw new \Exception( 'registration-error-email-exists' ); } $username = wc_create_new_customer_username( $user_email ); // Handle password creation. $password = wp_generate_password(); $password_generated = true; // Use WP_Error to handle registration errors. $errors = new \WP_Error(); do_action( 'woocommerce_register_post', $username, $user_email, $errors ); $errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $user_email ); if ( $errors->get_error_code() ) { throw new \Exception( $errors->get_error_code() ); } $new_customer_data = apply_filters( 'woocommerce_new_customer_data', array( 'is_checkout_block_customer_signup' => true, 'user_login' => $username, 'user_pass' => $password, 'user_email' => $user_email, 'first_name' => $first_name, 'last_name' => $last_name, 'role' => 'customer', ) ); $customer_id = wp_insert_user( $new_customer_data ); if ( is_wp_error( $customer_id ) ) { throw $this->map_create_account_error( $customer_id ); } // Set account flag to remind customer to update generated password. update_user_option( $customer_id, 'default_password_nag', true, true ); do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated ); return $customer_id; } }