api_base_url = $options['sxg_api_url'] ?? 'https://sxg-api.tigerstyle.com/v1'; $this->api_key = $options['sxg_api_key'] ?? ''; $this->timeout = 30; $this->cache_ttl = 3600; // 1 hour } /** * Check if API service is available */ public function is_service_available() { $cache_key = 'tigerstyle_heat_sxg_api_status'; $cached_status = get_transient($cache_key); if ($cached_status !== false) { return $cached_status === 'available'; } $response = $this->make_request('GET', '/health'); $is_available = $response && $response['status'] === 'healthy'; set_transient($cache_key, $is_available ? 'available' : 'unavailable', 300); // Cache for 5 minutes return $is_available; } /** * Register WordPress site with SXG API service */ public function register_site() { $site_data = [ 'domain' => parse_url(home_url(), PHP_URL_HOST), 'site_url' => home_url(), 'admin_email' => get_option('admin_email'), 'wordpress_version' => get_bloginfo('version'), 'plugin_version' => TIGERSTYLE_HEAT_VERSION, 'ssl_enabled' => is_ssl(), 'certificate_info' => $this->get_certificate_info() ]; $response = $this->make_request('POST', '/sites/register', $site_data); if ($response && isset($response['api_key'])) { // Store the generated API key $options = get_option('tigerstyle_heat_amp', []); $options['sxg_api_key'] = $response['api_key']; $options['sxg_site_id'] = $response['site_id']; update_option('tigerstyle_heat_amp', $options); return $response; } return false; } /** * Generate SXG for AMP content */ public function generate_sxg($url, $amp_content) { if (!$this->api_key) { return new WP_Error('no_api_key', 'SXG API key not configured'); } // Check cache first $cache_key = 'tigerstyle_heat_sxg_' . md5($url . $amp_content); $cached_sxg = get_transient($cache_key); if ($cached_sxg !== false) { return $cached_sxg; } $sxg_data = [ 'url' => $url, 'content' => $amp_content, 'timestamp' => time(), 'headers' => $this->get_sxg_headers(), 'options' => [ 'max_age' => 86400, // 24 hours 'stale_while_revalidate' => 604800 // 7 days ] ]; $response = $this->make_request('POST', '/sxg/generate', $sxg_data); if ($response && isset($response['sxg_package'])) { // Cache the SXG package set_transient($cache_key, $response, $this->cache_ttl); return $response; } return new WP_Error('sxg_generation_failed', 'Failed to generate SXG package'); } /** * Validate AMP content before SXG generation */ public function validate_amp_content($content) { $validation_data = [ 'content' => $content, 'url' => get_permalink(), 'validation_level' => 'strict' ]; $response = $this->make_request('POST', '/amp/validate', $validation_data); return $response; } /** * Get amppackager configuration for local installation */ public function get_amppackager_config() { $site_info = [ 'domain' => parse_url(home_url(), PHP_URL_HOST), 'certificate_path' => '/etc/ssl/certs/' . parse_url(home_url(), PHP_URL_HOST) . '.pem', 'private_key_path' => '/etc/ssl/private/' . parse_url(home_url(), PHP_URL_HOST) . '.key', 'amp_endpoint' => home_url() . '/{path}/amp', 'sxg_endpoint' => home_url() . '/{path}/amp.sxg' ]; $response = $this->make_request('POST', '/config/amppackager', $site_info); return $response; } /** * Get certificate recommendations */ public function get_certificate_recommendations() { $domain_info = [ 'domain' => parse_url(home_url(), PHP_URL_HOST), 'hosting_provider' => $this->detect_hosting_provider(), 'current_certificate' => $this->get_certificate_info() ]; $response = $this->make_request('POST', '/certificates/recommendations', $domain_info); return $response; } /** * Test SXG infrastructure */ public function test_infrastructure() { $test_data = [ 'domain' => parse_url(home_url(), PHP_URL_HOST), 'test_url' => home_url() . '/test-amp', 'user_agent' => 'TigerStyle-SEO-SXG-Test/1.0' ]; $response = $this->make_request('POST', '/test/infrastructure', $test_data); return $response; } /** * Get SXG analytics and performance metrics */ public function get_sxg_analytics($days = 30) { $params = [ 'days' => $days, 'metrics' => ['requests', 'cache_hits', 'validation_errors', 'performance'] ]; $response = $this->make_request('GET', '/analytics/sxg?' . http_build_query($params)); return $response; } /** * Make HTTP request to SXG API */ private function make_request($method, $endpoint, $data = null) { $url = rtrim($this->api_base_url, '/') . $endpoint; $args = [ 'method' => $method, 'timeout' => $this->timeout, 'headers' => [ 'Content-Type' => 'application/json', 'User-Agent' => 'TigerStyle-SEO/' . TIGERSTYLE_HEAT_VERSION . ' WordPress/' . get_bloginfo('version'), 'Accept' => 'application/json' ] ]; // Add API key if available if ($this->api_key) { $args['headers']['Authorization'] = 'Bearer ' . $this->api_key; } // Add request data if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) { $args['body'] = wp_json_encode($data); } $response = wp_remote_request($url, $args); if (is_wp_error($response)) { error_log('SXG API Request Error: ' . $response->get_error_message()); return false; } $response_code = wp_remote_retrieve_response_code($response); $response_body = wp_remote_retrieve_body($response); if ($response_code >= 200 && $response_code < 300) { return json_decode($response_body, true); } error_log("SXG API Error {$response_code}: {$response_body}"); return false; } /** * Get certificate information */ private function get_certificate_info() { if (!is_ssl()) { return null; } $domain = parse_url(home_url(), PHP_URL_HOST); // Try to get certificate info using OpenSSL $cert_info = []; try { $context = stream_context_create([ 'ssl' => [ 'capture_peer_cert' => true, 'verify_peer' => false, 'verify_peer_name' => false ] ]); $stream = stream_socket_client( "ssl://{$domain}:443", $errno, $errstr, 10, STREAM_CLIENT_CONNECT, $context ); if ($stream) { $cert = stream_context_get_params($stream)['options']['ssl']['peer_certificate']; $cert_data = openssl_x509_parse($cert); if ($cert_data) { $cert_info = [ 'subject' => $cert_data['subject']['CN'] ?? $domain, 'issuer' => $cert_data['issuer']['CN'] ?? 'Unknown', 'valid_from' => date('Y-m-d H:i:s', $cert_data['validFrom_time_t']), 'valid_to' => date('Y-m-d H:i:s', $cert_data['validTo_time_t']), 'signature_algorithm' => $cert_data['signatureTypeSN'] ?? 'Unknown' ]; } fclose($stream); } } catch (Exception $e) { error_log('Certificate info extraction failed: ' . $e->getMessage()); } return $cert_info; } /** * Get SXG headers for WordPress */ private function get_sxg_headers() { return [ 'cache-control' => 'public, max-age=86400, stale-while-revalidate=604800', 'content-type' => 'text/html; charset=utf-8', 'vary' => 'Accept, AMP-Cache-Transform', 'amp-access-control-allow-source-origin' => home_url(), 'access-control-expose-headers' => 'AMP-Access-Control-Allow-Source-Origin' ]; } /** * Detect hosting provider for better recommendations */ private function detect_hosting_provider() { $hosting_indicators = [ 'WP Engine' => ['wpengine.com', 'WPEngine'], 'Kinsta' => ['kinsta.com', 'Kinsta'], 'Pantheon' => ['pantheonsite.io', 'Pantheon'], 'WordPress.com' => ['wordpress.com', 'Automattic'], 'SiteGround' => ['siteground.com', 'SiteGround'], 'Cloudflare' => ['cloudflare.com', 'Cloudflare'], 'DigitalOcean' => ['digitalocean.com', 'DigitalOcean'], 'AWS' => ['amazonaws.com', 'Amazon'], 'Google Cloud' => ['googleusercontent.com', 'Google'] ]; $server_name = $_SERVER['SERVER_NAME'] ?? ''; $server_software = $_SERVER['SERVER_SOFTWARE'] ?? ''; $http_host = $_SERVER['HTTP_HOST'] ?? ''; foreach ($hosting_indicators as $provider => $indicators) { foreach ($indicators as $indicator) { if (stripos($server_name . $server_software . $http_host, $indicator) !== false) { return $provider; } } } return 'Unknown'; } /** * Get API service status and capabilities */ public function get_service_info() { return $this->make_request('GET', '/info'); } /** * Update API configuration */ public function update_config($config) { $options = get_option('tigerstyle_heat_amp', []); $options = array_merge($options, $config); update_option('tigerstyle_heat_amp', $options); // Update instance variables $this->api_base_url = $options['sxg_api_url'] ?? $this->api_base_url; $this->api_key = $options['sxg_api_key'] ?? $this->api_key; return true; } }