session || ! WC()->cart ) { return; } $snapshot = AIEO_Carts_Store::snapshot_live_cart(); if ( empty( $snapshot ) || empty( $snapshot['lines'] ) ) { return; } $email = $this->resolve_email( $request ); if ( '' === $email ) { return; } $session_id = (string) WC()->session->get_customer_id(); if ( '' === $session_id ) { return; } global $wpdb; $carts = AIEO_Carts_Store::carts_table(); if ( ! AIEO_Carts_Store::table_exists( $carts ) ) { return; } $this->ensure_session_index( $carts ); $now = current_time( 'mysql', true ); $user_id = get_current_user_id(); $existing = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM `{$carts}` WHERE session_id = %s AND source = %s AND wc_order_id IS NULL AND status = 'abandoned' ORDER BY id DESC LIMIT 1", $session_id, self::SOURCE ) ); $payload = array( 'user_id' => (int) $user_id, 'customer_email' => $email, 'session_id' => $session_id, 'items' => maybe_serialize( $snapshot['items'] ), 'coupons' => maybe_serialize( $snapshot['coupons'] ), 'currency' => (string) $snapshot['currency'], 'item_count' => (int) $snapshot['item_count'], 'subtotal' => (float) $snapshot['subtotal'], 'total' => (float) $snapshot['total'], 'updated_at' => $now, 'last_seen_at' => $now, ); if ( $existing ) { $wpdb->update( $carts, $payload, array( 'id' => (int) $existing ) ); $cart_id = (int) $existing; } else { $cart_id = (int) AIEO_Carts_Store::insert_cart( array_merge( $payload, array( 'token' => null, 'kind' => 'abandoned', 'source' => self::SOURCE, 'wc_order_id' => null, 'name' => null, 'status' => 'abandoned', 'outcome' => 'open', 'contains_restocked' => 0, 'created_at' => $now, ) ) ); } if ( $cart_id > 0 ) { AIEO_Carts_Store::replace_items( $cart_id, $snapshot['lines'] ); $this->touched_cart_id = $cart_id; } } public function attach_order( $order, $request = null ) { unset( $request ); if ( ! $order instanceof WC_Order || ! class_exists( 'AIEO_Carts_Store' ) ) { return; } if ( ! function_exists( 'WC' ) || ! WC() || ! WC()->session ) { return; } global $wpdb; $carts = AIEO_Carts_Store::carts_table(); if ( ! AIEO_Carts_Store::table_exists( $carts ) ) { return; } $order_id = (int) $order->get_id(); if ( $order_id <= 0 ) { return; } $cart_id = (int) $this->touched_cart_id; if ( $cart_id <= 0 ) { $session_id = (string) WC()->session->get_customer_id(); if ( '' === $session_id ) { return; } $cart_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT id FROM `{$carts}` WHERE session_id = %s AND source = %s AND wc_order_id IS NULL ORDER BY id DESC LIMIT 1", $session_id, self::SOURCE ) ); } if ( $cart_id <= 0 ) { return; } $claimed = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$carts}` WHERE wc_order_id = %d", $order_id ) ); if ( $claimed > 0 ) { return; } $wpdb->update( $carts, array( 'wc_order_id' => $order_id, 'updated_at' => current_time( 'mysql', true ), ), array( 'id' => $cart_id ) ); } private function resolve_email( $request ) { $email = ''; if ( WC()->customer && method_exists( WC()->customer, 'get_billing_email' ) ) { $email = (string) WC()->customer->get_billing_email(); } if ( '' === $email && $request instanceof WP_REST_Request ) { $billing = $request->get_param( 'billing_address' ); if ( is_array( $billing ) && ! empty( $billing['email'] ) ) { $email = (string) $billing['email']; } } $email = sanitize_email( trim( $email ) ); return is_email( $email ) ? $email : ''; } private function ensure_session_index( $carts ) { if ( get_option( self::INDEX_FLAG ) === '1' ) { return; } global $wpdb; $has = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s AND INDEX_NAME = 'session_source'", $carts ) ); if ( 0 === $has ) { $wpdb->query( "ALTER TABLE `{$carts}` ADD KEY `session_source` (`session_id`,`source`)" ); } update_option( self::INDEX_FLAG, '1', false ); } } }