1 <?php
2 /**
3 * Copyright 2014 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 abstract base resource class.
18 */
19
20 namespace Klarna\Rest;
21
22 use GuzzleHttp\Exception\RequestException;
23 use Klarna\Rest\Transport\Connector;
24 use Klarna\Rest\Transport\Exception\ConnectorException;
25 use Klarna\Rest\Transport\ResponseValidator;
26
27 /**
28 * Abstract resource class.
29 */
30 abstract class Resource extends \ArrayObject
31 {
32 /**
33 * Id property field name.
34 */
35 const ID_FIELD = 'id';
36
37 /**
38 * Path to the resource endpoint.
39 *
40 * @var string
41 */
42 public static $path;
43
44 /**
45 * HTTP transport connector instance.
46 *
47 * @var Connector
48 */
49 protected $connector;
50
51 /**
52 * Url to the resource.
53 *
54 * @var string
55 */
56 protected $url;
57
58 /**
59 * Constructs a resource instance.
60 *
61 * @param Connector $connector HTTP transport instance.
62 */
63 public function __construct(Connector $connector)
64 {
65 $this->connector = $connector;
66 }
67
68 /**
69 * Gets the resource id.
70 *
71 * @return string|null
72 */
73 public function getId()
74 {
75 return isset($this[static::ID_FIELD]) ? $this[static::ID_FIELD] : null;
76 }
77
78 /**
79 * Gets the resource location.
80 *
81 * @return string|null
82 */
83 public function getLocation()
84 {
85 return $this->url;
86 }
87
88 /**
89 * Sets the resource location.
90 *
91 * @param string $url Url to the resource
92 *
93 * @return self
94 */
95 public function setLocation($url)
96 {
97 $this->url = $url;
98
99 return $this;
100 }
101
102 /**
103 * Fetches the resource.
104 *
105 * @throws ConnectorException When the API replies with an error response
106 * @throws RequestException When an error is encountered
107 * @throws \RuntimeException On an unexpected API response
108 * @throws \RuntimeException If the response content type is not JSON
109 * @throws \InvalidArgumentException If the JSON cannot be parsed
110 * @throws \LogicException When Guzzle cannot populate the response
111 *
112 * @return self
113 */
114 public function fetch()
115 {
116 $data = $this->get($this->getLocation())
117 ->status('200')
118 ->contentType('application/json')
119 ->getJson();
120
121 $this->exchangeArray($data);
122
123 return $this;
124 }
125
126 /**
127 * Sends a HTTP request to the specified url.
128 *
129 * @param string $method HTTP method, e.g. 'GET'
130 * @param string $url Request destination
131 * @param array $headers
132 * @param string $body
133 *
134 * @throws ConnectorException When the API replies with an error response
135 * @throws RequestException When an error is encountered
136 * @throws \LogicException When Guzzle cannot populate the response'
137 * @return ResponseValidator When the API replies with an error response
138 *
139 */
140 protected function request($method, $url, array $headers = [], $body = '')
141 {
142 $request = $this->connector->createRequest($url, $method, $headers, $body);
143
144 return new ResponseValidator($this->connector->send($request));
145 }
146
147 /**
148 * Sends a HTTP GET request to the specified url.
149 *
150 * @param string $url Request destination
151 *
152 * @throws ConnectorException When the API replies with an error response
153 * @throws RequestException When an error is encountered
154 * @throws \LogicException When Guzzle cannot populate the response
155 *
156 * @return ResponseValidator
157 */
158 protected function get($url)
159 {
160 return $this->request('GET', $url);
161 }
162
163 /**
164 * Sends a HTTP PATCH request to the specified url.
165 *
166 * @param string $url Request destination
167 * @param array $data Data to be JSON encoded
168 *
169 * @throws ConnectorException When the API replies with an error response
170 * @throws RequestException When an error is encountered
171 * @throws \LogicException When Guzzle cannot populate the response
172 *
173 * @return ResponseValidator
174 */
175 protected function patch($url, array $data)
176 {
177 return $this->request('PATCH', $url, ['Content-Type' => 'application/json'], json_encode($data));
178 }
179
180 /**
181 * Sends a HTTP POST request to the specified url.
182 *
183 * @param string $url Request destination
184 * @param array $data Data to be JSON encoded
185 *
186 * @throws ConnectorException When the API replies with an error response
187 * @throws RequestException When an error is encountered
188 * @throws \LogicException When Guzzle cannot populate the response
189 *
190 * @return ResponseValidator
191 */
192 protected function post($url, array $data = null)
193 {
194 return $this->request(
195 'POST',
196 $url,
197 ['Content-Type' => 'application/json'],
198 $data !== null ? \json_encode($data) : null
199 );
200 }
201 }
202