register_block_scripts(); $this->extend_store_api(); } /** * Returns an array of script handles to enqueue in the frontend context. * * @return string[] */ public function get_script_handles() { return array( 'agentshop-blocks-frontend' ); } /** * Returns an array of script handles to enqueue in the editor context. * * @return string[] */ public function get_editor_script_handles() { return array(); } /** * An array of key, value pairs of data made available to the block on the client side. * * @return array */ public function get_script_data() { $options = agentshop()->get_options(); return array( 'pixelToken' => $options['pixel_token'] ?? '', 'storeId' => $options['store_id'] ?? '', 'storeUrl' => agentshop()->get_store_url(), 'apiEndpoint' => agentshop()->get_api_endpoint() . '/api/woocommerce/pixel/events', 'customerId' => agentshop()->get_customer_id(), 'sessionId' => agentshop()->get_session_id(), 'version' => AGENTSHOP_VERSION, 'currency' => get_woocommerce_currency(), 'llmOnlyTracking' => false, ); } /** * Register frontend block scripts. */ private function register_block_scripts() { $script_url = AGENTSHOP_PLUGIN_URL . 'assets/js/pixel.js'; wp_register_script( 'agentshop-blocks-frontend', $script_url, array(), AGENTSHOP_VERSION, array( 'in_footer' => true, 'strategy' => 'defer', ) ); } /** * Extend Store API with AgentShop data. */ private function extend_store_api() { if ( ! function_exists( 'woocommerce_store_api_register_endpoint_data' ) ) { return; } // Extend cart endpoint. woocommerce_store_api_register_endpoint_data( array( 'endpoint' => 'cart', 'namespace' => 'agentshop', 'data_callback' => array( $this, 'get_cart_endpoint_data' ), 'schema_callback' => array( $this, 'get_cart_endpoint_schema' ), 'schema_type' => ARRAY_A, ) ); // Extend checkout endpoint. woocommerce_store_api_register_endpoint_data( array( 'endpoint' => 'checkout', 'namespace' => 'agentshop', 'data_callback' => array( $this, 'get_checkout_endpoint_data' ), 'schema_callback' => array( $this, 'get_checkout_endpoint_schema' ), 'schema_type' => ARRAY_A, ) ); } /** * Get cart endpoint data. * * @return array */ public function get_cart_endpoint_data() { return array( 'customer_id' => agentshop()->get_customer_id(), 'session_id' => agentshop()->get_session_id(), 'llm_source' => $this->get_llm_source(), ); } /** * Get cart endpoint schema. * * @return array */ public function get_cart_endpoint_schema() { return array( 'customer_id' => array( 'description' => __( 'AgentShop customer identifier', 'agentshop' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'session_id' => array( 'description' => __( 'AgentShop session identifier', 'agentshop' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'llm_source' => array( 'description' => __( 'LLM traffic source', 'agentshop' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ); } /** * Get checkout endpoint data. * * @return array */ public function get_checkout_endpoint_data() { return array( 'customer_id' => agentshop()->get_customer_id(), 'session_id' => agentshop()->get_session_id(), 'llm_source' => $this->get_llm_source(), 'tracking_enabled' => agentshop()->is_tracking_enabled(), ); } /** * Get checkout endpoint schema. * * @return array */ public function get_checkout_endpoint_schema() { return array( 'customer_id' => array( 'description' => __( 'AgentShop customer identifier', 'agentshop' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'session_id' => array( 'description' => __( 'AgentShop session identifier', 'agentshop' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'llm_source' => array( 'description' => __( 'LLM traffic source', 'agentshop' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tracking_enabled' => array( 'description' => __( 'Whether tracking is enabled', 'agentshop' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ); } /** * Get LLM source from cookie or referrer. * * @return string|null */ private function get_llm_source() { if ( isset( $_COOKIE['agentshop_llm'] ) ) { return sanitize_text_field( wp_unslash( $_COOKIE['agentshop_llm'] ) ); } $referrer = wp_get_referer(); if ( $referrer ) { return agentshop()->detect_llm_source( $referrer ); } return null; } } /** * Register the Blocks integration. */ function register_blocks_integration() { if ( ! class_exists( 'Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface' ) ) { return; } add_action( 'woocommerce_blocks_checkout_block_registration', function ( $integration_registry ) { $integration_registry->register( new Integration() ); } ); add_action( 'woocommerce_blocks_cart_block_registration', function ( $integration_registry ) { $integration_registry->register( new Integration() ); } ); } add_action( 'woocommerce_blocks_loaded', __NAMESPACE__ . '\register_blocks_integration' ); /** * Track Store API checkout completion. * * @param \WC_Order $order Order object. * @param \WP_REST_Request $request Request object. */ function track_store_api_checkout( $order, $request ) { if ( ! $order || ! agentshop()->is_tracking_enabled() ) { return; } $customer_id = agentshop()->get_customer_id(); $session_id = agentshop()->get_session_id(); $llm_source = isset( $_COOKIE['agentshop_llm'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['agentshop_llm'] ) ) : null; $order->update_meta_data( '_agentshop_customer_id', $customer_id ); $order->update_meta_data( '_agentshop_session_id', $session_id ); if ( $llm_source ) { $order->update_meta_data( '_agentshop_llm_source', $llm_source ); } $order->save(); } add_action( 'woocommerce_store_api_checkout_order_processed', __NAMESPACE__ . '\track_store_api_checkout', 10, 2 );