backup
This commit is contained in:
1 parent
c8bcfe6bd6
commit
9c277e6db8
18 files changed
+2506
-671
No files matched your search
@@ -8,25 +8,16 @@ class EcomZoneClient
|
||||
private $apiToken;
|
||||
private $apiUrl;
|
||||
private $maxRetries = 3;
|
||||
private $timeout = 30;
|
||||
private $timeout = 60; // Increased timeout
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->apiToken = Configuration::get("ECOMZONE_API_TOKEN");
|
||||
$this->apiUrl = Configuration::get("ECOMZONE_API_URL");
|
||||
|
||||
if (empty($this->apiToken)) {
|
||||
throw new EcomZoneException(
|
||||
"API token not configured",
|
||||
EcomZoneException::API_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($this->apiUrl)) {
|
||||
throw new EcomZoneException(
|
||||
"API URL not configured",
|
||||
EcomZoneException::API_ERROR
|
||||
);
|
||||
$this->apiUrl = 'https://dropship.ecomzone.eu/api'; // Default API URL
|
||||
Configuration::updateValue("ECOMZONE_API_URL", $this->apiUrl);
|
||||
}
|
||||
|
||||
EcomZoneLogger::log("API Client initialized", "INFO", [
|
||||
@@ -34,44 +25,60 @@ class EcomZoneClient
|
||||
]);
|
||||
}
|
||||
|
||||
public function validateApiCredentials()
|
||||
{
|
||||
if (empty($this->apiToken)) {
|
||||
throw new EcomZoneException(
|
||||
"API token not configured",
|
||||
EcomZoneException::API_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getCatalog($page = 1, $perPage = 100)
|
||||
{
|
||||
$url = $this->apiUrl . "/catalog";
|
||||
$this->validateApiCredentials();
|
||||
|
||||
$params = [
|
||||
"page" => $page,
|
||||
"per_page" => $perPage,
|
||||
];
|
||||
|
||||
return $this->makeRequest("GET", $url, $params);
|
||||
return $this->makeRequest("catalog", "GET", $params);
|
||||
}
|
||||
|
||||
public function getProduct($sku)
|
||||
{
|
||||
$url = $this->apiUrl . "/product/" . urlencode($sku);
|
||||
return $this->makeRequest("GET", $url);
|
||||
$this->validateApiCredentials();
|
||||
|
||||
return $this->makeRequest("product/" . urlencode($sku), "GET");
|
||||
}
|
||||
|
||||
private function makeRequest($method, $url, $params = [], $data = null)
|
||||
private function makeRequest($endpoint, $method = "GET", $params = [], $data = null)
|
||||
{
|
||||
// Validate API credentials first
|
||||
$this->validateApiCredentials();
|
||||
|
||||
$retryCount = 0;
|
||||
$lastError = null;
|
||||
$url = rtrim($this->apiUrl, '/') . '/' . ltrim($endpoint, '/');
|
||||
|
||||
// Add query parameters to URL if method is GET
|
||||
if ($method === "GET" && !empty($params) && is_array($params)) {
|
||||
$url .= (strpos($url, "?") === false ? "?" : "&") . http_build_query($params);
|
||||
}
|
||||
|
||||
do {
|
||||
try {
|
||||
EcomZoneLogger::log("Making API request", "INFO", [
|
||||
"method" => $method,
|
||||
"url" => $url,
|
||||
"params" => $params,
|
||||
"retry" => $retryCount,
|
||||
"params" => $params
|
||||
]);
|
||||
|
||||
// Add query parameters
|
||||
if (!empty($params)) {
|
||||
$url .=
|
||||
(strpos($url, "?") === false ? "?" : "&") .
|
||||
http_build_query($params);
|
||||
}
|
||||
|
||||
$curl = curl_init();
|
||||
$options = [
|
||||
CURLOPT_URL => $url,
|
||||
@@ -86,36 +93,108 @@ class EcomZoneClient
|
||||
"Authorization: Bearer " . $this->apiToken,
|
||||
"Accept: application/json",
|
||||
"Content-Type: application/json",
|
||||
"User-Agent: PrestaShop-EcomZone/1.0",
|
||||
"Connection: close" // Avoid keep-alive issues
|
||||
],
|
||||
// SSL Options - disable verification for development
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => 0,
|
||||
// Verbose debugging
|
||||
CURLOPT_VERBOSE => true,
|
||||
];
|
||||
|
||||
// Create a temporary file for curl verbose output
|
||||
$verbose = fopen('php://temp', 'w+');
|
||||
curl_setopt($curl, CURLOPT_STDERR, $verbose);
|
||||
|
||||
// Add POST data if provided
|
||||
if ($data !== null) {
|
||||
$options[CURLOPT_POSTFIELDS] = json_encode($data);
|
||||
$jsonData = json_encode($data);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonData);
|
||||
EcomZoneLogger::log("Request payload", "DEBUG", [
|
||||
'data' => $jsonData
|
||||
]);
|
||||
}
|
||||
// For POST requests with params, add them to the body
|
||||
else if ($method !== "GET" && !empty($params)) {
|
||||
$jsonData = json_encode($params);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonData);
|
||||
EcomZoneLogger::log("Request params as payload", "DEBUG", [
|
||||
'data' => $jsonData
|
||||
]);
|
||||
}
|
||||
|
||||
curl_setopt_array($curl, $options);
|
||||
|
||||
// Execute the request
|
||||
$response = curl_exec($curl);
|
||||
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
$contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
|
||||
$error = curl_error($curl);
|
||||
$errorNo = curl_errno($curl);
|
||||
|
||||
// Get verbose information
|
||||
rewind($verbose);
|
||||
$verboseLog = stream_get_contents($verbose);
|
||||
fclose($verbose);
|
||||
|
||||
// Log detailed response information
|
||||
EcomZoneLogger::log("API Response Details", "DEBUG", [
|
||||
'http_code' => $httpCode,
|
||||
'content_type' => $contentType,
|
||||
'response_length' => strlen($response),
|
||||
'curl_error_code' => $errorNo,
|
||||
'curl_error' => $error,
|
||||
'verbose_log' => $verboseLog,
|
||||
'raw_response' => strlen($response) > 1000 ?
|
||||
substr($response, 0, 1000) . '... [truncated]' :
|
||||
$response
|
||||
]);
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
if ($error) {
|
||||
throw new Exception("cURL Error: " . $error);
|
||||
if ($errorNo > 0) {
|
||||
throw new Exception("cURL Error ({$errorNo}): " . $error);
|
||||
}
|
||||
|
||||
// Handle HTTP errors
|
||||
if ($httpCode >= 400) {
|
||||
throw new Exception(
|
||||
"HTTP Error: " . $httpCode . " Response: " . $response
|
||||
);
|
||||
$errorMessage = "HTTP Error: " . $httpCode;
|
||||
|
||||
// Try to extract error details from response
|
||||
if (!empty($response)) {
|
||||
try {
|
||||
$errorData = json_decode($response, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE && !empty($errorData['error'])) {
|
||||
$errorMessage .= " - " . $errorData['error'];
|
||||
} else {
|
||||
$errorMessage .= " - Response: " . substr($response, 0, 200);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$errorMessage .= " - Raw response: " . substr($response, 0, 200);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception($errorMessage);
|
||||
}
|
||||
|
||||
// Handle empty responses
|
||||
if (empty($response)) {
|
||||
throw new Exception("Empty response received from API");
|
||||
}
|
||||
|
||||
// Decode JSON response
|
||||
$decodedResponse = json_decode($response, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new Exception("Invalid JSON response");
|
||||
throw new Exception(
|
||||
"Invalid JSON response: " . json_last_error_msg() .
|
||||
"\nRaw response: " . substr($response, 0, 500)
|
||||
);
|
||||
}
|
||||
|
||||
EcomZoneLogger::log("API request successful", "INFO", [
|
||||
"http_code" => $httpCode,
|
||||
"content_type" => $contentType
|
||||
]);
|
||||
|
||||
return $decodedResponse;
|
||||
@@ -126,10 +205,18 @@ class EcomZoneClient
|
||||
EcomZoneLogger::log("API request failed", "ERROR", [
|
||||
"error" => $e->getMessage(),
|
||||
"retry" => $retryCount,
|
||||
"url" => $url,
|
||||
"trace" => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
if ($retryCount < $this->maxRetries) {
|
||||
sleep(pow(2, $retryCount));
|
||||
$sleepTime = pow(2, $retryCount);
|
||||
EcomZoneLogger::log("Retrying request", "INFO", [
|
||||
"retry_count" => $retryCount,
|
||||
"sleep_time" => $sleepTime,
|
||||
"url" => $url
|
||||
]);
|
||||
sleep($sleepTime);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -142,11 +229,117 @@ class EcomZoneClient
|
||||
}
|
||||
} while ($retryCount < $this->maxRetries);
|
||||
|
||||
// This should never be reached, but just in case
|
||||
throw new EcomZoneException(
|
||||
"Max retries reached: " . $lastError->getMessage(),
|
||||
EcomZoneException::API_ERROR,
|
||||
$lastError
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download an image from the EcomZone API with proper authentication
|
||||
*
|
||||
* @param string $imageUrl The full URL of the image to download
|
||||
* @return array Array containing image data and metadata
|
||||
* @throws EcomZoneException If the download fails
|
||||
*/
|
||||
public function downloadImage(string $imageUrl): array
|
||||
{
|
||||
try {
|
||||
EcomZoneLogger::log("Downloading image", "DEBUG", [
|
||||
'url' => $imageUrl
|
||||
]);
|
||||
|
||||
// Initialize cURL
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $imageUrl,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 5,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => 0,
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Accept: image/webp,image/apng,image/*,*/*;q=0.8',
|
||||
'Accept-Encoding: gzip, deflate, br',
|
||||
'Authorization: Bearer ' . $this->getApiToken()
|
||||
]
|
||||
]);
|
||||
|
||||
$imageData = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||
$error = curl_error($ch);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
// Check if the response is HTML instead of an image (authentication error)
|
||||
$isHtml = stripos($contentType, 'text/html') !== false ||
|
||||
(strlen($imageData) > 15 && stripos($imageData, '<!DOCTYPE html>') !== false);
|
||||
|
||||
if ($isHtml) {
|
||||
throw new EcomZoneException(
|
||||
"Authentication error: Received HTML instead of image data. Check API token.",
|
||||
EcomZoneException::API_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
if ($httpCode !== 200 || empty($imageData)) {
|
||||
throw new EcomZoneException(
|
||||
"Failed to download image (HTTP $httpCode): $error",
|
||||
EcomZoneException::API_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
EcomZoneLogger::log("Image download complete", "DEBUG", [
|
||||
'url' => $imageUrl,
|
||||
'content_type' => $contentType,
|
||||
'size' => strlen($imageData)
|
||||
]);
|
||||
|
||||
return [
|
||||
'data' => $imageData,
|
||||
'content_type' => $contentType,
|
||||
'http_code' => $httpCode
|
||||
];
|
||||
|
||||
} catch (Exception $e) {
|
||||
EcomZoneLogger::log("Image download failed", "ERROR", [
|
||||
'url' => $imageUrl,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
throw new EcomZoneException(
|
||||
"Image download failed: " . $e->getMessage(),
|
||||
EcomZoneException::API_ERROR,
|
||||
$e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API token, either from the class property or from the configuration
|
||||
*
|
||||
* @return string The API token
|
||||
*/
|
||||
protected function getApiToken()
|
||||
{
|
||||
if (empty($this->apiToken)) {
|
||||
$this->apiToken = Configuration::get("ECOMZONE_API_TOKEN");
|
||||
}
|
||||
|
||||
if (empty($this->apiToken)) {
|
||||
throw new EcomZoneException(
|
||||
"API token not configured",
|
||||
EcomZoneException::API_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return $this->apiToken;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user