| 1 |
<?php |
| 2 |
|
| 3 |
namespace Dudlewebs\WPMCS\s3\Aws\Api\ErrorParser; |
| 4 |
|
| 5 |
use Dudlewebs\WPMCS\s3\Aws\Api\Parser\PayloadParserTrait; |
| 6 |
use Dudlewebs\WPMCS\s3\Aws\Api\Parser\XmlParser; |
| 7 |
use Dudlewebs\WPMCS\s3\Aws\Api\Service; |
| 8 |
use Dudlewebs\WPMCS\s3\Aws\Api\StructureShape; |
| 9 |
use Dudlewebs\WPMCS\s3\Aws\CommandInterface; |
| 10 |
use Dudlewebs\WPMCS\s3\Psr\Http\Message\ResponseInterface; |
| 11 |
/** |
| 12 |
* Parses XML errors. |
| 13 |
*/ |
| 14 |
class XmlErrorParser extends AbstractErrorParser |
| 15 |
{ |
| 16 |
use PayloadParserTrait; |
| 17 |
protected $parser; |
| 18 |
public function __construct(Service $api = null, XmlParser $parser = null) |
| 19 |
{ |
| 20 |
parent::__construct($api); |
| 21 |
$this->parser = $parser ?: new XmlParser(); |
| 22 |
} |
| 23 |
public function __invoke(ResponseInterface $response, CommandInterface $command = null) |
| 24 |
{ |
| 25 |
$code = (string) $response->getStatusCode(); |
| 26 |
$data = ['type' => $code[0] == '4' ? 'client' : 'server', 'request_id' => null, 'code' => null, 'message' => null, 'parsed' => null]; |
| 27 |
$body = $response->getBody(); |
| 28 |
if ($body->getSize() > 0) { |
| 29 |
$this->parseBody($this->parseXml($body, $response), $data); |
| 30 |
} else { |
| 31 |
$this->parseHeaders($response, $data); |
| 32 |
} |
| 33 |
$this->populateShape($data, $response, $command); |
| 34 |
return $data; |
| 35 |
} |
| 36 |
private function parseHeaders(ResponseInterface $response, array &$data) |
| 37 |
{ |
| 38 |
if ($response->getStatusCode() == '404') { |
| 39 |
$data['code'] = 'NotFound'; |
| 40 |
} |
| 41 |
$data['message'] = $response->getStatusCode() . ' ' . $response->getReasonPhrase(); |
| 42 |
if ($requestId = $response->getHeaderLine('x-amz-request-id')) { |
| 43 |
$data['request_id'] = $requestId; |
| 44 |
$data['message'] .= " (Request-ID: {$requestId})"; |
| 45 |
} |
| 46 |
} |
| 47 |
private function parseBody(\SimpleXMLElement $body, array &$data) |
| 48 |
{ |
| 49 |
$data['parsed'] = $body; |
| 50 |
$prefix = $this->registerNamespacePrefix($body); |
| 51 |
if ($tempXml = $body->xpath("//{$prefix}Code[1]")) { |
| 52 |
$data['code'] = (string) $tempXml[0]; |
| 53 |
} |
| 54 |
if ($tempXml = $body->xpath("//{$prefix}Message[1]")) { |
| 55 |
$data['message'] = (string) $tempXml[0]; |
| 56 |
} |
| 57 |
$tempXml = $body->xpath("//{$prefix}RequestId[1]"); |
| 58 |
if (isset($tempXml[0])) { |
| 59 |
$data['request_id'] = (string) $tempXml[0]; |
| 60 |
} |
| 61 |
} |
| 62 |
protected function registerNamespacePrefix(\SimpleXMLElement $element) |
| 63 |
{ |
| 64 |
$namespaces = $element->getDocNamespaces(); |
| 65 |
if (!isset($namespaces[''])) { |
| 66 |
return ''; |
| 67 |
} |
| 68 |
// Account for the default namespace being defined and PHP not |
| 69 |
// being able to handle it :(. |
| 70 |
$element->registerXPathNamespace('ns', $namespaces['']); |
| 71 |
return 'ns:'; |
| 72 |
} |
| 73 |
protected function payload(ResponseInterface $response, StructureShape $member) |
| 74 |
{ |
| 75 |
$xmlBody = $this->parseXml($response->getBody(), $response); |
| 76 |
$prefix = $this->registerNamespacePrefix($xmlBody); |
| 77 |
$errorBody = $xmlBody->xpath("//{$prefix}Error"); |
| 78 |
if (\is_array($errorBody) && !empty($errorBody[0])) { |
| 79 |
return $this->parser->parse($member, $errorBody[0]); |
| 80 |
} |
| 81 |
} |
| 82 |
} |
| 83 |
|