false, 'downloaded' => []]; try { $data = readJsonBody(); $businessID = (int)($data['businessID'] ?? 0); if ($businessID === 0) { throw new Exception('businessID is required'); } $uploadsPath = uploadsRoot(); $logosPath = "$uploadsPath/logos"; $headersPath = "$uploadsPath/headers"; if (!is_dir($logosPath)) mkdir($logosPath, 0755, true); if (!is_dir($headersPath)) mkdir($headersPath, 0755, true); // Download logo if (!empty($data['logoUrl'])) { $logoUrl = $data['logoUrl']; $ext = '.png'; if (stripos($logoUrl, '.jpg') !== false || stripos($logoUrl, '.jpeg') !== false) $ext = '.jpg'; elseif (stripos($logoUrl, '.gif') !== false) $ext = '.gif'; elseif (stripos($logoUrl, '.webp') !== false) $ext = '.webp'; $logoFile = "$logosPath/$businessID$ext"; try { $ch = curl_init($logoUrl); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_FOLLOWLOCATION => true, ]); $content = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200 && $content !== false) { file_put_contents($logoFile, $content); $response['downloaded'][] = [ 'type' => 'logo', 'url' => $logoUrl, 'savedTo' => "/uploads/logos/$businessID$ext", 'size' => strlen($content), ]; } else { $response['downloaded'][] = [ 'type' => 'logo', 'url' => $logoUrl, 'error' => "HTTP $httpCode", ]; } } catch (Exception $e) { $response['downloaded'][] = [ 'type' => 'logo', 'url' => $logoUrl, 'error' => $e->getMessage(), ]; } } // Download header if (!empty($data['headerUrl'])) { $headerUrl = $data['headerUrl']; try { $ch = curl_init($headerUrl); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTPHEADER => [ 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', ], ]); $content = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch); if ($httpCode === 200 && $content !== false && strlen($content) > 100) { // Detect actual format from content-type or magic bytes $ext = 'jpg'; if (stripos($contentType, 'png') !== false) $ext = 'png'; elseif (stripos($contentType, 'gif') !== false) $ext = 'gif'; elseif (stripos($contentType, 'webp') !== false) $ext = 'webp'; else { // Fallback: check magic bytes $hex = strtoupper(bin2hex(substr($content, 0, 8))); if (str_starts_with($hex, '89504E47')) $ext = 'png'; elseif (str_starts_with($hex, '474946')) $ext = 'gif'; elseif (str_starts_with($hex, '52494646')) $ext = 'webp'; } $headerFile = "$headersPath/$businessID.$ext"; file_put_contents($headerFile, $content); // Update database queryTimed("UPDATE Businesses SET HeaderImageExtension = ? WHERE ID = ?", [$ext, $businessID]); $response['downloaded'][] = [ 'type' => 'header', 'url' => $headerUrl, 'savedTo' => "/uploads/headers/$businessID.$ext", 'size' => strlen($content), ]; } else { $response['downloaded'][] = [ 'type' => 'header', 'url' => $headerUrl, 'error' => "HTTP $httpCode (size: " . strlen($content ?: '') . ")", ]; } } catch (Exception $e) { $response['downloaded'][] = [ 'type' => 'header', 'url' => $headerUrl, 'error' => $e->getMessage(), ]; } } $response['OK'] = true; $response['businessID'] = $businessID; } catch (Exception $e) { $response['error'] = $e->getMessage(); } jsonResponse($response);