1: <?php
2: namespace Worldline\Connect\Sdk\Communication;
3:
4: use UnexpectedValueException;
5: use Worldline\Connect\Sdk\Domain\DataObject;
6:
7: /**
8: * Class ResponseFactory
9: *
10: * @package Worldline\Connect\Sdk\Communication
11: */
12: class ResponseFactory
13: {
14: const MIME_APPLICATION_JSON = 'application/json';
15:
16: /**
17: * @param ConnectionResponse $response
18: * @param ResponseClassMap $responseClassMap
19: * @return DataObject|null
20: */
21: public function createResponse(ConnectionResponse $response, ResponseClassMap $responseClassMap)
22: {
23: try {
24: return $this->getResponseObject($response, $responseClassMap);
25: } catch (UnexpectedValueException $e) {
26: throw new InvalidResponseException($response, $e->getMessage());
27: }
28: }
29:
30: /**
31: * @param ConnectionResponse $response
32: * @param ResponseClassMap $responseClassMap
33: * @return DataObject|null
34: */
35: protected function getResponseObject(ConnectionResponse $response, ResponseClassMap $responseClassMap)
36: {
37: $httpStatusCode = $response->getHttpStatusCode();
38: if (!$httpStatusCode) {
39: throw new UnexpectedValueException('HTTP status code is missing');
40: }
41: $contentType = $response->getHeaderValue('Content-Type');
42: if (!$contentType && $httpStatusCode !== 204) {
43: throw new UnexpectedValueException('Content type is missing or empty');
44: }
45: if (!$this->isJsonContentType($contentType) && $httpStatusCode !== 204) {
46: throw new UnexpectedValueException(
47: "Invalid content type; got '$contentType', expected '" . static::MIME_APPLICATION_JSON . "'"
48: );
49: }
50: $responseClassName = $responseClassMap->getResponseClassName($httpStatusCode);
51: if (empty($responseClassName)) {
52: if ($httpStatusCode < 400) {
53: return null;
54: }
55: throw new UnexpectedValueException('No default error response class name defined');
56: }
57: if (!class_exists($responseClassName)) {
58: throw new UnexpectedValueException("class '$responseClassName' does not exist");
59: }
60: $responseObject = new $responseClassName();
61: if (!$responseObject instanceof DataObject) {
62: throw new UnexpectedValueException("class '$responseClassName' is not a 'DataObject'");
63: }
64: return $responseObject->fromJson($response->getBody());
65: }
66:
67: private function isJsonContentType($contentType) {
68: return $contentType === static::MIME_APPLICATION_JSON
69: || substr($contentType, 0, strlen(static::MIME_APPLICATION_JSON)) === static::MIME_APPLICATION_JSON;
70: }
71: }
72: