/** * @param string $url * @param array $queries * * @throws InvalidRequest * @throws OverQueryLimit * @throws RequestDenied * @throws Unknown * * @return array */ protected static function query(string $url, array $queries = []) : array { if (!self::$client) { self::$client = new HttpClient(); $base = new Uri('https://maps.googleapis.com/maps/api'); self::$client->setBaseUri($base); } if (!isset($queries['key'])) { $queries['key'] = DI::config()->get('googleMaps/apikey'); } $uri = new Uri($url); $uri->addQueries($queries); $response = self::$client->get($uri->get()); $data = json_decode($response->getBody(), true); if (!($data['status'] == 'OK' || $data['status'] == 'ZERO_RESULTS')) { switch ($data['status']) { case 'OVER_QUERY_LIMIT': throw new OverQueryLimit($data['error_message'] ?? $data['status']); case 'REQUEST_DENIED': throw new RequestDenied($data['error_message'] ?? $data['status']); case 'INVALID_REQUEST': throw new InvalidRequest($data['error_message'] ?? $data['status']); default: throw new Unknown($data['error_message'] ?? $data['status']); } } return $data; }
/** * @param bool $relative * * @return string */ public function generateUrl(bool $relative = false) : string { if (!$this->hmacAdded && !$relative && ($sign = DI::config()->getIfExists('googleMaps/secret'))) { $binarySign = base64_decode(str_replace(['-', '_'], ['+', '/'], $sign)); $hmac = hash_hmac('sha1', $this->generateUrl(true), $binarySign, true); $this->queries['signature'] = str_replace(['+', '/'], ['-', '_'], base64_encode($hmac)); $this->hmacAdded = true; } $uri = new Uri('https://maps.googleapis.com/maps/api/staticmap'); $uri->addQueries($this->queries); $url = $uri->get($relative); // google maps expect markers=...&markers=... $url = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', $url); $url = str_replace('%2C', ',', $url); return $url; }
/** * Test InvalidArgumentException on removeQueries */ public function testAddQuerystringException() { $this->setExpectedException('InvalidArgumentException'); $uri = new Uri('http://example.com/'); $uri->addQueries([1 => 'test']); }
/** * @param string $name * @param array $data * @param bool $warnData * * @return Uri */ public function getUri(string $name, array $data = [], $warnData = true) : Uri { if (!isset($this->routes[$name])) { throw new \InvalidArgumentException(sprintf("Invalid route name '%s'", $name)); } $route = $this->routes[$name]; $uri = new Uri(); $uri->removeAllQueries()->setFragment(null)->setPath($this->routeRegexp($route, $data)); // $cloneData = $data; // append querystring if ($route->getUserInputs()) { $queryToAdd = []; foreach ($route->getUserInputs() as $querystring) { if (!isset($data[$querystring->getName()]) && $querystring->isMandatory() && $warnData && $route->getMethod() != 'POST' && $route->getMethod() != 'PUT' && $route->getMethod() != 'DELETE') { throw new \InvalidArgumentException(sprintf("Missing querystring '%s' to generate route '%s'", $querystring->getName(), $route->getName())); } if (isset($data[$querystring->getName()])) { // unset($cloneData[$querystring->getName()]); $queryToAdd[$querystring->getName()] = $data[$querystring->getName()]; } } $uri->addQueries($queryToAdd); } /* // Args can be consumed by routeRegexp and not remove from cloneData if (sizeof($cloneData)) { throw new \InvalidArgumentException(sprintf( "Too many data to generate route '%s' with keys %s", $route->getName(), "'" . implode("', '", array_keys($cloneData)) . "'" )); } */ return $uri; }
/** * @param int $maxWidth * @param int $maxHeight * * @return Uri */ public function getUrl(int $maxWidth = null, int $maxHeight = null) : Uri { if ($maxWidth && $maxHeight) { throw new \InvalidArgumentException("You can't specify maxWidth AND maxHeight"); } $queries = ['photoreference' => $this->reference, 'key' => DI::config()->get('googleMaps/apikey')]; if ($maxWidth) { $queries['maxwidth'] = (string) $maxWidth; } if ($maxHeight) { $queries['maxheight'] = (string) $maxHeight; } $uri = new Uri('https://maps.googleapis.com/maps/api/place/photo'); $uri->addQueries($queries); return $uri; }