added apiRuntimeCache

This commit is contained in:
O K
2025-12-08 13:21:40 +02:00
parent 5c2798dedd
commit dc9275909f

View File

@@ -8,6 +8,9 @@ use Symfony\Component\HttpClient\HttpClient;
class Usps_Api_Bridge extends Module class Usps_Api_Bridge extends Module
{ {
// Runtime cache to prevent duplicate API calls during a single page load
private $apiRuntimeCache = [];
public function __construct() public function __construct()
{ {
$this->name = 'usps_api_bridge'; $this->name = 'usps_api_bridge';
@@ -139,7 +142,7 @@ class Usps_Api_Bridge extends Module
return $helper->generateForm([$fields_form]); return $helper->generateForm([$fields_form]);
} }
public function calculateRate($params, $shipping_cost, $products, $originalModule) public function calculateRate($params, $shipping_cost, $products, $originalModule)
{ {
require_once(dirname(__FILE__) . '/classes/UspsV3Client.php'); require_once(dirname(__FILE__) . '/classes/UspsV3Client.php');
@@ -259,24 +262,65 @@ public function calculateRate($params, $shipping_cost, $products, $originalModul
} }
/** /**
* Helper to send request and handle Domestic vs International switching * Helper to send request with Runtime Caching & Domestic/Intl switching
*/ */
private function sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip) private function sendApiRequest($client, $payload, $isInternational, $destAddress, $destZip)
{ {
if ($isInternational) { // 1. Prepare the specific payload for the cache key
$payload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country); // We simulate the modifications we are about to do to ensure the key is accurate
// Cleanup domestic fields $cachePayload = $payload;
unset($payload['destinationEntryFacilityType']);
unset($payload['destinationZIPCode']);
return $client->getInternationalRate($payload); if ($isInternational) {
$cachePayload['destinationCountryCode'] = Country::getIsoById($destAddress->id_country);
$cachePayload['originZIPCode'] = $payload['originZIPCode']; // Ensure consistency
unset($cachePayload['destinationEntryFacilityType']);
unset($cachePayload['destinationZIPCode']);
$endpointType = 'INT';
} else {
$cachePayload['destinationZIPCode'] = $destZip;
$cachePayload['destinationEntryFacilityType'] = 'NONE';
$endpointType = 'DOM';
} }
// Domestic // 2. Generate Hash
$payload['destinationZIPCode'] = $destZip; // We include the endpoint type to ensure uniqueness
$payload['destinationEntryFacilityType'] = 'NONE'; $cacheKey = md5(json_encode($cachePayload) . $endpointType);
return $client->getDomesticRate($payload); // 3. Check Cache
if (isset($this->apiRuntimeCache[$cacheKey])) {
// Uncomment for deep debugging if needed
// $this->log("Returning cached rate for key: " . $cacheKey);
return $this->apiRuntimeCache[$cacheKey];
}
// 4. Perform Request
if ($isInternational) {
$response = $client->getInternationalRate($cachePayload);
} else {
$response = $client->getDomesticRate($cachePayload);
}
// 5. Determine if we should cache
// We DO cache API errors (like 400 Bad Request) because retrying them won't fix invalid data.
// We DO NOT cache Network/Transport errors (timeouts) so they can be retried.
$shouldCache = true;
if (isset($response['error'])) {
// Check for Guzzle/Symfony Transport errors strings defined in UspsV3Client
if (
strpos($response['error'], 'Network') !== false ||
strpos($response['error'], 'Connection') !== false ||
strpos($response['error'], 'Transport') !== false
) {
$shouldCache = false;
}
}
if ($shouldCache) {
$this->apiRuntimeCache[$cacheKey] = $response;
}
return $response;
} }
/** /**