settings = $settings; $this->reader = $reader; $this->http = $http; } public function register(): void { \add_action( ProductHooks::SYNC_HOOK, [ $this, 'handle' ], 10, 2 ); } public function handle( $product_id, $op = ProductHooks::OP_UPSERT ): void { $productId = (int) $product_id; if ( $productId <= 0 ) { return; } $apiKey = $this->settings->apiKey(); if ( $apiKey === '' ) { return; } if ( ! $this->settings->hasSelectedAgents() ) { return; } $this->doUpsert( $productId, $apiKey ); } private function doUpsert( int $productId, string $apiKey ): void { $product = $this->reader->readOne( $productId, $this->settings->syncCategories() ); if ( $product === null ) { $this->doDelete( $productId, $apiKey ); return; } $body = \wp_json_encode( [ 'site' => \home_url(), 'product' => $product, ] ); if ( $body === false ) { return; } $url = $this->settings->productEndpoint( (int) $product['id'] ); $result = $this->http->putJson( $url, $this->headers( $apiKey ), $body ); $this->guardResult( $result, 'upsert', $productId ); } private function doDelete( int $productId, string $apiKey ): void { $url = $this->settings->productEndpoint( $productId ); $result = $this->http->delete( $url, $this->headers( $apiKey ) ); $this->guardResult( $result, 'delete', $productId ); } private function guardResult( Result $result, string $op, int $productId ): void { if ( $result->isSuccess() ) { return; } $status = $result->status(); if ( $status === 404 && $op === 'delete' ) { return; } if ( $this->isTerminalStatus( $status ) ) { return; } throw new \RuntimeException( \esc_html( sprintf( /* translators: 1: operation name (upsert/delete), 2: product ID, 3: HTTP status code */ \__( '%1$s failed for product %2$d (HTTP %3$d).', 'agent001-support-assistant-for-woocommerce' ), $op, $productId, $status ) ) ); } private function isTerminalStatus( int $status ): bool { if ( $status === 0 ) { return false; } if ( $status === 408 || $status === 429 ) { return false; } if ( $status >= 400 && $status < 500 ) { return true; } return false; } /** * @return array */ private function headers( string $apiKey ): array { return [ 'Content-Type' => 'application/json', 'X-API-Key' => $apiKey, 'Accept' => 'application/json', 'User-Agent' => 'Agent001/' . ( \defined( 'AGENT001_VERSION' ) ? \AGENT001_VERSION : 'dev' ), ]; } }