ResponseHandler.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Signifyd\Model\SignifydGateway\Client;
  7. use Magento\Signifyd\Model\SignifydGateway\ApiCallException;
  8. use Magento\Framework\Json\DecoderInterface;
  9. /**
  10. * Class ResponseHandler
  11. */
  12. class ResponseHandler
  13. {
  14. /**
  15. * Successful HTTP response codes.
  16. *
  17. * @var array
  18. */
  19. private static $successResponseCodes = [200, 201, 204];
  20. /**
  21. * Current servers PHP version id.
  22. */
  23. private static $phpVersionId = PHP_VERSION_ID;
  24. /**
  25. * Failure HTTP response codes with messages.
  26. *
  27. * @var array
  28. */
  29. private static $failureResponses = [
  30. 400 => 'Bad Request - The request could not be parsed. Response: %s',
  31. 401 => 'Unauthorized - user is not logged in, could not be authenticated. Response: %s',
  32. 403 => 'Forbidden - Cannot access resource. Response: %s',
  33. 404 => 'Not Found - resource does not exist. Response: %s',
  34. 409 => 'Conflict - with state of the resource on server. Can occur with (too rapid) PUT requests. Response: %s',
  35. 500 => 'Server error. Response: %s'
  36. ];
  37. /**
  38. * Unexpected Signifyd API response message.
  39. *
  40. * @var string
  41. */
  42. private static $unexpectedResponse = 'Unexpected Signifyd API response code "%s" with content "%s".';
  43. /**
  44. * @var DecoderInterface
  45. */
  46. private $dataDecoder;
  47. /**
  48. * ResponseHandler constructor.
  49. *
  50. * @param DecoderInterface $dataDecoder
  51. */
  52. public function __construct(
  53. DecoderInterface $dataDecoder
  54. ) {
  55. $this->dataDecoder = $dataDecoder;
  56. }
  57. /**
  58. * Reads result of successful operation and throws exception in case of any failure.
  59. *
  60. * @param \Zend_Http_Response $response
  61. * @return array
  62. * @throws ApiCallException
  63. */
  64. public function handle(\Zend_Http_Response $response)
  65. {
  66. $responseCode = $response->getStatus();
  67. if (!in_array($responseCode, self::$successResponseCodes)) {
  68. $errorMessage = $this->buildApiCallFailureMessage($response);
  69. throw new ApiCallException($errorMessage);
  70. }
  71. $responseBody = (string)$response->getBody();
  72. if (self::$phpVersionId < 70000 && empty($responseBody)) {
  73. /*
  74. * Only since PHP 7.0 empty string treated as JSON syntax error
  75. * http://php.net/manual/en/function.json-decode.php
  76. */
  77. throw new ApiCallException('Response is not valid JSON: Decoding failed: Syntax error');
  78. }
  79. try {
  80. $decodedResponseBody = $this->dataDecoder->decode($responseBody);
  81. } catch (\Exception $e) {
  82. throw new ApiCallException(
  83. 'Response is not valid JSON: ' . $e->getMessage(),
  84. $e->getCode(),
  85. $e
  86. );
  87. }
  88. return $decodedResponseBody;
  89. }
  90. /**
  91. * Error message for request rejected by Signify.
  92. *
  93. * @param \Zend_Http_Response $response
  94. * @return string
  95. */
  96. private function buildApiCallFailureMessage(\Zend_Http_Response $response)
  97. {
  98. $responseBody = $response->getBody();
  99. if (key_exists($response->getStatus(), self::$failureResponses)) {
  100. return sprintf(self::$failureResponses[$response->getStatus()], $responseBody);
  101. }
  102. return sprintf(
  103. self::$unexpectedResponse,
  104. $response->getStatus(),
  105. $responseBody
  106. );
  107. }
  108. }