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 $options Request options
132 *
133 * @throws ConnectorException When the API replies with an error response
134 * @throws RequestException When an error is encountered
135 * @throws \LogicException When Guzzle cannot populate the response
136 *
137 * @return ResponseValidator
138 */
139 protected function request($method, $url, array $options = [])
140 {
141 $request = $this->connector->createRequest($url, $method, $options);
142
143 return new ResponseValidator($this->connector->send($request));
144 }
145
146 /**
147 * Sends a HTTP GET request to the specified url.
148 *
149 * @param string $url Request destination
150 *
151 * @throws ConnectorException When the API replies with an error response
152 * @throws RequestException When an error is encountered
153 * @throws \LogicException When Guzzle cannot populate the response
154 *
155 * @return ResponseValidator
156 */
157 protected function get($url)
158 {
159 return $this->request('GET', $url);
160 }
161
162 /**
163 * Sends a HTTP PATCH request to the specified url.
164 *
165 * @param string $url Request destination
166 * @param array $data Data to be JSON encoded
167 *
168 * @throws ConnectorException When the API replies with an error response
169 * @throws RequestException When an error is encountered
170 * @throws \LogicException When Guzzle cannot populate the response
171 *
172 * @return ResponseValidator
173 */
174 protected function patch($url, array $data)
175 {
176 return $this->request('PATCH', $url, ['json' => $data]);
177 }
178
179 /**
180 * Sends a HTTP POST request to the specified url.
181 *
182 * @param string $url Request destination
183 * @param array $data Data to be JSON encoded
184 *
185 * @throws ConnectorException When the API replies with an error response
186 * @throws RequestException When an error is encountered
187 * @throws \LogicException When Guzzle cannot populate the response
188 *
189 * @return ResponseValidator
190 */
191 protected function post($url, array $data = null)
192 {
193 $options = [];
194 if ($data !== null) {
195 $options['json'] = $data;
196 }
197
198 return $this->request('POST', $url, $options);
199 }
200 }
201