public function call($command, array $args = null, $verb = 'GET')
{
$attempts = 3;
if ($args === null) {
$args = array();
}
foreach ($args as $key => $value) {
if (is_null($value)) {
unset($args[$key]);
}
// Workaround for zones.
if ($key == 'zoneid' && !is_null($value)) {
if (empty($this->zonesCache)) {
foreach ($this->cloudstack->zone->describe() as $zone) {
$this->zonesCache[$zone->name] = $zone->id;
}
}
if (!empty($this->zonesCache[$value])) {
$args[$key] = $this->zonesCache[$value];
} else {
throw new RestClientException("Availability zone '{$value}' no longer supported");
}
}
}
$args['apikey'] = $this->apiKey;
$args['command'] = $command;
$args['response'] = 'json';
ksort($args);
$query = http_build_query($args, null, '&', PHP_QUERY_RFC3986);
if ('GET' == $verb) {
$query .= "&signature=" . $this->getSignature(strtolower($query));
} else {
$args['signature'] = $this->getSignature(strtolower($query));
}
$httpRequest = new Request();
$httpRequest->setRequestMethod($verb);
$url = 'GET' == $verb ? $this->endpoint . "?" . $query : $this->endpoint;
$httpRequest->setRequestUrl($url);
if ('POST' == $verb) {
$httpRequest->append($args);
}
$message = $this->tryCall($httpRequest, $attempts);
$response = new QueryClientResponse($message, $command);
$response->setRawRequestMessage($httpRequest->toString());
if ($this->debug) {
echo "\nURL: " . $httpRequest->getRequestUrl() . "\n", "{$httpRequest}\n", "{$response->getResponse()}\n";
}
return $response;
}