client = $client; $this->json = $json; $this->getApiKey = $getApiKey; $this->scopeConfig = $scopeConfig; $this->latLngToQueryString = $latLngToQueryString; } /** * @inheritdoc * @throws LocalizedException */ public function execute(LatLngInterface $source, LatLngInterface $destination): float { $sourceString = $this->latLngToQueryString->execute($source); $destinationString = $this->latLngToQueryString->execute($destination); $key = $sourceString . '|' . $destinationString; if (!isset($this->distanceCache[$key])) { $queryString = http_build_query([ 'key' => $this->getApiKey->execute(), 'origins' => $sourceString, 'destinations' => $destinationString, 'mode' => $this->scopeConfig->getValue(self::XML_PATH_MODE), ]); $this->client->get(self::GOOGLE_ENDPOINT . '?' . $queryString); if ($this->client->getStatus() !== 200) { throw new LocalizedException(__('Unable to connect google API for distance matrix')); } $res = $this->json->unserialize($this->client->getBody()); if ($res['status'] !== 'OK' || $res['rows'][0]['elements'][0]['status'] === self::ZERO_RESULT_RESPONSE ) { throw new LocalizedException( __( 'Unable to get distance between %1 and %2', $sourceString, $destinationString ) ); } $element = $res['rows'][0]['elements'][0]; if ($this->scopeConfig->getValue(self::XML_PATH_VALUE) === 'time') { $this->distanceCache[$key] = (float)$element['duration']['value']; } else { $this->distanceCache[$key] = (float)$element['distance']['value']; } } return $this->distanceCache[$key]; } }