Example #1
0
 /**
  * @param OptionsInterface $options
  * @param DataInterface $dataObject
  * @return DataAbstract
  * @throws Exception\AccessDenied
  * @throws Exception\AuthenticationFailure
  * @throws Exception\DecodingError
  * @throws Exception\NotFound
  * @throws Exception\TransferError
  */
 public function request(OptionsInterface $options, DataInterface $dataObject)
 {
     $apiKey = $options instanceof AccessInterface ? $this->accessApiKey : $this->manageApiKey;
     $apiSecret = $options instanceof AccessInterface ? $this->accessApiSecret : $this->manageApiSecret;
     if (!$options->hasAccessKey()) {
         $options->setAccessKey($apiKey);
     }
     $requestType = $options->getRequestType();
     $endPoint = $options->getEndPoint();
     $url = $options->getApiBaseURL() . $endPoint;
     $this->debug('URL', [$url]);
     $populatedValues = $options->getPopulated();
     ksort($populatedValues);
     $this->debug('Parameters', [$populatedValues]);
     $payload = '';
     if ($requestType == OptionsAbstract::REQUEST_TYPE_GET && !empty($populatedValues)) {
         $httpQuery = http_build_query($populatedValues);
         $url .= "?{$httpQuery}";
         $this->debug('Get query', [$httpQuery]);
         $payload = $httpQuery;
     } else {
         if (empty($populatedValues)) {
             $this->debug('Empty payload');
         } else {
             $json = json_encode($populatedValues);
             $this->debug('Json payload', [$json]);
             $payload = $json;
         }
     }
     $this->request->setRequestTypeAndPayload($requestType, $payload);
     $this->debug('Set Full URL', [$url]);
     $this->request->setUrl($url);
     $timestamp = gmdate('D, d M Y H:i:s T');
     $tokenValues = [strtoupper($requestType), $timestamp, strtolower($endPoint)];
     if ($requestType == OptionsAbstract::REQUEST_TYPE_GET) {
         $tokenValues[] = implode('&', array_map(function ($key, $value) {
             return sprintf('%s=%s', strtolower($key), strtolower($value));
         }, array_keys($populatedValues), $populatedValues));
         // note: this is different because it can't be escaped - unlike the http_build_query which does - and need to be lower cased
     } else {
         $tokenValues[] = '';
         // for non-get we don't send any parameters, but we need this for the new line...
     }
     $this->debug('Token values', $tokenValues);
     $token = base64_encode(hash_hmac('sha256', implode("\n", $tokenValues), $apiSecret, true));
     $this->debug('Token created', [$token]);
     $this->request->setAuthentication("{$apiKey}:{$token}")->setTimestamp($timestamp);
     $this->info("About to send to {$url} via {$requestType} with options of " . get_class($options));
     $this->debug('Beginning request');
     $result = $this->request->execute();
     $this->debug('Request completed.', ['INFO' => $this->request->getResponseInfo(), 'BODY' => $result]);
     $this->handleRequestError($result);
     // really shouldn't happen unless something changes or I missed something
     if (($httpCode = $this->request->getResponseHTTPCode()) !== 200) {
         $message = "HTTP Error Code of {$httpCode} was generated and not caught: " . $result;
         $this->error($message);
         throw new Exception\TransferError($message);
     }
     $this->debug('All error checking passed.');
     $this->info("The request was successful.");
     if (!$dataObject instanceof None) {
         $jsonArray = json_decode($result, true);
         if (is_null($jsonArray)) {
             throw new Exception\DecodingError(json_last_error_msg(), json_last_error());
         }
         $dataObject->populate($jsonArray);
     }
     return $dataObject;
 }