Woocommerce: Override login required for existing

2020-07-30 04:32发布

问题:

Woocommerce Settings:

  • Guest checkout disabled.
  • Create account during checkout enabled (user and passowrd auto generated)

If user is REGISTERED. But NOT logged in. Checkout errors with "An account is already registered with your email address. Please log in."

How do I override this to COMPLETE order, and tie order to existing account. Give a prompt to user to login next time for a faster checkout

Can't find any snippet or module that can do it

none yet. Happy to reward.

回答1:

There is no hook for this. You may need to modify process_customer function in WC core (plugins/woocommerce/includes/class-wc-checkout.php) Line#935 - Keep in mind, it's not encouraged to edit core ( when updated, your changes will loose)

protected function process_customer( $data ) {
        $customer_id = apply_filters( 'woocommerce_checkout_customer_id', get_current_user_id() );

        if ( ! is_user_logged_in() && ( $this->is_registration_required() || ! empty( $data['createaccount'] ) ) ) {
            $username    = ! empty( $data['account_username'] ) ? $data['account_username'] : '';
            $password    = ! empty( $data['account_password'] ) ? $data['account_password'] : '';

                        if(email_exists($data['billing_email'])){
                        $creds = array();
                        $creds['user_login'] = $user_login;
                        $creds['user_password'] = $user_password;
                        $creds['remember'] = true;

                        $user = wp_signon($creds, false);

                        $customer_id = $user->ID;

                        wp_set_current_user($customer_id, $user_login);
                        wp_set_auth_cookie($customer_id, true, false);
                        do_action('wp_login', $user_login);
                        }else{
                        $customer_id = wc_create_new_customer( $data['billing_email'], $username, $password );
                        }

            if ( is_wp_error( $customer_id ) ) {
                throw new Exception( $customer_id->get_error_message() );
            }

            wp_set_current_user( $customer_id );
            wc_set_customer_auth_cookie( $customer_id );

            // As we are now logged in, checkout will need to refresh to show logged in data.
            WC()->session->set( 'reload_checkout', true );

            // Also, recalculate cart totals to reveal any role-based discounts that were unavailable before registering.
            WC()->cart->calculate_totals();
        }

        // On multisite, ensure user exists on current site, if not add them before allowing login.
        if ( $customer_id && is_multisite() && is_user_logged_in() && ! is_user_member_of_blog() ) {
            add_user_to_blog( get_current_blog_id(), $customer_id, 'customer' );
        }

        // Add customer info from other fields.
        if ( $customer_id && apply_filters( 'woocommerce_checkout_update_customer_data', true, $this ) ) {
            $customer = new WC_Customer( $customer_id );

            if ( ! empty( $data['billing_first_name'] ) ) {
                $customer->set_first_name( $data['billing_first_name'] );
            }

            if ( ! empty( $data['billing_last_name'] ) ) {
                $customer->set_last_name( $data['billing_last_name'] );
            }

            // If the display name is an email, update to the user's full name.
            if ( is_email( $customer->get_display_name() ) ) {
                $customer->set_display_name( $data['billing_first_name'] . ' ' . $data['billing_last_name'] );
            }

            foreach ( $data as $key => $value ) {
                // Use setters where available.
                if ( is_callable( array( $customer, "set_{$key}" ) ) ) {
                    $customer->{"set_{$key}"}( $value );

                    // Store custom fields prefixed with wither shipping_ or billing_.
                } elseif ( 0 === stripos( $key, 'billing_' ) || 0 === stripos( $key, 'shipping_' ) ) {
                    $customer->update_meta_data( $key, $value );
                }
            }

            /**
             * Action hook to adjust customer before save.
             *
             * @since 3.0.0
             */
            do_action( 'woocommerce_checkout_update_customer', $customer, $data );

            $customer->save();
        }

        do_action( 'woocommerce_checkout_update_user_meta', $customer_id, $data );
    }

If you have enabled allow customers to login on checkout, the option login from checkout page will be coming.