5 * @package akeebaengine
6 * @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
7 * @license GNU General Public License version 3, or later
10 namespace Akeeba\Engine\Postproc\Connector\S3v4;
12 use Akeeba\Engine\Postproc\Connector\S3v4\Exception\PropertyNotFound;
13 use Akeeba\Engine\Postproc\Connector\S3v4\Response\Error;
16 // Protection against direct access
17 defined('AKEEBAENGINE') or die();
20 * Amazon S3 API response object
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
34 private $error = null;
39 * @var string|SimpleXMLElement|null
44 * Status code of the response, e.g. 200 for OK, 403 for Forbidden etc
55 private $headers = [];
58 * Response constructor.
60 public function __construct()
62 $this->error = new Error();
66 * Is this an error response?
70 public function isError(): bool
72 return is_null($this->error) || $this->error->isError();
76 * Does this response have a body?
80 public function hasBody(): bool
82 return !empty($this->body);
86 * Get the response error object
90 public function getError(): Error
96 * Set the response error object
100 public function setError(Error $error): void
102 $this->error = $error;
106 * Get the response body
108 * If there is no body set up you get NULL.
110 * If the body is binary data (e.g. downloading a file) or other non-XML data you get a string.
112 * If the body was an XML string – the standard Amazon S3 REST API response type – you get a SimpleXMLElement
115 * @return string|SimpleXMLElement|null
117 public function getBody()
123 * Set the response body. If it's a string we'll try to parse it as XML.
125 * @param string|SimpleXMLElement|null $body
127 public function setBody($body): void
138 $this->finaliseBody();
141 public function resetBody(): void
146 public function addToBody(string $data): void
148 if (empty($this->body))
153 $this->body .= $data;
156 public function finaliseBody(): void
158 if (!$this->hasBody())
163 if (!isset($this->headers['type']))
165 $this->headers['type'] = 'text/plain';
168 if (is_string($this->body) &&
169 (($this->headers['type'] == 'application/xml') || (substr($this->body, 0, 5) == '<?xml'))
172 $this->body = simplexml_load_string($this->body);
175 if (is_object($this->body) && ($this->body instanceof SimpleXMLElement))
182 * Returns the status code of the response
186 public function getCode(): int
192 * Sets the status code of the response
196 public function setCode(int $code): void
202 * Get the response headers
206 public function getHeaders(): array
208 return $this->headers;
212 * Set the response headers
214 * @param array $headers
216 public function setHeaders(array $headers): void
218 $this->headers = $headers;
222 * Set a single header
224 * @param string $name The header name
225 * @param string $value The header value
229 public function setHeader(string $name, string $value): void
231 $this->headers[$name] = $value;
235 * Does a header by this name exist?
237 * @param string $name The header to look for
239 * @return bool True if it exists
241 public function hasHeader(string $name): bool
243 return array_key_exists($name, $this->headers);
247 * Unset a response header
249 * @param string $name The header to unset
253 public function unsetHeader(string $name): void
255 if ($this->hasHeader($name))
257 unset ($this->headers[$name]);
262 * Magic getter for the protected properties
264 * @param string $name
268 public function __get(string $name)
273 return $this->getError();
277 return $this->getBody();
281 return $this->getCode();
285 return $this->getHeaders();
289 throw new PropertyNotFound("Property $name not found in " . get_class($this));
293 * Magic setter for the protected properties
295 * @param string $name The name of the property
296 * @param mixed $value The value of the property
300 public function __set(string $name, $value): void
305 $this->setError($value);
309 $this->setBody($value);
313 $this->setCode($value);
317 $this->setHeaders($value);
321 throw new PropertyNotFound("Property $name not found in " . get_class($this));
326 * Scans the SimpleXMLElement body for errors and propagates them to the Error object
328 protected function parseBody(): void
330 if (!in_array($this->code, [200, 204]) &&
331 isset($this->body->Code, $this->body->Message)
334 $this->error = new Error(
336 (string) $this->body->Message
339 if (isset($this->body->Resource))
341 $this->error->setResource((string) $this->body->Resource);