OwlCyberSecurity - MANAGER
Edit File: CreateAccount.php
<?php declare( strict_types = 1 ); namespace Automattic\WooCommerce\Blocks\BlockTypes\OrderConfirmation; use Automattic\WooCommerce\StoreApi\Utilities\OrderController; use Automattic\WooCommerce\Admin\Features\Features; /** * CreateAccount class. */ class CreateAccount extends AbstractOrderConfirmationBlock { /** * Block name. * * @var string */ protected $block_name = 'order-confirmation-create-account'; /** * Initialize this block type. */ protected function initialize() { parent::initialize(); if ( $this->is_feature_enabled() ) { $this->initialize_hooks(); } } /** * Initialize hooks. * * @see https://developer.wordpress.org/reference/hooks/hooked_block/ */ protected function initialize_hooks() { // This does not use the Block Hooks Trait used in mini cart. The implementation is simpler because we support // versions higher than WP 6.5 when hooks were introduced. They should be consolodated in the future. add_filter( 'hooked_block_types', function ( $hooked_block_types, $relative_position, $anchor_block_type, $context ) { if ( 'after' !== $relative_position || 'woocommerce/order-confirmation-summary' !== $anchor_block_type || ! $context instanceof \WP_Block_Template ) { return $hooked_block_types; } if ( ! str_contains( $context->content, '<!-- wp:' . $this->get_full_block_name() ) ) { $hooked_block_types[] = $this->get_full_block_name(); } return $hooked_block_types; }, 10, 4 ); add_filter( 'hooked_block_woocommerce/order-confirmation-create-account', function ( $parsed_hooked_block, $hooked_block_type, $relative_position ) { if ( 'after' !== $relative_position || is_null( $parsed_hooked_block ) ) { return $parsed_hooked_block; } /* translators: %s: Site title */ $site_title_heading = sprintf( __( 'Create an account with %s', 'woocommerce' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ); $parsed_hooked_block['innerContent'] = array( '<div class="wp-block-woocommerce-order-confirmation-create-account alignwide"> <!-- wp:heading {"level":3} --> <h3 class="wp-block-heading">' . esc_html( $site_title_heading ) . '</h3> <!-- /wp:heading --> <!-- wp:list {"className":"is-style-checkmark-list"} --> <ul class="wp-block-list is-style-checkmark-list"><!-- wp:list-item --> <li>' . esc_html__( 'Faster future purchases', 'woocommerce' ) . '</li> <!-- /wp:list-item --> <!-- wp:list-item --> <li>' . esc_html__( 'Securely save payment info', 'woocommerce' ) . '</li> <!-- /wp:list-item --> <!-- wp:list-item --> <li>' . esc_html__( 'Track orders & view shopping history', 'woocommerce' ) . '</li> <!-- /wp:list-item --></ul> <!-- /wp:list --> </div>', ); return $parsed_hooked_block; }, 10, 4 ); } /** * 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; } /** * Returns if delayed account creation is enabled. * * @return bool */ protected function is_feature_enabled() { return get_option( 'woocommerce_enable_delayed_account_creation', 'yes' ) === 'yes'; } /** * 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['_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'] ) ); // 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' ) ); } $generate_password = filter_var( get_option( 'woocommerce_registration_generate_password', 'no' ), FILTER_VALIDATE_BOOLEAN ); if ( $generate_password ) { $password = ''; // Will be generated by wc_create_new_customer. } else { $password = wp_unslash( $_POST['password'] ?? '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 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 || ! $this->is_feature_enabled() ) { 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 ); $notice = ''; 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="wc-block-order-confirmation-create-account-form-wrapper">' . $notice . '<div class="wc-block-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( 'wc-block-order-confirmation-create-account-content' ); if ( ! $processor->next_tag( array( 'class_name' => 'wc-block-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="wc-block-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; } /** * Extra data passed through from server to client for block. * * @param array $attributes Any attributes that currently are available from the block. * Note, this will be empty in the editor context when the block is * not in the post content on editor load. */ protected function enqueue_data( array $attributes = [] ) { parent::enqueue_data( $attributes ); $this->asset_data_registry->add( 'delayedAccountCreationEnabled', $this->is_feature_enabled() ); $this->asset_data_registry->add( 'registrationGeneratePassword', filter_var( get_option( 'woocommerce_registration_generate_password' ), FILTER_VALIDATE_BOOLEAN ) ); } }