• Namespace
  • Class

Namespaces

  • Klarna
    • Exceptions
    • Rest
      • Checkout
      • CustomerToken
      • HostedPaymentPage
      • InstantShopping
      • MerchantCardService
      • OrderManagement
      • Payments
      • Settlements
      • Transport
        • Exception

Classes

  • Klarna\Rest\Checkout\Order
  • Klarna\Rest\CustomerToken\Tokens
  • Klarna\Rest\HostedPaymentPage\Sessions
  • Klarna\Rest\InstantShopping\ButtonKeys
  • Klarna\Rest\InstantShopping\Orders
  • Klarna\Rest\MerchantCardService\VCCSettlements
  • Klarna\Rest\OrderManagement\Capture
  • Klarna\Rest\OrderManagement\Order
  • Klarna\Rest\OrderManagement\Refund
  • Klarna\Rest\Payments\Orders
  • Klarna\Rest\Payments\Sessions
  • Klarna\Rest\Resource
  • Klarna\Rest\Settlements\Payouts
  • Klarna\Rest\Settlements\Reports
  • Klarna\Rest\Settlements\Transactions
  • Klarna\Rest\Transport\ApiResponse
  • Klarna\Rest\Transport\Connector
  • Klarna\Rest\Transport\CURLConnector
  • Klarna\Rest\Transport\GuzzleConnector
  • Klarna\Rest\Transport\Method
  • Klarna\Rest\Transport\ResponseValidator
  • Klarna\Rest\Transport\UserAgent

Interfaces

  • Klarna\Rest\Transport\ConnectorInterface
  • Klarna\Rest\Transport\UserAgentInterface

