]> git.mxchange.org Git - friendica-addons.git/blob - s3_storage/vendor/akeeba/s3/src/Response.php
[s3_storage] Bump version of akeeba/s3 to version 2.3.1
[friendica-addons.git] / s3_storage / vendor / akeeba / s3 / src / Response.php
1 <?php
2 /**
3  * Akeeba Engine
4  *
5  * @package   akeebaengine
6  * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
7  * @license   GNU General Public License version 3, or later
8  */
9
10 namespace Akeeba\S3;
11
12 use Akeeba\S3\Exception\PropertyNotFound;
13 use Akeeba\S3\Response\Error;
14 use SimpleXMLElement;
15
16 // Protection against direct access
17 defined('AKEEBAENGINE') || die();
18
19 /**
20  * Amazon S3 API response object
21  *
22  * @property   Error                        $error    Response error object
23  * @property   string|SimpleXMLElement|null $body     Body data
24  * @property   int                          $code     Response code
25  * @property   array                        $headers  Any headers we may have
26  */
27 class Response
28 {
29         /**
30          * Error object
31          *
32          * @var  Error
33          */
34         private $error = null;
35
36         /**
37          * Response body
38          *
39          * @var  string|SimpleXMLElement|null
40          */
41         private $body = null;
42
43         /**
44          * Status code of the response, e.g. 200 for OK, 403 for Forbidden etc
45          *
46          * @var  int
47          */
48         private $code = 0;
49
50         /**
51          * Response headers
52          *
53          * @var  array
54          */
55         private $headers = [];
56
57         /**
58          * Response constructor.
59          */
60         public function __construct()
61         {
62                 $this->error = new Error();
63         }
64
65         /**
66          * Is this an error response?
67          *
68          * @return  bool
69          */
70         public function isError(): bool
71         {
72                 return is_null($this->error) || $this->error->isError();
73         }
74
75         /**
76          * Does this response have a body?
77          *
78          * @return  bool
79          */
80         public function hasBody(): bool
81         {
82                 return !empty($this->body);
83         }
84
85         /**
86          * Get the response error object
87          *
88          * @return  Error
89          */
90         public function getError(): Error
91         {
92                 return $this->error;
93         }
94
95         /**
96          * Set the response error object
97          *
98          * @param   Error  $error
99          */
100         public function setError(Error $error): void
101         {
102                 $this->error = $error;
103         }
104
105         /**
106          * Get the response body
107          *
108          * If there is no body set up you get NULL.
109          *
110          * If the body is binary data (e.g. downloading a file) or other non-XML data you get a string.
111          *
112          * If the body was an XML string – the standard Amazon S3 REST API response type – you get a SimpleXMLElement
113          * object.
114          *
115          * @return string|SimpleXMLElement|null
116          */
117         public function getBody()
118         {
119                 return $this->body;
120         }
121
122         /**
123          * Set the response body. If it's a string we'll try to parse it as XML.
124          *
125          * @param   string|SimpleXMLElement|null  $body
126          */
127         public function setBody($body, bool $rawResponse = false): void
128         {
129                 $this->body = null;
130
131                 if (empty($body))
132                 {
133                         return;
134                 }
135
136                 $this->body = $body;
137
138                 $this->finaliseBody($rawResponse);
139         }
140
141         public function resetBody(): void
142         {
143                 $this->body = null;
144         }
145
146         public function addToBody(string $data): void
147         {
148                 if (empty($this->body))
149                 {
150                         $this->body = '';
151                 }
152
153                 $this->body .= $data;
154         }
155
156         public function finaliseBody(bool $rawResponse = false): void
157         {
158                 if (!$this->hasBody())
159                 {
160                         return;
161                 }
162
163                 if (!isset($this->headers['type']))
164                 {
165                         $this->headers['type'] = 'text/plain';
166                 }
167
168                 if (
169                         !$rawResponse
170                         && is_string($this->body)
171                         &&
172                         (
173                                 ($this->headers['type'] == 'application/xml')
174                                 || (substr($this->body, 0, 5) == '<?xml')
175                         )
176                 )
177                 {
178                         $this->body = simplexml_load_string($this->body);
179                 }
180
181                 if (is_object($this->body) && ($this->body instanceof SimpleXMLElement))
182                 {
183                         $this->parseBody();
184                 }
185         }
186
187         /**
188          * Returns the status code of the response
189          *
190          * @return  int
191          */
192         public function getCode(): int
193         {
194                 return $this->code;
195         }
196
197         /**
198          * Sets the status code of the response
199          *
200          * @param   int  $code
201          */
202         public function setCode(int $code): void
203         {
204                 $this->code = $code;
205         }
206
207         /**
208          * Get the response headers
209          *
210          * @return  array
211          */
212         public function getHeaders(): array
213         {
214                 return $this->headers;
215         }
216
217         /**
218          * Set the response headers
219          *
220          * @param   array  $headers
221          */
222         public function setHeaders(array $headers): void
223         {
224                 $this->headers = $headers;
225         }
226
227         /**
228          * Set a single header
229          *
230          * @param   string  $name   The header name
231          * @param   string  $value  The header value
232          *
233          * @return  void
234          */
235         public function setHeader(string $name, string $value): void
236         {
237                 $this->headers[$name] = $value;
238         }
239
240         /**
241          * Does a header by this name exist?
242          *
243          * @param   string  $name  The header to look for
244          *
245          * @return  bool  True if it exists
246          */
247         public function hasHeader(string $name): bool
248         {
249                 return array_key_exists($name, $this->headers);
250         }
251
252         /**
253          * Unset a response header
254          *
255          * @param   string  $name  The header to unset
256          *
257          * @return  void
258          */
259         public function unsetHeader(string $name): void
260         {
261                 if ($this->hasHeader($name))
262                 {
263                         unset ($this->headers[$name]);
264                 }
265         }
266
267         /**
268          * Magic getter for the protected properties
269          *
270          * @param   string  $name
271          *
272          * @return  mixed
273          */
274         public function __get(string $name)
275         {
276                 switch ($name)
277                 {
278                         case 'error':
279                                 return $this->getError();
280                                 break;
281
282                         case 'body':
283                                 return $this->getBody();
284                                 break;
285
286                         case 'code':
287                                 return $this->getCode();
288                                 break;
289
290                         case 'headers':
291                                 return $this->getHeaders();
292                                 break;
293                 }
294
295                 throw new PropertyNotFound("Property $name not found in " . get_class($this));
296         }
297
298         /**
299          * Magic setter for the protected properties
300          *
301          * @param   string  $name   The name of the property
302          * @param   mixed   $value  The value of the property
303          *
304          * @return  void
305          */
306         public function __set(string $name, $value): void
307         {
308                 switch ($name)
309                 {
310                         case 'error':
311                                 $this->setError($value);
312                                 break;
313
314                         case 'body':
315                                 $this->setBody($value);
316                                 break;
317
318                         case 'code':
319                                 $this->setCode($value);
320                                 break;
321
322                         case 'headers':
323                                 $this->setHeaders($value);
324                                 break;
325
326                         default:
327                                 throw new PropertyNotFound("Property $name not found in " . get_class($this));
328                 }
329         }
330
331         /**
332          * Scans the SimpleXMLElement body for errors and propagates them to the Error object
333          */
334         protected function parseBody(): void
335         {
336                 if (!in_array($this->code, [200, 204]) &&
337                         isset($this->body->Code, $this->body->Message)
338                 )
339                 {
340                         $this->error = new Error(
341                                 500,
342                                 (string) $this->body->Code . ':' . (string) $this->body->Message
343                         );
344
345                         if (isset($this->body->Resource))
346                         {
347                                 $this->error->setResource((string) $this->body->Resource);
348                         }
349                 }
350         }
351 }