$arguments * @return array */ public static function create_cart( array $arguments ): array { $session_key = self::resolve_session_key( $arguments ); if ( $session_key === '' ) { return self::error_response( __( 'A valid chat session id is required in cart context.', 'agentmatica-mcp-connector' ) ); } $line_items = self::read_line_items( $arguments ); if ( empty( $line_items ) ) { return self::error_response( __( 'cart.line_items is required.', 'agentmatica-mcp-connector' ) ); } foreach ( $line_items as $line ) { $result = Agentmatica_WooCommerce_Cart::add_item( array( 'session_key' => $session_key, 'product_id' => (int) ( $line['product_id'] ?? 0 ), 'variation_id' => (int) ( $line['variation_id'] ?? 0 ), 'quantity' => (int) ( $line['quantity'] ?? 1 ), ) ); if ( empty( $result['success'] ) ) { return self::error_response( (string) ( $result['message'] ?? __( 'Failed to add item to cart.', 'agentmatica-mcp-connector' ) ) ); } } $attributes = self::read_cart_attributes( $arguments ); if ( ! empty( $attributes ) ) { Agentmatica_Order_Attribution::merge_cart_attributes( $session_key, $attributes ); } return self::cart_response( $session_key ); } /** * @param array $arguments * @return array */ public static function update_cart( array $arguments ): array { $session_key = self::read_session_key( $arguments ); if ( $session_key === '' ) { return self::error_response( __( 'A valid chat session id is required in cart context.', 'agentmatica-mcp-connector' ) ); } $remove_items = self::read_remove_line_items( $arguments ); foreach ( $remove_items as $line ) { $result = Agentmatica_WooCommerce_Cart::remove_item( array( 'session_key' => $session_key, 'product_id' => (int) ( $line['product_id'] ?? 0 ), 'variation_id' => (int) ( $line['variation_id'] ?? 0 ), ) ); if ( empty( $result['success'] ) ) { return self::error_response( (string) ( $result['message'] ?? __( 'Failed to remove item from cart.', 'agentmatica-mcp-connector' ) ) ); } } $line_items = self::read_line_items( $arguments ); foreach ( $line_items as $line ) { $result = Agentmatica_WooCommerce_Cart::add_item( array( 'session_key' => $session_key, 'product_id' => (int) ( $line['product_id'] ?? 0 ), 'variation_id' => (int) ( $line['variation_id'] ?? 0 ), 'quantity' => (int) ( $line['quantity'] ?? 1 ), ) ); if ( empty( $result['success'] ) ) { return self::error_response( (string) ( $result['message'] ?? __( 'Failed to add item to cart.', 'agentmatica-mcp-connector' ) ) ); } } if ( empty( $remove_items ) && empty( $line_items ) ) { return self::error_response( __( 'cart.line_items or cart.remove_line_items is required.', 'agentmatica-mcp-connector' ) ); } $attributes = self::read_cart_attributes( $arguments ); if ( ! empty( $attributes ) ) { Agentmatica_Order_Attribution::merge_cart_attributes( $session_key, $attributes ); } return self::cart_response( $session_key ); } /** * @return list */ private static function read_remove_line_items( array $arguments ): array { $cart = isset( $arguments['cart'] ) && is_array( $arguments['cart'] ) ? $arguments['cart'] : $arguments; $line_items = isset( $cart['remove_line_items'] ) && is_array( $cart['remove_line_items'] ) ? $cart['remove_line_items'] : array(); $parsed = array(); foreach ( $line_items as $line ) { if ( ! is_array( $line ) ) { continue; } $item = isset( $line['item'] ) && is_array( $line['item'] ) ? $line['item'] : $line; $item_id = isset( $item['id'] ) ? (string) $item['id'] : ''; $product_id = 0; $variation_id = 0; if ( preg_match( '/gid:\/\/woocommerce\/ProductVariation\/(\d+)/', $item_id, $matches ) ) { $maybe_id = (int) $matches[1]; $variation = wc_get_product( $maybe_id ); if ( $variation instanceof WC_Product_Variation ) { $variation_id = $maybe_id; $product_id = (int) $variation->get_parent_id(); } } elseif ( preg_match( '/gid:\/\/woocommerce\/Product\/(\d+)/', $item_id, $matches ) ) { $product_id = (int) $matches[1]; } elseif ( preg_match( '/^\d+$/', $item_id ) ) { $product_id = (int) $item_id; } if ( $product_id > 0 ) { $parsed[] = array( 'product_id' => $product_id, 'variation_id' => $variation_id, ); } } return $parsed; } /** * @param array $arguments * @return array */ public static function get_cart( array $arguments ): array { $session_key = self::read_session_key( $arguments ); if ( $session_key === '' ) { return self::error_response( __( 'cart id is required.', 'agentmatica-mcp-connector' ) ); } return self::cart_response( $session_key ); } /** * @param array $arguments * @return array */ public static function create_checkout( array $arguments ): array { $session_key = self::read_session_key( $arguments ); $checkout = isset( $arguments['checkout'] ) && is_array( $arguments['checkout'] ) ? $arguments['checkout'] : array(); if ( $session_key === '' && isset( $checkout['cart_id'] ) ) { $session_key = self::read_session_key( array( 'id' => (string) $checkout['cart_id'] ) ); } if ( $session_key === '' ) { $session_key = self::resolve_session_key( $arguments ); } if ( $session_key === '' ) { return self::error_response( __( 'cart id is required for checkout.', 'agentmatica-mcp-connector' ) ); } $result = Agentmatica_WooCommerce_Cart::checkout_url( array( 'session_key' => $session_key ) ); if ( empty( $result['success'] ) ) { return self::error_response( (string) ( $result['message'] ?? __( 'Checkout unavailable.', 'agentmatica-mcp-connector' ) ) ); } $checkout_url = (string) ( $result['checkout_url'] ?? '' ); return array( 'ucp' => array( 'version' => Agentmatica_Ucp_Profile::UCP_VERSION, ), 'checkout' => array( 'id' => self::checkout_gid( $session_key ), 'cart_id' => self::cart_gid( $session_key ), 'checkout_url' => $checkout_url, ), ); } /** * @return list */ private static function read_line_items( array $arguments ): array { $cart = isset( $arguments['cart'] ) && is_array( $arguments['cart'] ) ? $arguments['cart'] : $arguments; $line_items = isset( $cart['line_items'] ) && is_array( $cart['line_items'] ) ? $cart['line_items'] : array(); $parsed = array(); foreach ( $line_items as $line ) { if ( ! is_array( $line ) ) { continue; } $quantity = isset( $line['quantity'] ) ? max( 1, (int) $line['quantity'] ) : 1; $item = isset( $line['item'] ) && is_array( $line['item'] ) ? $line['item'] : $line; $item_id = isset( $item['id'] ) ? (string) $item['id'] : ''; $product_id = 0; $variation_id = 0; if ( preg_match( '/gid:\/\/woocommerce\/ProductVariation\/(\d+)/', $item_id, $matches ) ) { $maybe_id = (int) $matches[1]; $variation = wc_get_product( $maybe_id ); if ( $variation instanceof WC_Product_Variation ) { $variation_id = $maybe_id; $product_id = (int) $variation->get_parent_id(); } elseif ( $variation instanceof WC_Product ) { $product_id = $maybe_id; $variation_id = 0; } } elseif ( preg_match( '/gid:\/\/woocommerce\/Product\/(\d+)/', $item_id, $matches ) ) { $product_id = (int) $matches[1]; } elseif ( preg_match( '/^\d+$/', $item_id ) ) { $product_id = (int) $item_id; } if ( $product_id > 0 ) { $parsed[] = array( 'product_id' => $product_id, 'variation_id' => $variation_id, 'quantity' => $quantity, ); } } return $parsed; } private static function resolve_session_key( array $arguments ): string { $existing = self::read_session_key( $arguments ); if ( $existing !== '' ) { return $existing; } $cart = isset( $arguments['cart'] ) && is_array( $arguments['cart'] ) ? $arguments['cart'] : array(); $context = isset( $cart['context'] ) && is_array( $cart['context'] ) ? $cart['context'] : array(); if ( isset( $context['session_key'] ) ) { return Agentmatica_WooCommerce_Cart::sanitize_session_key( (string) $context['session_key'] ); } if ( isset( $arguments['session_key'] ) ) { return Agentmatica_WooCommerce_Cart::sanitize_session_key( (string) $arguments['session_key'] ); } return ''; } /** * @return array */ private static function cart_response( string $session_key ): array { $result = Agentmatica_WooCommerce_Cart::checkout_url( array( 'session_key' => $session_key ) ); if ( empty( $result['success'] ) ) { return self::error_response( (string) ( $result['message'] ?? __( 'Cart is empty.', 'agentmatica-mcp-connector' ) ) ); } $line_items = array(); foreach ( (array) ( $result['line_items'] ?? array() ) as $item ) { if ( ! is_array( $item ) ) { continue; } $product_id = (int) ( $item['product_id'] ?? 0 ); $variation_id = (int) ( $item['variation_id'] ?? 0 ); $quantity = (int) ( $item['quantity'] ?? 0 ); if ( $product_id <= 0 || $quantity <= 0 ) { continue; } $item_id = $variation_id > 0 ? Agentmatica_Ucp_Catalog::variant_gid( $variation_id ) : Agentmatica_Ucp_Catalog::product_gid( $product_id ); $title = (string) ( $item['title'] ?? '' ); $image_url = isset( $item['image_url'] ) ? trim( (string) $item['image_url'] ) : ''; $item_payload = array( 'id' => $item_id, 'title' => $title, 'product' => array( 'id' => Agentmatica_Ucp_Catalog::product_gid( $product_id ), 'title' => $title, ), ); if ( $image_url !== '' ) { $item_payload['image_url'] = $image_url; } $line_items[] = array( 'quantity' => $quantity, 'item' => $item_payload, ); } return array( 'ucp' => array( 'version' => Agentmatica_Ucp_Profile::UCP_VERSION, ), 'cart' => array( 'id' => self::cart_gid( $session_key ), 'line_items' => $line_items, 'checkout_url' => (string) ( $result['checkout_url'] ?? '' ), ), ); } /** * @return list */ private static function read_cart_attributes( array $arguments ): array { $cart = isset( $arguments['cart'] ) && is_array( $arguments['cart'] ) ? $arguments['cart'] : $arguments; $raw = isset( $cart['attributes'] ) && is_array( $cart['attributes'] ) ? $cart['attributes'] : array(); $attributes = array(); foreach ( $raw as $entry ) { if ( ! is_array( $entry ) ) { continue; } $key = isset( $entry['key'] ) ? trim( (string) $entry['key'] ) : ''; if ( $key === '' ) { continue; } $attributes[] = array( 'key' => $key, 'value' => isset( $entry['value'] ) ? (string) $entry['value'] : '', ); } return $attributes; } /** * @return array */ private static function error_response( string $message ): array { return array( 'ucp' => array( 'version' => Agentmatica_Ucp_Profile::UCP_VERSION, 'status' => 'error', ), 'messages' => array( array( 'severity' => 'error', 'text' => $message, ), ), ); } }