Exceptions

  • Klarna\Exceptions\NotApplicableException
  • Klarna\Rest\Transport\Exception\ConnectorException
  1 <?php
  2 /**
  3  * Copyright 2019 Klarna AB
  4  *
  5  * Licensed under the Apache License, Version 2.0 (the "License");
  6  * you may not use this file except in compliance with the License.
  7  * You may obtain a copy of the License at
  8  *
  9  * http://www.apache.org/licenses/LICENSE-2.0
 10  *
 11  * Unless required by applicable law or agreed to in writing, software
 12  * distributed under the License is distributed on an "AS IS" BASIS,
 13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  * See the License for the specific language governing permissions and
 15  * limitations under the License.
 16  *
 17  * File containing the ResponseValidator class.
 18  */
 19 
 20 namespace Klarna\Rest\Transport;
 21 
 22 use Klarna\Rest\Transport\ApiResponse;
 23 use Klarna\Rest\Transport\Exception\ConnectorException;
 24 
 25 /**
 26  * HTTP response validator helper class.
 27  */
 28 class ResponseValidator
 29 {
 30     /**
 31      * HTTP response to validate against.
 32      *
 33      * @var ApiResponse
 34      */
 35     protected $response;
 36 
 37     /**
 38      * Constructs a response validator instance.
 39      *
 40      * @param ApiResponse $response Response to validate
 41      */
 42     public function __construct(ApiResponse $response)
 43     {
 44         $this->response = $response;
 45     }
 46 
 47     /**
 48      * Gets the response object.
 49      *
 50      * @return ApiResponse
 51      */
 52     public function getResponse()
 53     {
 54         return $this->response;
 55     }
 56 
 57     /**
 58      * Asserts the HTTP response status code.
 59      *
 60      * @param string|string[] $status Expected status code(s)
 61      *
 62      * @throws \RuntimeException If status code does not match
 63      *
 64      * @return self
 65      */
 66     public function status($status)
 67     {
 68         $httpStatus = (string) $this->response->getStatus();
 69         if (is_array($status) && !in_array($httpStatus, $status)) {
 70             throw new \RuntimeException(
 71                 "Unexpected response status code: {$httpStatus}"
 72             );
 73         }
 74 
 75         if (is_string($status) && $httpStatus !== $status) {
 76             throw new \RuntimeException(
 77                 "Unexpected response status code: {$httpStatus}"
 78             );
 79         }
 80 
 81         return $this;
 82     }
 83 
 84     /**
 85      * Asserts the Content-Type header. Checks partial matching.
 86      * Validation PASSES in the following cases:
 87      *      Content-Type: application/json
 88      *      $mediaType = 'application/json'
 89      *
 90      *      Content-Type: application/json; charset=utf-8
 91      *      $mediaType = 'application/json'
 92      *
 93      * Validation FAILS in the following cases:
 94      *      Content-Type: plain/text
 95      *      $mediaType = 'application/json'
 96      *
 97      *      Content-Type: application/json; charset=utf-8
 98      *      $mediaType = 'application/json; charset=cp-1251'
 99      *
100      * @param string $mediaType Expected media type. RegExp rules can be used.
101      *
102      * @throws \RuntimeException If Content-Type header is missing
103      * @throws \RuntimeException If Content-Type header does not match
104      *
105      * @return self
106      */
107     public function contentType($mediaType)
108     {
109         $contentType = $this->response->getHeader('Content-Type');
110         if (empty($contentType)) {
111             throw new \RuntimeException('Response is missing a Content-Type header');
112         }
113         $mediaFound = false;
114         foreach ($contentType as $type) {
115             if (preg_match('#' . $mediaType . '#', $type)) {
116                 $mediaFound = true;
117                 break;
118             }
119         }
120 
121         if (!$mediaFound) {
122             throw new \RuntimeException(
123                 'Unexpected Content-Type header received: '
124                 . implode(',', $contentType) . '. Expected: ' . $mediaType
125             );
126         }
127 
128         return $this;
129     }
130 
131     /**
132      * Gets the decoded JSON response.
133      *
134      * @throws \RuntimeException         If the response body is not in JSON format
135      * @throws \InvalidArgumentException If the JSON cannot be parsed
136      *
137      * @return array
138      */
139     public function getJson()
140     {
141         return \json_decode($this->response->getBody(), true);
142     }
143 
144     /**
145      * Gets response body.
146      *
147      * @throws \RuntimeException         If the response body is not in JSON format
148      * @throws \InvalidArgumentException If the JSON cannot be parsed
149      *
150      * @return StreamInterface the body as a stream
151      */
152     public function getBody()
153     {
154         return $this->response->getBody();
155     }
156 
157     /**
158      * Gets the Location header.
159      *
160      * @throws \RuntimeException If the Location header is missing
161      *
162      * @return string
163      */
164     public function getLocation()
165     {
166         $location = $this->response->getHeader('Location');
167         if (empty($location)) {
168             throw new \RuntimeException('Response is missing a Location header');
169         }
170         return $location[0];
171     }
172 
173     
174     /**
175      * Asserts and analyze the response. Checks if the reponse has SUCCESSFULL family
176      * and try to parse the Klarna error message if possbile.
177      *
178      * @throws ConnectorException if response has non-2xx HTTP CODE and contains
179      *                      a <a href="https://developers.klarna.com/api/#errors">Error</a>
180      * @throws \RuntimeException if response has non-2xx HTTP CODE and body is not parsable
181      *
182      * @return void
183      */
184     public function expectSuccessfull()
185     {
186         if ($this->isSuccessfull()) {
187             return $this;
188         }
189 
190         $data = json_decode($this->response->getBody(), true);
191         if (is_array($data) && array_key_exists('error_code', $data)) {
192             throw new ConnectorException($data, $this->response->getStatus());
193         }
194 
195         throw new \RuntimeException(
196             'Unexpected reponse HTTP status ' . $this->response->getStatus() .
197             '. Excepted HTTP status should be in 2xx range',
198             $this->response->getStatus()
199         );
200     }
201 
202     public function isSuccessfull()
203     {
204         $status = $this->response->getStatus();
205         return $status >= 200 && $status < 300;
206     }
207 }
208 
API documentation generated by ApiGen