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