/** * Send request. * * @param string $method The request method. * @param mixed $payload The request body. * @param string $path The URL path or URL Template * @param array|ArrayObject $params The URL parameters. Parameters used for URL template or encode to query string. * @param array $headers The headers specific for request. * * @throws Http\Exception\ServerException * @throws Http\Exception\ClientException * * @return mixed|null The resulting resource or null */ public function send($method, $payload, $path, $params = [], array $headers = []) { if (!is_array($params)) { $params = (array) $params; } // Serialize $payload $payload = json_encode($payload, JSON_FORCE_OBJECT); $headers['Content-Type'] = 'application/json'; // Prepare request and response objects $uri = $this->createUri($path, $params); $request = $this->createRequest($method, $uri, $payload, $headers); $response = $this->createResponse(); /** * @var Response $response Call self middleware to send request and receive response */ $response = call_user_func($this->middleware, $request, $response, $this); if ($response->getStatusCode() === 404) { throw new Http\Exception\NotFoundException(); } if ($response->getStatusCode() === 410) { throw new Http\Exception\GoneException(); } if ($response->getStatusCode() === 422) { $content = json_decode($response->getBody()->getContents(), true); $content = isset($content['details']) ? $content['details'] : []; throw new Http\Exception\UnprocessableEntityException($content); } if ($response->getStatusCode() >= 500) { throw new Http\Exception\ServerException($response->getStatusCode(), $response->getReasonPhrase()); } if ($response->getStatusCode() >= 400) { throw new Http\Exception\ClientException($response->getStatusCode(), $response->getReasonPhrase()); } if (in_array($request->getMethod(), ['HEAD', 'DELETE'])) { return null; } // Find resource type (URL) in response location or request url $location = $response->hasHeader('Location') ? $this->createUri($response->getHeaderLine('Location')) : $request->getUri(); $uri = urldecode($location->getPath()); // Remove version from URI $uri = preg_replace('#^/' . self::CURRENT_VERSION . '#', '', $uri); // Unserialize response body $content = json_decode((string) $response->getBody(), true) ?: []; // Build expected resource $resource = $this->factory->create($uri, []); if ($resource instanceof Rest\Collection) { $content = ['data' => $content, '_metadata' => ['uri' => $uri, 'limit' => (int) $response->getHeaderLine('X-Pagination-Limit'), 'offset' => (int) $response->getHeaderLine('X-Pagination-Offset'), 'total' => (int) $response->getHeaderLine('X-Pagination-Total')]]; } else { $content['_metadata'] = ['uri' => $uri]; } $resource->populate($content); return $resource; }
/** * @param Request $request * @param Response $response * @param string $type * * @return mixed */ protected function parseJsonResponseBody(Request $request, Response $response, $type) { // Find resource type (URL) in response location or request url $location = $response->hasHeader('Location') ? $this->createUri($response->getHeaderLine('Location')) : $request->getUri(); $uri = urldecode($location->getPath()); // Remove version from URI $uri = preg_replace('#^/' . self::CURRENT_VERSION . '#', '', $uri); // Unserialize response body $content = json_decode((string) $response->getBody(), true) ?: []; // Build expected resource $resource = $this->factory->create($uri, []); if ($resource instanceof Rest\Collection) { $content = ['data' => $content, '_metadata' => ['uri' => $uri, 'limit' => (int) $response->getHeaderLine('X-Pagination-Limit'), 'offset' => (int) $response->getHeaderLine('X-Pagination-Offset'), 'total' => (int) $response->getHeaderLine('X-Pagination-Total')]]; } else { $content['_metadata'] = ['uri' => $uri]; } $resource->populate($content); return $resource; }